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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 'use client' import { cx, css, sva } from '../css/index.mjs'; import { styled } from './factory.mjs'; import { getDisplayName } from './factory-helper.mjs'; import { createContext, useContext, createElement, forwardRef } from 'react' function createSafeContext(contextName) { const Context = createContext(undefined) const useStyleContext = (componentName, slot) => { const context = useContext(Context) if (context === undefined) { const componentInfo = componentName ? `Component "${componentName}"` : 'A component' const slotInfo = slot ? ` (slot: "${slot}")` : '' throw new Error( `${componentInfo}${slotInfo} cannot access ${contextName} because it's missing its Provider.` ) } return context } return [Context, useStyleContext] } export function createStyleContext(recipe) { const isConfigRecipe = '__recipe__' in recipe const recipeName = isConfigRecipe && recipe.__name__ ? recipe.__name__ : undefined const contextName = recipeName ? `createStyleContext("${recipeName}")` : 'createStyleContext' const [StyleContext, useStyleContext] = createSafeContext(contextName) const svaFn = isConfigRecipe ? recipe : sva(recipe.config) const getResolvedProps = (props, slotStyles) => { const { unstyled, ...restProps } = props if (unstyled) return restProps if (isConfigRecipe) { return { ...restProps, className: cx(slotStyles, restProps.className) } } return { ...slotStyles, ...restProps } } const withRootProvider = (Component, options) => { const WithRootProvider = (props) => { const [variantProps, otherProps] = svaFn.splitVariantProps(props) const slotStyles = isConfigRecipe ? svaFn(variantProps) : svaFn.raw(variantProps) slotStyles._classNameMap = svaFn.classNameMap const mergedProps = options?.defaultProps ? { ...options.defaultProps, ...otherProps } : otherProps return createElement(StyleContext.Provider, { value: slotStyles, children: createElement(Component, mergedProps) }) } const componentName = getDisplayName(Component) WithRootProvider.displayName = `withRootProvider(${componentName})` return WithRootProvider } const withProvider = (Component, slot, options) => { const StyledComponent = styled(Component, {}, options) const WithProvider = forwardRef((props, ref) => { const [variantProps, restProps] = svaFn.splitVariantProps(props) const slotStyles = isConfigRecipe ? svaFn(variantProps) : svaFn.raw(variantProps) slotStyles._classNameMap = svaFn.classNameMap const propsWithClass = { ...restProps, className: restProps.className ?? options?.defaultProps?.className } const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot]) return createElement(StyleContext.Provider, { value: slotStyles, children: createElement(StyledComponent, { ...resolvedProps, className: cx(resolvedProps.className, slotStyles._classNameMap[slot]), ref, }) }) }) const componentName = getDisplayName(Component) WithProvider.displayName = `withProvider(${componentName})` return WithProvider } const withContext = (Component, slot, options) => { const StyledComponent = styled(Component, {}, options) const componentName = getDisplayName(Component) const WithContext = forwardRef((props, ref) => { const slotStyles = useStyleContext(componentName, slot) const propsWithClass = { ...props, className: props.className ?? options?.defaultProps?.className } const resolvedProps = getResolvedProps(propsWithClass, slotStyles[slot]) return createElement(StyledComponent, { ...resolvedProps, className: cx(resolvedProps.className, slotStyles._classNameMap[slot]), ref, }) }) WithContext.displayName = `withContext(${componentName})` return WithContext } return { withRootProvider, withProvider, withContext, } } |