@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
|
-
"use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),a=require("react"),i=require("../shared/accessibility/index.js");require("styled-components"),require("../theme/index.js"),require("../util/string-helper.js"),require("../shared/dropdown-list/dropdown-label.styles.js");var t=require("../shared/dropdown-list/dropdown-list.js"),s=require("../shared/dropdown-list/dropdown-list-state.js");require("../shared/dropdown-list/expandable-element.js"),require("@lifesg/react-icons/caret-right"),require("react-virtuoso"),require("../button/button.style.js"),require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var l=require("../util/simple-id-generator.js");require("@react-aria/live-announcer");var d=require("../shared/dropdown-wrapper/element-with-dropdown.js");require("../shared/dropdown-list/dropdown-list.styles.js"),require("../shared/dropdown-list/dropdown-search.js"),require("immer"),require("../external/lodash/_getTag.js"),require("../external/lodash/isArguments.js"),require("../external/lodash/_baseGetTag.js"),require("../external/lodash/isBuffer.js"),require("../external/lodash/isTypedArray.js"),require("../external/lodash/_Stack.js"),require("../external/lodash/_SetCache.js"),require("../external/lodash/_equalByTag.js"),require("../shared/dropdown-list/nested-dropdown-list.styles.js"),require("../shared/dropdown-list/virtuoso-components.js");var o=require("../shared/dropdown-wrapper/dropdown-wrapper.styles.js"),n=require("./input-group-list-addon.style.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}const c=(u,c)=>{var{addon:p,error:h,onChange:b,readOnly:x,disabled:j,className:y,onBlur:q,noBorder:m,"data-testid":w,"aria-labelledby":f,"aria-describedby":v,"aria-invalid":g,"aria-label":S}=u,$=e.__rest(u,["addon","error","onChange","readOnly","disabled","className","onBlur","noBorder","data-testid","aria-labelledby","aria-describedby","aria-invalid","aria-label"]);const{valueExtractor:
|
|
1
|
+
"use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),a=require("react"),i=require("../shared/accessibility/index.js");require("styled-components"),require("../theme/index.js"),require("../util/string-helper.js"),require("../shared/dropdown-list/dropdown-label.styles.js");var t=require("../shared/dropdown-list/dropdown-list.js"),s=require("../shared/dropdown-list/dropdown-list-state.js");require("../shared/dropdown-list/expandable-element.js"),require("@lifesg/react-icons/caret-right"),require("react-virtuoso"),require("../button/button.style.js"),require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var l=require("../util/simple-id-generator.js");require("@react-aria/live-announcer");var d=require("../shared/dropdown-wrapper/element-with-dropdown.js");require("../shared/dropdown-list/dropdown-list.styles.js"),require("../shared/dropdown-list/dropdown-search.js"),require("immer"),require("../external/lodash/_getTag.js"),require("../external/lodash/isArguments.js"),require("../external/lodash/_baseGetTag.js"),require("../external/lodash/isBuffer.js"),require("../external/lodash/isTypedArray.js"),require("../external/lodash/_Stack.js"),require("../external/lodash/_SetCache.js"),require("../external/lodash/_equalByTag.js"),require("../shared/dropdown-list/nested-dropdown-list.styles.js"),require("../shared/dropdown-list/virtuoso-components.js");var o=require("../shared/dropdown-wrapper/dropdown-wrapper.styles.js"),n=require("./input-group-list-addon.style.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}const c=(u,c)=>{var{addon:p,error:h,onChange:b,readOnly:x,disabled:j,className:y,onBlur:q,noBorder:m,"data-testid":w,"aria-labelledby":f,"aria-describedby":v,"aria-invalid":g,"aria-label":S}=u,$=e.__rest(u,["addon","error","onChange","readOnly","disabled","className","onBlur","noBorder","data-testid","aria-labelledby","aria-describedby","aria-invalid","aria-label"]);const{valueExtractor:O,listExtractor:I,isOptionDisabled:D,enableSearch:R,hideNoResultsDisplay:T,noResultsDescription:E,searchPlaceholder:B,searchFunction:L,onSearch:_,placeholder:C="Select",displayValueExtractor:N,"data-selector-testid":F,options:V,selectedOption:H,onSelectOption:A,optionsLoadState:P,optionTruncationType:k,onRetry:W,onHideOptions:G,onShowOptions:Z,dropdownZIndex:z,dropdownRootNode:J,"aria-label":K}=p.attributes,{position:M}=p,[Q,U]=a.useState(H),[X,Y]=a.useState(!1),[ee,re]=a.useState(!1),ae=l.useId(),ie=`${ae}-listbox`,te=`${ae}-instruction`,se=`${ae}-combobox-label`,le=`${ae}-textbox-label`,de=a.useRef(null),oe=a.useRef(null);a.useEffect((()=>{U(H)}),[H]);const ne=()=>{if(Q)return N?N(Q):O?O(Q):Q.toString()},ue=e=>{e?null==Z||Z():null==G||G()},ce=(e,r)=>{var a;null===(a=oe.current)||void 0===a||a.focus(),U(e),Y(!1),ue(!1),null==A||A(e,r)},pe=()=>{X&&(Y(!1),ue(!1))},he=()=>{Y(!0),ue(!0),re(!0)},be=e=>{Y(!1),ue(!1),"click"!==e&&(re(!1),null==q||q())},xe=()=>{var e;null===(e=oe.current)||void 0===e||e.focus(),Y(!1),ue(!1)},je=()=>r.jsxs("div",{children:[r.jsx(n.StyledExpandableElement,{ref:oe,disabled:j,expanded:X,listboxId:ie,popupRole:"listbox",readOnly:x,"aria-labelledby":i.concatIds(f,se),"aria-describedby":i.concatIds(v,te),"aria-invalid":g,$noBorder:m,$position:M,children:r.jsx(o.LabelContainer,{$disabled:j,children:Q?r.jsx(o.ValueLabel,{children:ne()}):r.jsx(o.PlaceholderLabel,{children:C})})}),r.jsx(i.VisuallyHidden,{id:te,children:"Press space to open options"})]}),ye=()=>r.jsx(t.DropdownList,{listboxId:ie,listItems:V,onSelectItem:ce,onDismiss:pe,valueExtractor:O,listExtractor:I,isOptionDisabled:D,enableSearch:R,hideNoResultsDisplay:T,noResultsDescription:E,searchPlaceholder:B,searchFunction:L,onSearch:_,selectedItems:Q?[Q]:[],itemsLoadState:P,itemTruncationType:k,onRetry:W,matchElementWidth:!0});return r.jsx(s.DropdownListState,{children:r.jsxs(n.FieldWrapper,{$focused:ee,$disabled:j,$readOnly:x,$error:h,$position:M,ref:de,className:y,"data-testid":w,$noBorder:m,tabIndex:-1,onFocus:()=>{ee||X||re(!0)},onBlur:e=>{ee&&!X&&de.current&&!de.current.contains(e.relatedTarget)&&(re(!1),null==q||q())},children:[r.jsx(i.VisuallyHidden,{"aria-hidden":!0,id:se,children:K}),r.jsx(n.FieldSelector,{"data-testid":F,children:x?Q?r.jsx(n.SelectorReadOnly,{"data-testid":"selector-label",tabIndex:0,role:"combobox","aria-haspopup":"listbox","aria-readonly":!0,"aria-expanded":!1,"aria-labelledby":f,"aria-describedby":v,"aria-invalid":g,children:r.jsx(o.ValueLabel,{children:ne()})}):null:r.jsx(d.ElementWithDropdown,{enabled:!x&&!j,isOpen:X,renderElement:je,renderDropdown:ye,onOpen:he,onClose:be,onDismiss:xe,clickToToggle:!0,offset:8,alignment:"right"===M?"right":"left",fitAvailableHeight:!0,customZIndex:z,rootNode:J,positionRef:de})}),r.jsx(n.Divider,{$readOnly:x,$position:M}),r.jsx(i.VisuallyHidden,{"aria-hidden":!0,id:le,children:S}),r.jsx(n.FieldInput,Object.assign({ref:c},$,{$position:M,$noBorder:m,readOnly:x,disabled:j,error:h,onChange:e=>{b&&b(e)},"data-testid":"input",styleType:"no-border","aria-labelledby":i.concatIds(f,le),"aria-describedby":v,"aria-invalid":g}))]})})},p=u(a).default.forwardRef(c);exports.Component=c,exports.InputGroupListAddon=p;
|
|
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":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("react"),o=require("../input/input.style.js"),n=require("../shared/accessibility/index.js");require("styled-components"),require("../theme/index.js");var i=require("../util/string-helper.js");require("../shared/dropdown-list/dropdown-label.styles.js");var l=require("../shared/dropdown-list/dropdown-list.js"),
|
|
1
|
+
"use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("react"),o=require("../input/input.style.js"),n=require("../shared/accessibility/index.js");require("styled-components"),require("../theme/index.js");var i=require("../util/string-helper.js");require("../shared/dropdown-list/dropdown-label.styles.js");var l=require("../shared/dropdown-list/dropdown-list.js"),s=require("../shared/dropdown-list/dropdown-list-state.js");require("../shared/dropdown-list/expandable-element.js"),require("@lifesg/react-icons/caret-right"),require("react-virtuoso"),require("../button/button.style.js"),require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var a=require("../util/simple-id-generator.js");require("@react-aria/live-announcer");var d=require("../shared/dropdown-wrapper/element-with-dropdown.js");require("../shared/dropdown-list/dropdown-list.styles.js"),require("../shared/dropdown-list/dropdown-search.js"),require("immer"),require("../external/lodash/_getTag.js"),require("../external/lodash/isArguments.js"),require("../external/lodash/_baseGetTag.js"),require("../external/lodash/isBuffer.js"),require("../external/lodash/isTypedArray.js"),require("../external/lodash/_Stack.js"),require("../external/lodash/_SetCache.js"),require("../external/lodash/_equalByTag.js"),require("../shared/dropdown-list/nested-dropdown-list.styles.js"),require("../shared/dropdown-list/virtuoso-components.js");var u=require("../shared/dropdown-wrapper/dropdown-wrapper.styles.js"),c=require("../shared/range-input-inner-container/range-input-inner-container.js"),p=require("./input-range-select.style.js");exports.InputRangeSelect=h=>{var{selectedOptions:m,placeholders:v={from:"Select",to:"Select"},options:f,disabled:b,className:j,readOnly:x,error:w,"data-testid":y,id:q,enableSearch:g=!1,searchFunction:S,searchPlaceholder:O,valueExtractor:T,valueToStringFunction:I,listExtractor:C,isOptionDisabled:D,displayValueExtractor:E,onSelectOption:L,onShowOptions:R,onHideOptions:$,onRetry:_,optionsLoadState:A={from:"success",to:"success"},optionTruncationType:F="middle",renderCustomSelectedOption:H,renderListItem:N,renderCustomCallToAction:P,alignment:W,dropdownZIndex:k,dropdownRootNode:V,dropdownWidth:B,"aria-labelledby":Z,"aria-describedby":M}=h,G=e.__rest(h,["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[K,z]=t.useState(),[J,Q]=t.useState(),[U,X]=t.useState("none"),Y="none"!==U,ee={from:t.useRef(null),to:t.useRef(null)},re=t.useRef(null),te=a.useId(),oe=`${te}-range-listbox`,ne=`${te}-from-label`,ie=`${te}-to-label`;t.useEffect((()=>{z(null==m?void 0:m.from),Q(null==m?void 0:m.to)}),[m]),t.useEffect((()=>{var e;Y&&"to"===U&&(null===(e=re.current)||void 0===e||e.refocus({index:0}))}),[Y,U]);const le=e=>{e||null==$||$(),e&&(null==R||R())},se=e=>{var r,t;const o="from"===e?K:J;if(!o)return"";if(E)return E(o);if(T){const e=T(o);return I?I(e):null!==(t=null===(r=null==e?void 0:e.toString)||void 0===r?void 0:r.call(e))&&void 0!==t?t:""}return o.toString()},ae=(e,r)=>{var t;if("middle"===F){let o=0;return(null===(t=ee[e])||void 0===t?void 0:t.current)&&(o=ee[e].current.getBoundingClientRect().width),i.StringHelper.truncateOneLine(r,o,120,8)}return r},de=()=>{switch(U){case"from":return"start";case"to":return"end";case"none":return U}},ue=t.useMemo((()=>{var e;return"none"===U?[]:null!==(e=null==f?void 0:f[U])&&void 0!==e?e:[]}),[U,f]),ce=t.useMemo((()=>{if("none"===U)return[];const e="from"===U?K:J;return e?[e]:[]}),[U,K,J]),pe=e=>{if(b||x)return;X("to"!==e||K?e:"from"),le(!0)},he=e=>{var r;null===(r=ee[e].current)||void 0===r||r.focus()},me=e=>{const r="from"===e?ne:ie;return n.concatIds(r,Z)},ve=e=>r=>{r.stopPropagation(),r.preventDefault(),pe(e)},fe=e=>r=>{if(!b&&!x)switch(r.key){case"Enter":case" ":case"ArrowDown":r.preventDefault(),pe(e)}},be=(e,r)=>{if("none"!==U){if("from"===U)return z(e),null==L||L({from:e},r),Q(void 0),X("to"),le(!0),void he("to");Q(e),null==L||L({to:e},r),X("none"),le(!1),he("to")}},je=()=>{const e=U;X("none"),le(!1),he("to"===e?"to":"from"),K&&J||(z(void 0),Q(void 0))},xe=e=>{e.stopPropagation(),e.preventDefault(),z(void 0),Q(void 0),null==L||L({from:void 0,to:void 0},void 0),he("from")},we=e=>{const t="from"===e?K:J;return t?H?H(t):r.jsx(u.ValueLabel,{$truncateType:F,children:ae(e,se(e))}):r.jsx(u.PlaceholderLabel,{$truncateType:F,children:ae(e,(null==v?void 0:v[e])||"")})},ye=e=>r.jsx(p.RangeSelectorButton,{type:"button",role:"combobox","aria-labelledby":me(e),"aria-describedby":M,"aria-expanded":Y&&U===e,"aria-controls":oe,"aria-disabled":b,"aria-readonly":x,onClick:ve(e),onKeyDown:fe(e),ref:ee[e],tabIndex:0,children:we(e)});return r.jsx(u.Wrapper,Object.assign({id:q},G,{children:r.jsx(s.DropdownListState,{children:r.jsx(d.ElementWithDropdown,{enabled:!x&&!b,isOpen:Y,renderElement:()=>r.jsxs(p.StyledInputWrapper,{className:j,"data-testid":y,$disabled:b,$readOnly:x,$error:w,$focused:Y,children:[r.jsx(n.VisuallyHidden,{id:ne,children:(null==v?void 0:v.from)||"Select From"}),r.jsx(n.VisuallyHidden,{id:ie,children:(null==v?void 0:v.to)||"Select To"}),r.jsxs(c.RangeInputInnerContainer,{currentActive:de(),error:w,children:[ye("from"),ye("to")]}),!Y&&K&&J&&!x&&!b&&r.jsx(p.ClearIconContainer,{onClick:xe,type:"button","aria-label":"Clear",children:r.jsx(o.ClearIcon,{"aria-hidden":!0})})]}),renderDropdown:()=>r.jsx(l.DropdownList,{ref:re,"data-testid":`${y}-dropdown`,listboxId:oe,ariaLabel:"from"===U?`Selecting for: ${null==v?void 0:v.from}`:"to"===U?`Selecting for: ${null==v?void 0:v.to}`:void 0,listItems:ue,onSelectItem:be,onDismiss:je,valueExtractor:T,listExtractor:C,isOptionDisabled:D,selectedItems:ce,itemsLoadState:A[U],itemTruncationType:F,onRetry:_,width:B,matchElementWidth:!B,enableSearch:g,searchFunction:S,searchPlaceholder:O,renderListItem:N,renderCustomCallToAction:P}),onOpen:()=>{b||x||"none"===U&&(X("from"),le(!0))},onClose:()=>{X("none"),le(!1),K&&J||(z(void 0),Q(void 0))},onDismiss:je,clickToToggle:!1,offset:8,alignment:W,fitAvailableHeight:!0,customZIndex:k,rootNode:V})})}))};
|
|
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":["_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","rangeLabelId","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":["_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","rangeLabelId","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
|
-
"use strict";var e=require("react/jsx-runtime"),r=require("react");require("styled-components"),require("../theme/index.js");var t=require("../util/string-helper.js");require("../shared/dropdown-list/dropdown-label.styles.js");var n=require("../shared/dropdown-list/dropdown-list.js"),s=require("../shared/dropdown-list/dropdown-list-state.js"),i=require("../shared/dropdown-list/expandable-element.js");require("@lifesg/react-icons/caret-right"),require("react-virtuoso"),require("../button/button.style.js"),require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var a=require("../util/simple-id-generator.js");require("@react-aria/live-announcer");var l=require("../shared/dropdown-wrapper/element-with-dropdown.js");require("../shared/dropdown-list/dropdown-list.styles.js"),require("../shared/dropdown-list/dropdown-search.js"),require("immer"),require("../external/lodash/_getTag.js"),require("../external/lodash/isArguments.js"),require("../external/lodash/_baseGetTag.js"),require("../external/lodash/isBuffer.js"),require("../external/lodash/isTypedArray.js"),require("../external/lodash/_Stack.js"),require("../external/lodash/_SetCache.js"),require("../external/lodash/_equalByTag.js"),require("../shared/dropdown-list/nested-dropdown-list.styles.js"),require("../shared/dropdown-list/virtuoso-components.js");var o=require("../shared/dropdown-wrapper/dropdown-wrapper.styles.js"),d=require("../shared/input-wrapper/input-wrapper.js");exports.InputSelect=({selectedOption:u,placeholder:c="Select",options:p,disabled:h,error:j,className:m,"data-testid":q,id:w,"aria-labelledby":x,"aria-describedby":b,"aria-invalid":v,enableSearch:y=!1,searchFunction:f,searchPlaceholder:g,valueExtractor:S,valueToStringFunction:T,listExtractor:I,displayValueExtractor:
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),r=require("react");require("styled-components"),require("../theme/index.js");var t=require("../util/string-helper.js");require("../shared/dropdown-list/dropdown-label.styles.js");var n=require("../shared/dropdown-list/dropdown-list.js"),s=require("../shared/dropdown-list/dropdown-list-state.js"),i=require("../shared/dropdown-list/expandable-element.js");require("@lifesg/react-icons/caret-right"),require("react-virtuoso"),require("../button/button.style.js"),require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var a=require("../util/simple-id-generator.js");require("@react-aria/live-announcer");var l=require("../shared/dropdown-wrapper/element-with-dropdown.js");require("../shared/dropdown-list/dropdown-list.styles.js"),require("../shared/dropdown-list/dropdown-search.js"),require("immer"),require("../external/lodash/_getTag.js"),require("../external/lodash/isArguments.js"),require("../external/lodash/_baseGetTag.js"),require("../external/lodash/isBuffer.js"),require("../external/lodash/isTypedArray.js"),require("../external/lodash/_Stack.js"),require("../external/lodash/_SetCache.js"),require("../external/lodash/_equalByTag.js"),require("../shared/dropdown-list/nested-dropdown-list.styles.js"),require("../shared/dropdown-list/virtuoso-components.js");var o=require("../shared/dropdown-wrapper/dropdown-wrapper.styles.js"),d=require("../shared/input-wrapper/input-wrapper.js");exports.InputSelect=({selectedOption:u,placeholder:c="Select",options:p,disabled:h,error:j,className:m,"data-testid":q,id:w,"aria-labelledby":x,"aria-describedby":b,"aria-invalid":v,enableSearch:y=!1,searchFunction:f,searchPlaceholder:g,valueExtractor:S,valueToStringFunction:T,listExtractor:I,isOptionDisabled:O,displayValueExtractor:D,onSelectOption:L,onShowOptions:R,onHideOptions:E,onRetry:C,optionsLoadState:$="success",optionTruncationType:B="end",renderCustomSelectedOption:N,renderListItem:A,hideNoResultsDisplay:_,noResultsDescription:F,customLabels:k,renderCustomCallToAction:H,onBlur:P,variant:W="default",readOnly:V,alignment:Z,dropdownZIndex:G,dropdownRootNode:z,dropdownWidth:J})=>{const[K,M]=r.useState(u),[Q,U]=r.useState(!1),[X,Y]=r.useState(!1),ee=a.useId(),re=r.useRef(null),te=r.useRef(null),ne=r.useRef(null);r.useEffect((()=>{M(u)}),[u]);const se=(e,r)=>{var t;null===(t=te.current)||void 0===t||t.focus(),M(e),U(!1),ue(!1),null==L||L(e,r)},ie=()=>{Q&&(U(!1),ue(!1))},ae=()=>{X||Q||Y(!0)},le=e=>{X&&!Q&&re.current&&!re.current.contains(e.relatedTarget)&&(Y(!1),null==P||P())},oe=()=>{var e;if(!K)return"";if(D)return D(K);if(S){const r=S(K);return T?T(r):null!==(e=null==r?void 0:r.toString())&&void 0!==e?e:""}return K.toString()},de=e=>{if("middle"===B){let r=0;return ne&&ne.current&&(r=ne.current.getBoundingClientRect().width),t.StringHelper.truncateOneLine(e,r,120,8)}return e},ue=e=>{e?null==R||R():null==E||E()};return e.jsx(s.DropdownListState,{children:e.jsx(l.ElementWithDropdown,{enabled:!V&&!h,isOpen:Q,renderElement:()=>e.jsx(d.InputBox,{className:m,"data-testid":q,id:w,ref:re,tabIndex:-1,onFocus:ae,onBlur:le,$focused:X,$disabled:h,$readOnly:V,$error:j,children:e.jsx(i.ExpandableElement,{ref:te,disabled:h,expanded:Q,listboxId:ee,popupRole:"listbox",readOnly:V,variant:W,"aria-labelledby":x,"aria-describedby":b,"aria-invalid":v,children:e.jsx(o.LabelContainer,{ref:ne,$disabled:h,children:K?N?N(K):e.jsx(o.ValueLabel,{$truncateType:B,$variant:W,children:de(oe())}):e.jsx(o.PlaceholderLabel,{$truncateType:B,$variant:W,children:c})})})}),renderDropdown:()=>e.jsx(n.DropdownList,{listboxId:ee,listItems:p,onSelectItem:se,onDismiss:ie,valueExtractor:S,listExtractor:I,isOptionDisabled:O,enableSearch:y,searchPlaceholder:g,searchFunction:f,selectedItems:K?[K]:[],onRetry:C,itemsLoadState:$,itemTruncationType:B,renderListItem:A,hideNoResultsDisplay:_,noResultsDescription:F,customLabels:k,renderCustomCallToAction:H,variant:W,width:J,matchElementWidth:!0}),onOpen:()=>{U(!0),ue(!0),Y(!0)},onClose:e=>{U(!1),ue(!1),"click"!==e&&(Y(!1),null==P||P())},onDismiss:()=>{var e;null===(e=te.current)||void 0===e||e.focus(),U(!1),ue(!1)},clickToToggle:!0,offset:8,alignment:Z,fitAvailableHeight:!0,customZIndex:G,rootNode:z})})};
|
|
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":["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":["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,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("../_virtual/_tslib.js"),n=require("react/jsx-runtime"),i=require("react"),t=require("../menu/menu.js"),r=require("./menu.js");require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var s=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var l=require("./navbar-items.styles.js");exports.NavbarItems=({items:a,selectedId:d,mobile:u=!1,hideNavBranding:o,hideLinkIndicator:c=!1,onItemClick:p})=>{const[h,j]=i.useState(-1),[x,m]=i.useState(!1),[b,g]=i.useState(null),v=i.useRef(null)
|
|
1
|
+
"use strict";var e=require("../_virtual/_tslib.js"),n=require("react/jsx-runtime"),i=require("react"),t=require("../menu/menu.js"),r=require("./menu.js");require("../util/calendar-helper.js"),require("../util/date-helper.js"),require("../util/date-input-helper.js");var s=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var l=require("./navbar-items.styles.js");exports.NavbarItems=({items:a,selectedId:d,mobile:u=!1,hideNavBranding:o,hideLinkIndicator:c=!1,onItemClick:p})=>{const[h,j]=i.useState(-1),[x,m]=i.useState(!1),[b,g]=i.useState(null),v=i.useRef(null),$=s.useId();i.useEffect((()=>{const e=e=>{v.current&&!v.current.contains(e.target)&&(m(!1),j(-1),g(null))};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[]);const k=(e,n)=>i=>{var t;if(i.stopPropagation(),u&&(null===(t=e.subMenu)||void 0===t?void 0:t.length)){const e=!(h===n&&x);j(n),m(e)}p(i,e)},L=(e,n)=>{e.stopPropagation(),p(e,n),m(!1),j(-1)},f=(e,i)=>n.jsx(t.Menu.Content,{id:i,children:n.jsx(t.Menu.Section,{showDivider:!1,children:e.map(((e,i)=>n.jsx(t.Menu.Link,{href:e.href,children:e.children},`${e.id}-${i}`)))})}),I=e=>n.jsx(r.Menu,{items:e,onItemClick:L}),q=(i,r)=>{const{children:s,options:p,subMenu:j}=i,m=e.__rest(i,["children","options","subMenu"]),v=!!(null==j?void 0:j.length),L=(e=>{var n;return e.id===d||!!(null===(n=e.subMenu)||void 0===n?void 0:n.length)&&!!e.subMenu.find((e=>e.id===d))})(i),q=u&&v&&h===r&&x,M=!u&&v&&b===r||q,C=null!==b?b===r:L,_=!c&&C,O=C?u?"bold":"semibold":"regular",w=u?`link__mobile-${r+1}`:`link__${r+1}`,E=()=>_?n.jsx(l.LinkIndicator,{"data-testid":`${w}-indicator`,$selected:C}):null;return n.jsx(l.LinkItem,{$hiddenBranding:o,children:v?(e=>{const a=`navbar-submenu-${$}-${i.id}`;return u?n.jsxs(n.Fragment,{children:[n.jsxs(l.Link,Object.assign({"data-testid":w,$weight:O,$selected:C},m,{"aria-current":L?"page":void 0,"aria-haspopup":"menu","aria-expanded":M,onClick:k(i,r)},p,{children:[n.jsx(l.LinkLabel,{children:s}),E(),u&&v?n.jsx(l.LinkIconContainer,{children:n.jsx(l.ExpandCollapseButton,{"data-testid":`${w}-expand-collapse-button`,$selected:C,$expanded:M,focusHighlight:!1,focusOutline:"browser","aria-label":M?"Collapse":"Expand",children:n.jsx(l.ChevronIcon,{$selected:C})})}):null]})),q&&I(j)]}):n.jsx(t.Menu,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:f(j,a),triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>g(r),onPopoverDismiss:()=>{g((e=>e===r?null:e))},children:n.jsxs(l.LinkButton,Object.assign({type:"button",tabIndex:0,"data-testid":w,$weight:O,$selected:C,"aria-haspopup":"menu","aria-expanded":M},p,{children:[n.jsx(l.LinkLabel,{children:s}),E(),n.jsx(l.ChevronIconDesktop,{$selected:C,$expanded:M})]}))})})(r===a.length-1):n.jsxs(l.Link,Object.assign({tabIndex:0,"data-testid":w,$weight:O,$selected:C},m,{"aria-current":L?"page":void 0,onClick:k(i,r)},p,{children:[n.jsx(l.LinkLabel,{children:s}),E()]}))},r)},M=()=>a.map(((e,i)=>{var t;return"component"===e.itemType?n.jsx("li",{children:null!==(t=e.children)&&void 0!==t?t:null},i):q(e,i)}));return a&&a.length>0?u?n.jsx(l.MobileWrapper,{ref:v,children:M()}):n.jsx(l.Wrapper,{ref:v,$alignLeft:o,children:M()}):n.jsx(n.Fragment,{})};
|
|
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":["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":["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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar-items.styles.js","sources":["../../../src/navbar/navbar-items.styles.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport styled, { css } from \"styled-components\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { Font, MediaQuery } from \"../theme\";\nimport { Colour } from \"../theme\";\nimport { ThemeNavbar } from \"../theme/components/theme-helper\";\nimport { TypographyWeight } from \"../typography\";\n\n// =============================================================================\n// STYLE INTERFACE, transient props are denoted with $\n// See more https://styled-components.com/docs/api#transient-props\n// =============================================================================\ninterface StyleProps {\n $selected: boolean;\n $expanded?: boolean;\n}\n\ninterface WrapperStyleProps {\n $alignLeft: boolean | undefined;\n}\n\ninterface ItemStyleProps {\n $hiddenBranding: boolean | undefined;\n}\n\n// =============================================================================\n// WRAPPER\n// =============================================================================\n\nexport const Wrapper = styled.ul<WrapperStyleProps>`\n display: flex;\n list-style: none;\n position: relative;\n\n ${(props) => props.$alignLeft && \"margin-right: auto;\"}\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n }\n`;\n\nexport const MobileWrapper = styled.ul`\n display: none;\n list-style: none;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n`;\n\n// =============================================================================\n// LINK ITEMS\n// =============================================================================\nexport const LinkItem = styled.li<ItemStyleProps>`\n display: flex;\n margin: 0 1rem;\n\n &:first-child {\n // negative margin to preserve touch target size for link\n margin-left: ${(props) => (props.$hiddenBranding ? \"-0.5rem\" : \"0\")};\n }\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n padding: 0.125rem 0;\n width: 100%;\n margin-left: 0rem;\n }\n`;\n\nconst linkCss = css<{ $selected: boolean; weight: TypographyWeight }>`\n ${(props) => Font[`body-md-${props
|
|
1
|
+
{"version":3,"file":"navbar-items.styles.js","sources":["../../../src/navbar/navbar-items.styles.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport styled, { css } from \"styled-components\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { Font, MediaQuery } from \"../theme\";\nimport { Colour } from \"../theme\";\nimport { ThemeNavbar } from \"../theme/components/theme-helper\";\nimport { TypographyWeight } from \"../typography\";\n\n// =============================================================================\n// STYLE INTERFACE, transient props are denoted with $\n// See more https://styled-components.com/docs/api#transient-props\n// =============================================================================\ninterface StyleProps {\n $selected: boolean;\n $expanded?: boolean;\n}\n\ninterface WrapperStyleProps {\n $alignLeft: boolean | undefined;\n}\n\ninterface ItemStyleProps {\n $hiddenBranding: boolean | undefined;\n}\n\n// =============================================================================\n// WRAPPER\n// =============================================================================\n\nexport const Wrapper = styled.ul<WrapperStyleProps>`\n display: flex;\n list-style: none;\n position: relative;\n\n ${(props) => props.$alignLeft && \"margin-right: auto;\"}\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n }\n`;\n\nexport const MobileWrapper = styled.ul`\n display: none;\n list-style: none;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n`;\n\n// =============================================================================\n// LINK ITEMS\n// =============================================================================\nexport const LinkItem = styled.li<ItemStyleProps>`\n display: flex;\n margin: 0 1rem;\n\n &:first-child {\n // negative margin to preserve touch target size for link\n margin-left: ${(props) => (props.$hiddenBranding ? \"-0.5rem\" : \"0\")};\n }\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n padding: 0.125rem 0;\n width: 100%;\n margin-left: 0rem;\n }\n`;\n\nconst linkCss = css<{ $selected: boolean; $weight: TypographyWeight }>`\n ${(props) => Font[`body-md-${props.$weight}`]}\n\n display: flex;\n position: relative;\n align-items: center;\n text-align: center;\n color: ${ThemeNavbar[\"navbar-link-colour-text\"]};\n height: 100%;\n gap: 0.5rem;\n\n &:active,\n &:hover,\n &:focus,\n &:focus-within {\n color: ${(props) =>\n props.$selected\n ? ThemeNavbar[\"navbar-link-colour-text-selected-hover\"]\n : ThemeNavbar[\"navbar-link-colour-text-hover\"]};\n }\n\n ${MediaQuery.MaxWidth.lg} {\n width: 100%;\n padding: 0.5rem 1rem;\n text-align: left;\n }\n`;\nexport const Link = styled.a<{ $selected: boolean; $weight: TypographyWeight }>`\n ${linkCss}\n`;\n\nexport const LinkButton = styled.button<{\n $selected: boolean;\n $weight: TypographyWeight;\n}>`\n ${linkCss}\n background: none;\n border: 0;\n padding: 0;\n cursor: pointer;\n text-align: left;\n margin: 0;\n box-shadow: none;\n font: inherit;\n color: inherit;\n`;\n\nexport const LinkLabel = styled.div`\n flex: 1;\n\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n white-space: pre-wrap;\n`;\n\nexport const LinkIndicator = styled.div<StyleProps>`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 0.25rem;\n background-color: ${Colour[\"border-selected\"]};\n\n ${(props) =>\n props.$selected &&\n css`\n ${Link}:active &,\n ${Link}:hover &,\n ${Link}:focus &,\n ${LinkButton}:active &,\n ${LinkButton}:hover &,\n ${LinkButton}:focus & {\n background-color: ${Colour[\"border-selected-hover\"]};\n }\n `};\n\n ${MediaQuery.MaxWidth.lg} {\n left: 0;\n right: unset;\n top: 0;\n bottom: 0;\n height: 100%;\n width: 0.25rem;\n }\n`;\n\nexport const LinkIconContainer = styled.div`\n margin-right: -0.5rem;\n`;\n\nexport const ExpandCollapseButton = styled(ClickableIcon)<StyleProps>`\n padding: 0.5rem;\n transform: rotate(${(props) => (props.$expanded ? 0 : 180)}deg);\n transition: transform 300ms ease-in-out;\n margin: auto 0.25rem auto 0;\n`;\n\nexport const ChevronIcon = styled(ChevronUpIcon)<StyleProps>`\n height: 1.25rem;\n width: 1.25rem;\n color: ${Colour.icon};\n\n ${Link}:active &,\n ${Link}:hover &,\n ${Link}:focus &,\n ${LinkButton}:active &,\n ${LinkButton}:hover &,\n ${LinkButton}:focus & {\n color: ${(props) =>\n props.$selected\n ? Colour[\"icon-selected-hover\"]\n : Colour[\"icon-hover\"]};\n }\n`;\n\nexport const ChevronIconDesktop = styled(ChevronIcon)<StyleProps>`\n transform: rotate(${(props) => (props.$expanded ? 0 : 180)}deg);\n transition: transform 300ms ease-in-out;\n\n height: 1.125rem;\n width: 1.125rem;\n`;\n"],"names":["Wrapper","styled","ul","props","$alignLeft","MediaQuery","MaxWidth","lg","MobileWrapper","LinkItem","li","$hiddenBranding","linkCss","css","Font","$weight","ThemeNavbar","$selected","Link","a","LinkButton","button","LinkLabel","div","LinkIndicator","Colour","LinkIconContainer","ExpandCollapseButton","ClickableIcon","$expanded","ChevronIcon","ChevronUpIcon","icon","ChevronIconDesktop"],"mappings":"uTA6BO,MAAMA,EAAUC,EAAAA,QAAOC,EAAqB;;;;;MAK5CC,GAAUA,EAAMC,YAAc;;MAE/BC,EAAAA,WAAWC,SAASC;;;EAKbC,EAAgBP,EAAAA,QAAOC,EAAE;;;;MAIhCG,EAAAA,WAAWC,SAASC;;;;;EAUbE,EAAWR,EAAAA,QAAOS,EAAkB;;;;;;uBAMzBP,GAAWA,EAAMQ,gBAAkB,UAAY;;;MAGjEN,EAAAA,WAAWC,SAASC;;;;;;EAQpBK,EAAUC,EAAAA,GAAsD;MAC/DV,GAAUW,OAAK,WAAWX,EAAMY;;;;;;aAM1BC,EAAAA,YAAY;;;;;;;;iBAQPb,GACNA,EAAMc,UACAD,EAAAA,YAAY,0CACZA,EAAAA,YAAY;;;MAGxBX,EAAAA,WAAWC,SAASC;;;;;EAMbW,EAAOjB,EAAAA,QAAOkB,CAAoD;MACzEP;EAGOQ,EAAanB,EAAAA,QAAOoB,MAG/B;MACIT;;;;;;;;;;EAYOU,EAAYrB,EAAAA,QAAOsB,GAAG;;;;;;;;EAUtBC,EAAgBvB,EAAAA,QAAOsB,GAAe;;;;;;wBAM3BE,EAAAA,OAAO;;MAExBtB,GACCA,EAAMc,WACNJ,KAAG;cACGK;cACAA;cACAA;cACAE;cACAA;cACAA;oCACsBK,EAAAA,OAAO;;;;MAIrCpB,EAAAA,WAAWC,SAASC;;;;;;;;EAUbmB,EAAoBzB,EAAAA,QAAOsB,GAAG;;EAI9BI,EAAuB1B,EAAAA,QAAO2B,EAAAA,cAA0B;;wBAE5CzB,GAAWA,EAAM0B,UAAY,EAAI;;;EAK7CC,EAAc7B,EAAAA,QAAO8B,EAAAA,cAA0B;;;aAG/CN,EAAAA,OAAOO;;MAEdd;MACAA;MACAA;MACAE;MACAA;MACAA;iBACYjB,GACNA,EAAMc,UACAQ,EAAAA,OAAO,uBACPA,EAAAA,OAAO;;EAIZQ,EAAqBhC,EAAAA,QAAO6B,EAAwB;wBACxC3B,GAAWA,EAAM0B,UAAY,EAAI;;;;;"}
|