UNPKG

woby

Version:

A high-performance framework with fine-grained observable/signal-based reactivity for building rich applications.

160 lines (107 loc) 4.76 kB
# Context API Documentation The Context API in Woby provides a way to pass data through the component tree without having to pass props down manually at every level. It's especially useful for global data like themes, user authentication, or preferred language. ## Table of Contents - [createContext](#createcontext) - [useContext](#usecontext) - [useMountedContext](#usemountedcontext) - [Custom Element Context Support](#custom-element-context-support) ## createContext Creates a context object that can be used to pass data through the component tree. ### Syntax ```typescript const Context = createContext<T>(defaultValue?: T) ``` ### Parameters - `defaultValue` (optional): The default value for the context when no Provider is found in the component tree. ### Returns A context object with: - `Provider`: A component that allows consuming components to subscribe to context changes - `symbol`: A unique symbol used internally for context identification ### Example ```tsx import { createContext, useContext } from 'woby' // Create a context with a default value const ThemeContext = createContext('light') // Create a context without a default value const UserContext = createContext<User | undefined>(undefined) // Use the Provider to pass a value down the tree const App = () => ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ) // Consume the context value in a component const ThemedButton = () => { const theme = useContext(ThemeContext) return <button className={theme}>Themed Button</button> } ``` ## useContext Accesses the current value of a context within a functional component. ### Syntax ```typescript const value = useContext(Context) ``` ### Parameters - `Context`: The context object created by `createContext` ### Returns - The current context value from the nearest Provider above the calling component - The default value if no Provider is found - `undefined` if no Provider is found and no default value was specified ### Example ```tsx const ThemeContext = createContext('light') const ThemedButton = () => { const theme = useContext(ThemeContext) return <button className={`theme-${theme}`}>Click me</button> } ``` ## useMountedContext A specialized hook that provides context values for components with special support for custom elements. This hook works in both JSX/TSX components and custom elements defined in HTML. ### Syntax ```typescript // Without ref parameter (returns [context, mount]) const [context, mount] = useMountedContext(Context) // With existing ref parameter (returns only context) const context = useMountedContext(Context, ref) ``` ### Parameters - `Context`: The context object created by `createContext` - `ref` (optional): An existing observable ref to use ### Returns - When called without `ref`: A tuple containing the context value and a mounting placeholder comment element - When called with `ref`: Only the context value ### Example ```tsx // Usage in custom elements (returns [context, mounting placeholder]) const CounterContext = createContext<number>(0) const [context, mount] = useMountedContext(CounterContext) return <div>{mount}Context value: {context}</div> // Usage with existing ref (returns only context) const myRef = $<HTMLDivElement>() const context = useMountedContext(CounterContext, myRef) return <div ref={myRef}>Context value: {context}</div> ``` ## Custom Element Context Support Custom elements created with Woby's `customElement` function have special support for context. The context value is stored on the first child node of the parent element and can be accessed by child custom elements. ### How it works 1. When a context Provider is used, the context value is stored on the first child node of the parent element 2. Child custom elements can access this context value using `useMountedContext` 3. The context lookup traverses up the DOM tree to find the nearest context provider ### Example ```tsx // Create a context const ValueContext = createContext(0) // Create a custom element that uses context const ValueDisplay = defaults(() => ({}), () => { const [context, mount] = useMountedContext(ValueContext) return <div>{mount}Value: {context}</div> }) customElement('value-display', ValueDisplay) // Usage in HTML: // <value-context-provider value="42"> // <value-display></value-display> // </value-context-provider> ``` ### Context in Shadow DOM For custom elements using Shadow DOM, the context lookup traverses through shadow boundaries and slots to find the nearest context provider in the light DOM.