UNPKG

react-class-variants

Version:

Type-safe React variants API for dynamic CSS class composition

229 lines (225 loc) 8.32 kB
"use strict"; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { defineConfig: () => defineConfig }); module.exports = __toCommonJS(index_exports); var import_react2 = require("react"); // src/utils.ts var import_react = require("react"); function hasOwnProperty(object, prop) { if (typeof Object.hasOwn === "function") { return Object.hasOwn(object, prop); } return Object.prototype.hasOwnProperty.call(object, prop); } function isValidElementWithRef(element) { if (!element) return false; if (!(0, import_react.isValidElement)(element)) return false; if ("ref" in element.props) return true; if ("ref" in element) return true; return false; } function getRefProperty(element) { if (!isValidElementWithRef(element)) return null; const props = __spreadValues({}, element.props); return props.ref || element.ref; } function setRef(ref, value) { if (typeof ref === "function") { ref(value); } else if (ref) { ref.current = value; } } function mergeProps(base, overrides) { const props = __spreadValues({}, base); for (const key in overrides) { if (!hasOwnProperty(overrides, key)) continue; if (key === "className") { const prop = "className"; props[prop] = base[prop] ? `${base[prop]} ${overrides[prop]}` : overrides[prop]; continue; } if (key === "style") { const prop = "style"; props[prop] = base[prop] ? __spreadValues(__spreadValues({}, base[prop]), overrides[prop]) : overrides[prop]; continue; } const overrideValue = overrides[key]; if (typeof overrideValue === "function" && key.startsWith("on")) { const baseValue = base[key]; if (typeof baseValue === "function") { props[key] = (...args) => { overrideValue(...args); baseValue(...args); }; continue; } } props[key] = overrideValue; } return props; } function useMergeRefs(...refs) { return (0, import_react.useMemo)(() => { if (!refs.some(Boolean)) return; return (value) => { for (const ref of refs) { setRef(ref, value); } }; }, refs); } // src/index.ts function defineConfig(options) { const { onClassesMerged } = options != null ? options : {}; function mergeClassNames(...classNames) { const flattened = classNames.flat(Infinity); const filtered = flattened.filter((cls) => Boolean(cls)); const joined = filtered.join(" "); return onClassesMerged ? onClassesMerged(joined) : joined; } function variants(config) { const { base, variants: variants2, compoundVariants, defaultVariants } = config; if (!("variants" in config) || !config.variants) { return (props) => mergeClassNames(base, props == null ? void 0 : props.className); } function isBooleanVariant(name) { const variant = variants2 == null ? void 0 : variants2[name]; return variant && ("false" in variant || "true" in variant); } return function(...[props]) { var _a; const result = [base]; const getSelectedVariant = (name) => { var _a2, _b; return (_b = (_a2 = props == null ? void 0 : props[name]) != null ? _a2 : defaultVariants == null ? void 0 : defaultVariants[name]) != null ? _b : isBooleanVariant(name) ? false : void 0; }; for (let name in variants2) { const selected = getSelectedVariant(name); if (selected !== void 0) result.push((_a = variants2[name]) == null ? void 0 : _a[selected]); } for (let { variants: variants3, className } of compoundVariants != null ? compoundVariants : []) { let isSelectedVariant2 = function(name) { const selected = getSelectedVariant(name); const cvSelector = variants3[name]; return Array.isArray(cvSelector) ? cvSelector.includes(selected) : selected === cvSelector; }; var isSelectedVariant = isSelectedVariant2; if (Object.keys(variants3).every(isSelectedVariant2)) { result.push(className); } } if (props == null ? void 0 : props.className) { result.push(props.className); } return mergeClassNames(result); }; } function variantPropsResolver(config) { const _a = config, { forwardProps, withoutRenderProp } = _a, variantsConfig = __objRest(_a, ["forwardProps", "withoutRenderProp"]); const variantsResolver = variants(variantsConfig); return function(props) { const result = __spreadValues({}, props); const onlyVariantProps = { className: result.className }; if (config.variants) { for (const variantKey in config.variants) { if (hasOwnProperty(config.variants, variantKey) && hasOwnProperty(result, variantKey)) { onlyVariantProps[variantKey] = result[variantKey]; if (!forwardProps || !forwardProps.includes(variantKey)) { delete result[variantKey]; } } } } result.className = variantsResolver(onlyVariantProps); return result; }; } function variantComponent(elementType, config) { const { withoutRenderProp } = config; const resolveProps = variantPropsResolver(config); if (typeof elementType !== "string" || withoutRenderProp) { return ((props) => { return (0, import_react2.createElement)(elementType, resolveProps(props)); }); } const component = ((props) => { const _a = props, { render } = _a, rest = __objRest(_a, ["render"]); const mergedRef = useMergeRefs( rest.ref, getRefProperty(render) ); const resolvedProps = resolveProps(rest); if (render) { if ((0, import_react2.isValidElement)(render)) { const renderProps = __spreadProps(__spreadValues({}, render.props), { ref: mergedRef }); return (0, import_react2.cloneElement)(render, mergeProps(resolvedProps, renderProps)); } else { return render(resolvedProps); } } return (0, import_react2.createElement)(elementType, __spreadProps(__spreadValues({}, resolvedProps), { ref: mergedRef })); }); return component; } return { variants, variantPropsResolver, variantComponent }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { defineConfig });