@contentful/f36-multiselect 4.20.11 → 4.20.12

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/README.mdx CHANGED
@@ -5,7 +5,7 @@ status: 'alpha'
5
5
  section: 'formComponents'
6
6
  slug: /components/multiselect/
7
7
  github: 'https://github.com/contentful/forma-36/tree/main/packages/components/Multiselect'
8
- storybook: 'https://v4-f36-storybook.netlify.app/?path=/story/components-multiselect--basic'
8
+ storybook: 'https://f36-storybook.contentful.com/?path=/story/components-multiselect--basic'
9
9
  typescript: ./Multiselect.tsx,./MultiselectOption.tsx
10
10
  ---
11
11
 
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import e, { useState, useRef, useCallback, useMemo } from 'react';
1
+ import o, { useState, useRef, useCallback, useMemo } from 'react';
2
2
  import { Checkbox, TextInput } from '@contentful/f36-forms';
3
3
  import { Text, Subheading } from '@contentful/f36-typography';
4
4
  import { cx, css } from 'emotion';
@@ -9,8 +9,10 @@ import { Button, IconButton } from '@contentful/f36-button';
9
9
  import { ChevronDownIcon, CloseIcon, SearchIcon } from '@contentful/f36-icons';
10
10
  import { SkeletonContainer, SkeletonBodyText } from '@contentful/f36-skeleton';
11
11
  import { Popover } from '@contentful/f36-popover';
12
+ import Pe from 'react-focus-lock';
12
13
 
