Skip to content

Instantly share code, notes, and snippets.

@Psvensso
Last active November 28, 2024 08:02
Show Gist options
  • Save Psvensso/19d738585879ce02d2b794a4b776dbb8 to your computer and use it in GitHub Desktop.
Save Psvensso/19d738585879ce02d2b794a4b776dbb8 to your computer and use it in GitHub Desktop.
ReactComponentSnippets.code-snippets
//Source from: chakra-ui/packages/utils/src/react-helpers.ts
import React from "react";
export interface ICreateContextOptions {
/**
* If `true`, React will throw if context is `null` or `undefined`
* In some cases, you might want to support nested context, so you can set it to `false`
*/
strict?: boolean;
/**
* Error message to throw if the context is `undefined`
*/
errorMessage?: string;
/**
* The display name of the context
*/
name?: string;
}
type CreateContextReturn<T> = [React.Provider<T>, () => T, React.Context<T>];
/**
* Creates a named context, provider, and hook.
*
* @param options create context options
*/
export function createContext<ContextType>(
options: ICreateContextOptions = {},
) {
const {
strict = true,
errorMessage = "useContext: `context` is undefined. Seems you forgot to wrap component within the Provider",
name,
} = options;
const Context = React.createContext<ContextType | undefined>(undefined);
Context.displayName = name;
function useContext() {
const context = React.useContext(Context);
if (!context && strict) {
throw new Error(errorMessage);
}
return context;
}
return [
Context.Provider,
useContext,
Context,
] as CreateContextReturn<ContextType>;
}
"Function component with context": {
"prefix": ["compcontext", "cont", "comp"],
"body": [
"import React from \"react\"; ",
"import { createContext } from \"./createContext.ts\";",
"",
"type TProps = {};",
"export function ${TM_FILENAME_BASE:COMPONENT}(p: TUse${TM_FILENAME_BASE:COMPONENT}Args & TProps) {",
"const {} = p;",
"const ctx = useCreate${TM_FILENAME_BASE:COMPONENT}Context(p);",
"",
"return <${TM_FILENAME_BASE:COMPONENT}Provider value={ctx}>${TM_FILENAME_BASE:COMPONENT}</${TM_FILENAME_BASE:COMPONENT}Provider>;",
"};",
"",
"",
"/* EXPORT BELOW CONTENT TO use${TM_FILENAME_BASE:COMPONENT}.ts once done */",
"export type TUse${TM_FILENAME_BASE:COMPONENT}Args = {};",
"export function useCreate${TM_FILENAME_BASE:COMPONENT}Context(args: TUse${TM_FILENAME_BASE:COMPONENT}Args) {",
" return {",
" ...args,",
" };",
"};",
"",
"export type T${TM_FILENAME_BASE:COMPONENT}Context = ReturnType<typeof useCreate${TM_FILENAME_BASE:COMPONENT}Context>;",
"const [${TM_FILENAME_BASE:COMPONENT}Provider, use${TM_FILENAME_BASE:COMPONENT}Context] = createContext<T${TM_FILENAME_BASE:COMPONENT}Context>",
" ({",
" name: \"${TM_FILENAME_BASE:COMPONENT}Context\",",
" errorMessage:",
" \"use${TM_FILENAME_BASE:COMPONENT}Context: `context` is undefined. Seems you forgot to wrap the panel parts in `<${TM_FILENAME_BASE:COMPONENT}Provider />` \", ",
"});",
"",
"export { ${TM_FILENAME_BASE:COMPONENT}Provider, use${TM_FILENAME_BASE:COMPONENT}Context };"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment