@spark-web/box
Version:
--- title: Box storybookPath: page-layout-box--default isExperimentalPackage: false ---
342 lines (321 loc) • 12.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var theme = require('@spark-web/theme');
var react = require('react');
var jsxRuntime = require('react/jsx-runtime');
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var css = require('@emotion/css');
var internal = require('@spark-web/utils/internal');
var ts = require('@spark-web/utils/ts');
// prepare context
var backgroundContext = /*#__PURE__*/react.createContext('body');
var InternalBackgroundProvider = backgroundContext.Provider;
var useBackground = function useBackground() {
return react.useContext(backgroundContext);
};
// conditional provider
function renderBackgroundProvider(background, element) {
return background ? /*#__PURE__*/jsxRuntime.jsx(InternalBackgroundProvider, {
value: background,
children: element
}) : element;
}
// a11y contrast utility
var useBackgroundLightness = function useBackgroundLightness(backgroundOverride) {
var backgroundFromContext = useBackground();
var background = backgroundOverride || backgroundFromContext;
var theme$1 = theme.useTheme();
var defaultLightness = theme$1.backgroundLightness.body;
// used by the consumer-facing/external BackgroundProvider
if (background === 'UNKNOWN_DARK') {
return 'dark';
}
if (background === 'UNKNOWN_LIGHT') {
return 'light';
}
return background ? theme$1.backgroundLightness[background] || defaultLightness : defaultLightness;
};
/** Enforce background "lightness" without applying a background color. */
var BackgroundProvider = function BackgroundProvider(_ref) {
var type = _ref.type,
children = _ref.children;
return renderBackgroundProvider(type === 'dark' ? 'UNKNOWN_DARK' : 'UNKNOWN_LIGHT', children);
};
// TODO perf review
// TODO: review responsive props! Now that we're using object syntax, un-mapped properties don't behave as expected
// types
// Hook
// ------------------------------
var useBoxStyles = function useBoxStyles(_ref) {
var alignItems = _ref.alignItems,
alignSelf = _ref.alignSelf,
background = _ref.background,
border = _ref.border,
borderTop = _ref.borderTop,
borderBottom = _ref.borderBottom,
borderLeft = _ref.borderLeft,
borderRight = _ref.borderRight,
borderRadius = _ref.borderRadius,
_ref$borderWidth = _ref.borderWidth,
borderWidth = _ref$borderWidth === void 0 ? 'standard' : _ref$borderWidth,
bottom = _ref.bottom,
cursor = _ref.cursor,
display = _ref.display,
flex = _ref.flex,
flexDirection = _ref.flexDirection,
flexGrow = _ref.flexGrow,
flexShrink = _ref.flexShrink,
flexWrap = _ref.flexWrap,
gap = _ref.gap,
height = _ref.height,
justifyContent = _ref.justifyContent,
left = _ref.left,
margin = _ref.margin,
marginBottom = _ref.marginBottom,
marginLeft = _ref.marginLeft,
marginRight = _ref.marginRight,
marginTop = _ref.marginTop,
marginX = _ref.marginX,
marginY = _ref.marginY,
minHeight = _ref.minHeight,
minWidth = _ref.minWidth,
opacity = _ref.opacity,
overflow = _ref.overflow,
padding = _ref.padding,
paddingBottom = _ref.paddingBottom,
paddingLeft = _ref.paddingLeft,
paddingRight = _ref.paddingRight,
paddingTop = _ref.paddingTop,
paddingX = _ref.paddingX,
paddingY = _ref.paddingY,
position = _ref.position,
right = _ref.right,
shadow = _ref.shadow,
top = _ref.top,
userSelect = _ref.userSelect,
width = _ref.width,
zIndex = _ref.zIndex;
var theme$1 = theme.useTheme();
var unresponsiveProps = {
background: background ? theme$1.color.background[background] : undefined,
boxShadow: shadow ? theme$1.shadow[shadow] : undefined,
cursor: cursor,
minHeight: minHeight,
minWidth: minWidth,
opacity: opacity,
overflow: overflow,
userSelect: userSelect
};
var conditionalBorderStyles = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, border ? {
borderStyle: 'solid',
borderColor: theme$1.utils.mapResponsiveScale(border, theme$1.border.color),
borderWidth: theme$1.utils.mapResponsiveScale(borderWidth, theme$1.border.width)
} : {}), borderTop ? {
borderTopStyle: 'solid',
borderTopColor: theme$1.utils.mapResponsiveScale(borderTop, theme$1.border.color),
borderTopWidth: theme$1.utils.mapResponsiveScale(borderWidth, theme$1.border.width)
} : {}), borderBottom ? {
borderBottomStyle: 'solid',
borderBottomColor: theme$1.utils.mapResponsiveScale(borderBottom, theme$1.border.color),
borderBottomWidth: theme$1.utils.mapResponsiveScale(borderWidth, theme$1.border.width)
} : {}), borderLeft ? {
borderLeftStyle: 'solid',
borderLeftColor: theme$1.utils.mapResponsiveScale(borderLeft, theme$1.border.color),
borderLeftWidth: theme$1.utils.mapResponsiveScale(borderWidth, theme$1.border.width)
} : {}), borderRight ? {
borderRightStyle: 'solid',
borderRightColor: theme$1.utils.mapResponsiveScale(borderRight, theme$1.border.color),
borderRightWidth: theme$1.utils.mapResponsiveScale(borderWidth, theme$1.border.width)
} : {});
return theme$1.utils.resolveResponsiveProps(_objectSpread(_objectSpread(_objectSpread({}, unresponsiveProps), conditionalBorderStyles), {}, {
// allow padding and height/width props to play nice
display: theme$1.utils.mapResponsiveProp(display),
// margin
marginBottom: theme$1.utils.mapResponsiveScale(marginBottom || marginY || margin, theme$1.spacing),
marginTop: theme$1.utils.mapResponsiveScale(marginTop || marginY || margin, theme$1.spacing),
marginLeft: theme$1.utils.mapResponsiveScale(marginLeft || marginX || margin, theme$1.spacing),
marginRight: theme$1.utils.mapResponsiveScale(marginRight || marginX || margin, theme$1.spacing),
// padding
paddingBottom: theme$1.utils.mapResponsiveScale(paddingBottom || paddingY || padding, theme$1.spacing),
paddingTop: theme$1.utils.mapResponsiveScale(paddingTop || paddingY || padding, theme$1.spacing),
paddingLeft: theme$1.utils.mapResponsiveScale(paddingLeft || paddingX || padding, theme$1.spacing),
paddingRight: theme$1.utils.mapResponsiveScale(paddingRight || paddingX || padding, theme$1.spacing),
// border
borderRadius: theme$1.utils.mapResponsiveScale(borderRadius, theme$1.border.radius),
// flex: parent
alignItems: theme$1.utils.mapResponsiveScale(alignItems, flexMap.alignItems),
gap: theme$1.utils.mapResponsiveScale(gap, theme$1.spacing),
flexDirection: theme$1.utils.mapResponsiveScale(flexDirection, flexMap.flexDirection),
justifyContent: theme$1.utils.mapResponsiveScale(justifyContent, flexMap.justifyContent),
flexWrap: theme$1.utils.mapResponsiveProp(flexWrap),
// flex: child
alignSelf: theme$1.utils.mapResponsiveScale(alignSelf, flexMap.alignItems),
flex: theme$1.utils.mapResponsiveProp(flex),
flexGrow: theme$1.utils.mapResponsiveProp(flexGrow),
flexShrink: theme$1.utils.mapResponsiveProp(flexShrink),
// dimension
height: theme$1.utils.mapResponsiveScale(height, theme$1.sizing),
width: theme$1.utils.mapResponsiveScale(width, theme$1.sizing),
// position
position: theme$1.utils.mapResponsiveProp(position),
bottom: theme$1.utils.mapResponsiveProp(bottom),
left: theme$1.utils.mapResponsiveProp(left),
right: theme$1.utils.mapResponsiveProp(right),
top: theme$1.utils.mapResponsiveProp(top),
zIndex: theme$1.utils.mapResponsiveScale(zIndex, theme$1.elevation)
}));
};
// Flex shorthand / adjustments
// ------------------------------
var flexMap = {
alignItems: {
start: 'flex-start',
center: 'center',
end: 'flex-end',
stretch: 'stretch'
},
justifyContent: {
start: 'flex-start',
center: 'center',
end: 'flex-end',
spaceBetween: 'space-between',
stretch: 'stretch'
},
flexDirection: {
row: 'row',
rowReverse: 'row-reverse',
column: 'column',
columnReverse: 'column-reverse'
}
};
var _excluded$1 = ["alignItems", "alignSelf", "background", "border", "borderRadius", "borderWidth", "borderTop", "borderBottom", "borderLeft", "borderRight", "bottom", "cursor", "display", "flex", "flexDirection", "flexGrow", "flexShrink", "flexWrap", "gap", "height", "justifyContent", "left", "margin", "marginBottom", "marginLeft", "marginRight", "marginTop", "marginX", "marginY", "minHeight", "minWidth", "opacity", "overflow", "padding", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "paddingX", "paddingY", "position", "right", "shadow", "top", "userSelect", "width", "zIndex"];
/** Separate the style properties from the element attributes. */
function useBoxProps(props) {
var alignItems = props.alignItems,
alignSelf = props.alignSelf,
background = props.background,
border = props.border,
borderRadius = props.borderRadius,
borderWidth = props.borderWidth,
borderTop = props.borderTop,
borderBottom = props.borderBottom,
borderLeft = props.borderLeft,
borderRight = props.borderRight,
bottom = props.bottom,
cursor = props.cursor,
display = props.display,
flex = props.flex,
flexDirection = props.flexDirection,
flexGrow = props.flexGrow,
flexShrink = props.flexShrink,
flexWrap = props.flexWrap,
gap = props.gap,
height = props.height,
justifyContent = props.justifyContent,
left = props.left,
margin = props.margin,
marginBottom = props.marginBottom,
marginLeft = props.marginLeft,
marginRight = props.marginRight,
marginTop = props.marginTop,
marginX = props.marginX,
marginY = props.marginY,
minHeight = props.minHeight,
minWidth = props.minWidth,
opacity = props.opacity,
overflow = props.overflow,
padding = props.padding,
paddingBottom = props.paddingBottom,
paddingLeft = props.paddingLeft,
paddingRight = props.paddingRight,
paddingTop = props.paddingTop,
paddingX = props.paddingX,
paddingY = props.paddingY,
position = props.position,
right = props.right,
shadow = props.shadow,
top = props.top,
userSelect = props.userSelect,
width = props.width,
zIndex = props.zIndex,
attributes = _objectWithoutProperties(props, _excluded$1);
var styles = useBoxStyles({
alignItems: alignItems,
alignSelf: alignSelf,
background: background,
border: border,
borderRadius: borderRadius,
borderWidth: borderWidth,
borderBottom: borderBottom,
borderLeft: borderLeft,
borderRight: borderRight,
borderTop: borderTop,
bottom: bottom,
cursor: cursor,
display: display,
flex: flex,
flexDirection: flexDirection,
flexGrow: flexGrow,
flexShrink: flexShrink,
flexWrap: flexWrap,
gap: gap,
height: height,
justifyContent: justifyContent,
left: left,
margin: margin,
marginBottom: marginBottom,
marginLeft: marginLeft,
marginRight: marginRight,
marginTop: marginTop,
marginX: marginX,
marginY: marginY,
minHeight: minHeight,
minWidth: minWidth,
opacity: opacity,
overflow: overflow,
padding: padding,
paddingBottom: paddingBottom,
paddingLeft: paddingLeft,
paddingRight: paddingRight,
paddingTop: paddingTop,
paddingX: paddingX,
paddingY: paddingY,
position: position,
right: right,
shadow: shadow,
top: top,
userSelect: userSelect,
width: width,
zIndex: zIndex
});
return {
styles: styles,
attributes: attributes
};
}
var _excluded = ["as", "asElement", "className", "data", "id"];
/** Exposes a prop-based API for adding styles to a view, within the constraints of the theme. */
var Box = ts.forwardRefWithAs(function (_ref, forwardedRef) {
var _ref$as = _ref.as,
Tag = _ref$as === void 0 ? 'div' : _ref$as,
asElement = _ref.asElement,
className = _ref.className,
data = _ref.data,
id = _ref.id,
props = _objectWithoutProperties(_ref, _excluded);
var _useBoxProps = useBoxProps(props),
styles = _useBoxProps.styles,
attributes = _useBoxProps.attributes;
var resetStyles = internal.resetElementStyles(asElement !== null && asElement !== void 0 ? asElement : Tag);
var element = /*#__PURE__*/jsxRuntime.jsx(Tag, _objectSpread(_objectSpread({}, data ? internal.buildDataAttributes(data) : undefined), {}, {
ref: forwardedRef,
id: id,
className: css.cx(css.css(resetStyles), css.css(styles), className)
}, attributes));
return renderBackgroundProvider(props.background, element);
});
exports.BackgroundProvider = BackgroundProvider;
exports.Box = Box;
exports.useBackground = useBackground;
exports.useBackgroundLightness = useBackgroundLightness;