@fidely-ui/react
Version:
Fidely UI is a modern, beautifully crafted React design system powered by Ark UI and Panda CSS, delivering accessible and themeable components for building exceptional web apps
55 lines (54 loc) • 2.26 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { styled, isCssProperty, } from '@fidely-ui/styled-system/jsx';
import { cx } from '@fidely-ui/styled-system/css';
const canForward = (prop, variantKeys, opts = {}) => opts.forwardProps?.includes(prop) ||
(!variantKeys.includes(prop) && !isCssProperty(prop));
/**
* Fidely UI – Style Context Factory
* Provides a root + slot API for building styled components
* around a recipe definition.
*/
export function makeStyleContext(recipe) {
const Ctx = React.createContext(null);
/**
* Root component provider
*/
function withSlotRootProvider(Component) {
const Comp = (props) => {
const [variantProps, rest] = recipe.splitVariantProps(props);
const slots = recipe(variantProps);
return (_jsx(Ctx.Provider, { value: slots, children: _jsx(Component, { ...rest }) }));
};
Comp.displayName = 'FidelyRoot';
return Comp;
}
/**
* Slot that can define and provide its own styles
*/
function withSlotProvider(Component, slot, opts) {
const Styled = styled(Component, {}, {
shouldForwardProp: (prop, variantKeys) => canForward(prop, variantKeys, opts),
});
const Comp = React.forwardRef((props, ref) => {
const [variantProps, rest] = recipe.splitVariantProps(props);
const slots = recipe(variantProps);
return (_jsx(Ctx.Provider, { value: slots, children: _jsx(Styled, { ...rest, ref: ref, className: cx(slots?.[slot], props.className) }) }));
});
Comp.displayName = `FidelySlotProvider(${String(slot)})`;
return Comp;
}
/**
* Slot that consumes styles from context
*/
function withSlotContext(Component, slot) {
const Styled = styled(Component);
const Comp = React.forwardRef((props, ref) => {
const slots = React.useContext(Ctx);
return (_jsx(Styled, { ...props, ref: ref, className: cx(slots?.[slot], props.className) }));
});
Comp.displayName = `FidelySlotConsumer(${String(slot)})`;
return Comp;
}
return { withSlotRootProvider, withSlotProvider, withSlotContext };
}