@workday/canvas-kit-react 11.0.0-alpha.671-next.0 → 11.0.0-alpha.693-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/checkbox/lib/CheckBackground.tsx +48 -0
- package/checkbox/lib/Checkbox.tsx +18 -355
- package/checkbox/lib/CheckboxCheck.tsx +81 -0
- package/checkbox/lib/CheckboxContainer.tsx +58 -0
- package/checkbox/lib/CheckboxInput.tsx +279 -0
- package/checkbox/lib/CheckboxRipple.tsx +21 -0
- package/collection/lib/useCursorListModel.tsx +86 -90
- package/collection/lib/useListItemAllowChildStrings.ts +3 -3
- package/collection/lib/useListRenderItem.tsx +1 -1
- package/combobox/lib/hooks/useComboboxInput.ts +1 -0
- package/combobox/lib/hooks/useComboboxKeyboardTypeAhead.ts +3 -3
- package/combobox/lib/hooks/useComboboxModel.tsx +1 -2
- package/common/README.md +32 -14
- package/common/lib/styles/errorRing.ts +2 -2
- package/common/lib/styles/focusRing.ts +4 -17
- package/dist/commonjs/avatar/lib/Avatar.js +1 -1
- package/dist/commonjs/badge/lib/CountBadge.js +8 -8
- package/dist/commonjs/banner/lib/Banner.js +1 -1
- package/dist/commonjs/button/lib/BaseButton.js +22 -22
- package/dist/commonjs/button/lib/DeleteButton.js +1 -1
- package/dist/commonjs/button/lib/PrimaryButton.js +2 -2
- package/dist/commonjs/button/lib/SecondaryButton.js +2 -2
- package/dist/commonjs/button/lib/TertiaryButton.js +15 -15
- package/dist/commonjs/button/lib/ToolbarDropdownButton.js +6 -1
- package/dist/commonjs/button/lib/ToolbarIconButton.js +6 -1
- package/dist/commonjs/button/lib/deprecated_Button.js +2 -2
- package/dist/commonjs/card/lib/Card.js +1 -1
- package/dist/commonjs/card/lib/CardHeading.js +1 -1
- package/dist/commonjs/checkbox/lib/CheckBackground.d.ts +10 -0
- package/dist/commonjs/checkbox/lib/CheckBackground.d.ts.map +1 -0
- package/dist/commonjs/checkbox/lib/CheckBackground.js +42 -0
- package/dist/commonjs/checkbox/lib/Checkbox.d.ts +3 -45
- package/dist/commonjs/checkbox/lib/Checkbox.d.ts.map +1 -1
- package/dist/commonjs/checkbox/lib/Checkbox.js +10 -204
- package/dist/commonjs/checkbox/lib/CheckboxCheck.d.ts +10 -0
- package/dist/commonjs/checkbox/lib/CheckboxCheck.d.ts.map +1 -0
- package/dist/commonjs/checkbox/lib/CheckboxCheck.js +51 -0
- package/dist/commonjs/checkbox/lib/CheckboxContainer.d.ts +13 -0
- package/dist/commonjs/checkbox/lib/CheckboxContainer.d.ts.map +1 -0
- package/dist/commonjs/checkbox/lib/CheckboxContainer.js +37 -0
- package/dist/commonjs/checkbox/lib/CheckboxInput.d.ts +48 -0
- package/dist/commonjs/checkbox/lib/CheckboxInput.d.ts.map +1 -0
- package/dist/commonjs/checkbox/lib/CheckboxInput.js +59 -0
- package/dist/commonjs/checkbox/lib/CheckboxRipple.d.ts +2 -0
- package/dist/commonjs/checkbox/lib/CheckboxRipple.d.ts.map +1 -0
- package/dist/commonjs/checkbox/lib/CheckboxRipple.js +33 -0
- package/dist/commonjs/collection/lib/useCursorListModel.d.ts.map +1 -1
- package/dist/commonjs/collection/lib/useListItemAllowChildStrings.d.ts +2 -1
- package/dist/commonjs/collection/lib/useListItemAllowChildStrings.d.ts.map +1 -1
- package/dist/commonjs/collection/lib/useListItemAllowChildStrings.js +1 -1
- package/dist/commonjs/collection/lib/useListRenderItem.js +1 -1
- package/dist/commonjs/combobox/lib/hooks/useComboboxInput.d.ts +1 -0
- package/dist/commonjs/combobox/lib/hooks/useComboboxInput.d.ts.map +1 -1
- package/dist/commonjs/combobox/lib/hooks/useComboboxInput.js +1 -0
- package/dist/commonjs/combobox/lib/hooks/useComboboxKeyboardTypeAhead.js +2 -3
- package/dist/commonjs/combobox/lib/hooks/useComboboxModel.d.ts.map +1 -1
- package/dist/commonjs/combobox/lib/hooks/useComboboxModel.js +1 -2
- package/dist/commonjs/common/lib/AccessibleHide.js +1 -1
- package/dist/commonjs/common/lib/CanvasProvider.js +1 -1
- package/dist/commonjs/common/lib/styles/errorRing.js +2 -2
- package/dist/commonjs/common/lib/styles/focusRing.d.ts.map +1 -1
- package/dist/commonjs/common/lib/styles/focusRing.js +5 -16
- package/dist/commonjs/form-field/lib/Label.js +3 -7
- package/dist/commonjs/loading-dots/lib/LoadingDots.js +3 -3
- package/dist/commonjs/radio/lib/Radio.js +17 -3
- package/dist/commonjs/select/lib/Select.d.ts +2 -1
- package/dist/commonjs/select/lib/Select.d.ts.map +1 -1
- package/dist/commonjs/select/lib/Select.js +5 -3
- package/dist/commonjs/select/lib/hooks/useSelectInput.d.ts +7 -1
- package/dist/commonjs/select/lib/hooks/useSelectInput.d.ts.map +1 -1
- package/dist/commonjs/select/lib/hooks/useSelectInput.js +45 -4
- package/dist/commonjs/select/lib/hooks/useSelectModel.d.ts.map +1 -1
- package/dist/commonjs/select/lib/hooks/useSelectModel.js +1 -2
- package/dist/commonjs/switch/lib/Switch.js +2 -2
- package/dist/commonjs/tabs/lib/TabsItem.js +1 -1
- package/dist/commonjs/text/lib/LabelText.js +24 -24
- package/dist/commonjs/text/lib/Text.js +15 -15
- package/dist/commonjs/text-input/lib/TextInput.js +3 -3
- package/dist/commonjs/tooltip/lib/OverflowTooltip.d.ts.map +1 -1
- package/dist/commonjs/tooltip/lib/OverflowTooltip.js +3 -2
- package/dist/es6/avatar/lib/Avatar.js +1 -1
- package/dist/es6/badge/lib/CountBadge.js +7 -7
- package/dist/es6/banner/lib/Banner.js +1 -1
- package/dist/es6/button/lib/BaseButton.js +22 -22
- package/dist/es6/button/lib/DeleteButton.js +1 -1
- package/dist/es6/button/lib/PrimaryButton.js +2 -2
- package/dist/es6/button/lib/SecondaryButton.js +2 -2
- package/dist/es6/button/lib/TertiaryButton.js +15 -15
- package/dist/es6/button/lib/ToolbarDropdownButton.js +6 -1
- package/dist/es6/button/lib/ToolbarIconButton.js +6 -1
- package/dist/es6/button/lib/deprecated_Button.js +2 -2
- package/dist/es6/card/lib/Card.js +1 -1
- package/dist/es6/card/lib/CardHeading.js +1 -1
- package/dist/es6/checkbox/lib/CheckBackground.d.ts +10 -0
- package/dist/es6/checkbox/lib/CheckBackground.d.ts.map +1 -0
- package/dist/es6/checkbox/lib/CheckBackground.js +20 -0
- package/dist/es6/checkbox/lib/Checkbox.d.ts +3 -45
- package/dist/es6/checkbox/lib/Checkbox.d.ts.map +1 -1
- package/dist/es6/checkbox/lib/Checkbox.js +11 -205
- package/dist/es6/checkbox/lib/CheckboxCheck.d.ts +10 -0
- package/dist/es6/checkbox/lib/CheckboxCheck.d.ts.map +1 -0
- package/dist/es6/checkbox/lib/CheckboxCheck.js +29 -0
- package/dist/es6/checkbox/lib/CheckboxContainer.d.ts +13 -0
- package/dist/es6/checkbox/lib/CheckboxContainer.d.ts.map +1 -0
- package/dist/es6/checkbox/lib/CheckboxContainer.js +15 -0
- package/dist/es6/checkbox/lib/CheckboxInput.d.ts +48 -0
- package/dist/es6/checkbox/lib/CheckboxInput.d.ts.map +1 -0
- package/dist/es6/checkbox/lib/CheckboxInput.js +37 -0
- package/dist/es6/checkbox/lib/CheckboxRipple.d.ts +2 -0
- package/dist/es6/checkbox/lib/CheckboxRipple.d.ts.map +1 -0
- package/dist/es6/checkbox/lib/CheckboxRipple.js +11 -0
- package/dist/es6/collection/lib/useCursorListModel.d.ts.map +1 -1
- package/dist/es6/collection/lib/useListItemAllowChildStrings.d.ts +2 -1
- package/dist/es6/collection/lib/useListItemAllowChildStrings.d.ts.map +1 -1
- package/dist/es6/collection/lib/useListItemAllowChildStrings.js +1 -1
- package/dist/es6/collection/lib/useListRenderItem.js +1 -1
- package/dist/es6/combobox/lib/hooks/useComboboxInput.d.ts +1 -0
- package/dist/es6/combobox/lib/hooks/useComboboxInput.d.ts.map +1 -1
- package/dist/es6/combobox/lib/hooks/useComboboxInput.js +1 -0
- package/dist/es6/combobox/lib/hooks/useComboboxKeyboardTypeAhead.js +2 -3
- package/dist/es6/combobox/lib/hooks/useComboboxModel.d.ts.map +1 -1
- package/dist/es6/combobox/lib/hooks/useComboboxModel.js +1 -2
- package/dist/es6/common/lib/AccessibleHide.js +1 -1
- package/dist/es6/common/lib/CanvasProvider.js +1 -1
- package/dist/es6/common/lib/styles/errorRing.js +2 -2
- package/dist/es6/common/lib/styles/focusRing.d.ts.map +1 -1
- package/dist/es6/common/lib/styles/focusRing.js +5 -16
- package/dist/es6/form-field/lib/Label.js +3 -7
- package/dist/es6/loading-dots/lib/LoadingDots.js +2 -2
- package/dist/es6/radio/lib/Radio.js +17 -3
- package/dist/es6/select/lib/Select.d.ts +2 -1
- package/dist/es6/select/lib/Select.d.ts.map +1 -1
- package/dist/es6/select/lib/Select.js +5 -3
- package/dist/es6/select/lib/hooks/useSelectInput.d.ts +7 -1
- package/dist/es6/select/lib/hooks/useSelectInput.d.ts.map +1 -1
- package/dist/es6/select/lib/hooks/useSelectInput.js +43 -5
- package/dist/es6/select/lib/hooks/useSelectModel.d.ts.map +1 -1
- package/dist/es6/select/lib/hooks/useSelectModel.js +1 -2
- package/dist/es6/switch/lib/Switch.js +2 -2
- package/dist/es6/tabs/lib/TabsItem.js +1 -1
- package/dist/es6/text/lib/LabelText.js +24 -24
- package/dist/es6/text/lib/Text.js +15 -15
- package/dist/es6/text-input/lib/TextInput.js +3 -3
- package/dist/es6/tooltip/lib/OverflowTooltip.d.ts.map +1 -1
- package/dist/es6/tooltip/lib/OverflowTooltip.js +3 -2
- package/form-field/lib/Label.tsx +10 -10
- package/package.json +4 -4
- package/select/lib/Select.tsx +51 -4
- package/select/lib/hooks/useSelectInput.ts +86 -44
- package/select/lib/hooks/useSelectModel.tsx +1 -2
- package/text-input/lib/TextInput.tsx +3 -3
- package/tooltip/lib/OverflowTooltip.tsx +3 -2
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {createComponent, focusRing, ErrorType} from '@workday/canvas-kit-react/common';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
calc,
|
|
6
|
+
createStencil,
|
|
7
|
+
cssVar,
|
|
8
|
+
handleCsProp,
|
|
9
|
+
px2rem,
|
|
10
|
+
CSProps,
|
|
11
|
+
} from '@workday/canvas-kit-styling';
|
|
12
|
+
import {base, brand, system} from '@workday/canvas-tokens-web';
|
|
13
|
+
import {backgroundVars} from './CheckBackground';
|
|
14
|
+
|
|
15
|
+
export interface CheckboxProps extends CSProps {
|
|
16
|
+
/**
|
|
17
|
+
* If true, set the Checkbox to the checked state.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
checked?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* If true, set the Checkbox to the disabled state.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The type of error associated with the Checkbox (if applicable).
|
|
28
|
+
*/
|
|
29
|
+
error?: ErrorType;
|
|
30
|
+
/**
|
|
31
|
+
* The HTML `id` of the underlying checkbox input element. This is required if `label` is defined as a non-empty string.
|
|
32
|
+
* @default {useUniqueId}
|
|
33
|
+
*/
|
|
34
|
+
id?: string;
|
|
35
|
+
/**
|
|
36
|
+
* If true, set the Checkbox to an indeterminate state. Use this on a Checkbox with nested child Checkboxes to denote that some (but not all) child Checkboxes are checked.
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
indeterminate?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The text of the Checkbox label.
|
|
42
|
+
* @default ''
|
|
43
|
+
*/
|
|
44
|
+
label?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The function called when the Checkbox state changes.
|
|
47
|
+
*/
|
|
48
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* The value of the Checkbox.
|
|
51
|
+
*/
|
|
52
|
+
value?: string;
|
|
53
|
+
/**
|
|
54
|
+
* The variant for the checkbox
|
|
55
|
+
*/
|
|
56
|
+
variant?: 'inverse' | undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const checkboxInputStencil = createStencil({
|
|
60
|
+
base: {
|
|
61
|
+
borderRadius: system.shape.half,
|
|
62
|
+
width: system.space.x6,
|
|
63
|
+
height: system.space.x6,
|
|
64
|
+
margin: system.space.zero,
|
|
65
|
+
marginTop: calc.negate(px2rem(3)),
|
|
66
|
+
marginInlineStart: calc.negate(px2rem(3)),
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
opacity: 0,
|
|
69
|
+
|
|
70
|
+
'&:not(:disabled)': {
|
|
71
|
+
cursor: 'pointer',
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
'&:where(:hover, .hover) ~ span:first-of-type': {
|
|
75
|
+
boxShadow: `0 0 0 ${px2rem(7)} ${base.soap200}`,
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// Disabled State
|
|
79
|
+
'&:not(:where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
80
|
+
{
|
|
81
|
+
borderColor: base.licorice500,
|
|
82
|
+
},
|
|
83
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
84
|
+
borderColor: brand.primary.base,
|
|
85
|
+
backgroundColor: brand.primary.base,
|
|
86
|
+
},
|
|
87
|
+
'&:disabled ~ div:first-of-type': {
|
|
88
|
+
borderColor: base.licorice100,
|
|
89
|
+
backgroundColor: base.soap100,
|
|
90
|
+
opacity: 1,
|
|
91
|
+
},
|
|
92
|
+
'&:disabled:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
93
|
+
borderColor: brand.primary.light,
|
|
94
|
+
backgroundColor: brand.primary.light,
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Focus State
|
|
98
|
+
'&:where(:focus-visible, :active, .focus, .active)': {
|
|
99
|
+
outline: 'none',
|
|
100
|
+
},
|
|
101
|
+
'&:where(:focus-visible, .focus) ~ div:first-of-type': {
|
|
102
|
+
borderColor: brand.primary.base,
|
|
103
|
+
borderWidth: px2rem(2),
|
|
104
|
+
boxShadow: 'none',
|
|
105
|
+
...focusRing({
|
|
106
|
+
width: 0,
|
|
107
|
+
separation: 0,
|
|
108
|
+
animate: false,
|
|
109
|
+
}),
|
|
110
|
+
},
|
|
111
|
+
'&:checked:focus-visible, &:indeterminate:focus-visible, &:checked.focus, &:indeterminate.focus':
|
|
112
|
+
{
|
|
113
|
+
'& ~ div:first-of-type': {
|
|
114
|
+
...focusRing({
|
|
115
|
+
width: 2,
|
|
116
|
+
separation: 2,
|
|
117
|
+
animate: false,
|
|
118
|
+
outerColor: cssVar(brand.common.focusOutline),
|
|
119
|
+
}),
|
|
120
|
+
borderColor: brand.primary.base,
|
|
121
|
+
borderWidth: px2rem(2),
|
|
122
|
+
span: {
|
|
123
|
+
marginInlineStart: calc.negate(px2rem(7)),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
modifiers: {
|
|
129
|
+
variant: {
|
|
130
|
+
inverse: {
|
|
131
|
+
'& ~ span:first-of-type': {
|
|
132
|
+
opacity: system.opacity.disabled,
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
'& ~ div:first-of-type': {
|
|
136
|
+
borderColor: base.soap300,
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
// Disabled State for inverse variant
|
|
140
|
+
'&:not(:where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
141
|
+
{
|
|
142
|
+
borderColor: base.soap300,
|
|
143
|
+
},
|
|
144
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
145
|
+
borderColor: base.soap300,
|
|
146
|
+
backgroundColor: base.frenchVanilla100,
|
|
147
|
+
},
|
|
148
|
+
'&:disabled ~ div:first-of-type': {
|
|
149
|
+
backgroundColor: base.soap300,
|
|
150
|
+
opacity: system.opacity.disabled,
|
|
151
|
+
},
|
|
152
|
+
'&:disabled:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
153
|
+
borderColor: base.soap300,
|
|
154
|
+
backgroundColor: base.soap300,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// Focus state for inverse variant
|
|
158
|
+
'&:where(:focus-visible, .focus) ~ div:first-of-type': {
|
|
159
|
+
borderColor: base.blackPepper400,
|
|
160
|
+
...focusRing({
|
|
161
|
+
width: 2,
|
|
162
|
+
separation: 0,
|
|
163
|
+
animate: false,
|
|
164
|
+
innerColor: cssVar(base.blackPepper400),
|
|
165
|
+
outerColor: cssVar(base.frenchVanilla100),
|
|
166
|
+
}),
|
|
167
|
+
},
|
|
168
|
+
'&:checked:focus-visible, &:checked.focus, &:indeterminate:focus-visible, &:indeterminate.focus':
|
|
169
|
+
{
|
|
170
|
+
'& ~ div:first-of-type': {
|
|
171
|
+
...focusRing({
|
|
172
|
+
width: 2,
|
|
173
|
+
separation: 2,
|
|
174
|
+
animate: false,
|
|
175
|
+
innerColor: cssVar(base.blackPepper400),
|
|
176
|
+
outerColor: cssVar(base.frenchVanilla100),
|
|
177
|
+
}),
|
|
178
|
+
borderColor: base.frenchVanilla100,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
disabled: {
|
|
184
|
+
true: {
|
|
185
|
+
'&:where(:hover, .hover) ~ span:first-of-type': {
|
|
186
|
+
boxShadow: 'none',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
error: {
|
|
191
|
+
error: {
|
|
192
|
+
'&:not(:where(:focus-visible, .focus)) ~ div:first-of-type': {
|
|
193
|
+
borderColor: backgroundVars.inner,
|
|
194
|
+
boxShadow: `
|
|
195
|
+
0 0 0 ${px2rem(1)} ${backgroundVars.inner},
|
|
196
|
+
0 0 0 ${px2rem(2)} ${backgroundVars.outer}`,
|
|
197
|
+
},
|
|
198
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
199
|
+
borderColor: 'transparent',
|
|
200
|
+
boxShadow: `
|
|
201
|
+
0 0 0 ${px2rem(2)} ${base.frenchVanilla100},
|
|
202
|
+
0 0 0 ${px2rem(4)} ${backgroundVars.inner},
|
|
203
|
+
0 0 0 ${px2rem(5)} ${backgroundVars.outer}`,
|
|
204
|
+
},
|
|
205
|
+
'&:not(:where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
206
|
+
{
|
|
207
|
+
borderColor: backgroundVars.inner,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
alert: {
|
|
211
|
+
'&:not(:where(:focus-visible, .focus)) ~ div:first-of-type': {
|
|
212
|
+
border: `${px2rem(1)} solid ${backgroundVars.inner}`,
|
|
213
|
+
boxShadow: `
|
|
214
|
+
0 0 0 ${px2rem(1)} ${backgroundVars.inner},
|
|
215
|
+
0 0 0 ${px2rem(2)} ${backgroundVars.outer}`,
|
|
216
|
+
},
|
|
217
|
+
'&:not(where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
218
|
+
{
|
|
219
|
+
borderColor: backgroundVars.inner,
|
|
220
|
+
},
|
|
221
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
222
|
+
borderColor: 'transparent',
|
|
223
|
+
boxShadow: `
|
|
224
|
+
0 0 0 ${px2rem(2)} ${base.frenchVanilla100},
|
|
225
|
+
0 0 0 ${px2rem(4)} ${backgroundVars.inner},
|
|
226
|
+
0 0 0 ${px2rem(5)} ${backgroundVars.outer}`,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
compound: [
|
|
232
|
+
{
|
|
233
|
+
modifiers: {variant: 'inverse', error: 'error'},
|
|
234
|
+
styles: {
|
|
235
|
+
'&:not(:where(:focus-visible, .focus)) ~ div:first-of-type': {
|
|
236
|
+
border: `${px2rem(1)} solid ${base.soap300}`,
|
|
237
|
+
},
|
|
238
|
+
'&:not(where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
239
|
+
{
|
|
240
|
+
borderColor: base.soap300,
|
|
241
|
+
},
|
|
242
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
243
|
+
borderColor: base.soap300,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
modifiers: {variant: 'inverse', error: 'alert'},
|
|
249
|
+
styles: {
|
|
250
|
+
'&:not(:where(:focus-visible, .focus)) ~ div:first-of-type': {
|
|
251
|
+
border: `${px2rem(1)} solid ${base.soap300}`,
|
|
252
|
+
},
|
|
253
|
+
'&:not(where(:checked, :indeterminate, :disabled, :focus-visible, .focus)):where(:hover, .hover, :active, .active) ~ div:first-of-type':
|
|
254
|
+
{
|
|
255
|
+
borderColor: base.soap300,
|
|
256
|
+
},
|
|
257
|
+
'&:where(:checked, :indeterminate) ~ div:first-of-type': {
|
|
258
|
+
borderColor: base.soap300,
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
export const CheckboxInput = createComponent('input')({
|
|
266
|
+
displayName: 'CheckboxInput',
|
|
267
|
+
Component: ({variant, error, ...elemProps}: CheckboxProps, ref, Element) => {
|
|
268
|
+
const {checked, disabled, indeterminate} = elemProps;
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<Element
|
|
272
|
+
type="checkbox"
|
|
273
|
+
ref={ref}
|
|
274
|
+
aria-checked={indeterminate ? 'mixed' : checked}
|
|
275
|
+
{...handleCsProp(elemProps, checkboxInputStencil({variant, disabled, error}))}
|
|
276
|
+
/>
|
|
277
|
+
);
|
|
278
|
+
},
|
|
279
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {createComponent} from '@workday/canvas-kit-react/common';
|
|
3
|
+
import {calc, createStyles, px2rem} from '@workday/canvas-kit-styling';
|
|
4
|
+
import {system} from '@workday/canvas-tokens-web';
|
|
5
|
+
|
|
6
|
+
const checkboxRippleStyles = createStyles({
|
|
7
|
+
borderRadius: system.shape.round,
|
|
8
|
+
boxShadow: 'none',
|
|
9
|
+
height: calc.add(system.space.x4, px2rem(2)),
|
|
10
|
+
width: calc.add(system.space.x4, px2rem(2)),
|
|
11
|
+
transition: 'box-shadow 150ms ease-out',
|
|
12
|
+
position: 'absolute',
|
|
13
|
+
pointerEvents: 'none',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const CheckboxRipple = createComponent('span')({
|
|
17
|
+
displayName: 'CheckboxRipple',
|
|
18
|
+
Component: elemProps => {
|
|
19
|
+
return <span className={checkboxRippleStyles} {...elemProps} />;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -135,112 +135,108 @@ const getItem: (id: string, model: NavigationInput) => Item<Generic> = (id, {sta
|
|
|
135
135
|
return item;
|
|
136
136
|
};
|
|
137
137
|
|
|
138
|
-
export const getWrappingOffsetItem =
|
|
139
|
-
|
|
140
|
-
{state}: NavigationInput,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (offset === -1) {
|
|
149
|
-
return getLast(index, {state});
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const items = state.items;
|
|
153
|
-
|
|
154
|
-
let nextIndex = index + offset;
|
|
155
|
-
|
|
156
|
-
// calculate idealLength as in if the grid was a perfect rectangle
|
|
157
|
-
const rows = Math.ceil(items.length / state.columnCount);
|
|
158
|
-
const idealLength = rows * state.columnCount;
|
|
159
|
-
if (nextIndex < 0) {
|
|
160
|
-
if (offset === -1) {
|
|
161
|
-
// if the offset is -1, we want to wrap to the end
|
|
162
|
-
nextIndex = items.length - 1;
|
|
163
|
-
} else {
|
|
164
|
-
// if the offset is smaller than -1, we want to wrap by column
|
|
165
|
-
if (idealLength + nextIndex >= items.length) {
|
|
166
|
-
// we'll overflow the grid because there isn't enough items. Move `nextIndex` up so we wrap in
|
|
167
|
-
// the right spot
|
|
168
|
-
nextIndex -= state.columnCount;
|
|
138
|
+
export const getWrappingOffsetItem =
|
|
139
|
+
(offset: number) =>
|
|
140
|
+
(index: number, {state}: NavigationInput, tries = state.items.length): number => {
|
|
141
|
+
if (Number.isNaN(index)) {
|
|
142
|
+
// we have no valid index. If the offset is positive, we'll return the first item
|
|
143
|
+
if (offset === 1) {
|
|
144
|
+
return getFirst(index, {state});
|
|
145
|
+
}
|
|
146
|
+
if (offset === -1) {
|
|
147
|
+
return getLast(index, {state});
|
|
169
148
|
}
|
|
170
|
-
nextIndex = idealLength + nextIndex;
|
|
171
149
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
150
|
+
const items = state.items;
|
|
151
|
+
|
|
152
|
+
let nextIndex = index + offset;
|
|
153
|
+
|
|
154
|
+
// calculate idealLength as in if the grid was a perfect rectangle
|
|
155
|
+
const rows = Math.ceil(items.length / state.columnCount);
|
|
156
|
+
const idealLength = rows * state.columnCount;
|
|
157
|
+
if (nextIndex < 0) {
|
|
158
|
+
if (offset === -1) {
|
|
159
|
+
// if the offset is -1, we want to wrap to the end
|
|
160
|
+
nextIndex = items.length - 1;
|
|
161
|
+
} else {
|
|
162
|
+
// if the offset is smaller than -1, we want to wrap by column
|
|
163
|
+
if (idealLength + nextIndex >= items.length) {
|
|
164
|
+
// we'll overflow the grid because there isn't enough items. Move `nextIndex` up so we wrap in
|
|
165
|
+
// the right spot
|
|
166
|
+
nextIndex -= state.columnCount;
|
|
167
|
+
}
|
|
168
|
+
nextIndex = idealLength + nextIndex;
|
|
169
|
+
}
|
|
170
|
+
} else if (nextIndex >= items.length) {
|
|
171
|
+
if (offset === 1) {
|
|
172
|
+
// if the offset is 1, we want to wrap to the beginning
|
|
173
|
+
nextIndex = 0;
|
|
174
|
+
} else {
|
|
175
|
+
// if the offset is larger than 1, we want to wrap by column
|
|
176
|
+
if (nextIndex - idealLength < 0) {
|
|
177
|
+
// we're going to overflow the grid because there isn't enough items. Move `nextIndex` down to
|
|
178
|
+
// the missing item in the next row. This way we'll end up wrapping in the right spot
|
|
179
|
+
nextIndex += state.columnCount;
|
|
180
|
+
}
|
|
181
|
+
nextIndex = nextIndex - idealLength;
|
|
182
182
|
}
|
|
183
|
-
nextIndex = nextIndex - idealLength;
|
|
184
183
|
}
|
|
185
|
-
}
|
|
186
184
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
185
|
+
if (items.length > 1 && state.nonInteractiveIds.includes(items[nextIndex].id) && tries > 0) {
|
|
186
|
+
// The next item is disabled, try again, but only if we haven't already tried everything.
|
|
187
|
+
// Avoid an infinite loop with `tries`
|
|
188
|
+
return getWrappingOffsetItem(offset)(nextIndex, {state}, tries - 1);
|
|
189
|
+
}
|
|
192
190
|
|
|
193
|
-
|
|
194
|
-
};
|
|
191
|
+
return nextIndex;
|
|
192
|
+
};
|
|
195
193
|
|
|
196
|
-
export const getOffsetItem =
|
|
197
|
-
|
|
198
|
-
{state}: NavigationInput,
|
|
199
|
-
|
|
200
|
-
): number => {
|
|
201
|
-
const {items, columnCount} = state;
|
|
194
|
+
export const getOffsetItem =
|
|
195
|
+
(offset: number) =>
|
|
196
|
+
(index: number, {state}: NavigationInput, tries = state.items.length): number => {
|
|
197
|
+
const {items, columnCount} = state;
|
|
202
198
|
|
|
203
|
-
|
|
199
|
+
let nextIndex = index + offset;
|
|
204
200
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
201
|
+
if (Math.abs(offset) < columnCount) {
|
|
202
|
+
// if we're here, the columnCount is non-zero and the absolute value of offset is less than the
|
|
203
|
+
// column count. We don't want to wrap, so we'll bound within the row
|
|
208
204
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
205
|
+
const currentIndexInRow = index % columnCount;
|
|
206
|
+
const nextIndexInRow = nextIndex - index + currentIndexInRow;
|
|
207
|
+
if (nextIndexInRow >= columnCount || nextIndexInRow < 0) {
|
|
208
|
+
nextIndex = index;
|
|
209
|
+
}
|
|
210
|
+
} else if (columnCount) {
|
|
211
|
+
// if we're here, there's a column count, but the offset will move into another row. We need to
|
|
212
|
+
// bound to row values
|
|
213
|
+
const nextRow = Math.floor(nextIndex / columnCount);
|
|
218
214
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
if (nextRow < 0 || nextRow >= columnCount) {
|
|
216
|
+
nextIndex = index;
|
|
217
|
+
}
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
// make sure we don't go out of bounds if the grid isn't a perfect rectangle
|
|
220
|
+
if (nextIndex > items.length - 1) {
|
|
221
|
+
nextIndex = index;
|
|
222
|
+
}
|
|
226
223
|
}
|
|
227
|
-
}
|
|
228
224
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
225
|
+
// make sure we're always in bounds
|
|
226
|
+
if (nextIndex < 0) {
|
|
227
|
+
nextIndex = 0;
|
|
228
|
+
} else if (nextIndex >= items.length) {
|
|
229
|
+
nextIndex = items.length - 1;
|
|
230
|
+
}
|
|
235
231
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
232
|
+
if (state.nonInteractiveIds.includes(items[nextIndex].id) && tries > 0) {
|
|
233
|
+
// The next item is disabled, try again, but only if we haven't already tried everything.
|
|
234
|
+
// Avoid an infinite loop with `tries`
|
|
235
|
+
return getOffsetItem(offset)(nextIndex, {state}, tries - 1);
|
|
236
|
+
}
|
|
241
237
|
|
|
242
|
-
|
|
243
|
-
};
|
|
238
|
+
return nextIndex;
|
|
239
|
+
};
|
|
244
240
|
|
|
245
241
|
/**
|
|
246
242
|
* The default navigation manager of lists. This navigation manager will wrap around when the edge
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {createElemPropsHook} from '@workday/canvas-kit-react/common';
|
|
2
|
-
import {useListModel} from '@workday/canvas-kit-react/collection';
|
|
2
|
+
import {useListModel, Item} from '@workday/canvas-kit-react/collection';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* This elemProps hook allows for children values to be considered identifiers if the children are
|
|
@@ -27,9 +27,9 @@ import {useListModel} from '@workday/canvas-kit-react/collection';
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export const useListItemAllowChildStrings = createElemPropsHook(useListModel)(
|
|
30
|
-
(_, __, elemProps: {'data-id'?: string; children?: React.ReactNode} = {}) => {
|
|
30
|
+
(_, __, elemProps: {'data-id'?: string; children?: React.ReactNode; item?: Item<any>} = {}) => {
|
|
31
31
|
const props: {'data-id'?: string} = {};
|
|
32
|
-
if (!elemProps['data-id'] && typeof elemProps.children === 'string') {
|
|
32
|
+
if (!elemProps['data-id'] && !elemProps.item && typeof elemProps.children === 'string') {
|
|
33
33
|
props['data-id'] = elemProps.children;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -74,6 +74,7 @@ export const useComboboxInput = composeHooks(
|
|
|
74
74
|
'aria-expanded': model.state.visibility === 'visible',
|
|
75
75
|
'aria-autocomplete': 'list',
|
|
76
76
|
'aria-controls': `${model.state.id}-list`,
|
|
77
|
+
'aria-activedescendant': model.state.visibility === 'hidden' ? null : undefined, // Removes activedescendant on menu close
|
|
77
78
|
id: model.state.id,
|
|
78
79
|
ref: elementRef,
|
|
79
80
|
} as const;
|
|
@@ -57,13 +57,13 @@ export const useComboboxKeyboardTypeAhead = createElemPropsHook(useComboboxModel
|
|
|
57
57
|
return -1;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
const
|
|
61
|
-
|
|
60
|
+
const currentItemIndex =
|
|
61
|
+
model.state.items.length > 0 ? model.navigation.getItem(model.state.cursorId, model).index : 0;
|
|
62
62
|
|
|
63
63
|
const handleKeyboardTypeAhead = (key: string, numOptions: number) => {
|
|
64
64
|
// If the starting point is beyond the list of options, reset it
|
|
65
65
|
// to the beginning of the list
|
|
66
|
-
const startNumber = keySofar.current.length === 0 ?
|
|
66
|
+
const startNumber = keySofar.current.length === 0 ? currentItemIndex + 1 : currentItemIndex;
|
|
67
67
|
|
|
68
68
|
const start = startNumber === numOptions ? 0 : startNumber;
|
|
69
69
|
|
|
@@ -56,8 +56,7 @@ export const useComboboxModel = createModelHook({
|
|
|
56
56
|
const menu = useMenuModel(
|
|
57
57
|
useMenuModel.mergeConfig(config, {
|
|
58
58
|
onSelect({id}) {
|
|
59
|
-
|
|
60
|
-
dispatchInputEvent(menu.state.targetRef.current, textValue);
|
|
59
|
+
dispatchInputEvent(menu.state.targetRef.current, id);
|
|
61
60
|
},
|
|
62
61
|
})
|
|
63
62
|
);
|
package/common/README.md
CHANGED
|
@@ -10,16 +10,32 @@ yarn add @workday/canvas-kit-react
|
|
|
10
10
|
|
|
11
11
|
Includes:
|
|
12
12
|
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- [
|
|
21
|
-
|
|
22
|
-
- [
|
|
13
|
+
- [Canvas Kit Common](#canvas-kit-common)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [CanvasProvider](#canvasprovider)
|
|
16
|
+
- [Storybook Decorator](#storybook-decorator)
|
|
17
|
+
- [Input Provider](#input-provider)
|
|
18
|
+
- [Definitions](#definitions)
|
|
19
|
+
- [Usage](#usage)
|
|
20
|
+
- [Static Properties](#static-properties)
|
|
21
|
+
- [`InputTypes`](#inputtypes)
|
|
22
|
+
- [Component Props](#component-props)
|
|
23
|
+
- [Required](#required)
|
|
24
|
+
- [Optional](#optional)
|
|
25
|
+
- [`provideIntent: boolean`](#provideintent-boolean)
|
|
26
|
+
- [`container: HTMLElement | React.RefObject<HTMLElement>`](#container-htmlelement--reactrefobjecthtmlelement)
|
|
27
|
+
- [Storybook Decorator](#storybook-decorator-1)
|
|
28
|
+
- [Theming](#theming)
|
|
29
|
+
- [Bidirectionality](#bidirectionality)
|
|
30
|
+
- [Component Functions](#component-functions)
|
|
31
|
+
- [`createComponent`](#createcomponent)
|
|
32
|
+
- [`ExtractProps`](#extractprops)
|
|
33
|
+
- [Common Hooks](#common-hooks)
|
|
34
|
+
- [useUniqueId](#useuniqueid)
|
|
35
|
+
- [Utility Functions](#utility-functions)
|
|
36
|
+
- [generateUniqueId](#generateuniqueid)
|
|
37
|
+
- [setUniqueSeed](#setuniqueseed)
|
|
38
|
+
- [resetUniqueIdCount](#resetuniqueidcount)
|
|
23
39
|
|
|
24
40
|
## CanvasProvider
|
|
25
41
|
|
|
@@ -71,7 +87,7 @@ MyStory.decorators = [CanvasProviderDecorator];
|
|
|
71
87
|
### Input Provider
|
|
72
88
|
|
|
73
89
|
This is a higher order (wrapping) component for providing css-referencable data attributes for the
|
|
74
|
-
users current input. Focus outlines are required for
|
|
90
|
+
users current input. Focus outlines are required for accessibility, but they can be unnecessary
|
|
75
91
|
visual noise when using a mouse. This allows us to hide focus outlines (as desired) while the user
|
|
76
92
|
is interacting with components using a mouse, touch, etc. and show them when keyboard navigation
|
|
77
93
|
begins. This logic is heavily influenced by [what-input](https://github.com/ten1seven/what-input).
|
|
@@ -344,7 +360,7 @@ this example, `onClick` doesn't exist on `MyComponent`, but since `MyComponent`
|
|
|
344
360
|
If we inspect the `MyNewComponentProps` type, it will return the following:
|
|
345
361
|
|
|
346
362
|
```tsx
|
|
347
|
-
MyComponentProps & React.HTMLAttributes<HTMLElement
|
|
363
|
+
MyComponentProps & React.HTMLAttributes<HTMLElement>;
|
|
348
364
|
```
|
|
349
365
|
|
|
350
366
|
Inside Canvas Kit components, we use `ExtractProps` when we need to extend from the interfaces of
|
|
@@ -377,9 +393,11 @@ be returned since there is not HTML attribute interface associated with `Compone
|
|
|
377
393
|
|
|
378
394
|
### useUniqueId
|
|
379
395
|
|
|
380
|
-
A hook to generate a unique identifier for an element
|
|
396
|
+
A hook to generate a unique identifier for an element – most commonly used for accessibility. The
|
|
381
397
|
hook will generate a unique id the first render and always return the same id every render. This
|
|
382
|
-
uses [generateUniqueId](#generateuniqueid) internally.
|
|
398
|
+
uses [generateUniqueId](#generateuniqueid) internally. You should use `useUniqueId` when you need to
|
|
399
|
+
create a unique ID within a component's render loop. Otherwise, you should opt for
|
|
400
|
+
`generateUniqueId`.
|
|
383
401
|
|
|
384
402
|
```tsx
|
|
385
403
|
const MyComponent = () => {
|
|
@@ -53,10 +53,10 @@ export function errorRing(error?: ErrorType, theme?: EmotionCanvasTheme): CSSObj
|
|
|
53
53
|
borderColor: errorColors.outer,
|
|
54
54
|
transition: '100ms box-shadow',
|
|
55
55
|
boxShadow: errorBoxShadow,
|
|
56
|
-
'&:hover, &:disabled': {
|
|
56
|
+
'&:hover, &:disabled, &.hover, &.disabled': {
|
|
57
57
|
borderColor: errorColors.outer,
|
|
58
58
|
},
|
|
59
|
-
'&:focus:not([disabled])': {
|
|
59
|
+
'&:focus-visible:not([disabled]), &.focus:not([disabled])': {
|
|
60
60
|
borderColor: errorColors.outer,
|
|
61
61
|
boxShadow: `${errorBoxShadow},
|
|
62
62
|
0 0 0 2px ${colors.frenchVanilla100},
|