@khanacademy/wonder-blocks-dropdown 5.8.1 → 6.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 +46 -0
- package/dist/components/combobox-live-region.d.ts +2 -2
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/dropdown-core-virtualized.d.ts +1 -1
- package/dist/components/dropdown-opener.d.ts +8 -0
- package/dist/components/listbox.d.ts +2 -2
- package/dist/components/multi-select.d.ts +44 -60
- package/dist/components/select-opener.d.ts +4 -0
- package/dist/components/single-select.d.ts +40 -42
- package/dist/es/index.js +475 -418
- package/dist/hooks/use-listbox.d.ts +1 -1
- package/dist/hooks/use-select-validation.d.ts +39 -0
- package/dist/index.js +474 -417
- package/dist/util/constants.d.ts +10 -7
- package/package.json +19 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-dropdown
|
|
2
2
|
|
|
3
|
+
## 6.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 71e70869: # SingleSelect
|
|
8
|
+
|
|
9
|
+
- Add `required`, `validate`, and `onValidate` props to support validation.
|
|
10
|
+
- DropdownOpener and SelectOpener:
|
|
11
|
+
- Add `onBlur` prop
|
|
12
|
+
- Set `aria-invalid` if it is in an error state.
|
|
13
|
+
|
|
14
|
+
- bc4da9ec: # MultiSelect
|
|
15
|
+
|
|
16
|
+
- Add `required`, `validate`, and `onValidate` props to support validation.
|
|
17
|
+
- Set `aria-invalid` on the opener if it is in an error state
|
|
18
|
+
- Share validation logic with SingleSelect
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- c7178e13: Update SingleSelect and MultiSelect to functional components
|
|
23
|
+
- 71e70869: Update `DropdownCore` to check for key presses using `event.key` instead of `event.which` or `event.keyCode` (which are both deprecated now)
|
|
24
|
+
- Updated dependencies [e9a119a8]
|
|
25
|
+
- Updated dependencies [257b6bc3]
|
|
26
|
+
- @khanacademy/wonder-blocks-search-field@3.1.0
|
|
27
|
+
|
|
28
|
+
## 6.0.0
|
|
29
|
+
|
|
30
|
+
### Major Changes
|
|
31
|
+
|
|
32
|
+
- e6abdd17: Upgrade to React 18
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [e6abdd17]
|
|
37
|
+
- @khanacademy/wonder-blocks-timing@6.0.0
|
|
38
|
+
- @khanacademy/wonder-blocks-core@8.0.0
|
|
39
|
+
- @khanacademy/wonder-blocks-cell@4.0.0
|
|
40
|
+
- @khanacademy/wonder-blocks-clickable@5.0.0
|
|
41
|
+
- @khanacademy/wonder-blocks-icon@5.0.0
|
|
42
|
+
- @khanacademy/wonder-blocks-layout@3.0.0
|
|
43
|
+
- @khanacademy/wonder-blocks-modal@6.0.0
|
|
44
|
+
- @khanacademy/wonder-blocks-pill@3.0.0
|
|
45
|
+
- @khanacademy/wonder-blocks-search-field@3.0.0
|
|
46
|
+
- @khanacademy/wonder-blocks-tokens@3.0.0
|
|
47
|
+
- @khanacademy/wonder-blocks-typography@3.0.0
|
|
48
|
+
|
|
3
49
|
## 5.8.1
|
|
4
50
|
|
|
5
51
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import { ComboboxLabels, MaybeValueOrValues, OptionItemComponent } from "../util/types";
|
|
3
3
|
type Props = {
|
|
4
4
|
/**
|
|
@@ -48,5 +48,5 @@ type Props = {
|
|
|
48
48
|
*
|
|
49
49
|
* @see https://bugs.webkit.org/show_bug.cgi?id=167671
|
|
50
50
|
*/
|
|
51
|
-
export declare function ComboboxLiveRegion({ focusedIndex, focusedMultiSelectIndex, labels, selectedLabels, opened, options, selected, selectionType, testId, }: Props): JSX.Element;
|
|
51
|
+
export declare function ComboboxLiveRegion({ focusedIndex, focusedMultiSelectIndex, labels, selectedLabels, opened, options, selected, selectionType, testId, }: Props): React.JSX.Element;
|
|
52
52
|
export {};
|
|
@@ -107,5 +107,5 @@ type Props = {
|
|
|
107
107
|
* Open button (🔽) is pressed.
|
|
108
108
|
* - It is displayed when the combobox receives focus.
|
|
109
109
|
*/
|
|
110
|
-
export default function Combobox({ autoComplete, children, disabled, error, id, labels, onChange, onToggle, opened, placeholder, selectionType, startIcon, testId, value, }: Props): JSX.Element;
|
|
110
|
+
export default function Combobox({ autoComplete, children, disabled, error, id, labels, onChange, onToggle, opened, placeholder, selectionType, startIcon, testId, value, }: Props): React.JSX.Element;
|
|
111
111
|
export {};
|
|
@@ -19,6 +19,10 @@ type Props = Partial<Omit<AriaProps, "aria-disabled">> & {
|
|
|
19
19
|
* Callback for when the opener is pressed.
|
|
20
20
|
*/
|
|
21
21
|
onClick: (e: React.SyntheticEvent) => unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Callback for when the opener is blurred.
|
|
24
|
+
*/
|
|
25
|
+
onBlur?: (e: React.SyntheticEvent) => unknown;
|
|
22
26
|
/**
|
|
23
27
|
* Test ID used for e2e testing.
|
|
24
28
|
*/
|
|
@@ -35,6 +39,10 @@ type Props = Partial<Omit<AriaProps, "aria-disabled">> & {
|
|
|
35
39
|
* The unique identifier for the opener.
|
|
36
40
|
*/
|
|
37
41
|
id?: string;
|
|
42
|
+
/**
|
|
43
|
+
* If the dropdown has an error.
|
|
44
|
+
*/
|
|
45
|
+
error?: boolean;
|
|
38
46
|
};
|
|
39
47
|
type DefaultProps = {
|
|
40
48
|
disabled: Props["disabled"];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import { StyleType } from "@khanacademy/wonder-blocks-core";
|
|
3
3
|
import { MaybeValueOrValues, OptionItemComponent } from "../util/types";
|
|
4
4
|
type Props = {
|
|
@@ -81,5 +81,5 @@ type Props = {
|
|
|
81
81
|
* </Listbox>
|
|
82
82
|
* ```
|
|
83
83
|
*/
|
|
84
|
-
export default function Listbox(props: Props): JSX.Element;
|
|
84
|
+
export default function Listbox(props: Props): React.JSX.Element;
|
|
85
85
|
export {};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type AriaProps, type StyleType } from "@khanacademy/wonder-blocks-core";
|
|
3
|
-
import DropdownOpener from "./dropdown-opener";
|
|
4
|
-
import SelectOpener from "./select-opener";
|
|
5
3
|
import OptionItem from "./option-item";
|
|
6
|
-
import type {
|
|
4
|
+
import type { OpenerProps } from "../util/types";
|
|
7
5
|
export type Labels = {
|
|
8
6
|
/**
|
|
9
7
|
* Label for describing the dismiss icon on the search filter.
|
|
@@ -43,36 +41,36 @@ type DefaultProps = Readonly<{
|
|
|
43
41
|
* Whether this dropdown should be left-aligned or right-aligned with the
|
|
44
42
|
* opener component. Defaults to left-aligned.
|
|
45
43
|
*/
|
|
46
|
-
alignment
|
|
44
|
+
alignment?: "left" | "right";
|
|
47
45
|
/**
|
|
48
46
|
* Whether this component is disabled. A disabled dropdown may not be opened
|
|
49
47
|
* and does not support interaction. Defaults to false.
|
|
50
48
|
*/
|
|
51
|
-
disabled
|
|
49
|
+
disabled?: boolean;
|
|
52
50
|
/**
|
|
53
51
|
* Whether this component is in an error state. Defaults to false.
|
|
54
52
|
*/
|
|
55
|
-
error
|
|
53
|
+
error?: boolean;
|
|
56
54
|
/**
|
|
57
55
|
* Whether to display the "light" version of this component instead, for
|
|
58
56
|
* use when the component is used on a dark background.
|
|
59
57
|
*/
|
|
60
|
-
light
|
|
58
|
+
light?: boolean;
|
|
61
59
|
/**
|
|
62
60
|
* The values of the items that are currently selected.
|
|
63
61
|
*/
|
|
64
|
-
selectedValues
|
|
62
|
+
selectedValues?: Array<string>;
|
|
65
63
|
/**
|
|
66
64
|
* Whether to display shortcuts for Select All and Select None.
|
|
67
65
|
*/
|
|
68
|
-
shortcuts
|
|
66
|
+
shortcuts?: boolean;
|
|
69
67
|
/**
|
|
70
68
|
* When false, the SelectOpener can show a Node as a label. When true, the
|
|
71
69
|
* SelectOpener will use a string as a label. If using custom OptionItems, a
|
|
72
70
|
* plain text label can be provided with the `labelAsText` prop.
|
|
73
71
|
* Defaults to true.
|
|
74
72
|
*/
|
|
75
|
-
showOpenerLabelAsText
|
|
73
|
+
showOpenerLabelAsText?: boolean;
|
|
76
74
|
}>;
|
|
77
75
|
type Props = AriaProps & DefaultProps & Readonly<{
|
|
78
76
|
/**
|
|
@@ -143,32 +141,41 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
143
141
|
* opener's `aria-controls` attribute for screenreaders.
|
|
144
142
|
*/
|
|
145
143
|
dropdownId?: string;
|
|
146
|
-
}>;
|
|
147
|
-
type State = Readonly<{
|
|
148
|
-
/**
|
|
149
|
-
* Whether or not the dropdown is open.
|
|
150
|
-
*/
|
|
151
|
-
open: boolean;
|
|
152
144
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
*
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
|
|
171
|
-
|
|
145
|
+
* Whether this field is required to continue, or the error message to
|
|
146
|
+
* render if this field is left blank.
|
|
147
|
+
*
|
|
148
|
+
* This can be a boolean or a string.
|
|
149
|
+
*
|
|
150
|
+
* String:
|
|
151
|
+
* Please pass in a translated string to use as the error message that will
|
|
152
|
+
* render if the user leaves this field blank. If this field is required,
|
|
153
|
+
* and a string is not passed in, a default untranslated string will render
|
|
154
|
+
* upon error.
|
|
155
|
+
* Note: The string will not be used if a `validate` prop is passed in.
|
|
156
|
+
*
|
|
157
|
+
* Example message: i18n._("A password is required to log in.")
|
|
158
|
+
*
|
|
159
|
+
* Boolean:
|
|
160
|
+
* True/false indicating whether this field is required. Please do not pass
|
|
161
|
+
* in `true` if possible - pass in the error string instead.
|
|
162
|
+
* If `true` is passed, and a `validate` prop is not passed, that means
|
|
163
|
+
* there is no corresponding message and the default untranlsated message
|
|
164
|
+
* will be used.
|
|
165
|
+
*/
|
|
166
|
+
required?: boolean | string;
|
|
167
|
+
/**
|
|
168
|
+
* Provide a validation for the field value.
|
|
169
|
+
* Return a string error message or null | void for a valid input.
|
|
170
|
+
*
|
|
171
|
+
* Use this for errors that are shown to the user while they are filling out
|
|
172
|
+
* a form.
|
|
173
|
+
*/
|
|
174
|
+
validate?: (value: string[]) => string | null | void;
|
|
175
|
+
/**
|
|
176
|
+
* Called right after the field is validated.
|
|
177
|
+
*/
|
|
178
|
+
onValidate?: (errorMessage?: string | null | undefined) => unknown;
|
|
172
179
|
}>;
|
|
173
180
|
/**
|
|
174
181
|
* A dropdown that consists of multiple selection items. This select allows
|
|
@@ -189,28 +196,5 @@ type State = Readonly<{
|
|
|
189
196
|
* </MultiSelect>
|
|
190
197
|
* ```
|
|
191
198
|
*/
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
static defaultProps: DefaultProps;
|
|
195
|
-
constructor(props: Props);
|
|
196
|
-
/**
|
|
197
|
-
* Used to sync the `opened` state when this component acts as a controlled
|
|
198
|
-
* component
|
|
199
|
-
*/
|
|
200
|
-
static getDerivedStateFromProps(props: Props, state: State): Partial<State> | null;
|
|
201
|
-
componentDidUpdate(prevProps: Props): void;
|
|
202
|
-
handleOpenChanged: (opened: boolean) => void;
|
|
203
|
-
handleToggle: (selectedValue: string) => void;
|
|
204
|
-
handleSelectAll: () => void;
|
|
205
|
-
handleSelectNone: () => void;
|
|
206
|
-
getMenuText(children: OptionItemComponentArray): string | JSX.Element;
|
|
207
|
-
getShortcuts(numOptions: number): DropdownItem[];
|
|
208
|
-
getMenuItems(children: OptionItemComponentArray): DropdownItem[];
|
|
209
|
-
mapOptionItemToDropdownItem: (option: OptionItemComponent) => DropdownItem;
|
|
210
|
-
handleOpenerRef: (node?: any) => void;
|
|
211
|
-
handleSearchTextChanged: (searchText: string) => void;
|
|
212
|
-
handleClick: (e: React.SyntheticEvent) => void;
|
|
213
|
-
renderOpener(allChildren: React.ReactElement<React.ComponentProps<typeof OptionItem>>[], isDisabled: boolean, dropdownId: string): React.ReactElement<React.ComponentProps<typeof DropdownOpener>> | React.ReactElement<React.ComponentProps<typeof SelectOpener>>;
|
|
214
|
-
render(): React.ReactNode;
|
|
215
|
-
}
|
|
216
|
-
export {};
|
|
199
|
+
declare const MultiSelect: (props: Props) => React.JSX.Element;
|
|
200
|
+
export default MultiSelect;
|
|
@@ -42,6 +42,10 @@ type SelectOpenerProps = AriaProps & {
|
|
|
42
42
|
* Test ID used for e2e testing.
|
|
43
43
|
*/
|
|
44
44
|
testId?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Called when it is blurred
|
|
47
|
+
*/
|
|
48
|
+
onBlur?: (e: React.SyntheticEvent) => unknown;
|
|
45
49
|
};
|
|
46
50
|
type DefaultProps = {
|
|
47
51
|
disabled: SelectOpenerProps["disabled"];
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type AriaProps, type StyleType } from "@khanacademy/wonder-blocks-core";
|
|
3
|
-
import DropdownOpener from "./dropdown-opener";
|
|
4
|
-
import SelectOpener from "./select-opener";
|
|
5
3
|
import OptionItem from "./option-item";
|
|
6
|
-
import type {
|
|
4
|
+
import type { OpenerProps } from "../util/types";
|
|
7
5
|
export type SingleSelectLabels = {
|
|
8
6
|
/**
|
|
9
7
|
* Label for describing the dismiss icon on the search filter.
|
|
@@ -27,16 +25,16 @@ type DefaultProps = Readonly<{
|
|
|
27
25
|
* Whether this dropdown should be left-aligned or right-aligned with the
|
|
28
26
|
* opener component. Defaults to left-aligned.
|
|
29
27
|
*/
|
|
30
|
-
alignment
|
|
28
|
+
alignment?: "left" | "right";
|
|
31
29
|
/**
|
|
32
30
|
* Whether to auto focus an option. Defaults to true.
|
|
33
31
|
*/
|
|
34
|
-
autoFocus
|
|
32
|
+
autoFocus?: boolean;
|
|
35
33
|
/**
|
|
36
34
|
* Whether this component is disabled. A disabled dropdown may not be opened
|
|
37
35
|
* and does not support interaction. Defaults to false.
|
|
38
36
|
*/
|
|
39
|
-
disabled
|
|
37
|
+
disabled?: boolean;
|
|
40
38
|
/**
|
|
41
39
|
* Whether to enable the type-ahead suggestions feature. Defaults to true.
|
|
42
40
|
*
|
|
@@ -50,27 +48,27 @@ type DefaultProps = Readonly<{
|
|
|
50
48
|
* some cases where it's not desirable (for example when using a `TextField`
|
|
51
49
|
* as the opener element).
|
|
52
50
|
*/
|
|
53
|
-
enableTypeAhead
|
|
51
|
+
enableTypeAhead?: boolean;
|
|
54
52
|
/**
|
|
55
53
|
* Whether or not the input in is an error state. Defaults to false.
|
|
56
54
|
*/
|
|
57
|
-
error
|
|
55
|
+
error?: boolean;
|
|
58
56
|
/**
|
|
59
57
|
* Whether to display the "light" version of this component instead, for
|
|
60
58
|
* use when the component is used on a dark background.
|
|
61
59
|
*/
|
|
62
|
-
light
|
|
60
|
+
light?: boolean;
|
|
63
61
|
/**
|
|
64
62
|
* The object containing the custom labels used inside this component.
|
|
65
63
|
*/
|
|
66
|
-
labels
|
|
64
|
+
labels?: SingleSelectLabels;
|
|
67
65
|
/**
|
|
68
66
|
* When false, the SelectOpener can show a Node as a label. When true, the
|
|
69
67
|
* SelectOpener will use a string as a label. If using custom OptionItems, a
|
|
70
68
|
* plain text label can be provided with the `labelAsText` prop.
|
|
71
69
|
* Defaults to true.
|
|
72
70
|
*/
|
|
73
|
-
showOpenerLabelAsText
|
|
71
|
+
showOpenerLabelAsText?: boolean;
|
|
74
72
|
}>;
|
|
75
73
|
type Props = AriaProps & DefaultProps & Readonly<{
|
|
76
74
|
/**
|
|
@@ -139,22 +137,41 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
139
137
|
* opener's `aria-controls` attribute for screenreaders.
|
|
140
138
|
*/
|
|
141
139
|
dropdownId?: string;
|
|
142
|
-
}>;
|
|
143
|
-
type State = Readonly<{
|
|
144
140
|
/**
|
|
145
|
-
* Whether or
|
|
141
|
+
* Whether this field is required to continue, or the error message to
|
|
142
|
+
* render if this field is left blank.
|
|
143
|
+
*
|
|
144
|
+
* This can be a boolean or a string.
|
|
145
|
+
*
|
|
146
|
+
* String:
|
|
147
|
+
* Please pass in a translated string to use as the error message that will
|
|
148
|
+
* render if the user leaves this field blank. If this field is required,
|
|
149
|
+
* and a string is not passed in, a default untranslated string will render
|
|
150
|
+
* upon error.
|
|
151
|
+
* Note: The string will not be used if a `validate` prop is passed in.
|
|
152
|
+
*
|
|
153
|
+
* Example message: i18n._("A password is required to log in.")
|
|
154
|
+
*
|
|
155
|
+
* Boolean:
|
|
156
|
+
* True/false indicating whether this field is required. Please do not pass
|
|
157
|
+
* in `true` if possible - pass in the error string instead.
|
|
158
|
+
* If `true` is passed, and a `validate` prop is not passed, that means
|
|
159
|
+
* there is no corresponding message and the default untranlsated message
|
|
160
|
+
* will be used.
|
|
146
161
|
*/
|
|
147
|
-
|
|
162
|
+
required?: boolean | string;
|
|
148
163
|
/**
|
|
149
|
-
*
|
|
150
|
-
* string.
|
|
164
|
+
* Provide a validation for the field value.
|
|
165
|
+
* Return a string error message or null | void for a valid input.
|
|
166
|
+
*
|
|
167
|
+
* Use this for errors that are shown to the user while they are filling out
|
|
168
|
+
* a form.
|
|
151
169
|
*/
|
|
152
|
-
|
|
170
|
+
validate?: (value?: string | null) => string | null | void;
|
|
153
171
|
/**
|
|
154
|
-
*
|
|
155
|
-
* to this element, and also to pass the reference to Popper.js.
|
|
172
|
+
* Called right after the field is validated.
|
|
156
173
|
*/
|
|
157
|
-
|
|
174
|
+
onValidate?: (errorMessage?: string | null | undefined) => unknown;
|
|
158
175
|
}>;
|
|
159
176
|
/**
|
|
160
177
|
* The single select allows the selection of one item. Clients are responsible
|
|
@@ -201,24 +218,5 @@ type State = Readonly<{
|
|
|
201
218
|
* </SingleSelect>
|
|
202
219
|
* ```
|
|
203
220
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
static defaultProps: DefaultProps;
|
|
207
|
-
constructor(props: Props);
|
|
208
|
-
/**
|
|
209
|
-
* Used to sync the `opened` state when this component acts as a controlled
|
|
210
|
-
* component
|
|
211
|
-
*/
|
|
212
|
-
static getDerivedStateFromProps(props: Props, state: State): Partial<State> | null;
|
|
213
|
-
handleOpenChanged: (opened: boolean) => void;
|
|
214
|
-
handleToggle: (selectedValue: string) => void;
|
|
215
|
-
mapOptionItemsToDropdownItems: (children: OptionItemComponentArray) => DropdownItem[];
|
|
216
|
-
filterChildren(children: OptionItemComponentArray): OptionItemComponentArray;
|
|
217
|
-
getMenuItems(children: OptionItemComponentArray): DropdownItem[];
|
|
218
|
-
handleSearchTextChanged: (searchText: string) => void;
|
|
219
|
-
handleOpenerRef: (node?: any) => void;
|
|
220
|
-
handleClick: (e: React.SyntheticEvent) => void;
|
|
221
|
-
renderOpener(isDisabled: boolean, dropdownId: string): React.ReactElement<React.ComponentProps<typeof DropdownOpener>> | React.ReactElement<React.ComponentProps<typeof SelectOpener>>;
|
|
222
|
-
render(): React.ReactNode;
|
|
223
|
-
}
|
|
224
|
-
export {};
|
|
221
|
+
declare const SingleSelect: (props: Props) => React.JSX.Element;
|
|
222
|
+
export default SingleSelect;
|