Skip to content

Instantly share code, notes, and snippets.

@brandonpittman
Created November 17, 2022 02:05
Show Gist options
  • Select an option

  • Save brandonpittman/392d11d86f6561b6d548b26e15dfc476 to your computer and use it in GitHub Desktop.

Select an option

Save brandonpittman/392d11d86f6561b6d548b26e15dfc476 to your computer and use it in GitHub Desktop.

Revisions

  1. brandonpittman created this gist Nov 17, 2022.
    72 changes: 72 additions & 0 deletions ProgressiveEnhancement.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    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>
    );
    }
    };
    6 changes: 6 additions & 0 deletions no-js.server.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    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)