@workday/canvas-kit-preview-react 9.1.0-473-next.0 → 9.1.0-477-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +1 -0
- package/dist/commonjs/radio/index.d.ts +4 -0
- package/dist/commonjs/radio/index.d.ts.map +1 -0
- package/dist/commonjs/radio/index.js +15 -0
- package/dist/commonjs/radio/lib/RadioButton.d.ts +13 -0
- package/dist/commonjs/radio/lib/RadioButton.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/RadioButton.js +18 -0
- package/dist/commonjs/radio/lib/RadioGroup.d.ts +103 -0
- package/dist/commonjs/radio/lib/RadioGroup.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/RadioGroup.js +62 -0
- package/dist/commonjs/radio/lib/RadioInput.d.ts +13 -0
- package/dist/commonjs/radio/lib/RadioInput.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/RadioInput.js +31 -0
- package/dist/commonjs/radio/lib/RadioLabel.d.ts +72 -0
- package/dist/commonjs/radio/lib/RadioLabel.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/RadioLabel.js +48 -0
- package/dist/commonjs/radio/lib/RadioText.d.ts +12 -0
- package/dist/commonjs/radio/lib/RadioText.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/RadioText.js +28 -0
- package/dist/commonjs/radio/lib/StyledRadioButton.d.ts +14 -0
- package/dist/commonjs/radio/lib/StyledRadioButton.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/StyledRadioButton.js +122 -0
- package/dist/commonjs/radio/lib/hooks/useRadioModel.d.ts +106 -0
- package/dist/commonjs/radio/lib/hooks/useRadioModel.d.ts.map +1 -0
- package/dist/commonjs/radio/lib/hooks/useRadioModel.js +67 -0
- package/dist/es6/index.d.ts +1 -0
- package/dist/es6/index.d.ts.map +1 -1
- package/dist/es6/index.js +1 -0
- package/dist/es6/radio/index.d.ts +4 -0
- package/dist/es6/radio/index.d.ts.map +1 -0
- package/dist/es6/radio/index.js +3 -0
- package/dist/es6/radio/lib/RadioButton.d.ts +13 -0
- package/dist/es6/radio/lib/RadioButton.d.ts.map +1 -0
- package/dist/es6/radio/lib/RadioButton.js +12 -0
- package/dist/es6/radio/lib/RadioGroup.d.ts +103 -0
- package/dist/es6/radio/lib/RadioGroup.d.ts.map +1 -0
- package/dist/es6/radio/lib/RadioGroup.js +56 -0
- package/dist/es6/radio/lib/RadioInput.d.ts +13 -0
- package/dist/es6/radio/lib/RadioInput.d.ts.map +1 -0
- package/dist/es6/radio/lib/RadioInput.js +25 -0
- package/dist/es6/radio/lib/RadioLabel.d.ts +72 -0
- package/dist/es6/radio/lib/RadioLabel.d.ts.map +1 -0
- package/dist/es6/radio/lib/RadioLabel.js +42 -0
- package/dist/es6/radio/lib/RadioText.d.ts +12 -0
- package/dist/es6/radio/lib/RadioText.d.ts.map +1 -0
- package/dist/es6/radio/lib/RadioText.js +22 -0
- package/dist/es6/radio/lib/StyledRadioButton.d.ts +14 -0
- package/dist/es6/radio/lib/StyledRadioButton.d.ts.map +1 -0
- package/dist/es6/radio/lib/StyledRadioButton.js +116 -0
- package/dist/es6/radio/lib/hooks/useRadioModel.d.ts +106 -0
- package/dist/es6/radio/lib/hooks/useRadioModel.d.ts.map +1 -0
- package/dist/es6/radio/lib/hooks/useRadioModel.js +61 -0
- package/index.ts +1 -0
- package/package.json +3 -3
- package/radio/LICENSE +52 -0
- package/radio/README.md +36 -0
- package/radio/index.ts +3 -0
- package/radio/lib/RadioButton.tsx +17 -0
- package/radio/lib/RadioGroup.tsx +90 -0
- package/radio/lib/RadioInput.tsx +28 -0
- package/radio/lib/RadioLabel.tsx +72 -0
- package/radio/lib/RadioText.tsx +32 -0
- package/radio/lib/StyledRadioButton.tsx +178 -0
- package/radio/lib/hooks/useRadioModel.tsx +64 -0
- package/radio/package.json +6 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
styled,
|
|
4
|
+
StyledType,
|
|
5
|
+
focusRing,
|
|
6
|
+
mouseFocusBehavior,
|
|
7
|
+
createComponent,
|
|
8
|
+
ExtractProps,
|
|
9
|
+
Themeable,
|
|
10
|
+
} from '@workday/canvas-kit-react/common';
|
|
11
|
+
import {colors, inputColors, spaceNumbers, borderRadius} from '@workday/canvas-kit-react/tokens';
|
|
12
|
+
|
|
13
|
+
import {Box, Flex} from '@workday/canvas-kit-react/layout';
|
|
14
|
+
|
|
15
|
+
const radioWidth = 18;
|
|
16
|
+
const rippleRadius = (spaceNumbers.l - radioWidth) / 2;
|
|
17
|
+
const radioHeight = 18;
|
|
18
|
+
|
|
19
|
+
export interface StyledRadioButtonProps extends ExtractProps<typeof Box, 'input'>, Themeable {
|
|
20
|
+
variant?: 'inverse' | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const StyledRadioInput = styled(Box.as('input'))<StyledRadioButtonProps & StyledType>(
|
|
24
|
+
{
|
|
25
|
+
'&:focus, &:active': {
|
|
26
|
+
outline: 'transparent',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
({
|
|
30
|
+
disabled,
|
|
31
|
+
variant,
|
|
32
|
+
theme: {
|
|
33
|
+
canvas: {
|
|
34
|
+
palette: {
|
|
35
|
+
primary: themePrimary,
|
|
36
|
+
common: {focusOutline: themeFocusOutline},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
}) => ({
|
|
41
|
+
cursor: !disabled ? 'pointer' : undefined,
|
|
42
|
+
opacity: disabled && variant === 'inverse' ? '.4' : '1',
|
|
43
|
+
height: '18px',
|
|
44
|
+
width: '18px',
|
|
45
|
+
|
|
46
|
+
// Circle element styles the radio as checked or unchecked
|
|
47
|
+
'+ .cnvs-radio-check': {
|
|
48
|
+
display: 'flex',
|
|
49
|
+
flexDirection: 'column',
|
|
50
|
+
alignItems: 'center',
|
|
51
|
+
backgroundColor: disabled ? inputColors.disabled.background : colors.frenchVanilla100,
|
|
52
|
+
borderRadius: '999px',
|
|
53
|
+
boxSizing: 'border-box',
|
|
54
|
+
border: `1px solid`,
|
|
55
|
+
borderColor: disabled
|
|
56
|
+
? inputColors.disabled.border
|
|
57
|
+
: variant === 'inverse'
|
|
58
|
+
? colors.soap300
|
|
59
|
+
: inputColors.border,
|
|
60
|
+
height: '18px',
|
|
61
|
+
width: '18px',
|
|
62
|
+
justifyContent: 'center',
|
|
63
|
+
pointerEvents: 'none',
|
|
64
|
+
position: 'absolute',
|
|
65
|
+
transition: 'border 200ms ease, background 200ms',
|
|
66
|
+
opacity: disabled && variant === 'inverse' ? '.4' : '1',
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
'&:hover + .cnvs-radio-check': {
|
|
70
|
+
borderColor: disabled
|
|
71
|
+
? inputColors.disabled.border
|
|
72
|
+
: variant === 'inverse'
|
|
73
|
+
? colors.soap300
|
|
74
|
+
: colors.licorice500,
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
'&:focus + .cnvs-radio-check': {
|
|
78
|
+
borderColor: disabled
|
|
79
|
+
? inputColors.disabled.border
|
|
80
|
+
: variant === 'inverse'
|
|
81
|
+
? colors.soap300
|
|
82
|
+
: colors.blueberry400,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
'&:checked + .cnvs-radio-check': {
|
|
86
|
+
backgroundColor: variant === 'inverse' ? themePrimary.main : themePrimary.contrast, // inner circle color
|
|
87
|
+
border: `5px solid`, // this creates the inner circle
|
|
88
|
+
borderColor: variant === 'inverse' ? colors.frenchVanilla100 : themePrimary.main, // outer circle color
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
'&:focus + .cnvs-radio-check, &:focus:hover + .cnvs-radio-check': {
|
|
92
|
+
outline: 'transparent',
|
|
93
|
+
|
|
94
|
+
...focusRing({
|
|
95
|
+
width: variant === 'inverse' ? 2 : 1,
|
|
96
|
+
separation: 0,
|
|
97
|
+
animate: false,
|
|
98
|
+
innerColor: variant === 'inverse' ? colors.blackPepper400 : colors.frenchVanilla100,
|
|
99
|
+
outerColor: variant === 'inverse' ? colors.frenchVanilla100 : themeFocusOutline,
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
'&:focus:checked + .cnvs-radio-check, &:focus:hover:checked + .cnvs-radio-check': {
|
|
104
|
+
outline: 'transparent',
|
|
105
|
+
...focusRing({
|
|
106
|
+
width: 2,
|
|
107
|
+
separation: 2,
|
|
108
|
+
animate: false,
|
|
109
|
+
innerColor: variant === 'inverse' ? colors.blackPepper400 : colors.frenchVanilla100,
|
|
110
|
+
outerColor: variant === 'inverse' ? colors.frenchVanilla100 : themeFocusOutline,
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
...mouseFocusBehavior({
|
|
115
|
+
'&:focus + .cnvs-radio-check, &:focus:hover + .cnvs-radio-check, &:focus:active + .cnvs-radio-check, &:focus:hover:checked + .cnvs-radio-check, &:focus:active:checked + .cnvs-radio-check': {
|
|
116
|
+
...focusRing({
|
|
117
|
+
width: 0,
|
|
118
|
+
outerColor: variant === 'inverse' ? colors.frenchVanilla100 : themeFocusOutline,
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const RadioInputWrapper = styled(Flex)<Pick<StyledRadioButtonProps, 'disabled' | 'variant'>>(
|
|
126
|
+
{
|
|
127
|
+
// Hover Ripple element
|
|
128
|
+
'::before': {
|
|
129
|
+
content: "''",
|
|
130
|
+
borderRadius: borderRadius.circle,
|
|
131
|
+
height: radioHeight,
|
|
132
|
+
transition: 'box-shadow 150ms ease-out',
|
|
133
|
+
width: radioWidth,
|
|
134
|
+
pointerEvents: 'none',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
({variant, disabled}) => ({
|
|
138
|
+
'::before': {
|
|
139
|
+
opacity: variant === 'inverse' ? '0.4' : '1',
|
|
140
|
+
},
|
|
141
|
+
'&:hover:before': {
|
|
142
|
+
boxShadow: !disabled ? `0 0 0 ${rippleRadius}px ${colors.soap200}` : undefined,
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
export interface StyledRadioButtonProps extends ExtractProps<typeof Box, 'input'> {
|
|
148
|
+
variant?: 'inverse' | undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Use `StyledRadioButton` when you want a styled radio button on its own without using `RadioGroup`.
|
|
153
|
+
* You will need to handle behavior and accessibility.
|
|
154
|
+
*/
|
|
155
|
+
export const StyledRadioButton = createComponent('input')({
|
|
156
|
+
displayName: 'Radio',
|
|
157
|
+
Component: ({...elemProps}: StyledRadioButtonProps, ref, Element) => {
|
|
158
|
+
return (
|
|
159
|
+
<RadioInputWrapper
|
|
160
|
+
height="18px"
|
|
161
|
+
width="18px"
|
|
162
|
+
flex="0 0 auto"
|
|
163
|
+
{...elemProps} // This ensures our visual testing stories work properly
|
|
164
|
+
>
|
|
165
|
+
<StyledRadioInput
|
|
166
|
+
borderRadius="circle"
|
|
167
|
+
position="absolute"
|
|
168
|
+
margin="zero"
|
|
169
|
+
as={Element}
|
|
170
|
+
type="radio"
|
|
171
|
+
ref={ref}
|
|
172
|
+
{...elemProps}
|
|
173
|
+
/>
|
|
174
|
+
<span className="cnvs-radio-check"></span>
|
|
175
|
+
</RadioInputWrapper>
|
|
176
|
+
);
|
|
177
|
+
},
|
|
178
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {createModelHook} from '@workday/canvas-kit-react/common';
|
|
4
|
+
|
|
5
|
+
export const useRadioModel = createModelHook({
|
|
6
|
+
defaultConfig: {
|
|
7
|
+
/**
|
|
8
|
+
* Use this attribute when you have a `FormField` that is in an `Alert` | `Error` or `Required` state. This will add attach an `aria-describedby` to each radio input so that screen readers can read out the message attached to the form field.
|
|
9
|
+
* The value of this attribute needs to match the value passed to `hintId` on the `FormField`.
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <FormField
|
|
13
|
+
* error={FormField.ErrorType.Alert}
|
|
14
|
+
* hintId="hint-alert"
|
|
15
|
+
* hintText="Deep dish is an extra $2.99"
|
|
16
|
+
* label="Choose Your Pizza Crust"
|
|
17
|
+
* useFieldset={true}
|
|
18
|
+
* >
|
|
19
|
+
* <RadioGroup
|
|
20
|
+
* name="crust"
|
|
21
|
+
* onChange={handleChange}
|
|
22
|
+
* initialValue={value}
|
|
23
|
+
* aria-describedby="hint-alert"
|
|
24
|
+
* >
|
|
25
|
+
* <RadioGroup.RadioButton value="deep-dish">Deep dish</RadioGroup.RadioButton>
|
|
26
|
+
* <RadioGroup.RadioButton value="thin">Thin</RadioGroup.RadioButton>
|
|
27
|
+
* <RadioGroup.RadioButton value="gluten-free">Gluten free</RadioGroup.RadioButton>
|
|
28
|
+
* <RadioGroup.RadioButton value="cauliflower">Cauliflower</RadioGroup.RadioButton>
|
|
29
|
+
* </RadioGroup>
|
|
30
|
+
* </FormField>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
'aria-describedby': undefined as string | undefined,
|
|
34
|
+
/**
|
|
35
|
+
* The common `name` passed to all Radio button children of the RadioGroup. This enables you to avoid specifying the `name` for each child.
|
|
36
|
+
*/
|
|
37
|
+
name: '',
|
|
38
|
+
/**
|
|
39
|
+
* The selected value of the RadioGroup. Providing this prop will cause the model be in a controlled state
|
|
40
|
+
*/
|
|
41
|
+
value: undefined as string | number | undefined,
|
|
42
|
+
/**
|
|
43
|
+
* `onChange` handler. Any `onChange` passed to children will be overwritten by this event so that there is only one per group.
|
|
44
|
+
*/
|
|
45
|
+
onChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
46
|
+
return;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
})(config => {
|
|
50
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
51
|
+
const state = {
|
|
52
|
+
value: config.value,
|
|
53
|
+
name: config.name,
|
|
54
|
+
'aria-describedby': config['aria-describedby'],
|
|
55
|
+
inputRef,
|
|
56
|
+
};
|
|
57
|
+
const events = {};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
onChange: config.onChange,
|
|
61
|
+
state,
|
|
62
|
+
events,
|
|
63
|
+
};
|
|
64
|
+
});
|