recastui
Version:
Solidjs components library focused on usability, whitelabel theming, accessibility and developer experience
77 lines (65 loc) • 2.35 kB
JavaScript
import { css } from 'goober';
import { mergeProps, splitProps } from 'solid-js';
import { isServer, Dynamic } from 'solid-js/web';
import { get, systemCss } from '../system/index.js';
import { getAllUsedStyleProps, isEmptyObject } from '../utils.js';
import { useTheme } from '../theme/index.js';
/**
* Use the Box component as a layout primitive to add margin, padding, and colors to content.
* @see https://recastui.com/components/box
*/
function Box(props) {
const theme = useTheme();
const withTheme = mergeProps({
as: 'div',
__themeKey: 'variants',
theme
}, props); // Get all used system style props
const usedSystemStylePropNames = getAllUsedStyleProps(props);
const baseStyles = {
boxSizing: 'border-box',
margin: 0,
minWidth: 0
};
const [__themeKey, __css, variant, sxProp, systemStyleProps, otherProps] = splitProps(withTheme, ['__themeKey'], ['__css'], ['variant'], ['sx'], usedSystemStylePropNames);
const variantInTheme = get(theme, `${__themeKey}.${variant}`) || get(theme, variant);
/*
* Style injection order (first to last)
* - class prop (least specific)
* - baseStyle
* - variants
* - __css
* - styled system props
* - sx (override all)
*/
const baseStylesClass = css(systemCss(baseStyles)(theme));
const variantStyles = variantInTheme && systemCss(variantInTheme)(theme);
const __cssStylesStyles = systemCss(__css)(theme);
const systemPropsStyles = systemCss(systemStyleProps)(theme);
const sxPropStyles = systemCss(sxProp)(theme);
const clone = mergeProps(otherProps, {
get class() {
return [otherProps.class, baseStylesClass, ...[variantStyles, __cssStylesStyles, systemPropsStyles, sxPropStyles].map(styles => styles && !isEmptyObject(styles) ? css(styles) : '')].filter(Boolean).join(' ');
}
});
const [local, newProps] = splitProps(clone, ['as', 'theme']);
let component;
if (typeof local.as === 'function') {
component = local.as(newProps);
} else if (isServer) {
const [children, others] = splitProps(newProps, ['children']);
component = Dynamic({
component: local.as,
get children() {
return children;
},
...others
});
} else {
component = Dynamic(mergeProps({
component: local.as
}, newProps));
}
return component;
}
export { Box };