@khanacademy/wonder-blocks-dropdown 10.4.2 → 10.4.4
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 +19 -0
- package/dist/es/index.js +2 -2
- package/dist/index.js +2 -2
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @khanacademy/wonder-blocks-dropdown@10.4.
|
|
2
|
+
> @khanacademy/wonder-blocks-dropdown@10.4.4 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,24 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-dropdown
|
|
2
2
|
|
|
3
|
+
## 10.4.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 11eac78: Prevents announcements on initial render
|
|
8
|
+
- Updated dependencies [aa67854]
|
|
9
|
+
- Updated dependencies [79ea5ab]
|
|
10
|
+
- Updated dependencies [79ea5ab]
|
|
11
|
+
- @khanacademy/wonder-blocks-modal@8.4.5
|
|
12
|
+
- @khanacademy/wonder-blocks-cell@6.0.1
|
|
13
|
+
|
|
14
|
+
## 10.4.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [e095f19]
|
|
19
|
+
- @khanacademy/wonder-blocks-form@7.4.0
|
|
20
|
+
- @khanacademy/wonder-blocks-search-field@5.1.48
|
|
21
|
+
|
|
3
22
|
## 10.4.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/es/index.js
CHANGED
|
@@ -69,9 +69,9 @@ const StyledButton=addStyle("button");class SelectOpener extends React.Component
|
|
|
69
69
|
|
|
70
70
|
const defaultErrorMessage="This field is required.";function hasValue(value){return value?value.length>0:false}function useSelectValidation({value,disabled=false,validate,onValidate,required,open}){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:defaultErrorMessage;const error=hasValue(newValue)?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}},[disabled,validate,setErrorMessage,onValidate,required]);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}}
|
|
71
71
|
|
|
72
|
-
const SingleSelect=props=>{const selectedIndex=React.useRef(0);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};React.useEffect(()=>{const optionItems=React.Children.toArray(children);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}},[selectedValue,children]);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,children:opener}):jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,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{someResults}=labels;React.useEffect(()=>{if(open){handleAnnouncement(someResults(items.length));}},[items.length,someResults,open]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore$1,{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,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
|
|
72
|
+
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={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};React.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}const optionItems=React.Children.toArray(children);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}},[selectedValue,children]);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,children:opener}):jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,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{someResults}=labels;React.useEffect(()=>{if(open){handleAnnouncement(someResults(items.length));}},[items.length,someResults,open]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore$1,{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,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
|
|
73
73
|
|
|
74
|
-
const MultiSelect=props=>{const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React.useMemo(()=>{return {...defaultLabels,...propLabels}},[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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};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]);React.useEffect(()=>{const optionItems=React.Children.toArray(children);const openerContent=getMenuTextOrNode(optionItems);const openerStringValue=maybeGetOpenerStringValue(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}},[children,getMenuTextOrNode,maybeGetOpenerStringValue]);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,children:opener}):jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;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;React.useEffect(()=>{if(open){handleAnnouncement(someSelected(filteredItems.length));}},[filteredItems.length,someSelected,open]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore$1,{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},"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:isDisabled})})};
|
|
74
|
+
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-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React.useMemo(()=>{return {...defaultLabels,...propLabels}},[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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};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]);React.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}const optionItems=React.Children.toArray(children);const openerContent=getMenuTextOrNode(optionItems);const openerStringValue=maybeGetOpenerStringValue(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}},[children,getMenuTextOrNode,maybeGetOpenerStringValue]);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,children:opener}):jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;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;React.useEffect(()=>{if(open){handleAnnouncement(someSelected(filteredItems.length));}},[filteredItems.length,someSelected,open]);return jsx(Id,{id:dropdownId,children:uniqueDropdownId=>jsx(DropdownCore$1,{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},"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:isDisabled})})};
|
|
75
75
|
|
|
76
76
|
function updateMultipleSelection(previousSelection,value=""){if(!previousSelection){return [value]}return previousSelection.includes(value)?previousSelection.filter(item=>item!==value):[...previousSelection,value]}
|
|
77
77
|
|
package/dist/index.js
CHANGED
|
@@ -102,9 +102,9 @@ const StyledButton=wonderBlocksCore.addStyle("button");class SelectOpener extend
|
|
|
102
102
|
|
|
103
103
|
const defaultErrorMessage="This field is required.";function hasValue(value){return value?value.length>0:false}function useSelectValidation({value,disabled=false,validate,onValidate,required,open}){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:defaultErrorMessage;const error=hasValue(newValue)?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}},[disabled,validate,setErrorMessage,onValidate,required]);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}}
|
|
104
104
|
|
|
105
|
-
const SingleSelect=props=>{const selectedIndex=React__namespace.useRef(0);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};React__namespace.useEffect(()=>{const optionItems=React__namespace.Children.toArray(children);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}},[selectedValue,children]);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,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,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{someResults}=labels;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someResults(items.length));}},[items.length,someResults,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{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,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
|
|
105
|
+
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={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};React__namespace.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}const optionItems=React__namespace.Children.toArray(children);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}},[selectedValue,children]);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,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,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{someResults}=labels;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someResults(items.length));}},[items.length,someResults,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{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,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
|
|
106
106
|
|
|
107
|
-
const MultiSelect=props=>{const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React__namespace.useMemo(()=>{return {...defaultLabels,...propLabels}},[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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};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]);React__namespace.useEffect(()=>{const optionItems=React__namespace.Children.toArray(children);const openerContent=getMenuTextOrNode(optionItems);const openerStringValue=maybeGetOpenerStringValue(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}},[children,getMenuTextOrNode,maybeGetOpenerStringValue]);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,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;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;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someSelected(filteredItems.length));}},[filteredItems.length,someSelected,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{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},"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:isDisabled})})};
|
|
107
|
+
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-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React__namespace.useMemo(()=>{return {...defaultLabels,...propLabels}},[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){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);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});};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]);React__namespace.useEffect(()=>{if(isInitialRender.current){isInitialRender.current=false;return}const optionItems=React__namespace.Children.toArray(children);const openerContent=getMenuTextOrNode(optionItems);const openerStringValue=maybeGetOpenerStringValue(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}},[children,getMenuTextOrNode,maybeGetOpenerStringValue]);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,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-required":computedRequired,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;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;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someSelected(filteredItems.length));}},[filteredItems.length,someSelected,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{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},"aria-invalid":ariaInvalid,"aria-required":computedRequired,disabled:isDisabled})})};
|
|
108
108
|
|
|
109
109
|
function updateMultipleSelection(previousSelection,value=""){if(!previousSelection){return [value]}return previousSelection.includes(value)?previousSelection.filter(item=>item!==value):[...previousSelection,value]}
|
|
110
110
|
|
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.4",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Dropdown variants for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,15 +21,15 @@
|
|
|
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.0.1",
|
|
25
25
|
"@khanacademy/wonder-blocks-clickable": "8.0.0",
|
|
26
|
-
"@khanacademy/wonder-blocks-
|
|
27
|
-
"@khanacademy/wonder-blocks-form": "7.3.9",
|
|
26
|
+
"@khanacademy/wonder-blocks-form": "7.4.0",
|
|
28
27
|
"@khanacademy/wonder-blocks-icon": "5.2.20",
|
|
28
|
+
"@khanacademy/wonder-blocks-core": "12.4.0",
|
|
29
29
|
"@khanacademy/wonder-blocks-icon-button": "10.5.2",
|
|
30
|
-
"@khanacademy/wonder-blocks-modal": "8.4.
|
|
30
|
+
"@khanacademy/wonder-blocks-modal": "8.4.5",
|
|
31
31
|
"@khanacademy/wonder-blocks-pill": "3.1.42",
|
|
32
|
-
"@khanacademy/wonder-blocks-search-field": "5.1.
|
|
32
|
+
"@khanacademy/wonder-blocks-search-field": "5.1.48",
|
|
33
33
|
"@khanacademy/wonder-blocks-styles": "0.2.32",
|
|
34
34
|
"@khanacademy/wonder-blocks-timing": "7.0.2",
|
|
35
35
|
"@khanacademy/wonder-blocks-tokens": "14.0.0",
|