@lifesg/react-design-system 3.5.0-canary.6 → 3.5.0-canary.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/types.d.ts +7 -1
- package/cjs/external/dompurify/dist/purify.es.js +2 -2
- package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
- package/cjs/input-group/input-group-list-addon.js +1 -1
- package/cjs/input-group/input-group-list-addon.js.map +1 -1
- package/cjs/input-range-select/input-range-select.js +1 -1
- package/cjs/input-range-select/input-range-select.js.map +1 -1
- package/cjs/input-select/input-select.js +1 -1
- package/cjs/input-select/input-select.js.map +1 -1
- package/cjs/navbar/navbar-items.js +1 -1
- package/cjs/navbar/navbar-items.js.map +1 -1
- package/cjs/navbar/navbar-items.styles.js +1 -1
- package/cjs/navbar/navbar-items.styles.js.map +1 -1
- package/cjs/otp-verification/thumbnail/email-thumbnail.js.map +1 -1
- package/cjs/otp-verification/thumbnail/phone-thumbnail.js.map +1 -1
- package/cjs/shared/dropdown-list/dropdown-list.js +1 -1
- package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
- package/cjs/sidenav/sidenav-item.js +1 -1
- package/cjs/sidenav/sidenav-item.js.map +1 -1
- package/cjs/tab/tab-context-provider.js +2 -0
- package/cjs/tab/tab-context-provider.js.map +1 -0
- package/cjs/tab/tab-context.js +1 -1
- package/cjs/tab/tab-context.js.map +1 -1
- package/cjs/tab/tab-item.js +1 -1
- package/cjs/tab/tab-item.js.map +1 -1
- package/cjs/tab/tab-link-chain.js +1 -1
- package/cjs/tab/tab-link-chain.js.map +1 -1
- package/cjs/tab/tab-list-item.js +2 -0
- package/cjs/tab/tab-list-item.js.map +1 -0
- package/cjs/tab/tab-list.js +2 -0
- package/cjs/tab/tab-list.js.map +1 -0
- package/cjs/tab/tab-panel.js +2 -0
- package/cjs/tab/tab-panel.js.map +1 -0
- package/cjs/tab/tab.js +1 -1
- package/cjs/tab/tab.js.map +1 -1
- package/external/dompurify/dist/purify.es.js +2 -2
- package/external/dompurify/dist/purify.es.js.map +1 -1
- package/input-group/input-group-list-addon.js +1 -1
- package/input-group/input-group-list-addon.js.map +1 -1
- package/input-multi-select/types.d.ts +1 -1
- package/input-range-select/input-range-select.d.ts +1 -1
- package/input-range-select/input-range-select.js +1 -1
- package/input-range-select/input-range-select.js.map +1 -1
- package/input-select/input-select.d.ts +1 -1
- package/input-select/input-select.js +1 -1
- package/input-select/input-select.js.map +1 -1
- package/link-list/internal-types.d.ts +3 -3
- package/navbar/navbar-items.js +1 -1
- package/navbar/navbar-items.js.map +1 -1
- package/navbar/navbar-items.styles.d.ts +8 -8
- package/navbar/navbar-items.styles.js +1 -1
- package/navbar/navbar-items.styles.js.map +1 -1
- package/otp-verification/thumbnail/email-thumbnail.js.map +1 -1
- package/otp-verification/thumbnail/phone-thumbnail.js.map +1 -1
- package/package.json +1 -1
- package/shared/dropdown-list/dropdown-list.js +1 -1
- package/shared/dropdown-list/dropdown-list.js.map +1 -1
- package/shared/dropdown-list/types.d.ts +4 -1
- package/sidenav/sidenav-item.js +1 -1
- package/sidenav/sidenav-item.js.map +1 -1
- package/tab/tab-context-provider.d.ts +5 -0
- package/tab/tab-context-provider.js +2 -0
- package/tab/tab-context-provider.js.map +1 -0
- package/tab/tab-context.d.ts +5 -0
- package/tab/tab-context.js +1 -1
- package/tab/tab-context.js.map +1 -1
- package/tab/tab-item.js +1 -1
- package/tab/tab-item.js.map +1 -1
- package/tab/tab-link-chain.js +1 -1
- package/tab/tab-link-chain.js.map +1 -1
- package/tab/tab-list-item.d.ts +5 -0
- package/tab/tab-list-item.js +2 -0
- package/tab/tab-list-item.js.map +1 -0
- package/tab/tab-list.d.ts +5 -0
- package/tab/tab-list.js +2 -0
- package/tab/tab-list.js.map +1 -0
- package/tab/tab-panel.d.ts +5 -0
- package/tab/tab-panel.js +2 -0
- package/tab/tab-panel.js.map +1 -0
- package/tab/tab.d.ts +31 -0
- package/tab/tab.js +1 -1
- package/tab/tab.js.map +1 -1
- package/tab/types.d.ts +83 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as r,jsxs as o}from"react/jsx-runtime";import t,{useState as i,useRef as a,useEffect as l}from"react";import{VisuallyHidden as d,concatIds as s}from"../shared/accessibility/index.js";import"styled-components";import"../theme/index.js";import"../util/string-helper.js";import"../shared/dropdown-list/dropdown-label.styles.js";import{DropdownList as n}from"../shared/dropdown-list/dropdown-list.js";import{DropdownListState as p}from"../shared/dropdown-list/dropdown-list-state.js";import"../shared/dropdown-list/expandable-element.js";import"@lifesg/react-icons/caret-right";import"react-virtuoso";import"../button/button.style.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as c}from"../util/simple-id-generator.js";import"@react-aria/live-announcer";import{ElementWithDropdown as m}from"../shared/dropdown-wrapper/element-with-dropdown.js";import"../shared/dropdown-list/dropdown-list.styles.js";import"../shared/dropdown-list/dropdown-search.js";import"immer";import"../external/lodash/_getTag.js";import"../external/lodash/isArguments.js";import"../external/lodash/_baseGetTag.js";import"../external/lodash/isBuffer.js";import"../external/lodash/isTypedArray.js";import"../external/lodash/_Stack.js";import"../external/lodash/_SetCache.js";import"../external/lodash/_equalByTag.js";import"../shared/dropdown-list/nested-dropdown-list.styles.js";import"../shared/dropdown-list/virtuoso-components.js";import{ValueLabel as h,LabelContainer as b,PlaceholderLabel as u}from"../shared/dropdown-wrapper/dropdown-wrapper.styles.js";import{FieldWrapper as y,FieldSelector as x,Divider as j,FieldInput as f,SelectorReadOnly as w,StyledExpandableElement as g}from"./input-group-list-addon.style.js";const v=(t,v)=>{var{addon:$,error:O,onChange:S,readOnly:T,disabled:B,className:R,onBlur:
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as r,jsxs as o}from"react/jsx-runtime";import t,{useState as i,useRef as a,useEffect as l}from"react";import{VisuallyHidden as d,concatIds as s}from"../shared/accessibility/index.js";import"styled-components";import"../theme/index.js";import"../util/string-helper.js";import"../shared/dropdown-list/dropdown-label.styles.js";import{DropdownList as n}from"../shared/dropdown-list/dropdown-list.js";import{DropdownListState as p}from"../shared/dropdown-list/dropdown-list-state.js";import"../shared/dropdown-list/expandable-element.js";import"@lifesg/react-icons/caret-right";import"react-virtuoso";import"../button/button.style.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as c}from"../util/simple-id-generator.js";import"@react-aria/live-announcer";import{ElementWithDropdown as m}from"../shared/dropdown-wrapper/element-with-dropdown.js";import"../shared/dropdown-list/dropdown-list.styles.js";import"../shared/dropdown-list/dropdown-search.js";import"immer";import"../external/lodash/_getTag.js";import"../external/lodash/isArguments.js";import"../external/lodash/_baseGetTag.js";import"../external/lodash/isBuffer.js";import"../external/lodash/isTypedArray.js";import"../external/lodash/_Stack.js";import"../external/lodash/_SetCache.js";import"../external/lodash/_equalByTag.js";import"../shared/dropdown-list/nested-dropdown-list.styles.js";import"../shared/dropdown-list/virtuoso-components.js";import{ValueLabel as h,LabelContainer as b,PlaceholderLabel as u}from"../shared/dropdown-wrapper/dropdown-wrapper.styles.js";import{FieldWrapper as y,FieldSelector as x,Divider as j,FieldInput as f,SelectorReadOnly as w,StyledExpandableElement as g}from"./input-group-list-addon.style.js";const v=(t,v)=>{var{addon:$,error:O,onChange:S,readOnly:T,disabled:B,className:R,onBlur:D,noBorder:I,"data-testid":E,"aria-labelledby":N,"aria-describedby":_,"aria-invalid":C,"aria-label":k}=t,A=e(t,["addon","error","onChange","readOnly","disabled","className","onBlur","noBorder","data-testid","aria-labelledby","aria-describedby","aria-invalid","aria-label"]);const{valueExtractor:F,listExtractor:P,isOptionDisabled:H,enableSearch:L,hideNoResultsDisplay:Z,noResultsDescription:q,searchPlaceholder:G,searchFunction:V,onSearch:W,placeholder:z="Select",displayValueExtractor:J,"data-selector-testid":K,options:M,selectedOption:Q,onSelectOption:U,optionsLoadState:X,optionTruncationType:Y,onRetry:ee,onHideOptions:re,onShowOptions:oe,dropdownZIndex:te,dropdownRootNode:ie,"aria-label":ae}=$.attributes,{position:le}=$,[de,se]=i(Q),[ne,pe]=i(!1),[ce,me]=i(!1),he=c(),be=`${he}-listbox`,ue=`${he}-instruction`,ye=`${he}-combobox-label`,xe=`${he}-textbox-label`,je=a(null),fe=a(null);l((()=>{se(Q)}),[Q]);const we=()=>{if(de)return J?J(de):F?F(de):de.toString()},ge=e=>{e?null==oe||oe():null==re||re()},ve=(e,r)=>{var o;null===(o=fe.current)||void 0===o||o.focus(),se(e),pe(!1),ge(!1),null==U||U(e,r)},$e=()=>{ne&&(pe(!1),ge(!1))},Oe=()=>{pe(!0),ge(!0),me(!0)},Se=e=>{pe(!1),ge(!1),"click"!==e&&(me(!1),null==D||D())},Te=()=>{var e;null===(e=fe.current)||void 0===e||e.focus(),pe(!1),ge(!1)},Be=()=>o("div",{children:[r(g,{ref:fe,disabled:B,expanded:ne,listboxId:be,popupRole:"listbox",readOnly:T,"aria-labelledby":s(N,ye),"aria-describedby":s(_,ue),"aria-invalid":C,$noBorder:I,$position:le,children:r(b,{$disabled:B,children:de?r(h,{children:we()}):r(u,{children:z})})}),r(d,{id:ue,children:"Press space to open options"})]}),Re=()=>r(n,{listboxId:be,listItems:M,onSelectItem:ve,onDismiss:$e,valueExtractor:F,listExtractor:P,isOptionDisabled:H,enableSearch:L,hideNoResultsDisplay:Z,noResultsDescription:q,searchPlaceholder:G,searchFunction:V,onSearch:W,selectedItems:de?[de]:[],itemsLoadState:X,itemTruncationType:Y,onRetry:ee,matchElementWidth:!0});return r(p,{children:o(y,{$focused:ce,$disabled:B,$readOnly:T,$error:O,$position:le,ref:je,className:R,"data-testid":E,$noBorder:I,tabIndex:-1,onFocus:()=>{ce||ne||me(!0)},onBlur:e=>{ce&&!ne&&je.current&&!je.current.contains(e.relatedTarget)&&(me(!1),null==D||D())},children:[r(d,{"aria-hidden":!0,id:ye,children:ae}),r(x,{"data-testid":K,children:T?de?r(w,{"data-testid":"selector-label",tabIndex:0,role:"combobox","aria-haspopup":"listbox","aria-readonly":!0,"aria-expanded":!1,"aria-labelledby":N,"aria-describedby":_,"aria-invalid":C,children:r(h,{children:we()})}):null:r(m,{enabled:!T&&!B,isOpen:ne,renderElement:Be,renderDropdown:Re,onOpen:Oe,onClose:Se,onDismiss:Te,clickToToggle:!0,offset:8,alignment:"right"===le?"right":"left",fitAvailableHeight:!0,customZIndex:te,rootNode:ie,positionRef:je})}),r(j,{$readOnly:T,$position:le}),r(d,{"aria-hidden":!0,id:xe,children:k}),r(f,Object.assign({ref:v},A,{$position:le,$noBorder:I,readOnly:T,disabled:B,error:O,onChange:e=>{S&&S(e)},"data-testid":"input",styleType:"no-border","aria-labelledby":s(N,xe),"aria-describedby":_,"aria-invalid":C}))]})})},$=t.forwardRef(v);export{v as Component,$ as InputGroupListAddon};
|
|
2
2
|
//# sourceMappingURL=input-group-list-addon.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group-list-addon.js","sources":["../../src/input-group/input-group-list-addon.tsx"],"sourcesContent":["import { OpenChangeReason } from \"@floating-ui/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden, concatIds } from \"../shared/accessibility\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { useId } from \"../util\";\nimport {\n Divider,\n FieldInput,\n FieldSelector,\n FieldWrapper,\n SelectorReadOnly,\n StyledExpandableElement,\n} from \"./input-group-list-addon.style\";\nimport { InputGroupProps, ListAddon } from \"./types\";\n\nexport const Component = <T, V>(\n {\n addon,\n error,\n onChange,\n readOnly,\n disabled,\n className,\n onBlur,\n noBorder,\n \"data-testid\": testId,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": textboxAriaLabel,\n ...otherProps\n }: InputGroupProps<T, V>,\n ref: React.Ref<HTMLInputElement>\n) => {\n const {\n /* display props */\n valueExtractor,\n listExtractor,\n /* search props */\n enableSearch,\n hideNoResultsDisplay,\n noResultsDescription,\n searchPlaceholder,\n searchFunction,\n onSearch,\n /* list addon props */\n placeholder = \"Select\",\n displayValueExtractor,\n \"data-selector-testid\": selectorTestId,\n options,\n selectedOption,\n onSelectOption,\n optionsLoadState,\n optionTruncationType,\n onRetry,\n onHideOptions,\n onShowOptions,\n dropdownZIndex,\n dropdownRootNode,\n \"aria-label\": comboboxAriaLabel,\n } = addon!.attributes as ListAddon<T, V>;\n\n const { position } = addon!;\n\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selected, setSelected] = useState<T | undefined>(selectedOption);\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n const listboxId = `${internalId}-listbox`;\n const instructionId = `${internalId}-instruction`;\n const comboboxLabelId = `${internalId}-combobox-label`;\n const textboxLabelId = `${internalId}-textbox-label`;\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(selectedOption);\n }, [selectedOption]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getDisplayValue = () => {\n if (!selected) return;\n\n if (displayValueExtractor) {\n return displayValueExtractor(selected);\n }\n\n if (valueExtractor) {\n return valueExtractor(selected);\n }\n\n return selected.toString();\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (show) {\n onShowOptions?.();\n } else {\n onHideOptions?.();\n }\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setSelected(item);\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n onSelectOption?.(item, extractedValue);\n };\n\n const handleListDismiss = () => {\n if (showOptions) {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n }\n };\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (onChange) onChange(event);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderLabel = () => {\n if (!selected) {\n return <PlaceholderLabel>{placeholder}</PlaceholderLabel>;\n } else {\n return <ValueLabel>{getDisplayValue()}</ValueLabel>;\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer $disabled={disabled}>{renderLabel()}</LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <div>\n <StyledExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={listboxId}\n popupRole=\"listbox\"\n readOnly={readOnly}\n aria-labelledby={concatIds(ariaLabelledBy, comboboxLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, instructionId)}\n aria-invalid={ariaInvalid}\n $noBorder={noBorder}\n $position={position}\n >\n {renderSelectorContent()}\n </StyledExpandableElement>\n <VisuallyHidden id={instructionId}>\n Press space to open options\n </VisuallyHidden>\n </div>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n listboxId={listboxId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n enableSearch={enableSearch}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n searchPlaceholder={searchPlaceholder}\n searchFunction={searchFunction}\n onSearch={onSearch}\n selectedItems={selected ? [selected] : []}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n matchElementWidth\n />\n );\n };\n\n const renderSelector = () => {\n if (readOnly) {\n return selected ? (\n <SelectorReadOnly\n data-testid=\"selector-label\"\n tabIndex={0}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-readonly\n aria-expanded={false}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n <ValueLabel>{getDisplayValue()}</ValueLabel>\n </SelectorReadOnly>\n ) : null;\n } else {\n return (\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={position === \"right\" ? \"right\" : \"left\"}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n positionRef={nodeRef}\n />\n );\n }\n };\n\n return (\n <DropdownListState>\n <FieldWrapper\n $focused={focused}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n $position={position}\n ref={nodeRef}\n className={className}\n data-testid={testId}\n $noBorder={noBorder}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n >\n <VisuallyHidden aria-hidden id={comboboxLabelId}>\n {comboboxAriaLabel}\n </VisuallyHidden>\n <FieldSelector data-testid={selectorTestId}>\n {renderSelector()}\n </FieldSelector>\n <Divider $readOnly={readOnly} $position={position} />\n <VisuallyHidden aria-hidden id={textboxLabelId}>\n {textboxAriaLabel}\n </VisuallyHidden>\n <FieldInput\n ref={ref}\n {...otherProps}\n $position={position}\n $noBorder={noBorder}\n readOnly={readOnly}\n disabled={disabled}\n error={error}\n onChange={handleInputChange}\n data-testid=\"input\"\n styleType=\"no-border\"\n aria-labelledby={concatIds(ariaLabelledBy, textboxLabelId)}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n />\n </FieldWrapper>\n </DropdownListState>\n );\n};\n\nexport const InputGroupListAddon = React.forwardRef(Component);\n"],"names":["Component","_a","ref","addon","error","onChange","readOnly","disabled","className","onBlur","noBorder","testId","ariaLabelledBy","ariaDescribedBy","ariaInvalid","textboxAriaLabel","otherProps","__rest","valueExtractor","listExtractor","enableSearch","hideNoResultsDisplay","noResultsDescription","searchPlaceholder","searchFunction","onSearch","placeholder","displayValueExtractor","selectorTestId","options","selectedOption","onSelectOption","optionsLoadState","optionTruncationType","onRetry","onHideOptions","onShowOptions","dropdownZIndex","dropdownRootNode","comboboxAriaLabel","attributes","position","selected","setSelected","useState","showOptions","setShowOptions","focused","setFocused","internalId","useId","listboxId","instructionId","comboboxLabelId","textboxLabelId","nodeRef","useRef","selectorRef","useEffect","getDisplayValue","toString","triggerOptionDisplayCallback","show","handleListItemClick","item","extractedValue","current","focus","handleListDismiss","handleOpen","handleClose","reason","handleDismiss","renderElement","_jsxs","children","_jsx","StyledExpandableElement","expanded","popupRole","concatIds","$noBorder","$position","LabelContainer","$disabled","ValueLabel","PlaceholderLabel","VisuallyHidden","id","renderDropdown","DropdownList","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","DropdownListState","FieldWrapper","$focused","$readOnly","$error","tabIndex","onFocus","e","contains","relatedTarget","FieldSelector","SelectorReadOnly","role","ElementWithDropdown","enabled","isOpen","onOpen","onClose","clickToToggle","offset","alignment","fitAvailableHeight","customZIndex","rootNode","positionRef","Divider","FieldInput","Object","assign","event","styleType","InputGroupListAddon","React","forwardRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-group-list-addon.js","sources":["../../src/input-group/input-group-list-addon.tsx"],"sourcesContent":["import { OpenChangeReason } from \"@floating-ui/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden, concatIds } from \"../shared/accessibility\";\nimport { DropdownList, DropdownListState } from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { useId } from \"../util\";\nimport {\n Divider,\n FieldInput,\n FieldSelector,\n FieldWrapper,\n SelectorReadOnly,\n StyledExpandableElement,\n} from \"./input-group-list-addon.style\";\nimport { InputGroupProps, ListAddon } from \"./types\";\n\nexport const Component = <T, V>(\n {\n addon,\n error,\n onChange,\n readOnly,\n disabled,\n className,\n onBlur,\n noBorder,\n \"data-testid\": testId,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": textboxAriaLabel,\n ...otherProps\n }: InputGroupProps<T, V>,\n ref: React.Ref<HTMLInputElement>\n) => {\n const {\n /* display props */\n valueExtractor,\n listExtractor,\n isOptionDisabled,\n /* search props */\n enableSearch,\n hideNoResultsDisplay,\n noResultsDescription,\n searchPlaceholder,\n searchFunction,\n onSearch,\n /* list addon props */\n placeholder = \"Select\",\n displayValueExtractor,\n \"data-selector-testid\": selectorTestId,\n options,\n selectedOption,\n onSelectOption,\n optionsLoadState,\n optionTruncationType,\n onRetry,\n onHideOptions,\n onShowOptions,\n dropdownZIndex,\n dropdownRootNode,\n \"aria-label\": comboboxAriaLabel,\n } = addon!.attributes as ListAddon<T, V>;\n\n const { position } = addon!;\n\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selected, setSelected] = useState<T | undefined>(selectedOption);\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n const listboxId = `${internalId}-listbox`;\n const instructionId = `${internalId}-instruction`;\n const comboboxLabelId = `${internalId}-combobox-label`;\n const textboxLabelId = `${internalId}-textbox-label`;\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(selectedOption);\n }, [selectedOption]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getDisplayValue = () => {\n if (!selected) return;\n\n if (displayValueExtractor) {\n return displayValueExtractor(selected);\n }\n\n if (valueExtractor) {\n return valueExtractor(selected);\n }\n\n return selected.toString();\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (show) {\n onShowOptions?.();\n } else {\n onHideOptions?.();\n }\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setSelected(item);\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n onSelectOption?.(item, extractedValue);\n };\n\n const handleListDismiss = () => {\n if (showOptions) {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n }\n };\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (onChange) onChange(event);\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderLabel = () => {\n if (!selected) {\n return <PlaceholderLabel>{placeholder}</PlaceholderLabel>;\n } else {\n return <ValueLabel>{getDisplayValue()}</ValueLabel>;\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer $disabled={disabled}>{renderLabel()}</LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <div>\n <StyledExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={listboxId}\n popupRole=\"listbox\"\n readOnly={readOnly}\n aria-labelledby={concatIds(ariaLabelledBy, comboboxLabelId)}\n aria-describedby={concatIds(ariaDescribedBy, instructionId)}\n aria-invalid={ariaInvalid}\n $noBorder={noBorder}\n $position={position}\n >\n {renderSelectorContent()}\n </StyledExpandableElement>\n <VisuallyHidden id={instructionId}>\n Press space to open options\n </VisuallyHidden>\n </div>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n listboxId={listboxId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n isOptionDisabled={isOptionDisabled}\n enableSearch={enableSearch}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n searchPlaceholder={searchPlaceholder}\n searchFunction={searchFunction}\n onSearch={onSearch}\n selectedItems={selected ? [selected] : []}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n matchElementWidth\n />\n );\n };\n\n const renderSelector = () => {\n if (readOnly) {\n return selected ? (\n <SelectorReadOnly\n data-testid=\"selector-label\"\n tabIndex={0}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-readonly\n aria-expanded={false}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n <ValueLabel>{getDisplayValue()}</ValueLabel>\n </SelectorReadOnly>\n ) : null;\n } else {\n return (\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={position === \"right\" ? \"right\" : \"left\"}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n positionRef={nodeRef}\n />\n );\n }\n };\n\n return (\n <DropdownListState>\n <FieldWrapper\n $focused={focused}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n $position={position}\n ref={nodeRef}\n className={className}\n data-testid={testId}\n $noBorder={noBorder}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n >\n <VisuallyHidden aria-hidden id={comboboxLabelId}>\n {comboboxAriaLabel}\n </VisuallyHidden>\n <FieldSelector data-testid={selectorTestId}>\n {renderSelector()}\n </FieldSelector>\n <Divider $readOnly={readOnly} $position={position} />\n <VisuallyHidden aria-hidden id={textboxLabelId}>\n {textboxAriaLabel}\n </VisuallyHidden>\n <FieldInput\n ref={ref}\n {...otherProps}\n $position={position}\n $noBorder={noBorder}\n readOnly={readOnly}\n disabled={disabled}\n error={error}\n onChange={handleInputChange}\n data-testid=\"input\"\n styleType=\"no-border\"\n aria-labelledby={concatIds(ariaLabelledBy, textboxLabelId)}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n />\n </FieldWrapper>\n </DropdownListState>\n );\n};\n\nexport const InputGroupListAddon = React.forwardRef(Component);\n"],"names":["Component","_a","ref","addon","error","onChange","readOnly","disabled","className","onBlur","noBorder","testId","ariaLabelledBy","ariaDescribedBy","ariaInvalid","textboxAriaLabel","otherProps","__rest","valueExtractor","listExtractor","isOptionDisabled","enableSearch","hideNoResultsDisplay","noResultsDescription","searchPlaceholder","searchFunction","onSearch","placeholder","displayValueExtractor","selectorTestId","options","selectedOption","onSelectOption","optionsLoadState","optionTruncationType","onRetry","onHideOptions","onShowOptions","dropdownZIndex","dropdownRootNode","comboboxAriaLabel","attributes","position","selected","setSelected","useState","showOptions","setShowOptions","focused","setFocused","internalId","useId","listboxId","instructionId","comboboxLabelId","textboxLabelId","nodeRef","useRef","selectorRef","useEffect","getDisplayValue","toString","triggerOptionDisplayCallback","show","handleListItemClick","item","extractedValue","current","focus","handleListDismiss","handleOpen","handleClose","reason","handleDismiss","renderElement","_jsxs","children","_jsx","StyledExpandableElement","expanded","popupRole","concatIds","$noBorder","$position","LabelContainer","$disabled","ValueLabel","PlaceholderLabel","VisuallyHidden","id","renderDropdown","DropdownList","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","DropdownListState","FieldWrapper","$focused","$readOnly","$error","tabIndex","onFocus","e","contains","relatedTarget","FieldSelector","SelectorReadOnly","role","ElementWithDropdown","enabled","isOpen","onOpen","onClose","clickToToggle","offset","alignment","fitAvailableHeight","customZIndex","rootNode","positionRef","Divider","FieldInput","Object","assign","event","styleType","InputGroupListAddon","React","forwardRef"],"mappings":"qyDAqBaA,EAAY,CACrBC,EAgBAC,KAhBA,IAAAC,MACIA,EAAKC,MACLA,EAAKC,SACLA,EAAQC,SACRA,EAAQC,SACRA,EAAQC,UACRA,EAASC,OACTA,EAAMC,SACNA,EACA,cAAeC,EACf,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAChB,aAAcC,GAAgBd,EAC3Be,EAAUC,EAAAhB,EAdjB,mKAkBA,MAAMiB,eAEFA,EAAcC,cACdA,EAAaC,iBACbA,EAAgBC,aAEhBA,EAAYC,qBACZA,EAAoBC,qBACpBA,EAAoBC,kBACpBA,EAAiBC,eACjBA,EAAcC,SACdA,EAAQC,YAERA,EAAc,SAAQC,sBACtBA,EACA,uBAAwBC,EAAcC,QACtCA,EAAOC,eACPA,EAAcC,eACdA,EAAcC,iBACdA,EAAgBC,qBAChBA,EAAoBC,QACpBA,GAAOC,cACPA,GAAaC,cACbA,GAAaC,eACbA,GAAcC,iBACdA,GACA,aAAcC,IACdrC,EAAOsC,YAELC,SAAEA,IAAavC,GAKdwC,GAAUC,IAAeC,EAAwBd,IACjDe,GAAaC,IAAkBF,GAAkB,IACjDG,GAASC,IAAcJ,GAAkB,GAC1CK,GAAaC,IACbC,GAAY,GAAGF,aACfG,GAAgB,GAAGH,iBACnBI,GAAkB,GAAGJ,oBACrBK,GAAiB,GAAGL,mBAEpBM,GAAUC,EAAuB,MACjCC,GAAcD,EAA0B,MAK9CE,GAAU,KACNf,GAAYb,EAAe,GAC5B,CAACA,IAKJ,MAAM6B,GAAkB,KACpB,GAAKjB,GAEL,OAAIf,EACOA,EAAsBe,IAG7BzB,EACOA,EAAeyB,IAGnBA,GAASkB,UAAU,EAGxBC,GAAgCC,IAC9BA,EACA1B,UAAAA,KAEAD,UAAAA,IACJ,EAME4B,GAAsB,CAACC,EAASC,WACf,QAAnBjE,EAAAyD,GAAYS,eAAO,IAAAlE,GAAAA,EAAEmE,QACrBxB,GAAYqB,GACZlB,IAAe,GACfe,IAA6B,GAE7B9B,SAAAA,EAAiBiC,EAAMC,EAAe,EAGpCG,GAAoB,KAClBvB,KACAC,IAAe,GACfe,IAA6B,GACjC,EAyBEQ,GAAa,KACfvB,IAAe,GACfe,IAA6B,GAC7Bb,IAAW,EAAK,EAGdsB,GAAeC,IACjBzB,IAAe,GACfe,IAA6B,GAGd,UAAXU,IACAvB,IAAW,GACXxC,SAAAA,IACJ,EAGEgE,GAAgB,WACC,QAAnBxE,EAAAyD,GAAYS,eAAO,IAAAlE,GAAAA,EAAEmE,QACrBrB,IAAe,GACfe,IAA6B,EAAM,EAkBjCY,GAAgB,IAEdC,EAAA,MAAA,CAAAC,SAAA,CACIC,EAACC,EAAuB,CACpB5E,IAAKwD,GACLnD,SAAUA,EACVwE,SAAUjC,GACVM,UAAWA,GACX4B,UAAU,UACV1E,SAAUA,oBACO2E,EAAUrE,EAAgB0C,IAAgB,mBACzC2B,EAAUpE,EAAiBwC,IAAc,eAC7CvC,EAAWoE,UACdxE,EAAQyE,UACRzC,GAAQkC,SAjB/BC,EAACO,EAAc,CAAAC,UAAY9E,EAAQqE,SAR9BjC,GAGMkC,EAACS,EAAU,CAAAV,SAAEhB,OAFbiB,EAACU,EAAgB,CAAAX,SAAEjD,QA4BtBkD,EAACW,EAAc,CAACC,GAAIpC,GAAauB,SAAA,mCAOvCc,GAAiB,IAEfb,EAACc,GACGvC,UAAWA,GACXwC,UAAW9D,EACX+D,aAAc7B,GACd8B,UAAWzB,GACXnD,eAAgBA,EAChBC,cAAeA,EACfC,iBAAkBA,EAClBC,aAAcA,EACdC,qBAAsBA,EACtBC,qBAAsBA,EACtBC,kBAAmBA,EACnBC,eAAgBA,EAChBC,SAAUA,EACVqE,cAAepD,GAAW,CAACA,IAAY,GACvCqD,eAAgB/D,EAChBgE,mBAAoB/D,EACpBC,QAASA,GACT+D,mBAAiB,IA4C7B,OACIrB,EAACsB,EAAiB,CAAAvB,SACdD,EAACyB,EAAY,CAAAC,SACCrD,GAAOqC,UACN9E,EAAQ+F,UACRhG,EAAQiG,OACXnG,EAAK+E,UACFzC,GACXxC,IAAKsD,GACLhD,UAAWA,EAAS,cACPG,EAAMuE,UACRxE,EACX8F,UAAU,EACVC,QA9JY,KACfzD,IAAYF,IACbG,IAAW,EACf,EA4JQxC,OAzJYiG,IAEhB1D,KACCF,IACDU,GAAQW,UACPX,GAAQW,QAAQwC,SAASD,EAAEE,iBAE5B3D,IAAW,GACXxC,SAAAA,IACJ,EAgJ8BmE,SAAA,CAEtBC,EAACW,EAAc,CAAA,eAAA,EAAaC,GAAInC,GAAesB,SAC1CpC,KAELqC,EAACgC,EAAa,CAAA,cAAchF,EAAc+C,SAzD9CtE,EACOqC,GACHkC,EAACiC,EAAgB,CAAA,cACD,iBACZN,SAAU,EACVO,KAAK,2BACS,UAAS,iBAAA,EAAA,iBAER,EAAK,kBACHnG,EAAc,mBACbC,iBACJC,EAAW8D,SAEzBC,EAACS,EAAU,CAAAV,SAAEhB,SAEjB,KAGAiB,EAACmC,EAAmB,CAChBC,SAAU3G,IAAaC,EACvB2G,OAAQpE,GACR4B,cAAeA,GACfgB,eAAgBA,GAChByB,OAAQ7C,GACR8C,QAAS7C,GACTuB,UAAWrB,GACX4C,eAAa,EACbC,OAAQ,EACRC,UAAwB,UAAb7E,GAAuB,QAAU,OAC5C8E,oBAAkB,EAClBC,aAAcnF,GACdoF,SAAUnF,GACVoF,YAAanE,OA4BjBqB,EAAC+C,EAAO,CAAAtB,UAAYhG,EAAQ6E,UAAazC,KACzCmC,EAACW,EAAc,CAAA,eAAA,EAAaC,GAAIlC,GAAcqB,SACzC7D,IAEL8D,EAACgD,EAAUC,OAAAC,OAAA,CACP7H,IAAKA,GACDc,EAAU,CAAAmE,UACHzC,GAAQwC,UACRxE,EACXJ,SAAUA,EACVC,SAAUA,EACVH,MAAOA,EACPC,SAvLW2H,IACnB3H,GAAUA,EAAS2H,EAAM,EAsLU,cACf,QACZC,UAAU,YAAW,kBACJhD,EAAUrE,EAAgB2C,IAAe,mBACxC1C,EAAe,eACnBC,SAGN,EAIfoH,EAAsBC,EAAMC,WAAWpI"}
|
|
@@ -2,7 +2,7 @@ import { RefObject } from "react";
|
|
|
2
2
|
import { InputSelectOptionsProps, InputSelectSharedProps } from "../input-select/types";
|
|
3
3
|
import { DropdownCustomLabelProps, DropdownDisplayProps, DropdownSearchProps, DropdownVariantType } from "../shared/dropdown-list/types";
|
|
4
4
|
import { DropdownAlignmentType } from "../shared/dropdown-wrapper";
|
|
5
|
-
export interface InputMultiSelectProps<T, V> extends React.HTMLAttributes<HTMLElement>, InputSelectOptionsProps<T>, InputSelectSharedProps<T>, DropdownDisplayProps<T, V>, DropdownSearchProps<T> {
|
|
5
|
+
export interface InputMultiSelectProps<T, V> extends React.HTMLAttributes<HTMLElement>, InputSelectOptionsProps<T>, InputSelectSharedProps<T>, Omit<DropdownDisplayProps<T, V>, "isOptionDisabled">, DropdownSearchProps<T> {
|
|
6
6
|
readOnly?: boolean | undefined;
|
|
7
7
|
selectedOptions?: T[] | undefined;
|
|
8
8
|
onSelectOptions?: ((options: T[]) => void) | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { InputRangeSelectProps } from "./types";
|
|
2
|
-
export declare const InputRangeSelect: <T, V>({ selectedOptions, placeholders, options, disabled, className, readOnly, error, "data-testid": testId, id, enableSearch, searchFunction, searchPlaceholder, valueExtractor, valueToStringFunction, listExtractor, displayValueExtractor, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, renderCustomSelectedOption, renderListItem, renderCustomCallToAction, alignment, dropdownZIndex, dropdownRootNode, dropdownWidth, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...otherProps }: InputRangeSelectProps<T, V>) => JSX.Element;
|
|
2
|
+
export declare const InputRangeSelect: <T, V>({ selectedOptions, placeholders, options, disabled, className, readOnly, error, "data-testid": testId, id, enableSearch, searchFunction, searchPlaceholder, valueExtractor, valueToStringFunction, listExtractor, isOptionDisabled, displayValueExtractor, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, renderCustomSelectedOption, renderListItem, renderCustomCallToAction, alignment, dropdownZIndex, dropdownRootNode, dropdownWidth, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...otherProps }: InputRangeSelectProps<T, V>) => JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as o,jsxs as r}from"react/jsx-runtime";import{useState as t,useRef as n,useEffect as i,useMemo as l}from"react";import{ClearIcon as d}from"../input/input.style.js";import{VisuallyHidden as a,concatIds as s}from"../shared/accessibility/index.js";import"styled-components";import"../theme/index.js";import{StringHelper as c}from"../util/string-helper.js";import"../shared/dropdown-list/dropdown-label.styles.js";import{DropdownList as p}from"../shared/dropdown-list/dropdown-list.js";import{DropdownListState as m}from"../shared/dropdown-list/dropdown-list-state.js";import"../shared/dropdown-list/expandable-element.js";import"@lifesg/react-icons/caret-right";import"react-virtuoso";import"../button/button.style.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as u}from"../util/simple-id-generator.js";import"@react-aria/live-announcer";import{ElementWithDropdown as h}from"../shared/dropdown-wrapper/element-with-dropdown.js";import"../shared/dropdown-list/dropdown-list.styles.js";import"../shared/dropdown-list/dropdown-search.js";import"immer";import"../external/lodash/_getTag.js";import"../external/lodash/isArguments.js";import"../external/lodash/_baseGetTag.js";import"../external/lodash/isBuffer.js";import"../external/lodash/isTypedArray.js";import"../external/lodash/_Stack.js";import"../external/lodash/_SetCache.js";import"../external/lodash/_equalByTag.js";import"../shared/dropdown-list/nested-dropdown-list.styles.js";import"../shared/dropdown-list/virtuoso-components.js";import{Wrapper as f,PlaceholderLabel as v,ValueLabel as b}from"../shared/dropdown-wrapper/dropdown-wrapper.styles.js";import{RangeInputInnerContainer as w}from"../shared/range-input-inner-container/range-input-inner-container.js";import{StyledInputWrapper as y,ClearIconContainer as j,RangeSelectorButton as g}from"./input-range-select.style.js";const x=x=>{var{selectedOptions:S,placeholders:
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as o,jsxs as r}from"react/jsx-runtime";import{useState as t,useRef as n,useEffect as i,useMemo as l}from"react";import{ClearIcon as d}from"../input/input.style.js";import{VisuallyHidden as a,concatIds as s}from"../shared/accessibility/index.js";import"styled-components";import"../theme/index.js";import{StringHelper as c}from"../util/string-helper.js";import"../shared/dropdown-list/dropdown-label.styles.js";import{DropdownList as p}from"../shared/dropdown-list/dropdown-list.js";import{DropdownListState as m}from"../shared/dropdown-list/dropdown-list-state.js";import"../shared/dropdown-list/expandable-element.js";import"@lifesg/react-icons/caret-right";import"react-virtuoso";import"../button/button.style.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as u}from"../util/simple-id-generator.js";import"@react-aria/live-announcer";import{ElementWithDropdown as h}from"../shared/dropdown-wrapper/element-with-dropdown.js";import"../shared/dropdown-list/dropdown-list.styles.js";import"../shared/dropdown-list/dropdown-search.js";import"immer";import"../external/lodash/_getTag.js";import"../external/lodash/isArguments.js";import"../external/lodash/_baseGetTag.js";import"../external/lodash/isBuffer.js";import"../external/lodash/isTypedArray.js";import"../external/lodash/_Stack.js";import"../external/lodash/_SetCache.js";import"../external/lodash/_equalByTag.js";import"../shared/dropdown-list/nested-dropdown-list.styles.js";import"../shared/dropdown-list/virtuoso-components.js";import{Wrapper as f,PlaceholderLabel as v,ValueLabel as b}from"../shared/dropdown-wrapper/dropdown-wrapper.styles.js";import{RangeInputInnerContainer as w}from"../shared/range-input-inner-container/range-input-inner-container.js";import{StyledInputWrapper as y,ClearIconContainer as j,RangeSelectorButton as g}from"./input-range-select.style.js";const x=x=>{var{selectedOptions:S,placeholders:O={from:"Select",to:"Select"},options:T,disabled:C,className:$,readOnly:D,error:E,"data-testid":I,id:A,enableSearch:L=!1,searchFunction:_,searchPlaceholder:F,valueExtractor:N,valueToStringFunction:R,listExtractor:k,isOptionDisabled:P,displayValueExtractor:B,onSelectOption:H,onShowOptions:W,onHideOptions:Z,onRetry:V,optionsLoadState:q={from:"success",to:"success"},optionTruncationType:G="middle",renderCustomSelectedOption:K,renderListItem:z,renderCustomCallToAction:J,alignment:M,dropdownZIndex:Q,dropdownRootNode:U,dropdownWidth:X,"aria-labelledby":Y,"aria-describedby":ee}=x,oe=e(x,["selectedOptions","placeholders","options","disabled","className","readOnly","error","data-testid","id","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","isOptionDisabled","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","renderCustomCallToAction","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","aria-labelledby","aria-describedby"]);const[re,te]=t(),[ne,ie]=t(),[le,de]=t("none"),ae="none"!==le,se={from:n(null),to:n(null)},ce=n(null),pe=u(),me=`${pe}-range-listbox`,ue=`${pe}-from-label`,he=`${pe}-to-label`;i((()=>{te(null==S?void 0:S.from),ie(null==S?void 0:S.to)}),[S]),i((()=>{var e;ae&&"to"===le&&(null===(e=ce.current)||void 0===e||e.refocus({index:0}))}),[ae,le]);const fe=e=>{e||null==Z||Z(),e&&(null==W||W())},ve=e=>{var o,r;const t="from"===e?re:ne;if(!t)return"";if(B)return B(t);if(N){const e=N(t);return R?R(e):null!==(r=null===(o=null==e?void 0:e.toString)||void 0===o?void 0:o.call(e))&&void 0!==r?r:""}return t.toString()},be=(e,o)=>{var r;if("middle"===G){let t=0;return(null===(r=se[e])||void 0===r?void 0:r.current)&&(t=se[e].current.getBoundingClientRect().width),c.truncateOneLine(o,t,120,8)}return o},we=()=>{switch(le){case"from":return"start";case"to":return"end";case"none":return le}},ye=l((()=>{var e;return"none"===le?[]:null!==(e=null==T?void 0:T[le])&&void 0!==e?e:[]}),[le,T]),je=l((()=>{if("none"===le)return[];const e="from"===le?re:ne;return e?[e]:[]}),[le,re,ne]),ge=e=>{if(C||D)return;de("to"!==e||re?e:"from"),fe(!0)},xe=e=>{var o;null===(o=se[e].current)||void 0===o||o.focus()},Se=e=>s("from"===e?ue:he,Y),Oe=e=>o=>{o.stopPropagation(),o.preventDefault(),ge(e)},Te=e=>o=>{if(!C&&!D)switch(o.key){case"Enter":case" ":case"ArrowDown":o.preventDefault(),ge(e)}},Ce=(e,o)=>{if("none"!==le){if("from"===le)return te(e),null==H||H({from:e},o),ie(void 0),de("to"),fe(!0),void xe("to");ie(e),null==H||H({to:e},o),de("none"),fe(!1),xe("to")}},$e=()=>{const e=le;de("none"),fe(!1),xe("to"===e?"to":"from"),re&&ne||(te(void 0),ie(void 0))},De=e=>{e.stopPropagation(),e.preventDefault(),te(void 0),ie(void 0),null==H||H({from:void 0,to:void 0},void 0),xe("from")},Ee=e=>{const r="from"===e?re:ne;return r?K?K(r):o(b,{$truncateType:G,children:be(e,ve(e))}):o(v,{$truncateType:G,children:be(e,(null==O?void 0:O[e])||"")})},Ie=e=>o(g,{type:"button",role:"combobox","aria-labelledby":Se(e),"aria-describedby":ee,"aria-expanded":ae&&le===e,"aria-controls":me,"aria-disabled":C,"aria-readonly":D,onClick:Oe(e),onKeyDown:Te(e),ref:se[e],tabIndex:0,children:Ee(e)});return o(f,Object.assign({id:A},oe,{children:o(m,{children:o(h,{enabled:!D&&!C,isOpen:ae,renderElement:()=>r(y,{className:$,"data-testid":I,$disabled:C,$readOnly:D,$error:E,$focused:ae,children:[o(a,{id:ue,children:(null==O?void 0:O.from)||"Select From"}),o(a,{id:he,children:(null==O?void 0:O.to)||"Select To"}),r(w,{currentActive:we(),error:E,children:[Ie("from"),Ie("to")]}),!ae&&re&&ne&&!D&&!C&&o(j,{onClick:De,type:"button","aria-label":"Clear",children:o(d,{"aria-hidden":!0})})]}),renderDropdown:()=>o(p,{ref:ce,"data-testid":`${I}-dropdown`,listboxId:me,ariaLabel:"from"===le?`Selecting for: ${null==O?void 0:O.from}`:"to"===le?`Selecting for: ${null==O?void 0:O.to}`:void 0,listItems:ye,onSelectItem:Ce,onDismiss:$e,valueExtractor:N,listExtractor:k,isOptionDisabled:P,selectedItems:je,itemsLoadState:q[le],itemTruncationType:G,onRetry:V,width:X,matchElementWidth:!X,enableSearch:L,searchFunction:_,searchPlaceholder:F,renderListItem:z,renderCustomCallToAction:J}),onOpen:()=>{C||D||"none"===le&&(de("from"),fe(!0))},onClose:()=>{de("none"),fe(!1),re&&ne||(te(void 0),ie(void 0))},onDismiss:$e,clickToToggle:!1,offset:8,alignment:M,fitAvailableHeight:!0,customZIndex:Q,rootNode:U})})}))};export{x as InputRangeSelect};
|
|
2
2
|
//# sourceMappingURL=input-range-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-range-select.js","sources":["../../src/input-range-select/input-range-select.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { ClearIcon } from \"../input/input.style\";\nimport { VisuallyHidden, concatIds } from \"../shared/accessibility\";\nimport {\n DropdownList,\n DropdownListApi,\n DropdownListState,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n PlaceholderLabel,\n ValueLabel,\n Wrapper,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../shared/range-input-inner-container\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport {\n ClearIconContainer,\n RangeSelectorButton,\n StyledInputWrapper,\n} from \"./input-range-select.style\";\nimport { InputRangeSelectProps } from \"./types\";\n\ntype RangeType = \"from\" | \"to\";\n\nexport const InputRangeSelect = <T, V>({\n selectedOptions,\n placeholders = { from: \"Select\", to: \"Select\" },\n options,\n disabled,\n className,\n readOnly,\n error,\n \"data-testid\": testId,\n id,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = { from: \"success\", to: \"success\" },\n optionTruncationType = \"middle\",\n renderCustomSelectedOption,\n renderListItem,\n renderCustomCallToAction,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: InputRangeSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selectedFromValue, setSelectedFromValue] = useState<T | undefined>();\n const [selectedToValue, setSelectedToValue] = useState<T | undefined>();\n const [focusedInput, setFocusedInput] = useState<RangeType | \"none\">(\n \"none\"\n );\n const isOpen = focusedInput !== \"none\";\n\n const labelButtonRef = {\n from: useRef<HTMLButtonElement>(null),\n to: useRef<HTMLButtonElement>(null),\n };\n const dropdownRef = useRef<DropdownListApi>(null);\n\n const internalId = useId();\n const listboxId = `${internalId}-range-listbox`;\n const fromLabelId = `${internalId}-from-label`;\n const toLabelId = `${internalId}-to-label`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelectedFromValue(selectedOptions?.from);\n setSelectedToValue(selectedOptions?.to);\n }, [selectedOptions]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n if (focusedInput === \"to\") {\n dropdownRef.current?.refocus({ index: 0 });\n }\n }, [isOpen, focusedInput]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show) onHideOptions?.();\n if (show) onShowOptions?.();\n };\n\n const getDisplayValue = (rangeType: RangeType): string => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n if (!selected) return \"\";\n\n if (displayValueExtractor) return displayValueExtractor(selected);\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString?.() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (type: RangeType, value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelButtonRef[type]?.current) {\n widthOfElement =\n labelButtonRef[type].current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const getCurrentFocused = (): \"none\" | \"start\" | \"end\" => {\n switch (focusedInput) {\n case \"from\":\n return \"start\";\n case \"to\":\n return \"end\";\n case \"none\":\n return focusedInput;\n }\n };\n\n const currentOptions = useMemo(() => {\n if (focusedInput === \"none\") return [];\n return options?.[focusedInput] ?? [];\n }, [focusedInput, options]);\n\n const currentSelectedItems = useMemo(() => {\n if (focusedInput === \"none\") return [];\n const selected =\n focusedInput === \"from\" ? selectedFromValue : selectedToValue;\n return selected ? [selected] : [];\n }, [focusedInput, selectedFromValue, selectedToValue]);\n\n const openDropdownFor = (rangeType: RangeType) => {\n if (disabled || readOnly) return;\n\n const nextFocusedInput =\n rangeType === \"to\" && !selectedFromValue ? \"from\" : rangeType;\n\n setFocusedInput(nextFocusedInput);\n triggerOptionDisplayCallback(true);\n };\n\n const focusButton = (type: RangeType) => {\n labelButtonRef[type].current?.focus();\n };\n\n const getButtonLabelledBy = (rangeType: RangeType) => {\n const rangeLabelId = rangeType === \"from\" ? fromLabelId : toLabelId;\n return concatIds(rangeLabelId, ariaLabelledBy);\n };\n\n const getDropdownAriaLabel = () => {\n if (focusedInput === \"from\") {\n return `Selecting for: ${placeholders?.from}`;\n }\n\n if (focusedInput === \"to\") {\n return `Selecting for: ${placeholders?.to}`;\n }\n\n return undefined;\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleSelectorClick =\n (rangeType: RangeType) => (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n openDropdownFor(rangeType);\n };\n\n const handleSelectorKeyDown =\n (rangeType: RangeType) =>\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || readOnly) return;\n\n switch (event.key) {\n case \"Enter\":\n case \" \":\n case \"ArrowDown\":\n event.preventDefault();\n openDropdownFor(rangeType);\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, extractedValue: V) => {\n if (focusedInput === \"none\") return;\n\n if (focusedInput === \"from\") {\n setSelectedFromValue(item);\n onSelectOption?.({ from: item }, extractedValue);\n\n setSelectedToValue(undefined);\n setFocusedInput(\"to\");\n triggerOptionDisplayCallback(true);\n focusButton(\"to\");\n return;\n }\n\n setSelectedToValue(item);\n onSelectOption?.({ to: item }, extractedValue);\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n focusButton(\"to\");\n };\n\n const handleDismiss = () => {\n const last = focusedInput;\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (last === \"to\") focusButton(\"to\");\n else focusButton(\"from\");\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleClose = () => {\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleOpen = () => {\n if (disabled || readOnly) return;\n\n if (focusedInput === \"none\") {\n setFocusedInput(\"from\");\n triggerOptionDisplayCallback(true);\n }\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n onSelectOption?.({ from: undefined, to: undefined }, undefined);\n\n focusButton(\"from\");\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n const renderLabel = (rangeType: RangeType) => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n\n if (!selected) {\n return (\n <PlaceholderLabel $truncateType={optionTruncationType}>\n {truncateValue(rangeType, placeholders?.[rangeType] || \"\")}\n </PlaceholderLabel>\n );\n }\n\n if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n }\n\n return (\n <ValueLabel $truncateType={optionTruncationType}>\n {truncateValue(rangeType, getDisplayValue(rangeType))}\n </ValueLabel>\n );\n };\n\n const renderSelectorContent = (rangeType: RangeType) => (\n <RangeSelectorButton\n type=\"button\"\n role=\"combobox\"\n aria-labelledby={getButtonLabelledBy(rangeType)}\n aria-describedby={ariaDescribedBy}\n aria-expanded={isOpen && focusedInput === rangeType}\n aria-controls={listboxId}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n onClick={handleSelectorClick(rangeType)}\n onKeyDown={handleSelectorKeyDown(rangeType)}\n ref={labelButtonRef[rangeType]}\n tabIndex={0}\n >\n {renderLabel(rangeType)}\n </RangeSelectorButton>\n );\n\n const renderElement = () => {\n return (\n <StyledInputWrapper\n className={className}\n data-testid={testId}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n $focused={isOpen}\n >\n <VisuallyHidden id={fromLabelId}>\n {placeholders?.from || \"Select From\"}\n </VisuallyHidden>\n <VisuallyHidden id={toLabelId}>\n {placeholders?.to || \"Select To\"}\n </VisuallyHidden>\n\n <RangeInputInnerContainer\n currentActive={getCurrentFocused()}\n error={error}\n >\n {renderSelectorContent(\"from\")}\n {renderSelectorContent(\"to\")}\n </RangeInputInnerContainer>\n\n {!isOpen &&\n selectedFromValue &&\n selectedToValue &&\n !readOnly &&\n !disabled && (\n <ClearIconContainer\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n >\n <ClearIcon aria-hidden />\n </ClearIconContainer>\n )}\n </StyledInputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n ref={dropdownRef}\n data-testid={`${testId}-dropdown`}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n listItems={currentOptions}\n onSelectItem={handleListItemClick}\n onDismiss={handleDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n selectedItems={currentSelectedItems}\n itemsLoadState={optionsLoadState[focusedInput as RangeType]}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n width={dropdownWidth}\n matchElementWidth={!dropdownWidth}\n enableSearch={enableSearch}\n searchFunction={searchFunction}\n searchPlaceholder={searchPlaceholder}\n renderListItem={renderListItem}\n renderCustomCallToAction={renderCustomCallToAction}\n />\n );\n };\n\n return (\n <Wrapper id={id} {...otherProps}>\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n </Wrapper>\n );\n};\n"],"names":["InputRangeSelect","_a","selectedOptions","placeholders","from","to","options","disabled","className","readOnly","error","testId","id","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","renderCustomCallToAction","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaLabelledBy","ariaDescribedBy","otherProps","__rest","selectedFromValue","setSelectedFromValue","useState","selectedToValue","setSelectedToValue","focusedInput","setFocusedInput","isOpen","labelButtonRef","useRef","dropdownRef","internalId","useId","listboxId","fromLabelId","toLabelId","useEffect","current","refocus","index","triggerOptionDisplayCallback","show","getDisplayValue","rangeType","selected","value","_b","toString","call","truncateValue","type","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","getCurrentFocused","currentOptions","useMemo","currentSelectedItems","openDropdownFor","focusButton","focus","getButtonLabelledBy","concatIds","handleSelectorClick","event","stopPropagation","preventDefault","handleSelectorKeyDown","key","handleListItemClick","item","extractedValue","undefined","handleDismiss","last","handleClear","renderLabel","_jsx","ValueLabel","$truncateType","PlaceholderLabel","renderSelectorContent","RangeSelectorButton","role","onClick","onKeyDown","ref","tabIndex","children","Wrapper","Object","assign","DropdownListState","ElementWithDropdown","enabled","renderElement","_jsxs","StyledInputWrapper","$disabled","$readOnly","$focused","VisuallyHidden","RangeInputInnerContainer","currentActive","ClearIconContainer","ClearIcon","renderDropdown","DropdownList","ariaLabel","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-range-select.js","sources":["../../src/input-range-select/input-range-select.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { ClearIcon } from \"../input/input.style\";\nimport { VisuallyHidden, concatIds } from \"../shared/accessibility\";\nimport {\n DropdownList,\n DropdownListApi,\n DropdownListState,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n PlaceholderLabel,\n ValueLabel,\n Wrapper,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { RangeInputInnerContainer } from \"../shared/range-input-inner-container\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport {\n ClearIconContainer,\n RangeSelectorButton,\n StyledInputWrapper,\n} from \"./input-range-select.style\";\nimport { InputRangeSelectProps } from \"./types\";\n\ntype RangeType = \"from\" | \"to\";\n\nexport const InputRangeSelect = <T, V>({\n selectedOptions,\n placeholders = { from: \"Select\", to: \"Select\" },\n options,\n disabled,\n className,\n readOnly,\n error,\n \"data-testid\": testId,\n id,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n isOptionDisabled,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = { from: \"success\", to: \"success\" },\n optionTruncationType = \"middle\",\n renderCustomSelectedOption,\n renderListItem,\n renderCustomCallToAction,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: InputRangeSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [selectedFromValue, setSelectedFromValue] = useState<T | undefined>();\n const [selectedToValue, setSelectedToValue] = useState<T | undefined>();\n const [focusedInput, setFocusedInput] = useState<RangeType | \"none\">(\n \"none\"\n );\n const isOpen = focusedInput !== \"none\";\n\n const labelButtonRef = {\n from: useRef<HTMLButtonElement>(null),\n to: useRef<HTMLButtonElement>(null),\n };\n const dropdownRef = useRef<DropdownListApi>(null);\n\n const internalId = useId();\n const listboxId = `${internalId}-range-listbox`;\n const fromLabelId = `${internalId}-from-label`;\n const toLabelId = `${internalId}-to-label`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelectedFromValue(selectedOptions?.from);\n setSelectedToValue(selectedOptions?.to);\n }, [selectedOptions]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n if (focusedInput === \"to\") {\n dropdownRef.current?.refocus({ index: 0 });\n }\n }, [isOpen, focusedInput]);\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (!show) onHideOptions?.();\n if (show) onShowOptions?.();\n };\n\n const getDisplayValue = (rangeType: RangeType): string => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n if (!selected) return \"\";\n\n if (displayValueExtractor) return displayValueExtractor(selected);\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString?.() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (type: RangeType, value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelButtonRef[type]?.current) {\n widthOfElement =\n labelButtonRef[type].current.getBoundingClientRect().width;\n }\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const getCurrentFocused = (): \"none\" | \"start\" | \"end\" => {\n switch (focusedInput) {\n case \"from\":\n return \"start\";\n case \"to\":\n return \"end\";\n case \"none\":\n return focusedInput;\n }\n };\n\n const currentOptions = useMemo(() => {\n if (focusedInput === \"none\") return [];\n return options?.[focusedInput] ?? [];\n }, [focusedInput, options]);\n\n const currentSelectedItems = useMemo(() => {\n if (focusedInput === \"none\") return [];\n const selected =\n focusedInput === \"from\" ? selectedFromValue : selectedToValue;\n return selected ? [selected] : [];\n }, [focusedInput, selectedFromValue, selectedToValue]);\n\n const openDropdownFor = (rangeType: RangeType) => {\n if (disabled || readOnly) return;\n\n const nextFocusedInput =\n rangeType === \"to\" && !selectedFromValue ? \"from\" : rangeType;\n\n setFocusedInput(nextFocusedInput);\n triggerOptionDisplayCallback(true);\n };\n\n const focusButton = (type: RangeType) => {\n labelButtonRef[type].current?.focus();\n };\n\n const getButtonLabelledBy = (rangeType: RangeType) => {\n const rangeLabelId = rangeType === \"from\" ? fromLabelId : toLabelId;\n return concatIds(rangeLabelId, ariaLabelledBy);\n };\n\n const getDropdownAriaLabel = () => {\n if (focusedInput === \"from\") {\n return `Selecting for: ${placeholders?.from}`;\n }\n\n if (focusedInput === \"to\") {\n return `Selecting for: ${placeholders?.to}`;\n }\n\n return undefined;\n };\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleSelectorClick =\n (rangeType: RangeType) => (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n openDropdownFor(rangeType);\n };\n\n const handleSelectorKeyDown =\n (rangeType: RangeType) =>\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled || readOnly) return;\n\n switch (event.key) {\n case \"Enter\":\n case \" \":\n case \"ArrowDown\":\n event.preventDefault();\n openDropdownFor(rangeType);\n break;\n default:\n break;\n }\n };\n\n const handleListItemClick = (item: T, extractedValue: V) => {\n if (focusedInput === \"none\") return;\n\n if (focusedInput === \"from\") {\n setSelectedFromValue(item);\n onSelectOption?.({ from: item }, extractedValue);\n\n setSelectedToValue(undefined);\n setFocusedInput(\"to\");\n triggerOptionDisplayCallback(true);\n focusButton(\"to\");\n return;\n }\n\n setSelectedToValue(item);\n onSelectOption?.({ to: item }, extractedValue);\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n focusButton(\"to\");\n };\n\n const handleDismiss = () => {\n const last = focusedInput;\n\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (last === \"to\") focusButton(\"to\");\n else focusButton(\"from\");\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleClose = () => {\n setFocusedInput(\"none\");\n triggerOptionDisplayCallback(false);\n\n if (!selectedFromValue || !selectedToValue) {\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n }\n };\n\n const handleOpen = () => {\n if (disabled || readOnly) return;\n\n if (focusedInput === \"none\") {\n setFocusedInput(\"from\");\n triggerOptionDisplayCallback(true);\n }\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n setSelectedFromValue(undefined);\n setSelectedToValue(undefined);\n onSelectOption?.({ from: undefined, to: undefined }, undefined);\n\n focusButton(\"from\");\n };\n\n // =============================================================================\n // RENDER\n // =============================================================================\n const renderLabel = (rangeType: RangeType) => {\n const selected =\n rangeType === \"from\" ? selectedFromValue : selectedToValue;\n\n if (!selected) {\n return (\n <PlaceholderLabel $truncateType={optionTruncationType}>\n {truncateValue(rangeType, placeholders?.[rangeType] || \"\")}\n </PlaceholderLabel>\n );\n }\n\n if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n }\n\n return (\n <ValueLabel $truncateType={optionTruncationType}>\n {truncateValue(rangeType, getDisplayValue(rangeType))}\n </ValueLabel>\n );\n };\n\n const renderSelectorContent = (rangeType: RangeType) => (\n <RangeSelectorButton\n type=\"button\"\n role=\"combobox\"\n aria-labelledby={getButtonLabelledBy(rangeType)}\n aria-describedby={ariaDescribedBy}\n aria-expanded={isOpen && focusedInput === rangeType}\n aria-controls={listboxId}\n aria-disabled={disabled}\n aria-readonly={readOnly}\n onClick={handleSelectorClick(rangeType)}\n onKeyDown={handleSelectorKeyDown(rangeType)}\n ref={labelButtonRef[rangeType]}\n tabIndex={0}\n >\n {renderLabel(rangeType)}\n </RangeSelectorButton>\n );\n\n const renderElement = () => {\n return (\n <StyledInputWrapper\n className={className}\n data-testid={testId}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n $focused={isOpen}\n >\n <VisuallyHidden id={fromLabelId}>\n {placeholders?.from || \"Select From\"}\n </VisuallyHidden>\n <VisuallyHidden id={toLabelId}>\n {placeholders?.to || \"Select To\"}\n </VisuallyHidden>\n\n <RangeInputInnerContainer\n currentActive={getCurrentFocused()}\n error={error}\n >\n {renderSelectorContent(\"from\")}\n {renderSelectorContent(\"to\")}\n </RangeInputInnerContainer>\n\n {!isOpen &&\n selectedFromValue &&\n selectedToValue &&\n !readOnly &&\n !disabled && (\n <ClearIconContainer\n onClick={handleClear}\n type=\"button\"\n aria-label=\"Clear\"\n >\n <ClearIcon aria-hidden />\n </ClearIconContainer>\n )}\n </StyledInputWrapper>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n ref={dropdownRef}\n data-testid={`${testId}-dropdown`}\n listboxId={listboxId}\n ariaLabel={getDropdownAriaLabel()}\n listItems={currentOptions}\n onSelectItem={handleListItemClick}\n onDismiss={handleDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n isOptionDisabled={isOptionDisabled}\n selectedItems={currentSelectedItems}\n itemsLoadState={optionsLoadState[focusedInput as RangeType]}\n itemTruncationType={optionTruncationType}\n onRetry={onRetry}\n width={dropdownWidth}\n matchElementWidth={!dropdownWidth}\n enableSearch={enableSearch}\n searchFunction={searchFunction}\n searchPlaceholder={searchPlaceholder}\n renderListItem={renderListItem}\n renderCustomCallToAction={renderCustomCallToAction}\n />\n );\n };\n\n return (\n <Wrapper id={id} {...otherProps}>\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={isOpen}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle={false}\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n </Wrapper>\n );\n};\n"],"names":["InputRangeSelect","_a","selectedOptions","placeholders","from","to","options","disabled","className","readOnly","error","testId","id","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","isOptionDisabled","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","renderCustomCallToAction","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","ariaLabelledBy","ariaDescribedBy","otherProps","__rest","selectedFromValue","setSelectedFromValue","useState","selectedToValue","setSelectedToValue","focusedInput","setFocusedInput","isOpen","labelButtonRef","useRef","dropdownRef","internalId","useId","listboxId","fromLabelId","toLabelId","useEffect","current","refocus","index","triggerOptionDisplayCallback","show","getDisplayValue","rangeType","selected","value","_b","toString","call","truncateValue","type","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","getCurrentFocused","currentOptions","useMemo","currentSelectedItems","openDropdownFor","focusButton","focus","getButtonLabelledBy","concatIds","handleSelectorClick","event","stopPropagation","preventDefault","handleSelectorKeyDown","key","handleListItemClick","item","extractedValue","undefined","handleDismiss","last","handleClear","renderLabel","_jsx","ValueLabel","$truncateType","PlaceholderLabel","renderSelectorContent","RangeSelectorButton","role","onClick","onKeyDown","ref","tabIndex","children","Wrapper","Object","assign","DropdownListState","ElementWithDropdown","enabled","renderElement","_jsxs","StyledInputWrapper","$disabled","$readOnly","$focused","VisuallyHidden","RangeInputInnerContainer","currentActive","ClearIconContainer","ClearIcon","renderDropdown","DropdownList","ariaLabel","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { InputSelectProps } from "./types";
|
|
2
|
-
export declare const InputSelect: <T, V>({ selectedOption, placeholder, options, disabled, error, className, "data-testid": testId, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, enableSearch, searchFunction, searchPlaceholder, valueExtractor, valueToStringFunction, listExtractor, displayValueExtractor, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, renderCustomSelectedOption, renderListItem, hideNoResultsDisplay, noResultsDescription, customLabels, renderCustomCallToAction, onBlur, variant, readOnly, alignment, dropdownZIndex, dropdownRootNode, dropdownWidth, }: InputSelectProps<T, V>) => JSX.Element;
|
|
2
|
+
export declare const InputSelect: <T, V>({ selectedOption, placeholder, options, disabled, error, className, "data-testid": testId, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, enableSearch, searchFunction, searchPlaceholder, valueExtractor, valueToStringFunction, listExtractor, isOptionDisabled, displayValueExtractor, onSelectOption, onShowOptions, onHideOptions, onRetry, optionsLoadState, optionTruncationType, renderCustomSelectedOption, renderListItem, hideNoResultsDisplay, noResultsDescription, customLabels, renderCustomCallToAction, onBlur, variant, readOnly, alignment, dropdownZIndex, dropdownRootNode, dropdownWidth, }: InputSelectProps<T, V>) => JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{useState as r,useRef as t,useEffect as o}from"react";import"styled-components";import"../theme/index.js";import{StringHelper as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{useState as r,useRef as t,useEffect as o}from"react";import"styled-components";import"../theme/index.js";import{StringHelper as i}from"../util/string-helper.js";import"../shared/dropdown-list/dropdown-label.styles.js";import{DropdownList as n}from"../shared/dropdown-list/dropdown-list.js";import{DropdownListState as s}from"../shared/dropdown-list/dropdown-list-state.js";import{ExpandableElement as l}from"../shared/dropdown-list/expandable-element.js";import"@lifesg/react-icons/caret-right";import"react-virtuoso";import"../button/button.style.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as a}from"../util/simple-id-generator.js";import"@react-aria/live-announcer";import{ElementWithDropdown as d}from"../shared/dropdown-wrapper/element-with-dropdown.js";import"../shared/dropdown-list/dropdown-list.styles.js";import"../shared/dropdown-list/dropdown-search.js";import"immer";import"../external/lodash/_getTag.js";import"../external/lodash/isArguments.js";import"../external/lodash/_baseGetTag.js";import"../external/lodash/isBuffer.js";import"../external/lodash/isTypedArray.js";import"../external/lodash/_Stack.js";import"../external/lodash/_SetCache.js";import"../external/lodash/_equalByTag.js";import"../shared/dropdown-list/nested-dropdown-list.styles.js";import"../shared/dropdown-list/virtuoso-components.js";import{LabelContainer as p,PlaceholderLabel as c,ValueLabel as m}from"../shared/dropdown-wrapper/dropdown-wrapper.styles.js";import{InputBox as u}from"../shared/input-wrapper/input-wrapper.js";const h=({selectedOption:h,placeholder:w="Select",options:b,disabled:f,error:j,className:y,"data-testid":x,id:v,"aria-labelledby":g,"aria-describedby":T,"aria-invalid":S,enableSearch:O=!1,searchFunction:I,searchPlaceholder:D,valueExtractor:R,valueToStringFunction:$,listExtractor:C,isOptionDisabled:E,displayValueExtractor:L,onSelectOption:N,onShowOptions:A,onHideOptions:B,onRetry:_,optionsLoadState:F="success",optionTruncationType:k="end",renderCustomSelectedOption:H,renderListItem:P,hideNoResultsDisplay:W,noResultsDescription:Z,customLabels:q,renderCustomCallToAction:G,onBlur:V,variant:z="default",readOnly:J,alignment:K,dropdownZIndex:M,dropdownRootNode:Q,dropdownWidth:U})=>{const[X,Y]=r(h),[ee,re]=r(!1),[te,oe]=r(!1),ie=a(),ne=t(null),se=t(null),le=t(null);o((()=>{Y(h)}),[h]);const ae=(e,r)=>{var t;null===(t=se.current)||void 0===t||t.focus(),Y(e),re(!1),he(!1),null==N||N(e,r)},de=()=>{ee&&(re(!1),he(!1))},pe=()=>{te||ee||oe(!0)},ce=e=>{te&&!ee&&ne.current&&!ne.current.contains(e.relatedTarget)&&(oe(!1),null==V||V())},me=()=>{var e;if(!X)return"";if(L)return L(X);if(R){const r=R(X);return $?$(r):null!==(e=null==r?void 0:r.toString())&&void 0!==e?e:""}return X.toString()},ue=e=>{if("middle"===k){let r=0;return le&&le.current&&(r=le.current.getBoundingClientRect().width),i.truncateOneLine(e,r,120,8)}return e},he=e=>{e?null==A||A():null==B||B()};return e(s,{children:e(d,{enabled:!J&&!f,isOpen:ee,renderElement:()=>e(u,{className:y,"data-testid":x,id:v,ref:ne,tabIndex:-1,onFocus:pe,onBlur:ce,$focused:te,$disabled:f,$readOnly:J,$error:j,children:e(l,{ref:se,disabled:f,expanded:ee,listboxId:ie,popupRole:"listbox",readOnly:J,variant:z,"aria-labelledby":g,"aria-describedby":T,"aria-invalid":S,children:e(p,{ref:le,$disabled:f,children:X?H?H(X):e(m,{$truncateType:k,$variant:z,children:ue(me())}):e(c,{$truncateType:k,$variant:z,children:w})})})}),renderDropdown:()=>e(n,{listboxId:ie,listItems:b,onSelectItem:ae,onDismiss:de,valueExtractor:R,listExtractor:C,isOptionDisabled:E,enableSearch:O,searchPlaceholder:D,searchFunction:I,selectedItems:X?[X]:[],onRetry:_,itemsLoadState:F,itemTruncationType:k,renderListItem:P,hideNoResultsDisplay:W,noResultsDescription:Z,customLabels:q,renderCustomCallToAction:G,variant:z,width:U,matchElementWidth:!0}),onOpen:()=>{re(!0),he(!0),oe(!0)},onClose:e=>{re(!1),he(!1),"click"!==e&&(oe(!1),null==V||V())},onDismiss:()=>{var e;null===(e=se.current)||void 0===e||e.focus(),re(!1),he(!1)},clickToToggle:!0,offset:8,alignment:K,fitAvailableHeight:!0,customZIndex:M,rootNode:Q})})};export{h as InputSelect};
|
|
2
2
|
//# sourceMappingURL=input-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-select.js","sources":["../../src/input-select/input-select.tsx"],"sourcesContent":["import { OpenChangeReason } from \"@floating-ui/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n DropdownList,\n DropdownListState,\n ExpandableElement,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { InputBox } from \"../shared/input-wrapper/input-wrapper\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport { InputSelectProps } from \"./types\";\n\nexport const InputSelect = <T, V>({\n selectedOption,\n placeholder = \"Select\",\n options,\n disabled,\n error,\n className,\n \"data-testid\": testId,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = \"success\",\n optionTruncationType = \"end\",\n renderCustomSelectedOption,\n renderListItem,\n hideNoResultsDisplay,\n noResultsDescription,\n customLabels,\n renderCustomCallToAction,\n onBlur,\n variant = \"default\",\n readOnly,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n}: InputSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const [selected, setSelected] = useState<T | undefined>(selectedOption);\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(selectedOption);\n }, [selectedOption]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setSelected(item);\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n onSelectOption?.(item, extractedValue);\n };\n\n const handleListDismiss = () => {\n if (showOptions) {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n }\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =============================================================================\n // HELPER FUNCTION\n // =============================================================================\n const getDisplayValue = (): string => {\n if (!selected) return \"\";\n\n if (displayValueExtractor) {\n return displayValueExtractor(selected);\n }\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelContainerRef && labelContainerRef.current) {\n widthOfElement =\n labelContainerRef.current.getBoundingClientRect().width;\n }\n\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (show) {\n onShowOptions?.();\n } else {\n onHideOptions?.();\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderLabel = () => {\n if (!selected) {\n return (\n <PlaceholderLabel\n $truncateType={optionTruncationType}\n $variant={variant}\n >\n {placeholder}\n </PlaceholderLabel>\n );\n } else if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n } else {\n return (\n <ValueLabel\n $truncateType={optionTruncationType}\n $variant={variant}\n >\n {truncateValue(getDisplayValue())}\n </ValueLabel>\n );\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer ref={labelContainerRef} $disabled={disabled}>\n {renderLabel()}\n </LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n $focused={focused}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"listbox\"\n readOnly={readOnly}\n variant={variant}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n listboxId={internalId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n searchFunction={searchFunction}\n selectedItems={selected ? [selected] : []}\n onRetry={onRetry}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n renderListItem={renderListItem}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n customLabels={customLabels}\n renderCustomCallToAction={renderCustomCallToAction}\n variant={variant}\n width={dropdownWidth}\n matchElementWidth\n />\n );\n };\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["InputSelect","selectedOption","placeholder","options","disabled","error","className","testId","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","hideNoResultsDisplay","noResultsDescription","customLabels","renderCustomCallToAction","onBlur","variant","readOnly","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","selected","setSelected","useState","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","useEffect","handleListItemClick","item","extractedValue","_a","current","focus","triggerOptionDisplayCallback","handleListDismiss","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","getDisplayValue","value","toString","truncateValue","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","show","_jsx","DropdownListState","children","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","$focused","$disabled","$error","ExpandableElement","expanded","listboxId","popupRole","LabelContainer","ValueLabel","$truncateType","$variant","PlaceholderLabel","renderDropdown","DropdownList","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","reason","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-select.js","sources":["../../src/input-select/input-select.tsx"],"sourcesContent":["import { OpenChangeReason } from \"@floating-ui/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n DropdownList,\n DropdownListState,\n ExpandableElement,\n} from \"../shared/dropdown-list\";\nimport { ElementWithDropdown } from \"../shared/dropdown-wrapper\";\nimport {\n LabelContainer,\n PlaceholderLabel,\n ValueLabel,\n} from \"../shared/dropdown-wrapper/dropdown-wrapper.styles\";\nimport { InputBox } from \"../shared/input-wrapper/input-wrapper\";\nimport { useId } from \"../util\";\nimport { StringHelper } from \"../util/string-helper\";\nimport { InputSelectProps } from \"./types\";\n\nexport const InputSelect = <T, V>({\n selectedOption,\n placeholder = \"Select\",\n options,\n disabled,\n error,\n className,\n \"data-testid\": testId,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n enableSearch = false,\n searchFunction,\n searchPlaceholder,\n valueExtractor,\n valueToStringFunction,\n listExtractor,\n isOptionDisabled,\n displayValueExtractor,\n onSelectOption,\n onShowOptions,\n onHideOptions,\n onRetry,\n optionsLoadState = \"success\",\n optionTruncationType = \"end\",\n renderCustomSelectedOption,\n renderListItem,\n hideNoResultsDisplay,\n noResultsDescription,\n customLabels,\n renderCustomCallToAction,\n onBlur,\n variant = \"default\",\n readOnly,\n alignment,\n dropdownZIndex,\n dropdownRootNode,\n dropdownWidth,\n}: InputSelectProps<T, V>): JSX.Element => {\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const [selected, setSelected] = useState<T | undefined>(selectedOption);\n const [showOptions, setShowOptions] = useState<boolean>(false);\n const [focused, setFocused] = useState<boolean>(false);\n const internalId = useId();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const selectorRef = useRef<HTMLButtonElement>(null);\n const labelContainerRef = useRef<HTMLDivElement>(null);\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(selectedOption);\n }, [selectedOption]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleListItemClick = (item: T, extractedValue: V) => {\n selectorRef.current?.focus();\n setSelected(item);\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n onSelectOption?.(item, extractedValue);\n };\n\n const handleListDismiss = () => {\n if (showOptions) {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n }\n };\n\n const handleNodeFocus = () => {\n if (!focused && !showOptions) {\n setFocused(true);\n }\n };\n\n const handleNodeBlur = (e: React.FocusEvent) => {\n if (\n focused &&\n !showOptions &&\n nodeRef.current &&\n !nodeRef.current.contains(e.relatedTarget as Node)\n ) {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleOpen = () => {\n setShowOptions(true);\n triggerOptionDisplayCallback(true);\n setFocused(true);\n };\n\n const handleClose = (reason: OpenChangeReason | undefined) => {\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n\n // click to toggle should not blur the input\n if (reason !== \"click\") {\n setFocused(false);\n onBlur?.();\n }\n };\n\n const handleDismiss = () => {\n selectorRef.current?.focus();\n setShowOptions(false);\n triggerOptionDisplayCallback(false);\n };\n\n // =============================================================================\n // HELPER FUNCTION\n // =============================================================================\n const getDisplayValue = (): string => {\n if (!selected) return \"\";\n\n if (displayValueExtractor) {\n return displayValueExtractor(selected);\n }\n\n if (valueExtractor) {\n const value = valueExtractor(selected);\n return valueToStringFunction\n ? valueToStringFunction(value)\n : value?.toString() ?? \"\";\n }\n\n return selected.toString();\n };\n\n const truncateValue = (value: string) => {\n if (optionTruncationType === \"middle\") {\n let widthOfElement = 0;\n if (labelContainerRef && labelContainerRef.current) {\n widthOfElement =\n labelContainerRef.current.getBoundingClientRect().width;\n }\n\n return StringHelper.truncateOneLine(value, widthOfElement, 120, 8);\n }\n return value;\n };\n\n const triggerOptionDisplayCallback = (show: boolean) => {\n if (show) {\n onShowOptions?.();\n } else {\n onHideOptions?.();\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderLabel = () => {\n if (!selected) {\n return (\n <PlaceholderLabel\n $truncateType={optionTruncationType}\n $variant={variant}\n >\n {placeholder}\n </PlaceholderLabel>\n );\n } else if (renderCustomSelectedOption) {\n return renderCustomSelectedOption(selected);\n } else {\n return (\n <ValueLabel\n $truncateType={optionTruncationType}\n $variant={variant}\n >\n {truncateValue(getDisplayValue())}\n </ValueLabel>\n );\n }\n };\n\n const renderSelectorContent = () => (\n <LabelContainer ref={labelContainerRef} $disabled={disabled}>\n {renderLabel()}\n </LabelContainer>\n );\n\n const renderElement = () => {\n return (\n <InputBox\n className={className}\n data-testid={testId}\n id={id}\n ref={nodeRef}\n tabIndex={-1}\n onFocus={handleNodeFocus}\n onBlur={handleNodeBlur}\n $focused={focused}\n $disabled={disabled}\n $readOnly={readOnly}\n $error={error}\n >\n <ExpandableElement\n ref={selectorRef}\n disabled={disabled}\n expanded={showOptions}\n listboxId={internalId}\n popupRole=\"listbox\"\n readOnly={readOnly}\n variant={variant}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n >\n {renderSelectorContent()}\n </ExpandableElement>\n </InputBox>\n );\n };\n\n const renderDropdown = () => {\n return (\n <DropdownList\n listboxId={internalId}\n listItems={options}\n onSelectItem={handleListItemClick}\n onDismiss={handleListDismiss}\n valueExtractor={valueExtractor}\n listExtractor={listExtractor}\n isOptionDisabled={isOptionDisabled}\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n searchFunction={searchFunction}\n selectedItems={selected ? [selected] : []}\n onRetry={onRetry}\n itemsLoadState={optionsLoadState}\n itemTruncationType={optionTruncationType}\n renderListItem={renderListItem}\n hideNoResultsDisplay={hideNoResultsDisplay}\n noResultsDescription={noResultsDescription}\n customLabels={customLabels}\n renderCustomCallToAction={renderCustomCallToAction}\n variant={variant}\n width={dropdownWidth}\n matchElementWidth\n />\n );\n };\n\n return (\n <DropdownListState>\n <ElementWithDropdown\n enabled={!readOnly && !disabled}\n isOpen={showOptions}\n renderElement={renderElement}\n renderDropdown={renderDropdown}\n onOpen={handleOpen}\n onClose={handleClose}\n onDismiss={handleDismiss}\n clickToToggle\n offset={8}\n alignment={alignment}\n fitAvailableHeight\n customZIndex={dropdownZIndex}\n rootNode={dropdownRootNode}\n />\n </DropdownListState>\n );\n};\n"],"names":["InputSelect","selectedOption","placeholder","options","disabled","error","className","testId","id","ariaLabelledBy","ariaDescribedBy","ariaInvalid","enableSearch","searchFunction","searchPlaceholder","valueExtractor","valueToStringFunction","listExtractor","isOptionDisabled","displayValueExtractor","onSelectOption","onShowOptions","onHideOptions","onRetry","optionsLoadState","optionTruncationType","renderCustomSelectedOption","renderListItem","hideNoResultsDisplay","noResultsDescription","customLabels","renderCustomCallToAction","onBlur","variant","readOnly","alignment","dropdownZIndex","dropdownRootNode","dropdownWidth","selected","setSelected","useState","showOptions","setShowOptions","focused","setFocused","internalId","useId","nodeRef","useRef","selectorRef","labelContainerRef","useEffect","handleListItemClick","item","extractedValue","_a","current","focus","triggerOptionDisplayCallback","handleListDismiss","handleNodeFocus","handleNodeBlur","e","contains","relatedTarget","getDisplayValue","value","toString","truncateValue","widthOfElement","getBoundingClientRect","width","StringHelper","truncateOneLine","show","_jsx","DropdownListState","children","ElementWithDropdown","enabled","isOpen","renderElement","InputBox","ref","tabIndex","onFocus","$focused","$disabled","$error","ExpandableElement","expanded","listboxId","popupRole","LabelContainer","ValueLabel","$truncateType","$variant","PlaceholderLabel","renderDropdown","DropdownList","listItems","onSelectItem","onDismiss","selectedItems","itemsLoadState","itemTruncationType","matchElementWidth","onOpen","onClose","reason","clickToToggle","offset","fitAvailableHeight","customZIndex","rootNode"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type LinkListStyle = "default" | "small";
|
|
2
|
-
export interface LinkListItemProps<T> extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
3
|
-
title: string;
|
|
4
|
-
description?: string | undefined;
|
|
2
|
+
export interface LinkListItemProps<T> extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "title"> {
|
|
3
|
+
title: string | JSX.Element;
|
|
4
|
+
description?: string | JSX.Element | undefined;
|
|
5
5
|
secondaryDescription?: JSX.Element | undefined;
|
|
6
6
|
"data-testid"?: string | undefined;
|
|
7
7
|
options?: T | undefined;
|
package/navbar/navbar-items.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as t,jsxs as i}from"react/jsx-runtime";import{useState as r,useRef as l,useEffect as o}from"react";import{Menu as d}from"../menu/menu.js";import{Menu as a}from"./menu.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as s}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{MobileWrapper as c,Wrapper as u,LinkItem as p,Link as m,LinkLabel as h,LinkButton as g,ChevronIconDesktop as b,LinkIndicator as v,LinkIconContainer as $,ExpandCollapseButton as f,ChevronIcon as j}from"./navbar-items.styles.js";const k=({items:k,selectedId:x,mobile:C=!1,hideNavBranding:M,hideLinkIndicator:I=!1,onItemClick:O})=>{const[_,w]=r(-1),[
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as t,jsxs as i}from"react/jsx-runtime";import{useState as r,useRef as l,useEffect as o}from"react";import{Menu as d}from"../menu/menu.js";import{Menu as a}from"./menu.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as s}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{MobileWrapper as c,Wrapper as u,LinkItem as p,Link as m,LinkLabel as h,LinkButton as g,ChevronIconDesktop as b,LinkIndicator as v,LinkIconContainer as $,ExpandCollapseButton as f,ChevronIcon as j}from"./navbar-items.styles.js";const k=({items:k,selectedId:x,mobile:C=!1,hideNavBranding:M,hideLinkIndicator:I=!1,onItemClick:O})=>{const[_,w]=r(-1),[L,P]=r(!1),[y,E]=r(null),B=l(null),D=s();o((()=>{const e=e=>{B.current&&!B.current.contains(e.target)&&(P(!1),w(-1),E(null))};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[]);const A=(e,n)=>t=>{var i;if(t.stopPropagation(),C&&(null===(i=e.subMenu)||void 0===i?void 0:i.length)){const e=!(_===n&&L);w(n),P(e)}O(t,e)},F=(e,n)=>{e.stopPropagation(),O(e,n),P(!1),w(-1)},H=(e,t)=>n(d.Content,{id:t,children:n(d.Section,{showDivider:!1,children:e.map(((e,t)=>n(d.Link,{href:e.href,children:e.children},`${e.id}-${t}`)))})}),N=e=>n(a,{items:e,onItemClick:F}),S=(r,l)=>{const{children:o,options:a,subMenu:s}=r,c=e(r,["children","options","subMenu"]),u=!!(null==s?void 0:s.length),O=(e=>{var n;return e.id===x||!!(null===(n=e.subMenu)||void 0===n?void 0:n.length)&&!!e.subMenu.find((e=>e.id===x))})(r),w=C&&u&&_===l&&L,P=!C&&u&&y===l||w,B=null!==y?y===l:O,F=!I&&B,S=B?C?"bold":"semibold":"regular",T=C?`link__mobile-${l+1}`:`link__${l+1}`,q=()=>F?n(v,{"data-testid":`${T}-indicator`,$selected:B}):null;return n(p,{$hiddenBranding:M,children:u?(e=>{const p=`navbar-submenu-${D}-${r.id}`;return C?i(t,{children:[i(m,Object.assign({"data-testid":T,$weight:S,$selected:B},c,{"aria-current":O?"page":void 0,"aria-haspopup":"menu","aria-expanded":P,onClick:A(r,l)},a,{children:[n(h,{children:o}),q(),C&&u?n($,{children:n(f,{"data-testid":`${T}-expand-collapse-button`,$selected:B,$expanded:P,focusHighlight:!1,focusOutline:"browser","aria-label":P?"Collapse":"Expand",children:n(j,{$selected:B})})}):null]})),w&&N(s)]}):n(d,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:H(s,p),triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>E(l),onPopoverDismiss:()=>{E((e=>e===l?null:e))},children:i(g,Object.assign({type:"button",tabIndex:0,"data-testid":T,$weight:S,$selected:B,"aria-haspopup":"menu","aria-expanded":P},a,{children:[n(h,{children:o}),q(),n(b,{$selected:B,$expanded:P})]}))})})(l===k.length-1):i(m,Object.assign({tabIndex:0,"data-testid":T,$weight:S,$selected:B},c,{"aria-current":O?"page":void 0,onClick:A(r,l)},a,{children:[n(h,{children:o}),q()]}))},l)},T=()=>k.map(((e,t)=>{var i;return"component"===e.itemType?n("li",{children:null!==(i=e.children)&&void 0!==i?i:null},t):S(e,t)}));return k&&k.length>0?C?n(c,{ref:B,children:T()}):n(u,{ref:B,$alignLeft:M,children:T()}):n(t,{})};export{k as NavbarItems};
|
|
2
2
|
//# sourceMappingURL=navbar-items.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { TypographyWeight } from \"../typography\";\nimport { Menu as MobileMenu } from \"./menu\";\n\nimport { useId } from \"../util\";\nimport {\n ChevronIcon,\n ChevronIconDesktop,\n ExpandCollapseButton,\n Link,\n LinkButton,\n LinkIconContainer,\n LinkIndicator,\n LinkItem,\n LinkLabel,\n MobileWrapper,\n Wrapper,\n} from \"./navbar-items.styles\";\nimport { NavItemCommonProps, NavItemLinkProps, NavItemProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number>(-1);\n const [showSubMenu, setShowSubMenu] = useState<boolean>(false);\n const [openSubMenuIndex, setOpenSubMenuIndex] = useState<number | null>(\n null\n );\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const resetAll = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n setOpenSubMenuIndex(null);\n };\n\n const closeMobileSubMenu = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n };\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean => {\n if (item.id === selectedId) return true;\n if (item.subMenu?.length) {\n return !!item.subMenu.find((s) => s.id === selectedId);\n }\n return false;\n };\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n resetAll();\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, []);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile && item.subMenu?.length) {\n const nextExpanded = !(selectedIndex === index && showSubMenu);\n setSelectedIndex(index);\n setShowSubMenu(nextExpanded);\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n closeMobileSubMenu();\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu items={subMenu} onItemClick={handleMobileSubLinkClick} />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const { children, options, subMenu, ...otherItemAttrs } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && openSubMenuIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index && showSubMenu;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n openSubMenuIndex !== null\n ? openSubMenuIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <LinkIndicator\n data-testid={`${testId}-indicator`}\n $selected={selected}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <LinkIconContainer>\n <ExpandCollapseButton\n data-testid={`${testId}-expand-collapse-button`}\n $selected={selected}\n $expanded={isExpanded}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronIcon $selected={selected} />\n </ExpandCollapseButton>\n </LinkIconContainer>\n ) : null;\n\n const renderLink = () => (\n <Link\n tabIndex={0}\n data-testid={testId}\n weight={textWeight}\n $selected={selected}\n underlineStyle=\"none\"\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n </Link>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <Link\n data-testid={testId}\n weight={textWeight}\n $selected={selected}\n underlineStyle=\"none\"\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n {renderMobileChevron()}\n </Link>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(subMenu!, subMenuId)}\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => setOpenSubMenuIndex(index)}\n onPopoverDismiss={() => {\n setOpenSubMenuIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <LinkButton\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n weight={textWeight}\n $selected={selected}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n <ChevronIconDesktop\n $selected={selected}\n $expanded={isExpanded}\n />\n </LinkButton>\n </DesktopMenu>\n );\n };\n\n return (\n <LinkItem key={index} $hiddenBranding={hideNavBranding}>\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </LinkItem>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <MobileWrapper ref={listRef}>{renderItems()}</MobileWrapper>\n ) : (\n <Wrapper ref={listRef} $alignLeft={hideNavBranding}>\n {renderItems()}\n </Wrapper>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","showSubMenu","setShowSubMenu","openSubMenuIndex","setOpenSubMenuIndex","listRef","useRef","instanceId","useId","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","item","index","stopPropagation","_a","subMenu","length","nextExpanded","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","_jsx","DesktopMenu","Content","id","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","find","s","checkSelected","isMobileExpanded","isExpanded","selected","showIndicator","textWeight","testId","renderIndicator","LinkIndicator","$selected","LinkItem","$hiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","weight","underlineStyle","undefined","onClick","LinkLabel","LinkIconContainer","ExpandCollapseButton","$expanded","focusHighlight","focusOutline","ChevronIcon","position","customOffset","menuContent","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","prev","LinkButton","type","tabIndex","ChevronIconDesktop","renderLinkWithSubmenu","renderItems","itemType","MobileWrapper","ref","Wrapper","$alignLeft"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { TypographyWeight } from \"../typography\";\nimport { Menu as MobileMenu } from \"./menu\";\n\nimport { useId } from \"../util\";\nimport {\n ChevronIcon,\n ChevronIconDesktop,\n ExpandCollapseButton,\n Link,\n LinkButton,\n LinkIconContainer,\n LinkIndicator,\n LinkItem,\n LinkLabel,\n MobileWrapper,\n Wrapper,\n} from \"./navbar-items.styles\";\nimport { NavItemCommonProps, NavItemLinkProps, NavItemProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number>(-1);\n const [showSubMenu, setShowSubMenu] = useState<boolean>(false);\n const [openSubMenuIndex, setOpenSubMenuIndex] = useState<number | null>(\n null\n );\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const resetAll = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n setOpenSubMenuIndex(null);\n };\n\n const closeMobileSubMenu = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n };\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean => {\n if (item.id === selectedId) return true;\n if (item.subMenu?.length) {\n return !!item.subMenu.find((s) => s.id === selectedId);\n }\n return false;\n };\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n resetAll();\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, []);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile && item.subMenu?.length) {\n const nextExpanded = !(selectedIndex === index && showSubMenu);\n setSelectedIndex(index);\n setShowSubMenu(nextExpanded);\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n closeMobileSubMenu();\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu items={subMenu} onItemClick={handleMobileSubLinkClick} />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const { children, options, subMenu, ...otherItemAttrs } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && openSubMenuIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index && showSubMenu;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n openSubMenuIndex !== null\n ? openSubMenuIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <LinkIndicator\n data-testid={`${testId}-indicator`}\n $selected={selected}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <LinkIconContainer>\n <ExpandCollapseButton\n data-testid={`${testId}-expand-collapse-button`}\n $selected={selected}\n $expanded={isExpanded}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronIcon $selected={selected} />\n </ExpandCollapseButton>\n </LinkIconContainer>\n ) : null;\n\n const renderLink = () => (\n <Link\n tabIndex={0}\n data-testid={testId}\n $weight={textWeight}\n $selected={selected}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n </Link>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <Link\n data-testid={testId}\n $weight={textWeight}\n $selected={selected}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n {renderMobileChevron()}\n </Link>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(subMenu!, subMenuId)}\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => setOpenSubMenuIndex(index)}\n onPopoverDismiss={() => {\n setOpenSubMenuIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <LinkButton\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n $weight={textWeight}\n $selected={selected}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <LinkLabel>{children}</LinkLabel>\n {renderIndicator()}\n <ChevronIconDesktop\n $selected={selected}\n $expanded={isExpanded}\n />\n </LinkButton>\n </DesktopMenu>\n );\n };\n\n return (\n <LinkItem key={index} $hiddenBranding={hideNavBranding}>\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </LinkItem>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <MobileWrapper ref={listRef}>{renderItems()}</MobileWrapper>\n ) : (\n <Wrapper ref={listRef} $alignLeft={hideNavBranding}>\n {renderItems()}\n </Wrapper>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","showSubMenu","setShowSubMenu","openSubMenuIndex","setOpenSubMenuIndex","listRef","useRef","instanceId","useId","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","item","index","stopPropagation","_a","subMenu","length","nextExpanded","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","_jsx","DesktopMenu","Content","id","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","find","s","checkSelected","isMobileExpanded","isExpanded","selected","showIndicator","textWeight","testId","renderIndicator","LinkIndicator","$selected","LinkItem","$hiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","$weight","undefined","onClick","LinkLabel","LinkIconContainer","ExpandCollapseButton","$expanded","focusHighlight","focusOutline","ChevronIcon","position","customOffset","menuContent","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","prev","LinkButton","type","tabIndex","ChevronIconDesktop","renderLinkWithSubmenu","renderItems","itemType","MobileWrapper","ref","Wrapper","$alignLeft"],"mappings":"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"}
|