UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

232 lines (228 loc) • 8.98 kB
"use client"; import { createContext as createContext$1 } from "../../utils/context.js"; import { utils_exports } from "../../utils/index.js"; import { useSystem } from "../system/system-provider.js"; import { styled } from "../system/factory.js"; import { chainProps, mergeProps } from "./props.js"; import { getSlotClassName, mergeSlotCSS, useComponentSlotStyle, useComponentStyle } from "./use-component-style.js"; import { getClassName, getDisplayName } from "./utils.js"; import { Fragment } from "react"; import { jsx } from "react/jsx-runtime"; //#region src/core/components/create-component.tsx function createProxyComponent(el, { shouldStyleProps,...options } = {}) { options.shouldForwardProp ??= (0, utils_exports.isFunction)(el); shouldStyleProps ??= !(0, utils_exports.isFunction)(el); if (el === "fragment") el = Fragment; if (shouldStyleProps || (0, utils_exports.isString)(el)) { const ProxyComponent = styled(el, options); ProxyComponent.displayName = "ProxyComponent"; return ProxyComponent; } else { el.displayName ??= "ProxyComponent"; return el; } } function withDisplayName(Component, displayName) { Object.defineProperty(Component, "name", { value: displayName }); Object.defineProperty(Component, "displayName", { value: displayName }); return Component; } function getSlotKey(slot) { if (!slot) return "unknown"; if ((0, utils_exports.isArray)(slot) || !(0, utils_exports.isObject)(slot)) return (0, utils_exports.toCamelCase)((0, utils_exports.toArray)(slot).join("-")); else return (0, utils_exports.toCamelCase)(slot.name); } function getSlotName(slot) { if (!slot) return ""; if ((0, utils_exports.isArray)(slot)) return slot.map((value) => (0, utils_exports.toPascalCase)(value)).join(""); else if ((0, utils_exports.isObject)(slot)) return (0, utils_exports.toPascalCase)(slot.name); else return (0, utils_exports.toPascalCase)(slot); } function createComponent(name, style) { const defaultClassName = style?.className; const defaultDisplayName = getDisplayName(name); const [ComponentContext, useComponentContext] = createContext$1({ name: `${defaultDisplayName}Context` }); const [PropsContext, usePropsContext] = createContext$1({ name: `${defaultDisplayName}PropsContext`, strict: false }); function useClassName(name$1, className) { const system = useSystem(); className = (0, utils_exports.runIfFn)(className, system); className ??= getClassName(name$1, defaultClassName)(system); return className; } function useComponentProps(props, { className, withContext: withContext$1 = true, transferProps } = {}) { const system = useSystem(); className = (0, utils_exports.runIfFn)(className, system); className ??= defaultClassName; className ??= getClassName(name)(system); const contextProps = usePropsContext() ?? {}; const [, rest] = useComponentStyle(withContext$1 ? mergeProps(contextProps, props)() : props, { className, style, transferProps }); return rest; } function component(el, { name: name$1, className,...options } = {}) { const displayName = getDisplayName(name$1, defaultDisplayName); const ProxyComponent = createProxyComponent(el, options); return function(...superProps) { return withDisplayName((props) => { className = useClassName(name$1, className); const mergedProps = chainProps(...superProps)()(props); return /* @__PURE__ */ jsx(ProxyComponent, { ...mergedProps, className: (0, utils_exports.cx)(className, mergedProps.className) }); }, displayName); }; } function withContext(el, { name: name$1, className, withContext: withContext$1, transferProps,...options } = {}) { const displayName = getDisplayName(name$1, defaultDisplayName); const ProxyComponent = createProxyComponent(el, options); return function(initialProps, ...superProps) { return withDisplayName((props) => { className = useClassName(name$1, className); const mergedProps = useComponentProps((0, utils_exports.isFunction)(initialProps) ? initialProps(props) : mergeProps(initialProps ?? {}, props)(), { className, withContext: withContext$1, transferProps }); return /* @__PURE__ */ jsx(ProxyComponent, { ...chainProps(...(0, utils_exports.toArray)(superProps))()(mergedProps) }); }, displayName); }; } return { component, ComponentContext, PropsContext, useComponentContext, usePropsContext, withContext, useComponentProps }; } function createSlotComponent(rootName, style) { const rootClassName = style?.className; const rootDisplayName = getDisplayName(rootName); const classNameMap = /* @__PURE__ */ new Map(); const [StyleContext, useStyleContext] = createContext$1({ name: `${rootDisplayName}StyleContext` }); const [ComponentContext, useComponentContext] = createContext$1({ name: `${rootDisplayName}Context` }); const [PropsContext, usePropsContext] = createContext$1({ name: `${rootDisplayName}PropsContext`, strict: false }); function useClassName(slot, className) { const system = useSystem(); className = (0, utils_exports.runIfFn)(className, system); className ??= getSlotClassName(rootClassName ?? getClassName(rootName)(system), slot); return className; } function useClassNames() { const system = useSystem(); const entries = classNameMap.entries().map(([key, { className, slot }]) => { className = (0, utils_exports.runIfFn)(className, system); className ??= getSlotClassName(rootClassName ?? getClassName(rootName)(system), slot); return [key, className]; }); return Object.fromEntries(entries.filter(([_, className]) => className)); } function useRootComponentProps(props, slot, { className, withContext: withContext$1 = true, transferProps } = {}) { className = useClassName(slot, className); const contextProps = usePropsContext() ?? {}; const [css, rest] = useComponentSlotStyle(withContext$1 ? mergeProps(contextProps, props)() : props, { className, style, slot, transferProps }); return [css, rest]; } function useSlotComponentProps(props, slot, { className } = {}) { className = useClassName(slot, className); const style$1 = useStyleContext(); return { ...props, className: (0, utils_exports.cx)(className, props.className), css: mergeSlotCSS(slot, style$1, props.css) }; } function component(el, slot, { name, className,...options } = {}) { const ProxyComponent = createProxyComponent(el, options); const slotKey = getSlotKey(slot); const displayName = getDisplayName(name, `${rootDisplayName}${getSlotName(slot)}`); classNameMap.set(slotKey, { className, slot }); return function(...superProps) { return withDisplayName((props) => { className = useClassName(slot, className); const mergedProps = chainProps(...superProps)()(props); return /* @__PURE__ */ jsx(ProxyComponent, { ...mergedProps, className: (0, utils_exports.cx)(className, mergedProps.className) }); }, displayName); }; } function withProvider(el, slot = "root", { name, className, withContext: withContext$1, transferProps,...options } = {}) { const ProxyComponent = createProxyComponent(el, options); const slotKey = getSlotKey(slot); const displayName = getDisplayName(name, `${rootDisplayName}${getSlotName(slot)}`); classNameMap.set(slotKey, { className, slot }); return function(initialProps, ...superProps) { return withDisplayName((props) => { const [context, mergedProps] = useRootComponentProps((0, utils_exports.isFunction)(initialProps) ? initialProps(props) : mergeProps(initialProps ?? {}, props)(), slot, { className, withContext: withContext$1, transferProps }); return /* @__PURE__ */ jsx(StyleContext, { value: context, children: /* @__PURE__ */ jsx(ProxyComponent, { ...chainProps(...superProps)()(mergedProps) }) }); }, displayName); }; } function withContext(el, slot, { name, className, withContext: withContext$1,...options } = {}) { const ProxyComponent = createProxyComponent(el, options); const slotKey = getSlotKey(slot); const displayName = getDisplayName(name, `${rootDisplayName}${getSlotName(slot)}`); classNameMap.set(slotKey, { className, slot }); return function(initialProps, ...superProps) { return withDisplayName((props) => { const mergedProps = useSlotComponentProps((0, utils_exports.isFunction)(initialProps) ? initialProps(props) : mergeProps(initialProps ?? {}, props)(), slot, { className, withContext: withContext$1 }); return /* @__PURE__ */ jsx(ProxyComponent, { ...chainProps(...superProps)()(mergedProps) }); }, displayName); }; } return { component, ComponentContext, PropsContext, StyleContext, useClassNames, useComponentContext, usePropsContext, useStyleContext, withContext, withProvider, useRootComponentProps, useSlotComponentProps }; } //#endregion export { createComponent, createSlotComponent }; //# sourceMappingURL=create-component.js.map