# All files / src/form FormThemeProvider.tsx

88.15% Statements 67/76
100% Branches 3/3
50% Functions 1/2
88.15% Lines 67/76

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    771x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    46x
    46x
    46x
    46x
    46x
    46x
    46x
    46x
    46x
    46x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x

     "use client";
    import {
      createContext,
      useContext,
      useMemo,
      type ReactElement,
      type ReactNode,
    } from "react";
    import { type FormThemeOptions } from "./types.js";

    export type FormThemeContext = Required<FormThemeOptions>;

    const context = createContext<FormThemeContext>({
      theme: "outline",
      underlineDirection: "left",
    });

    /**
     * Gets the current theme values for a form component by inheriting the current
     * form theme via context. If you provide an object of theme props, the returned
     * value will use any defined values from the theme props and fallback to the
     * context value.
     *
     * @example
     * Simple Example
     * ```ts
     * // everything is inherited
     * const formTheme = useFormTheme();
     *
     * // theme will be set to "underline" while the others will be inherited
     * const formTheme = useFormTheme({ theme: "underline" });
     * ```
     */
    export function useFormTheme(options: FormThemeOptions = {}): FormThemeContext {
      const formTheme = useContext(context);
      let { theme, underlineDirection } = options;
      theme = theme ?? formTheme.theme;
      underlineDirection = underlineDirection ?? formTheme.underlineDirection;

      return {
        theme,
        underlineDirection,
      };
    }

    const { Provider } = context;

    export interface FormThemeProviderProps extends FormThemeOptions {
      children: ReactNode;
    }

    /**
     * **Client Component**
     *
     * Since you'll normally want all of your form components to use the same theme,
     * this is a simple way to provide the same theme to all components without
     * needing all the prop-drilling/copying.
     *
     * @example
     * Change Global Theme
     * ```tsx
     * <FormThemeProvider theme="filled" underlineDirection="center">
     *   <RestOfTheApp />
     * </FormThemeProvider>
     * ```
     */
    export function FormThemeProvider(props: FormThemeProviderProps): ReactElement {
      const { theme = "outline", underlineDirection = "left", children } = props;

      const value = useMemo(
        () => ({ theme, underlineDirection }),
        [theme, underlineDirection]
      );

      return <Provider value={value}>{children}</Provider>;
    }