@khanacademy/wonder-blocks-dropdown 3.0.29 → 3.1.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/CHANGELOG.md +6 -0
- package/dist/components/multi-select.d.ts +9 -5
- package/dist/components/select-opener.d.ts +9 -4
- package/dist/components/single-select.d.ts +11 -7
- package/dist/es/index.js +107 -94
- package/dist/index.js +107 -94
- package/dist/util/types.d.ts +1 -0
- package/package.json +2 -1
- package/src/components/__tests__/multi-select.test.tsx +60 -12
- package/src/components/__tests__/single-select.test.tsx +51 -1
- package/src/components/dropdown-core.tsx +23 -5
- package/src/components/multi-select.tsx +33 -22
- package/src/components/select-opener.tsx +68 -52
- package/src/components/single-select.tsx +30 -21
- package/src/util/constants.ts +3 -3
- package/src/util/types.ts +4 -0
- package/tsconfig-build.json +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@ import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
|
3
3
|
import DropdownOpener from "./dropdown-opener";
|
|
4
4
|
import SelectOpener from "./select-opener";
|
|
5
5
|
import OptionItem from "./option-item";
|
|
6
|
-
import type { DropdownItem, OpenerProps } from "../util/types";
|
|
6
|
+
import type { DropdownItem, OpenerProps, OptionItemComponentArray } from "../util/types";
|
|
7
7
|
export type Labels = {
|
|
8
8
|
/**
|
|
9
9
|
* Label for describing the dismiss icon on the search filter.
|
|
@@ -49,6 +49,10 @@ type DefaultProps = Readonly<{
|
|
|
49
49
|
* and does not support interaction. Defaults to false.
|
|
50
50
|
*/
|
|
51
51
|
disabled: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether this component is in an error state. Defaults to false.
|
|
54
|
+
*/
|
|
55
|
+
error: boolean;
|
|
52
56
|
/**
|
|
53
57
|
* Whether to display the "light" version of this component instead, for
|
|
54
58
|
* use when the component is used on a dark background.
|
|
@@ -185,14 +189,14 @@ export default class MultiSelect extends React.Component<Props, State> {
|
|
|
185
189
|
handleToggle: (selectedValue: string) => void;
|
|
186
190
|
handleSelectAll: () => void;
|
|
187
191
|
handleSelectNone: () => void;
|
|
188
|
-
getMenuText(children:
|
|
189
|
-
getShortcuts(numOptions: number):
|
|
190
|
-
getMenuItems(children:
|
|
192
|
+
getMenuText(children: OptionItemComponentArray): string;
|
|
193
|
+
getShortcuts(numOptions: number): DropdownItem[];
|
|
194
|
+
getMenuItems(children: OptionItemComponentArray): DropdownItem[];
|
|
191
195
|
mapOptionItemToDropdownItem: (option: React.ReactElement<React.ComponentProps<typeof OptionItem>>) => DropdownItem;
|
|
192
196
|
handleOpenerRef: (node?: any) => void;
|
|
193
197
|
handleSearchTextChanged: (searchText: string) => void;
|
|
194
198
|
handleClick: (e: React.SyntheticEvent) => void;
|
|
195
|
-
renderOpener(allChildren:
|
|
199
|
+
renderOpener(allChildren: React.ReactElement<React.ComponentProps<typeof OptionItem>>[]): React.ReactElement<React.ComponentProps<typeof DropdownOpener>> | React.ReactElement<React.ComponentProps<typeof SelectOpener>>;
|
|
196
200
|
render(): React.ReactNode;
|
|
197
201
|
}
|
|
198
202
|
export {};
|
|
@@ -10,6 +10,10 @@ type SelectOpenerProps = AriaProps & {
|
|
|
10
10
|
* Default false.
|
|
11
11
|
*/
|
|
12
12
|
disabled: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether or not the input is in an error state. Defaults to false.
|
|
15
|
+
*/
|
|
16
|
+
error: boolean;
|
|
13
17
|
/**
|
|
14
18
|
* Auto-populated by parent. Used for accessibility purposes, where the label
|
|
15
19
|
* id should match the field id.
|
|
@@ -25,10 +29,6 @@ type SelectOpenerProps = AriaProps & {
|
|
|
25
29
|
* use when the item is used on a dark background.
|
|
26
30
|
*/
|
|
27
31
|
light: boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Test ID used for e2e testing.
|
|
30
|
-
*/
|
|
31
|
-
testId?: string;
|
|
32
32
|
/**
|
|
33
33
|
* Callback for when the SelectOpener is pressed.
|
|
34
34
|
*/
|
|
@@ -37,9 +37,14 @@ type SelectOpenerProps = AriaProps & {
|
|
|
37
37
|
* Whether the dropdown is open.
|
|
38
38
|
*/
|
|
39
39
|
open: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Test ID used for e2e testing.
|
|
42
|
+
*/
|
|
43
|
+
testId?: string;
|
|
40
44
|
};
|
|
41
45
|
type DefaultProps = {
|
|
42
46
|
disabled: SelectOpenerProps["disabled"];
|
|
47
|
+
error: SelectOpenerProps["error"];
|
|
43
48
|
light: SelectOpenerProps["light"];
|
|
44
49
|
isPlaceholder: SelectOpenerProps["isPlaceholder"];
|
|
45
50
|
};
|
|
@@ -3,7 +3,7 @@ import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
|
3
3
|
import DropdownOpener from "./dropdown-opener";
|
|
4
4
|
import SelectOpener from "./select-opener";
|
|
5
5
|
import OptionItem from "./option-item";
|
|
6
|
-
import type { DropdownItem, OpenerProps } from "../util/types";
|
|
6
|
+
import type { DropdownItem, OpenerProps, OptionItemComponentArray } from "../util/types";
|
|
7
7
|
export type SingleSelectLabels = {
|
|
8
8
|
/**
|
|
9
9
|
* Label for describing the dismiss icon on the search filter.
|
|
@@ -32,6 +32,11 @@ type DefaultProps = Readonly<{
|
|
|
32
32
|
* Whether to auto focus an option. Defaults to true.
|
|
33
33
|
*/
|
|
34
34
|
autoFocus: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether this component is disabled. A disabled dropdown may not be opened
|
|
37
|
+
* and does not support interaction. Defaults to false.
|
|
38
|
+
*/
|
|
39
|
+
disabled: boolean;
|
|
35
40
|
/**
|
|
36
41
|
* Whether to enable the type-ahead suggestions feature. Defaults to true.
|
|
37
42
|
*
|
|
@@ -47,10 +52,9 @@ type DefaultProps = Readonly<{
|
|
|
47
52
|
*/
|
|
48
53
|
enableTypeAhead: boolean;
|
|
49
54
|
/**
|
|
50
|
-
* Whether
|
|
51
|
-
* and does not support interaction. Defaults to false.
|
|
55
|
+
* Whether or not the input in is an error state. Defaults to false.
|
|
52
56
|
*/
|
|
53
|
-
|
|
57
|
+
error: boolean;
|
|
54
58
|
/**
|
|
55
59
|
* Whether to display the "light" version of this component instead, for
|
|
56
60
|
* use when the component is used on a dark background.
|
|
@@ -194,9 +198,9 @@ export default class SingleSelect extends React.Component<Props, State> {
|
|
|
194
198
|
static getDerivedStateFromProps(props: Props, state: State): Partial<State> | null;
|
|
195
199
|
handleOpenChanged: (opened: boolean) => void;
|
|
196
200
|
handleToggle: (selectedValue: string) => void;
|
|
197
|
-
mapOptionItemsToDropdownItems: (children:
|
|
198
|
-
filterChildren(children:
|
|
199
|
-
getMenuItems(children:
|
|
201
|
+
mapOptionItemsToDropdownItems: (children: OptionItemComponentArray) => DropdownItem[];
|
|
202
|
+
filterChildren(children: OptionItemComponentArray): OptionItemComponentArray;
|
|
203
|
+
getMenuItems(children: OptionItemComponentArray): DropdownItem[];
|
|
200
204
|
handleSearchTextChanged: (searchText: string) => void;
|
|
201
205
|
handleOpenerRef: (node?: any) => void;
|
|
202
206
|
handleClick: (e: React.SyntheticEvent) => void;
|
package/dist/es/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
|
7
7
|
import { LabelMedium, LabelLarge } from '@khanacademy/wonder-blocks-typography';
|
|
8
8
|
import { getClickableBehavior, isClientSideUrl, ClickableBehavior } from '@khanacademy/wonder-blocks-clickable';
|
|
9
9
|
import { addStyle, View } from '@khanacademy/wonder-blocks-core';
|
|
10
|
+
import { tokens } from '@khanacademy/wonder-blocks-theming';
|
|
10
11
|
import Icon, { icons } from '@khanacademy/wonder-blocks-icon';
|
|
11
12
|
import * as ReactDOM from 'react-dom';
|
|
12
13
|
import SearchField from '@khanacademy/wonder-blocks-search-field';
|
|
@@ -40,8 +41,8 @@ const keyCodes = {
|
|
|
40
41
|
down: 40
|
|
41
42
|
};
|
|
42
43
|
const selectDropdownStyle = {
|
|
43
|
-
marginTop:
|
|
44
|
-
marginBottom:
|
|
44
|
+
marginTop: tokens.spacing.xSmall_8,
|
|
45
|
+
marginBottom: tokens.spacing.xSmall_8
|
|
45
46
|
};
|
|
46
47
|
const filterableDropdownStyle = {
|
|
47
48
|
minHeight: 100
|
|
@@ -61,10 +62,10 @@ const defaultLabels = {
|
|
|
61
62
|
};
|
|
62
63
|
|
|
63
64
|
const {
|
|
64
|
-
blue: blue$
|
|
65
|
-
white: white$
|
|
66
|
-
offBlack: offBlack$
|
|
67
|
-
offBlack32: offBlack32$
|
|
65
|
+
blue: blue$2,
|
|
66
|
+
white: white$3,
|
|
67
|
+
offBlack: offBlack$2,
|
|
68
|
+
offBlack32: offBlack32$3
|
|
68
69
|
} = Color;
|
|
69
70
|
const StyledAnchor = addStyle("a");
|
|
70
71
|
const StyledButton$2 = addStyle("button");
|
|
@@ -139,8 +140,8 @@ ActionItem.defaultProps = {
|
|
|
139
140
|
ActionItem.__IS_ACTION_ITEM__ = true;
|
|
140
141
|
const styles$8 = StyleSheet.create({
|
|
141
142
|
shared: {
|
|
142
|
-
background: white$
|
|
143
|
-
color: offBlack$
|
|
143
|
+
background: white$3,
|
|
144
|
+
color: offBlack$2,
|
|
144
145
|
textDecoration: "none",
|
|
145
146
|
border: "none",
|
|
146
147
|
outline: "none",
|
|
@@ -161,15 +162,15 @@ const styles$8 = StyleSheet.create({
|
|
|
161
162
|
marginLeft: Spacing.medium_16
|
|
162
163
|
},
|
|
163
164
|
focus: {
|
|
164
|
-
color: white$
|
|
165
|
-
background: blue$
|
|
165
|
+
color: white$3,
|
|
166
|
+
background: blue$2
|
|
166
167
|
},
|
|
167
168
|
active: {
|
|
168
|
-
color: mix(fade(blue$
|
|
169
|
-
background: mix(offBlack32$
|
|
169
|
+
color: mix(fade(blue$2, 0.32), white$3),
|
|
170
|
+
background: mix(offBlack32$3, blue$2)
|
|
170
171
|
},
|
|
171
172
|
disabled: {
|
|
172
|
-
color: offBlack32$
|
|
173
|
+
color: offBlack32$3,
|
|
173
174
|
cursor: "default"
|
|
174
175
|
}
|
|
175
176
|
});
|
|
@@ -188,9 +189,9 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
const {
|
|
191
|
-
offBlack: offBlack$
|
|
192
|
-
offBlack32: offBlack32$
|
|
193
|
-
white: white$
|
|
192
|
+
offBlack: offBlack$1,
|
|
193
|
+
offBlack32: offBlack32$2,
|
|
194
|
+
white: white$2
|
|
194
195
|
} = Color;
|
|
195
196
|
const Check = function Check(props) {
|
|
196
197
|
const {
|
|
@@ -203,7 +204,7 @@ const Check = function Check(props) {
|
|
|
203
204
|
return React.createElement(Icon, {
|
|
204
205
|
icon: icons.check,
|
|
205
206
|
size: "small",
|
|
206
|
-
color: disabled ? offBlack32$
|
|
207
|
+
color: disabled ? offBlack32$2 : pressed || hovered || focused ? white$2 : offBlack$1,
|
|
207
208
|
style: [styles$7.bounds, !selected && styles$7.hide]
|
|
208
209
|
});
|
|
209
210
|
};
|
|
@@ -221,10 +222,10 @@ const checkboxCheck = {
|
|
|
221
222
|
small: "M11.263 4.324a1 1 0 1 1 1.474 1.352l-5.5 6a1 1 0 0 1-1.505-.036l-2.5-3a1 1 0 1 1 1.536-1.28L6.536 9.48l4.727-5.157z"
|
|
222
223
|
};
|
|
223
224
|
const {
|
|
224
|
-
blue: blue$
|
|
225
|
-
white: white$
|
|
226
|
-
offBlack16
|
|
227
|
-
offBlack32: offBlack32$
|
|
225
|
+
blue: blue$1,
|
|
226
|
+
white: white$1,
|
|
227
|
+
offBlack16,
|
|
228
|
+
offBlack32: offBlack32$1,
|
|
228
229
|
offBlack50,
|
|
229
230
|
offWhite
|
|
230
231
|
} = Color;
|
|
@@ -236,10 +237,10 @@ const Checkbox = function Checkbox(props) {
|
|
|
236
237
|
hovered,
|
|
237
238
|
focused
|
|
238
239
|
} = props;
|
|
239
|
-
const activeBlue = mix(offBlack32$
|
|
240
|
+
const activeBlue = mix(offBlack32$1, blue$1);
|
|
240
241
|
const clickInteraction = pressed || hovered || focused;
|
|
241
|
-
const bgColor = disabled ? offWhite : selected && !clickInteraction ? blue$
|
|
242
|
-
const checkColor = disabled ? offBlack32$
|
|
242
|
+
const bgColor = disabled ? offWhite : selected && !clickInteraction ? blue$1 : white$1;
|
|
243
|
+
const checkColor = disabled ? offBlack32$1 : clickInteraction ? pressed ? activeBlue : blue$1 : white$1;
|
|
243
244
|
return React.createElement(View, {
|
|
244
245
|
style: [styles$6.checkbox, (clickInteraction || selected && !disabled) && styles$6.noBorder, disabled && styles$6.disabledCheckbox, {
|
|
245
246
|
backgroundColor: bgColor
|
|
@@ -264,7 +265,7 @@ const styles$6 = StyleSheet.create({
|
|
|
264
265
|
borderWidth: 0
|
|
265
266
|
},
|
|
266
267
|
disabledCheckbox: {
|
|
267
|
-
borderColor: offBlack16
|
|
268
|
+
borderColor: offBlack16,
|
|
268
269
|
backgroundColor: offWhite
|
|
269
270
|
},
|
|
270
271
|
disabledCheckFormatting: {
|
|
@@ -350,16 +351,16 @@ OptionItem.defaultProps = {
|
|
|
350
351
|
};
|
|
351
352
|
OptionItem.__IS_OPTION_ITEM__ = true;
|
|
352
353
|
const {
|
|
353
|
-
blue
|
|
354
|
-
white
|
|
355
|
-
offBlack
|
|
356
|
-
offBlack32
|
|
354
|
+
blue,
|
|
355
|
+
white,
|
|
356
|
+
offBlack,
|
|
357
|
+
offBlack32
|
|
357
358
|
} = Color;
|
|
358
359
|
const styles$5 = StyleSheet.create({
|
|
359
360
|
itemContainer: {
|
|
360
361
|
flexDirection: "row",
|
|
361
|
-
background: white
|
|
362
|
-
color: offBlack
|
|
362
|
+
background: white,
|
|
363
|
+
color: offBlack,
|
|
363
364
|
alignItems: "center",
|
|
364
365
|
height: DROPDOWN_ITEM_HEIGHT,
|
|
365
366
|
minHeight: DROPDOWN_ITEM_HEIGHT,
|
|
@@ -371,16 +372,16 @@ const styles$5 = StyleSheet.create({
|
|
|
371
372
|
cursor: "default"
|
|
372
373
|
},
|
|
373
374
|
focus: {
|
|
374
|
-
color: white
|
|
375
|
-
background: blue
|
|
375
|
+
color: white,
|
|
376
|
+
background: blue
|
|
376
377
|
},
|
|
377
378
|
active: {
|
|
378
|
-
color: mix(fade(blue
|
|
379
|
-
background: mix(offBlack32
|
|
379
|
+
color: mix(fade(blue, 0.32), white),
|
|
380
|
+
background: mix(offBlack32, blue)
|
|
380
381
|
},
|
|
381
382
|
disabled: {
|
|
382
|
-
color: offBlack32
|
|
383
|
-
background: white
|
|
383
|
+
color: offBlack32,
|
|
384
|
+
background: white
|
|
384
385
|
},
|
|
385
386
|
label: {
|
|
386
387
|
whiteSpace: "nowrap",
|
|
@@ -1109,9 +1110,13 @@ class DropdownCore extends React.Component {
|
|
|
1109
1110
|
}
|
|
1110
1111
|
renderDropdownMenu(listRenderer, isReferenceHidden) {
|
|
1111
1112
|
const {
|
|
1113
|
+
"aria-invalid": ariaInvalid,
|
|
1114
|
+
"aria-required": ariaRequired,
|
|
1112
1115
|
dropdownStyle,
|
|
1116
|
+
isFilterable,
|
|
1113
1117
|
light,
|
|
1114
|
-
openerElement
|
|
1118
|
+
openerElement,
|
|
1119
|
+
role
|
|
1115
1120
|
} = this.props;
|
|
1116
1121
|
const openerStyle = openerElement && window.getComputedStyle(openerElement);
|
|
1117
1122
|
const minDropdownWidth = openerStyle ? openerStyle.getPropertyValue("width") : 0;
|
|
@@ -1120,9 +1125,11 @@ class DropdownCore extends React.Component {
|
|
|
1120
1125
|
onMouseUp: this.handleDropdownMouseUp,
|
|
1121
1126
|
style: [styles$3.dropdown, light && styles$3.light, isReferenceHidden && styles$3.hidden, dropdownStyle],
|
|
1122
1127
|
testId: "dropdown-core-container"
|
|
1123
|
-
},
|
|
1124
|
-
role:
|
|
1125
|
-
style: [styles$3.listboxOrMenu, generateDropdownMenuStyles(minDropdownWidth, maxDropdownHeight)]
|
|
1128
|
+
}, isFilterable && this.renderSearchField(), React.createElement(View, {
|
|
1129
|
+
role: role,
|
|
1130
|
+
style: [styles$3.listboxOrMenu, generateDropdownMenuStyles(minDropdownWidth, maxDropdownHeight)],
|
|
1131
|
+
"aria-invalid": role === "listbox" ? ariaInvalid : undefined,
|
|
1132
|
+
"aria-required": role === "listbox" ? ariaRequired : undefined
|
|
1126
1133
|
}, listRenderer), this.maybeRenderNoResults());
|
|
1127
1134
|
}
|
|
1128
1135
|
renderDropdown() {
|
|
@@ -1509,17 +1516,8 @@ const styles$1 = StyleSheet.create({
|
|
|
1509
1516
|
}
|
|
1510
1517
|
});
|
|
1511
1518
|
|
|
1512
|
-
const _excluded$2 = ["children", "disabled", "id", "isPlaceholder", "light", "open", "testId", "onOpenChanged"];
|
|
1519
|
+
const _excluded$2 = ["children", "disabled", "error", "id", "isPlaceholder", "light", "open", "testId", "onOpenChanged"];
|
|
1513
1520
|
const StyledButton = addStyle("button");
|
|
1514
|
-
const {
|
|
1515
|
-
blue,
|
|
1516
|
-
white,
|
|
1517
|
-
white50,
|
|
1518
|
-
offBlack,
|
|
1519
|
-
offBlack16,
|
|
1520
|
-
offBlack32,
|
|
1521
|
-
offBlack64
|
|
1522
|
-
} = Color;
|
|
1523
1521
|
class SelectOpener extends React.Component {
|
|
1524
1522
|
constructor(...args) {
|
|
1525
1523
|
super(...args);
|
|
@@ -1535,6 +1533,7 @@ class SelectOpener extends React.Component {
|
|
|
1535
1533
|
{
|
|
1536
1534
|
children,
|
|
1537
1535
|
disabled,
|
|
1536
|
+
error,
|
|
1538
1537
|
id,
|
|
1539
1538
|
isPlaceholder,
|
|
1540
1539
|
light,
|
|
@@ -1547,13 +1546,13 @@ class SelectOpener extends React.Component {
|
|
|
1547
1546
|
disabled: disabled,
|
|
1548
1547
|
onClick: this.handleClick
|
|
1549
1548
|
}, (state, childrenProps) => {
|
|
1550
|
-
const stateStyles = _generateStyles(light, isPlaceholder);
|
|
1549
|
+
const stateStyles = _generateStyles(light, isPlaceholder, error);
|
|
1551
1550
|
const {
|
|
1552
1551
|
hovered,
|
|
1553
1552
|
focused,
|
|
1554
1553
|
pressed
|
|
1555
1554
|
} = state;
|
|
1556
|
-
const iconColor = light ? disabled || pressed ? "currentColor" : white : disabled ? offBlack32 : offBlack64;
|
|
1555
|
+
const iconColor = light ? disabled || pressed ? "currentColor" : tokens.color.white : disabled ? tokens.color.offBlack32 : tokens.color.offBlack64;
|
|
1557
1556
|
const style = [styles.shared, stateStyles.default, disabled && stateStyles.disabled, !disabled && (pressed ? stateStyles.active : (hovered || focused) && stateStyles.focus)];
|
|
1558
1557
|
return React.createElement(StyledButton, _extends({}, sharedProps, {
|
|
1559
1558
|
"aria-expanded": open ? "true" : "false",
|
|
@@ -1580,22 +1579,22 @@ class SelectOpener extends React.Component {
|
|
|
1580
1579
|
}
|
|
1581
1580
|
SelectOpener.defaultProps = {
|
|
1582
1581
|
disabled: false,
|
|
1582
|
+
error: false,
|
|
1583
1583
|
light: false,
|
|
1584
1584
|
isPlaceholder: false
|
|
1585
1585
|
};
|
|
1586
|
-
const buttonRadius = 4;
|
|
1587
1586
|
const styles = StyleSheet.create({
|
|
1588
1587
|
shared: {
|
|
1589
1588
|
position: "relative",
|
|
1590
1589
|
display: "inline-flex",
|
|
1591
1590
|
alignItems: "center",
|
|
1592
1591
|
justifyContent: "space-between",
|
|
1593
|
-
color: offBlack,
|
|
1592
|
+
color: tokens.color.offBlack,
|
|
1594
1593
|
height: DROPDOWN_ITEM_HEIGHT,
|
|
1595
|
-
paddingLeft:
|
|
1596
|
-
paddingRight:
|
|
1594
|
+
paddingLeft: tokens.spacing.medium_16,
|
|
1595
|
+
paddingRight: tokens.spacing.small_12,
|
|
1597
1596
|
borderWidth: 0,
|
|
1598
|
-
borderRadius:
|
|
1597
|
+
borderRadius: tokens.border.radius.medium_4,
|
|
1599
1598
|
borderStyle: "solid",
|
|
1600
1599
|
outline: "none",
|
|
1601
1600
|
textDecoration: "none",
|
|
@@ -1604,7 +1603,7 @@ const styles = StyleSheet.create({
|
|
|
1604
1603
|
touchAction: "manipulation"
|
|
1605
1604
|
},
|
|
1606
1605
|
text: {
|
|
1607
|
-
marginRight:
|
|
1606
|
+
marginRight: tokens.spacing.xSmall_8,
|
|
1608
1607
|
whiteSpace: "nowrap",
|
|
1609
1608
|
userSelect: "none",
|
|
1610
1609
|
overflow: "hidden",
|
|
@@ -1614,11 +1613,11 @@ const styles = StyleSheet.create({
|
|
|
1614
1613
|
minWidth: 16
|
|
1615
1614
|
}
|
|
1616
1615
|
});
|
|
1617
|
-
const adjustedPaddingLeft =
|
|
1618
|
-
const adjustedPaddingRight =
|
|
1616
|
+
const adjustedPaddingLeft = tokens.spacing.medium_16 - 1;
|
|
1617
|
+
const adjustedPaddingRight = tokens.spacing.small_12 - 1;
|
|
1619
1618
|
const stateStyles = {};
|
|
1620
|
-
const _generateStyles = (light, placeholder) => {
|
|
1621
|
-
const styleKey = `${
|
|
1619
|
+
const _generateStyles = (light, placeholder, error) => {
|
|
1620
|
+
const styleKey = `${light}-${placeholder}-${error}`;
|
|
1622
1621
|
if (stateStyles[styleKey]) {
|
|
1623
1622
|
return stateStyles[styleKey];
|
|
1624
1623
|
}
|
|
@@ -1626,56 +1625,57 @@ const _generateStyles = (light, placeholder) => {
|
|
|
1626
1625
|
if (light) {
|
|
1627
1626
|
newStyles = {
|
|
1628
1627
|
default: {
|
|
1629
|
-
background: "transparent",
|
|
1630
|
-
color: placeholder ? white50 : white,
|
|
1631
|
-
borderColor: white50,
|
|
1632
|
-
borderWidth:
|
|
1628
|
+
background: error ? tokens.color.fadedRed8 : "transparent",
|
|
1629
|
+
color: placeholder ? tokens.color.white50 : tokens.color.white,
|
|
1630
|
+
borderColor: error ? tokens.color.red : tokens.color.white50,
|
|
1631
|
+
borderWidth: tokens.border.width.hairline
|
|
1633
1632
|
},
|
|
1634
1633
|
focus: {
|
|
1635
|
-
borderColor: white,
|
|
1636
|
-
borderWidth:
|
|
1634
|
+
borderColor: error ? tokens.color.fadedRed8 : tokens.color.white,
|
|
1635
|
+
borderWidth: tokens.spacing.xxxxSmall_2,
|
|
1637
1636
|
paddingLeft: adjustedPaddingLeft,
|
|
1638
1637
|
paddingRight: adjustedPaddingRight
|
|
1639
1638
|
},
|
|
1640
1639
|
active: {
|
|
1641
1640
|
paddingLeft: adjustedPaddingLeft,
|
|
1642
1641
|
paddingRight: adjustedPaddingRight,
|
|
1643
|
-
borderColor:
|
|
1644
|
-
borderWidth:
|
|
1645
|
-
color: placeholder ? mix(
|
|
1646
|
-
backgroundColor:
|
|
1642
|
+
borderColor: error ? tokens.color.red : tokens.color.fadedBlue,
|
|
1643
|
+
borderWidth: tokens.border.width.thin,
|
|
1644
|
+
color: placeholder ? mix(tokens.color.white32, tokens.color.blue) : tokens.color.fadedBlue,
|
|
1645
|
+
backgroundColor: error ? tokens.color.fadedRed : tokens.color.activeBlue
|
|
1647
1646
|
},
|
|
1648
1647
|
disabled: {
|
|
1649
|
-
|
|
1650
|
-
|
|
1648
|
+
background: "transparent",
|
|
1649
|
+
borderColor: mix(tokens.color.white32, tokens.color.blue),
|
|
1650
|
+
color: mix(tokens.color.white32, tokens.color.blue),
|
|
1651
1651
|
cursor: "auto"
|
|
1652
1652
|
}
|
|
1653
1653
|
};
|
|
1654
1654
|
} else {
|
|
1655
1655
|
newStyles = {
|
|
1656
1656
|
default: {
|
|
1657
|
-
background: white,
|
|
1658
|
-
borderColor: offBlack16,
|
|
1659
|
-
borderWidth:
|
|
1660
|
-
color: placeholder ? offBlack64 : offBlack
|
|
1657
|
+
background: error ? tokens.color.fadedRed8 : tokens.color.white,
|
|
1658
|
+
borderColor: error ? tokens.color.red : tokens.color.offBlack16,
|
|
1659
|
+
borderWidth: tokens.border.width.hairline,
|
|
1660
|
+
color: placeholder ? tokens.color.offBlack64 : tokens.color.offBlack
|
|
1661
1661
|
},
|
|
1662
1662
|
focus: {
|
|
1663
|
-
borderColor: blue,
|
|
1664
|
-
borderWidth:
|
|
1663
|
+
borderColor: error ? tokens.color.red : tokens.color.blue,
|
|
1664
|
+
borderWidth: tokens.border.width.thin,
|
|
1665
1665
|
paddingLeft: adjustedPaddingLeft,
|
|
1666
1666
|
paddingRight: adjustedPaddingRight
|
|
1667
1667
|
},
|
|
1668
1668
|
active: {
|
|
1669
|
-
background:
|
|
1670
|
-
borderColor:
|
|
1671
|
-
borderWidth:
|
|
1669
|
+
background: error ? tokens.color.fadedRed : tokens.color.fadedBlue,
|
|
1670
|
+
borderColor: error ? tokens.color.red : tokens.color.activeBlue,
|
|
1671
|
+
borderWidth: tokens.border.width.thin,
|
|
1672
1672
|
paddingLeft: adjustedPaddingLeft,
|
|
1673
1673
|
paddingRight: adjustedPaddingRight
|
|
1674
1674
|
},
|
|
1675
1675
|
disabled: {
|
|
1676
|
-
background:
|
|
1677
|
-
borderColor: offBlack16,
|
|
1678
|
-
color: offBlack64,
|
|
1676
|
+
background: tokens.color.offWhite,
|
|
1677
|
+
borderColor: tokens.color.offBlack16,
|
|
1678
|
+
color: tokens.color.offBlack64,
|
|
1679
1679
|
cursor: "auto"
|
|
1680
1680
|
}
|
|
1681
1681
|
};
|
|
@@ -1684,7 +1684,7 @@ const _generateStyles = (light, placeholder) => {
|
|
|
1684
1684
|
return stateStyles[styleKey];
|
|
1685
1685
|
};
|
|
1686
1686
|
|
|
1687
|
-
const _excluded$1 = ["children", "disabled", "id", "light", "opener", "placeholder", "selectedValue", "testId", "alignment", "autoFocus", "dropdownStyle", "enableTypeAhead", "isFilterable", "labels", "onChange", "onToggle", "opened", "style", "className"];
|
|
1687
|
+
const _excluded$1 = ["children", "disabled", "error", "id", "light", "opener", "placeholder", "selectedValue", "testId", "alignment", "autoFocus", "dropdownStyle", "enableTypeAhead", "isFilterable", "labels", "onChange", "onToggle", "opened", "style", "className", "aria-invalid", "aria-required"];
|
|
1688
1688
|
class SingleSelect extends React.Component {
|
|
1689
1689
|
constructor(props) {
|
|
1690
1690
|
super(props);
|
|
@@ -1786,6 +1786,7 @@ class SingleSelect extends React.Component {
|
|
|
1786
1786
|
{
|
|
1787
1787
|
children,
|
|
1788
1788
|
disabled,
|
|
1789
|
+
error,
|
|
1789
1790
|
id,
|
|
1790
1791
|
light,
|
|
1791
1792
|
opener,
|
|
@@ -1794,7 +1795,8 @@ class SingleSelect extends React.Component {
|
|
|
1794
1795
|
testId
|
|
1795
1796
|
} = _this$props,
|
|
1796
1797
|
sharedProps = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
|
|
1797
|
-
const
|
|
1798
|
+
const items = React.Children.toArray(children);
|
|
1799
|
+
const selectedItem = items.find(option => option.props.value === selectedValue);
|
|
1798
1800
|
const menuText = selectedItem ? selectedItem.props.label : placeholder;
|
|
1799
1801
|
const dropdownOpener = opener ? React.createElement(DropdownOpener, {
|
|
1800
1802
|
onClick: this.handleClick,
|
|
@@ -1804,6 +1806,7 @@ class SingleSelect extends React.Component {
|
|
|
1804
1806
|
}, opener) : React.createElement(SelectOpener, _extends({}, sharedProps, {
|
|
1805
1807
|
disabled: numItems === 0 || disabled,
|
|
1806
1808
|
id: id,
|
|
1809
|
+
error: error,
|
|
1807
1810
|
isPlaceholder: !selectedItem,
|
|
1808
1811
|
light: light,
|
|
1809
1812
|
onOpenChanged: this.handleOpenChanged,
|
|
@@ -1824,7 +1827,9 @@ class SingleSelect extends React.Component {
|
|
|
1824
1827
|
isFilterable,
|
|
1825
1828
|
labels,
|
|
1826
1829
|
light,
|
|
1827
|
-
style
|
|
1830
|
+
style,
|
|
1831
|
+
"aria-invalid": ariaInvalid,
|
|
1832
|
+
"aria-required": ariaRequired
|
|
1828
1833
|
} = this.props;
|
|
1829
1834
|
const {
|
|
1830
1835
|
searchText
|
|
@@ -1851,7 +1856,9 @@ class SingleSelect extends React.Component {
|
|
|
1851
1856
|
isFilterable: isFilterable,
|
|
1852
1857
|
onSearchTextChanged: isFilterable ? this.handleSearchTextChanged : undefined,
|
|
1853
1858
|
searchText: isFilterable ? searchText : "",
|
|
1854
|
-
labels: labels
|
|
1859
|
+
labels: labels,
|
|
1860
|
+
"aria-invalid": ariaInvalid,
|
|
1861
|
+
"aria-required": ariaRequired
|
|
1855
1862
|
});
|
|
1856
1863
|
}
|
|
1857
1864
|
}
|
|
@@ -1860,6 +1867,7 @@ SingleSelect.defaultProps = {
|
|
|
1860
1867
|
autoFocus: true,
|
|
1861
1868
|
disabled: false,
|
|
1862
1869
|
enableTypeAhead: true,
|
|
1870
|
+
error: false,
|
|
1863
1871
|
light: false,
|
|
1864
1872
|
labels: {
|
|
1865
1873
|
clearSearch: defaultLabels.clearSearch,
|
|
@@ -1869,7 +1877,7 @@ SingleSelect.defaultProps = {
|
|
|
1869
1877
|
}
|
|
1870
1878
|
};
|
|
1871
1879
|
|
|
1872
|
-
const _excluded = ["disabled", "id", "light", "opener", "testId", "alignment", "dropdownStyle", "implicitAllEnabled", "isFilterable", "labels", "onChange", "onToggle", "opened", "selectedValues", "shortcuts", "style", "className"];
|
|
1880
|
+
const _excluded = ["disabled", "id", "light", "opener", "testId", "alignment", "dropdownStyle", "implicitAllEnabled", "isFilterable", "labels", "onChange", "onToggle", "opened", "selectedValues", "shortcuts", "style", "className", "aria-invalid", "aria-required"];
|
|
1873
1881
|
class MultiSelect extends React.Component {
|
|
1874
1882
|
constructor(props) {
|
|
1875
1883
|
super(props);
|
|
@@ -2106,7 +2114,9 @@ class MultiSelect extends React.Component {
|
|
|
2106
2114
|
className,
|
|
2107
2115
|
dropdownStyle,
|
|
2108
2116
|
children,
|
|
2109
|
-
isFilterable
|
|
2117
|
+
isFilterable,
|
|
2118
|
+
"aria-invalid": ariaInvalid,
|
|
2119
|
+
"aria-required": ariaRequired
|
|
2110
2120
|
} = this.props;
|
|
2111
2121
|
const {
|
|
2112
2122
|
open,
|
|
@@ -2143,13 +2153,16 @@ class MultiSelect extends React.Component {
|
|
|
2143
2153
|
filter,
|
|
2144
2154
|
noResults,
|
|
2145
2155
|
someResults: someSelected
|
|
2146
|
-
}
|
|
2156
|
+
},
|
|
2157
|
+
"aria-invalid": ariaInvalid,
|
|
2158
|
+
"aria-required": ariaRequired
|
|
2147
2159
|
});
|
|
2148
2160
|
}
|
|
2149
2161
|
}
|
|
2150
2162
|
MultiSelect.defaultProps = {
|
|
2151
2163
|
alignment: "left",
|
|
2152
2164
|
disabled: false,
|
|
2165
|
+
error: false,
|
|
2153
2166
|
light: false,
|
|
2154
2167
|
shortcuts: false,
|
|
2155
2168
|
selectedValues: []
|