@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
JavaScript
"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