@khanacademy/wonder-blocks-dropdown 9.1.5 → 9.2.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 +12 -0
- package/dist/es/index.js +70 -29
- package/dist/index.js +70 -29
- package/dist/util/helpers.d.ts +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-dropdown
|
|
2
2
|
|
|
3
|
+
## 9.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- af828a5: Integrates Announcer for value announcements in SingleSelect and MultiSelect
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [af828a5]
|
|
12
|
+
- Updated dependencies [fe17b20]
|
|
13
|
+
- @khanacademy/wonder-blocks-announcer@1.0.0
|
|
14
|
+
|
|
3
15
|
## 9.1.5
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/es/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { Popper } from 'react-popper';
|
|
|
19
19
|
import { maybeGetPortalMountedModalHostElement } from '@khanacademy/wonder-blocks-modal';
|
|
20
20
|
import { detectOverflow } from '@popperjs/core';
|
|
21
21
|
import caretDownIcon from '@phosphor-icons/core/bold/caret-down-bold.svg';
|
|
22
|
+
import { announceMessage } from '@khanacademy/wonder-blocks-announcer';
|
|
22
23
|
import caretDownIcon$1 from '@phosphor-icons/core/regular/caret-down.svg';
|
|
23
24
|
import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
24
25
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
@@ -855,7 +856,6 @@ function getSelectOpenerLabel(showOpenerLabelAsText, props) {
|
|
|
855
856
|
}
|
|
856
857
|
|
|
857
858
|
const VIRTUALIZE_THRESHOLD = 125;
|
|
858
|
-
const StyledSpan$1 = addStyle("span");
|
|
859
859
|
class DropdownCore extends React.Component {
|
|
860
860
|
static sameItemsFocusable(prevItems, currentItems) {
|
|
861
861
|
if (prevItems.length !== currentItems.length) {
|
|
@@ -1357,23 +1357,6 @@ class DropdownCore extends React.Component {
|
|
|
1357
1357
|
referenceElement: openerElement
|
|
1358
1358
|
}, isReferenceHidden => this.renderDropdownMenu(listRenderer, isReferenceHidden));
|
|
1359
1359
|
}
|
|
1360
|
-
renderLiveRegion() {
|
|
1361
|
-
const {
|
|
1362
|
-
items,
|
|
1363
|
-
open
|
|
1364
|
-
} = this.props;
|
|
1365
|
-
const {
|
|
1366
|
-
labels
|
|
1367
|
-
} = this.state;
|
|
1368
|
-
const totalItems = items.length;
|
|
1369
|
-
return React.createElement(StyledSpan$1, {
|
|
1370
|
-
"aria-live": "polite",
|
|
1371
|
-
"aria-atomic": "true",
|
|
1372
|
-
"aria-relevant": "additions text",
|
|
1373
|
-
style: styles$6.srOnly,
|
|
1374
|
-
"data-testid": "dropdown-live-region"
|
|
1375
|
-
}, open && labels.someResults(totalItems));
|
|
1376
|
-
}
|
|
1377
1360
|
render() {
|
|
1378
1361
|
const {
|
|
1379
1362
|
open,
|
|
@@ -1387,7 +1370,7 @@ class DropdownCore extends React.Component {
|
|
|
1387
1370
|
onKeyUp: !disabled ? this.handleKeyUp : undefined,
|
|
1388
1371
|
style: [styles$6.menuWrapper, style],
|
|
1389
1372
|
className: className
|
|
1390
|
-
},
|
|
1373
|
+
}, opener, open && this.renderDropdown());
|
|
1391
1374
|
}
|
|
1392
1375
|
}
|
|
1393
1376
|
DropdownCore.defaultProps = {
|
|
@@ -2137,10 +2120,30 @@ const SingleSelect = props => {
|
|
|
2137
2120
|
const handleClick = e => {
|
|
2138
2121
|
handleOpenChanged(!open);
|
|
2139
2122
|
};
|
|
2123
|
+
const handleAnnouncement = message => {
|
|
2124
|
+
announceMessage({
|
|
2125
|
+
message
|
|
2126
|
+
});
|
|
2127
|
+
};
|
|
2128
|
+
React.useEffect(() => {
|
|
2129
|
+
const optionItems = React.Children.toArray(children);
|
|
2130
|
+
const selectedItem = optionItems.find(option => option.props.value === selectedValue);
|
|
2131
|
+
if (selectedItem) {
|
|
2132
|
+
const label = getLabel(selectedItem.props);
|
|
2133
|
+
if (label) {
|
|
2134
|
+
handleAnnouncement(label);
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
}, [selectedValue, children]);
|
|
2140
2138
|
const renderOpener = (isDisabled, dropdownId) => {
|
|
2141
2139
|
const items = React.Children.toArray(children);
|
|
2142
2140
|
const selectedItem = items.find(option => option.props.value === selectedValue);
|
|
2143
|
-
|
|
2141
|
+
let menuContent;
|
|
2142
|
+
if (selectedItem) {
|
|
2143
|
+
menuContent = getSelectOpenerLabel(showOpenerLabelAsText, selectedItem.props);
|
|
2144
|
+
} else {
|
|
2145
|
+
menuContent = placeholder;
|
|
2146
|
+
}
|
|
2144
2147
|
const dropdownOpener = React.createElement(Id, {
|
|
2145
2148
|
id: id
|
|
2146
2149
|
}, uniqueOpenerId => {
|
|
@@ -2153,7 +2156,7 @@ const SingleSelect = props => {
|
|
|
2153
2156
|
disabled: isDisabled,
|
|
2154
2157
|
ref: handleOpenerRef,
|
|
2155
2158
|
role: "combobox",
|
|
2156
|
-
text:
|
|
2159
|
+
text: menuContent,
|
|
2157
2160
|
opened: open,
|
|
2158
2161
|
error: hasError,
|
|
2159
2162
|
onBlur: onOpenerBlurValidation
|
|
@@ -2169,7 +2172,7 @@ const SingleSelect = props => {
|
|
|
2169
2172
|
ref: handleOpenerRef,
|
|
2170
2173
|
testId: testId,
|
|
2171
2174
|
onBlur: onOpenerBlurValidation
|
|
2172
|
-
}),
|
|
2175
|
+
}), menuContent);
|
|
2173
2176
|
});
|
|
2174
2177
|
return dropdownOpener;
|
|
2175
2178
|
};
|
|
@@ -2177,6 +2180,14 @@ const SingleSelect = props => {
|
|
|
2177
2180
|
const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
|
|
2178
2181
|
const items = getMenuItems(allChildren);
|
|
2179
2182
|
const isDisabled = numEnabledOptions === 0 || disabled;
|
|
2183
|
+
const {
|
|
2184
|
+
someResults
|
|
2185
|
+
} = labels;
|
|
2186
|
+
React.useEffect(() => {
|
|
2187
|
+
if (open) {
|
|
2188
|
+
handleAnnouncement(someResults(items.length));
|
|
2189
|
+
}
|
|
2190
|
+
}, [items.length, someResults, open]);
|
|
2180
2191
|
return React.createElement(Id, {
|
|
2181
2192
|
id: dropdownId
|
|
2182
2193
|
}, uniqueDropdownId => React.createElement(DropdownCore$1, {
|
|
@@ -2236,7 +2247,9 @@ const MultiSelect = props => {
|
|
|
2236
2247
|
required
|
|
2237
2248
|
} = props,
|
|
2238
2249
|
sharedProps = _objectWithoutPropertiesLoose(props, _excluded);
|
|
2239
|
-
const labels =
|
|
2250
|
+
const labels = React.useMemo(() => {
|
|
2251
|
+
return _extends({}, defaultLabels, propLabels);
|
|
2252
|
+
}, [propLabels]);
|
|
2240
2253
|
const [open, setOpen] = React.useState(false);
|
|
2241
2254
|
const [searchText, setSearchText] = React.useState("");
|
|
2242
2255
|
const [lastSelectedValues, setLastSelectedValues] = React.useState([]);
|
|
@@ -2298,7 +2311,7 @@ const MultiSelect = props => {
|
|
|
2298
2311
|
onChange([]);
|
|
2299
2312
|
onSelectedValuesChangeValidation();
|
|
2300
2313
|
};
|
|
2301
|
-
const getMenuTextOrNode = children => {
|
|
2314
|
+
const getMenuTextOrNode = React.useCallback(children => {
|
|
2302
2315
|
const {
|
|
2303
2316
|
noneSelected,
|
|
2304
2317
|
someSelected,
|
|
@@ -2325,7 +2338,7 @@ const MultiSelect = props => {
|
|
|
2325
2338
|
default:
|
|
2326
2339
|
return someSelected(selectedValues.length);
|
|
2327
2340
|
}
|
|
2328
|
-
};
|
|
2341
|
+
}, [implicitAllEnabled, labels, selectedValues, showOpenerLabelAsText]);
|
|
2329
2342
|
const getShortcuts = numOptions => {
|
|
2330
2343
|
const {
|
|
2331
2344
|
selectAllLabel,
|
|
@@ -2420,11 +2433,34 @@ const MultiSelect = props => {
|
|
|
2420
2433
|
const handleClick = e => {
|
|
2421
2434
|
handleOpenChanged(!open);
|
|
2422
2435
|
};
|
|
2436
|
+
const handleAnnouncement = message => {
|
|
2437
|
+
announceMessage({
|
|
2438
|
+
message
|
|
2439
|
+
});
|
|
2440
|
+
};
|
|
2441
|
+
const maybeGetOpenerStringValue = React.useCallback((children, openerContent) => {
|
|
2442
|
+
let openerStringValue;
|
|
2443
|
+
if (selectedValues.length === 1) {
|
|
2444
|
+
const selectedItem = children.find(option => option.props.value === selectedValues[0]);
|
|
2445
|
+
openerStringValue = selectedItem ? getLabel(selectedItem == null ? void 0 : selectedItem.props) : undefined;
|
|
2446
|
+
} else if (typeof openerContent === "string") {
|
|
2447
|
+
openerStringValue = openerContent;
|
|
2448
|
+
}
|
|
2449
|
+
return openerStringValue;
|
|
2450
|
+
}, [selectedValues]);
|
|
2451
|
+
React.useEffect(() => {
|
|
2452
|
+
const optionItems = React.Children.toArray(children);
|
|
2453
|
+
const openerContent = getMenuTextOrNode(optionItems);
|
|
2454
|
+
const openerStringValue = maybeGetOpenerStringValue(optionItems, openerContent);
|
|
2455
|
+
if (openerStringValue) {
|
|
2456
|
+
handleAnnouncement(openerStringValue);
|
|
2457
|
+
}
|
|
2458
|
+
}, [children, getMenuTextOrNode, maybeGetOpenerStringValue]);
|
|
2423
2459
|
const renderOpener = (allChildren, isDisabled, dropdownId) => {
|
|
2424
2460
|
const {
|
|
2425
2461
|
noneSelected
|
|
2426
2462
|
} = labels;
|
|
2427
|
-
const
|
|
2463
|
+
const openerContent = getMenuTextOrNode(allChildren);
|
|
2428
2464
|
const dropdownOpener = React.createElement(Id, {
|
|
2429
2465
|
id: id
|
|
2430
2466
|
}, uniqueOpenerId => {
|
|
@@ -2439,7 +2475,7 @@ const MultiSelect = props => {
|
|
|
2439
2475
|
disabled: isDisabled,
|
|
2440
2476
|
ref: handleOpenerRef,
|
|
2441
2477
|
role: "combobox",
|
|
2442
|
-
text:
|
|
2478
|
+
text: openerContent,
|
|
2443
2479
|
opened: open
|
|
2444
2480
|
}, opener) : React.createElement(SelectOpener, _extends({}, sharedProps, {
|
|
2445
2481
|
error: hasError,
|
|
@@ -2447,13 +2483,13 @@ const MultiSelect = props => {
|
|
|
2447
2483
|
id: uniqueOpenerId,
|
|
2448
2484
|
"aria-label": ariaLabel,
|
|
2449
2485
|
"aria-controls": dropdownId,
|
|
2450
|
-
isPlaceholder:
|
|
2486
|
+
isPlaceholder: openerContent === noneSelected,
|
|
2451
2487
|
onOpenChanged: handleOpenChanged,
|
|
2452
2488
|
onBlur: onOpenerBlurValidation,
|
|
2453
2489
|
open: open,
|
|
2454
2490
|
ref: handleOpenerRef,
|
|
2455
2491
|
testId: testId
|
|
2456
|
-
}),
|
|
2492
|
+
}), openerContent);
|
|
2457
2493
|
});
|
|
2458
2494
|
return dropdownOpener;
|
|
2459
2495
|
};
|
|
@@ -2467,6 +2503,11 @@ const MultiSelect = props => {
|
|
|
2467
2503
|
const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
|
|
2468
2504
|
const filteredItems = getMenuItems(allChildren);
|
|
2469
2505
|
const isDisabled = numEnabledOptions === 0 || disabled;
|
|
2506
|
+
React.useEffect(() => {
|
|
2507
|
+
if (open) {
|
|
2508
|
+
handleAnnouncement(someSelected(filteredItems.length));
|
|
2509
|
+
}
|
|
2510
|
+
}, [filteredItems.length, someSelected, open]);
|
|
2470
2511
|
return React.createElement(Id, {
|
|
2471
2512
|
id: dropdownId
|
|
2472
2513
|
}, uniqueDropdownId => React.createElement(DropdownCore$1, {
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ var reactPopper = require('react-popper');
|
|
|
22
22
|
var wonderBlocksModal = require('@khanacademy/wonder-blocks-modal');
|
|
23
23
|
var core = require('@popperjs/core');
|
|
24
24
|
var caretDownIcon = require('@phosphor-icons/core/bold/caret-down-bold.svg');
|
|
25
|
+
var wonderBlocksAnnouncer = require('@khanacademy/wonder-blocks-announcer');
|
|
25
26
|
var caretDownIcon$1 = require('@phosphor-icons/core/regular/caret-down.svg');
|
|
26
27
|
var xIcon = require('@phosphor-icons/core/regular/x.svg');
|
|
27
28
|
var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
|
|
@@ -890,7 +891,6 @@ function getSelectOpenerLabel(showOpenerLabelAsText, props) {
|
|
|
890
891
|
}
|
|
891
892
|
|
|
892
893
|
const VIRTUALIZE_THRESHOLD = 125;
|
|
893
|
-
const StyledSpan$1 = wonderBlocksCore.addStyle("span");
|
|
894
894
|
class DropdownCore extends React__namespace.Component {
|
|
895
895
|
static sameItemsFocusable(prevItems, currentItems) {
|
|
896
896
|
if (prevItems.length !== currentItems.length) {
|
|
@@ -1392,23 +1392,6 @@ class DropdownCore extends React__namespace.Component {
|
|
|
1392
1392
|
referenceElement: openerElement
|
|
1393
1393
|
}, isReferenceHidden => this.renderDropdownMenu(listRenderer, isReferenceHidden));
|
|
1394
1394
|
}
|
|
1395
|
-
renderLiveRegion() {
|
|
1396
|
-
const {
|
|
1397
|
-
items,
|
|
1398
|
-
open
|
|
1399
|
-
} = this.props;
|
|
1400
|
-
const {
|
|
1401
|
-
labels
|
|
1402
|
-
} = this.state;
|
|
1403
|
-
const totalItems = items.length;
|
|
1404
|
-
return React__namespace.createElement(StyledSpan$1, {
|
|
1405
|
-
"aria-live": "polite",
|
|
1406
|
-
"aria-atomic": "true",
|
|
1407
|
-
"aria-relevant": "additions text",
|
|
1408
|
-
style: styles$6.srOnly,
|
|
1409
|
-
"data-testid": "dropdown-live-region"
|
|
1410
|
-
}, open && labels.someResults(totalItems));
|
|
1411
|
-
}
|
|
1412
1395
|
render() {
|
|
1413
1396
|
const {
|
|
1414
1397
|
open,
|
|
@@ -1422,7 +1405,7 @@ class DropdownCore extends React__namespace.Component {
|
|
|
1422
1405
|
onKeyUp: !disabled ? this.handleKeyUp : undefined,
|
|
1423
1406
|
style: [styles$6.menuWrapper, style],
|
|
1424
1407
|
className: className
|
|
1425
|
-
},
|
|
1408
|
+
}, opener, open && this.renderDropdown());
|
|
1426
1409
|
}
|
|
1427
1410
|
}
|
|
1428
1411
|
DropdownCore.defaultProps = {
|
|
@@ -2172,10 +2155,30 @@ const SingleSelect = props => {
|
|
|
2172
2155
|
const handleClick = e => {
|
|
2173
2156
|
handleOpenChanged(!open);
|
|
2174
2157
|
};
|
|
2158
|
+
const handleAnnouncement = message => {
|
|
2159
|
+
wonderBlocksAnnouncer.announceMessage({
|
|
2160
|
+
message
|
|
2161
|
+
});
|
|
2162
|
+
};
|
|
2163
|
+
React__namespace.useEffect(() => {
|
|
2164
|
+
const optionItems = React__namespace.Children.toArray(children);
|
|
2165
|
+
const selectedItem = optionItems.find(option => option.props.value === selectedValue);
|
|
2166
|
+
if (selectedItem) {
|
|
2167
|
+
const label = getLabel(selectedItem.props);
|
|
2168
|
+
if (label) {
|
|
2169
|
+
handleAnnouncement(label);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
}, [selectedValue, children]);
|
|
2175
2173
|
const renderOpener = (isDisabled, dropdownId) => {
|
|
2176
2174
|
const items = React__namespace.Children.toArray(children);
|
|
2177
2175
|
const selectedItem = items.find(option => option.props.value === selectedValue);
|
|
2178
|
-
|
|
2176
|
+
let menuContent;
|
|
2177
|
+
if (selectedItem) {
|
|
2178
|
+
menuContent = getSelectOpenerLabel(showOpenerLabelAsText, selectedItem.props);
|
|
2179
|
+
} else {
|
|
2180
|
+
menuContent = placeholder;
|
|
2181
|
+
}
|
|
2179
2182
|
const dropdownOpener = React__namespace.createElement(wonderBlocksCore.Id, {
|
|
2180
2183
|
id: id
|
|
2181
2184
|
}, uniqueOpenerId => {
|
|
@@ -2188,7 +2191,7 @@ const SingleSelect = props => {
|
|
|
2188
2191
|
disabled: isDisabled,
|
|
2189
2192
|
ref: handleOpenerRef,
|
|
2190
2193
|
role: "combobox",
|
|
2191
|
-
text:
|
|
2194
|
+
text: menuContent,
|
|
2192
2195
|
opened: open,
|
|
2193
2196
|
error: hasError,
|
|
2194
2197
|
onBlur: onOpenerBlurValidation
|
|
@@ -2204,7 +2207,7 @@ const SingleSelect = props => {
|
|
|
2204
2207
|
ref: handleOpenerRef,
|
|
2205
2208
|
testId: testId,
|
|
2206
2209
|
onBlur: onOpenerBlurValidation
|
|
2207
|
-
}),
|
|
2210
|
+
}), menuContent);
|
|
2208
2211
|
});
|
|
2209
2212
|
return dropdownOpener;
|
|
2210
2213
|
};
|
|
@@ -2212,6 +2215,14 @@ const SingleSelect = props => {
|
|
|
2212
2215
|
const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
|
|
2213
2216
|
const items = getMenuItems(allChildren);
|
|
2214
2217
|
const isDisabled = numEnabledOptions === 0 || disabled;
|
|
2218
|
+
const {
|
|
2219
|
+
someResults
|
|
2220
|
+
} = labels;
|
|
2221
|
+
React__namespace.useEffect(() => {
|
|
2222
|
+
if (open) {
|
|
2223
|
+
handleAnnouncement(someResults(items.length));
|
|
2224
|
+
}
|
|
2225
|
+
}, [items.length, someResults, open]);
|
|
2215
2226
|
return React__namespace.createElement(wonderBlocksCore.Id, {
|
|
2216
2227
|
id: dropdownId
|
|
2217
2228
|
}, uniqueDropdownId => React__namespace.createElement(DropdownCore$1, {
|
|
@@ -2271,7 +2282,9 @@ const MultiSelect = props => {
|
|
|
2271
2282
|
required
|
|
2272
2283
|
} = props,
|
|
2273
2284
|
sharedProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded);
|
|
2274
|
-
const labels =
|
|
2285
|
+
const labels = React__namespace.useMemo(() => {
|
|
2286
|
+
return _extends__default["default"]({}, defaultLabels, propLabels);
|
|
2287
|
+
}, [propLabels]);
|
|
2275
2288
|
const [open, setOpen] = React__namespace.useState(false);
|
|
2276
2289
|
const [searchText, setSearchText] = React__namespace.useState("");
|
|
2277
2290
|
const [lastSelectedValues, setLastSelectedValues] = React__namespace.useState([]);
|
|
@@ -2333,7 +2346,7 @@ const MultiSelect = props => {
|
|
|
2333
2346
|
onChange([]);
|
|
2334
2347
|
onSelectedValuesChangeValidation();
|
|
2335
2348
|
};
|
|
2336
|
-
const getMenuTextOrNode = children => {
|
|
2349
|
+
const getMenuTextOrNode = React__namespace.useCallback(children => {
|
|
2337
2350
|
const {
|
|
2338
2351
|
noneSelected,
|
|
2339
2352
|
someSelected,
|
|
@@ -2360,7 +2373,7 @@ const MultiSelect = props => {
|
|
|
2360
2373
|
default:
|
|
2361
2374
|
return someSelected(selectedValues.length);
|
|
2362
2375
|
}
|
|
2363
|
-
};
|
|
2376
|
+
}, [implicitAllEnabled, labels, selectedValues, showOpenerLabelAsText]);
|
|
2364
2377
|
const getShortcuts = numOptions => {
|
|
2365
2378
|
const {
|
|
2366
2379
|
selectAllLabel,
|
|
@@ -2455,11 +2468,34 @@ const MultiSelect = props => {
|
|
|
2455
2468
|
const handleClick = e => {
|
|
2456
2469
|
handleOpenChanged(!open);
|
|
2457
2470
|
};
|
|
2471
|
+
const handleAnnouncement = message => {
|
|
2472
|
+
wonderBlocksAnnouncer.announceMessage({
|
|
2473
|
+
message
|
|
2474
|
+
});
|
|
2475
|
+
};
|
|
2476
|
+
const maybeGetOpenerStringValue = React__namespace.useCallback((children, openerContent) => {
|
|
2477
|
+
let openerStringValue;
|
|
2478
|
+
if (selectedValues.length === 1) {
|
|
2479
|
+
const selectedItem = children.find(option => option.props.value === selectedValues[0]);
|
|
2480
|
+
openerStringValue = selectedItem ? getLabel(selectedItem == null ? void 0 : selectedItem.props) : undefined;
|
|
2481
|
+
} else if (typeof openerContent === "string") {
|
|
2482
|
+
openerStringValue = openerContent;
|
|
2483
|
+
}
|
|
2484
|
+
return openerStringValue;
|
|
2485
|
+
}, [selectedValues]);
|
|
2486
|
+
React__namespace.useEffect(() => {
|
|
2487
|
+
const optionItems = React__namespace.Children.toArray(children);
|
|
2488
|
+
const openerContent = getMenuTextOrNode(optionItems);
|
|
2489
|
+
const openerStringValue = maybeGetOpenerStringValue(optionItems, openerContent);
|
|
2490
|
+
if (openerStringValue) {
|
|
2491
|
+
handleAnnouncement(openerStringValue);
|
|
2492
|
+
}
|
|
2493
|
+
}, [children, getMenuTextOrNode, maybeGetOpenerStringValue]);
|
|
2458
2494
|
const renderOpener = (allChildren, isDisabled, dropdownId) => {
|
|
2459
2495
|
const {
|
|
2460
2496
|
noneSelected
|
|
2461
2497
|
} = labels;
|
|
2462
|
-
const
|
|
2498
|
+
const openerContent = getMenuTextOrNode(allChildren);
|
|
2463
2499
|
const dropdownOpener = React__namespace.createElement(wonderBlocksCore.Id, {
|
|
2464
2500
|
id: id
|
|
2465
2501
|
}, uniqueOpenerId => {
|
|
@@ -2474,7 +2510,7 @@ const MultiSelect = props => {
|
|
|
2474
2510
|
disabled: isDisabled,
|
|
2475
2511
|
ref: handleOpenerRef,
|
|
2476
2512
|
role: "combobox",
|
|
2477
|
-
text:
|
|
2513
|
+
text: openerContent,
|
|
2478
2514
|
opened: open
|
|
2479
2515
|
}, opener) : React__namespace.createElement(SelectOpener, _extends__default["default"]({}, sharedProps, {
|
|
2480
2516
|
error: hasError,
|
|
@@ -2482,13 +2518,13 @@ const MultiSelect = props => {
|
|
|
2482
2518
|
id: uniqueOpenerId,
|
|
2483
2519
|
"aria-label": ariaLabel,
|
|
2484
2520
|
"aria-controls": dropdownId,
|
|
2485
|
-
isPlaceholder:
|
|
2521
|
+
isPlaceholder: openerContent === noneSelected,
|
|
2486
2522
|
onOpenChanged: handleOpenChanged,
|
|
2487
2523
|
onBlur: onOpenerBlurValidation,
|
|
2488
2524
|
open: open,
|
|
2489
2525
|
ref: handleOpenerRef,
|
|
2490
2526
|
testId: testId
|
|
2491
|
-
}),
|
|
2527
|
+
}), openerContent);
|
|
2492
2528
|
});
|
|
2493
2529
|
return dropdownOpener;
|
|
2494
2530
|
};
|
|
@@ -2502,6 +2538,11 @@ const MultiSelect = props => {
|
|
|
2502
2538
|
const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
|
|
2503
2539
|
const filteredItems = getMenuItems(allChildren);
|
|
2504
2540
|
const isDisabled = numEnabledOptions === 0 || disabled;
|
|
2541
|
+
React__namespace.useEffect(() => {
|
|
2542
|
+
if (open) {
|
|
2543
|
+
handleAnnouncement(someSelected(filteredItems.length));
|
|
2544
|
+
}
|
|
2545
|
+
}, [filteredItems.length, someSelected, open]);
|
|
2505
2546
|
return React__namespace.createElement(wonderBlocksCore.Id, {
|
|
2506
2547
|
id: dropdownId
|
|
2507
2548
|
}, uniqueDropdownId => React__namespace.createElement(DropdownCore$1, {
|
package/dist/util/helpers.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ type OptionItemProps = PropsFor<typeof OptionItem>;
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function getLabel(props: OptionItemProps): string;
|
|
24
24
|
/**
|
|
25
|
-
* Returns the label for the SelectOpener in
|
|
25
|
+
* Returns the label for the SelectOpener in SingleSelect.
|
|
26
26
|
* If the label is a Node, and `labelAsText` is undefined, returns the label.
|
|
27
27
|
*/
|
|
28
28
|
export declare function getSelectOpenerLabel(showOpenerLabelAsText: boolean, props: OptionItemProps): string | JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-dropdown",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Dropdown variants for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@babel/runtime": "^7.24.5",
|
|
16
|
+
"@khanacademy/wonder-blocks-announcer": "1.0.0",
|
|
16
17
|
"@khanacademy/wonder-blocks-cell": "4.1.4",
|
|
17
18
|
"@khanacademy/wonder-blocks-clickable": "6.1.4",
|
|
18
19
|
"@khanacademy/wonder-blocks-core": "12.2.1",
|
|
@@ -21,9 +22,9 @@
|
|
|
21
22
|
"@khanacademy/wonder-blocks-modal": "7.1.4",
|
|
22
23
|
"@khanacademy/wonder-blocks-pill": "3.1.4",
|
|
23
24
|
"@khanacademy/wonder-blocks-search-field": "5.1.4",
|
|
24
|
-
"@khanacademy/wonder-blocks-timing": "7.0.2",
|
|
25
25
|
"@khanacademy/wonder-blocks-tokens": "5.1.1",
|
|
26
|
-
"@khanacademy/wonder-blocks-typography": "3.1.3"
|
|
26
|
+
"@khanacademy/wonder-blocks-typography": "3.1.3",
|
|
27
|
+
"@khanacademy/wonder-blocks-timing": "7.0.2"
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
29
30
|
"@phosphor-icons/core": "^2.0.2",
|