@workday/canvas-kit-react
Version:
The parent module that contains all Workday Canvas Kit React components
223 lines (222 loc) • 9.61 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Radio = void 0;
const React = __importStar(require("react"));
const common_1 = require("@workday/canvas-kit-react/common");
const tokens_1 = require("@workday/canvas-kit-react/tokens");
const text_1 = require("@workday/canvas-kit-react/text");
const canvas_kit_styling_1 = require("@workday/canvas-kit-styling");
const radioBorderRadius = 9;
const RadioContainer = (0, common_1.styled)('div')({
display: 'flex',
alignItems: 'center',
minHeight: tokens_1.space.m,
position: 'relative',
});
/**
* Using a wrapper prevents the browser default behavior of trigging
* :hover on the radio when you hover on it's corresponding label.
* This stops the ripple from showing when you hover on the label.
*/
const RadioInputWrapper = (0, common_1.styled)('div')({
display: 'flex',
height: `calc(${tokens_1.space.s} + 2px)`,
width: `calc(${tokens_1.space.s} + 2px)`,
});
const RadioRipple = (0, common_1.styled)('span')({
borderRadius: tokens_1.borderRadius.circle,
boxShadow: `0 0 0 0 ${tokens_1.colors.soap200}`,
height: `calc(${tokens_1.space.s} + 2px)`,
transition: 'box-shadow 150ms ease-out',
width: `calc(${tokens_1.space.s} + 2px)`,
position: 'absolute',
pointerEvents: 'none', // This is a decorative element we don't want it to block clicks to input
}, ({ variant }) => ({
opacity: variant === 'inverse' ? '0.4' : '1',
}));
const RadioInput = (0, common_1.styled)('input')({
borderRadius: `calc(${tokens_1.space.xxs} + 1px)`,
width: tokens_1.space.m,
height: tokens_1.space.m,
margin: 0,
marginTop: '-3px',
marginLeft: '-3px',
position: 'absolute',
opacity: 0,
'&:focus, &:active': {
outline: 'none',
},
}, ({ checked, disabled, variant, theme: { canvas: { palette: { primary: themePrimary, common: { focusOutline: themeFocusOutline }, }, }, }, }) => ({
cursor: disabled ? undefined : 'pointer',
/**
* These selectors are targetting various sibling elements (~) here because
* their styles need to be connected to changes around the input's state
* (e.g. hover, focus, etc.).
*
* We are choosing not to use component selectors from Emotion in this case.
* The Babel transforms have been problematic in the past.
*/
// `span:first-of-type` refers to `RadioRipple`, the light grey
// element that animates around the component on hover
'&:hover ~ span:first-of-type': {
boxShadow: disabled
? undefined
: `0 0 0 calc((${tokens_1.space.l} - (${tokens_1.space.s} + 2px)) / 2) ${tokens_1.colors.soap200}`,
},
// `div:first-of-type` refers to the `RadioBackground`, the visual facade of the
// input (which is visually hidden)
'&:hover ~ div:first-of-type': {
backgroundColor: checked
? variant === 'inverse'
? tokens_1.colors.frenchVanilla100
: themePrimary.main
: disabled
? tokens_1.inputColors.disabled.background
: 'white',
borderColor: checked
? variant === 'inverse'
? tokens_1.colors.soap300
: themePrimary.main
: disabled
? tokens_1.inputColors.disabled.border
: variant === 'inverse'
? tokens_1.colors.soap300
: tokens_1.inputColors.hoverBorder,
borderWidth: '1px',
},
'&:focus, &focus:hover': {
'& ~ div:first-of-type': {
borderWidth: '2px',
borderColor: variant === 'inverse' ? tokens_1.colors.blackPepper400 : themeFocusOutline,
boxShadow: 'none',
outline: `${(0, canvas_kit_styling_1.px2rem)(2)} solid transparent`,
outlineOffset: variant === 'inverse' ? '0' : '2px',
...(0, common_1.focusRing)({
width: variant === 'inverse' ? 2 : 0,
separation: 0,
animate: false,
innerColor: variant === 'inverse' ? tokens_1.colors.blackPepper400 : undefined,
outerColor: variant === 'inverse' ? tokens_1.colors.frenchVanilla100 : undefined,
}),
},
},
'&:checked:focus ~ div:first-of-type': {
...(0, common_1.focusRing)({
separation: 2,
width: 2,
innerColor: variant === 'inverse' ? tokens_1.colors.blackPepper400 : undefined,
outerColor: variant === 'inverse' ? tokens_1.colors.frenchVanilla100 : themeFocusOutline,
}),
borderColor: variant === 'inverse' ? tokens_1.colors.frenchVanilla100 : themePrimary.main,
borderWidth: '2px',
},
...(0, common_1.mouseFocusBehavior)({
'&:focus ~ div:first-of-type': {
...(0, common_1.focusRing)({
width: 0,
outerColor: variant === 'inverse' ? tokens_1.colors.frenchVanilla100 : themeFocusOutline,
}),
borderWidth: '1px',
borderColor: checked
? variant === 'inverse'
? tokens_1.colors.soap300
: themePrimary.main
: tokens_1.inputColors.border,
},
'&:focus:hover ~ div:first-of-type, &:focus:active ~ div:first-of-type': {
borderColor: checked
? variant === 'inverse'
? tokens_1.colors.soap300
: themePrimary.main
: variant === 'inverse'
? tokens_1.colors.soap300
: tokens_1.inputColors.hoverBorder,
},
}),
}));
const RadioBackground = (0, common_1.styled)('div')({
alignItems: 'center',
backgroundColor: tokens_1.colors.frenchVanilla100,
borderRadius: radioBorderRadius,
borderStyle: 'solid',
borderWidth: '1px',
boxSizing: 'border-box',
display: 'flex',
height: `calc(${tokens_1.space.s} + 2px)`,
justifyContent: 'center',
padding: '0px 2px',
pointerEvents: 'none',
position: 'absolute',
transition: 'border 200ms ease, background 200ms',
width: `calc(${tokens_1.space.s} + 2px)`,
}, ({ checked, disabled, variant, theme: { canvas: { palette: { primary: themePrimary }, }, }, }) => ({
borderColor: checked
? variant === 'inverse'
? tokens_1.colors.soap300
: themePrimary.main
: disabled
? tokens_1.colors.licorice100
: variant === 'inverse'
? tokens_1.colors.soap300
: tokens_1.inputColors.border,
backgroundColor: checked
? variant === 'inverse'
? tokens_1.colors.frenchVanilla100
: themePrimary.main
: disabled
? tokens_1.inputColors.disabled.background
: 'white',
opacity: disabled && variant === 'inverse' ? '.4' : '1',
}));
const RadioCheck = (0, common_1.styled)('div')({
borderRadius: radioBorderRadius,
display: 'flex',
flexDirection: 'column',
height: tokens_1.space.xxs,
pointerEvents: 'none',
transition: 'transform 200ms ease, opacity 200ms ease',
width: tokens_1.space.xxs,
}, ({ theme, variant }) => ({
backgroundColor: variant === 'inverse'
? theme.canvas.palette.primary.main
: theme.canvas.palette.primary.contrast,
}), ({ checked }) => ({
opacity: checked ? 1 : 0,
transform: checked ? 'scale(1)' : 'scale(0.5)',
}));
exports.Radio = (0, common_1.createComponent)('input')({
displayName: 'Radio',
Component: ({ checked = false, id, label = '', disabled, name, onChange, value, variant, ...elemProps }, ref, Element) => {
const inputId = (0, common_1.useUniqueId)(id);
return (React.createElement(RadioContainer, null,
React.createElement(RadioInputWrapper, { disabled: disabled },
React.createElement(RadioInput, { as: Element, checked: checked, disabled: disabled, id: inputId, ref: ref, name: name, onChange: onChange, type: "radio", value: value, "aria-checked": checked, variant: variant, ...elemProps }),
React.createElement(RadioRipple, { variant: variant }),
React.createElement(RadioBackground, { checked: checked, disabled: disabled, variant: variant },
React.createElement(RadioCheck, { checked: checked, variant: variant }))),
label && (React.createElement(text_1.LabelText, { paddingLeft: tokens_1.space.xs, htmlFor: inputId, disabled: disabled, variant: variant }, label))));
},
});
;