UNPKG

recastui

Version:

Solidjs components library focused on usability, whitelabel theming, accessibility and developer experience

77 lines (65 loc) 2.35 kB
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 };