@khanacademy/wonder-blocks-dropdown 10.4.6 → 10.4.7
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @khanacademy/wonder-blocks-dropdown@10.4.
|
|
2
|
+
> @khanacademy/wonder-blocks-dropdown@10.4.7 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,13 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-dropdown
|
|
2
2
|
|
|
3
|
+
## 10.4.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bfeaf57: Combobox improvements: Use Button instead of Pill for selected items. Also fixes styling for TB theme and uses logical css properties to support RTL
|
|
8
|
+
- Updated dependencies [bfeaf57]
|
|
9
|
+
- @khanacademy/wonder-blocks-cell@6.1.0
|
|
10
|
+
|
|
3
11
|
## 10.4.6
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -5,7 +5,7 @@ type Props = {
|
|
|
5
5
|
*/
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
/**
|
|
8
|
-
* The index of the focused item in the
|
|
8
|
+
* The index of the focused item in the selected items group.
|
|
9
9
|
*/
|
|
10
10
|
focusedMultiSelectIndex: number;
|
|
11
11
|
/**
|
|
@@ -30,13 +30,12 @@ type Props = {
|
|
|
30
30
|
*/
|
|
31
31
|
selected: Array<string>;
|
|
32
32
|
/**
|
|
33
|
-
* The testId prefix used for the
|
|
33
|
+
* The testId prefix used for the items.
|
|
34
34
|
*/
|
|
35
35
|
testId?: string;
|
|
36
36
|
};
|
|
37
37
|
/**
|
|
38
|
-
* Renders the selected items
|
|
39
|
-
* the input element.
|
|
38
|
+
* Renders the selected items before the input element.
|
|
40
39
|
*/
|
|
41
40
|
export declare const MultipleSelection: React.NamedExoticComponent<Props>;
|
|
42
41
|
export {};
|
package/dist/es/index.js
CHANGED
|
@@ -25,7 +25,6 @@ import caretDownIcon$1 from '@phosphor-icons/core/regular/caret-down.svg';
|
|
|
25
25
|
import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
26
26
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
27
27
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
28
|
-
import Pill from '@khanacademy/wonder-blocks-pill';
|
|
29
28
|
|
|
30
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;const defaultLabels={clearSearch:"Clear search",filter:"Filter",noResults:"No results",selectNoneLabel:"Select none",selectAllLabel:numOptions=>`Select all (${numOptions})`,noneSelected:"0 items",someSelected:numSelectedValues=>numSelectedValues===1?"1 item":`${numSelectedValues} items`,allSelected:"All items"};const defaultComboboxLabels={clearSelection:"Clear selection",closedState:"Combobox is closed",comboboxButton:"Toggle listbox",listbox:"Options list",removeSelected:label=>`Remove ${label}`,liveRegionCurrentItem:({current,index,total,disabled,focused,selected})=>`${current}${focused?" focused":""}${disabled?" disabled":""}${selected?" selected":""}, ${index+1} of ${total}.`,liveRegionMultipleSelectionTotal:total=>`${total} selected options.`,liveRegionListboxTotal:total=>`${total} results available.`,noItems:"No results",selected:labels=>`${labels} selected`,selectionCleared:"Selection cleared",unselected:labels=>`${labels} not selected`};
|
|
31
30
|
|
|
@@ -81,10 +80,10 @@ function useMultipleSelection({inputValue,selected,setSelected}){const[focusedMu
|
|
|
81
80
|
|
|
82
81
|
const StyledSpan=addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels={closedState:defaultComboboxLabels.closedState,liveRegionCurrentItem:defaultComboboxLabels.liveRegionCurrentItem,liveRegionListboxTotal:defaultComboboxLabels.liveRegionListboxTotal,liveRegionMultipleSelectionTotal:defaultComboboxLabels.liveRegionMultipleSelectionTotal,noItems:defaultComboboxLabels.noItems,selected:defaultComboboxLabels.selected,selectionCleared:defaultComboboxLabels.selectionCleared,unselected:defaultComboboxLabels.unselected},selectedLabels,opened,options,selected,selectionType="single",testId}){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$3.srOnly,"data-testid":testId?`${testId}-status`:undefined,children:opened?focusedElementDescription:message})}const styles$3=StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
83
82
|
|
|
84
|
-
const MultipleSelection=React.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsx(View,{role:"group",style:styles$2.
|
|
83
|
+
const MultipleSelection=React.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsx(View,{role:"group",style:styles$2.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$2.item,focused&&styles$2.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$2=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"]});
|
|
85
84
|
|
|
86
85
|
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$1.listbox,style,disabled&&styles$1.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$1.listbox,style,disabled&&styles$1.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",children:children})}const styles$1=StyleSheet.create({listbox:{backgroundColor:semanticColor.core.background.base.default,outline:"none",paddingBlock:theme$3.listbox.layout.padding.block,paddingInline:theme$3.listbox.layout.padding.inline},disabled:{color:semanticColor.action.secondary.disabled.foreground}});
|
|
87
86
|
|
|
88
|
-
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value=""}){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{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,setSelected});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 handleOnRemove=React.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);setSelected(newValues);},[selected,setSelected]);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.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.wrapper,isListboxFocused&&styles.focused,disabled&&styles.disabled,!disabled&&error&&styles.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:handleOnRemove,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsx(TextField,{id:textFieldId,testId:testId,style:styles.combobox,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"}),inputValue&&!disabled&&jsx(IconButton,{icon:xIcon,onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"
|
|
87
|
+
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value=""}){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{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,setSelected});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 handleOnRemove=React.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);setSelected(newValues);},[selected,setSelected]);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.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.wrapper,isListboxFocused&&styles.focused,disabled&&styles.disabled,!disabled&&error&&styles.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:handleOnRemove,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsx(TextField,{id:textFieldId,testId:testId,style:styles.combobox,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"}),inputValue&&!disabled&&jsx(IconButton,{icon:xIcon,onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles.button,styles.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.button,openState&&styles.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.listbox,{minWidth:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles.listbox,isReferenceHidden&&styles.hidden,{minWidth:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles=StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxWidth:"100%",flexWrap:"wrap",background:semanticColor.core.background.base.default,borderRadius:theme$3.opener.border.radius.rest,border:`${border.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,paddingInline:theme$3.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$3.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,minWidth:sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none"}},listbox:{backgroundColor:semanticColor.core.background.base.default,borderRadius:theme$3.listbox.border.radius,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,boxShadow:theme$3.listbox.shadow.default,maxHeight:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",insetInlineEnd:sizing.size_0,margin:0},buttonOpen:{transform:"rotate(180deg)"},clearButton:{insetInlineEnd:sizing.size_360},iconWrapper:{padding:sizing.size_040,minWidth:"auto"}});
|
|
89
88
|
|
|
90
89
|
export { ActionItem, ActionMenu, Combobox, Listbox, MultiSelect, OptionItem, SeparatorItem, SingleSelect };
|
|
@@ -68,7 +68,7 @@ export declare function useListbox({ children: options, disabled, disableSpaceSe
|
|
|
68
68
|
rightAccessory?: import("../util/types").CellProps["rightAccessory"];
|
|
69
69
|
subtitle1?: import("../util/types").CellProps["subtitle1"];
|
|
70
70
|
subtitle2?: import("../util/types").CellProps["subtitle2"];
|
|
71
|
-
}, keyof import("@khanacademy/wonder-blocks-core").AriaAttributes | "style" | "label" | "leftAccessory" | "rightAccessory" | "testId" | "onClick" | "subtitle1" | "subtitle2" | "labelAsText" | "value" | "variant" | "parentComponent"
|
|
71
|
+
}, keyof import("@khanacademy/wonder-blocks-core").AriaAttributes | "style" | "label" | "leftAccessory" | "rightAccessory" | "id" | "testId" | "onClick" | "subtitle1" | "subtitle2" | "labelAsText" | "value" | "variant" | "parentComponent"> & {
|
|
72
72
|
selected?: boolean | undefined;
|
|
73
73
|
disabled?: boolean | undefined;
|
|
74
74
|
role?: "menuitem" | "menuitemcheckbox" | "option" | undefined;
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,6 @@ var caretDownIcon$1 = require('@phosphor-icons/core/regular/caret-down.svg');
|
|
|
28
28
|
var xIcon = require('@phosphor-icons/core/regular/x.svg');
|
|
29
29
|
var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
|
|
30
30
|
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
31
|
-
var Pill = require('@khanacademy/wonder-blocks-pill');
|
|
32
31
|
|
|
33
32
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
34
33
|
|
|
@@ -58,7 +57,6 @@ var caretDownIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDownIcon);
|
|
|
58
57
|
var caretDownIcon__default$1 = /*#__PURE__*/_interopDefaultLegacy(caretDownIcon$1);
|
|
59
58
|
var xIcon__default = /*#__PURE__*/_interopDefaultLegacy(xIcon);
|
|
60
59
|
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
61
|
-
var Pill__default = /*#__PURE__*/_interopDefaultLegacy(Pill);
|
|
62
60
|
|
|
63
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;const defaultLabels={clearSearch:"Clear search",filter:"Filter",noResults:"No results",selectNoneLabel:"Select none",selectAllLabel:numOptions=>`Select all (${numOptions})`,noneSelected:"0 items",someSelected:numSelectedValues=>numSelectedValues===1?"1 item":`${numSelectedValues} items`,allSelected:"All items"};const defaultComboboxLabels={clearSelection:"Clear selection",closedState:"Combobox is closed",comboboxButton:"Toggle listbox",listbox:"Options list",removeSelected:label=>`Remove ${label}`,liveRegionCurrentItem:({current,index,total,disabled,focused,selected})=>`${current}${focused?" focused":""}${disabled?" disabled":""}${selected?" selected":""}, ${index+1} of ${total}.`,liveRegionMultipleSelectionTotal:total=>`${total} selected options.`,liveRegionListboxTotal:total=>`${total} results available.`,noItems:"No results",selected:labels=>`${labels} selected`,selectionCleared:"Selection cleared",unselected:labels=>`${labels} not selected`};
|
|
64
62
|
|
|
@@ -114,11 +112,11 @@ function useMultipleSelection({inputValue,selected,setSelected}){const[focusedMu
|
|
|
114
112
|
|
|
115
113
|
const StyledSpan=wonderBlocksCore.addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels={closedState:defaultComboboxLabels.closedState,liveRegionCurrentItem:defaultComboboxLabels.liveRegionCurrentItem,liveRegionListboxTotal:defaultComboboxLabels.liveRegionListboxTotal,liveRegionMultipleSelectionTotal:defaultComboboxLabels.liveRegionMultipleSelectionTotal,noItems:defaultComboboxLabels.noItems,selected:defaultComboboxLabels.selected,selectionCleared:defaultComboboxLabels.selectionCleared,unselected:defaultComboboxLabels.unselected},selectedLabels,opened,options,selected,selectionType="single",testId}){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$3.srOnly,"data-testid":testId?`${testId}-status`:undefined,children:opened?focusedElementDescription:message})}const styles$3=aphrodite.StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
|
|
116
114
|
|
|
117
|
-
const MultipleSelection=React__namespace.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsxRuntime.jsx(wonderBlocksCore.View,{role:"group",style:styles$2.
|
|
115
|
+
const MultipleSelection=React__namespace.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsxRuntime.jsx(wonderBlocksCore.View,{role:"group",style:styles$2.container,id:id,children:selected.map((value,index)=>{const label=labels[index];const focused=index===focusedMultiSelectIndex;const uniqueId=id+index;return jsxRuntime.jsx(Button,{id:uniqueId,testId:testId?`${testId}-item-${index}`:undefined,size:"small",style:[styles$2.item,focused&&styles$2.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$2=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"]});
|
|
118
116
|
|
|
119
117
|
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$1.listbox,style,disabled&&styles$1.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$1.listbox,style,disabled&&styles$1.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",children:children})}const styles$1=aphrodite.StyleSheet.create({listbox:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,outline:"none",paddingBlock:theme$3.listbox.layout.padding.block,paddingInline:theme$3.listbox.layout.padding.inline},disabled:{color:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground}});
|
|
120
118
|
|
|
121
|
-
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value=""}){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{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,setSelected});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 handleOnRemove=React__namespace.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);setSelected(newValues);},[selected,setSelected]);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.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.wrapper,isListboxFocused&&styles.focused,disabled&&styles.disabled,!disabled&&error&&styles.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:handleOnRemove,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsxRuntime.jsx(wonderBlocksForm.TextField,{id:textFieldId,testId:testId,style:styles.combobox,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"}),inputValue&&!disabled&&jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"
|
|
119
|
+
function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value=""}){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{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,setSelected});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 handleOnRemove=React__namespace.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);setSelected(newValues);},[selected,setSelected]);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.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.wrapper,isListboxFocused&&styles.focused,disabled&&styles.disabled,!disabled&&error&&styles.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:handleOnRemove,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsxRuntime.jsx(wonderBlocksForm.TextField,{id:textFieldId,testId:testId,style:styles.combobox,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"}),inputValue&&!disabled&&jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"medium",style:[styles.button,styles.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.button,openState&&styles.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.listbox,{minWidth:rootNodeRef?.current?.offsetWidth}]},horizontalRule:"none"}):jsxRuntime.jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles.listbox,isReferenceHidden&&styles.hidden,{minWidth:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const styles=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxWidth:"100%",flexWrap:"wrap",background:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme$3.opener.border.radius.rest,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,paddingInline:theme$3.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$3.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,minWidth:wonderBlocksTokens.sizing.size_040,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none"}},listbox:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,borderRadius:theme$3.listbox.border.radius,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,boxShadow:theme$3.listbox.shadow.default,maxHeight:"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)"},clearButton:{insetInlineEnd:wonderBlocksTokens.sizing.size_360},iconWrapper:{padding:wonderBlocksTokens.sizing.size_040,minWidth:"auto"}});
|
|
122
120
|
|
|
123
121
|
exports.ActionItem = ActionItem;
|
|
124
122
|
exports.ActionMenu = ActionMenu;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-dropdown",
|
|
3
|
-
"version": "10.4.
|
|
3
|
+
"version": "10.4.7",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Dropdown variants for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@khanacademy/wonder-blocks-announcer": "1.0.3",
|
|
24
|
-
"@khanacademy/wonder-blocks-cell": "6.0
|
|
24
|
+
"@khanacademy/wonder-blocks-cell": "6.1.0",
|
|
25
25
|
"@khanacademy/wonder-blocks-clickable": "8.0.0",
|
|
26
26
|
"@khanacademy/wonder-blocks-core": "12.4.0",
|
|
27
27
|
"@khanacademy/wonder-blocks-form": "7.4.1",
|