Skip to content

Instantly share code, notes, and snippets.

@brandonpittman
Created November 17, 2022 02:05
Show Gist options
  • Save brandonpittman/392d11d86f6561b6d548b26e15dfc476 to your computer and use it in GitHub Desktop.
Save brandonpittman/392d11d86f6561b6d548b26e15dfc476 to your computer and use it in GitHub Desktop.
Progress enhancement helpers/components for Remix
import { z } from "zod";
export let noJS = z
// convert "true" to boolean, treat any other value as false
.preprocess((v) => v === "true", z.boolean())
.nullable() // allow it to be null
.default(true); // default to true (support the worst scenario)
import type { FetcherWithComponents, FormProps } from "@remix-run/react";
import type { ReactElement, ReactNode } from "react";
import { Form } from "@remix-run/react";
import { useHydrated } from "remix-utils";
export let NoJS = ({ children }: { children: ReactElement }) => {
let isHydrated = useHydrated();
if (!isHydrated) {
return children;
} else {
return null;
}
};
export let HasJS = ({ children }: { children: ReactElement }) => {
let isHydrated = useHydrated();
if (isHydrated) {
return children;
} else {
return null;
}
};
export let ProgessiveEnhancement = ({
children,
fallback,
}: {
children: ReactElement;
fallback: ReactElement;
}) => {
let isHydrated = useHydrated();
if (isHydrated) {
return children;
} else {
return fallback;
}
};
export let ProgressiveForm = ({
fetcher,
children,
...props
}: {
children: ReactNode;
fetcher?: FetcherWithComponents<any>;
} & FormProps) => {
let isHydrated = useHydrated();
let NoJS = () => (
<input type="hidden" name="no-js" value={String(!isHydrated)} />
);
if (fetcher) {
return (
<fetcher.Form {...props}>
<NoJS />
{children}
</fetcher.Form>
);
} else {
return (
<Form {...props}>
<NoJS />
{children}
</Form>
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment