@khanacademy/wonder-blocks-dropdown 10.13.7 → 10.14.1
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/.turbo/turbo-build$colon$css.log +1 -1
- package/CHANGELOG.md +35 -0
- package/dist/components/combobox-live-region.d.ts +2 -2
- package/dist/components/combobox.d.ts +4 -3
- package/dist/components/dropdown-core.d.ts +3 -0
- package/dist/components/multi-select.d.ts +7 -4
- package/dist/components/single-select.d.ts +8 -5
- package/dist/es/index.js +8 -7
- package/dist/index.js +8 -7
- package/dist/util/constants.d.ts +0 -12
- package/package.json +8 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @khanacademy/wonder-blocks-dropdown@10.
|
|
2
|
+
> @khanacademy/wonder-blocks-dropdown@10.14.1 build:css /home/runner/work/wonder-blocks/wonder-blocks/packages/wonder-blocks-dropdown
|
|
3
3
|
> pnpm exec wonder-blocks-tokens .
|
|
4
4
|
|
|
5
5
|
CSS variables generated successfully in: /home/runner/work/wonder-blocks/wonder-blocks/packages/wonder-blocks-dropdown/dist/css
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-dropdown
|
|
2
2
|
|
|
3
|
+
## 10.14.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [3652e16]
|
|
8
|
+
- Updated dependencies [53fee3b]
|
|
9
|
+
- @khanacademy/wonder-blocks-cell@6.3.0
|
|
10
|
+
- @khanacademy/wonder-blocks-config@0.7.1
|
|
11
|
+
- @khanacademy/wonder-blocks-form@7.7.6
|
|
12
|
+
- @khanacademy/wonder-blocks-modal@8.10.3
|
|
13
|
+
- @khanacademy/wonder-blocks-search-field@5.2.6
|
|
14
|
+
- @khanacademy/wonder-blocks-pill@3.1.83
|
|
15
|
+
|
|
16
|
+
## 10.14.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- a2504f1: The default labels and screen reader announcements in `Combobox` now read translated strings from `WonderBlocksConfigProvider`. The `labels` prop overrides the built-in translations. An empty label falls back to the built-in translation. The `labels` prop now accepts a partial object, so you only need to pass the labels you want to override.
|
|
21
|
+
|
|
22
|
+
Combobox announcements now use the correct singular grammar: "1 selected option." and "1 result available." instead of "1 selected options." and "1 results available.".
|
|
23
|
+
|
|
24
|
+
- 63e8d90: The default labels, screen reader announcements and required field error message in `SingleSelect` and `MultiSelect` now read translated strings from `WonderBlocksConfigProvider`. The `labels` and `required` props override the built-in translations. An empty label falls back to the built-in translation. The `labels` prop of `SingleSelect` now accepts a partial object, so you only need to pass the labels you want to override.
|
|
25
|
+
|
|
26
|
+
Changes to the `labels` prop of `SingleSelect` and `MultiSelect` now always update the search field's placeholder and clear button label. Before, they only updated when the set of focusable options also changed while the menu was open.
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [a2504f1]
|
|
31
|
+
- Updated dependencies [63e8d90]
|
|
32
|
+
- @khanacademy/wonder-blocks-config@0.7.0
|
|
33
|
+
- @khanacademy/wonder-blocks-form@7.7.5
|
|
34
|
+
- @khanacademy/wonder-blocks-modal@8.10.2
|
|
35
|
+
- @khanacademy/wonder-blocks-search-field@5.2.5
|
|
36
|
+
- @khanacademy/wonder-blocks-pill@3.1.82
|
|
37
|
+
|
|
3
38
|
## 10.13.7
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
|
@@ -12,7 +12,7 @@ type Props = {
|
|
|
12
12
|
/**
|
|
13
13
|
* The labels associated with the live region.
|
|
14
14
|
*/
|
|
15
|
-
labels?: Pick<ComboboxLabels, "closedState" | "liveRegionCurrentItem" | "liveRegionListboxTotal" | "liveRegionMultipleSelectionTotal" | "noItems" | "selected" | "selectionCleared" | "unselected"
|
|
15
|
+
labels?: Partial<Pick<ComboboxLabels, "closedState" | "liveRegionCurrentItem" | "liveRegionListboxTotal" | "liveRegionMultipleSelectionTotal" | "noItems" | "selected" | "selectionCleared" | "unselected">>;
|
|
16
16
|
/**
|
|
17
17
|
* Whether the listbox is open/expanded.
|
|
18
18
|
*/
|
|
@@ -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): React.JSX.Element;
|
|
51
|
+
export declare function ComboboxLiveRegion({ focusedIndex, focusedMultiSelectIndex, labels: propLabels, selectedLabels, opened, options, selected, selectionType, testId, }: Props): React.JSX.Element;
|
|
52
52
|
export {};
|
|
@@ -44,9 +44,10 @@ type Props = {
|
|
|
44
44
|
/**
|
|
45
45
|
* The object containing the custom labels used inside this component.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
47
|
+
* Any labels set here override the default labels provided by
|
|
48
|
+
* `WonderBlocksConfigProvider` (in English by default).
|
|
48
49
|
*/
|
|
49
|
-
labels?: ComboboxLabels
|
|
50
|
+
labels?: Partial<ComboboxLabels>;
|
|
50
51
|
/**
|
|
51
52
|
* TODO(WB-1678): Add async support to the listbox.
|
|
52
53
|
*
|
|
@@ -100,5 +101,5 @@ type Props = {
|
|
|
100
101
|
* Open button (🔽) is pressed.
|
|
101
102
|
* - It is displayed when the combobox receives focus.
|
|
102
103
|
*/
|
|
103
|
-
export default function Combobox({ autoComplete, children, disabled, error, id, labels, onChange, onToggle, opened, placeholder, selectionType, startIcon, testId, value, loading, style, ...ariaAttrs }: Props & AriaAttributes): React.JSX.Element;
|
|
104
|
+
export default function Combobox({ autoComplete, children, disabled, error, id, labels: propLabels, onChange, onToggle, opened, placeholder, selectionType, startIcon, testId, value, loading, style, ...ariaAttrs }: Props & AriaAttributes): React.JSX.Element;
|
|
104
105
|
export {};
|
|
@@ -117,6 +117,9 @@ type ExportProps = Readonly<{
|
|
|
117
117
|
initialFocusedIndex?: number;
|
|
118
118
|
/**
|
|
119
119
|
* The object containing the custom labels used inside this component.
|
|
120
|
+
*
|
|
121
|
+
* This overrides the default labels provided by `WonderBlocksConfigProvider`
|
|
122
|
+
* (in English by default).
|
|
120
123
|
*/
|
|
121
124
|
labels?: LabelsValues;
|
|
122
125
|
/**
|
|
@@ -102,6 +102,9 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
102
102
|
isFilterable?: boolean;
|
|
103
103
|
/**
|
|
104
104
|
* The object containing the custom labels and placeholder values used inside this component.
|
|
105
|
+
*
|
|
106
|
+
* Any labels set here override the default labels provided by
|
|
107
|
+
* `WonderBlocksConfigProvider` (in English by default).
|
|
105
108
|
*/
|
|
106
109
|
labels?: Partial<LabelsValues>;
|
|
107
110
|
/**
|
|
@@ -152,8 +155,8 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
152
155
|
* String:
|
|
153
156
|
* Please pass in a translated string to use as the error message that will
|
|
154
157
|
* render if the user leaves this field blank. If this field is required,
|
|
155
|
-
* and a string is not passed in,
|
|
156
|
-
* upon error.
|
|
158
|
+
* and a string is not passed in, the default `requiredFieldMessage` string
|
|
159
|
+
* from `WonderBlocksConfigProvider` will render upon error.
|
|
157
160
|
* Note: The string will not be used if a `validate` prop is passed in.
|
|
158
161
|
*
|
|
159
162
|
* Example message: i18n._("A password is required to log in.")
|
|
@@ -162,8 +165,8 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
162
165
|
* True/false indicating whether this field is required. Please do not pass
|
|
163
166
|
* in `true` if possible - pass in the error string instead.
|
|
164
167
|
* If `true` is passed, and a `validate` prop is not passed, that means
|
|
165
|
-
* there is no corresponding message and the default
|
|
166
|
-
* will be used.
|
|
168
|
+
* there is no corresponding message and the default `requiredFieldMessage`
|
|
169
|
+
* string from `WonderBlocksConfigProvider` will be used.
|
|
167
170
|
*/
|
|
168
171
|
required?: boolean | string;
|
|
169
172
|
/**
|
|
@@ -62,8 +62,11 @@ type DefaultProps = Readonly<{
|
|
|
62
62
|
error?: boolean;
|
|
63
63
|
/**
|
|
64
64
|
* The object containing the custom labels and placeholder values used inside this component.
|
|
65
|
+
*
|
|
66
|
+
* Any labels set here override the default labels provided by
|
|
67
|
+
* `WonderBlocksConfigProvider` (in English by default).
|
|
65
68
|
*/
|
|
66
|
-
labels?: SingleSelectLabelsValues
|
|
69
|
+
labels?: Partial<SingleSelectLabelsValues>;
|
|
67
70
|
/**
|
|
68
71
|
* When false, the SelectOpener can show a Node as a value. When true, the
|
|
69
72
|
* SelectOpener will use a string as a value. If using custom OptionItems, a
|
|
@@ -149,8 +152,8 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
149
152
|
* String:
|
|
150
153
|
* Please pass in a translated string to use as the error message that will
|
|
151
154
|
* render if the user leaves this field blank. If this field is required,
|
|
152
|
-
* and a string is not passed in,
|
|
153
|
-
* upon error.
|
|
155
|
+
* and a string is not passed in, the default `requiredFieldMessage` string
|
|
156
|
+
* from `WonderBlocksConfigProvider` will render upon error.
|
|
154
157
|
* Note: The string will not be used if a `validate` prop is passed in.
|
|
155
158
|
*
|
|
156
159
|
* Example message: i18n._("A password is required to log in.")
|
|
@@ -159,8 +162,8 @@ type Props = AriaProps & DefaultProps & Readonly<{
|
|
|
159
162
|
* True/false indicating whether this field is required. Please do not pass
|
|
160
163
|
* in `true` if possible - pass in the error string instead.
|
|
161
164
|
* If `true` is passed, and a `validate` prop is not passed, that means
|
|
162
|
-
* there is no corresponding message and the default
|
|
163
|
-
* will be used.
|
|
165
|
+
* there is no corresponding message and the default `requiredFieldMessage`
|
|
166
|
+
* string from `WonderBlocksConfigProvider` will be used.
|
|
164
167
|
*/
|
|
165
168
|
required?: boolean | string;
|
|
166
169
|
/**
|
package/dist/es/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { ClickableBehavior } from '@khanacademy/wonder-blocks-clickable';
|
|
|
13
13
|
import * as ReactDOM from 'react-dom';
|
|
14
14
|
import SearchField from '@khanacademy/wonder-blocks-search-field';
|
|
15
15
|
import { withActionScheduler, useActionScheduler } from '@khanacademy/wonder-blocks-timing';
|
|
16
|
+
import { useWonderBlocksI18n } from '@khanacademy/wonder-blocks-config';
|
|
16
17
|
import { VariableSizeList } from 'react-window';
|
|
17
18
|
import { Popper } from 'react-popper';
|
|
18
19
|
import { maybeGetPortalMountedModalHostElement } from '@khanacademy/wonder-blocks-modal';
|
|
@@ -25,7 +26,7 @@ import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
|
25
26
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
26
27
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
27
28
|
|
|
28
|
-
const selectDropdownStyle={marginBlock:sizing.size_080};const filterableDropdownStyle={minHeight:100};const DROPDOWN_ITEM_HEIGHT=40;const MAX_VISIBLE_ITEMS=9;const SEPARATOR_ITEM_HEIGHT=9;
|
|
29
|
+
const selectDropdownStyle={marginBlock:sizing.size_080};const filterableDropdownStyle={minHeight:100};const DROPDOWN_ITEM_HEIGHT=40;const MAX_VISIBLE_ITEMS=9;const SEPARATOR_ITEM_HEIGHT=9;
|
|
29
30
|
|
|
30
31
|
var themeDefault = {listbox:{border:{radius:border.radius.radius_040},layout:{padding:{inline:sizing.size_0,block:sizing.size_040}},shadow:{default:boxShadow.mid}},opener:{border:{width:{error:border.width.thin},radius:{rest:border.radius.radius_040}},layout:{padding:{inline:sizing.size_160,inlineStart:sizing.size_160,inlineEnd:sizing.size_120}}},item:{border:{radius:{default:border.radius.radius_040,press:border.radius.radius_040}},layout:{padding:{block:sizing.size_100,inlineStart:sizing.size_080,inlineEnd:sizing.size_160}},font:{weight:font.weight.regular}}};
|
|
31
32
|
|
|
@@ -55,7 +56,7 @@ const modifiers=[{name:"preventOverflow",options:{rootBoundary:"viewport",altAxi
|
|
|
55
56
|
|
|
56
57
|
function getStringForKey(key){if(key.length===1||!/^[A-Z]/i.test(key)){return key}return ""}function debounce(callback,wait){let timeout;return function executedFunction(...args){const later=()=>{clearTimeout(timeout);callback(...args);};clearTimeout(timeout);timeout=setTimeout(later,wait);}}function isString(x){return typeof x==="string"}function getLabel(props){if(isString(props.label)){return props.label}if(isString(props.labelAsText)){return props.labelAsText}return ""}function getSelectOpenerLabel(showOpenerLabelAsText,props){if(showOpenerLabelAsText){return getLabel(props)}return props.label}function getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement}){const openerLabel=getOpenerLabel(openerElement);const labelId=ariaLabelledBy||openerLabel?.id;if(labelId){return {"aria-labelledby":labelId}}const label=openerLabel?.textContent||ariaLabel;return label?{"aria-label":label}:{}}function getOpenerLabel(openerElement){if(!openerElement||!("labels"in openerElement)){return undefined}return openerElement.labels?.[0]}
|
|
57
58
|
|
|
58
|
-
const VIRTUALIZE_THRESHOLD=125;const sameItemsFocusable=(prevItems,currentItems)=>{if(prevItems.length!==currentItems.length){return false}for(let i=0;i<prevItems.length;i++){if(prevItems[i].focusable!==currentItems[i].focusable){return false}}return true};const createItemRefs=items=>{const itemRefs=[];for(let i=0;i<items.length;i++){if(items[i].focusable){const ref=React.createRef();itemRefs.push({ref,originalIndex:i});}}return itemRefs};const defaultPropLabels={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected};const DropdownCore=props=>{const{"aria-invalid":ariaInvalid,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-required":ariaRequired,alignment="left",autoFocus=true,className,disabled,dropdownStyle,enableTypeAhead=true,id,initialFocusedIndex,isFilterable,items,labels:propLabels=defaultPropLabels,onOpenChanged,onSearchTextChanged,open,opener,openerElement,role,searchText,selectionType="single",style}=props;const schedule=useActionScheduler();const openRef=useLatestRef(open);const onOpenChangedRef=useLatestRef(onOpenChanged);const rootRef=React.useRef(null);const popperElementRef=React.useRef(undefined);const virtualizedListRef=React.useRef(null);const searchFieldRef=React.useRef(null);const textSuggestionRef=React.useRef("");const[labels,setLabels]=React.useState(()=>({noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected,...propLabels}));const committedItemsRef=React.useRef({itemRefs:[],prevItems:items});const{itemRefs:prevItemRefs,prevItems}=committedItemsRef.current;const shouldCreateItemRefs=prevItemRefs.length===0&&open||!sameItemsFocusable(prevItems,items);const derivedItems=shouldCreateItemRefs?{itemRefs:createItemRefs(items),sameItemsFocusable:false}:{itemRefs:prevItemRefs,sameItemsFocusable:true};const itemRefsRef=React.useRef(derivedItems.itemRefs);React.useEffect(()=>{committedItemsRef.current={itemRefs:derivedItems.itemRefs,prevItems:items};itemRefsRef.current=derivedItems.itemRefs;});const hasSearchField=React.useCallback(()=>{return !!isFilterable},[isFilterable]);const isSearchFieldFocused=React.useCallback(()=>{return hasSearchField()&&document.activeElement===searchFieldRef.current},[hasSearchField]);const focusSearchField=React.useCallback(()=>{if(searchFieldRef.current){searchFieldRef.current.focus();}},[]);const focusedIndexRef=React.useRef(-1);const focusedOriginalIndexRef=React.useRef(-1);const itemsClickedRef=React.useRef(false);const resetFocusedIndex=React.useCallback(()=>{if(typeof initialFocusedIndex!=="undefined"){focusedIndexRef.current=initialFocusedIndex;}else {if(hasSearchField()&&!isSearchFieldFocused()){return focusSearchField()}focusedIndexRef.current=0;}},[focusSearchField,hasSearchField,initialFocusedIndex,isSearchFieldFocused]);const initializedRef=React.useRef(false);if(!initializedRef.current){initializedRef.current=true;resetFocusedIndex();}const shouldVirtualizeList=React.useCallback(()=>{return items.length>VIRTUALIZE_THRESHOLD},[items]);const focusCurrentItem=React.useCallback(onFocus=>{const focusedItemRef=itemRefsRef.current[focusedIndexRef.current];if(!focusedItemRef){return}const{current:virtualizedList}=virtualizedListRef;if(virtualizedList){virtualizedList.scrollToItem(focusedItemRef.originalIndex);}const focusNode=()=>{if(!openRef.current){return}const currentFocusedItemRef=itemRefsRef.current[focusedIndexRef.current];const node=ReactDOM.findDOMNode(currentFocusedItemRef.ref.current);if(!node&&shouldVirtualizeList()){schedule.animationFrame(focusNode);return}if(node){schedule.timeout(()=>{node.focus();},0);focusedOriginalIndexRef.current=currentFocusedItemRef.originalIndex;if(onFocus){onFocus(node);}}};if(shouldVirtualizeList()){schedule.animationFrame(focusNode);}else {focusNode();}},[openRef,schedule,shouldVirtualizeList]);const scheduleToFocusCurrentItem=React.useCallback(onFocus=>{if(shouldVirtualizeList()){schedule.animationFrame(()=>{focusCurrentItem(onFocus);});}else {focusCurrentItem(onFocus);}},[focusCurrentItem,schedule,shouldVirtualizeList]);const maybeFocusInitialItem=React.useCallback(()=>{if(!autoFocus){return}if(open){resetFocusedIndex();scheduleToFocusCurrentItem();}else if(!open){itemsClickedRef.current=false;}},[autoFocus,open,resetFocusedIndex,scheduleToFocusCurrentItem]);React.useEffect(()=>{if(!open){return}const handleInteract=event=>{const target=event.target;const thisElement=rootRef.current;if(thisElement&&!thisElement.contains(target)&&popperElementRef.current&&!popperElementRef.current.contains(target)){onOpenChangedRef.current(false);}};document.addEventListener("mouseup",handleInteract);document.addEventListener("touchend",handleInteract);return ()=>{document.removeEventListener("mouseup",handleInteract);document.removeEventListener("touchend",handleInteract);}},[open,onOpenChangedRef]);useOnMountEffect(()=>{maybeFocusInitialItem();});const prevRenderRef=React.useRef(null);React.useEffect(()=>{const prevProps=prevRenderRef.current;prevRenderRef.current={open,searchText,labels:propLabels,derivedItems};if(!prevProps||prevProps.derivedItems===derivedItems){return}if(prevProps.open!==open){maybeFocusInitialItem();}else if(open){const{itemRefs,sameItemsFocusable}=derivedItems;if(sameItemsFocusable||prevProps.searchText!==searchText){return}else {const newFocusableIndex=itemRefs.findIndex(ref=>ref.originalIndex===focusedOriginalIndexRef.current);if(newFocusableIndex===-1){focusedIndexRef.current=0;itemsClickedRef.current=false;scheduleToFocusCurrentItem();}else {focusedIndexRef.current=newFocusableIndex;}}if(propLabels!==prevProps.labels){setLabels(prevLabels=>({...prevLabels,...propLabels}));}}});const focusPreviousItem=React.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=itemRefsRef.current.length-1;}else if(focusedIndexRef.current===0){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=itemRefsRef.current.length-1;}else {focusedIndexRef.current-=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const focusNextItem=React.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=0;}else if(focusedIndexRef.current===itemRefsRef.current.length-1){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=0;}else {focusedIndexRef.current+=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const restoreTabOrder=React.useCallback(()=>{if(openerElement){openerElement.focus();}},[openerElement]);const handleKeyDownDebounceResult=React.useCallback(key=>{const foundIndex=items.filter(item=>item.focusable).findIndex(({component})=>{if(SeparatorItem.isClassOf(component)){return false}if(OptionItem.isClassOf(component)){const optionItemProps=component.props;return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase())}return false});if(foundIndex>=0){const isClosed=!open;if(isClosed){onOpenChanged(true);}focusedIndexRef.current=foundIndex;scheduleToFocusCurrentItem(node=>{if(selectionType==="single"&&isClosed&&node){node.click();onOpenChanged(false);}});}textSuggestionRef.current="";},[items,onOpenChanged,open,scheduleToFocusCurrentItem,selectionType]);const handleKeyDownDebounceResultRef=React.useRef(handleKeyDownDebounceResult);handleKeyDownDebounceResultRef.current=handleKeyDownDebounceResult;const handleKeyDownDebounced=React.useMemo(()=>debounce(key=>handleKeyDownDebounceResultRef.current(key),500),[]);const handleKeyDown=event=>{const key=event.key;if(enableTypeAhead&&getStringForKey(key)){event.stopPropagation();textSuggestionRef.current+=key;handleKeyDownDebounced(textSuggestionRef.current);}if(!open){if(key===keys.down){event.preventDefault();onOpenChanged(true);return}return}switch(key){case keys.tab:if(isSearchFieldFocused()&&searchText){return}restoreTabOrder();onOpenChanged(false);return;case keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case keys.up:event.preventDefault();focusPreviousItem();return;case keys.down:event.preventDefault();focusNextItem();return}};const handleKeyUp=event=>{const key=event.key;switch(key){case keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case keys.escape:if(open){event.stopPropagation();restoreTabOrder();onOpenChanged(false);}return}};const handleClickFocus=index=>{itemsClickedRef.current=true;focusedIndexRef.current=index;focusedOriginalIndexRef.current=derivedItems.itemRefs[focusedIndexRef.current].originalIndex;};const handleDropdownMouseUp=event=>{if(event.nativeEvent.stopImmediatePropagation){event.nativeEvent.stopImmediatePropagation();}else {event.stopPropagation();}};const getItemRole=()=>{switch(role){case"listbox":return "option";case"menu":return "menuitem";default:throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`)}};const maybeRenderNoResults=()=>{const{noResults}=propLabels;const numResults=items.length;if(numResults===0){return jsx(BodyText,{style:styles$7.noResult,testId:"dropdown-core-no-results",children:noResults})}return null};const handleItemClick=(focusIndex,item)=>{handleClickFocus(focusIndex);if(item.component.props.onClick){item.component.props.onClick();}if(item.populatedProps.onClick){item.populatedProps.onClick();}};const renderList=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{if(SeparatorItem.isClassOf(item.component)){return item.component}const{component,focusable,populatedProps}=item;if(focusable){focusCounter+=1;}const focusIndex=focusCounter-1;const currentRef=derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null;return React.cloneElement(component,{...populatedProps,key:index,onClick:()=>{handleItemClick(focusIndex,item);},ref:focusable?currentRef:null,role:populatedProps.role||itemRole})})};const parseVirtualizedItems=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{const{populatedProps}=item;if(!SeparatorItem.isClassOf(item.component)&&item.focusable){focusCounter+=1;}const focusIndex=focusCounter-1;return {...item,role:populatedProps.role||itemRole,ref:item.focusable&&derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null,onClick:()=>{handleItemClick(focusIndex,item);}}})};const renderVirtualizedList=()=>{const virtualizedItems=parseVirtualizedItems();return jsx(DropdownCoreVirtualized$1,{data:virtualizedItems,listRef:virtualizedListRef})};const handleSearchTextChanged=searchText=>{if(onSearchTextChanged){onSearchTextChanged(searchText);}};const renderSearchField=()=>{return jsx(SearchField,{clearAriaLabel:labels.clearSearch,onChange:handleSearchTextChanged,placeholder:labels.filter,ref:searchFieldRef,style:styles$7.searchInputStyle,value:searchText||""})};const renderDropdownMenu=(listRenderer,isReferenceHidden)=>{const openerStyle=openerElement&&window.getComputedStyle(openerElement);const minDropdownWidth=openerStyle?openerStyle.getPropertyValue("width"):0;return jsxs(View,{onMouseUp:handleDropdownMouseUp,style:[styles$7.dropdown,isReferenceHidden&&styles$7.hidden,dropdownStyle],testId:"dropdown-core-container",children:[isFilterable&&renderSearchField(),jsx(View,{id:id,role:role,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,style:[styles$7.listboxOrMenu,{minInlineSize:minDropdownWidth}],"aria-invalid":role==="listbox"?ariaInvalid:undefined,"aria-required":role==="listbox"?ariaRequired:undefined,children:listRenderer}),maybeRenderNoResults()]})};const renderDropdown=()=>{const listRenderer=shouldVirtualizeList()?renderVirtualizedList():renderList();return jsx(DropdownPopper,{alignment:alignment,onPopperElement:popperElement=>{popperElementRef.current=popperElement;},referenceElement:openerElement,children:isReferenceHidden=>renderDropdownMenu(listRenderer,isReferenceHidden)})};return jsxs(View,{ref:rootRef,onKeyDown:!disabled?handleKeyDown:undefined,onKeyUp:!disabled?handleKeyUp:undefined,style:[styles$7.menuWrapper,style],className:className,children:[opener,open&&renderDropdown()]})};const styles$7=StyleSheet.create({menuWrapper:{width:"fit-content",maxInlineSize:"100%"},dropdown:{backgroundColor:semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)"},listboxOrMenu:{overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},noResult:{color:semanticColor.core.foreground.neutral.default,alignSelf:"center",marginBlockStart:sizing.size_060},searchInputStyle:{margin:sizing.size_080,marginBlockStart:sizing.size_040,minBlockSize:"auto",position:"sticky"},srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
59
|
+
const VIRTUALIZE_THRESHOLD=125;const sameItemsFocusable=(prevItems,currentItems)=>{if(prevItems.length!==currentItems.length){return false}for(let i=0;i<prevItems.length;i++){if(prevItems[i].focusable!==currentItems[i].focusable){return false}}return true};const createItemRefs=items=>{const itemRefs=[];for(let i=0;i<items.length;i++){if(items[i].focusable){const ref=React.createRef();itemRefs.push({ref,originalIndex:i});}}return itemRefs};const DropdownCore=props=>{const{strings}=useWonderBlocksI18n();const{"aria-invalid":ariaInvalid,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-required":ariaRequired,alignment="left",autoFocus=true,className,disabled,dropdownStyle,enableTypeAhead=true,id,initialFocusedIndex,isFilterable,items,labels,onOpenChanged,onSearchTextChanged,open,opener,openerElement,role,searchText,selectionType="single",style}=props;const schedule=useActionScheduler();const openRef=useLatestRef(open);const onOpenChangedRef=useLatestRef(onOpenChanged);const rootRef=React.useRef(null);const popperElementRef=React.useRef(undefined);const virtualizedListRef=React.useRef(null);const searchFieldRef=React.useRef(null);const textSuggestionRef=React.useRef("");const committedItemsRef=React.useRef({itemRefs:[],prevItems:items});const{itemRefs:prevItemRefs,prevItems}=committedItemsRef.current;const shouldCreateItemRefs=prevItemRefs.length===0&&open||!sameItemsFocusable(prevItems,items);const derivedItems=shouldCreateItemRefs?{itemRefs:createItemRefs(items),sameItemsFocusable:false}:{itemRefs:prevItemRefs,sameItemsFocusable:true};const itemRefsRef=React.useRef(derivedItems.itemRefs);React.useEffect(()=>{committedItemsRef.current={itemRefs:derivedItems.itemRefs,prevItems:items};itemRefsRef.current=derivedItems.itemRefs;});const hasSearchField=React.useCallback(()=>{return !!isFilterable},[isFilterable]);const isSearchFieldFocused=React.useCallback(()=>{return hasSearchField()&&document.activeElement===searchFieldRef.current},[hasSearchField]);const focusSearchField=React.useCallback(()=>{if(searchFieldRef.current){searchFieldRef.current.focus();}},[]);const focusedIndexRef=React.useRef(-1);const focusedOriginalIndexRef=React.useRef(-1);const itemsClickedRef=React.useRef(false);const resetFocusedIndex=React.useCallback(()=>{if(typeof initialFocusedIndex!=="undefined"){focusedIndexRef.current=initialFocusedIndex;}else {if(hasSearchField()&&!isSearchFieldFocused()){return focusSearchField()}focusedIndexRef.current=0;}},[focusSearchField,hasSearchField,initialFocusedIndex,isSearchFieldFocused]);const initializedRef=React.useRef(false);if(!initializedRef.current){initializedRef.current=true;resetFocusedIndex();}const shouldVirtualizeList=React.useCallback(()=>{return items.length>VIRTUALIZE_THRESHOLD},[items]);const focusCurrentItem=React.useCallback(onFocus=>{const focusedItemRef=itemRefsRef.current[focusedIndexRef.current];if(!focusedItemRef){return}const{current:virtualizedList}=virtualizedListRef;if(virtualizedList){virtualizedList.scrollToItem(focusedItemRef.originalIndex);}const focusNode=()=>{if(!openRef.current){return}const currentFocusedItemRef=itemRefsRef.current[focusedIndexRef.current];const node=ReactDOM.findDOMNode(currentFocusedItemRef.ref.current);if(!node&&shouldVirtualizeList()){schedule.animationFrame(focusNode);return}if(node){schedule.timeout(()=>{node.focus();},0);focusedOriginalIndexRef.current=currentFocusedItemRef.originalIndex;if(onFocus){onFocus(node);}}};if(shouldVirtualizeList()){schedule.animationFrame(focusNode);}else {focusNode();}},[openRef,schedule,shouldVirtualizeList]);const scheduleToFocusCurrentItem=React.useCallback(onFocus=>{if(shouldVirtualizeList()){schedule.animationFrame(()=>{focusCurrentItem(onFocus);});}else {focusCurrentItem(onFocus);}},[focusCurrentItem,schedule,shouldVirtualizeList]);const maybeFocusInitialItem=React.useCallback(()=>{if(!autoFocus){return}if(open){resetFocusedIndex();scheduleToFocusCurrentItem();}else if(!open){itemsClickedRef.current=false;}},[autoFocus,open,resetFocusedIndex,scheduleToFocusCurrentItem]);React.useEffect(()=>{if(!open){return}const handleInteract=event=>{const target=event.target;const thisElement=rootRef.current;if(thisElement&&!thisElement.contains(target)&&popperElementRef.current&&!popperElementRef.current.contains(target)){onOpenChangedRef.current(false);}};document.addEventListener("mouseup",handleInteract);document.addEventListener("touchend",handleInteract);return ()=>{document.removeEventListener("mouseup",handleInteract);document.removeEventListener("touchend",handleInteract);}},[open,onOpenChangedRef]);useOnMountEffect(()=>{maybeFocusInitialItem();});const prevRenderRef=React.useRef(null);React.useEffect(()=>{const prevProps=prevRenderRef.current;prevRenderRef.current={open,searchText,derivedItems};if(!prevProps||prevProps.derivedItems===derivedItems){return}if(prevProps.open!==open){maybeFocusInitialItem();}else if(open){const{itemRefs,sameItemsFocusable}=derivedItems;if(sameItemsFocusable||prevProps.searchText!==searchText){return}else {const newFocusableIndex=itemRefs.findIndex(ref=>ref.originalIndex===focusedOriginalIndexRef.current);if(newFocusableIndex===-1){focusedIndexRef.current=0;itemsClickedRef.current=false;scheduleToFocusCurrentItem();}else {focusedIndexRef.current=newFocusableIndex;}}}});const focusPreviousItem=React.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=itemRefsRef.current.length-1;}else if(focusedIndexRef.current===0){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=itemRefsRef.current.length-1;}else {focusedIndexRef.current-=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const focusNextItem=React.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=0;}else if(focusedIndexRef.current===itemRefsRef.current.length-1){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=0;}else {focusedIndexRef.current+=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const restoreTabOrder=React.useCallback(()=>{if(openerElement){openerElement.focus();}},[openerElement]);const handleKeyDownDebounceResult=React.useCallback(key=>{const foundIndex=items.filter(item=>item.focusable).findIndex(({component})=>{if(SeparatorItem.isClassOf(component)){return false}if(OptionItem.isClassOf(component)){const optionItemProps=component.props;return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase())}return false});if(foundIndex>=0){const isClosed=!open;if(isClosed){onOpenChanged(true);}focusedIndexRef.current=foundIndex;scheduleToFocusCurrentItem(node=>{if(selectionType==="single"&&isClosed&&node){node.click();onOpenChanged(false);}});}textSuggestionRef.current="";},[items,onOpenChanged,open,scheduleToFocusCurrentItem,selectionType]);const handleKeyDownDebounceResultRef=React.useRef(handleKeyDownDebounceResult);handleKeyDownDebounceResultRef.current=handleKeyDownDebounceResult;const handleKeyDownDebounced=React.useMemo(()=>debounce(key=>handleKeyDownDebounceResultRef.current(key),500),[]);const handleKeyDown=event=>{const key=event.key;if(enableTypeAhead&&getStringForKey(key)){event.stopPropagation();textSuggestionRef.current+=key;handleKeyDownDebounced(textSuggestionRef.current);}if(!open){if(key===keys.down){event.preventDefault();onOpenChanged(true);return}return}switch(key){case keys.tab:if(isSearchFieldFocused()&&searchText){return}restoreTabOrder();onOpenChanged(false);return;case keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case keys.up:event.preventDefault();focusPreviousItem();return;case keys.down:event.preventDefault();focusNextItem();return}};const handleKeyUp=event=>{const key=event.key;switch(key){case keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case keys.escape:if(open){event.stopPropagation();restoreTabOrder();onOpenChanged(false);}return}};const handleClickFocus=index=>{itemsClickedRef.current=true;focusedIndexRef.current=index;focusedOriginalIndexRef.current=derivedItems.itemRefs[focusedIndexRef.current].originalIndex;};const handleDropdownMouseUp=event=>{if(event.nativeEvent.stopImmediatePropagation){event.nativeEvent.stopImmediatePropagation();}else {event.stopPropagation();}};const getItemRole=()=>{switch(role){case"listbox":return "option";case"menu":return "menuitem";default:throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`)}};const maybeRenderNoResults=()=>{const noResults=labels?.noResults||strings.noResults;const numResults=items.length;if(numResults===0){return jsx(BodyText,{style:styles$7.noResult,testId:"dropdown-core-no-results",children:noResults})}return null};const handleItemClick=(focusIndex,item)=>{handleClickFocus(focusIndex);if(item.component.props.onClick){item.component.props.onClick();}if(item.populatedProps.onClick){item.populatedProps.onClick();}};const renderList=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{if(SeparatorItem.isClassOf(item.component)){return item.component}const{component,focusable,populatedProps}=item;if(focusable){focusCounter+=1;}const focusIndex=focusCounter-1;const currentRef=derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null;return React.cloneElement(component,{...populatedProps,key:index,onClick:()=>{handleItemClick(focusIndex,item);},ref:focusable?currentRef:null,role:populatedProps.role||itemRole})})};const parseVirtualizedItems=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{const{populatedProps}=item;if(!SeparatorItem.isClassOf(item.component)&&item.focusable){focusCounter+=1;}const focusIndex=focusCounter-1;return {...item,role:populatedProps.role||itemRole,ref:item.focusable&&derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null,onClick:()=>{handleItemClick(focusIndex,item);}}})};const renderVirtualizedList=()=>{const virtualizedItems=parseVirtualizedItems();return jsx(DropdownCoreVirtualized$1,{data:virtualizedItems,listRef:virtualizedListRef})};const handleSearchTextChanged=searchText=>{if(onSearchTextChanged){onSearchTextChanged(searchText);}};const renderSearchField=()=>{return jsx(SearchField,{clearAriaLabel:labels?.clearSearch||strings.iconAltClearSearch,onChange:handleSearchTextChanged,placeholder:labels?.filter||strings.filter,ref:searchFieldRef,style:styles$7.searchInputStyle,value:searchText||""})};const renderDropdownMenu=(listRenderer,isReferenceHidden)=>{const openerStyle=openerElement&&window.getComputedStyle(openerElement);const minDropdownWidth=openerStyle?openerStyle.getPropertyValue("width"):0;return jsxs(View,{onMouseUp:handleDropdownMouseUp,style:[styles$7.dropdown,isReferenceHidden&&styles$7.hidden,dropdownStyle],testId:"dropdown-core-container",children:[isFilterable&&renderSearchField(),jsx(View,{id:id,role:role,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,style:[styles$7.listboxOrMenu,{minInlineSize:minDropdownWidth}],"aria-invalid":role==="listbox"?ariaInvalid:undefined,"aria-required":role==="listbox"?ariaRequired:undefined,children:listRenderer}),maybeRenderNoResults()]})};const renderDropdown=()=>{const listRenderer=shouldVirtualizeList()?renderVirtualizedList():renderList();return jsx(DropdownPopper,{alignment:alignment,onPopperElement:popperElement=>{popperElementRef.current=popperElement;},referenceElement:openerElement,children:isReferenceHidden=>renderDropdownMenu(listRenderer,isReferenceHidden)})};return jsxs(View,{ref:rootRef,onKeyDown:!disabled?handleKeyDown:undefined,onKeyUp:!disabled?handleKeyUp:undefined,style:[styles$7.menuWrapper,style],className:className,children:[opener,open&&renderDropdown()]})};const styles$7=StyleSheet.create({menuWrapper:{width:"fit-content",maxInlineSize:"100%"},dropdown:{backgroundColor:semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)"},listboxOrMenu:{overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},noResult:{color:semanticColor.core.foreground.neutral.default,alignSelf:"center",marginBlockStart:sizing.size_060},searchInputStyle:{margin:sizing.size_080,marginBlockStart:sizing.size_040,minBlockSize:"auto",position:"sticky"},srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
59
60
|
|
|
60
61
|
const ActionMenuOpenerCore=React.forwardRef(function ActionMenuOpenerCore(props,ref){const{children,disabled,waiting:_,testId,opened,"aria-label":ariaLabel,...restProps}=props;return jsx(Button,{"aria-expanded":opened?"true":"false","aria-haspopup":"menu",kind:"tertiary","aria-label":ariaLabel,disabled:disabled,...restProps,testId:testId,endIcon:caretDownIcon,ref:ref,children:children})});
|
|
61
62
|
|
|
@@ -63,11 +64,11 @@ const ActionMenu=React.forwardRef(function ActionMenu({alignment="left","aria-la
|
|
|
63
64
|
|
|
64
65
|
const StyledButton$1=addStyle("button");class SelectOpener extends React.Component{render(){const{children,disabled,readOnly,error,id,isPlaceholder,open,testId,"aria-label":ariaLabel,"aria-required":ariaRequired,"aria-controls":ariaControls,onBlur,onOpenChanged,...sharedProps}=this.props;const iconColor=disabled?semanticColor.core.foreground.disabled.default:semanticColor.core.foreground.neutral.default;const style=[styles$5.shared,styles$5.default,disabled&&styles$5.disabled,error&&styles$5.error,isPlaceholder&&styles$5.placeholder,isPlaceholder&&disabled&&styles$5.disabledPlaceholder,!disabled&&!readOnly&&this.state.pressed&&styles$5.press,readOnly&&styles$5.readOnly,readOnly&&isPlaceholder&&styles$5.placeholder];const allowInteraction=!disabled&&!readOnly;return jsxs(StyledButton$1,{...sharedProps,"aria-disabled":readOnly||disabled||undefined,"aria-expanded":open?"true":"false","aria-invalid":error,"aria-label":ariaLabel??undefined,"aria-required":ariaRequired,"aria-haspopup":"listbox","aria-controls":ariaControls,"data-testid":testId,id:id,role:"combobox",type:"button",style:style,onClick:allowInteraction?this.handleClick:undefined,onKeyDown:allowInteraction?this.handleKeyDown:undefined,onKeyUp:allowInteraction?this.handleKeyUp:undefined,onBlur:onBlur,children:[jsx(BodyText,{tag:"span",style:styles$5.text,children:children||jsx("span",{"aria-hidden":"true",children:" "})}),jsx(PhosphorIcon,{icon:caretDownIcon,color:iconColor,size:"small",style:styles$5.caret,"aria-hidden":"true"})]})}constructor(props){super(props),this.handleClick=e=>{const{open}=this.props;this.props.onOpenChanged(!open);},this.handleKeyDown=e=>{const keyName=e.key;if(keyName===keys.enter||keyName===keys.space){this.setState({pressed:true});e.preventDefault();}},this.handleKeyUp=e=>{const keyName=e.key;if(keyName===keys.enter||keyName===keys.space){this.setState({pressed:false});this.handleClick(e);}};this.state={pressed:false};}}SelectOpener.defaultProps={disabled:false,readOnly:false,error:false,isPlaceholder:false};const PRESS_SHADOW=`0 0 0 ${border.width.thin} ${semanticColor.input.default.border}`;const styles$5=StyleSheet.create({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"space-between",color:semanticColor.core.foreground.neutral.strong,height:DROPDOWN_ITEM_HEIGHT,paddingInlineStart:theme.opener.layout.padding.inlineStart,paddingInlineEnd:theme.opener.layout.padding.inlineEnd,borderWidth:0,borderRadius:theme.opener.border.radius.rest,borderStyle:"solid",outline:"none",textDecoration:"none",boxSizing:"border-box",whiteSpace:"nowrap",touchAction:"manipulation"},text:{marginInlineEnd:sizing.size_080,whiteSpace:"nowrap",userSelect:"none",overflow:"hidden",textOverflow:"ellipsis"},caret:{minInlineSize:sizing.size_160},default:{background:semanticColor.input.default.background,border:`${border.width.thin} solid ${semanticColor.input.default.border}`,color:semanticColor.input.default.foreground,cursor:"pointer",":active":{boxShadow:PRESS_SHADOW},":focus":{...focusStyles.focus[":focus-visible"]},[":focus:active"]:{boxShadow:`${PRESS_SHADOW}, ${focusStyles.focus[":focus-visible"].boxShadow}`}},error:{background:semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground,[":focus:active"]:{boxShadow:`${PRESS_SHADOW}, ${focusStyles.focus[":focus-visible"].boxShadow}`}},disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground,cursor:"not-allowed",":active":{boxShadow:"none"},[":focus:active"]:{boxShadow:focusStyles.focus[":focus-visible"].boxShadow}},press:{boxShadow:PRESS_SHADOW,":focus-visible":{boxShadow:`${PRESS_SHADOW}, ${focusStyles.focus[":focus-visible"].boxShadow}`}},placeholder:{color:semanticColor.input.default.placeholder},disabledPlaceholder:{color:semanticColor.input.disabled.placeholder},readOnly:{background:semanticColor.input.readOnly.background,color:semanticColor.input.readOnly.text,":active":{boxShadow:"none"},[":focus:active"]:{boxShadow:focusStyles.focus[":focus-visible"].boxShadow}}});
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
function hasValue(value){return value?value.length>0:false}function useSelectValidation({value,disabled=false,validate,onValidate,required,open}){const{strings}=useWonderBlocksI18n();const[errorMessage,setErrorMessage]=React.useState(()=>validate&&hasValue(value)&&!disabled&&validate(value)||null);const handleValidation=React.useCallback(newValue=>{if(disabled){return}if(validate){const error=newValue!==undefined&&validate(newValue)||null;setErrorMessage(error);if(onValidate){onValidate(error);}if(error){return}}if(required){const requiredString=typeof required==="string"?required:strings.requiredFieldMessage;const error=hasValue(newValue)?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}},[disabled,validate,setErrorMessage,onValidate,required,strings.requiredFieldMessage]);useOnMountEffect(()=>{if(hasValue(value)){handleValidation(value);}});function onOpenerBlurValidation(){if(!open&&required&&!hasValue(value)){handleValidation(value);}}const onDropdownClosedValidation=()=>{if(required&&!hasValue(value)){handleValidation(value);}};const onSelectionValidation=newValue=>{handleValidation(newValue);};const onSelectedValuesChangeValidation=()=>{setErrorMessage(null);if(onValidate){onValidate(null);}};return {errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}}
|
|
67
68
|
|
|
68
|
-
const SingleSelect=props=>{const selectedIndex=React.useRef(0);const isInitialRender=React.useRef(true);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels
|
|
69
|
+
const SingleSelect=props=>{const selectedIndex=React.useRef(0);const isInitialRender=React.useRef(true);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels:propLabels,onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;const{strings}=useWonderBlocksI18n();const labels=React.useMemo(()=>({clearSearch:propLabels?.clearSearch||strings.iconAltClearSearch,filter:propLabels?.filter||strings.filter,noResults:propLabels?.noResults||strings.noResults,someResults:propLabels?.someResults||(numResults=>strings.numItems({num:numResults}))}),[strings,propLabels]);const[open,setOpen]=React.useState(false);const[searchText,setSearchText]=React.useState("");const[openerElement,setOpenerElement]=React.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation}=useSelectValidation({value:selectedValue,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React.useEffect(()=>{if(disabled||readOnly){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened,readOnly]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");if(onToggle){onToggle(opened);}if(!opened){onDropdownClosedValidation();}};const handleToggle=newSelectedValue=>{if(newSelectedValue!==selectedValue){onChange(newSelectedValue);}if(open&&openerElement){openerElement.focus();}setOpen(false);if(onToggle){onToggle(false);}onSelectionValidation(newSelectedValue);};const mapOptionItemsToDropdownItems=children=>{let indexCounter=0;selectedIndex.current=0;return children.map(option=>{const{disabled,value}=option.props;const selected=selectedValue===value;if(selected){selectedIndex.current=indexCounter;}if(!disabled){indexCounter+=1;}return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selected,variant:"check"}}})};const filterChildren=children=>{const lowercasedSearchText=searchText.toLowerCase();return children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1)};const getMenuItems=children=>{return mapOptionItemsToDropdownItems(isFilterable?filterChildren(children):children)};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleOpenerRef=node=>{const openerElement=ReactDOM.findDOMNode(node);setOpenerElement(openerElement);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{announceMessage({message,level:"polite"});};const childrenRef=React.useRef(children);childrenRef.current=children;const announceSelectedItem=()=>{const optionItems=React.Children.toArray(childrenRef.current);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}};React.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}announceSelectedItem();},[selectedValue]);const computedRequired=ariaRequired??!!required;const renderOpener=(isDisabled,dropdownId)=>{const items=React.Children.toArray(children);const selectedItem=items.find(option=>option.props.value===selectedValue);let menuContent;if(selectedItem){menuContent=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem.props);}else {menuContent=placeholder;}const dropdownOpener=jsx(Id,{id:id,children:uniqueOpenerId=>{return opener?jsx(DropdownOpener,{id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,"aria-haspopup":"listbox",onClick:handleClick,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:menuContent,opened:open,error:hasError,onBlur:onOpenerBlurValidation,readOnly:readOnly,children:opener}):jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,readOnly:readOnly,children:menuContent})}});return dropdownOpener};const allChildren=React.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const items=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;const disableInteraction=isDisabled||readOnly;const listboxLabelProps=getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement});const{someResults}=labels;const someResultsRef=React.useRef(someResults);someResultsRef.current=someResults;const openRef=React.useRef(open);openRef.current=open;React.useEffect(()=>{if(openRef.current){handleAnnouncement(someResultsRef.current(items.length));}},[items.length]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore,{id:uniqueDropdownId,role:"listbox",selectionType:"single",alignment:alignment,autoFocus:autoFocus,enableTypeAhead:enableTypeAhead,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],initialFocusedIndex:selectedIndex.current,items:items,onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(isDisabled,uniqueDropdownId),openerElement:openerElement,style:style,className:className,isFilterable:isFilterable,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:labels,...listboxLabelProps,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:disableInteraction})})};
|
|
69
70
|
|
|
70
|
-
const MultiSelect=props=>{const isInitialRender=React.useRef(true);const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React.useMemo(()=>{
|
|
71
|
+
const MultiSelect=props=>{const isInitialRender=React.useRef(true);const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const{strings}=useWonderBlocksI18n();const labels=React.useMemo(()=>({clearSearch:propLabels?.clearSearch||strings.iconAltClearSearch,filter:propLabels?.filter||strings.filter,noResults:propLabels?.noResults||strings.noResults,selectAllLabel:propLabels?.selectAllLabel||(numOptions=>strings.selectAllWithCount({num:numOptions})),selectNoneLabel:propLabels?.selectNoneLabel||strings.selectNone,noneSelected:propLabels?.noneSelected||strings.zeroItems,someSelected:propLabels?.someSelected||(numSelectedValues=>strings.numItems({num:numSelectedValues})),allSelected:propLabels?.allSelected||strings.allItems}),[strings,propLabels]);const[open,setOpen]=React.useState(false);const[searchText,setSearchText]=React.useState("");const[lastSelectedValues,setLastSelectedValues]=React.useState([]);const[openerElement,setOpenerElement]=React.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}=useSelectValidation({value:selectedValues,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React.useEffect(()=>{if(disabled||readOnly){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened,readOnly]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");setLastSelectedValues(selectedValues);if(onToggle){onToggle(opened);}if(!opened){if(lastSelectedValues!==selectedValues){onSelectionValidation(selectedValues);}else {onDropdownClosedValidation();}}};const handleToggle=selectedValue=>{if(selectedValues.includes(selectedValue)){const index=selectedValues.indexOf(selectedValue);const updatedSelection=[...selectedValues.slice(0,index),...selectedValues.slice(index+1)];onChange(updatedSelection);}else {onChange([...selectedValues,selectedValue]);}onSelectedValuesChangeValidation();};const handleSelectAll=()=>{const allChildren=React.Children.toArray(children);const selected=allChildren.filter(option=>!!option&&!option.props.disabled).map(option=>option.props.value);onChange(selected);onSelectedValuesChangeValidation();};const handleSelectNone=()=>{onChange([]);onSelectedValuesChangeValidation();};const getMenuTextOrNode=React.useCallback(children=>{const{noneSelected,someSelected,allSelected}=labels;const numSelectedAll=children.filter(option=>!option.props.disabled).length;const noSelectionText=implicitAllEnabled?allSelected:noneSelected;switch(selectedValues.length){case 0:return noSelectionText;case 1:const selectedItem=children.find(option=>option.props.value===selectedValues[0]);if(selectedItem){const selectedLabel=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem?.props);if(selectedLabel){return selectedLabel}else {return someSelected(1)}}return noSelectionText;case numSelectedAll:return allSelected;default:return someSelected(selectedValues.length)}},[implicitAllEnabled,labels,selectedValues,showOpenerLabelAsText]);const getShortcuts=numOptions=>{const{selectAllLabel,selectNoneLabel}=labels;if(shortcuts&&!searchText){const selectAllDisabled=numOptions===selectedValues.length;const selectAll={component:jsx(ActionItem,{disabled:selectAllDisabled,label:selectAllLabel(numOptions),indent:true,onClick:handleSelectAll}),focusable:!selectAllDisabled,populatedProps:{}};const selectNoneDisabled=selectedValues.length===0;const selectNone={component:jsx(ActionItem,{disabled:selectNoneDisabled,label:selectNoneLabel,indent:true,onClick:handleSelectNone}),focusable:!selectNoneDisabled,populatedProps:{}};const separator={component:jsx(SeparatorItem,{},"shortcuts-separator"),focusable:false,populatedProps:{}};return [selectAll,selectNone,separator]}else {return []}};const getMenuItems=children=>{if(!isFilterable){return children.map(mapOptionItemToDropdownItem)}const lowercasedSearchText=searchText.toLowerCase();const filteredChildren=children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1);const lastSelectedChildren=[];const restOfTheChildren=[];for(const child of filteredChildren){if(lastSelectedValues.includes(child.props.value)){lastSelectedChildren.push(child);}else {restOfTheChildren.push(child);}}const lastSelectedItems=lastSelectedChildren.map(mapOptionItemToDropdownItem);if(lastSelectedChildren.length&&restOfTheChildren.length){lastSelectedItems.push({component:jsx(SeparatorItem,{},"selected-separator"),focusable:false,populatedProps:{}});}return [...lastSelectedItems,...restOfTheChildren.map(mapOptionItemToDropdownItem)]};const mapOptionItemToDropdownItem=option=>{const{disabled,value}=option.props;return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selectedValues.includes(value),variant:"checkbox"}}};const handleOpenerRef=node=>{const openerElement=ReactDOM.findDOMNode(node);setOpenerElement(openerElement);};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{announceMessage({message,level:"polite"});};const maybeGetOpenerStringValue=React.useCallback((children,openerContent)=>{let openerStringValue;if(selectedValues.length===1){const selectedItem=children.find(option=>option.props.value===selectedValues[0]);openerStringValue=selectedItem?getLabel(selectedItem?.props):undefined;}else if(typeof openerContent==="string"){openerStringValue=openerContent;}return openerStringValue},[selectedValues]);const prevOpenRef=React.useRef(open);const selectionChangedRef=React.useRef(false);const childrenRef=React.useRef(children);childrenRef.current=children;const getMenuTextOrNodeRef=React.useRef(getMenuTextOrNode);getMenuTextOrNodeRef.current=getMenuTextOrNode;const maybeGetOpenerStringValueRef=React.useRef(maybeGetOpenerStringValue);maybeGetOpenerStringValueRef.current=maybeGetOpenerStringValue;const announceOpenerValue=()=>{const optionItems=React.Children.toArray(childrenRef.current);const openerContent=getMenuTextOrNodeRef.current(optionItems);const openerStringValue=maybeGetOpenerStringValueRef.current(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}};React.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;prevOpenRef.current=open;return}const justOpened=open&&!prevOpenRef.current;const justClosed=!open&&prevOpenRef.current;prevOpenRef.current=open;if(justOpened){selectionChangedRef.current=false;}else if(justClosed){if(selectionChangedRef.current){announceOpenerValue();selectionChangedRef.current=false;}}else if(open){selectionChangedRef.current=true;announceOpenerValue();}},[selectedValues,open]);const computedRequired=ariaRequired??!!required;const renderOpener=(allChildren,isDisabled,dropdownId)=>{const{noneSelected}=labels;const openerContent=getMenuTextOrNode(allChildren);const dropdownOpener=jsx(Id,{id:id,children:uniqueOpenerId=>{return opener?jsx(DropdownOpener,{id:uniqueOpenerId,error:hasError,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,"aria-haspopup":"listbox",onClick:handleClick,onBlur:onOpenerBlurValidation,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:openerContent,opened:open,readOnly:readOnly,children:opener}):jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,readOnly:readOnly,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;const listboxLabelProps=getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement});const someSelectedRef=React.useRef(someSelected);someSelectedRef.current=someSelected;const allChildren=React.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const filteredItems=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;const disableInteraction=isDisabled||readOnly;React.useEffect(()=>{if(searchText){handleAnnouncement(someSelectedRef.current(filteredItems.length));}},[filteredItems.length,someSelectedRef]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore,{id:uniqueDropdownId,role:"listbox",alignment:alignment,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],isFilterable:isFilterable,items:[...getShortcuts(numEnabledOptions),...filteredItems],onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(allChildren,isDisabled,uniqueDropdownId),openerElement:openerElement,selectionType:"multi",style:style,className:className,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:{clearSearch,filter,noResults,someResults:someSelected},...listboxLabelProps,"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:disableInteraction})})};
|
|
71
72
|
|
|
72
73
|
function updateMultipleSelection(previousSelection,value=""){if(!previousSelection){return [value]}return previousSelection.includes(value)?previousSelection.filter(item=>item!==value):[...previousSelection,value]}
|
|
73
74
|
|
|
@@ -75,13 +76,13 @@ function useListbox({children:options,disabled,disableSpaceSelection,id,onChange
|
|
|
75
76
|
|
|
76
77
|
function useMultipleSelection({inputValue,isComboboxOpen,selected,onRemove}){const[focusedMultiSelectIndex,setFocusedMultiSelectIndex]=React.useState(-1);React.useEffect(()=>{if(!isComboboxOpen){setFocusedMultiSelectIndex(-1);}},[isComboboxOpen]);const handleKeyDown=React.useCallback(event=>{const{key}=event;if(!Array.isArray(selected)||selected.length===0){return}if(inputValue===""&&key==="ArrowLeft"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev-1;return newIndex<0?selected?.length-1:newIndex});}if(inputValue===""&&key==="ArrowRight"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev+1;return newIndex>=selected?.length?0:newIndex});}if(inputValue===""&&key==="Backspace"){let newSelected=[];if(focusedMultiSelectIndex<0){newSelected=selected?.slice(0,-1);}else {newSelected=selected.filter((_,index)=>index!==focusedMultiSelectIndex);}setFocusedMultiSelectIndex(-1);onRemove?.(newSelected);}if(focusedMultiSelectIndex>=0&&key==="Enter"){const newSelected=selected?.filter((_,index)=>index!==focusedMultiSelectIndex);onRemove?.(newSelected);setFocusedMultiSelectIndex(-1);}if(key==="ArrowDown"||key==="ArrowUp"){setFocusedMultiSelectIndex(-1);}if(key==="Escape"){setFocusedMultiSelectIndex(-1);}},[focusedMultiSelectIndex,inputValue,selected,onRemove]);return {focusedMultiSelectIndex,handleKeyDown}}
|
|
77
78
|
|
|
78
|
-
const StyledSpan=addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels={closedState:
|
|
79
|
+
const StyledSpan=addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels:propLabels,selectedLabels,opened,options,selected,selectionType="single",testId}){const{strings}=useWonderBlocksI18n();const labels=React.useMemo(()=>({closedState:propLabels?.closedState||strings.srComboboxClosed,liveRegionCurrentItem:propLabels?.liveRegionCurrentItem||(({current,index,total,disabled,focused,selected})=>{const states=[focused&&strings.srFocused,disabled&&strings.srDisabled,selected&&strings.srSelected].filter(Boolean);return strings.srCurrentItemDetails({current:[current,...states].join(" "),index:index+1,total})}),liveRegionListboxTotal:propLabels?.liveRegionListboxTotal||(total=>strings.srNumResultsAvailable({num:total})),liveRegionMultipleSelectionTotal:propLabels?.liveRegionMultipleSelectionTotal||(total=>strings.srNumSelectedOptions({num:total})),noItems:propLabels?.noItems||strings.noResults,selected:propLabels?.selected||(labels=>strings.srItemsSelected({labels})),selectionCleared:propLabels?.selectionCleared||strings.srSelectionCleared,unselected:propLabels?.unselected||(labels=>strings.srItemsNotSelected({labels}))}),[propLabels,strings]);const lastSelectedValue=React.useRef(null);const[message,setMessage]=React.useState("");React.useEffect(()=>{if(selected&&selected!==lastSelectedValue?.current){let newMessage="";const lastSelectedLength=lastSelectedValue?.current?.length??0;const selectedLength=selected?.length??0;if(Array.isArray(selected)&&selected.length>0){const currentLabels=selectedLabels.join(", ");const selectedState=selectedLength>lastSelectedLength?labels.selected(currentLabels):labels.unselected(currentLabels);newMessage=selectedState;}else {newMessage=labels.selected(selectedLabels[0]);}setMessage(newMessage);}if(selectionType==="single"&&!selected&&lastSelectedValue.current){setMessage(labels.selectionCleared);}lastSelectedValue.current=selected;if(selectionType==="multiple"&&!opened){setMessage(labels.closedState);}},[labels,labels.closedState,selectedLabels,opened,selected,selectionType]);const focusedElementDescription=React.useMemo(()=>{if(focusedMultiSelectIndex>=0){const label=selectedLabels[focusedMultiSelectIndex];return labels.liveRegionCurrentItem({current:label,focused:true,index:focusedMultiSelectIndex,total:selectedLabels.length})+" "+labels.liveRegionMultipleSelectionTotal(selectedLabels.length)}if(options.length===0){return labels.noItems}if(focusedIndex<0||!options[focusedIndex]){return ""}const currentItemProps=options[focusedIndex].props;const label=getLabel(currentItemProps);const totalResults=options.length;return labels.liveRegionCurrentItem({current:label,disabled:currentItemProps.disabled,focused:false,index:focusedIndex,selected:currentItemProps.selected,total:totalResults})+" "+labels.liveRegionListboxTotal(totalResults)},[focusedIndex,focusedMultiSelectIndex,labels,options,selectedLabels]);return jsx(StyledSpan,{role:"log","aria-live":"polite","aria-atomic":"false","aria-relevant":"additions text",style:styles$4.srOnly,"data-testid":testId?`${testId}-status`:undefined,children:opened?focusedElementDescription:message})}const styles$4=StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
79
80
|
|
|
80
81
|
const MultipleSelection=React.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsx(View,{role:"group",style:styles$3.container,id:id,children:selected.map((value,index)=>{const label=labels[index];const focused=index===focusedMultiSelectIndex;const uniqueId=id+index;return jsx(Button,{id:uniqueId,testId:testId?`${testId}-item-${index}`:undefined,size:"small",style:[styles$3.item,focused&&styles$3.itemFocused],kind:"secondary",actionType:"neutral","aria-label":removeSelectedLabel(label),tabIndex:-1,onClick:()=>onRemove(value),endIcon:disabled?undefined:jsx(PhosphorIcon,{icon:xIcon,size:"small"}),children:label},uniqueId)})})});const styles$3=StyleSheet.create({container:{flexDirection:"row",flexWrap:"wrap",gap:sizing.size_080,paddingBlockStart:sizing.size_080},item:{fontSize:font.body.size.small,justifyContent:"space-between",alignItems:"center",height:"auto",paddingInline:sizing.size_080},itemFocused:focusStyles.focus[":focus-visible"]});
|
|
81
82
|
|
|
82
83
|
function StandaloneListbox(props){const{children,disabled,id,onChange,selectionType="single",style,tabIndex=0,testId,value,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;const generatedUniqueId=useId();const uniqueId=id??generatedUniqueId;const{focusedIndex,isListboxFocused,renderList,selected,handleKeyDown,handleKeyUp,handleFocus,handleBlur}=useListbox({children,disabled,id:uniqueId,selectionType,value});React.useEffect(()=>{if(selected&&selected!==value){onChange?.(selected);}},[onChange,selected,value]);return jsx(View,{role:"listbox",id:uniqueId,style:[styles$2.listbox,style,disabled&&styles$2.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",onKeyDown:handleKeyDown,onKeyUp:handleKeyUp,onFocus:handleFocus,onBlur:handleBlur,"aria-activedescendant":isListboxFocused?renderList[focusedIndex].props.id:undefined,children:renderList})}function Listbox(props){const{children,disabled,id,selectionType="single",style,tabIndex=0,testId,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;if(tabIndex===0){return jsx(StandaloneListbox,{...props})}return jsx(View,{role:"listbox",id:id,style:[styles$2.listbox,style,disabled&&styles$2.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",children:children})}const styles$2=StyleSheet.create({listbox:{backgroundColor:semanticColor.core.background.base.default,outline:"none",paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline},disabled:{color:semanticColor.action.secondary.disabled.foreground}});
|
|
83
84
|
|
|
84
|
-
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value="",loading,style,...ariaAttrs}){const generatedUniqueId=useId();const uniqueId=id??generatedUniqueId;const comboboxRef=React.useRef(null);const rootNodeRef=React.useRef(null);const[open,setOpen]=React.useState(opened??false);const isControlled=opened!==undefined;const openState=disabled?false:isControlled?opened:open;const[selectedValue,setSelectedValue]=React.useState(value);const isValueControlled=value!==""&&onChange!==undefined;const valueState=isValueControlled?value:selectedValue;const[currentOptions,setCurrentOptions]=React.useState(children);const{focusedIndex,isListboxFocused,setFocusedIndex,handleKeyDown,handleFocus,handleBlur,selected,setSelected,renderList}=useListbox({children:currentOptions,disabled,id:uniqueId,onChange:value=>handleChange(value),value:valueState,disableSpaceSelection:true,selectionType});const itemFromSelected=renderList.find(item=>item.props.value===selected)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";const initialValue=typeof value==="string"?labelFromSelected:"";const[inputValue,setInputValue]=React.useState(initialValue);const updateAfterSelectionChange=React.useCallback(value=>{setSelected(value);onChange?.(value);},[onChange,setSelected]);const{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,onRemove:updateAfterSelectionChange,isComboboxOpen:openState});const updateOpenState=React.useCallback((newState,selectedLabel=labelFromSelected)=>{if(disabled||newState===openState){return}if(!isControlled){setOpen(newState);}if(!newState){setFocusedIndex(-1);if(selectionType==="multiple"){setInputValue("");}else {setInputValue(selectedLabel??"");}setCurrentOptions(children);}onToggle?.(newState);},[children,disabled,isControlled,labelFromSelected,onToggle,openState,selectionType,setFocusedIndex]);const handleChange=React.useCallback(value=>{if(value!==valueState){setSelectedValue(value);onChange?.(value);}if(selectionType==="single"&&typeof value==="string"){const itemFromSelected=renderList.find(item=>item.props.value===value)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";updateOpenState(false,labelFromSelected);}else if(Array.isArray(value)){setInputValue("");setCurrentOptions(children);}},[children,onChange,renderList,selectionType,updateOpenState,valueState]);const focusOnFilteredItem=React.useCallback((filtered,value)=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();const itemIndex=filtered.findIndex(item=>getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));setFocusedIndex(itemIndex);},[setFocusedIndex]);const filterItems=React.useCallback(value=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();return children.filter(item=>getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText)>-1)},[children]);const onKeyDown=event=>{const{key}=event;const conditionsToOpen=key==="ArrowDown"||key==="ArrowUp"||key==="Backspace"||key.length===1;if(!openState&&conditionsToOpen){updateOpenState(true);}if(key==="ArrowLeft"||key==="ArrowRight"){setFocusedIndex(-1);}handleMultipleSelectionKeyDown(event);if(key==="Escape"&&openState){event.stopPropagation();updateOpenState(false);}handleKeyDown(event);};const handleOnRemoveClick=React.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);updateAfterSelectionChange(newValues);},[selected,updateAfterSelectionChange]);const handleTextFieldChange=React.useCallback(value=>{setInputValue(value);let filteredItems=renderList;if(autoComplete==="list"){filteredItems=filterItems(value);setCurrentOptions(filteredItems);}focusOnFilteredItem(filteredItems,value);},[autoComplete,filterItems,focusOnFilteredItem,renderList]);const handleClearClick=React.useCallback(e=>{e.stopPropagation();setInputValue("");setSelected("");onChange?.("");comboboxRef.current?.focus();},[onChange,setSelected]);React.useEffect(()=>{if(openState){comboboxRef.current?.focus();}},[openState]);const selectedLabels=React.useMemo(()=>{if(Array.isArray(selected)){return selected.map(value=>{const item=children.find(item=>item.props.value===value);return item?getLabel(item?.props):""})}return [labelFromSelected]},[children,labelFromSelected,selected]);const maybeRenderStartIcon=()=>{if(!startIcon){return null}const startIconElement=React.cloneElement(startIcon,{size:"small",...startIcon.props,color:disabled?semanticColor.core.foreground.disabled.default:startIcon.props.color??semanticColor.core.foreground.neutral.default});return jsx(View,{style:styles$1.iconWrapper,children:startIconElement})};const pillIdPrefix=`${uniqueId}-pill-`;const textFieldId=useId();const currentActiveDescendant=!openState?undefined:focusedIndex>=0?renderList[focusedIndex]?.props?.id:pillIdPrefix+focusedMultiSelectIndex;const controlledWidget=!openState?undefined:focusedIndex>=0?uniqueId:pillIdPrefix;return jsxs(Fragment,{children:[jsxs(View,{onClick:()=>{updateOpenState(true);},ref:rootNodeRef,style:[styles$1.wrapper,isListboxFocused&&styles$1.focused,disabled&&styles$1.disabled,!disabled&&error&&styles$1.error],children:[jsx(ComboboxLiveRegion,{focusedIndex:focusedIndex,focusedMultiSelectIndex:focusedMultiSelectIndex,labels:labels,options:renderList,selectedLabels:selectedLabels,testId:testId,opened:openState,selected:selected,selectionType:selectionType}),selectionType==="multiple"&&Array.isArray(selected)&&jsx(MultipleSelection,{labels:selectedLabels,focusedMultiSelectIndex:focusedMultiSelectIndex,id:pillIdPrefix,selected:selected,onRemove:handleOnRemoveClick,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsx(TextField,{id:textFieldId,testId:testId,style:[styles$1.combobox,style],value:inputValue,onChange:handleTextFieldChange,disabled:disabled,onFocus:()=>{updateOpenState(true);handleFocus();},placeholder:placeholder,onBlur:()=>{updateOpenState(false);handleBlur();},onKeyDown:onKeyDown,"aria-activedescendant":currentActiveDescendant,"aria-autocomplete":autoComplete,"aria-controls":controlledWidget,"aria-expanded":openState,"aria-invalid":!!error,ref:comboboxRef,autoComplete:"off",role:"combobox",...ariaAttrs}),inputValue&&!disabled&&jsx(IconButton,{icon:xIcon,onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.clearButton],"aria-label":labels.clearSelection,testId:testId?`${testId}-clear`:undefined}),jsx(IconButton,{disabled:disabled,icon:caretDownIcon$1,onClick:e=>{e.stopPropagation();updateOpenState(!openState);},onMouseDown:e=>{e.preventDefault();},actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.openButtonResetStates,openState&&styles$1.buttonOpen],tabIndex:-1,"aria-controls":uniqueId,"aria-expanded":openState,"aria-label":labels.comboboxButton})]}),openState&&jsx(DropdownPopper,{alignment:"left",referenceElement:rootNodeRef?.current,children:isReferenceHidden=>jsx(View,{onMouseDown:e=>{e.preventDefault();},children:renderList.length===0?jsx(DetailCell,{title:labels.noItems,styles:{root:[styles$1.listbox,{minInlineSize:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles$1.listbox,isReferenceHidden&&styles$1.hidden,{minInlineSize:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles$1=StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxInlineSize:"100%",flexWrap:"wrap",background:semanticColor.core.background.base.default,borderRadius:theme.opener.border.radius.rest,border:`${border.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,paddingInline:theme.opener.layout.padding.inline,overflow:"hidden"},focused:focusStyles.focus[":focus-visible"],disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground},error:{background:semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground},combobox:{appearance:"none",background:"none",border:"none",outline:"none",padding:0,minInlineSize:sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none",boxShadow:"none"},[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"},[":focus-visible:active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"}},listbox:{backgroundColor:semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",insetInlineEnd:sizing.size_0,margin:0},buttonOpen:{transform:"rotate(180deg)"},openButtonResetStates:{":hover":{borderColor:semanticColor.core.transparent},":active":{borderColor:semanticColor.core.transparent},":focus-visible":{outline:"none",boxShadow:"none"}},clearButton:{insetInlineEnd:sizing.size_360},iconWrapper:{padding:sizing.size_040,minInlineSize:"auto"}});
|
|
85
|
+
function Combobox({autoComplete,children,disabled,error,id,labels:propLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value="",loading,style,...ariaAttrs}){const{strings}=useWonderBlocksI18n();const labels=React.useMemo(()=>({clearSelection:propLabels?.clearSelection||strings.iconAltClearSelection,comboboxButton:propLabels?.comboboxButton||strings.iconAltToggleListbox,listbox:propLabels?.listbox||strings.optionsList,noItems:propLabels?.noItems||strings.noResults,removeSelected:propLabels?.removeSelected||(label=>strings.removeOption({label}))}),[propLabels,strings]);const liveRegionLabels=React.useMemo(()=>({closedState:propLabels?.closedState,liveRegionCurrentItem:propLabels?.liveRegionCurrentItem,liveRegionListboxTotal:propLabels?.liveRegionListboxTotal,liveRegionMultipleSelectionTotal:propLabels?.liveRegionMultipleSelectionTotal,noItems:propLabels?.noItems,selected:propLabels?.selected,selectionCleared:propLabels?.selectionCleared,unselected:propLabels?.unselected}),[propLabels]);const generatedUniqueId=useId();const uniqueId=id??generatedUniqueId;const comboboxRef=React.useRef(null);const rootNodeRef=React.useRef(null);const[open,setOpen]=React.useState(opened??false);const isControlled=opened!==undefined;const openState=disabled?false:isControlled?opened:open;const[selectedValue,setSelectedValue]=React.useState(value);const isValueControlled=value!==""&&onChange!==undefined;const valueState=isValueControlled?value:selectedValue;const[currentOptions,setCurrentOptions]=React.useState(children);const{focusedIndex,isListboxFocused,setFocusedIndex,handleKeyDown,handleFocus,handleBlur,selected,setSelected,renderList}=useListbox({children:currentOptions,disabled,id:uniqueId,onChange:value=>handleChange(value),value:valueState,disableSpaceSelection:true,selectionType});const itemFromSelected=renderList.find(item=>item.props.value===selected)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";const initialValue=typeof value==="string"?labelFromSelected:"";const[inputValue,setInputValue]=React.useState(initialValue);const updateAfterSelectionChange=React.useCallback(value=>{setSelected(value);onChange?.(value);},[onChange,setSelected]);const{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,onRemove:updateAfterSelectionChange,isComboboxOpen:openState});const updateOpenState=React.useCallback((newState,selectedLabel=labelFromSelected)=>{if(disabled||newState===openState){return}if(!isControlled){setOpen(newState);}if(!newState){setFocusedIndex(-1);if(selectionType==="multiple"){setInputValue("");}else {setInputValue(selectedLabel??"");}setCurrentOptions(children);}onToggle?.(newState);},[children,disabled,isControlled,labelFromSelected,onToggle,openState,selectionType,setFocusedIndex]);const handleChange=React.useCallback(value=>{if(value!==valueState){setSelectedValue(value);onChange?.(value);}if(selectionType==="single"&&typeof value==="string"){const itemFromSelected=renderList.find(item=>item.props.value===value)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";updateOpenState(false,labelFromSelected);}else if(Array.isArray(value)){setInputValue("");setCurrentOptions(children);}},[children,onChange,renderList,selectionType,updateOpenState,valueState]);const focusOnFilteredItem=React.useCallback((filtered,value)=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();const itemIndex=filtered.findIndex(item=>getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));setFocusedIndex(itemIndex);},[setFocusedIndex]);const filterItems=React.useCallback(value=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();return children.filter(item=>getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText)>-1)},[children]);const onKeyDown=event=>{const{key}=event;const conditionsToOpen=key==="ArrowDown"||key==="ArrowUp"||key==="Backspace"||key.length===1;if(!openState&&conditionsToOpen){updateOpenState(true);}if(key==="ArrowLeft"||key==="ArrowRight"){setFocusedIndex(-1);}handleMultipleSelectionKeyDown(event);if(key==="Escape"&&openState){event.stopPropagation();updateOpenState(false);}handleKeyDown(event);};const handleOnRemoveClick=React.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);updateAfterSelectionChange(newValues);},[selected,updateAfterSelectionChange]);const handleTextFieldChange=React.useCallback(value=>{setInputValue(value);let filteredItems=renderList;if(autoComplete==="list"){filteredItems=filterItems(value);setCurrentOptions(filteredItems);}focusOnFilteredItem(filteredItems,value);},[autoComplete,filterItems,focusOnFilteredItem,renderList]);const handleClearClick=React.useCallback(e=>{e.stopPropagation();setInputValue("");setSelected("");onChange?.("");comboboxRef.current?.focus();},[onChange,setSelected]);React.useEffect(()=>{if(openState){comboboxRef.current?.focus();}},[openState]);const selectedLabels=React.useMemo(()=>{if(Array.isArray(selected)){return selected.map(value=>{const item=children.find(item=>item.props.value===value);return item?getLabel(item?.props):""})}return [labelFromSelected]},[children,labelFromSelected,selected]);const maybeRenderStartIcon=()=>{if(!startIcon){return null}const startIconElement=React.cloneElement(startIcon,{size:"small",...startIcon.props,color:disabled?semanticColor.core.foreground.disabled.default:startIcon.props.color??semanticColor.core.foreground.neutral.default});return jsx(View,{style:styles$1.iconWrapper,children:startIconElement})};const pillIdPrefix=`${uniqueId}-pill-`;const textFieldId=useId();const currentActiveDescendant=!openState?undefined:focusedIndex>=0?renderList[focusedIndex]?.props?.id:pillIdPrefix+focusedMultiSelectIndex;const controlledWidget=!openState?undefined:focusedIndex>=0?uniqueId:pillIdPrefix;return jsxs(Fragment,{children:[jsxs(View,{onClick:()=>{updateOpenState(true);},ref:rootNodeRef,style:[styles$1.wrapper,isListboxFocused&&styles$1.focused,disabled&&styles$1.disabled,!disabled&&error&&styles$1.error],children:[jsx(ComboboxLiveRegion,{focusedIndex:focusedIndex,focusedMultiSelectIndex:focusedMultiSelectIndex,labels:liveRegionLabels,options:renderList,selectedLabels:selectedLabels,testId:testId,opened:openState,selected:selected,selectionType:selectionType}),selectionType==="multiple"&&Array.isArray(selected)&&jsx(MultipleSelection,{labels:selectedLabels,focusedMultiSelectIndex:focusedMultiSelectIndex,id:pillIdPrefix,selected:selected,onRemove:handleOnRemoveClick,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsx(TextField,{id:textFieldId,testId:testId,style:[styles$1.combobox,style],value:inputValue,onChange:handleTextFieldChange,disabled:disabled,onFocus:()=>{updateOpenState(true);handleFocus();},placeholder:placeholder,onBlur:()=>{updateOpenState(false);handleBlur();},onKeyDown:onKeyDown,"aria-activedescendant":currentActiveDescendant,"aria-autocomplete":autoComplete,"aria-controls":controlledWidget,"aria-expanded":openState,"aria-invalid":!!error,ref:comboboxRef,autoComplete:"off",role:"combobox",...ariaAttrs}),inputValue&&!disabled&&jsx(IconButton,{icon:xIcon,onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.clearButton],"aria-label":labels.clearSelection,testId:testId?`${testId}-clear`:undefined}),jsx(IconButton,{disabled:disabled,icon:caretDownIcon$1,onClick:e=>{e.stopPropagation();updateOpenState(!openState);},onMouseDown:e=>{e.preventDefault();},actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.openButtonResetStates,openState&&styles$1.buttonOpen],tabIndex:-1,"aria-controls":uniqueId,"aria-expanded":openState,"aria-label":labels.comboboxButton})]}),openState&&jsx(DropdownPopper,{alignment:"left",referenceElement:rootNodeRef?.current,children:isReferenceHidden=>jsx(View,{onMouseDown:e=>{e.preventDefault();},children:renderList.length===0?jsx(DetailCell,{title:labels.noItems,styles:{root:[styles$1.listbox,{minInlineSize:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles$1.listbox,isReferenceHidden&&styles$1.hidden,{minInlineSize:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles$1=StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxInlineSize:"100%",flexWrap:"wrap",background:semanticColor.core.background.base.default,borderRadius:theme.opener.border.radius.rest,border:`${border.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,paddingInline:theme.opener.layout.padding.inline,overflow:"hidden"},focused:focusStyles.focus[":focus-visible"],disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground},error:{background:semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground},combobox:{appearance:"none",background:"none",border:"none",outline:"none",padding:0,minInlineSize:sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none",boxShadow:"none"},[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"},[":focus-visible:active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"}},listbox:{backgroundColor:semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",insetInlineEnd:sizing.size_0,margin:0},buttonOpen:{transform:"rotate(180deg)"},openButtonResetStates:{":hover":{borderColor:semanticColor.core.transparent},":active":{borderColor:semanticColor.core.transparent},":focus-visible":{outline:"none",boxShadow:"none"}},clearButton:{insetInlineEnd:sizing.size_360},iconWrapper:{padding:sizing.size_040,minInlineSize:"auto"}});
|
|
85
86
|
|
|
86
87
|
const StyledButton=addStyle("button");const CustomOpener=React.forwardRef(function CustomOpener(props,ref){const{children,disabled,onClick,styles:stylesProp,testId,...restProps}=props;const injectedAriaDisabled=restProps["aria-disabled"];const ariaDisabled=injectedAriaDisabled??(disabled||undefined);return jsx(StyledButton,{...restProps,ref:ref,type:"button","aria-disabled":ariaDisabled,onClick:disabled?undefined:onClick,"data-testid":testId,style:[styles.reset,disabled&&styles.disabled,stylesProp?.root],children:jsx(BodyText,{tag:"span",style:[styles.labelReset,stylesProp?.label],children:children})})});CustomOpener.displayName="CustomOpener";const styles=StyleSheet.create({reset:{appearance:"none",background:"none",border:"none",boxSizing:"border-box",cursor:"pointer",font:"inherit",margin:0,padding:0,textAlign:"inherit",touchAction:"manipulation",...focusStyles.focus},labelReset:{alignItems:"center",display:"flex",flexDirection:"row",gap:sizing.size_020},disabled:{cursor:"not-allowed"}});
|
|
87
88
|
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var wonderBlocksClickable = require('@khanacademy/wonder-blocks-clickable');
|
|
|
16
16
|
var ReactDOM = require('react-dom');
|
|
17
17
|
var SearchField = require('@khanacademy/wonder-blocks-search-field');
|
|
18
18
|
var wonderBlocksTiming = require('@khanacademy/wonder-blocks-timing');
|
|
19
|
+
var wonderBlocksConfig = require('@khanacademy/wonder-blocks-config');
|
|
19
20
|
var reactWindow = require('react-window');
|
|
20
21
|
var reactPopper = require('react-popper');
|
|
21
22
|
var wonderBlocksModal = require('@khanacademy/wonder-blocks-modal');
|
|
@@ -58,7 +59,7 @@ var caretDownIcon__default$1 = /*#__PURE__*/_interopDefaultLegacy(caretDownIcon$
|
|
|
58
59
|
var xIcon__default = /*#__PURE__*/_interopDefaultLegacy(xIcon);
|
|
59
60
|
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
60
61
|
|
|
61
|
-
const selectDropdownStyle={marginBlock:wonderBlocksTokens.sizing.size_080};const filterableDropdownStyle={minHeight:100};const DROPDOWN_ITEM_HEIGHT=40;const MAX_VISIBLE_ITEMS=9;const SEPARATOR_ITEM_HEIGHT=9;
|
|
62
|
+
const selectDropdownStyle={marginBlock:wonderBlocksTokens.sizing.size_080};const filterableDropdownStyle={minHeight:100};const DROPDOWN_ITEM_HEIGHT=40;const MAX_VISIBLE_ITEMS=9;const SEPARATOR_ITEM_HEIGHT=9;
|
|
62
63
|
|
|
63
64
|
var themeDefault = {listbox:{border:{radius:wonderBlocksTokens.border.radius.radius_040},layout:{padding:{inline:wonderBlocksTokens.sizing.size_0,block:wonderBlocksTokens.sizing.size_040}},shadow:{default:wonderBlocksTokens.boxShadow.mid}},opener:{border:{width:{error:wonderBlocksTokens.border.width.thin},radius:{rest:wonderBlocksTokens.border.radius.radius_040}},layout:{padding:{inline:wonderBlocksTokens.sizing.size_160,inlineStart:wonderBlocksTokens.sizing.size_160,inlineEnd:wonderBlocksTokens.sizing.size_120}}},item:{border:{radius:{default:wonderBlocksTokens.border.radius.radius_040,press:wonderBlocksTokens.border.radius.radius_040}},layout:{padding:{block:wonderBlocksTokens.sizing.size_100,inlineStart:wonderBlocksTokens.sizing.size_080,inlineEnd:wonderBlocksTokens.sizing.size_160}},font:{weight:wonderBlocksTokens.font.weight.regular}}};
|
|
64
65
|
|
|
@@ -88,7 +89,7 @@ const modifiers=[{name:"preventOverflow",options:{rootBoundary:"viewport",altAxi
|
|
|
88
89
|
|
|
89
90
|
function getStringForKey(key){if(key.length===1||!/^[A-Z]/i.test(key)){return key}return ""}function debounce(callback,wait){let timeout;return function executedFunction(...args){const later=()=>{clearTimeout(timeout);callback(...args);};clearTimeout(timeout);timeout=setTimeout(later,wait);}}function isString(x){return typeof x==="string"}function getLabel(props){if(isString(props.label)){return props.label}if(isString(props.labelAsText)){return props.labelAsText}return ""}function getSelectOpenerLabel(showOpenerLabelAsText,props){if(showOpenerLabelAsText){return getLabel(props)}return props.label}function getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement}){const openerLabel=getOpenerLabel(openerElement);const labelId=ariaLabelledBy||openerLabel?.id;if(labelId){return {"aria-labelledby":labelId}}const label=openerLabel?.textContent||ariaLabel;return label?{"aria-label":label}:{}}function getOpenerLabel(openerElement){if(!openerElement||!("labels"in openerElement)){return undefined}return openerElement.labels?.[0]}
|
|
90
91
|
|
|
91
|
-
const VIRTUALIZE_THRESHOLD=125;const sameItemsFocusable=(prevItems,currentItems)=>{if(prevItems.length!==currentItems.length){return false}for(let i=0;i<prevItems.length;i++){if(prevItems[i].focusable!==currentItems[i].focusable){return false}}return true};const createItemRefs=items=>{const itemRefs=[];for(let i=0;i<items.length;i++){if(items[i].focusable){const ref=React__namespace.createRef();itemRefs.push({ref,originalIndex:i});}}return itemRefs};const defaultPropLabels={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected};const DropdownCore=props=>{const{"aria-invalid":ariaInvalid,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-required":ariaRequired,alignment="left",autoFocus=true,className,disabled,dropdownStyle,enableTypeAhead=true,id,initialFocusedIndex,isFilterable,items,labels:propLabels=defaultPropLabels,onOpenChanged,onSearchTextChanged,open,opener,openerElement,role,searchText,selectionType="single",style}=props;const schedule=wonderBlocksTiming.useActionScheduler();const openRef=wonderBlocksCore.useLatestRef(open);const onOpenChangedRef=wonderBlocksCore.useLatestRef(onOpenChanged);const rootRef=React__namespace.useRef(null);const popperElementRef=React__namespace.useRef(undefined);const virtualizedListRef=React__namespace.useRef(null);const searchFieldRef=React__namespace.useRef(null);const textSuggestionRef=React__namespace.useRef("");const[labels,setLabels]=React__namespace.useState(()=>({noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected,...propLabels}));const committedItemsRef=React__namespace.useRef({itemRefs:[],prevItems:items});const{itemRefs:prevItemRefs,prevItems}=committedItemsRef.current;const shouldCreateItemRefs=prevItemRefs.length===0&&open||!sameItemsFocusable(prevItems,items);const derivedItems=shouldCreateItemRefs?{itemRefs:createItemRefs(items),sameItemsFocusable:false}:{itemRefs:prevItemRefs,sameItemsFocusable:true};const itemRefsRef=React__namespace.useRef(derivedItems.itemRefs);React__namespace.useEffect(()=>{committedItemsRef.current={itemRefs:derivedItems.itemRefs,prevItems:items};itemRefsRef.current=derivedItems.itemRefs;});const hasSearchField=React__namespace.useCallback(()=>{return !!isFilterable},[isFilterable]);const isSearchFieldFocused=React__namespace.useCallback(()=>{return hasSearchField()&&document.activeElement===searchFieldRef.current},[hasSearchField]);const focusSearchField=React__namespace.useCallback(()=>{if(searchFieldRef.current){searchFieldRef.current.focus();}},[]);const focusedIndexRef=React__namespace.useRef(-1);const focusedOriginalIndexRef=React__namespace.useRef(-1);const itemsClickedRef=React__namespace.useRef(false);const resetFocusedIndex=React__namespace.useCallback(()=>{if(typeof initialFocusedIndex!=="undefined"){focusedIndexRef.current=initialFocusedIndex;}else {if(hasSearchField()&&!isSearchFieldFocused()){return focusSearchField()}focusedIndexRef.current=0;}},[focusSearchField,hasSearchField,initialFocusedIndex,isSearchFieldFocused]);const initializedRef=React__namespace.useRef(false);if(!initializedRef.current){initializedRef.current=true;resetFocusedIndex();}const shouldVirtualizeList=React__namespace.useCallback(()=>{return items.length>VIRTUALIZE_THRESHOLD},[items]);const focusCurrentItem=React__namespace.useCallback(onFocus=>{const focusedItemRef=itemRefsRef.current[focusedIndexRef.current];if(!focusedItemRef){return}const{current:virtualizedList}=virtualizedListRef;if(virtualizedList){virtualizedList.scrollToItem(focusedItemRef.originalIndex);}const focusNode=()=>{if(!openRef.current){return}const currentFocusedItemRef=itemRefsRef.current[focusedIndexRef.current];const node=ReactDOM__namespace.findDOMNode(currentFocusedItemRef.ref.current);if(!node&&shouldVirtualizeList()){schedule.animationFrame(focusNode);return}if(node){schedule.timeout(()=>{node.focus();},0);focusedOriginalIndexRef.current=currentFocusedItemRef.originalIndex;if(onFocus){onFocus(node);}}};if(shouldVirtualizeList()){schedule.animationFrame(focusNode);}else {focusNode();}},[openRef,schedule,shouldVirtualizeList]);const scheduleToFocusCurrentItem=React__namespace.useCallback(onFocus=>{if(shouldVirtualizeList()){schedule.animationFrame(()=>{focusCurrentItem(onFocus);});}else {focusCurrentItem(onFocus);}},[focusCurrentItem,schedule,shouldVirtualizeList]);const maybeFocusInitialItem=React__namespace.useCallback(()=>{if(!autoFocus){return}if(open){resetFocusedIndex();scheduleToFocusCurrentItem();}else if(!open){itemsClickedRef.current=false;}},[autoFocus,open,resetFocusedIndex,scheduleToFocusCurrentItem]);React__namespace.useEffect(()=>{if(!open){return}const handleInteract=event=>{const target=event.target;const thisElement=rootRef.current;if(thisElement&&!thisElement.contains(target)&&popperElementRef.current&&!popperElementRef.current.contains(target)){onOpenChangedRef.current(false);}};document.addEventListener("mouseup",handleInteract);document.addEventListener("touchend",handleInteract);return ()=>{document.removeEventListener("mouseup",handleInteract);document.removeEventListener("touchend",handleInteract);}},[open,onOpenChangedRef]);wonderBlocksCore.useOnMountEffect(()=>{maybeFocusInitialItem();});const prevRenderRef=React__namespace.useRef(null);React__namespace.useEffect(()=>{const prevProps=prevRenderRef.current;prevRenderRef.current={open,searchText,labels:propLabels,derivedItems};if(!prevProps||prevProps.derivedItems===derivedItems){return}if(prevProps.open!==open){maybeFocusInitialItem();}else if(open){const{itemRefs,sameItemsFocusable}=derivedItems;if(sameItemsFocusable||prevProps.searchText!==searchText){return}else {const newFocusableIndex=itemRefs.findIndex(ref=>ref.originalIndex===focusedOriginalIndexRef.current);if(newFocusableIndex===-1){focusedIndexRef.current=0;itemsClickedRef.current=false;scheduleToFocusCurrentItem();}else {focusedIndexRef.current=newFocusableIndex;}}if(propLabels!==prevProps.labels){setLabels(prevLabels=>({...prevLabels,...propLabels}));}}});const focusPreviousItem=React__namespace.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=itemRefsRef.current.length-1;}else if(focusedIndexRef.current===0){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=itemRefsRef.current.length-1;}else {focusedIndexRef.current-=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const focusNextItem=React__namespace.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=0;}else if(focusedIndexRef.current===itemRefsRef.current.length-1){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=0;}else {focusedIndexRef.current+=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const restoreTabOrder=React__namespace.useCallback(()=>{if(openerElement){openerElement.focus();}},[openerElement]);const handleKeyDownDebounceResult=React__namespace.useCallback(key=>{const foundIndex=items.filter(item=>item.focusable).findIndex(({component})=>{if(SeparatorItem.isClassOf(component)){return false}if(OptionItem.isClassOf(component)){const optionItemProps=component.props;return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase())}return false});if(foundIndex>=0){const isClosed=!open;if(isClosed){onOpenChanged(true);}focusedIndexRef.current=foundIndex;scheduleToFocusCurrentItem(node=>{if(selectionType==="single"&&isClosed&&node){node.click();onOpenChanged(false);}});}textSuggestionRef.current="";},[items,onOpenChanged,open,scheduleToFocusCurrentItem,selectionType]);const handleKeyDownDebounceResultRef=React__namespace.useRef(handleKeyDownDebounceResult);handleKeyDownDebounceResultRef.current=handleKeyDownDebounceResult;const handleKeyDownDebounced=React__namespace.useMemo(()=>debounce(key=>handleKeyDownDebounceResultRef.current(key),500),[]);const handleKeyDown=event=>{const key=event.key;if(enableTypeAhead&&getStringForKey(key)){event.stopPropagation();textSuggestionRef.current+=key;handleKeyDownDebounced(textSuggestionRef.current);}if(!open){if(key===wonderBlocksCore.keys.down){event.preventDefault();onOpenChanged(true);return}return}switch(key){case wonderBlocksCore.keys.tab:if(isSearchFieldFocused()&&searchText){return}restoreTabOrder();onOpenChanged(false);return;case wonderBlocksCore.keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.up:event.preventDefault();focusPreviousItem();return;case wonderBlocksCore.keys.down:event.preventDefault();focusNextItem();return}};const handleKeyUp=event=>{const key=event.key;switch(key){case wonderBlocksCore.keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.escape:if(open){event.stopPropagation();restoreTabOrder();onOpenChanged(false);}return}};const handleClickFocus=index=>{itemsClickedRef.current=true;focusedIndexRef.current=index;focusedOriginalIndexRef.current=derivedItems.itemRefs[focusedIndexRef.current].originalIndex;};const handleDropdownMouseUp=event=>{if(event.nativeEvent.stopImmediatePropagation){event.nativeEvent.stopImmediatePropagation();}else {event.stopPropagation();}};const getItemRole=()=>{switch(role){case"listbox":return "option";case"menu":return "menuitem";default:throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`)}};const maybeRenderNoResults=()=>{const{noResults}=propLabels;const numResults=items.length;if(numResults===0){return jsxRuntime.jsx(wonderBlocksTypography.BodyText,{style:styles$7.noResult,testId:"dropdown-core-no-results",children:noResults})}return null};const handleItemClick=(focusIndex,item)=>{handleClickFocus(focusIndex);if(item.component.props.onClick){item.component.props.onClick();}if(item.populatedProps.onClick){item.populatedProps.onClick();}};const renderList=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{if(SeparatorItem.isClassOf(item.component)){return item.component}const{component,focusable,populatedProps}=item;if(focusable){focusCounter+=1;}const focusIndex=focusCounter-1;const currentRef=derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null;return React__namespace.cloneElement(component,{...populatedProps,key:index,onClick:()=>{handleItemClick(focusIndex,item);},ref:focusable?currentRef:null,role:populatedProps.role||itemRole})})};const parseVirtualizedItems=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{const{populatedProps}=item;if(!SeparatorItem.isClassOf(item.component)&&item.focusable){focusCounter+=1;}const focusIndex=focusCounter-1;return {...item,role:populatedProps.role||itemRole,ref:item.focusable&&derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null,onClick:()=>{handleItemClick(focusIndex,item);}}})};const renderVirtualizedList=()=>{const virtualizedItems=parseVirtualizedItems();return jsxRuntime.jsx(DropdownCoreVirtualized$1,{data:virtualizedItems,listRef:virtualizedListRef})};const handleSearchTextChanged=searchText=>{if(onSearchTextChanged){onSearchTextChanged(searchText);}};const renderSearchField=()=>{return jsxRuntime.jsx(SearchField__default["default"],{clearAriaLabel:labels.clearSearch,onChange:handleSearchTextChanged,placeholder:labels.filter,ref:searchFieldRef,style:styles$7.searchInputStyle,value:searchText||""})};const renderDropdownMenu=(listRenderer,isReferenceHidden)=>{const openerStyle=openerElement&&window.getComputedStyle(openerElement);const minDropdownWidth=openerStyle?openerStyle.getPropertyValue("width"):0;return jsxRuntime.jsxs(wonderBlocksCore.View,{onMouseUp:handleDropdownMouseUp,style:[styles$7.dropdown,isReferenceHidden&&styles$7.hidden,dropdownStyle],testId:"dropdown-core-container",children:[isFilterable&&renderSearchField(),jsxRuntime.jsx(wonderBlocksCore.View,{id:id,role:role,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,style:[styles$7.listboxOrMenu,{minInlineSize:minDropdownWidth}],"aria-invalid":role==="listbox"?ariaInvalid:undefined,"aria-required":role==="listbox"?ariaRequired:undefined,children:listRenderer}),maybeRenderNoResults()]})};const renderDropdown=()=>{const listRenderer=shouldVirtualizeList()?renderVirtualizedList():renderList();return jsxRuntime.jsx(DropdownPopper,{alignment:alignment,onPopperElement:popperElement=>{popperElementRef.current=popperElement;},referenceElement:openerElement,children:isReferenceHidden=>renderDropdownMenu(listRenderer,isReferenceHidden)})};return jsxRuntime.jsxs(wonderBlocksCore.View,{ref:rootRef,onKeyDown:!disabled?handleKeyDown:undefined,onKeyUp:!disabled?handleKeyUp:undefined,style:[styles$7.menuWrapper,style],className:className,children:[opener,open&&renderDropdown()]})};const styles$7=aphrodite.StyleSheet.create({menuWrapper:{width:"fit-content",maxInlineSize:"100%"},dropdown:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)"},listboxOrMenu:{overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},noResult:{color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,alignSelf:"center",marginBlockStart:wonderBlocksTokens.sizing.size_060},searchInputStyle:{margin:wonderBlocksTokens.sizing.size_080,marginBlockStart:wonderBlocksTokens.sizing.size_040,minBlockSize:"auto",position:"sticky"},srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
92
|
+
const VIRTUALIZE_THRESHOLD=125;const sameItemsFocusable=(prevItems,currentItems)=>{if(prevItems.length!==currentItems.length){return false}for(let i=0;i<prevItems.length;i++){if(prevItems[i].focusable!==currentItems[i].focusable){return false}}return true};const createItemRefs=items=>{const itemRefs=[];for(let i=0;i<items.length;i++){if(items[i].focusable){const ref=React__namespace.createRef();itemRefs.push({ref,originalIndex:i});}}return itemRefs};const DropdownCore=props=>{const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const{"aria-invalid":ariaInvalid,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-required":ariaRequired,alignment="left",autoFocus=true,className,disabled,dropdownStyle,enableTypeAhead=true,id,initialFocusedIndex,isFilterable,items,labels,onOpenChanged,onSearchTextChanged,open,opener,openerElement,role,searchText,selectionType="single",style}=props;const schedule=wonderBlocksTiming.useActionScheduler();const openRef=wonderBlocksCore.useLatestRef(open);const onOpenChangedRef=wonderBlocksCore.useLatestRef(onOpenChanged);const rootRef=React__namespace.useRef(null);const popperElementRef=React__namespace.useRef(undefined);const virtualizedListRef=React__namespace.useRef(null);const searchFieldRef=React__namespace.useRef(null);const textSuggestionRef=React__namespace.useRef("");const committedItemsRef=React__namespace.useRef({itemRefs:[],prevItems:items});const{itemRefs:prevItemRefs,prevItems}=committedItemsRef.current;const shouldCreateItemRefs=prevItemRefs.length===0&&open||!sameItemsFocusable(prevItems,items);const derivedItems=shouldCreateItemRefs?{itemRefs:createItemRefs(items),sameItemsFocusable:false}:{itemRefs:prevItemRefs,sameItemsFocusable:true};const itemRefsRef=React__namespace.useRef(derivedItems.itemRefs);React__namespace.useEffect(()=>{committedItemsRef.current={itemRefs:derivedItems.itemRefs,prevItems:items};itemRefsRef.current=derivedItems.itemRefs;});const hasSearchField=React__namespace.useCallback(()=>{return !!isFilterable},[isFilterable]);const isSearchFieldFocused=React__namespace.useCallback(()=>{return hasSearchField()&&document.activeElement===searchFieldRef.current},[hasSearchField]);const focusSearchField=React__namespace.useCallback(()=>{if(searchFieldRef.current){searchFieldRef.current.focus();}},[]);const focusedIndexRef=React__namespace.useRef(-1);const focusedOriginalIndexRef=React__namespace.useRef(-1);const itemsClickedRef=React__namespace.useRef(false);const resetFocusedIndex=React__namespace.useCallback(()=>{if(typeof initialFocusedIndex!=="undefined"){focusedIndexRef.current=initialFocusedIndex;}else {if(hasSearchField()&&!isSearchFieldFocused()){return focusSearchField()}focusedIndexRef.current=0;}},[focusSearchField,hasSearchField,initialFocusedIndex,isSearchFieldFocused]);const initializedRef=React__namespace.useRef(false);if(!initializedRef.current){initializedRef.current=true;resetFocusedIndex();}const shouldVirtualizeList=React__namespace.useCallback(()=>{return items.length>VIRTUALIZE_THRESHOLD},[items]);const focusCurrentItem=React__namespace.useCallback(onFocus=>{const focusedItemRef=itemRefsRef.current[focusedIndexRef.current];if(!focusedItemRef){return}const{current:virtualizedList}=virtualizedListRef;if(virtualizedList){virtualizedList.scrollToItem(focusedItemRef.originalIndex);}const focusNode=()=>{if(!openRef.current){return}const currentFocusedItemRef=itemRefsRef.current[focusedIndexRef.current];const node=ReactDOM__namespace.findDOMNode(currentFocusedItemRef.ref.current);if(!node&&shouldVirtualizeList()){schedule.animationFrame(focusNode);return}if(node){schedule.timeout(()=>{node.focus();},0);focusedOriginalIndexRef.current=currentFocusedItemRef.originalIndex;if(onFocus){onFocus(node);}}};if(shouldVirtualizeList()){schedule.animationFrame(focusNode);}else {focusNode();}},[openRef,schedule,shouldVirtualizeList]);const scheduleToFocusCurrentItem=React__namespace.useCallback(onFocus=>{if(shouldVirtualizeList()){schedule.animationFrame(()=>{focusCurrentItem(onFocus);});}else {focusCurrentItem(onFocus);}},[focusCurrentItem,schedule,shouldVirtualizeList]);const maybeFocusInitialItem=React__namespace.useCallback(()=>{if(!autoFocus){return}if(open){resetFocusedIndex();scheduleToFocusCurrentItem();}else if(!open){itemsClickedRef.current=false;}},[autoFocus,open,resetFocusedIndex,scheduleToFocusCurrentItem]);React__namespace.useEffect(()=>{if(!open){return}const handleInteract=event=>{const target=event.target;const thisElement=rootRef.current;if(thisElement&&!thisElement.contains(target)&&popperElementRef.current&&!popperElementRef.current.contains(target)){onOpenChangedRef.current(false);}};document.addEventListener("mouseup",handleInteract);document.addEventListener("touchend",handleInteract);return ()=>{document.removeEventListener("mouseup",handleInteract);document.removeEventListener("touchend",handleInteract);}},[open,onOpenChangedRef]);wonderBlocksCore.useOnMountEffect(()=>{maybeFocusInitialItem();});const prevRenderRef=React__namespace.useRef(null);React__namespace.useEffect(()=>{const prevProps=prevRenderRef.current;prevRenderRef.current={open,searchText,derivedItems};if(!prevProps||prevProps.derivedItems===derivedItems){return}if(prevProps.open!==open){maybeFocusInitialItem();}else if(open){const{itemRefs,sameItemsFocusable}=derivedItems;if(sameItemsFocusable||prevProps.searchText!==searchText){return}else {const newFocusableIndex=itemRefs.findIndex(ref=>ref.originalIndex===focusedOriginalIndexRef.current);if(newFocusableIndex===-1){focusedIndexRef.current=0;itemsClickedRef.current=false;scheduleToFocusCurrentItem();}else {focusedIndexRef.current=newFocusableIndex;}}}});const focusPreviousItem=React__namespace.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=itemRefsRef.current.length-1;}else if(focusedIndexRef.current===0){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=itemRefsRef.current.length-1;}else {focusedIndexRef.current-=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const focusNextItem=React__namespace.useCallback(()=>{if(isSearchFieldFocused()){focusedIndexRef.current=0;}else if(focusedIndexRef.current===itemRefsRef.current.length-1){if(hasSearchField()){return focusSearchField()}focusedIndexRef.current=0;}else {focusedIndexRef.current+=1;}scheduleToFocusCurrentItem();},[focusSearchField,hasSearchField,isSearchFieldFocused,scheduleToFocusCurrentItem]);const restoreTabOrder=React__namespace.useCallback(()=>{if(openerElement){openerElement.focus();}},[openerElement]);const handleKeyDownDebounceResult=React__namespace.useCallback(key=>{const foundIndex=items.filter(item=>item.focusable).findIndex(({component})=>{if(SeparatorItem.isClassOf(component)){return false}if(OptionItem.isClassOf(component)){const optionItemProps=component.props;return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase())}return false});if(foundIndex>=0){const isClosed=!open;if(isClosed){onOpenChanged(true);}focusedIndexRef.current=foundIndex;scheduleToFocusCurrentItem(node=>{if(selectionType==="single"&&isClosed&&node){node.click();onOpenChanged(false);}});}textSuggestionRef.current="";},[items,onOpenChanged,open,scheduleToFocusCurrentItem,selectionType]);const handleKeyDownDebounceResultRef=React__namespace.useRef(handleKeyDownDebounceResult);handleKeyDownDebounceResultRef.current=handleKeyDownDebounceResult;const handleKeyDownDebounced=React__namespace.useMemo(()=>debounce(key=>handleKeyDownDebounceResultRef.current(key),500),[]);const handleKeyDown=event=>{const key=event.key;if(enableTypeAhead&&getStringForKey(key)){event.stopPropagation();textSuggestionRef.current+=key;handleKeyDownDebounced(textSuggestionRef.current);}if(!open){if(key===wonderBlocksCore.keys.down){event.preventDefault();onOpenChanged(true);return}return}switch(key){case wonderBlocksCore.keys.tab:if(isSearchFieldFocused()&&searchText){return}restoreTabOrder();onOpenChanged(false);return;case wonderBlocksCore.keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.up:event.preventDefault();focusPreviousItem();return;case wonderBlocksCore.keys.down:event.preventDefault();focusNextItem();return}};const handleKeyUp=event=>{const key=event.key;switch(key){case wonderBlocksCore.keys.space:if(isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.escape:if(open){event.stopPropagation();restoreTabOrder();onOpenChanged(false);}return}};const handleClickFocus=index=>{itemsClickedRef.current=true;focusedIndexRef.current=index;focusedOriginalIndexRef.current=derivedItems.itemRefs[focusedIndexRef.current].originalIndex;};const handleDropdownMouseUp=event=>{if(event.nativeEvent.stopImmediatePropagation){event.nativeEvent.stopImmediatePropagation();}else {event.stopPropagation();}};const getItemRole=()=>{switch(role){case"listbox":return "option";case"menu":return "menuitem";default:throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`)}};const maybeRenderNoResults=()=>{const noResults=labels?.noResults||strings.noResults;const numResults=items.length;if(numResults===0){return jsxRuntime.jsx(wonderBlocksTypography.BodyText,{style:styles$7.noResult,testId:"dropdown-core-no-results",children:noResults})}return null};const handleItemClick=(focusIndex,item)=>{handleClickFocus(focusIndex);if(item.component.props.onClick){item.component.props.onClick();}if(item.populatedProps.onClick){item.populatedProps.onClick();}};const renderList=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{if(SeparatorItem.isClassOf(item.component)){return item.component}const{component,focusable,populatedProps}=item;if(focusable){focusCounter+=1;}const focusIndex=focusCounter-1;const currentRef=derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null;return React__namespace.cloneElement(component,{...populatedProps,key:index,onClick:()=>{handleItemClick(focusIndex,item);},ref:focusable?currentRef:null,role:populatedProps.role||itemRole})})};const parseVirtualizedItems=()=>{let focusCounter=0;const itemRole=getItemRole();return items.map((item,index)=>{const{populatedProps}=item;if(!SeparatorItem.isClassOf(item.component)&&item.focusable){focusCounter+=1;}const focusIndex=focusCounter-1;return {...item,role:populatedProps.role||itemRole,ref:item.focusable&&derivedItems.itemRefs[focusIndex]?derivedItems.itemRefs[focusIndex].ref:null,onClick:()=>{handleItemClick(focusIndex,item);}}})};const renderVirtualizedList=()=>{const virtualizedItems=parseVirtualizedItems();return jsxRuntime.jsx(DropdownCoreVirtualized$1,{data:virtualizedItems,listRef:virtualizedListRef})};const handleSearchTextChanged=searchText=>{if(onSearchTextChanged){onSearchTextChanged(searchText);}};const renderSearchField=()=>{return jsxRuntime.jsx(SearchField__default["default"],{clearAriaLabel:labels?.clearSearch||strings.iconAltClearSearch,onChange:handleSearchTextChanged,placeholder:labels?.filter||strings.filter,ref:searchFieldRef,style:styles$7.searchInputStyle,value:searchText||""})};const renderDropdownMenu=(listRenderer,isReferenceHidden)=>{const openerStyle=openerElement&&window.getComputedStyle(openerElement);const minDropdownWidth=openerStyle?openerStyle.getPropertyValue("width"):0;return jsxRuntime.jsxs(wonderBlocksCore.View,{onMouseUp:handleDropdownMouseUp,style:[styles$7.dropdown,isReferenceHidden&&styles$7.hidden,dropdownStyle],testId:"dropdown-core-container",children:[isFilterable&&renderSearchField(),jsxRuntime.jsx(wonderBlocksCore.View,{id:id,role:role,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,style:[styles$7.listboxOrMenu,{minInlineSize:minDropdownWidth}],"aria-invalid":role==="listbox"?ariaInvalid:undefined,"aria-required":role==="listbox"?ariaRequired:undefined,children:listRenderer}),maybeRenderNoResults()]})};const renderDropdown=()=>{const listRenderer=shouldVirtualizeList()?renderVirtualizedList():renderList();return jsxRuntime.jsx(DropdownPopper,{alignment:alignment,onPopperElement:popperElement=>{popperElementRef.current=popperElement;},referenceElement:openerElement,children:isReferenceHidden=>renderDropdownMenu(listRenderer,isReferenceHidden)})};return jsxRuntime.jsxs(wonderBlocksCore.View,{ref:rootRef,onKeyDown:!disabled?handleKeyDown:undefined,onKeyUp:!disabled?handleKeyUp:undefined,style:[styles$7.menuWrapper,style],className:className,children:[opener,open&&renderDropdown()]})};const styles$7=aphrodite.StyleSheet.create({menuWrapper:{width:"fit-content",maxInlineSize:"100%"},dropdown:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)"},listboxOrMenu:{overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},noResult:{color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,alignSelf:"center",marginBlockStart:wonderBlocksTokens.sizing.size_060},searchInputStyle:{margin:wonderBlocksTokens.sizing.size_080,marginBlockStart:wonderBlocksTokens.sizing.size_040,minBlockSize:"auto",position:"sticky"},srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
92
93
|
|
|
93
94
|
const ActionMenuOpenerCore=React__namespace.forwardRef(function ActionMenuOpenerCore(props,ref){const{children,disabled,waiting:_,testId,opened,"aria-label":ariaLabel,...restProps}=props;return jsxRuntime.jsx(Button__default["default"],{"aria-expanded":opened?"true":"false","aria-haspopup":"menu",kind:"tertiary","aria-label":ariaLabel,disabled:disabled,...restProps,testId:testId,endIcon:caretDownIcon__default["default"],ref:ref,children:children})});
|
|
94
95
|
|
|
@@ -96,11 +97,11 @@ const ActionMenu=React__namespace.forwardRef(function ActionMenu({alignment="lef
|
|
|
96
97
|
|
|
97
98
|
const StyledButton$1=wonderBlocksCore.addStyle("button");class SelectOpener extends React__namespace.Component{render(){const{children,disabled,readOnly,error,id,isPlaceholder,open,testId,"aria-label":ariaLabel,"aria-required":ariaRequired,"aria-controls":ariaControls,onBlur,onOpenChanged,...sharedProps}=this.props;const iconColor=disabled?wonderBlocksTokens.semanticColor.core.foreground.disabled.default:wonderBlocksTokens.semanticColor.core.foreground.neutral.default;const style=[styles$5.shared,styles$5.default,disabled&&styles$5.disabled,error&&styles$5.error,isPlaceholder&&styles$5.placeholder,isPlaceholder&&disabled&&styles$5.disabledPlaceholder,!disabled&&!readOnly&&this.state.pressed&&styles$5.press,readOnly&&styles$5.readOnly,readOnly&&isPlaceholder&&styles$5.placeholder];const allowInteraction=!disabled&&!readOnly;return jsxRuntime.jsxs(StyledButton$1,{...sharedProps,"aria-disabled":readOnly||disabled||undefined,"aria-expanded":open?"true":"false","aria-invalid":error,"aria-label":ariaLabel??undefined,"aria-required":ariaRequired,"aria-haspopup":"listbox","aria-controls":ariaControls,"data-testid":testId,id:id,role:"combobox",type:"button",style:style,onClick:allowInteraction?this.handleClick:undefined,onKeyDown:allowInteraction?this.handleKeyDown:undefined,onKeyUp:allowInteraction?this.handleKeyUp:undefined,onBlur:onBlur,children:[jsxRuntime.jsx(wonderBlocksTypography.BodyText,{tag:"span",style:styles$5.text,children:children||jsxRuntime.jsx("span",{"aria-hidden":"true",children:" "})}),jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:caretDownIcon__default["default"],color:iconColor,size:"small",style:styles$5.caret,"aria-hidden":"true"})]})}constructor(props){super(props),this.handleClick=e=>{const{open}=this.props;this.props.onOpenChanged(!open);},this.handleKeyDown=e=>{const keyName=e.key;if(keyName===wonderBlocksCore.keys.enter||keyName===wonderBlocksCore.keys.space){this.setState({pressed:true});e.preventDefault();}},this.handleKeyUp=e=>{const keyName=e.key;if(keyName===wonderBlocksCore.keys.enter||keyName===wonderBlocksCore.keys.space){this.setState({pressed:false});this.handleClick(e);}};this.state={pressed:false};}}SelectOpener.defaultProps={disabled:false,readOnly:false,error:false,isPlaceholder:false};const PRESS_SHADOW=`0 0 0 ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.input.default.border}`;const styles$5=aphrodite.StyleSheet.create({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"space-between",color:wonderBlocksTokens.semanticColor.core.foreground.neutral.strong,height:DROPDOWN_ITEM_HEIGHT,paddingInlineStart:theme.opener.layout.padding.inlineStart,paddingInlineEnd:theme.opener.layout.padding.inlineEnd,borderWidth:0,borderRadius:theme.opener.border.radius.rest,borderStyle:"solid",outline:"none",textDecoration:"none",boxSizing:"border-box",whiteSpace:"nowrap",touchAction:"manipulation"},text:{marginInlineEnd:wonderBlocksTokens.sizing.size_080,whiteSpace:"nowrap",userSelect:"none",overflow:"hidden",textOverflow:"ellipsis"},caret:{minInlineSize:wonderBlocksTokens.sizing.size_160},default:{background:wonderBlocksTokens.semanticColor.input.default.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.default.border}`,color:wonderBlocksTokens.semanticColor.input.default.foreground,cursor:"pointer",":active":{boxShadow:PRESS_SHADOW},":focus":{...wonderBlocksStyles.focusStyles.focus[":focus-visible"]},[":focus:active"]:{boxShadow:`${PRESS_SHADOW}, ${wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}`}},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground,[":focus:active"]:{boxShadow:`${PRESS_SHADOW}, ${wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}`}},disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground,cursor:"not-allowed",":active":{boxShadow:"none"},[":focus:active"]:{boxShadow:wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}},press:{boxShadow:PRESS_SHADOW,":focus-visible":{boxShadow:`${PRESS_SHADOW}, ${wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}`}},placeholder:{color:wonderBlocksTokens.semanticColor.input.default.placeholder},disabledPlaceholder:{color:wonderBlocksTokens.semanticColor.input.disabled.placeholder},readOnly:{background:wonderBlocksTokens.semanticColor.input.readOnly.background,color:wonderBlocksTokens.semanticColor.input.readOnly.text,":active":{boxShadow:"none"},[":focus:active"]:{boxShadow:wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}}});
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
function hasValue(value){return value?value.length>0:false}function useSelectValidation({value,disabled=false,validate,onValidate,required,open}){const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const[errorMessage,setErrorMessage]=React__namespace.useState(()=>validate&&hasValue(value)&&!disabled&&validate(value)||null);const handleValidation=React__namespace.useCallback(newValue=>{if(disabled){return}if(validate){const error=newValue!==undefined&&validate(newValue)||null;setErrorMessage(error);if(onValidate){onValidate(error);}if(error){return}}if(required){const requiredString=typeof required==="string"?required:strings.requiredFieldMessage;const error=hasValue(newValue)?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}},[disabled,validate,setErrorMessage,onValidate,required,strings.requiredFieldMessage]);wonderBlocksCore.useOnMountEffect(()=>{if(hasValue(value)){handleValidation(value);}});function onOpenerBlurValidation(){if(!open&&required&&!hasValue(value)){handleValidation(value);}}const onDropdownClosedValidation=()=>{if(required&&!hasValue(value)){handleValidation(value);}};const onSelectionValidation=newValue=>{handleValidation(newValue);};const onSelectedValuesChangeValidation=()=>{setErrorMessage(null);if(onValidate){onValidate(null);}};return {errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}}
|
|
100
101
|
|
|
101
|
-
const SingleSelect=props=>{const selectedIndex=React__namespace.useRef(0);const isInitialRender=React__namespace.useRef(true);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels
|
|
102
|
+
const SingleSelect=props=>{const selectedIndex=React__namespace.useRef(0);const isInitialRender=React__namespace.useRef(true);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels:propLabels,onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const labels=React__namespace.useMemo(()=>({clearSearch:propLabels?.clearSearch||strings.iconAltClearSearch,filter:propLabels?.filter||strings.filter,noResults:propLabels?.noResults||strings.noResults,someResults:propLabels?.someResults||(numResults=>strings.numItems({num:numResults}))}),[strings,propLabels]);const[open,setOpen]=React__namespace.useState(false);const[searchText,setSearchText]=React__namespace.useState("");const[openerElement,setOpenerElement]=React__namespace.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation}=useSelectValidation({value:selectedValue,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React__namespace.useEffect(()=>{if(disabled||readOnly){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened,readOnly]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");if(onToggle){onToggle(opened);}if(!opened){onDropdownClosedValidation();}};const handleToggle=newSelectedValue=>{if(newSelectedValue!==selectedValue){onChange(newSelectedValue);}if(open&&openerElement){openerElement.focus();}setOpen(false);if(onToggle){onToggle(false);}onSelectionValidation(newSelectedValue);};const mapOptionItemsToDropdownItems=children=>{let indexCounter=0;selectedIndex.current=0;return children.map(option=>{const{disabled,value}=option.props;const selected=selectedValue===value;if(selected){selectedIndex.current=indexCounter;}if(!disabled){indexCounter+=1;}return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selected,variant:"check"}}})};const filterChildren=children=>{const lowercasedSearchText=searchText.toLowerCase();return children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1)};const getMenuItems=children=>{return mapOptionItemsToDropdownItems(isFilterable?filterChildren(children):children)};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleOpenerRef=node=>{const openerElement=ReactDOM__namespace.findDOMNode(node);setOpenerElement(openerElement);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{wonderBlocksAnnouncer.announceMessage({message,level:"polite"});};const childrenRef=React__namespace.useRef(children);childrenRef.current=children;const announceSelectedItem=()=>{const optionItems=React__namespace.Children.toArray(childrenRef.current);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}};React__namespace.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}announceSelectedItem();},[selectedValue]);const computedRequired=ariaRequired??!!required;const renderOpener=(isDisabled,dropdownId)=>{const items=React__namespace.Children.toArray(children);const selectedItem=items.find(option=>option.props.value===selectedValue);let menuContent;if(selectedItem){menuContent=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem.props);}else {menuContent=placeholder;}const dropdownOpener=jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueOpenerId=>{return opener?jsxRuntime.jsx(DropdownOpener,{id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,"aria-haspopup":"listbox",onClick:handleClick,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:menuContent,opened:open,error:hasError,onBlur:onOpenerBlurValidation,readOnly:readOnly,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,readOnly:readOnly,children:menuContent})}});return dropdownOpener};const allChildren=React__namespace.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const items=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;const disableInteraction=isDisabled||readOnly;const listboxLabelProps=getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement});const{someResults}=labels;const someResultsRef=React__namespace.useRef(someResults);someResultsRef.current=someResults;const openRef=React__namespace.useRef(open);openRef.current=open;React__namespace.useEffect(()=>{if(openRef.current){handleAnnouncement(someResultsRef.current(items.length));}},[items.length]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore,{id:uniqueDropdownId,role:"listbox",selectionType:"single",alignment:alignment,autoFocus:autoFocus,enableTypeAhead:enableTypeAhead,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],initialFocusedIndex:selectedIndex.current,items:items,onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(isDisabled,uniqueDropdownId),openerElement:openerElement,style:style,className:className,isFilterable:isFilterable,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:labels,...listboxLabelProps,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:disableInteraction})})};
|
|
102
103
|
|
|
103
|
-
const MultiSelect=props=>{const isInitialRender=React__namespace.useRef(true);const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React__namespace.useMemo(()=>{
|
|
104
|
+
const MultiSelect=props=>{const isInitialRender=React__namespace.useRef(true);const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,readOnly=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const labels=React__namespace.useMemo(()=>({clearSearch:propLabels?.clearSearch||strings.iconAltClearSearch,filter:propLabels?.filter||strings.filter,noResults:propLabels?.noResults||strings.noResults,selectAllLabel:propLabels?.selectAllLabel||(numOptions=>strings.selectAllWithCount({num:numOptions})),selectNoneLabel:propLabels?.selectNoneLabel||strings.selectNone,noneSelected:propLabels?.noneSelected||strings.zeroItems,someSelected:propLabels?.someSelected||(numSelectedValues=>strings.numItems({num:numSelectedValues})),allSelected:propLabels?.allSelected||strings.allItems}),[strings,propLabels]);const[open,setOpen]=React__namespace.useState(false);const[searchText,setSearchText]=React__namespace.useState("");const[lastSelectedValues,setLastSelectedValues]=React__namespace.useState([]);const[openerElement,setOpenerElement]=React__namespace.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}=useSelectValidation({value:selectedValues,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React__namespace.useEffect(()=>{if(disabled||readOnly){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened,readOnly]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");setLastSelectedValues(selectedValues);if(onToggle){onToggle(opened);}if(!opened){if(lastSelectedValues!==selectedValues){onSelectionValidation(selectedValues);}else {onDropdownClosedValidation();}}};const handleToggle=selectedValue=>{if(selectedValues.includes(selectedValue)){const index=selectedValues.indexOf(selectedValue);const updatedSelection=[...selectedValues.slice(0,index),...selectedValues.slice(index+1)];onChange(updatedSelection);}else {onChange([...selectedValues,selectedValue]);}onSelectedValuesChangeValidation();};const handleSelectAll=()=>{const allChildren=React__namespace.Children.toArray(children);const selected=allChildren.filter(option=>!!option&&!option.props.disabled).map(option=>option.props.value);onChange(selected);onSelectedValuesChangeValidation();};const handleSelectNone=()=>{onChange([]);onSelectedValuesChangeValidation();};const getMenuTextOrNode=React__namespace.useCallback(children=>{const{noneSelected,someSelected,allSelected}=labels;const numSelectedAll=children.filter(option=>!option.props.disabled).length;const noSelectionText=implicitAllEnabled?allSelected:noneSelected;switch(selectedValues.length){case 0:return noSelectionText;case 1:const selectedItem=children.find(option=>option.props.value===selectedValues[0]);if(selectedItem){const selectedLabel=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem?.props);if(selectedLabel){return selectedLabel}else {return someSelected(1)}}return noSelectionText;case numSelectedAll:return allSelected;default:return someSelected(selectedValues.length)}},[implicitAllEnabled,labels,selectedValues,showOpenerLabelAsText]);const getShortcuts=numOptions=>{const{selectAllLabel,selectNoneLabel}=labels;if(shortcuts&&!searchText){const selectAllDisabled=numOptions===selectedValues.length;const selectAll={component:jsxRuntime.jsx(ActionItem,{disabled:selectAllDisabled,label:selectAllLabel(numOptions),indent:true,onClick:handleSelectAll}),focusable:!selectAllDisabled,populatedProps:{}};const selectNoneDisabled=selectedValues.length===0;const selectNone={component:jsxRuntime.jsx(ActionItem,{disabled:selectNoneDisabled,label:selectNoneLabel,indent:true,onClick:handleSelectNone}),focusable:!selectNoneDisabled,populatedProps:{}};const separator={component:jsxRuntime.jsx(SeparatorItem,{},"shortcuts-separator"),focusable:false,populatedProps:{}};return [selectAll,selectNone,separator]}else {return []}};const getMenuItems=children=>{if(!isFilterable){return children.map(mapOptionItemToDropdownItem)}const lowercasedSearchText=searchText.toLowerCase();const filteredChildren=children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1);const lastSelectedChildren=[];const restOfTheChildren=[];for(const child of filteredChildren){if(lastSelectedValues.includes(child.props.value)){lastSelectedChildren.push(child);}else {restOfTheChildren.push(child);}}const lastSelectedItems=lastSelectedChildren.map(mapOptionItemToDropdownItem);if(lastSelectedChildren.length&&restOfTheChildren.length){lastSelectedItems.push({component:jsxRuntime.jsx(SeparatorItem,{},"selected-separator"),focusable:false,populatedProps:{}});}return [...lastSelectedItems,...restOfTheChildren.map(mapOptionItemToDropdownItem)]};const mapOptionItemToDropdownItem=option=>{const{disabled,value}=option.props;return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selectedValues.includes(value),variant:"checkbox"}}};const handleOpenerRef=node=>{const openerElement=ReactDOM__namespace.findDOMNode(node);setOpenerElement(openerElement);};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{wonderBlocksAnnouncer.announceMessage({message,level:"polite"});};const maybeGetOpenerStringValue=React__namespace.useCallback((children,openerContent)=>{let openerStringValue;if(selectedValues.length===1){const selectedItem=children.find(option=>option.props.value===selectedValues[0]);openerStringValue=selectedItem?getLabel(selectedItem?.props):undefined;}else if(typeof openerContent==="string"){openerStringValue=openerContent;}return openerStringValue},[selectedValues]);const prevOpenRef=React__namespace.useRef(open);const selectionChangedRef=React__namespace.useRef(false);const childrenRef=React__namespace.useRef(children);childrenRef.current=children;const getMenuTextOrNodeRef=React__namespace.useRef(getMenuTextOrNode);getMenuTextOrNodeRef.current=getMenuTextOrNode;const maybeGetOpenerStringValueRef=React__namespace.useRef(maybeGetOpenerStringValue);maybeGetOpenerStringValueRef.current=maybeGetOpenerStringValue;const announceOpenerValue=()=>{const optionItems=React__namespace.Children.toArray(childrenRef.current);const openerContent=getMenuTextOrNodeRef.current(optionItems);const openerStringValue=maybeGetOpenerStringValueRef.current(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}};React__namespace.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;prevOpenRef.current=open;return}const justOpened=open&&!prevOpenRef.current;const justClosed=!open&&prevOpenRef.current;prevOpenRef.current=open;if(justOpened){selectionChangedRef.current=false;}else if(justClosed){if(selectionChangedRef.current){announceOpenerValue();selectionChangedRef.current=false;}}else if(open){selectionChangedRef.current=true;announceOpenerValue();}},[selectedValues,open]);const computedRequired=ariaRequired??!!required;const renderOpener=(allChildren,isDisabled,dropdownId)=>{const{noneSelected}=labels;const openerContent=getMenuTextOrNode(allChildren);const dropdownOpener=jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueOpenerId=>{return opener?jsxRuntime.jsx(DropdownOpener,{id:uniqueOpenerId,error:hasError,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,"aria-haspopup":"listbox",onClick:handleClick,onBlur:onOpenerBlurValidation,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:openerContent,opened:open,readOnly:readOnly,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,readOnly:readOnly,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;const listboxLabelProps=getListboxLabelProps({ariaLabel,ariaLabelledBy,openerElement});const someSelectedRef=React__namespace.useRef(someSelected);someSelectedRef.current=someSelected;const allChildren=React__namespace.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const filteredItems=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;const disableInteraction=isDisabled||readOnly;React__namespace.useEffect(()=>{if(searchText){handleAnnouncement(someSelectedRef.current(filteredItems.length));}},[filteredItems.length,someSelectedRef]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore,{id:uniqueDropdownId,role:"listbox",alignment:alignment,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],isFilterable:isFilterable,items:[...getShortcuts(numEnabledOptions),...filteredItems],onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(allChildren,isDisabled,uniqueDropdownId),openerElement:openerElement,selectionType:"multi",style:style,className:className,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:{clearSearch,filter,noResults,someResults:someSelected},...listboxLabelProps,"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:disableInteraction})})};
|
|
104
105
|
|
|
105
106
|
function updateMultipleSelection(previousSelection,value=""){if(!previousSelection){return [value]}return previousSelection.includes(value)?previousSelection.filter(item=>item!==value):[...previousSelection,value]}
|
|
106
107
|
|
|
@@ -108,13 +109,13 @@ function useListbox({children:options,disabled,disableSpaceSelection,id,onChange
|
|
|
108
109
|
|
|
109
110
|
function useMultipleSelection({inputValue,isComboboxOpen,selected,onRemove}){const[focusedMultiSelectIndex,setFocusedMultiSelectIndex]=React__namespace.useState(-1);React__namespace.useEffect(()=>{if(!isComboboxOpen){setFocusedMultiSelectIndex(-1);}},[isComboboxOpen]);const handleKeyDown=React__namespace.useCallback(event=>{const{key}=event;if(!Array.isArray(selected)||selected.length===0){return}if(inputValue===""&&key==="ArrowLeft"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev-1;return newIndex<0?selected?.length-1:newIndex});}if(inputValue===""&&key==="ArrowRight"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev+1;return newIndex>=selected?.length?0:newIndex});}if(inputValue===""&&key==="Backspace"){let newSelected=[];if(focusedMultiSelectIndex<0){newSelected=selected?.slice(0,-1);}else {newSelected=selected.filter((_,index)=>index!==focusedMultiSelectIndex);}setFocusedMultiSelectIndex(-1);onRemove?.(newSelected);}if(focusedMultiSelectIndex>=0&&key==="Enter"){const newSelected=selected?.filter((_,index)=>index!==focusedMultiSelectIndex);onRemove?.(newSelected);setFocusedMultiSelectIndex(-1);}if(key==="ArrowDown"||key==="ArrowUp"){setFocusedMultiSelectIndex(-1);}if(key==="Escape"){setFocusedMultiSelectIndex(-1);}},[focusedMultiSelectIndex,inputValue,selected,onRemove]);return {focusedMultiSelectIndex,handleKeyDown}}
|
|
110
111
|
|
|
111
|
-
const StyledSpan=wonderBlocksCore.addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels={closedState:
|
|
112
|
+
const StyledSpan=wonderBlocksCore.addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels:propLabels,selectedLabels,opened,options,selected,selectionType="single",testId}){const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const labels=React__namespace.useMemo(()=>({closedState:propLabels?.closedState||strings.srComboboxClosed,liveRegionCurrentItem:propLabels?.liveRegionCurrentItem||(({current,index,total,disabled,focused,selected})=>{const states=[focused&&strings.srFocused,disabled&&strings.srDisabled,selected&&strings.srSelected].filter(Boolean);return strings.srCurrentItemDetails({current:[current,...states].join(" "),index:index+1,total})}),liveRegionListboxTotal:propLabels?.liveRegionListboxTotal||(total=>strings.srNumResultsAvailable({num:total})),liveRegionMultipleSelectionTotal:propLabels?.liveRegionMultipleSelectionTotal||(total=>strings.srNumSelectedOptions({num:total})),noItems:propLabels?.noItems||strings.noResults,selected:propLabels?.selected||(labels=>strings.srItemsSelected({labels})),selectionCleared:propLabels?.selectionCleared||strings.srSelectionCleared,unselected:propLabels?.unselected||(labels=>strings.srItemsNotSelected({labels}))}),[propLabels,strings]);const lastSelectedValue=React__namespace.useRef(null);const[message,setMessage]=React__namespace.useState("");React__namespace.useEffect(()=>{if(selected&&selected!==lastSelectedValue?.current){let newMessage="";const lastSelectedLength=lastSelectedValue?.current?.length??0;const selectedLength=selected?.length??0;if(Array.isArray(selected)&&selected.length>0){const currentLabels=selectedLabels.join(", ");const selectedState=selectedLength>lastSelectedLength?labels.selected(currentLabels):labels.unselected(currentLabels);newMessage=selectedState;}else {newMessage=labels.selected(selectedLabels[0]);}setMessage(newMessage);}if(selectionType==="single"&&!selected&&lastSelectedValue.current){setMessage(labels.selectionCleared);}lastSelectedValue.current=selected;if(selectionType==="multiple"&&!opened){setMessage(labels.closedState);}},[labels,labels.closedState,selectedLabels,opened,selected,selectionType]);const focusedElementDescription=React__namespace.useMemo(()=>{if(focusedMultiSelectIndex>=0){const label=selectedLabels[focusedMultiSelectIndex];return labels.liveRegionCurrentItem({current:label,focused:true,index:focusedMultiSelectIndex,total:selectedLabels.length})+" "+labels.liveRegionMultipleSelectionTotal(selectedLabels.length)}if(options.length===0){return labels.noItems}if(focusedIndex<0||!options[focusedIndex]){return ""}const currentItemProps=options[focusedIndex].props;const label=getLabel(currentItemProps);const totalResults=options.length;return labels.liveRegionCurrentItem({current:label,disabled:currentItemProps.disabled,focused:false,index:focusedIndex,selected:currentItemProps.selected,total:totalResults})+" "+labels.liveRegionListboxTotal(totalResults)},[focusedIndex,focusedMultiSelectIndex,labels,options,selectedLabels]);return jsxRuntime.jsx(StyledSpan,{role:"log","aria-live":"polite","aria-atomic":"false","aria-relevant":"additions text",style:styles$4.srOnly,"data-testid":testId?`${testId}-status`:undefined,children:opened?focusedElementDescription:message})}const styles$4=aphrodite.StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
112
113
|
|
|
113
114
|
const MultipleSelection=React__namespace.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsxRuntime.jsx(wonderBlocksCore.View,{role:"group",style:styles$3.container,id:id,children:selected.map((value,index)=>{const label=labels[index];const focused=index===focusedMultiSelectIndex;const uniqueId=id+index;return jsxRuntime.jsx(Button__default["default"],{id:uniqueId,testId:testId?`${testId}-item-${index}`:undefined,size:"small",style:[styles$3.item,focused&&styles$3.itemFocused],kind:"secondary",actionType:"neutral","aria-label":removeSelectedLabel(label),tabIndex:-1,onClick:()=>onRemove(value),endIcon:disabled?undefined:jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:xIcon__default["default"],size:"small"}),children:label},uniqueId)})})});const styles$3=aphrodite.StyleSheet.create({container:{flexDirection:"row",flexWrap:"wrap",gap:wonderBlocksTokens.sizing.size_080,paddingBlockStart:wonderBlocksTokens.sizing.size_080},item:{fontSize:wonderBlocksTokens.font.body.size.small,justifyContent:"space-between",alignItems:"center",height:"auto",paddingInline:wonderBlocksTokens.sizing.size_080},itemFocused:wonderBlocksStyles.focusStyles.focus[":focus-visible"]});
|
|
114
115
|
|
|
115
116
|
function StandaloneListbox(props){const{children,disabled,id,onChange,selectionType="single",style,tabIndex=0,testId,value,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const{focusedIndex,isListboxFocused,renderList,selected,handleKeyDown,handleKeyUp,handleFocus,handleBlur}=useListbox({children,disabled,id:uniqueId,selectionType,value});React__namespace.useEffect(()=>{if(selected&&selected!==value){onChange?.(selected);}},[onChange,selected,value]);return jsxRuntime.jsx(wonderBlocksCore.View,{role:"listbox",id:uniqueId,style:[styles$2.listbox,style,disabled&&styles$2.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",onKeyDown:handleKeyDown,onKeyUp:handleKeyUp,onFocus:handleFocus,onBlur:handleBlur,"aria-activedescendant":isListboxFocused?renderList[focusedIndex].props.id:undefined,children:renderList})}function Listbox(props){const{children,disabled,id,selectionType="single",style,tabIndex=0,testId,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;if(tabIndex===0){return jsxRuntime.jsx(StandaloneListbox,{...props})}return jsxRuntime.jsx(wonderBlocksCore.View,{role:"listbox",id:id,style:[styles$2.listbox,style,disabled&&styles$2.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",children:children})}const styles$2=aphrodite.StyleSheet.create({listbox:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,outline:"none",paddingBlock:theme.listbox.layout.padding.block,paddingInline:theme.listbox.layout.padding.inline},disabled:{color:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground}});
|
|
116
117
|
|
|
117
|
-
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value="",loading,style,...ariaAttrs}){const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const comboboxRef=React__namespace.useRef(null);const rootNodeRef=React__namespace.useRef(null);const[open,setOpen]=React__namespace.useState(opened??false);const isControlled=opened!==undefined;const openState=disabled?false:isControlled?opened:open;const[selectedValue,setSelectedValue]=React__namespace.useState(value);const isValueControlled=value!==""&&onChange!==undefined;const valueState=isValueControlled?value:selectedValue;const[currentOptions,setCurrentOptions]=React__namespace.useState(children);const{focusedIndex,isListboxFocused,setFocusedIndex,handleKeyDown,handleFocus,handleBlur,selected,setSelected,renderList}=useListbox({children:currentOptions,disabled,id:uniqueId,onChange:value=>handleChange(value),value:valueState,disableSpaceSelection:true,selectionType});const itemFromSelected=renderList.find(item=>item.props.value===selected)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";const initialValue=typeof value==="string"?labelFromSelected:"";const[inputValue,setInputValue]=React__namespace.useState(initialValue);const updateAfterSelectionChange=React__namespace.useCallback(value=>{setSelected(value);onChange?.(value);},[onChange,setSelected]);const{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,onRemove:updateAfterSelectionChange,isComboboxOpen:openState});const updateOpenState=React__namespace.useCallback((newState,selectedLabel=labelFromSelected)=>{if(disabled||newState===openState){return}if(!isControlled){setOpen(newState);}if(!newState){setFocusedIndex(-1);if(selectionType==="multiple"){setInputValue("");}else {setInputValue(selectedLabel??"");}setCurrentOptions(children);}onToggle?.(newState);},[children,disabled,isControlled,labelFromSelected,onToggle,openState,selectionType,setFocusedIndex]);const handleChange=React__namespace.useCallback(value=>{if(value!==valueState){setSelectedValue(value);onChange?.(value);}if(selectionType==="single"&&typeof value==="string"){const itemFromSelected=renderList.find(item=>item.props.value===value)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";updateOpenState(false,labelFromSelected);}else if(Array.isArray(value)){setInputValue("");setCurrentOptions(children);}},[children,onChange,renderList,selectionType,updateOpenState,valueState]);const focusOnFilteredItem=React__namespace.useCallback((filtered,value)=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();const itemIndex=filtered.findIndex(item=>getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));setFocusedIndex(itemIndex);},[setFocusedIndex]);const filterItems=React__namespace.useCallback(value=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();return children.filter(item=>getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText)>-1)},[children]);const onKeyDown=event=>{const{key}=event;const conditionsToOpen=key==="ArrowDown"||key==="ArrowUp"||key==="Backspace"||key.length===1;if(!openState&&conditionsToOpen){updateOpenState(true);}if(key==="ArrowLeft"||key==="ArrowRight"){setFocusedIndex(-1);}handleMultipleSelectionKeyDown(event);if(key==="Escape"&&openState){event.stopPropagation();updateOpenState(false);}handleKeyDown(event);};const handleOnRemoveClick=React__namespace.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);updateAfterSelectionChange(newValues);},[selected,updateAfterSelectionChange]);const handleTextFieldChange=React__namespace.useCallback(value=>{setInputValue(value);let filteredItems=renderList;if(autoComplete==="list"){filteredItems=filterItems(value);setCurrentOptions(filteredItems);}focusOnFilteredItem(filteredItems,value);},[autoComplete,filterItems,focusOnFilteredItem,renderList]);const handleClearClick=React__namespace.useCallback(e=>{e.stopPropagation();setInputValue("");setSelected("");onChange?.("");comboboxRef.current?.focus();},[onChange,setSelected]);React__namespace.useEffect(()=>{if(openState){comboboxRef.current?.focus();}},[openState]);const selectedLabels=React__namespace.useMemo(()=>{if(Array.isArray(selected)){return selected.map(value=>{const item=children.find(item=>item.props.value===value);return item?getLabel(item?.props):""})}return [labelFromSelected]},[children,labelFromSelected,selected]);const maybeRenderStartIcon=()=>{if(!startIcon){return null}const startIconElement=React__namespace.cloneElement(startIcon,{size:"small",...startIcon.props,color:disabled?wonderBlocksTokens.semanticColor.core.foreground.disabled.default:startIcon.props.color??wonderBlocksTokens.semanticColor.core.foreground.neutral.default});return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles$1.iconWrapper,children:startIconElement})};const pillIdPrefix=`${uniqueId}-pill-`;const textFieldId=React.useId();const currentActiveDescendant=!openState?undefined:focusedIndex>=0?renderList[focusedIndex]?.props?.id:pillIdPrefix+focusedMultiSelectIndex;const controlledWidget=!openState?undefined:focusedIndex>=0?uniqueId:pillIdPrefix;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(wonderBlocksCore.View,{onClick:()=>{updateOpenState(true);},ref:rootNodeRef,style:[styles$1.wrapper,isListboxFocused&&styles$1.focused,disabled&&styles$1.disabled,!disabled&&error&&styles$1.error],children:[jsxRuntime.jsx(ComboboxLiveRegion,{focusedIndex:focusedIndex,focusedMultiSelectIndex:focusedMultiSelectIndex,labels:labels,options:renderList,selectedLabels:selectedLabels,testId:testId,opened:openState,selected:selected,selectionType:selectionType}),selectionType==="multiple"&&Array.isArray(selected)&&jsxRuntime.jsx(MultipleSelection,{labels:selectedLabels,focusedMultiSelectIndex:focusedMultiSelectIndex,id:pillIdPrefix,selected:selected,onRemove:handleOnRemoveClick,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsxRuntime.jsx(wonderBlocksForm.TextField,{id:textFieldId,testId:testId,style:[styles$1.combobox,style],value:inputValue,onChange:handleTextFieldChange,disabled:disabled,onFocus:()=>{updateOpenState(true);handleFocus();},placeholder:placeholder,onBlur:()=>{updateOpenState(false);handleBlur();},onKeyDown:onKeyDown,"aria-activedescendant":currentActiveDescendant,"aria-autocomplete":autoComplete,"aria-controls":controlledWidget,"aria-expanded":openState,"aria-invalid":!!error,ref:comboboxRef,autoComplete:"off",role:"combobox",...ariaAttrs}),inputValue&&!disabled&&jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.clearButton],"aria-label":labels.clearSelection,testId:testId?`${testId}-clear`:undefined}),jsxRuntime.jsx(IconButton__default["default"],{disabled:disabled,icon:caretDownIcon__default$1["default"],onClick:e=>{e.stopPropagation();updateOpenState(!openState);},onMouseDown:e=>{e.preventDefault();},actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.openButtonResetStates,openState&&styles$1.buttonOpen],tabIndex:-1,"aria-controls":uniqueId,"aria-expanded":openState,"aria-label":labels.comboboxButton})]}),openState&&jsxRuntime.jsx(DropdownPopper,{alignment:"left",referenceElement:rootNodeRef?.current,children:isReferenceHidden=>jsxRuntime.jsx(wonderBlocksCore.View,{onMouseDown:e=>{e.preventDefault();},children:renderList.length===0?jsxRuntime.jsx(wonderBlocksCell.DetailCell,{title:labels.noItems,styles:{root:[styles$1.listbox,{minInlineSize:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsxRuntime.jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles$1.listbox,isReferenceHidden&&styles$1.hidden,{minInlineSize:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles$1=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxInlineSize:"100%",flexWrap:"wrap",background:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.opener.border.radius.rest,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,paddingInline:theme.opener.layout.padding.inline,overflow:"hidden"},focused:wonderBlocksStyles.focusStyles.focus[":focus-visible"],disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground},combobox:{appearance:"none",background:"none",border:"none",outline:"none",padding:0,minInlineSize:wonderBlocksTokens.sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none",boxShadow:"none"},[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"},[":focus-visible:active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"}},listbox:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",insetInlineEnd:wonderBlocksTokens.sizing.size_0,margin:0},buttonOpen:{transform:"rotate(180deg)"},openButtonResetStates:{":hover":{borderColor:wonderBlocksTokens.semanticColor.core.transparent},":active":{borderColor:wonderBlocksTokens.semanticColor.core.transparent},":focus-visible":{outline:"none",boxShadow:"none"}},clearButton:{insetInlineEnd:wonderBlocksTokens.sizing.size_360},iconWrapper:{padding:wonderBlocksTokens.sizing.size_040,minInlineSize:"auto"}});
|
|
118
|
+
function Combobox({autoComplete,children,disabled,error,id,labels:propLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value="",loading,style,...ariaAttrs}){const{strings}=wonderBlocksConfig.useWonderBlocksI18n();const labels=React__namespace.useMemo(()=>({clearSelection:propLabels?.clearSelection||strings.iconAltClearSelection,comboboxButton:propLabels?.comboboxButton||strings.iconAltToggleListbox,listbox:propLabels?.listbox||strings.optionsList,noItems:propLabels?.noItems||strings.noResults,removeSelected:propLabels?.removeSelected||(label=>strings.removeOption({label}))}),[propLabels,strings]);const liveRegionLabels=React__namespace.useMemo(()=>({closedState:propLabels?.closedState,liveRegionCurrentItem:propLabels?.liveRegionCurrentItem,liveRegionListboxTotal:propLabels?.liveRegionListboxTotal,liveRegionMultipleSelectionTotal:propLabels?.liveRegionMultipleSelectionTotal,noItems:propLabels?.noItems,selected:propLabels?.selected,selectionCleared:propLabels?.selectionCleared,unselected:propLabels?.unselected}),[propLabels]);const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const comboboxRef=React__namespace.useRef(null);const rootNodeRef=React__namespace.useRef(null);const[open,setOpen]=React__namespace.useState(opened??false);const isControlled=opened!==undefined;const openState=disabled?false:isControlled?opened:open;const[selectedValue,setSelectedValue]=React__namespace.useState(value);const isValueControlled=value!==""&&onChange!==undefined;const valueState=isValueControlled?value:selectedValue;const[currentOptions,setCurrentOptions]=React__namespace.useState(children);const{focusedIndex,isListboxFocused,setFocusedIndex,handleKeyDown,handleFocus,handleBlur,selected,setSelected,renderList}=useListbox({children:currentOptions,disabled,id:uniqueId,onChange:value=>handleChange(value),value:valueState,disableSpaceSelection:true,selectionType});const itemFromSelected=renderList.find(item=>item.props.value===selected)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";const initialValue=typeof value==="string"?labelFromSelected:"";const[inputValue,setInputValue]=React__namespace.useState(initialValue);const updateAfterSelectionChange=React__namespace.useCallback(value=>{setSelected(value);onChange?.(value);},[onChange,setSelected]);const{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,onRemove:updateAfterSelectionChange,isComboboxOpen:openState});const updateOpenState=React__namespace.useCallback((newState,selectedLabel=labelFromSelected)=>{if(disabled||newState===openState){return}if(!isControlled){setOpen(newState);}if(!newState){setFocusedIndex(-1);if(selectionType==="multiple"){setInputValue("");}else {setInputValue(selectedLabel??"");}setCurrentOptions(children);}onToggle?.(newState);},[children,disabled,isControlled,labelFromSelected,onToggle,openState,selectionType,setFocusedIndex]);const handleChange=React__namespace.useCallback(value=>{if(value!==valueState){setSelectedValue(value);onChange?.(value);}if(selectionType==="single"&&typeof value==="string"){const itemFromSelected=renderList.find(item=>item.props.value===value)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";updateOpenState(false,labelFromSelected);}else if(Array.isArray(value)){setInputValue("");setCurrentOptions(children);}},[children,onChange,renderList,selectionType,updateOpenState,valueState]);const focusOnFilteredItem=React__namespace.useCallback((filtered,value)=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();const itemIndex=filtered.findIndex(item=>getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));setFocusedIndex(itemIndex);},[setFocusedIndex]);const filterItems=React__namespace.useCallback(value=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();return children.filter(item=>getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText)>-1)},[children]);const onKeyDown=event=>{const{key}=event;const conditionsToOpen=key==="ArrowDown"||key==="ArrowUp"||key==="Backspace"||key.length===1;if(!openState&&conditionsToOpen){updateOpenState(true);}if(key==="ArrowLeft"||key==="ArrowRight"){setFocusedIndex(-1);}handleMultipleSelectionKeyDown(event);if(key==="Escape"&&openState){event.stopPropagation();updateOpenState(false);}handleKeyDown(event);};const handleOnRemoveClick=React__namespace.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);updateAfterSelectionChange(newValues);},[selected,updateAfterSelectionChange]);const handleTextFieldChange=React__namespace.useCallback(value=>{setInputValue(value);let filteredItems=renderList;if(autoComplete==="list"){filteredItems=filterItems(value);setCurrentOptions(filteredItems);}focusOnFilteredItem(filteredItems,value);},[autoComplete,filterItems,focusOnFilteredItem,renderList]);const handleClearClick=React__namespace.useCallback(e=>{e.stopPropagation();setInputValue("");setSelected("");onChange?.("");comboboxRef.current?.focus();},[onChange,setSelected]);React__namespace.useEffect(()=>{if(openState){comboboxRef.current?.focus();}},[openState]);const selectedLabels=React__namespace.useMemo(()=>{if(Array.isArray(selected)){return selected.map(value=>{const item=children.find(item=>item.props.value===value);return item?getLabel(item?.props):""})}return [labelFromSelected]},[children,labelFromSelected,selected]);const maybeRenderStartIcon=()=>{if(!startIcon){return null}const startIconElement=React__namespace.cloneElement(startIcon,{size:"small",...startIcon.props,color:disabled?wonderBlocksTokens.semanticColor.core.foreground.disabled.default:startIcon.props.color??wonderBlocksTokens.semanticColor.core.foreground.neutral.default});return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles$1.iconWrapper,children:startIconElement})};const pillIdPrefix=`${uniqueId}-pill-`;const textFieldId=React.useId();const currentActiveDescendant=!openState?undefined:focusedIndex>=0?renderList[focusedIndex]?.props?.id:pillIdPrefix+focusedMultiSelectIndex;const controlledWidget=!openState?undefined:focusedIndex>=0?uniqueId:pillIdPrefix;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(wonderBlocksCore.View,{onClick:()=>{updateOpenState(true);},ref:rootNodeRef,style:[styles$1.wrapper,isListboxFocused&&styles$1.focused,disabled&&styles$1.disabled,!disabled&&error&&styles$1.error],children:[jsxRuntime.jsx(ComboboxLiveRegion,{focusedIndex:focusedIndex,focusedMultiSelectIndex:focusedMultiSelectIndex,labels:liveRegionLabels,options:renderList,selectedLabels:selectedLabels,testId:testId,opened:openState,selected:selected,selectionType:selectionType}),selectionType==="multiple"&&Array.isArray(selected)&&jsxRuntime.jsx(MultipleSelection,{labels:selectedLabels,focusedMultiSelectIndex:focusedMultiSelectIndex,id:pillIdPrefix,selected:selected,onRemove:handleOnRemoveClick,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsxRuntime.jsx(wonderBlocksForm.TextField,{id:textFieldId,testId:testId,style:[styles$1.combobox,style],value:inputValue,onChange:handleTextFieldChange,disabled:disabled,onFocus:()=>{updateOpenState(true);handleFocus();},placeholder:placeholder,onBlur:()=>{updateOpenState(false);handleBlur();},onKeyDown:onKeyDown,"aria-activedescendant":currentActiveDescendant,"aria-autocomplete":autoComplete,"aria-controls":controlledWidget,"aria-expanded":openState,"aria-invalid":!!error,ref:comboboxRef,autoComplete:"off",role:"combobox",...ariaAttrs}),inputValue&&!disabled&&jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.clearButton],"aria-label":labels.clearSelection,testId:testId?`${testId}-clear`:undefined}),jsxRuntime.jsx(IconButton__default["default"],{disabled:disabled,icon:caretDownIcon__default$1["default"],onClick:e=>{e.stopPropagation();updateOpenState(!openState);},onMouseDown:e=>{e.preventDefault();},actionType:"neutral",kind:"tertiary",size:"medium",style:[styles$1.button,styles$1.openButtonResetStates,openState&&styles$1.buttonOpen],tabIndex:-1,"aria-controls":uniqueId,"aria-expanded":openState,"aria-label":labels.comboboxButton})]}),openState&&jsxRuntime.jsx(DropdownPopper,{alignment:"left",referenceElement:rootNodeRef?.current,children:isReferenceHidden=>jsxRuntime.jsx(wonderBlocksCore.View,{onMouseDown:e=>{e.preventDefault();},children:renderList.length===0?jsxRuntime.jsx(wonderBlocksCell.DetailCell,{title:labels.noItems,styles:{root:[styles$1.listbox,{minInlineSize:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsxRuntime.jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles$1.listbox,isReferenceHidden&&styles$1.hidden,{minInlineSize:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles$1=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxInlineSize:"100%",flexWrap:"wrap",background:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.opener.border.radius.rest,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,paddingInline:theme.opener.layout.padding.inline,overflow:"hidden"},focused:wonderBlocksStyles.focusStyles.focus[":focus-visible"],disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${theme.opener.border.width.error} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground},combobox:{appearance:"none",background:"none",border:"none",outline:"none",padding:0,minInlineSize:wonderBlocksTokens.sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none",boxShadow:"none"},[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"},[":focus-visible:active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:"none"}},listbox:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme.listbox.border.radius,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,boxShadow:theme.listbox.shadow.default,maxBlockSize:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",insetInlineEnd:wonderBlocksTokens.sizing.size_0,margin:0},buttonOpen:{transform:"rotate(180deg)"},openButtonResetStates:{":hover":{borderColor:wonderBlocksTokens.semanticColor.core.transparent},":active":{borderColor:wonderBlocksTokens.semanticColor.core.transparent},":focus-visible":{outline:"none",boxShadow:"none"}},clearButton:{insetInlineEnd:wonderBlocksTokens.sizing.size_360},iconWrapper:{padding:wonderBlocksTokens.sizing.size_040,minInlineSize:"auto"}});
|
|
118
119
|
|
|
119
120
|
const StyledButton=wonderBlocksCore.addStyle("button");const CustomOpener=React__namespace.forwardRef(function CustomOpener(props,ref){const{children,disabled,onClick,styles:stylesProp,testId,...restProps}=props;const injectedAriaDisabled=restProps["aria-disabled"];const ariaDisabled=injectedAriaDisabled??(disabled||undefined);return jsxRuntime.jsx(StyledButton,{...restProps,ref:ref,type:"button","aria-disabled":ariaDisabled,onClick:disabled?undefined:onClick,"data-testid":testId,style:[styles.reset,disabled&&styles.disabled,stylesProp?.root],children:jsxRuntime.jsx(wonderBlocksTypography.BodyText,{tag:"span",style:[styles.labelReset,stylesProp?.label],children:children})})});CustomOpener.displayName="CustomOpener";const styles=aphrodite.StyleSheet.create({reset:{appearance:"none",background:"none",border:"none",boxSizing:"border-box",cursor:"pointer",font:"inherit",margin:0,padding:0,textAlign:"inherit",touchAction:"manipulation",...wonderBlocksStyles.focusStyles.focus},labelReset:{alignItems:"center",display:"flex",flexDirection:"row",gap:wonderBlocksTokens.sizing.size_020},disabled:{cursor:"not-allowed"}});
|
|
120
121
|
|
package/dist/util/constants.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ComboboxLabels } from "./types";
|
|
2
1
|
export declare const selectDropdownStyle: {
|
|
3
2
|
readonly marginBlock: string;
|
|
4
3
|
};
|
|
@@ -13,14 +12,3 @@ export declare const DROPDOWN_ITEM_HEIGHT = 40;
|
|
|
13
12
|
*/
|
|
14
13
|
export declare const MAX_VISIBLE_ITEMS = 9;
|
|
15
14
|
export declare const SEPARATOR_ITEM_HEIGHT = 9;
|
|
16
|
-
export declare const defaultLabels: {
|
|
17
|
-
readonly clearSearch: "Clear search";
|
|
18
|
-
readonly filter: "Filter";
|
|
19
|
-
readonly noResults: "No results";
|
|
20
|
-
readonly selectNoneLabel: "Select none";
|
|
21
|
-
readonly selectAllLabel: (numOptions: number) => string;
|
|
22
|
-
readonly noneSelected: "0 items";
|
|
23
|
-
readonly someSelected: (numSelectedValues: number) => string;
|
|
24
|
-
readonly allSelected: "All items";
|
|
25
|
-
};
|
|
26
|
-
export declare const defaultComboboxLabels: ComboboxLabels;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Dropdown variants for Wonder Blocks.",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "10.
|
|
6
|
+
"version": "10.14.1",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -30,15 +30,16 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@khanacademy/wonder-blocks-announcer": "1.1.2",
|
|
32
32
|
"@khanacademy/wonder-blocks-button": "11.7.13",
|
|
33
|
-
"@khanacademy/wonder-blocks-cell": "6.
|
|
33
|
+
"@khanacademy/wonder-blocks-cell": "6.3.0",
|
|
34
34
|
"@khanacademy/wonder-blocks-clickable": "8.3.2",
|
|
35
|
+
"@khanacademy/wonder-blocks-config": "0.7.1",
|
|
35
36
|
"@khanacademy/wonder-blocks-core": "12.5.0",
|
|
36
|
-
"@khanacademy/wonder-blocks-form": "7.7.
|
|
37
|
+
"@khanacademy/wonder-blocks-form": "7.7.6",
|
|
37
38
|
"@khanacademy/wonder-blocks-icon": "6.0.3",
|
|
38
39
|
"@khanacademy/wonder-blocks-icon-button": "12.0.2",
|
|
39
|
-
"@khanacademy/wonder-blocks-modal": "8.10.
|
|
40
|
-
"@khanacademy/wonder-blocks-pill": "3.1.
|
|
41
|
-
"@khanacademy/wonder-blocks-search-field": "5.2.
|
|
40
|
+
"@khanacademy/wonder-blocks-modal": "8.10.3",
|
|
41
|
+
"@khanacademy/wonder-blocks-pill": "3.1.83",
|
|
42
|
+
"@khanacademy/wonder-blocks-search-field": "5.2.6",
|
|
42
43
|
"@khanacademy/wonder-blocks-styles": "0.4.1",
|
|
43
44
|
"@khanacademy/wonder-blocks-timing": "7.1.0",
|
|
44
45
|
"@khanacademy/wonder-blocks-tokens": "18.1.0",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@khanacademy/wb-dev-build-settings": "3.3.0",
|
|
61
|
-
"@khanacademy/wonder-blocks-labeled-field": "4.3.
|
|
62
|
+
"@khanacademy/wonder-blocks-labeled-field": "4.3.6"
|
|
62
63
|
},
|
|
63
64
|
"scripts": {
|
|
64
65
|
"build:css": "pnpm exec wonder-blocks-tokens .",
|