Created
November 17, 2022 02:05
-
-
Save brandonpittman/392d11d86f6561b6d548b26e15dfc476 to your computer and use it in GitHub Desktop.
Progress enhancement helpers/components for Remix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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