@spark-web/checkbox
Version:
--- title: Checkbox storybookPath: forms-checkbox--default isExperimentalPackage: false ---
173 lines (165 loc) • 5.75 kB
JavaScript
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import { ControlLabel } from '@spark-web/control-label';
import { useFieldIds, FieldMessage } from '@spark-web/field';
import { Stack } from '@spark-web/stack';
import { forwardRef } from 'react';
import { css } from '@emotion/css';
import { useFocusRing } from '@spark-web/a11y';
import { Box } from '@spark-web/box';
import { CheckIcon } from '@spark-web/icon';
import { useTheme } from '@spark-web/theme';
import { jsxs, jsx } from 'react/jsx-runtime';
var _excluded$1 = ["size"];
var CheckboxPrimitive = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
var _ref$size = _ref.size,
size = _ref$size === void 0 ? 'small' : _ref$size,
inputProps = _objectWithoutProperties(_ref, _excluded$1);
var theme = useTheme();
var checkboxStyles = useCheckbox(size);
var responsiveStyles = theme.utils.responsiveStyles({
mobile: {
height: theme.typography.text.small.mobile.capHeight
},
tablet: {
height: theme.typography.text.small.tablet.capHeight
}
});
return /*#__PURE__*/jsxs(Box, {
display: "flex",
alignItems: "center",
flexShrink: 0,
className: css(responsiveStyles),
children: [/*#__PURE__*/jsx(Box, _objectSpread(_objectSpread(_objectSpread({}, inputProps), checkboxStyles), {}, {
"aria-checked": inputProps.checked,
"aria-disabled": inputProps.disabled,
ref: forwardedRef,
as: "input",
type: "checkbox"
})), /*#__PURE__*/jsx(CheckIcon, {
size: sizeToScaleKey[size]
})]
});
});
CheckboxPrimitive.displayName = 'CheckboxPrimitive';
var sizeToScaleKey = {
small: 'xxsmall',
medium: 'xsmall'
};
function useCheckbox(size) {
var theme = useTheme();
var focusRingStyles = useFocusRing({
always: true
});
var outerSize = sizeToScaleKey[size];
var transitionProperties = {
transitionProperty: 'color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter',
transitionTimingFunction: theme.animation.standard.easing,
transitionDuration: "".concat(theme.animation.standard.duration, "ms")
};
return {
border: 'field',
borderRadius: 'small',
background: 'surface',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flex: 1,
height: outerSize,
width: outerSize,
position: 'relative',
shadow: 'small',
className: css(_objectSpread(_objectSpread({
appearance: 'none',
verticalAlign: 'text-bottom'
}, transitionProperties), {}, {
'&::before': _objectSpread({
content: '""',
position: 'absolute',
margin: 'auto',
top: 0,
right: 0,
bottom: 0,
left: 0,
height: 0,
width: 0,
overflow: 'hidden'
}, transitionProperties),
'label:hover &:not([disabled], &[aria-disabled=true])': {
borderColor: theme.border.color.primaryHover
},
'& + svg': {
position: 'absolute',
pointerEvents: 'none',
opacity: 0
},
'&:focus': focusRingStyles,
'&:checked': {
background: theme.color.background.primary,
borderColor: theme.border.color.primaryHover,
'+ svg': {
opacity: 1,
stroke: theme.color.foreground.neutralInverted
}
},
'label:hover &:not([disabled], &[aria-disabled=true]):checked': {
// TODO: checkbox gets lighter on hover instead of darker like in the designs, will fix once tokens are revised
background: theme.backgroundInteractions.primaryHover,
border: theme.border.color.fieldAccent
},
'&[disabled]:checked, &[aria-disabled=true]:checked': {
// TODO: using a `border` color for background here as we don't have a token for it just yet
background: theme.border.color.field,
border: theme.border.color.accent,
'+ svg': {
stroke: theme.color.foreground.neutral
}
},
'&[disabled]:checked::before, &[aria-disabled=true]:checked::before': {
background: theme.color.background.fieldAccent
}
}))
};
}
var _excluded = ["children", "data", "disabled", "id", "message", "size", "tone"];
var Checkbox = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
var children = _ref.children,
data = _ref.data,
_ref$disabled = _ref.disabled,
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
idProp = _ref.id,
message = _ref.message,
_ref$size = _ref.size,
size = _ref$size === void 0 ? 'small' : _ref$size,
_ref$tone = _ref.tone,
tone = _ref$tone === void 0 ? 'neutral' : _ref$tone,
inputProps = _objectWithoutProperties(_ref, _excluded);
var _useFieldIds = useFieldIds(idProp),
inputId = _useFieldIds.inputId,
messageId = _useFieldIds.messageId;
var a11yProps = {
'aria-describedby': message && messageId
};
return /*#__PURE__*/jsxs(Stack, {
gap: "small",
children: [/*#__PURE__*/jsx(ControlLabel, {
control: /*#__PURE__*/jsx(CheckboxPrimitive, _objectSpread(_objectSpread(_objectSpread({}, inputProps), a11yProps), {}, {
ref: forwardedRef,
disabled: disabled,
size: size,
id: inputId,
data: data
})),
disabled: disabled,
htmlFor: inputId,
size: size,
children: children
}), message && /*#__PURE__*/jsx(FieldMessage, {
tone: tone,
id: messageId,
message: message
})]
});
});
Checkbox.displayName = 'Checkbox';
export { Checkbox, CheckboxPrimitive };