utils.tsx 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import {createContext, useContext} from 'react';
  2. type CreateContextReturn<T> = [React.Provider<T>, () => T, React.Context<T>];
  3. /*
  4. * Creates provider, context and useContext hook, guarding against calling useContext without a provider.
  5. * [0]: https://github.com/chakra-ui/chakra-ui/blob/c0f9c287df0397e2aa9bd90eb3d5c2f2c08aa0b1/packages/utils/src/react-helpers.ts#L27
  6. *
  7. * Renamed to createDefinedContext to not conflate with React context.
  8. */
  9. export function createDefinedContext<ContextType>(options: {
  10. name: string;
  11. errorMessage?: string;
  12. strict?: boolean;
  13. }) {
  14. const {
  15. strict = true,
  16. errorMessage = `useContext for "${options.name}" must be inside a Provider with a value`,
  17. name,
  18. } = options;
  19. const Context = createContext<ContextType | undefined>(undefined);
  20. Context.displayName = name;
  21. function useDefinedContext() {
  22. const context = useContext(Context);
  23. if (!context && strict) {
  24. throw new Error(errorMessage);
  25. }
  26. return context;
  27. }
  28. return [
  29. Context.Provider,
  30. useDefinedContext,
  31. Context,
  32. ] as CreateContextReturn<ContextType>;
  33. }