orcs-design-system
Version:
TeamForm's Design System, aka: ORCS
386 lines (381 loc) • 15.6 kB
JavaScript
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
}
}
};