UNPKG

@cerberus-design/react

Version:

The Cerberus Design React component library.

126 lines (123 loc) 4.47 kB
import { jsx } from 'react/jsx-runtime'; import { ark } from '../node_modules/.pnpm/@ark-ui_react@5.29.1_react-dom@19.2.1_react@19.2.1__react@19.2.1/node_modules/@ark-ui/react/dist/components/factory.js'; import { cerberus } from 'styled-system/jsx/factory'; import { cx, css } from 'styled-system/css'; import { forwardRef } from 'react'; class CerberusPrimitive { recipe; constructor(recipe) { this.recipe = recipe ?? null; } hasStyles(styles) { if (styles) { return { className: styles }; } return {}; } setupStyledComponent(component) { const arkComponent = ark[component]; if (typeof component !== "string") { return cerberus(component); } if (arkComponent) { return cerberus(arkComponent); } throw new Error(`Unknown component: ${component}`); } /** * Creates a Cerberus component with bare features and no recipe. * @param Component - The React component to enhance with Cerberus features. * Can be a string or a component reference. * @returns A new React component that applies Cerberus features to the * original component. * * @example * ```ts * const { withNoRecipe } = createCerberusPrimitive(buttonRecipe) * const Button = withNoRecipe('button') * ``` */ withNoRecipe = (Component, options) => { const { defaultProps } = options || {}; const El = this.setupStyledComponent(Component); const CerbComponent = (props) => { return /* @__PURE__ */ jsx(El, { ...defaultProps, ...props }); }; const ElName = typeof El === "string" ? El : El.displayName || El.name; CerbComponent.displayName = `Cerberus.${ElName}`; return CerbComponent; }; /** * Creates a Cerberus component with the given recipe. * @param Component - The React component to enhance with the recipe. * @param options - Options for the recipe. * @returns A new React component that applies the recipe to the original * component. */ withRecipe = (Component, options) => { const { defaultProps } = options || {}; const El = this.setupStyledComponent(Component); const recipe = this.recipe; const CerbComponent = forwardRef( (internalProps, ref) => { const { css: customCss, ...restOfInternalProps } = internalProps; const [variantOptions, nativeProps] = recipe.splitVariantProps(restOfInternalProps); const recipeStyles = recipe(variantOptions); const className = typeof nativeProps.className === "string" ? nativeProps.className : void 0; return /* @__PURE__ */ jsx( El, { ...defaultProps, ...nativeProps, ref, className: cx(className, recipeStyles, css(customCss)) } ); } ); const ElName = typeof El === "string" ? El : El.displayName || El.name; CerbComponent.displayName = ElName; return CerbComponent; }; /** * Creates a Cerberus component with a slot recipe applied. * @param Component - The React component to enhance with Cerberus features. * @param recipe - The slot recipe to apply to the component. * @returns A new React component that applies Cerberus features and the * specified slot recipe to the original component. * @example * ```typescript * const { withSlotRecipe } = createCerberusPrimitive(field) * const Field = withSlotRecipe(RawField, field) * ``` */ withSlotRecipe = (Component, slot, options) => { const { defaultProps } = options || {}; const El = this.setupStyledComponent(Component); const recipe = this.recipe; const CerbComponent = forwardRef( (internalProps, ref) => { const { css: customCss, ...restOfInternalProps } = internalProps; const [variantOptions, nativeProps] = recipe.splitVariantProps(restOfInternalProps); const styles = recipe(variantOptions); const slotStyles = styles[slot]; const className = typeof nativeProps.className === "string" ? nativeProps.className : void 0; return /* @__PURE__ */ jsx( El, { ...defaultProps, ...nativeProps, ref, className: cx(className, slotStyles, css(customCss)) } ); } ); const ElName = typeof El === "string" ? El : El.displayName || El.name; CerbComponent.displayName = ElName; return CerbComponent; }; } export { CerberusPrimitive };