13
- var ce=Object.defineProperty,pe=Object.defineProperties;var ue=Object.getOwnPropertyDescriptors;var C=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var F=(t,l,o)=>l in t?ce(t,l,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[l]=o,h=(t,l)=>{for(var o in l||(l={}))W.call(l,o)&&F(t,o,l[o]);if(C)for(var o of C(l))j.call(l,o)&&F(t,o,l[o]);return t},U=(t,l)=>pe(t,ue(l));var P=(t,l)=>{var o={};for(var n in t)W.call(t,n)&&l.indexOf(n)<0&&(o[n]=t[n]);if(t!=null&&C)for(var n of C(t))l.indexOf(n)<0&&j.call(t,n)&&(o[n]=t[n]);return o};var M=()=>({multiselect:css({position:"relative",width:"100%"}),triggerButton:css({justifyContent:"space-between"}),currentSelection:css({width:"50%",whiteSpace:"nowrap",textOverflow:"ellipsis",overflow:"hidden",verticalAlign:"bottom",marginRight:r.spacing2Xs}),currentSelectionAddition:css({color:r.gray600}),inputField:css({paddingRight:r.spacingXl,textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",borderRadius:"0px",borderBottom:`1px solid ${r.gray200}`}),toggleButton:css({position:"absolute",top:"1px",right:"1px",zIndex:r.zIndexDefault,padding:r.spacing2Xs,height:r.spacingXl}),content:t=>css({overflow:"auto",maxHeight:`${t}px`}),list:css({listStyle:"none",padding:`${r.spacingXs} 0`,margin:0}),groupTitle:css({padding:`${r.spacingXs} ${r.spacingM}`,lineHeight:r.lineHeightM}),noMatchesTitle:css({color:r.gray500,margin:r.spacingM}),selectAll:css({"label > *":{fontWeight:"bold"}}),item:css({label:{padding:`${r.spacingXs} ${r.spacingM}`,wordBreak:"break-word",whiteSpace:"break-spaces",hyphens:"auto",display:"flex",flexDirection:"row",alignItems:"center",cursor:"pointer","&:focus, &:hover":{backgroundColor:r.gray100},"&:active":{backgroundColor:r.gray200},"&:focus":{boxShadow:r.glowPrimary},"&:focus:not(:focus-visible)":{boxShadow:"unset"},"&:focus-visible":{boxShadow:r.glowPrimary}}}),disabled:css({opacity:.5,cursor:"not-allowed"})});var d=H=>{var x=H,{label:t,value:l,itemId:o,onSelectItem:n,searchValue:p,isChecked:u=!1,isDisabled:c=!1,className:S}=x,v=P(x,["label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className"]);let y=M();return e.createElement("li",h({className:S},v),e.createElement(Checkbox,{id:o,value:l,onChange:b=>n(b),isChecked:u,isDisabled:c,className:cx(y.item,c&&y.disabled)},e.createElement(Text,{"data-test-id":`cf-multiselect-list-item-${o}`},e.createElement(_,{item:t,inputValue:p}))))};function _({item:t,inputValue:l=""}){let{before:o,match:n,after:p}=getStringMatch(t,l);return e.createElement(e.Fragment,null,o,e.createElement("b",{"data-test-id":"cf-multiselect-item-match"},n),p)}_.displayName="HighlightedItem";var Q=(t,l,o)=>e.Children.map(t,n=>{if(!e.isValidElement(n))return n;if(l(n))return o(n);let p=Q(n.props.children,l,o);return e.cloneElement(n,{children:p})}),Y=(t,l)=>{let o=0;return e.Children.forEach(t,n=>{!e.isValidElement(n)||(l(n)?o+=1:o+=Y(n.props.children,l));}),o};function Pe(t,l){let{className:o,startIcon:n,placeholder:p="Select one or more Items",currentSelection:u=[],onSearchValueChange:c,searchPlaceholder:S="Search",searchInputRef:v,searchInputName:H,noMatchesMessage:x="No matches found",toggleRef:y,isLoading:b=!1,testId:ee="cf-multiselect",popoverProps:N={},children:I,onBlur:E}=t,{listMaxHeight:te=180,listRef:oe}=N,a=M(),[m,R]=useState(""),[B,V]=useState(!1),L=useRef(null),D=useRef(null),$=typeof c=="function",O=useCallback(()=>{var i;(i=D.current)==null||i.focus();},[]),le=useCallback(i=>{R(i.target.value),c==null||c(i);},[c,R]),ne=useCallback(()=>{if(!m)return;O(),Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set.call(L.current,"");let f=new Event("change",{bubbles:!0});L.current.dispatchEvent(f);},[m,O]),re=useCallback(()=>{if(u.length===0)return e.createElement(e.Fragment,null,p);let i=u.length-1;return i===0?e.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:a.currentSelection},u[0]):e.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:a.currentSelection},u[0]," ",e.createElement("span",{className:a.currentSelectionAddition},"and ",i," more"))},[u,p,a.currentSelection,a.currentSelectionAddition]),X=useMemo(()=>Y(I,i=>i.type===d),[I]),ie=e.useCallback(i=>Q(i,f=>f.type===d,f=>{let se=ae=>{var z;O(),(z=f.props)==null||z.onSelectItem(ae);};return e.cloneElement(f,{searchValue:m,onSelectItem:se})}),[m,O]);return e.createElement("div",{"data-test-id":ee,className:cx(a.multiselect,o),ref:l},e.createElement(Popover,U(h({renderOnlyWhenOpen:!1,isFullWidth:!0},N),{isOpen:B,onClose:()=>V(!1)}),e.createElement(Popover.Trigger,null,e.createElement(Button,{"aria-label":"Toggle Multiselect",ref:y,onClick:()=>V(!B),startIcon:n,endIcon:e.createElement(ChevronDownIcon,null),isFullWidth:!0,className:a.triggerButton},re())),e.createElement(Popover.Content,{ref:mergeRefs(oe,D),className:cx(a.content(te),N.className),testId:"cf-multiselect-container",onBlur:()=>E==null?void 0:E()},e.createElement(e.Fragment,null,$&&e.createElement(e.Fragment,null,e.createElement(TextInput,{"aria-label":"Search",type:"text",value:m,className:a.inputField,testId:"cf-multiselect-search",placeholder:S,onChange:le,ref:mergeRefs(v,L),name:H,size:"small"}),e.createElement(IconButton,{"aria-label":m?"Clear search":"Search",className:a.toggleButton,variant:"transparent",icon:m?e.createElement(CloseIcon,{variant:"muted"}):e.createElement(SearchIcon,{variant:"muted"}),onClick:ne,isDisabled:!m,size:"small"})),b&&e.createElement(we,null),!b&&X>0&&e.createElement("ul",{className:a.list,"data-test-id":"cf-multiselect-items"},$?ie(I):I),!b&&X===0&&e.createElement(Subheading,{className:a.noMatchesTitle},x)))))}var we=()=>e.createElement(SkeletonContainer,{svgHeight:16},e.createElement(SkeletonBodyText,{numberOfLines:1})),Z=e.forwardRef(Pe);var k=u=>{var c=u,{label:t,onSelectItem:l,isChecked:o=!1,className:n}=c,p=P(c,["label","onSelectItem","isChecked","className"]);let S=M();return e.createElement(d,h({value:"all",label:t||o?"Deselect all":"Select all",itemId:"SelectAll",onSelectItem:l,isChecked:o,className:cx(S.selectAll,n)},p))};var A=Z;A.Option=d;A.SelectAll=k;
14
+ var pe=Object.defineProperty,ue=Object.defineProperties;var me=Object.getOwnPropertyDescriptors;var C=Object.getOwnPropertySymbols;var F=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var W=(e,n,t)=>n in e?pe(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,h=(e,n)=>{for(var t in n||(n={}))F.call(n,t)&&W(e,t,n[t]);if(C)for(var t of C(n))j.call(n,t)&&W(e,t,n[t]);return e},U=(e,n)=>ue(e,me(n));var P=(e,n)=>{var t={};for(var l in e)F.call(e,l)&&n.indexOf(l)<0&&(t[l]=e[l]);if(e!=null&&C)for(var l of C(e))n.indexOf(l)<0&&j.call(e,l)&&(t[l]=e[l]);return t};var S=()=>({multiselect:css({position:"relative",width:"100%"}),triggerButton:css({justifyContent:"space-between"}),currentSelection:css({width:"50%",whiteSpace:"nowrap",textOverflow:"ellipsis",overflow:"hidden",verticalAlign:"bottom",marginRight:r.spacing2Xs}),currentSelectionAddition:css({color:r.gray600}),searchBar:css({paddingTop:r.spacing2Xs,position:"sticky",top:"0px",zIndex:"10",backgroundColor:r.colorWhite}),inputField:css({padding:`6px ${r.spacingXl} 10px ${r.spacingXs}`,textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",borderRadius:"0px",borderBottom:`1px solid ${r.gray200}`,boxShadow:"none","&:focus, &:active, &:active:hover":{boxShadow:"none",borderBottom:`1px solid ${r.gray200}`}}),toggleButton:css({position:"absolute",top:"1px",right:"1px",zIndex:r.zIndexDefault,padding:r.spacing2Xs,height:r.spacingXl}),content:e=>css({overflow:"auto",maxHeight:`${e}px`}),container:css({}),list:css({listStyle:"none",padding:`${r.spacing2Xs}`,margin:0}),groupTitle:css({padding:`6px ${r.spacingXs}`,lineHeight:r.lineHeightM}),noMatchesTitle:css({color:r.gray500,margin:r.spacingM}),selectAll:css({borderBottom:`1px solid ${r.gray200}`,marginBottom:r.spacing2Xs,paddingBottom:r.spacing2Xs,"label > *":{fontWeight:"500"}}),option:css({listStyleType:"none"}),item:css({label:{padding:`6px ${r.spacingXs}`,width:"100%",wordBreak:"break-word",whiteSpace:"break-spaces",hyphens:"auto",display:"flex",flexDirection:"row",alignItems:"center",borderRadius:r.borderRadiusMedium,border:0,cursor:"pointer",fontSize:r.fontSizeM,lineHeight:r.lineHeightM,fontWeight:r.fontWeightNormal,"&:focus, &:hover":{backgroundColor:r.gray100},"&:active":{backgroundColor:r.gray200},"&:focus":{boxShadow:r.glowPrimary},"&:focus:not(:focus-visible)":{boxShadow:"unset"},"&:focus-visible":{boxShadow:r.glowPrimary}}}),disabled:css({opacity:.5,cursor:"not-allowed"})});var d=H=>{var y=H,{label:e,value:n,itemId:t,onSelectItem:l,searchValue:p,isChecked:u=!1,isDisabled:c=!1,className:b}=y,x=P(y,["label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className"]);let M=S();return o.createElement("li",h({className:cx(M.option,b)},x),o.createElement(Checkbox,{id:t,value:n,onChange:v=>l(v),isChecked:u,isDisabled:c,className:cx(M.item,c&&M.disabled)},o.createElement(Text,{"data-test-id":`cf-multiselect-list-item-${t}`},o.createElement(q,{item:e,inputValue:p}))))};function q({item:e,inputValue:n=""}){let{before:t,match:l,after:p}=getStringMatch(e,n);return o.createElement(o.Fragment,null,t,o.createElement("b",{"data-test-id":"cf-multiselect-item-match"},l),p)}q.displayName="HighlightedItem";var Y=(e,n,t)=>o.Children.map(e,l=>{if(!o.isValidElement(l))return l;if(n(l))return t(l);let p=Y(l.props.children,n,t);return o.cloneElement(l,{children:p})}),Z=(e,n)=>{let t=0;return o.Children.forEach(e,l=>{o.isValidElement(l)&&(n(l)?t+=1:t+=Z(l.props.children,n));}),t};function we(e,n){let{className:t,startIcon:l,placeholder:p="Select one or more Items",currentSelection:u=[],onSearchValueChange:c,searchPlaceholder:b="Search",searchInputRef:x,searchInputName:H,noMatchesMessage:y="No matches found",toggleRef:M,isLoading:v=!1,testId:te="cf-multiselect",popoverProps:N={},children:I,onBlur:E}=e,{listMaxHeight:oe=180,listRef:ne}=N,s=S(),[m,A]=useState(""),[B,X]=useState(!1),L=useRef(null),$=useRef(null),V=typeof c=="function",O=useCallback(()=>{var a;(a=$.current)==null||a.focus();},[]),le=useCallback(a=>{A(a.target.value),c==null||c(a);},[c,A]),re=useCallback(()=>{if(!m)return;O(),Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set.call(L.current,"");let f=new Event("change",{bubbles:!0});L.current.dispatchEvent(f);},[m,O]),ie=useCallback(()=>{if(u.length===0)return o.createElement(o.Fragment,null,p);let a=u.length-1;return a===0?o.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:s.currentSelection},u[0]):o.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:s.currentSelection},u[0]," ",o.createElement("span",{className:s.currentSelectionAddition},"and ",a," more"))},[u,p,s.currentSelection,s.currentSelectionAddition]),D=useMemo(()=>Z(I,a=>a.type===d),[I]),se=o.useCallback(a=>Y(a,f=>f.type===d,f=>{let ae=ce=>{var z;O(),(z=f.props)==null||z.onSelectItem(ce);};return o.cloneElement(f,{searchValue:m,onSelectItem:ae})}),[m,O]);return o.createElement("div",{"data-test-id":te,className:cx(s.multiselect,t),ref:n},o.createElement(Popover,U(h({renderOnlyWhenOpen:!1,isFullWidth:!0},N),{isOpen:B,onClose:()=>X(!1)}),o.createElement(Popover.Trigger,null,o.createElement(Button,{"aria-label":"Toggle Multiselect",ref:M,onClick:()=>X(!B),startIcon:l,endIcon:o.createElement(ChevronDownIcon,null),isFullWidth:!0,className:s.triggerButton},ie())),o.createElement(Popover.Content,{ref:mergeRefs(ne,$),className:cx(s.content(oe),N.className,s.container),testId:"cf-multiselect-container",onBlur:()=>E==null?void 0:E()},o.createElement(Pe,null,V&&o.createElement("div",{className:s.searchBar},o.createElement(TextInput,{"aria-label":"Search",type:"text",value:m,className:s.inputField,testId:"cf-multiselect-search",placeholder:b,onChange:le,ref:mergeRefs(x,L),name:H,size:"small"}),o.createElement(IconButton,{"aria-label":m?"Clear search":"Search",className:s.toggleButton,variant:"transparent",icon:m?o.createElement(CloseIcon,{variant:"muted"}):o.createElement(SearchIcon,{variant:"muted"}),onClick:re,isDisabled:!m,size:"small"})),v&&o.createElement(Ne,null),!v&&D>0&&o.createElement("ul",{className:s.list,"data-test-id":"cf-multiselect-items"},V?se(I):I),!v&&D===0&&o.createElement(Subheading,{className:s.noMatchesTitle},y)))))}var Ne=()=>o.createElement(SkeletonContainer,{svgHeight:16},o.createElement(SkeletonBodyText,{numberOfLines:1})),ee=o.forwardRef(we);var T=u=>{var c=u,{label:e,onSelectItem:n,isChecked:t=!1,className:l}=c,p=P(c,["label","onSelectItem","isChecked","className"]);let b=S();return o.createElement(d,h({value:"all",label:e||t?"Deselect all":"Select all",itemId:"SelectAll",onSelectItem:n,isChecked:t,className:cx(b.selectAll,l)},p))};var R=ee;R.Option=d;R.SelectAll=T;
14
15
 
15
- export { A as Multiselect, d as MultiselectOption, k as SelectAllOption };
16
+ export { R as Multiselect, d as MultiselectOption, T as SelectAllOption };
17
+ //# sourceMappingURL=out.js.map
16
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/MultiselectOption.tsx","../../src/Multiselect.styles.ts","../../src/Multiselect.tsx","../../src/SelectAllOption.tsx","../../src/CompoundMultiselect.tsx"],"names":["React","Checkbox","Text","css","tokens","getMultiselectStyles","listMaxHeight","getStringMatch","cx","MultiselectOption","_a","_b","label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className","rest","__objRest","styles","__spreadValues","event","HighlightedItem","item","inputValue","before","match","after","useRef","useState","useCallback","useMemo","mergeRefs","Button","IconButton","TextInput","CloseIcon","ChevronDownIcon","SearchIcon","SkeletonContainer","SkeletonBodyText","Popover","Subheading","iterateOverChildren","children","filter","callback","child","childChildren","countMatchingChildren","counter","_Multiselect","props","ref","startIcon","placeholder","currentSelection","onSearchValueChange","searchPlaceholder","searchInputRef","searchInputName","noMatchesMessage","toggleRef","isLoading","testId","popoverProps","onBlur","listRef","setSearchValue","isOpen","setIsOpen","internalSearchInputRef","internalListRef","hasSearch","focusList","handleSearchChange","resetSearchInput","forcedEvent","renderMultiselectLabel","leftoverCount","optionsLength","enrichOptions","__spreadProps","ListItemLoadingState","Multiselect","SelectAllOption","otherProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Checkbox } from '@contentful/f36-forms';\nimport { Text } from '@contentful/f36-typography';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { getStringMatch } from '@contentful/f36-utils';\nimport { cx } from 'emotion';\n\nexport interface MultiselectOptionProps {\n label: string;\n value: string;\n itemId: string;\n searchValue?: string;\n className?: string;\n onSelectItem: (event: React.ChangeEvent<HTMLInputElement>) => void;\n isChecked?: boolean;\n isDisabled?: boolean;\n}\n\nexport const MultiselectOption = ({\n label,\n value,\n itemId,\n onSelectItem,\n searchValue,\n isChecked = false,\n isDisabled = false,\n className,\n ...rest\n}: MultiselectOptionProps) => {\n const styles = getMultiselectStyles();\n\n return (\n <li className={className} {...rest}>\n <Checkbox\n id={itemId}\n value={value}\n onChange={(event) => onSelectItem(event)}\n isChecked={isChecked}\n isDisabled={isDisabled}\n className={cx(styles.item, isDisabled && styles.disabled)}\n >\n <Text data-test-id={`cf-multiselect-list-item-${itemId}`}>\n <HighlightedItem item={label} inputValue={searchValue} />\n </Text>\n </Checkbox>\n </li>\n );\n};\n\nfunction HighlightedItem({\n item,\n inputValue = '',\n}: {\n item: string;\n inputValue?: string;\n}) {\n const { before, match, after } = getStringMatch(item, inputValue);\n return (\n <>\n {before}\n <b data-test-id=\"cf-multiselect-item-match\">{match}</b>\n {after}\n </>\n );\n}\n\nHighlightedItem.displayName = 'HighlightedItem';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMultiselectStyles = () => ({\n multiselect: css({\n position: 'relative',\n width: '100%',\n }),\n triggerButton: css({\n justifyContent: 'space-between',\n }),\n currentSelection: css({\n width: '50%',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n verticalAlign: 'bottom',\n marginRight: tokens.spacing2Xs,\n }),\n currentSelectionAddition: css({\n color: tokens.gray600,\n }),\n inputField: css({\n paddingRight: tokens.spacingXl,\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n border: 'none',\n borderRadius: '0px',\n borderBottom: `1px solid ${tokens.gray200}`,\n }),\n toggleButton: css({\n position: 'absolute',\n top: '1px',\n right: '1px',\n zIndex: tokens.zIndexDefault,\n padding: tokens.spacing2Xs,\n height: tokens.spacingXl,\n }),\n content: (listMaxHeight: number) =>\n css({\n overflow: 'auto',\n maxHeight: `${listMaxHeight}px`,\n }),\n list: css({\n listStyle: 'none',\n padding: `${tokens.spacingXs} 0`,\n margin: 0,\n }),\n groupTitle: css({\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n lineHeight: tokens.lineHeightM,\n }),\n noMatchesTitle: css({\n color: tokens.gray500,\n margin: tokens.spacingM,\n }),\n selectAll: css({\n 'label > *': {\n fontWeight: 'bold',\n },\n }),\n item: css({\n label: {\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n hyphens: 'auto',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n cursor: 'pointer',\n '&:focus, &:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:focus': {\n boxShadow: tokens.glowPrimary,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n },\n '&:focus-visible': {\n boxShadow: tokens.glowPrimary,\n },\n },\n }),\n disabled: css({\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n});\n","import React, { useRef, useState, useCallback, useMemo } from 'react';\nimport { cx } from 'emotion';\n\nimport { mergeRefs, type CommonProps } from '@contentful/f36-core';\nimport { Button, IconButton } from '@contentful/f36-button';\nimport { TextInput } from '@contentful/f36-forms';\nimport { CloseIcon, ChevronDownIcon, SearchIcon } from '@contentful/f36-icons';\nimport { SkeletonContainer, SkeletonBodyText } from '@contentful/f36-skeleton';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\nimport { Subheading } from '@contentful/f36-typography';\n\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\n\nexport interface MultiselectProps extends CommonProps {\n /** Select Options */\n children?: React.ReactNode;\n\n /**\n * Set a custom icon for the text input\n */\n startIcon?: React.ReactElement;\n\n /**\n * Placeholder shown before selecting any elements. Defaults to 'Select one or more items'\n */\n placeholder?: string;\n\n /**\n * current Selected items, to be shown on the trigger button\n */\n currentSelection?: Array<string>;\n\n /**\n * Function called whenever the search input value changes\n */\n onSearchValueChange?: (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => void | undefined;\n\n /**\n * This is the value will be passed to the `placeholder` prop of the input.\n * @default \"Search\"\n */\n searchPlaceholder?: string;\n\n /**\n * A message that will be shown when it is not possible to find any option that matches the input value\n * @default \"No matches\"\n */\n noMatchesMessage?: string;\n\n /**\n * Use this prop to get a ref to the input element of the component\n */\n searchInputRef?: React.Ref<HTMLInputElement>;\n\n /**\n * Pass a form name to the search text input\n */\n searchInputName?: string;\n\n /**\n * Sets the list to show its loading state\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Use this prop to get a ref to the toggle button of the component\n */\n toggleRef?: React.Ref<HTMLButtonElement>;\n\n /**\n * Props to pass to the Popover (Dropdown) component\n */\n popoverProps?: Partial<PopoverProps> & {\n /**\n * It sets the max-height, in pixels, of the list\n * The default value is the height of 5 single line items\n * @default 180\n */\n listMaxHeight?: number;\n\n /**\n * Use this prop to get a ref to the list of items of the component\n */\n listRef?: React.Ref<HTMLUListElement>;\n } & Pick<CommonProps, 'className'>;\n\n /**\n * Function called when the popover loses its focus.\n */\n onBlur?: () => void;\n}\n\n// Scan through the whole hierachy until `filter` returns true and apply `transform`\n// Inspired from https://stackoverflow.com/a/70676868/17269164\nconst iterateOverChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n callback: (child: React.ReactElement) => React.ReactElement | void,\n): React.ReactNode => {\n return React.Children.map(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return child;\n if (filter(child)) {\n return callback(child);\n }\n const childChildren = iterateOverChildren(\n child.props.children,\n filter,\n callback,\n );\n return React.cloneElement(child, { children: childChildren } as unknown);\n });\n};\n\n// Scan through the whole hierachy to count the number of children where `filter` returns true\nconst countMatchingChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n): number => {\n let counter = 0;\n React.Children.forEach(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return;\n if (!filter(child)) {\n counter += countMatchingChildren(child.props.children, filter);\n } else {\n counter += 1;\n }\n });\n return counter;\n};\n\nfunction _Multiselect(props: MultiselectProps, ref: React.Ref<HTMLDivElement>) {\n const {\n className,\n startIcon,\n placeholder = 'Select one or more Items',\n currentSelection = [],\n onSearchValueChange,\n searchPlaceholder = 'Search',\n searchInputRef,\n searchInputName,\n noMatchesMessage = 'No matches found',\n toggleRef,\n isLoading = false,\n testId = 'cf-multiselect',\n popoverProps = {},\n children,\n onBlur,\n } = props;\n\n const { listMaxHeight = 180, listRef } = popoverProps;\n\n const styles = getMultiselectStyles();\n\n const [searchValue, setSearchValue] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const internalSearchInputRef = useRef<HTMLInputElement>(null);\n const internalListRef = useRef<HTMLUListElement>(null);\n\n const hasSearch = typeof onSearchValueChange === 'function';\n\n const focusList = useCallback(() => {\n // Clearing the search input or selecting an item triggers a rerendering and\n // thereby the client loses the focus on the clicked element. To avoid having\n // the focus on the document body (which breaks `closeOnBlur`), we force it\n // back to the list in the popup.\n internalListRef.current?.focus();\n }, []);\n\n const handleSearchChange = useCallback(\n (event) => {\n setSearchValue(event.target.value);\n onSearchValueChange?.(event);\n },\n [onSearchValueChange, setSearchValue],\n );\n\n const resetSearchInput = useCallback(() => {\n if (!searchValue) return;\n focusList();\n // this looks a bit hacky, but is the official way of externally triggering the onChange handler for an input\n // https://stackoverflow.com/a/46012210/17269164\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value',\n ).set;\n nativeInputValueSetter.call(internalSearchInputRef.current, '');\n const forcedEvent = new Event('change', { bubbles: true });\n internalSearchInputRef.current.dispatchEvent(forcedEvent);\n }, [searchValue, focusList]);\n\n const renderMultiselectLabel = useCallback(() => {\n if (currentSelection.length === 0) {\n return <>{placeholder}</>;\n }\n const leftoverCount = currentSelection.length - 1;\n if (leftoverCount === 0) {\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}\n </span>\n );\n }\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}{' '}\n <span className={styles.currentSelectionAddition}>\n and {leftoverCount} more\n </span>\n </span>\n );\n }, [\n currentSelection,\n placeholder,\n styles.currentSelection,\n styles.currentSelectionAddition,\n ]);\n\n const optionsLength = useMemo(\n () =>\n countMatchingChildren(\n children,\n (child) => child.type === MultiselectOption,\n ),\n [children],\n );\n\n // clones and enriches the multiselect options\n const enrichOptions = React.useCallback(\n (children: React.ReactNode): React.ReactNode => {\n return iterateOverChildren(\n children,\n (child) => child.type === MultiselectOption,\n (child) => {\n const onSelectItem = (event: React.ChangeEvent<HTMLInputElement>) => {\n focusList();\n child.props?.onSelectItem(event);\n };\n return React.cloneElement(child, {\n searchValue,\n onSelectItem,\n } as Partial<MultiselectOptionProps>);\n },\n );\n },\n [searchValue, focusList],\n );\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles.multiselect, className)}\n ref={ref}\n >\n <Popover\n renderOnlyWhenOpen={false}\n isFullWidth\n {...popoverProps}\n // popoverProps should never overwrite the internal opening logic\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n >\n <Popover.Trigger>\n <Button\n aria-label=\"Toggle Multiselect\"\n ref={toggleRef}\n onClick={() => setIsOpen(!isOpen)}\n startIcon={startIcon}\n endIcon={<ChevronDownIcon />}\n isFullWidth\n className={styles.triggerButton}\n >\n {renderMultiselectLabel()}\n </Button>\n </Popover.Trigger>\n <Popover.Content\n ref={mergeRefs(listRef, internalListRef)}\n className={cx(styles.content(listMaxHeight), popoverProps.className)}\n testId=\"cf-multiselect-container\"\n onBlur={() => onBlur?.()}\n >\n <>\n {hasSearch && (\n <>\n <TextInput\n aria-label=\"Search\"\n type=\"text\"\n value={searchValue}\n className={styles.inputField}\n testId=\"cf-multiselect-search\"\n placeholder={searchPlaceholder}\n onChange={handleSearchChange}\n ref={mergeRefs(searchInputRef, internalSearchInputRef)}\n name={searchInputName}\n size=\"small\"\n />\n <IconButton\n aria-label={searchValue ? 'Clear search' : 'Search'}\n className={styles.toggleButton}\n variant=\"transparent\"\n icon={\n searchValue ? (\n <CloseIcon variant=\"muted\" />\n ) : (\n <SearchIcon variant=\"muted\" />\n )\n }\n onClick={resetSearchInput}\n isDisabled={!searchValue}\n size=\"small\"\n />\n </>\n )}\n {isLoading && <ListItemLoadingState />}\n\n {!isLoading && optionsLength > 0 && (\n <ul className={styles.list} data-test-id=\"cf-multiselect-items\">\n {hasSearch ? enrichOptions(children) : children}\n </ul>\n )}\n\n {!isLoading && optionsLength === 0 && (\n <Subheading className={styles.noMatchesTitle}>\n {noMatchesMessage}\n </Subheading>\n )}\n </>\n </Popover.Content>\n </Popover>\n </div>\n );\n}\n\nconst ListItemLoadingState = () => {\n return (\n <SkeletonContainer svgHeight={16}>\n <SkeletonBodyText numberOfLines={1} />\n </SkeletonContainer>\n );\n};\n\n/**\n * The Multiselect is a component that will allow a user to select multiple items.\n * It has an optional\n */\nexport const Multiselect = React.forwardRef(_Multiselect);\n","import React from 'react';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { cx } from 'emotion';\n\nexport interface SelectAllOptionProps\n extends Omit<MultiselectOptionProps, 'value' | 'itemId' | 'label'> {\n label?: string;\n}\n\nexport const SelectAllOption = ({\n label,\n onSelectItem,\n isChecked = false,\n className,\n ...otherProps\n}: SelectAllOptionProps) => {\n const styles = getMultiselectStyles();\n const displayLabel = label || isChecked ? 'Deselect all' : 'Select all';\n return (\n <MultiselectOption\n value=\"all\"\n label={displayLabel}\n itemId=\"SelectAll\"\n onSelectItem={onSelectItem}\n isChecked={isChecked}\n className={cx(styles.selectAll, className)}\n {...otherProps}\n />\n );\n};\n","import { Multiselect as OriginalMultiSelect } from './Multiselect';\nimport { MultiselectOption } from './MultiselectOption';\nimport { SelectAllOption } from './SelectAllOption';\n\ntype CompoundMultiselect = typeof OriginalMultiSelect & {\n Option: typeof MultiselectOption;\n SelectAll: typeof SelectAllOption;\n};\n\nexport const Multiselect = OriginalMultiSelect as CompoundMultiselect;\nMultiselect.Option = MultiselectOption;\nMultiselect.SelectAll = SelectAllOption;\n"]}
1
+ {"version":3,"sources":["../../src/MultiselectOption.tsx","../../src/Multiselect.styles.ts","../../src/Multiselect.tsx","../../src/SelectAllOption.tsx","../../src/CompoundMultiselect.tsx"],"names":["React","Checkbox","Text","css","tokens","getMultiselectStyles","listMaxHeight","getStringMatch","cx","MultiselectOption","_a","_b","label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className","rest","__objRest","styles","__spreadValues","event","HighlightedItem","item","inputValue","before","match","after","useRef","useState","useCallback","useMemo","mergeRefs","Button","IconButton","TextInput","CloseIcon","ChevronDownIcon","SearchIcon","SkeletonContainer","SkeletonBodyText","Popover","Subheading","FocusLock","iterateOverChildren","children","filter","callback","child","childChildren","countMatchingChildren","counter","_Multiselect","props","ref","startIcon","placeholder","currentSelection","onSearchValueChange","searchPlaceholder","searchInputRef","searchInputName","noMatchesMessage","toggleRef","isLoading","testId","popoverProps","onBlur","listRef","setSearchValue","isOpen","setIsOpen","internalSearchInputRef","internalListRef","hasSearch","focusList","handleSearchChange","resetSearchInput","forcedEvent","renderMultiselectLabel","leftoverCount","optionsLength","enrichOptions","__spreadProps","ListItemLoadingState","Multiselect","SelectAllOption","otherProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Checkbox } from '@contentful/f36-forms';\nimport { Text } from '@contentful/f36-typography';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { getStringMatch } from '@contentful/f36-utils';\nimport { cx } from 'emotion';\n\nexport interface MultiselectOptionProps {\n label: string;\n value: string;\n itemId: string;\n searchValue?: string;\n className?: string;\n onSelectItem: (event: React.ChangeEvent<HTMLInputElement>) => void;\n isChecked?: boolean;\n isDisabled?: boolean;\n}\n\nexport const MultiselectOption = ({\n label,\n value,\n itemId,\n onSelectItem,\n searchValue,\n isChecked = false,\n isDisabled = false,\n className,\n ...rest\n}: MultiselectOptionProps) => {\n const styles = getMultiselectStyles();\n\n return (\n <li className={cx(styles.option, className)} {...rest}>\n <Checkbox\n id={itemId}\n value={value}\n onChange={(event) => onSelectItem(event)}\n isChecked={isChecked}\n isDisabled={isDisabled}\n className={cx(styles.item, isDisabled && styles.disabled)}\n >\n <Text data-test-id={`cf-multiselect-list-item-${itemId}`}>\n <HighlightedItem item={label} inputValue={searchValue} />\n </Text>\n </Checkbox>\n </li>\n );\n};\n\nfunction HighlightedItem({\n item,\n inputValue = '',\n}: {\n item: string;\n inputValue?: string;\n}) {\n const { before, match, after } = getStringMatch(item, inputValue);\n return (\n <>\n {before}\n <b data-test-id=\"cf-multiselect-item-match\">{match}</b>\n {after}\n </>\n );\n}\n\nHighlightedItem.displayName = 'HighlightedItem';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMultiselectStyles = () => ({\n multiselect: css({\n position: 'relative',\n width: '100%',\n }),\n triggerButton: css({\n justifyContent: 'space-between',\n }),\n currentSelection: css({\n width: '50%',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n verticalAlign: 'bottom',\n marginRight: tokens.spacing2Xs,\n }),\n currentSelectionAddition: css({\n color: tokens.gray600,\n }),\n searchBar: css({\n paddingTop: tokens.spacing2Xs,\n position: 'sticky',\n top: '0px',\n zIndex: '10',\n backgroundColor: tokens.colorWhite,\n }),\n inputField: css({\n padding: `6px ${tokens.spacingXl} 10px ${tokens.spacingXs}`,\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n border: 'none',\n borderRadius: '0px',\n borderBottom: `1px solid ${tokens.gray200}`,\n boxShadow: 'none',\n '&:focus, &:active, &:active:hover': {\n boxShadow: 'none',\n borderBottom: `1px solid ${tokens.gray200}`,\n },\n }),\n toggleButton: css({\n position: 'absolute',\n top: '1px',\n right: '1px',\n zIndex: tokens.zIndexDefault,\n padding: tokens.spacing2Xs,\n height: tokens.spacingXl,\n }),\n content: (listMaxHeight: number) =>\n css({\n overflow: 'auto',\n maxHeight: `${listMaxHeight}px`,\n }),\n container: css({}),\n list: css({\n listStyle: 'none',\n padding: `${tokens.spacing2Xs}`,\n margin: 0,\n }),\n groupTitle: css({\n // Magic number to get a height of 32px on the item\n padding: `6px ${tokens.spacingXs}`,\n lineHeight: tokens.lineHeightM,\n }),\n noMatchesTitle: css({\n color: tokens.gray500,\n margin: tokens.spacingM,\n }),\n selectAll: css({\n borderBottom: `1px solid ${tokens.gray200}`,\n marginBottom: tokens.spacing2Xs,\n paddingBottom: tokens.spacing2Xs,\n 'label > *': {\n fontWeight: '500',\n },\n }),\n option: css({\n listStyleType: 'none',\n }),\n item: css({\n label: {\n // Magic number to get a height of 32px on the item\n padding: `6px ${tokens.spacingXs}`,\n width: '100%',\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n hyphens: 'auto',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: tokens.borderRadiusMedium,\n border: 0,\n cursor: 'pointer',\n fontSize: tokens.fontSizeM,\n lineHeight: tokens.lineHeightM,\n fontWeight: tokens.fontWeightNormal,\n '&:focus, &:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:focus': {\n boxShadow: tokens.glowPrimary,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n },\n '&:focus-visible': {\n boxShadow: tokens.glowPrimary,\n },\n },\n }),\n disabled: css({\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n});\n","import React, { useRef, useState, useCallback, useMemo } from 'react';\nimport { cx } from 'emotion';\n\nimport { mergeRefs, type CommonProps } from '@contentful/f36-core';\nimport { Button, IconButton } from '@contentful/f36-button';\nimport { TextInput } from '@contentful/f36-forms';\nimport { CloseIcon, ChevronDownIcon, SearchIcon } from '@contentful/f36-icons';\nimport { SkeletonContainer, SkeletonBodyText } from '@contentful/f36-skeleton';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\nimport { Subheading } from '@contentful/f36-typography';\n\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport FocusLock from 'react-focus-lock';\n\nexport interface MultiselectProps extends CommonProps {\n /** Select Options */\n children?: React.ReactNode;\n\n /**\n * Set a custom icon for the text input\n */\n startIcon?: React.ReactElement;\n\n /**\n * Placeholder shown before selecting any elements. Defaults to 'Select one or more items'\n */\n placeholder?: string;\n\n /**\n * current Selected items, to be shown on the trigger button\n */\n currentSelection?: Array<string>;\n\n /**\n * Function called whenever the search input value changes\n */\n onSearchValueChange?: (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => void | undefined;\n\n /**\n * This is the value will be passed to the `placeholder` prop of the input.\n * @default \"Search\"\n */\n searchPlaceholder?: string;\n\n /**\n * A message that will be shown when it is not possible to find any option that matches the input value\n * @default \"No matches\"\n */\n noMatchesMessage?: string;\n\n /**\n * Use this prop to get a ref to the input element of the component\n */\n searchInputRef?: React.Ref<HTMLInputElement>;\n\n /**\n * Pass a form name to the search text input\n */\n searchInputName?: string;\n\n /**\n * Sets the list to show its loading state\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Use this prop to get a ref to the toggle button of the component\n */\n toggleRef?: React.Ref<HTMLButtonElement>;\n\n /**\n * Props to pass to the Popover (Dropdown) component\n */\n popoverProps?: Partial<PopoverProps> & {\n /**\n * It sets the max-height, in pixels, of the list\n * The default value is the height of 5 single line items\n * @default 180\n */\n listMaxHeight?: number;\n\n /**\n * Use this prop to get a ref to the list of items of the component\n */\n listRef?: React.Ref<HTMLUListElement>;\n } & Pick<CommonProps, 'className'>;\n\n /**\n * Function called when the popover loses its focus.\n */\n onBlur?: () => void;\n}\n\n// Scan through the whole hierachy until `filter` returns true and apply `transform`\n// Inspired from https://stackoverflow.com/a/70676868/17269164\nconst iterateOverChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n callback: (child: React.ReactElement) => React.ReactElement | void,\n): React.ReactNode => {\n return React.Children.map(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return child;\n if (filter(child)) {\n return callback(child);\n }\n const childChildren = iterateOverChildren(\n child.props.children,\n filter,\n callback,\n );\n return React.cloneElement(child, { children: childChildren } as unknown);\n });\n};\n\n// Scan through the whole hierachy to count the number of children where `filter` returns true\nconst countMatchingChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n): number => {\n let counter = 0;\n React.Children.forEach(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return;\n if (!filter(child)) {\n counter += countMatchingChildren(child.props.children, filter);\n } else {\n counter += 1;\n }\n });\n return counter;\n};\n\nfunction _Multiselect(props: MultiselectProps, ref: React.Ref<HTMLDivElement>) {\n const {\n className,\n startIcon,\n placeholder = 'Select one or more Items',\n currentSelection = [],\n onSearchValueChange,\n searchPlaceholder = 'Search',\n searchInputRef,\n searchInputName,\n noMatchesMessage = 'No matches found',\n toggleRef,\n isLoading = false,\n testId = 'cf-multiselect',\n popoverProps = {},\n children,\n onBlur,\n } = props;\n\n const { listMaxHeight = 180, listRef } = popoverProps;\n\n const styles = getMultiselectStyles();\n\n const [searchValue, setSearchValue] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const internalSearchInputRef = useRef<HTMLInputElement>(null);\n const internalListRef = useRef<HTMLUListElement>(null);\n\n const hasSearch = typeof onSearchValueChange === 'function';\n\n const focusList = useCallback(() => {\n // Clearing the search input or selecting an item triggers a rerendering and\n // thereby the client loses the focus on the clicked element. To avoid having\n // the focus on the document body (which breaks `closeOnBlur`), we force it\n // back to the list in the popup.\n internalListRef.current?.focus();\n }, []);\n\n const handleSearchChange = useCallback(\n (event) => {\n setSearchValue(event.target.value);\n onSearchValueChange?.(event);\n },\n [onSearchValueChange, setSearchValue],\n );\n\n const resetSearchInput = useCallback(() => {\n if (!searchValue) return;\n focusList();\n // this looks a bit hacky, but is the official way of externally triggering the onChange handler for an input\n // https://stackoverflow.com/a/46012210/17269164\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value',\n ).set;\n nativeInputValueSetter.call(internalSearchInputRef.current, '');\n const forcedEvent = new Event('change', { bubbles: true });\n internalSearchInputRef.current.dispatchEvent(forcedEvent);\n }, [searchValue, focusList]);\n\n const renderMultiselectLabel = useCallback(() => {\n if (currentSelection.length === 0) {\n return <>{placeholder}</>;\n }\n const leftoverCount = currentSelection.length - 1;\n if (leftoverCount === 0) {\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}\n </span>\n );\n }\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}{' '}\n <span className={styles.currentSelectionAddition}>\n and {leftoverCount} more\n </span>\n </span>\n );\n }, [\n currentSelection,\n placeholder,\n styles.currentSelection,\n styles.currentSelectionAddition,\n ]);\n\n const optionsLength = useMemo(\n () =>\n countMatchingChildren(\n children,\n (child) => child.type === MultiselectOption,\n ),\n [children],\n );\n\n // clones and enriches the multiselect options\n const enrichOptions = React.useCallback(\n (children: React.ReactNode): React.ReactNode => {\n return iterateOverChildren(\n children,\n (child) => child.type === MultiselectOption,\n (child) => {\n const onSelectItem = (event: React.ChangeEvent<HTMLInputElement>) => {\n focusList();\n child.props?.onSelectItem(event);\n };\n return React.cloneElement(child, {\n searchValue,\n onSelectItem,\n } as Partial<MultiselectOptionProps>);\n },\n );\n },\n [searchValue, focusList],\n );\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles.multiselect, className)}\n ref={ref}\n >\n <Popover\n renderOnlyWhenOpen={false}\n isFullWidth\n {...popoverProps}\n // popoverProps should never overwrite the internal opening logic\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n >\n <Popover.Trigger>\n <Button\n aria-label=\"Toggle Multiselect\"\n ref={toggleRef}\n onClick={() => setIsOpen(!isOpen)}\n startIcon={startIcon}\n endIcon={<ChevronDownIcon />}\n isFullWidth\n className={styles.triggerButton}\n >\n {renderMultiselectLabel()}\n </Button>\n </Popover.Trigger>\n <Popover.Content\n ref={mergeRefs(listRef, internalListRef)}\n className={cx(\n styles.content(listMaxHeight),\n popoverProps.className,\n styles.container,\n )}\n testId=\"cf-multiselect-container\"\n onBlur={() => onBlur?.()}\n >\n <FocusLock>\n {hasSearch && (\n <div className={styles.searchBar}>\n <TextInput\n aria-label=\"Search\"\n type=\"text\"\n value={searchValue}\n className={styles.inputField}\n testId=\"cf-multiselect-search\"\n placeholder={searchPlaceholder}\n onChange={handleSearchChange}\n ref={mergeRefs(searchInputRef, internalSearchInputRef)}\n name={searchInputName}\n size=\"small\"\n />\n <IconButton\n aria-label={searchValue ? 'Clear search' : 'Search'}\n className={styles.toggleButton}\n variant=\"transparent\"\n icon={\n searchValue ? (\n <CloseIcon variant=\"muted\" />\n ) : (\n <SearchIcon variant=\"muted\" />\n )\n }\n onClick={resetSearchInput}\n isDisabled={!searchValue}\n size=\"small\"\n />\n </div>\n )}\n {isLoading && <ListItemLoadingState />}\n\n {!isLoading && optionsLength > 0 && (\n <ul className={styles.list} data-test-id=\"cf-multiselect-items\">\n {hasSearch ? enrichOptions(children) : children}\n </ul>\n )}\n\n {!isLoading && optionsLength === 0 && (\n <Subheading className={styles.noMatchesTitle}>\n {noMatchesMessage}\n </Subheading>\n )}\n </FocusLock>\n </Popover.Content>\n </Popover>\n </div>\n );\n}\n\nconst ListItemLoadingState = () => {\n return (\n <SkeletonContainer svgHeight={16}>\n <SkeletonBodyText numberOfLines={1} />\n </SkeletonContainer>\n );\n};\n\n/**\n * The Multiselect is a component that will allow a user to select multiple items.\n * It has an optional\n */\nexport const Multiselect = React.forwardRef(_Multiselect);\n","import React from 'react';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { cx } from 'emotion';\n\nexport interface SelectAllOptionProps\n extends Omit<MultiselectOptionProps, 'value' | 'itemId' | 'label'> {\n label?: string;\n}\n\nexport const SelectAllOption = ({\n label,\n onSelectItem,\n isChecked = false,\n className,\n ...otherProps\n}: SelectAllOptionProps) => {\n const styles = getMultiselectStyles();\n const displayLabel = label || isChecked ? 'Deselect all' : 'Select all';\n return (\n <MultiselectOption\n value=\"all\"\n label={displayLabel}\n itemId=\"SelectAll\"\n onSelectItem={onSelectItem}\n isChecked={isChecked}\n className={cx(styles.selectAll, className)}\n {...otherProps}\n />\n );\n};\n","import { Multiselect as OriginalMultiSelect } from './Multiselect';\nimport { MultiselectOption } from './MultiselectOption';\nimport { SelectAllOption } from './SelectAllOption';\n\ntype CompoundMultiselect = typeof OriginalMultiSelect & {\n Option: typeof MultiselectOption;\n SelectAll: typeof SelectAllOption;\n};\n\nexport const Multiselect = OriginalMultiSelect as CompoundMultiselect;\nMultiselect.Option = MultiselectOption;\nMultiselect.SelectAll = SelectAllOption;\n"]}
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import { CommonProps } from '@contentful/f36-core';
3
+ import { PopoverProps } from '@contentful/f36-popover';
4
+
5
+ interface MultiselectOptionProps {
6
+ label: string;
7
+ value: string;
8
+ itemId: string;
9
+ searchValue?: string;
10
+ className?: string;
11
+ onSelectItem: (event: React.ChangeEvent<HTMLInputElement>) => void;
12
+ isChecked?: boolean;
13
+ isDisabled?: boolean;
14
+ }
15
+ declare const MultiselectOption: ({ label, value, itemId, onSelectItem, searchValue, isChecked, isDisabled, className, ...rest }: MultiselectOptionProps) => JSX.Element;
16
+
17
+ interface MultiselectProps extends CommonProps {
18
+ /** Select Options */
19
+ children?: React.ReactNode;
20
+ /**
21
+ * Set a custom icon for the text input
22
+ */
23
+ startIcon?: React.ReactElement;
24
+ /**
25
+ * Placeholder shown before selecting any elements. Defaults to 'Select one or more items'
26
+ */
27
+ placeholder?: string;
28
+ /**
29
+ * current Selected items, to be shown on the trigger button
30
+ */
31
+ currentSelection?: Array<string>;
32
+ /**
33
+ * Function called whenever the search input value changes
34
+ */
35
+ onSearchValueChange?: (event: React.ChangeEvent<HTMLInputElement>) => void | undefined;
36
+ /**
37
+ * This is the value will be passed to the `placeholder` prop of the input.
38
+ * @default "Search"
39
+ */
40
+ searchPlaceholder?: string;
41
+ /**
42
+ * A message that will be shown when it is not possible to find any option that matches the input value
43
+ * @default "No matches"
44
+ */
45
+ noMatchesMessage?: string;
46
+ /**
47
+ * Use this prop to get a ref to the input element of the component
48
+ */
49
+ searchInputRef?: React.Ref<HTMLInputElement>;
50
+ /**
51
+ * Pass a form name to the search text input
52
+ */
53
+ searchInputName?: string;
54
+ /**
55
+ * Sets the list to show its loading state
56
+ * @default false
57
+ */
58
+ isLoading?: boolean;
59
+ /**
60
+ * Use this prop to get a ref to the toggle button of the component
61
+ */
62
+ toggleRef?: React.Ref<HTMLButtonElement>;
63
+ /**
64
+ * Props to pass to the Popover (Dropdown) component
65
+ */
66
+ popoverProps?: Partial<PopoverProps> & {
67
+ /**
68
+ * It sets the max-height, in pixels, of the list
69
+ * The default value is the height of 5 single line items
70
+ * @default 180
71
+ */
72
+ listMaxHeight?: number;
73
+ /**
74
+ * Use this prop to get a ref to the list of items of the component
75
+ */
76
+ listRef?: React.Ref<HTMLUListElement>;
77
+ } & Pick<CommonProps, 'className'>;
78
+ /**
79
+ * Function called when the popover loses its focus.
80
+ */
81
+ onBlur?: () => void;
82
+ }
83
+ /**
84
+ * The Multiselect is a component that will allow a user to select multiple items.
85
+ * It has an optional
86
+ */
87
+ declare const Multiselect$1: React.ForwardRefExoticComponent<MultiselectProps & React.RefAttributes<HTMLDivElement>>;
88
+
89
+ interface SelectAllOptionProps extends Omit<MultiselectOptionProps, 'value' | 'itemId' | 'label'> {
90
+ label?: string;
91
+ }
92
+ declare const SelectAllOption: ({ label, onSelectItem, isChecked, className, ...otherProps }: SelectAllOptionProps) => JSX.Element;
93
+
94
+ declare type CompoundMultiselect = typeof Multiselect$1 & {
95
+ Option: typeof MultiselectOption;
96
+ SelectAll: typeof SelectAllOption;
97
+ };
98
+ declare const Multiselect: CompoundMultiselect;
99
+
100
+ export { Multiselect, MultiselectOption, MultiselectOptionProps, MultiselectProps, SelectAllOption, SelectAllOptionProps };
package/dist/index.js CHANGED
@@ -1,8 +1,6 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var e = require('react');
3
+ var o = require('react');
6
4
  var f36Forms = require('@contentful/f36-forms');
7
5
  var f36Typography = require('@contentful/f36-typography');
8
6
  var emotion = require('emotion');
@@ -13,15 +11,18 @@ var f36Button = require('@contentful/f36-button');
13
11
  var f36Icons = require('@contentful/f36-icons');
14
12
  var f36Skeleton = require('@contentful/f36-skeleton');
15
13
  var f36Popover = require('@contentful/f36-popover');
14
+ var Pe = require('react-focus-lock');
16
15
 
17
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
17
 
19
- var e__default = /*#__PURE__*/_interopDefaultLegacy(e);
20
- var r__default = /*#__PURE__*/_interopDefaultLegacy(r);
18
+ var o__default = /*#__PURE__*/_interopDefault(o);
19
+ var r__default = /*#__PURE__*/_interopDefault(r);
20
+ var Pe__default = /*#__PURE__*/_interopDefault(Pe);
21
21
 
22
- var ce=Object.defineProperty,pe=Object.defineProperties;var ue=Object.getOwnPropertyDescriptors;var C=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var F=(t,l,o)=>l in t?ce(t,l,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[l]=o,h=(t,l)=>{for(var o in l||(l={}))W.call(l,o)&&F(t,o,l[o]);if(C)for(var o of C(l))j.call(l,o)&&F(t,o,l[o]);return t},U=(t,l)=>pe(t,ue(l));var P=(t,l)=>{var o={};for(var n in t)W.call(t,n)&&l.indexOf(n)<0&&(o[n]=t[n]);if(t!=null&&C)for(var n of C(t))l.indexOf(n)<0&&j.call(t,n)&&(o[n]=t[n]);return o};var M=()=>({multiselect:emotion.css({position:"relative",width:"100%"}),triggerButton:emotion.css({justifyContent:"space-between"}),currentSelection:emotion.css({width:"50%",whiteSpace:"nowrap",textOverflow:"ellipsis",overflow:"hidden",verticalAlign:"bottom",marginRight:r__default["default"].spacing2Xs}),currentSelectionAddition:emotion.css({color:r__default["default"].gray600}),inputField:emotion.css({paddingRight:r__default["default"].spacingXl,textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",borderRadius:"0px",borderBottom:`1px solid ${r__default["default"].gray200}`}),toggleButton:emotion.css({position:"absolute",top:"1px",right:"1px",zIndex:r__default["default"].zIndexDefault,padding:r__default["default"].spacing2Xs,height:r__default["default"].spacingXl}),content:t=>emotion.css({overflow:"auto",maxHeight:`${t}px`}),list:emotion.css({listStyle:"none",padding:`${r__default["default"].spacingXs} 0`,margin:0}),groupTitle:emotion.css({padding:`${r__default["default"].spacingXs} ${r__default["default"].spacingM}`,lineHeight:r__default["default"].lineHeightM}),noMatchesTitle:emotion.css({color:r__default["default"].gray500,margin:r__default["default"].spacingM}),selectAll:emotion.css({"label > *":{fontWeight:"bold"}}),item:emotion.css({label:{padding:`${r__default["default"].spacingXs} ${r__default["default"].spacingM}`,wordBreak:"break-word",whiteSpace:"break-spaces",hyphens:"auto",display:"flex",flexDirection:"row",alignItems:"center",cursor:"pointer","&:focus, &:hover":{backgroundColor:r__default["default"].gray100},"&:active":{backgroundColor:r__default["default"].gray200},"&:focus":{boxShadow:r__default["default"].glowPrimary},"&:focus:not(:focus-visible)":{boxShadow:"unset"},"&:focus-visible":{boxShadow:r__default["default"].glowPrimary}}}),disabled:emotion.css({opacity:.5,cursor:"not-allowed"})});var d=H=>{var x=H,{label:t,value:l,itemId:o,onSelectItem:n,searchValue:p,isChecked:u=!1,isDisabled:c=!1,className:S}=x,v=P(x,["label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className"]);let y=M();return e__default["default"].createElement("li",h({className:S},v),e__default["default"].createElement(f36Forms.Checkbox,{id:o,value:l,onChange:b=>n(b),isChecked:u,isDisabled:c,className:emotion.cx(y.item,c&&y.disabled)},e__default["default"].createElement(f36Typography.Text,{"data-test-id":`cf-multiselect-list-item-${o}`},e__default["default"].createElement(_,{item:t,inputValue:p}))))};function _({item:t,inputValue:l=""}){let{before:o,match:n,after:p}=f36Utils.getStringMatch(t,l);return e__default["default"].createElement(e__default["default"].Fragment,null,o,e__default["default"].createElement("b",{"data-test-id":"cf-multiselect-item-match"},n),p)}_.displayName="HighlightedItem";var Q=(t,l,o)=>e__default["default"].Children.map(t,n=>{if(!e__default["default"].isValidElement(n))return n;if(l(n))return o(n);let p=Q(n.props.children,l,o);return e__default["default"].cloneElement(n,{children:p})}),Y=(t,l)=>{let o=0;return e__default["default"].Children.forEach(t,n=>{!e__default["default"].isValidElement(n)||(l(n)?o+=1:o+=Y(n.props.children,l));}),o};function Pe(t,l){let{className:o,startIcon:n,placeholder:p="Select one or more Items",currentSelection:u=[],onSearchValueChange:c,searchPlaceholder:S="Search",searchInputRef:v,searchInputName:H,noMatchesMessage:x="No matches found",toggleRef:y,isLoading:b=!1,testId:ee="cf-multiselect",popoverProps:N={},children:I,onBlur:E}=t,{listMaxHeight:te=180,listRef:oe}=N,a=M(),[m,R]=e.useState(""),[B,V]=e.useState(!1),L=e.useRef(null),D=e.useRef(null),$=typeof c=="function",O=e.useCallback(()=>{var i;(i=D.current)==null||i.focus();},[]),le=e.useCallback(i=>{R(i.target.value),c==null||c(i);},[c,R]),ne=e.useCallback(()=>{if(!m)return;O(),Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set.call(L.current,"");let f=new Event("change",{bubbles:!0});L.current.dispatchEvent(f);},[m,O]),re=e.useCallback(()=>{if(u.length===0)return e__default["default"].createElement(e__default["default"].Fragment,null,p);let i=u.length-1;return i===0?e__default["default"].createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:a.currentSelection},u[0]):e__default["default"].createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:a.currentSelection},u[0]," ",e__default["default"].createElement("span",{className:a.currentSelectionAddition},"and ",i," more"))},[u,p,a.currentSelection,a.currentSelectionAddition]),X=e.useMemo(()=>Y(I,i=>i.type===d),[I]),ie=e__default["default"].useCallback(i=>Q(i,f=>f.type===d,f=>{let se=ae=>{var z;O(),(z=f.props)==null||z.onSelectItem(ae);};return e__default["default"].cloneElement(f,{searchValue:m,onSelectItem:se})}),[m,O]);return e__default["default"].createElement("div",{"data-test-id":ee,className:emotion.cx(a.multiselect,o),ref:l},e__default["default"].createElement(f36Popover.Popover,U(h({renderOnlyWhenOpen:!1,isFullWidth:!0},N),{isOpen:B,onClose:()=>V(!1)}),e__default["default"].createElement(f36Popover.Popover.Trigger,null,e__default["default"].createElement(f36Button.Button,{"aria-label":"Toggle Multiselect",ref:y,onClick:()=>V(!B),startIcon:n,endIcon:e__default["default"].createElement(f36Icons.ChevronDownIcon,null),isFullWidth:!0,className:a.triggerButton},re())),e__default["default"].createElement(f36Popover.Popover.Content,{ref:f36Core.mergeRefs(oe,D),className:emotion.cx(a.content(te),N.className),testId:"cf-multiselect-container",onBlur:()=>E==null?void 0:E()},e__default["default"].createElement(e__default["default"].Fragment,null,$&&e__default["default"].createElement(e__default["default"].Fragment,null,e__default["default"].createElement(f36Forms.TextInput,{"aria-label":"Search",type:"text",value:m,className:a.inputField,testId:"cf-multiselect-search",placeholder:S,onChange:le,ref:f36Core.mergeRefs(v,L),name:H,size:"small"}),e__default["default"].createElement(f36Button.IconButton,{"aria-label":m?"Clear search":"Search",className:a.toggleButton,variant:"transparent",icon:m?e__default["default"].createElement(f36Icons.CloseIcon,{variant:"muted"}):e__default["default"].createElement(f36Icons.SearchIcon,{variant:"muted"}),onClick:ne,isDisabled:!m,size:"small"})),b&&e__default["default"].createElement(we,null),!b&&X>0&&e__default["default"].createElement("ul",{className:a.list,"data-test-id":"cf-multiselect-items"},$?ie(I):I),!b&&X===0&&e__default["default"].createElement(f36Typography.Subheading,{className:a.noMatchesTitle},x)))))}var we=()=>e__default["default"].createElement(f36Skeleton.SkeletonContainer,{svgHeight:16},e__default["default"].createElement(f36Skeleton.SkeletonBodyText,{numberOfLines:1})),Z=e__default["default"].forwardRef(Pe);var k=u=>{var c=u,{label:t,onSelectItem:l,isChecked:o=!1,className:n}=c,p=P(c,["label","onSelectItem","isChecked","className"]);let S=M();return e__default["default"].createElement(d,h({value:"all",label:t||o?"Deselect all":"Select all",itemId:"SelectAll",onSelectItem:l,isChecked:o,className:emotion.cx(S.selectAll,n)},p))};var A=Z;A.Option=d;A.SelectAll=k;
22
+ var pe=Object.defineProperty,ue=Object.defineProperties;var me=Object.getOwnPropertyDescriptors;var C=Object.getOwnPropertySymbols;var F=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var W=(e,n,t)=>n in e?pe(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,h=(e,n)=>{for(var t in n||(n={}))F.call(n,t)&&W(e,t,n[t]);if(C)for(var t of C(n))j.call(n,t)&&W(e,t,n[t]);return e},U=(e,n)=>ue(e,me(n));var P=(e,n)=>{var t={};for(var l in e)F.call(e,l)&&n.indexOf(l)<0&&(t[l]=e[l]);if(e!=null&&C)for(var l of C(e))n.indexOf(l)<0&&j.call(e,l)&&(t[l]=e[l]);return t};var S=()=>({multiselect:emotion.css({position:"relative",width:"100%"}),triggerButton:emotion.css({justifyContent:"space-between"}),currentSelection:emotion.css({width:"50%",whiteSpace:"nowrap",textOverflow:"ellipsis",overflow:"hidden",verticalAlign:"bottom",marginRight:r__default.default.spacing2Xs}),currentSelectionAddition:emotion.css({color:r__default.default.gray600}),searchBar:emotion.css({paddingTop:r__default.default.spacing2Xs,position:"sticky",top:"0px",zIndex:"10",backgroundColor:r__default.default.colorWhite}),inputField:emotion.css({padding:`6px ${r__default.default.spacingXl} 10px ${r__default.default.spacingXs}`,textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",borderRadius:"0px",borderBottom:`1px solid ${r__default.default.gray200}`,boxShadow:"none","&:focus, &:active, &:active:hover":{boxShadow:"none",borderBottom:`1px solid ${r__default.default.gray200}`}}),toggleButton:emotion.css({position:"absolute",top:"1px",right:"1px",zIndex:r__default.default.zIndexDefault,padding:r__default.default.spacing2Xs,height:r__default.default.spacingXl}),content:e=>emotion.css({overflow:"auto",maxHeight:`${e}px`}),container:emotion.css({}),list:emotion.css({listStyle:"none",padding:`${r__default.default.spacing2Xs}`,margin:0}),groupTitle:emotion.css({padding:`6px ${r__default.default.spacingXs}`,lineHeight:r__default.default.lineHeightM}),noMatchesTitle:emotion.css({color:r__default.default.gray500,margin:r__default.default.spacingM}),selectAll:emotion.css({borderBottom:`1px solid ${r__default.default.gray200}`,marginBottom:r__default.default.spacing2Xs,paddingBottom:r__default.default.spacing2Xs,"label > *":{fontWeight:"500"}}),option:emotion.css({listStyleType:"none"}),item:emotion.css({label:{padding:`6px ${r__default.default.spacingXs}`,width:"100%",wordBreak:"break-word",whiteSpace:"break-spaces",hyphens:"auto",display:"flex",flexDirection:"row",alignItems:"center",borderRadius:r__default.default.borderRadiusMedium,border:0,cursor:"pointer",fontSize:r__default.default.fontSizeM,lineHeight:r__default.default.lineHeightM,fontWeight:r__default.default.fontWeightNormal,"&:focus, &:hover":{backgroundColor:r__default.default.gray100},"&:active":{backgroundColor:r__default.default.gray200},"&:focus":{boxShadow:r__default.default.glowPrimary},"&:focus:not(:focus-visible)":{boxShadow:"unset"},"&:focus-visible":{boxShadow:r__default.default.glowPrimary}}}),disabled:emotion.css({opacity:.5,cursor:"not-allowed"})});var d=H=>{var y=H,{label:e,value:n,itemId:t,onSelectItem:l,searchValue:p,isChecked:u=!1,isDisabled:c=!1,className:b}=y,x=P(y,["label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className"]);let M=S();return o__default.default.createElement("li",h({className:emotion.cx(M.option,b)},x),o__default.default.createElement(f36Forms.Checkbox,{id:t,value:n,onChange:v=>l(v),isChecked:u,isDisabled:c,className:emotion.cx(M.item,c&&M.disabled)},o__default.default.createElement(f36Typography.Text,{"data-test-id":`cf-multiselect-list-item-${t}`},o__default.default.createElement(q,{item:e,inputValue:p}))))};function q({item:e,inputValue:n=""}){let{before:t,match:l,after:p}=f36Utils.getStringMatch(e,n);return o__default.default.createElement(o__default.default.Fragment,null,t,o__default.default.createElement("b",{"data-test-id":"cf-multiselect-item-match"},l),p)}q.displayName="HighlightedItem";var Y=(e,n,t)=>o__default.default.Children.map(e,l=>{if(!o__default.default.isValidElement(l))return l;if(n(l))return t(l);let p=Y(l.props.children,n,t);return o__default.default.cloneElement(l,{children:p})}),Z=(e,n)=>{let t=0;return o__default.default.Children.forEach(e,l=>{o__default.default.isValidElement(l)&&(n(l)?t+=1:t+=Z(l.props.children,n));}),t};function we(e,n){let{className:t,startIcon:l,placeholder:p="Select one or more Items",currentSelection:u=[],onSearchValueChange:c,searchPlaceholder:b="Search",searchInputRef:x,searchInputName:H,noMatchesMessage:y="No matches found",toggleRef:M,isLoading:v=!1,testId:te="cf-multiselect",popoverProps:N={},children:I,onBlur:E}=e,{listMaxHeight:oe=180,listRef:ne}=N,s=S(),[m,A]=o.useState(""),[B,X]=o.useState(!1),L=o.useRef(null),$=o.useRef(null),V=typeof c=="function",O=o.useCallback(()=>{var a;(a=$.current)==null||a.focus();},[]),le=o.useCallback(a=>{A(a.target.value),c==null||c(a);},[c,A]),re=o.useCallback(()=>{if(!m)return;O(),Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set.call(L.current,"");let f=new Event("change",{bubbles:!0});L.current.dispatchEvent(f);},[m,O]),ie=o.useCallback(()=>{if(u.length===0)return o__default.default.createElement(o__default.default.Fragment,null,p);let a=u.length-1;return a===0?o__default.default.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:s.currentSelection},u[0]):o__default.default.createElement("span",{"data-test-id":"cf-multiselect-current-selection",className:s.currentSelection},u[0]," ",o__default.default.createElement("span",{className:s.currentSelectionAddition},"and ",a," more"))},[u,p,s.currentSelection,s.currentSelectionAddition]),D=o.useMemo(()=>Z(I,a=>a.type===d),[I]),se=o__default.default.useCallback(a=>Y(a,f=>f.type===d,f=>{let ae=ce=>{var z;O(),(z=f.props)==null||z.onSelectItem(ce);};return o__default.default.cloneElement(f,{searchValue:m,onSelectItem:ae})}),[m,O]);return o__default.default.createElement("div",{"data-test-id":te,className:emotion.cx(s.multiselect,t),ref:n},o__default.default.createElement(f36Popover.Popover,U(h({renderOnlyWhenOpen:!1,isFullWidth:!0},N),{isOpen:B,onClose:()=>X(!1)}),o__default.default.createElement(f36Popover.Popover.Trigger,null,o__default.default.createElement(f36Button.Button,{"aria-label":"Toggle Multiselect",ref:M,onClick:()=>X(!B),startIcon:l,endIcon:o__default.default.createElement(f36Icons.ChevronDownIcon,null),isFullWidth:!0,className:s.triggerButton},ie())),o__default.default.createElement(f36Popover.Popover.Content,{ref:f36Core.mergeRefs(ne,$),className:emotion.cx(s.content(oe),N.className,s.container),testId:"cf-multiselect-container",onBlur:()=>E==null?void 0:E()},o__default.default.createElement(Pe__default.default,null,V&&o__default.default.createElement("div",{className:s.searchBar},o__default.default.createElement(f36Forms.TextInput,{"aria-label":"Search",type:"text",value:m,className:s.inputField,testId:"cf-multiselect-search",placeholder:b,onChange:le,ref:f36Core.mergeRefs(x,L),name:H,size:"small"}),o__default.default.createElement(f36Button.IconButton,{"aria-label":m?"Clear search":"Search",className:s.toggleButton,variant:"transparent",icon:m?o__default.default.createElement(f36Icons.CloseIcon,{variant:"muted"}):o__default.default.createElement(f36Icons.SearchIcon,{variant:"muted"}),onClick:re,isDisabled:!m,size:"small"})),v&&o__default.default.createElement(Ne,null),!v&&D>0&&o__default.default.createElement("ul",{className:s.list,"data-test-id":"cf-multiselect-items"},V?se(I):I),!v&&D===0&&o__default.default.createElement(f36Typography.Subheading,{className:s.noMatchesTitle},y)))))}var Ne=()=>o__default.default.createElement(f36Skeleton.SkeletonContainer,{svgHeight:16},o__default.default.createElement(f36Skeleton.SkeletonBodyText,{numberOfLines:1})),ee=o__default.default.forwardRef(we);var T=u=>{var c=u,{label:e,onSelectItem:n,isChecked:t=!1,className:l}=c,p=P(c,["label","onSelectItem","isChecked","className"]);let b=S();return o__default.default.createElement(d,h({value:"all",label:e||t?"Deselect all":"Select all",itemId:"SelectAll",onSelectItem:n,isChecked:t,className:emotion.cx(b.selectAll,l)},p))};var R=ee;R.Option=d;R.SelectAll=T;
23
23
 
24
- exports.Multiselect = A;
24
+ exports.Multiselect = R;
25
25
  exports.MultiselectOption = d;
26
- exports.SelectAllOption = k;
26
+ exports.SelectAllOption = T;
27
+ //# sourceMappingURL=out.js.map
27
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MultiselectOption.tsx","../src/Multiselect.styles.ts","../src/Multiselect.tsx","../src/SelectAllOption.tsx","../src/CompoundMultiselect.tsx"],"names":["React","Checkbox","Text","css","tokens","getMultiselectStyles","listMaxHeight","getStringMatch","cx","MultiselectOption","_a","_b","label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className","rest","__objRest","styles","__spreadValues","event","HighlightedItem","item","inputValue","before","match","after","useRef","useState","useCallback","useMemo","mergeRefs","Button","IconButton","TextInput","CloseIcon","ChevronDownIcon","SearchIcon","SkeletonContainer","SkeletonBodyText","Popover","Subheading","iterateOverChildren","children","filter","callback","child","childChildren","countMatchingChildren","counter","_Multiselect","props","ref","startIcon","placeholder","currentSelection","onSearchValueChange","searchPlaceholder","searchInputRef","searchInputName","noMatchesMessage","toggleRef","isLoading","testId","popoverProps","onBlur","listRef","setSearchValue","isOpen","setIsOpen","internalSearchInputRef","internalListRef","hasSearch","focusList","handleSearchChange","resetSearchInput","forcedEvent","renderMultiselectLabel","leftoverCount","optionsLength","enrichOptions","__spreadProps","ListItemLoadingState","Multiselect","SelectAllOption","otherProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Checkbox } from '@contentful/f36-forms';\nimport { Text } from '@contentful/f36-typography';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { getStringMatch } from '@contentful/f36-utils';\nimport { cx } from 'emotion';\n\nexport interface MultiselectOptionProps {\n label: string;\n value: string;\n itemId: string;\n searchValue?: string;\n className?: string;\n onSelectItem: (event: React.ChangeEvent<HTMLInputElement>) => void;\n isChecked?: boolean;\n isDisabled?: boolean;\n}\n\nexport const MultiselectOption = ({\n label,\n value,\n itemId,\n onSelectItem,\n searchValue,\n isChecked = false,\n isDisabled = false,\n className,\n ...rest\n}: MultiselectOptionProps) => {\n const styles = getMultiselectStyles();\n\n return (\n <li className={className} {...rest}>\n <Checkbox\n id={itemId}\n value={value}\n onChange={(event) => onSelectItem(event)}\n isChecked={isChecked}\n isDisabled={isDisabled}\n className={cx(styles.item, isDisabled && styles.disabled)}\n >\n <Text data-test-id={`cf-multiselect-list-item-${itemId}`}>\n <HighlightedItem item={label} inputValue={searchValue} />\n </Text>\n </Checkbox>\n </li>\n );\n};\n\nfunction HighlightedItem({\n item,\n inputValue = '',\n}: {\n item: string;\n inputValue?: string;\n}) {\n const { before, match, after } = getStringMatch(item, inputValue);\n return (\n <>\n {before}\n <b data-test-id=\"cf-multiselect-item-match\">{match}</b>\n {after}\n </>\n );\n}\n\nHighlightedItem.displayName = 'HighlightedItem';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMultiselectStyles = () => ({\n multiselect: css({\n position: 'relative',\n width: '100%',\n }),\n triggerButton: css({\n justifyContent: 'space-between',\n }),\n currentSelection: css({\n width: '50%',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n verticalAlign: 'bottom',\n marginRight: tokens.spacing2Xs,\n }),\n currentSelectionAddition: css({\n color: tokens.gray600,\n }),\n inputField: css({\n paddingRight: tokens.spacingXl,\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n border: 'none',\n borderRadius: '0px',\n borderBottom: `1px solid ${tokens.gray200}`,\n }),\n toggleButton: css({\n position: 'absolute',\n top: '1px',\n right: '1px',\n zIndex: tokens.zIndexDefault,\n padding: tokens.spacing2Xs,\n height: tokens.spacingXl,\n }),\n content: (listMaxHeight: number) =>\n css({\n overflow: 'auto',\n maxHeight: `${listMaxHeight}px`,\n }),\n list: css({\n listStyle: 'none',\n padding: `${tokens.spacingXs} 0`,\n margin: 0,\n }),\n groupTitle: css({\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n lineHeight: tokens.lineHeightM,\n }),\n noMatchesTitle: css({\n color: tokens.gray500,\n margin: tokens.spacingM,\n }),\n selectAll: css({\n 'label > *': {\n fontWeight: 'bold',\n },\n }),\n item: css({\n label: {\n padding: `${tokens.spacingXs} ${tokens.spacingM}`,\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n hyphens: 'auto',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n cursor: 'pointer',\n '&:focus, &:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:focus': {\n boxShadow: tokens.glowPrimary,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n },\n '&:focus-visible': {\n boxShadow: tokens.glowPrimary,\n },\n },\n }),\n disabled: css({\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n});\n","import React, { useRef, useState, useCallback, useMemo } from 'react';\nimport { cx } from 'emotion';\n\nimport { mergeRefs, type CommonProps } from '@contentful/f36-core';\nimport { Button, IconButton } from '@contentful/f36-button';\nimport { TextInput } from '@contentful/f36-forms';\nimport { CloseIcon, ChevronDownIcon, SearchIcon } from '@contentful/f36-icons';\nimport { SkeletonContainer, SkeletonBodyText } from '@contentful/f36-skeleton';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\nimport { Subheading } from '@contentful/f36-typography';\n\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\n\nexport interface MultiselectProps extends CommonProps {\n /** Select Options */\n children?: React.ReactNode;\n\n /**\n * Set a custom icon for the text input\n */\n startIcon?: React.ReactElement;\n\n /**\n * Placeholder shown before selecting any elements. Defaults to 'Select one or more items'\n */\n placeholder?: string;\n\n /**\n * current Selected items, to be shown on the trigger button\n */\n currentSelection?: Array<string>;\n\n /**\n * Function called whenever the search input value changes\n */\n onSearchValueChange?: (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => void | undefined;\n\n /**\n * This is the value will be passed to the `placeholder` prop of the input.\n * @default \"Search\"\n */\n searchPlaceholder?: string;\n\n /**\n * A message that will be shown when it is not possible to find any option that matches the input value\n * @default \"No matches\"\n */\n noMatchesMessage?: string;\n\n /**\n * Use this prop to get a ref to the input element of the component\n */\n searchInputRef?: React.Ref<HTMLInputElement>;\n\n /**\n * Pass a form name to the search text input\n */\n searchInputName?: string;\n\n /**\n * Sets the list to show its loading state\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Use this prop to get a ref to the toggle button of the component\n */\n toggleRef?: React.Ref<HTMLButtonElement>;\n\n /**\n * Props to pass to the Popover (Dropdown) component\n */\n popoverProps?: Partial<PopoverProps> & {\n /**\n * It sets the max-height, in pixels, of the list\n * The default value is the height of 5 single line items\n * @default 180\n */\n listMaxHeight?: number;\n\n /**\n * Use this prop to get a ref to the list of items of the component\n */\n listRef?: React.Ref<HTMLUListElement>;\n } & Pick<CommonProps, 'className'>;\n\n /**\n * Function called when the popover loses its focus.\n */\n onBlur?: () => void;\n}\n\n// Scan through the whole hierachy until `filter` returns true and apply `transform`\n// Inspired from https://stackoverflow.com/a/70676868/17269164\nconst iterateOverChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n callback: (child: React.ReactElement) => React.ReactElement | void,\n): React.ReactNode => {\n return React.Children.map(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return child;\n if (filter(child)) {\n return callback(child);\n }\n const childChildren = iterateOverChildren(\n child.props.children,\n filter,\n callback,\n );\n return React.cloneElement(child, { children: childChildren } as unknown);\n });\n};\n\n// Scan through the whole hierachy to count the number of children where `filter` returns true\nconst countMatchingChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n): number => {\n let counter = 0;\n React.Children.forEach(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return;\n if (!filter(child)) {\n counter += countMatchingChildren(child.props.children, filter);\n } else {\n counter += 1;\n }\n });\n return counter;\n};\n\nfunction _Multiselect(props: MultiselectProps, ref: React.Ref<HTMLDivElement>) {\n const {\n className,\n startIcon,\n placeholder = 'Select one or more Items',\n currentSelection = [],\n onSearchValueChange,\n searchPlaceholder = 'Search',\n searchInputRef,\n searchInputName,\n noMatchesMessage = 'No matches found',\n toggleRef,\n isLoading = false,\n testId = 'cf-multiselect',\n popoverProps = {},\n children,\n onBlur,\n } = props;\n\n const { listMaxHeight = 180, listRef } = popoverProps;\n\n const styles = getMultiselectStyles();\n\n const [searchValue, setSearchValue] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const internalSearchInputRef = useRef<HTMLInputElement>(null);\n const internalListRef = useRef<HTMLUListElement>(null);\n\n const hasSearch = typeof onSearchValueChange === 'function';\n\n const focusList = useCallback(() => {\n // Clearing the search input or selecting an item triggers a rerendering and\n // thereby the client loses the focus on the clicked element. To avoid having\n // the focus on the document body (which breaks `closeOnBlur`), we force it\n // back to the list in the popup.\n internalListRef.current?.focus();\n }, []);\n\n const handleSearchChange = useCallback(\n (event) => {\n setSearchValue(event.target.value);\n onSearchValueChange?.(event);\n },\n [onSearchValueChange, setSearchValue],\n );\n\n const resetSearchInput = useCallback(() => {\n if (!searchValue) return;\n focusList();\n // this looks a bit hacky, but is the official way of externally triggering the onChange handler for an input\n // https://stackoverflow.com/a/46012210/17269164\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value',\n ).set;\n nativeInputValueSetter.call(internalSearchInputRef.current, '');\n const forcedEvent = new Event('change', { bubbles: true });\n internalSearchInputRef.current.dispatchEvent(forcedEvent);\n }, [searchValue, focusList]);\n\n const renderMultiselectLabel = useCallback(() => {\n if (currentSelection.length === 0) {\n return <>{placeholder}</>;\n }\n const leftoverCount = currentSelection.length - 1;\n if (leftoverCount === 0) {\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}\n </span>\n );\n }\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}{' '}\n <span className={styles.currentSelectionAddition}>\n and {leftoverCount} more\n </span>\n </span>\n );\n }, [\n currentSelection,\n placeholder,\n styles.currentSelection,\n styles.currentSelectionAddition,\n ]);\n\n const optionsLength = useMemo(\n () =>\n countMatchingChildren(\n children,\n (child) => child.type === MultiselectOption,\n ),\n [children],\n );\n\n // clones and enriches the multiselect options\n const enrichOptions = React.useCallback(\n (children: React.ReactNode): React.ReactNode => {\n return iterateOverChildren(\n children,\n (child) => child.type === MultiselectOption,\n (child) => {\n const onSelectItem = (event: React.ChangeEvent<HTMLInputElement>) => {\n focusList();\n child.props?.onSelectItem(event);\n };\n return React.cloneElement(child, {\n searchValue,\n onSelectItem,\n } as Partial<MultiselectOptionProps>);\n },\n );\n },\n [searchValue, focusList],\n );\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles.multiselect, className)}\n ref={ref}\n >\n <Popover\n renderOnlyWhenOpen={false}\n isFullWidth\n {...popoverProps}\n // popoverProps should never overwrite the internal opening logic\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n >\n <Popover.Trigger>\n <Button\n aria-label=\"Toggle Multiselect\"\n ref={toggleRef}\n onClick={() => setIsOpen(!isOpen)}\n startIcon={startIcon}\n endIcon={<ChevronDownIcon />}\n isFullWidth\n className={styles.triggerButton}\n >\n {renderMultiselectLabel()}\n </Button>\n </Popover.Trigger>\n <Popover.Content\n ref={mergeRefs(listRef, internalListRef)}\n className={cx(styles.content(listMaxHeight), popoverProps.className)}\n testId=\"cf-multiselect-container\"\n onBlur={() => onBlur?.()}\n >\n <>\n {hasSearch && (\n <>\n <TextInput\n aria-label=\"Search\"\n type=\"text\"\n value={searchValue}\n className={styles.inputField}\n testId=\"cf-multiselect-search\"\n placeholder={searchPlaceholder}\n onChange={handleSearchChange}\n ref={mergeRefs(searchInputRef, internalSearchInputRef)}\n name={searchInputName}\n size=\"small\"\n />\n <IconButton\n aria-label={searchValue ? 'Clear search' : 'Search'}\n className={styles.toggleButton}\n variant=\"transparent\"\n icon={\n searchValue ? (\n <CloseIcon variant=\"muted\" />\n ) : (\n <SearchIcon variant=\"muted\" />\n )\n }\n onClick={resetSearchInput}\n isDisabled={!searchValue}\n size=\"small\"\n />\n </>\n )}\n {isLoading && <ListItemLoadingState />}\n\n {!isLoading && optionsLength > 0 && (\n <ul className={styles.list} data-test-id=\"cf-multiselect-items\">\n {hasSearch ? enrichOptions(children) : children}\n </ul>\n )}\n\n {!isLoading && optionsLength === 0 && (\n <Subheading className={styles.noMatchesTitle}>\n {noMatchesMessage}\n </Subheading>\n )}\n </>\n </Popover.Content>\n </Popover>\n </div>\n );\n}\n\nconst ListItemLoadingState = () => {\n return (\n <SkeletonContainer svgHeight={16}>\n <SkeletonBodyText numberOfLines={1} />\n </SkeletonContainer>\n );\n};\n\n/**\n * The Multiselect is a component that will allow a user to select multiple items.\n * It has an optional\n */\nexport const Multiselect = React.forwardRef(_Multiselect);\n","import React from 'react';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { cx } from 'emotion';\n\nexport interface SelectAllOptionProps\n extends Omit<MultiselectOptionProps, 'value' | 'itemId' | 'label'> {\n label?: string;\n}\n\nexport const SelectAllOption = ({\n label,\n onSelectItem,\n isChecked = false,\n className,\n ...otherProps\n}: SelectAllOptionProps) => {\n const styles = getMultiselectStyles();\n const displayLabel = label || isChecked ? 'Deselect all' : 'Select all';\n return (\n <MultiselectOption\n value=\"all\"\n label={displayLabel}\n itemId=\"SelectAll\"\n onSelectItem={onSelectItem}\n isChecked={isChecked}\n className={cx(styles.selectAll, className)}\n {...otherProps}\n />\n );\n};\n","import { Multiselect as OriginalMultiSelect } from './Multiselect';\nimport { MultiselectOption } from './MultiselectOption';\nimport { SelectAllOption } from './SelectAllOption';\n\ntype CompoundMultiselect = typeof OriginalMultiSelect & {\n Option: typeof MultiselectOption;\n SelectAll: typeof SelectAllOption;\n};\n\nexport const Multiselect = OriginalMultiSelect as CompoundMultiselect;\nMultiselect.Option = MultiselectOption;\nMultiselect.SelectAll = SelectAllOption;\n"]}
1
+ {"version":3,"sources":["../src/MultiselectOption.tsx","../src/Multiselect.styles.ts","../src/Multiselect.tsx","../src/SelectAllOption.tsx","../src/CompoundMultiselect.tsx"],"names":["React","Checkbox","Text","css","tokens","getMultiselectStyles","listMaxHeight","getStringMatch","cx","MultiselectOption","_a","_b","label","value","itemId","onSelectItem","searchValue","isChecked","isDisabled","className","rest","__objRest","styles","__spreadValues","event","HighlightedItem","item","inputValue","before","match","after","useRef","useState","useCallback","useMemo","mergeRefs","Button","IconButton","TextInput","CloseIcon","ChevronDownIcon","SearchIcon","SkeletonContainer","SkeletonBodyText","Popover","Subheading","FocusLock","iterateOverChildren","children","filter","callback","child","childChildren","countMatchingChildren","counter","_Multiselect","props","ref","startIcon","placeholder","currentSelection","onSearchValueChange","searchPlaceholder","searchInputRef","searchInputName","noMatchesMessage","toggleRef","isLoading","testId","popoverProps","onBlur","listRef","setSearchValue","isOpen","setIsOpen","internalSearchInputRef","internalListRef","hasSearch","focusList","handleSearchChange","resetSearchInput","forcedEvent","renderMultiselectLabel","leftoverCount","optionsLength","enrichOptions","__spreadProps","ListItemLoadingState","Multiselect","SelectAllOption","otherProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Checkbox } from '@contentful/f36-forms';\nimport { Text } from '@contentful/f36-typography';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { getStringMatch } from '@contentful/f36-utils';\nimport { cx } from 'emotion';\n\nexport interface MultiselectOptionProps {\n label: string;\n value: string;\n itemId: string;\n searchValue?: string;\n className?: string;\n onSelectItem: (event: React.ChangeEvent<HTMLInputElement>) => void;\n isChecked?: boolean;\n isDisabled?: boolean;\n}\n\nexport const MultiselectOption = ({\n label,\n value,\n itemId,\n onSelectItem,\n searchValue,\n isChecked = false,\n isDisabled = false,\n className,\n ...rest\n}: MultiselectOptionProps) => {\n const styles = getMultiselectStyles();\n\n return (\n <li className={cx(styles.option, className)} {...rest}>\n <Checkbox\n id={itemId}\n value={value}\n onChange={(event) => onSelectItem(event)}\n isChecked={isChecked}\n isDisabled={isDisabled}\n className={cx(styles.item, isDisabled && styles.disabled)}\n >\n <Text data-test-id={`cf-multiselect-list-item-${itemId}`}>\n <HighlightedItem item={label} inputValue={searchValue} />\n </Text>\n </Checkbox>\n </li>\n );\n};\n\nfunction HighlightedItem({\n item,\n inputValue = '',\n}: {\n item: string;\n inputValue?: string;\n}) {\n const { before, match, after } = getStringMatch(item, inputValue);\n return (\n <>\n {before}\n <b data-test-id=\"cf-multiselect-item-match\">{match}</b>\n {after}\n </>\n );\n}\n\nHighlightedItem.displayName = 'HighlightedItem';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const getMultiselectStyles = () => ({\n multiselect: css({\n position: 'relative',\n width: '100%',\n }),\n triggerButton: css({\n justifyContent: 'space-between',\n }),\n currentSelection: css({\n width: '50%',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n verticalAlign: 'bottom',\n marginRight: tokens.spacing2Xs,\n }),\n currentSelectionAddition: css({\n color: tokens.gray600,\n }),\n searchBar: css({\n paddingTop: tokens.spacing2Xs,\n position: 'sticky',\n top: '0px',\n zIndex: '10',\n backgroundColor: tokens.colorWhite,\n }),\n inputField: css({\n padding: `6px ${tokens.spacingXl} 10px ${tokens.spacingXs}`,\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n border: 'none',\n borderRadius: '0px',\n borderBottom: `1px solid ${tokens.gray200}`,\n boxShadow: 'none',\n '&:focus, &:active, &:active:hover': {\n boxShadow: 'none',\n borderBottom: `1px solid ${tokens.gray200}`,\n },\n }),\n toggleButton: css({\n position: 'absolute',\n top: '1px',\n right: '1px',\n zIndex: tokens.zIndexDefault,\n padding: tokens.spacing2Xs,\n height: tokens.spacingXl,\n }),\n content: (listMaxHeight: number) =>\n css({\n overflow: 'auto',\n maxHeight: `${listMaxHeight}px`,\n }),\n container: css({}),\n list: css({\n listStyle: 'none',\n padding: `${tokens.spacing2Xs}`,\n margin: 0,\n }),\n groupTitle: css({\n // Magic number to get a height of 32px on the item\n padding: `6px ${tokens.spacingXs}`,\n lineHeight: tokens.lineHeightM,\n }),\n noMatchesTitle: css({\n color: tokens.gray500,\n margin: tokens.spacingM,\n }),\n selectAll: css({\n borderBottom: `1px solid ${tokens.gray200}`,\n marginBottom: tokens.spacing2Xs,\n paddingBottom: tokens.spacing2Xs,\n 'label > *': {\n fontWeight: '500',\n },\n }),\n option: css({\n listStyleType: 'none',\n }),\n item: css({\n label: {\n // Magic number to get a height of 32px on the item\n padding: `6px ${tokens.spacingXs}`,\n width: '100%',\n wordBreak: 'break-word',\n whiteSpace: 'break-spaces',\n hyphens: 'auto',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: tokens.borderRadiusMedium,\n border: 0,\n cursor: 'pointer',\n fontSize: tokens.fontSizeM,\n lineHeight: tokens.lineHeightM,\n fontWeight: tokens.fontWeightNormal,\n '&:focus, &:hover': {\n backgroundColor: tokens.gray100,\n },\n '&:active': {\n backgroundColor: tokens.gray200,\n },\n '&:focus': {\n boxShadow: tokens.glowPrimary,\n },\n '&:focus:not(:focus-visible)': {\n boxShadow: 'unset',\n },\n '&:focus-visible': {\n boxShadow: tokens.glowPrimary,\n },\n },\n }),\n disabled: css({\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n});\n","import React, { useRef, useState, useCallback, useMemo } from 'react';\nimport { cx } from 'emotion';\n\nimport { mergeRefs, type CommonProps } from '@contentful/f36-core';\nimport { Button, IconButton } from '@contentful/f36-button';\nimport { TextInput } from '@contentful/f36-forms';\nimport { CloseIcon, ChevronDownIcon, SearchIcon } from '@contentful/f36-icons';\nimport { SkeletonContainer, SkeletonBodyText } from '@contentful/f36-skeleton';\nimport { Popover, type PopoverProps } from '@contentful/f36-popover';\nimport { Subheading } from '@contentful/f36-typography';\n\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport FocusLock from 'react-focus-lock';\n\nexport interface MultiselectProps extends CommonProps {\n /** Select Options */\n children?: React.ReactNode;\n\n /**\n * Set a custom icon for the text input\n */\n startIcon?: React.ReactElement;\n\n /**\n * Placeholder shown before selecting any elements. Defaults to 'Select one or more items'\n */\n placeholder?: string;\n\n /**\n * current Selected items, to be shown on the trigger button\n */\n currentSelection?: Array<string>;\n\n /**\n * Function called whenever the search input value changes\n */\n onSearchValueChange?: (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => void | undefined;\n\n /**\n * This is the value will be passed to the `placeholder` prop of the input.\n * @default \"Search\"\n */\n searchPlaceholder?: string;\n\n /**\n * A message that will be shown when it is not possible to find any option that matches the input value\n * @default \"No matches\"\n */\n noMatchesMessage?: string;\n\n /**\n * Use this prop to get a ref to the input element of the component\n */\n searchInputRef?: React.Ref<HTMLInputElement>;\n\n /**\n * Pass a form name to the search text input\n */\n searchInputName?: string;\n\n /**\n * Sets the list to show its loading state\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Use this prop to get a ref to the toggle button of the component\n */\n toggleRef?: React.Ref<HTMLButtonElement>;\n\n /**\n * Props to pass to the Popover (Dropdown) component\n */\n popoverProps?: Partial<PopoverProps> & {\n /**\n * It sets the max-height, in pixels, of the list\n * The default value is the height of 5 single line items\n * @default 180\n */\n listMaxHeight?: number;\n\n /**\n * Use this prop to get a ref to the list of items of the component\n */\n listRef?: React.Ref<HTMLUListElement>;\n } & Pick<CommonProps, 'className'>;\n\n /**\n * Function called when the popover loses its focus.\n */\n onBlur?: () => void;\n}\n\n// Scan through the whole hierachy until `filter` returns true and apply `transform`\n// Inspired from https://stackoverflow.com/a/70676868/17269164\nconst iterateOverChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n callback: (child: React.ReactElement) => React.ReactElement | void,\n): React.ReactNode => {\n return React.Children.map(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return child;\n if (filter(child)) {\n return callback(child);\n }\n const childChildren = iterateOverChildren(\n child.props.children,\n filter,\n callback,\n );\n return React.cloneElement(child, { children: childChildren } as unknown);\n });\n};\n\n// Scan through the whole hierachy to count the number of children where `filter` returns true\nconst countMatchingChildren = (\n children: React.ReactNode,\n filter: (child: React.ReactElement) => boolean,\n): number => {\n let counter = 0;\n React.Children.forEach(children, (child) => {\n // equal to (if (child == null || typeof child == 'string'))\n if (!React.isValidElement(child)) return;\n if (!filter(child)) {\n counter += countMatchingChildren(child.props.children, filter);\n } else {\n counter += 1;\n }\n });\n return counter;\n};\n\nfunction _Multiselect(props: MultiselectProps, ref: React.Ref<HTMLDivElement>) {\n const {\n className,\n startIcon,\n placeholder = 'Select one or more Items',\n currentSelection = [],\n onSearchValueChange,\n searchPlaceholder = 'Search',\n searchInputRef,\n searchInputName,\n noMatchesMessage = 'No matches found',\n toggleRef,\n isLoading = false,\n testId = 'cf-multiselect',\n popoverProps = {},\n children,\n onBlur,\n } = props;\n\n const { listMaxHeight = 180, listRef } = popoverProps;\n\n const styles = getMultiselectStyles();\n\n const [searchValue, setSearchValue] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const internalSearchInputRef = useRef<HTMLInputElement>(null);\n const internalListRef = useRef<HTMLUListElement>(null);\n\n const hasSearch = typeof onSearchValueChange === 'function';\n\n const focusList = useCallback(() => {\n // Clearing the search input or selecting an item triggers a rerendering and\n // thereby the client loses the focus on the clicked element. To avoid having\n // the focus on the document body (which breaks `closeOnBlur`), we force it\n // back to the list in the popup.\n internalListRef.current?.focus();\n }, []);\n\n const handleSearchChange = useCallback(\n (event) => {\n setSearchValue(event.target.value);\n onSearchValueChange?.(event);\n },\n [onSearchValueChange, setSearchValue],\n );\n\n const resetSearchInput = useCallback(() => {\n if (!searchValue) return;\n focusList();\n // this looks a bit hacky, but is the official way of externally triggering the onChange handler for an input\n // https://stackoverflow.com/a/46012210/17269164\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n window.HTMLInputElement.prototype,\n 'value',\n ).set;\n nativeInputValueSetter.call(internalSearchInputRef.current, '');\n const forcedEvent = new Event('change', { bubbles: true });\n internalSearchInputRef.current.dispatchEvent(forcedEvent);\n }, [searchValue, focusList]);\n\n const renderMultiselectLabel = useCallback(() => {\n if (currentSelection.length === 0) {\n return <>{placeholder}</>;\n }\n const leftoverCount = currentSelection.length - 1;\n if (leftoverCount === 0) {\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}\n </span>\n );\n }\n return (\n <span\n data-test-id=\"cf-multiselect-current-selection\"\n className={styles.currentSelection}\n >\n {currentSelection[0]}{' '}\n <span className={styles.currentSelectionAddition}>\n and {leftoverCount} more\n </span>\n </span>\n );\n }, [\n currentSelection,\n placeholder,\n styles.currentSelection,\n styles.currentSelectionAddition,\n ]);\n\n const optionsLength = useMemo(\n () =>\n countMatchingChildren(\n children,\n (child) => child.type === MultiselectOption,\n ),\n [children],\n );\n\n // clones and enriches the multiselect options\n const enrichOptions = React.useCallback(\n (children: React.ReactNode): React.ReactNode => {\n return iterateOverChildren(\n children,\n (child) => child.type === MultiselectOption,\n (child) => {\n const onSelectItem = (event: React.ChangeEvent<HTMLInputElement>) => {\n focusList();\n child.props?.onSelectItem(event);\n };\n return React.cloneElement(child, {\n searchValue,\n onSelectItem,\n } as Partial<MultiselectOptionProps>);\n },\n );\n },\n [searchValue, focusList],\n );\n\n return (\n <div\n data-test-id={testId}\n className={cx(styles.multiselect, className)}\n ref={ref}\n >\n <Popover\n renderOnlyWhenOpen={false}\n isFullWidth\n {...popoverProps}\n // popoverProps should never overwrite the internal opening logic\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n >\n <Popover.Trigger>\n <Button\n aria-label=\"Toggle Multiselect\"\n ref={toggleRef}\n onClick={() => setIsOpen(!isOpen)}\n startIcon={startIcon}\n endIcon={<ChevronDownIcon />}\n isFullWidth\n className={styles.triggerButton}\n >\n {renderMultiselectLabel()}\n </Button>\n </Popover.Trigger>\n <Popover.Content\n ref={mergeRefs(listRef, internalListRef)}\n className={cx(\n styles.content(listMaxHeight),\n popoverProps.className,\n styles.container,\n )}\n testId=\"cf-multiselect-container\"\n onBlur={() => onBlur?.()}\n >\n <FocusLock>\n {hasSearch && (\n <div className={styles.searchBar}>\n <TextInput\n aria-label=\"Search\"\n type=\"text\"\n value={searchValue}\n className={styles.inputField}\n testId=\"cf-multiselect-search\"\n placeholder={searchPlaceholder}\n onChange={handleSearchChange}\n ref={mergeRefs(searchInputRef, internalSearchInputRef)}\n name={searchInputName}\n size=\"small\"\n />\n <IconButton\n aria-label={searchValue ? 'Clear search' : 'Search'}\n className={styles.toggleButton}\n variant=\"transparent\"\n icon={\n searchValue ? (\n <CloseIcon variant=\"muted\" />\n ) : (\n <SearchIcon variant=\"muted\" />\n )\n }\n onClick={resetSearchInput}\n isDisabled={!searchValue}\n size=\"small\"\n />\n </div>\n )}\n {isLoading && <ListItemLoadingState />}\n\n {!isLoading && optionsLength > 0 && (\n <ul className={styles.list} data-test-id=\"cf-multiselect-items\">\n {hasSearch ? enrichOptions(children) : children}\n </ul>\n )}\n\n {!isLoading && optionsLength === 0 && (\n <Subheading className={styles.noMatchesTitle}>\n {noMatchesMessage}\n </Subheading>\n )}\n </FocusLock>\n </Popover.Content>\n </Popover>\n </div>\n );\n}\n\nconst ListItemLoadingState = () => {\n return (\n <SkeletonContainer svgHeight={16}>\n <SkeletonBodyText numberOfLines={1} />\n </SkeletonContainer>\n );\n};\n\n/**\n * The Multiselect is a component that will allow a user to select multiple items.\n * It has an optional\n */\nexport const Multiselect = React.forwardRef(_Multiselect);\n","import React from 'react';\nimport { MultiselectOption, MultiselectOptionProps } from './MultiselectOption';\nimport { getMultiselectStyles } from './Multiselect.styles';\nimport { cx } from 'emotion';\n\nexport interface SelectAllOptionProps\n extends Omit<MultiselectOptionProps, 'value' | 'itemId' | 'label'> {\n label?: string;\n}\n\nexport const SelectAllOption = ({\n label,\n onSelectItem,\n isChecked = false,\n className,\n ...otherProps\n}: SelectAllOptionProps) => {\n const styles = getMultiselectStyles();\n const displayLabel = label || isChecked ? 'Deselect all' : 'Select all';\n return (\n <MultiselectOption\n value=\"all\"\n label={displayLabel}\n itemId=\"SelectAll\"\n onSelectItem={onSelectItem}\n isChecked={isChecked}\n className={cx(styles.selectAll, className)}\n {...otherProps}\n />\n );\n};\n","import { Multiselect as OriginalMultiSelect } from './Multiselect';\nimport { MultiselectOption } from './MultiselectOption';\nimport { SelectAllOption } from './SelectAllOption';\n\ntype CompoundMultiselect = typeof OriginalMultiSelect & {\n Option: typeof MultiselectOption;\n SelectAll: typeof SelectAllOption;\n};\n\nexport const Multiselect = OriginalMultiSelect as CompoundMultiselect;\nMultiselect.Option = MultiselectOption;\nMultiselect.SelectAll = SelectAllOption;\n"]}
package/package.json CHANGED
@@ -1,22 +1,23 @@
1
1
  {
2
2
  "name": "@contentful/f36-multiselect",
3
- "version": "4.20.11",
3
+ "version": "4.20.12",
4
4
  "description": "Forma 36: Multiselect Component",
5
5
  "scripts": {
6
6
  "build": "tsup"
7
7
  },
8
8
  "dependencies": {
9
- "@babel/runtime": "^7.6.2",
9
+ "@babel/runtime": "^7.21.0",
10
10
  "@contentful/f36-button": "^4.20.8",
11
11
  "@contentful/f36-core": "^4.20.8",
12
+ "@contentful/f36-forms": "^4.20.8",
12
13
  "@contentful/f36-icons": "^4.20.8",
14
+ "@contentful/f36-popover": "^4.20.8",
13
15
  "@contentful/f36-skeleton": "^4.20.8",
14
16
  "@contentful/f36-tokens": "^4.0.1",
15
17
  "@contentful/f36-typography": "^4.20.8",
16
- "@contentful/f36-popover": "^4.20.8",
17
18
  "@contentful/f36-utils": "^4.20.8",
18
- "@contentful/f36-forms": "^4.20.8",
19
- "emotion": "^10.0.17"
19
+ "emotion": "^10.0.17",
20
+ "react-focus-lock": "^2.9.5"
20
21
  },
21
22
  "peerDependencies": {
22
23
  "react": ">=16.8"
@@ -39,7 +40,7 @@
39
40
  "access": "public"
40
41
  },
41
42
  "devDependencies": {
42
- "formik": "^2.2.9",
43
+ "formik": "^2.4.2",
43
44
  "react-hook-form": "^7.15.0"
44
45
  }
45
46
  }