UNPKG

orcs-design-system

Version:
386 lines (381 loc) 15.6 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; const _excluded = ["name", "label", "colour", "variant", "disabled", "checked", "onClick", "onChange", "theme", "ariaLabel"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React, { useRef } from "react"; import PropTypes from "prop-types"; import styled, { keyframes, ThemeProvider } from "styled-components"; import { space, layout, typography, variant } from "styled-system"; import { themeGet } from "@styled-system/theme-get"; import { pick } from "lodash"; // Utility function to create checkbox variant configs import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const createCheckboxVariants = colorMap => { return { default: colorMap.default, success: colorMap.success, warning: colorMap.warning, danger: colorMap.danger, primary: colorMap.primary, white: colorMap.white }; }; // Color mappings for different checkbox parts const getCheckboxColors = props => ({ default: themeGet("colors.greyDarker")(props), success: themeGet("colors.success")(props), warning: themeGet("colors.warning")(props), danger: themeGet("colors.danger")(props), primary: themeGet("colors.primary")(props), white: themeGet("colors.white")(props) }); const getCheckboxFocusColors = props => ({ default: themeGet("colors.black20")(props), success: themeGet("colors.success30")(props), warning: themeGet("colors.warning30")(props), danger: themeGet("colors.danger30")(props), primary: themeGet("colors.primary30")(props), white: themeGet("colors.white30")(props) }); /* Animations */ const checkboxOn = /*#__PURE__*/keyframes(["0%{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,15px 2px 0 11px;}50%{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,20px 2px 0 11px;}100%{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,20px -12px 0 11px;}"]); const checkboxOff = /*#__PURE__*/keyframes(["0%{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,20px -12px 0 11px,0 0 0 0 inset;}25%{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,20px -12px 0 11px,0 0 0 0 inset;}50%{transform:rotate(45deg);margin-top:-4px;margin-left:6px;width:0px;height:0px;box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,15px 2px 0 11px,0 0 0 0 inset;}51%{transform:rotate(0deg);margin-top:-2px;margin-left:-2px;width:20px;height:20px;box-shadow:0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0px 0px 0 10px inset;}100%{transform:rotate(0deg);margin-top:-2px;margin-left:-2px;width:20px;height:20px;box-shadow:0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0px 0px 0 0px inset;}"]); const Item = /*#__PURE__*/styled.div.withConfig({ displayName: "Item", componentId: "sc-p4d19b-0" })(["", " ", " display:block;transform:translateZ(0);color:", ";"], space, layout, props => { const colors = getCheckboxColors(props); return props.variant === "white" ? colors.white : colors.default; }); const Label = /*#__PURE__*/styled.label.withConfig({ displayName: "Label", componentId: "sc-p4d19b-1" })(["display:flex;align-items:center;cursor:", ";opacity:", ";"], props => props.disabled ? "default" : "pointer", props => props.disabled ? "0.5" : "1"); const Control = /*#__PURE__*/styled.input.attrs({ type: "checkbox" }).withConfig({ displayName: "Control", componentId: "sc-p4d19b-2" })(["opacity:0;position:absolute;margin:0;z-index:-1;width:0;height:0;overflow:hidden;pointer-events:none;&:focus{+ div{border-radius:2px;", "}}+ div{transition:", ";&::before{", "}> div{", "}}&:focus + div div::after{opacity:0.2;}&:checked{+ div div::before{box-shadow:0 0 0 10px,10px -10px 0 10px,32px 0px 0 20px,0px 32px 0 20px,-5px 5px 0 10px,20px -12px 0 11px;.animate&{animation:", " 300ms forwards ease-out;}}}&:not(:checked) + div div::before{.animate&{animation:", " 300ms forwards ease-out;}}"], props => { const shadow = themeGet("shadows.thickOutline")(props); const focusColors = getCheckboxFocusColors(props); return variant({ variants: createCheckboxVariants({ default: { boxShadow: "".concat(shadow, " ").concat(focusColors.default) }, success: { boxShadow: "".concat(shadow, " ").concat(focusColors.success) }, warning: { boxShadow: "".concat(shadow, " ").concat(focusColors.warning) }, danger: { boxShadow: "".concat(shadow, " ").concat(focusColors.danger) }, primary: { boxShadow: "".concat(shadow, " ").concat(focusColors.primary) }, white: { boxShadow: "".concat(shadow, " ").concat(focusColors.white) } }) })(props); }, themeGet("transition.transitionDefault"), props => { const colors = getCheckboxColors(props); return variant({ variants: createCheckboxVariants({ default: { backgroundColor: colors.default }, success: { backgroundColor: colors.success }, warning: { backgroundColor: colors.warning }, danger: { backgroundColor: colors.danger }, primary: { backgroundColor: colors.primary }, white: { backgroundColor: colors.white } }) })(props); }, props => { const colors = getCheckboxColors(props); return variant({ variants: createCheckboxVariants({ default: { color: colors.default }, success: { color: colors.success }, warning: { color: colors.warning }, danger: { color: colors.danger }, primary: { color: colors.primary }, white: { color: colors.white } }) })(props); }, checkboxOn, checkboxOff); const Box = /*#__PURE__*/styled.div.withConfig({ displayName: "Box", componentId: "sc-p4d19b-3" })(["position:relative;height:20px;width:20px;&::before{content:\"\";display:block;position:absolute;left:8px;top:8px;height:4px;width:4px;border-radius:100%;z-index:1;opacity:0;margin:0;pointer-events:none;background-color:", ";}"], props => themeGet("colors.black50")(props)); const Check = /*#__PURE__*/styled.div.withConfig({ displayName: "Check", componentId: "sc-p4d19b-4" })(["position:relative;display:inline-block;width:20px;height:20px;border:2px solid;border-radius:", ";overflow:hidden;z-index:1;color:", ";", " &::before{content:\"\";position:absolute;transform:rotate(45deg);display:block;margin-top:-4px;margin-left:6px;width:0;height:0;box-shadow:0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0,0 0 0 0 inset;@media not all and (min-resolution:0.001dpcm){@supports (-webkit-appearance:none){width:1px;height:1px;}}}"], props => themeGet("radii.1")(props), props => themeGet("colors.greyDarker")(props), props => { const colors = getCheckboxColors(props); return variant({ variants: createCheckboxVariants({ default: { color: colors.default }, success: { color: colors.success }, warning: { color: colors.warning }, danger: { color: colors.danger }, primary: { color: colors.primary }, white: { color: colors.white } }) })(props); }); const Text = /*#__PURE__*/styled.div.withConfig({ displayName: "Text", componentId: "sc-p4d19b-5" })(["font-size:", ";padding-left:8px;", ""], props => themeGet("fontSizes.2")(props), typography); /** * The default checkbox (or inverted if on dark background) should be used for the majority of the UI; however, the coloured ones can be used in situations where the colour corresponds with some indication of status, e.g. in a task list, green could denote task completed, red could denote task overdue. */ export default function Checkbox(_ref) { let { name, label, colour, variant: variantProp, disabled, checked, onClick, onChange, theme, ariaLabel } = _ref, props = _objectWithoutProperties(_ref, _excluded); const inputRef = useRef(null); // Support both colour (legacy) and variant props for backward compatibility const variant = variantProp || colour || "default"; // Warn if using deprecated colour prop if (colour && !variantProp) { if (process.env.NODE_ENV !== "production") { console.warn("Checkbox: The `colour` prop is deprecated. Please use `variant` instead. `colour` will be removed in a future version."); } } const handleClick = () => { if (!inputRef.current || disabled) { return; } inputRef.current.classList.add("animate"); }; const handleAnimationEnd = () => { if (!inputRef.current || disabled) { return; } inputRef.current.classList.remove("animate"); }; const component = /*#__PURE__*/_jsx(Item, _objectSpread(_objectSpread({ variant: variant }, props), {}, { onClick: handleClick, onAnimationEnd: handleAnimationEnd, children: /*#__PURE__*/_jsxs(Label, { disabled: disabled, children: [/*#__PURE__*/_jsx(Control, { name: name, variant: variant, disabled: disabled, checked: checked, onChange: onChange, ref: inputRef, "aria-label": ariaLabel }), /*#__PURE__*/_jsx(Box, { variant: variant, onClick: onClick, children: /*#__PURE__*/_jsx(Check, { variant: variant }) }), /*#__PURE__*/_jsx(Text, _objectSpread(_objectSpread({}, pick(props, typography.propNames)), {}, { children: label }))] }) })); return theme ? /*#__PURE__*/_jsx(ThemeProvider, { theme: theme, children: component }) : component; } Checkbox.propTypes = { /** Sets the colour of the checkbox. Colours used are the design system standard colours. @deprecated Use `variant` instead. */ colour: PropTypes.oneOf(["success", "warning", "danger", "primary", "white"]), /** Sets the variant of the checkbox. Colours used are the design system standard colours. */ variant: PropTypes.oneOf(["success", "warning", "danger", "primary", "white", "default"]), /** Applies disabled attribute and styling */ disabled: PropTypes.bool, /** Applies checked attribute and styling */ checked: PropTypes.bool, /** Input name attribute (should be unique id) */ name: PropTypes.string, /** On checkbox input change handler */ onChange: PropTypes.func, /** On checkbox click handler */ onClick: PropTypes.func, /** Text label to display beside the checkbox */ label: PropTypes.string, // ariaLabel prop must be specified if label is not provided ariaLabel: (props, propName) => { if (!props.label && (props[propName] == null || props[propName] === "")) { return new Error("Missing prop `".concat(propName, "` not specified for Checkbox component. When `label` is not provided, `").concat(propName, "` is required.")); } if (props[propName] && typeof props[propName] !== "string") { return new Error("Invalid propType for `".concat(propName, "` supplied to Checkbox component. Expected `string`, received `").concat(typeof props[propName], "`.")); } return null; }, /** Specifies the system design theme. */ theme: PropTypes.object }; Checkbox.__docgenInfo = { "description": "The default checkbox (or inverted if on dark background) should be used for the majority of the UI; however, the coloured ones can be used in situations where the colour corresponds with some indication of status, e.g. in a task list, green could denote task completed, red could denote task overdue.", "methods": [], "displayName": "Checkbox", "props": { "colour": { "description": "Sets the colour of the checkbox. Colours used are the design system standard colours. @deprecated Use `variant` instead.", "type": { "name": "enum", "value": [{ "value": "\"success\"", "computed": false }, { "value": "\"warning\"", "computed": false }, { "value": "\"danger\"", "computed": false }, { "value": "\"primary\"", "computed": false }, { "value": "\"white\"", "computed": false }] }, "required": false }, "variant": { "description": "Sets the variant of the checkbox. Colours used are the design system standard colours.", "type": { "name": "enum", "value": [{ "value": "\"success\"", "computed": false }, { "value": "\"warning\"", "computed": false }, { "value": "\"danger\"", "computed": false }, { "value": "\"primary\"", "computed": false }, { "value": "\"white\"", "computed": false }, { "value": "\"default\"", "computed": false }] }, "required": false }, "disabled": { "description": "Applies disabled attribute and styling", "type": { "name": "bool" }, "required": false }, "checked": { "description": "Applies checked attribute and styling", "type": { "name": "bool" }, "required": false }, "name": { "description": "Input name attribute (should be unique id)", "type": { "name": "string" }, "required": false }, "onChange": { "description": "On checkbox input change handler", "type": { "name": "func" }, "required": false }, "onClick": { "description": "On checkbox click handler", "type": { "name": "func" }, "required": false }, "label": { "description": "Text label to display beside the checkbox", "type": { "name": "string" }, "required": false }, "ariaLabel": { "description": "", "type": { "name": "custom", "raw": "(props, propName) => {\n if (!props.label && (props[propName] == null || props[propName] === \"\")) {\n return new Error(\n `Missing prop \\`${propName}\\` not specified for Checkbox component. When \\`label\\` is not provided, \\`${propName}\\` is required.`\n );\n }\n if (props[propName] && typeof props[propName] !== \"string\") {\n return new Error(\n `Invalid propType for \\`${propName}\\` supplied to Checkbox component. Expected \\`string\\`, received \\`${typeof props[\n propName\n ]}\\`.`\n );\n }\n return null;\n}" }, "required": false }, "theme": { "description": "Specifies the system design theme.", "type": { "name": "object" }, "required": false } } };