@persona/design-system 0.1.6 → 0.1.8
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/CHANGELOG.md +346 -202
- package/dist/{Action-DSg3yZck.d.mts → Action-CVtzREhU.d.mts} +3 -3
- package/dist/{Action-uduFOh2m.d.cts → Action-E90Wvqmc.d.cts} +3 -3
- package/dist/Action.d.cts +1 -1
- package/dist/Action.d.mts +1 -1
- package/dist/AdvancedFilterRuleRow.d.mts +37 -0
- package/dist/AdvancedFilterRulesPopover.d.mts +62 -0
- package/dist/ArrayValueControl.d.mts +38 -0
- package/dist/Attribute.d.mts +4 -4
- package/dist/AttributeGrid.d.mts +1 -1
- package/dist/{Badge-CvdUyXSH.cjs → Badge-ADPloFsd.cjs} +2 -5
- package/dist/{Badge-CvdUyXSH.cjs.map → Badge-ADPloFsd.cjs.map} +1 -1
- package/dist/{Badge-pq6B-3ue.mjs → Badge-DortWowZ.mjs} +2 -5
- package/dist/{Badge-pq6B-3ue.mjs.map → Badge-DortWowZ.mjs.map} +1 -1
- package/dist/Banner.d.mts +1 -1
- package/dist/BooleanValueControl.d.mts +20 -0
- package/dist/Breadcrumb-VH-Mwo-M.d.cts +44 -0
- package/dist/Breadcrumb-lziQ1FX9.d.mts +44 -0
- package/dist/Breadcrumb.d.cts +2 -0
- package/dist/Breadcrumb.d.mts +2 -0
- package/dist/Breadcrumbs-BBREROrw.d.cts +26 -0
- package/dist/Breadcrumbs-CDZ_Mrcg.mjs +288 -0
- package/dist/Breadcrumbs-CDZ_Mrcg.mjs.map +1 -0
- package/dist/Breadcrumbs-DJ5qqqRD.d.mts +26 -0
- package/dist/Breadcrumbs-tR49JqAS.cjs +295 -0
- package/dist/Breadcrumbs-tR49JqAS.cjs.map +1 -0
- package/dist/Breadcrumbs.d.cts +2 -0
- package/dist/Breadcrumbs.d.mts +2 -0
- package/dist/{Button-DcTUxRNI.d.mts → Button-9p469xA1.d.mts} +3 -3
- package/dist/Button.d.mts +1 -1
- package/dist/ButtonGroup.d.mts +1 -1
- package/dist/Calendar.d.mts +1 -1
- package/dist/CalendarBase.d.mts +1 -1
- package/dist/{Card-CLTkZLKr.mjs → Card-BMCB9eFC.mjs} +4 -4
- package/dist/{Card-CLTkZLKr.mjs.map → Card-BMCB9eFC.mjs.map} +1 -1
- package/dist/{Card-CrQL0hXm.d.cts → Card-CJPEmUvg.d.cts} +2 -2
- package/dist/{Card-YzGS3nQI.d.mts → Card-CqnG--CU.d.mts} +4 -4
- package/dist/{Card-CaOItkgL.cjs → Card-Csz-PxX0.cjs} +4 -4
- package/dist/{Card-CaOItkgL.cjs.map → Card-Csz-PxX0.cjs.map} +1 -1
- package/dist/Card.d.cts +1 -1
- package/dist/Card.d.mts +1 -1
- package/dist/Card2.d.cts +1 -1
- package/dist/Card2.d.mts +1 -1
- package/dist/CardV2-C9z0Hr-c.mjs +411 -0
- package/dist/CardV2-C9z0Hr-c.mjs.map +1 -0
- package/dist/CardV2-DJXgFomd.cjs +419 -0
- package/dist/CardV2-DJXgFomd.cjs.map +1 -0
- package/dist/{Checkbox-UWdk4pqb.mjs → Checkbox-B0bjZbji.mjs} +5 -5
- package/dist/{Checkbox-UWdk4pqb.mjs.map → Checkbox-B0bjZbji.mjs.map} +1 -1
- package/dist/{Checkbox-BmjK0Wac.d.cts → Checkbox-Bm8exUfH.d.mts} +1 -1
- package/dist/{Checkbox-B83WfsOZ.cjs → Checkbox-CmCujC1W.cjs} +5 -5
- package/dist/{Checkbox-B83WfsOZ.cjs.map → Checkbox-CmCujC1W.cjs.map} +1 -1
- package/dist/{Checkbox-Bc2kzl9q.d.mts → Checkbox-Cr8ifm10.d.cts} +1 -1
- package/dist/Checkbox.d.cts +1 -1
- package/dist/Checkbox.d.mts +1 -1
- package/dist/CheckboxGroupField.d.cts +1 -1
- package/dist/CheckboxGroupField.d.mts +2 -2
- package/dist/ChoicesValueControl.d.mts +35 -0
- package/dist/{Combobox-I44W5oX0.mjs → Combobox-BdqU5WLG.mjs} +261 -72
- package/dist/Combobox-BdqU5WLG.mjs.map +1 -0
- package/dist/{Combobox-Dx1u-L1A.d.cts → Combobox-C99xluaM.d.mts} +3 -3
- package/dist/{Combobox-R3_NDBi3.cjs → Combobox-COXvmxlM.cjs} +254 -65
- package/dist/Combobox-COXvmxlM.cjs.map +1 -0
- package/dist/{Combobox-DtD1XXaf.d.mts → Combobox-DBWMHwUt.d.cts} +3 -3
- package/dist/Combobox.d.cts +2 -2
- package/dist/Combobox.d.mts +2 -2
- package/dist/{ComboboxBase-sRVxlTJw.d.mts → ComboboxBase-BsY7CYoB.d.mts} +50 -9
- package/dist/{ComboboxBase-d98GJD-k.d.cts → ComboboxBase-zZ3tE-dH.d.cts} +47 -6
- package/dist/ComboboxBase.d.cts +2 -2
- package/dist/ComboboxBase.d.mts +2 -2
- package/dist/{ComboboxMultiSelect-CdLQDBMN.d.mts → ComboboxMultiSelect-dNuETspL.d.mts} +2 -2
- package/dist/{ComboboxMultiSelect-CRHf5TI-.d.cts → ComboboxMultiSelect-ioB4Jx7_.d.cts} +2 -2
- package/dist/ComboboxMultiSelect.d.cts +1 -1
- package/dist/ComboboxMultiSelect.d.mts +1 -1
- package/dist/{ComboboxSingleSelect-CxiQ2o6t.d.mts → ComboboxSingleSelect-C8KvIJ43.d.mts} +4 -4
- package/dist/{ComboboxSingleSelect-DvK8QioK.d.cts → ComboboxSingleSelect-Fn80tdhz.d.cts} +4 -4
- package/dist/ComboboxSingleSelect.d.cts +1 -1
- package/dist/ComboboxSingleSelect.d.mts +1 -1
- package/dist/{CompactBar-ODUl2Q6G.d.cts → CompactBar-BEAK55kh.d.cts} +3 -3
- package/dist/{CompactBar-k-rhZ5Z-.d.mts → CompactBar-CXqlVKy7.d.mts} +3 -3
- package/dist/CompactBar.d.cts +1 -1
- package/dist/CompactBar.d.mts +1 -1
- package/dist/{ConfigFormGroup-BhO9nm3P.cjs → ConfigFormGroup-m5YdVa9n.cjs} +3 -3
- package/dist/{ConfigFormGroup-BhO9nm3P.cjs.map → ConfigFormGroup-m5YdVa9n.cjs.map} +1 -1
- package/dist/{ConfigFormGroup-_yCksmZo.mjs → ConfigFormGroup-yhb2jldT.mjs} +3 -3
- package/dist/{ConfigFormGroup-_yCksmZo.mjs.map → ConfigFormGroup-yhb2jldT.mjs.map} +1 -1
- package/dist/{ControlBar-9m-DNImB.d.mts → ControlBar-D8CirAyZ.d.cts} +2 -2
- package/dist/{ControlBar-oT-I2y6E.d.cts → ControlBar-tOCQnbAl.d.mts} +2 -2
- package/dist/ControlBar.d.cts +1 -1
- package/dist/ControlBar.d.mts +1 -1
- package/dist/DataTable.d.cts +3 -3
- package/dist/DataTable.d.mts +4 -4
- package/dist/DateField.d.cts +1 -1
- package/dist/DateField.d.mts +1 -1
- package/dist/DatePicker-BlCgFb7g.cjs +948 -0
- package/dist/DatePicker-BlCgFb7g.cjs.map +1 -0
- package/dist/DatePicker-DY1YA_Fu.mjs +922 -0
- package/dist/DatePicker-DY1YA_Fu.mjs.map +1 -0
- package/dist/DatePicker.d.cts +1 -1
- package/dist/DatePicker.d.mts +1 -1
- package/dist/DateRangePicker.d.cts +6 -1
- package/dist/DateRangePicker.d.mts +6 -1
- package/dist/DateValueControl.d.mts +26 -0
- package/dist/{DropdownButton-BS1QfVX_.mjs → DropdownButton-DKLjJylQ.mjs} +3 -3
- package/dist/{DropdownButton-BS1QfVX_.mjs.map → DropdownButton-DKLjJylQ.mjs.map} +1 -1
- package/dist/{DropdownButton-Dpiy5v-R.cjs → DropdownButton-Dl7IEzAc.cjs} +3 -3
- package/dist/{DropdownButton-Dpiy5v-R.cjs.map → DropdownButton-Dl7IEzAc.cjs.map} +1 -1
- package/dist/DropdownButton.d.cts +1 -1
- package/dist/DropdownButton.d.mts +2 -2
- package/dist/{DropdownMenu-COkpUmIO.d.mts → DropdownMenu-CVPanvKA.d.mts} +3 -3
- package/dist/{DropdownMenu-cN_AnKAT.mjs → DropdownMenu-DGYexb7s.mjs} +3 -3
- package/dist/{DropdownMenu-cN_AnKAT.mjs.map → DropdownMenu-DGYexb7s.mjs.map} +1 -1
- package/dist/{DropdownMenu-CeqZAxjs.cjs → DropdownMenu-DnlQqTjs.cjs} +3 -3
- package/dist/{DropdownMenu-CeqZAxjs.cjs.map → DropdownMenu-DnlQqTjs.cjs.map} +1 -1
- package/dist/{DropdownMenu-D1E1jpZu.d.cts → DropdownMenu-FkiManPP.d.cts} +2 -2
- package/dist/DropdownMenu.d.cts +1 -1
- package/dist/DropdownMenu.d.mts +1 -1
- package/dist/{ErrorProps-DBw1_Z0a.d.mts → ErrorProps-CN2XjaOX.d.mts} +1 -1
- package/dist/{ErrorProps-DLdVsYlk.d.cts → ErrorProps-Dxqb4gw_.d.cts} +1 -1
- package/dist/ErrorProps.d.cts +1 -1
- package/dist/ErrorProps.d.mts +1 -1
- package/dist/FieldRegistry-OX60T3hr.d.cts +122 -0
- package/dist/FieldRegistry-rqSkjchY.d.mts +122 -0
- package/dist/FieldRegistry.d.cts +2 -0
- package/dist/FieldRegistry.d.mts +2 -0
- package/dist/FilterBar-D3LiIy1-.d.mts +103 -0
- package/dist/FilterBar-YzOh02f9.d.cts +103 -0
- package/dist/FilterBar.d.cts +2 -0
- package/dist/FilterBar.d.mts +2 -0
- package/dist/FilterPickerMenu.d.mts +84 -0
- package/dist/FilterPill.d.mts +60 -0
- package/dist/FilterPopover.d.mts +87 -0
- package/dist/FloatValueControl.d.mts +40 -0
- package/dist/{FormControl-fK4HA_yF.mjs → FormControl-B28qa7aQ.mjs} +6 -6
- package/dist/{FormControl-fK4HA_yF.mjs.map → FormControl-B28qa7aQ.mjs.map} +1 -1
- package/dist/{FormControl-OqBTbSwv.d.cts → FormControl-DFp_qcW1.d.cts} +2 -2
- package/dist/{FormControl-vfFzrYhv.d.mts → FormControl-DH3bgqaB.d.mts} +3 -3
- package/dist/{FormControl-DjxkL5Ft.cjs → FormControl-MkBXuUF6.cjs} +6 -6
- package/dist/{FormControl-DjxkL5Ft.cjs.map → FormControl-MkBXuUF6.cjs.map} +1 -1
- package/dist/FormControl.d.cts +1 -1
- package/dist/FormControl.d.mts +1 -1
- package/dist/FormControlLabel.d.mts +1 -1
- package/dist/{FormField-24UPuoL6.d.mts → FormField-BugkBvN4.d.mts} +2 -2
- package/dist/FormField-D3XhxTMg.cjs +550 -0
- package/dist/FormField-D3XhxTMg.cjs.map +1 -0
- package/dist/FormField-PeYYRO4s.mjs +471 -0
- package/dist/FormField-PeYYRO4s.mjs.map +1 -0
- package/dist/{FormField-Cqwi_PyR.d.cts → FormField-idNLw5PW.d.cts} +2 -2
- package/dist/FormField.d.cts +1 -1
- package/dist/FormField.d.mts +1 -1
- package/dist/{Header-D8oDtnIL.d.cts → Header-C-WhPOin.d.cts} +3 -3
- package/dist/{Header-WNGlG541.d.mts → Header-CDTYK1XJ.d.mts} +2 -2
- package/dist/Header.d.cts +1 -1
- package/dist/Header.d.mts +1 -1
- package/dist/{HelperTooltip-Bd5pQLqL.d.mts → HelperTooltip-B7Ysh8B3.d.mts} +3 -3
- package/dist/{HelperTooltip-oXdyk2At.d.cts → HelperTooltip-T-sTGGLD.d.cts} +2 -2
- package/dist/HelperTooltip.d.cts +1 -1
- package/dist/HelperTooltip.d.mts +1 -1
- package/dist/{HoverCopyableField-DyW2iZuo.cjs → HoverCopyableField-CRkM7o4B.cjs} +12 -12
- package/dist/HoverCopyableField-CRkM7o4B.cjs.map +1 -0
- package/dist/{HoverCopyableField-DBkYvwii.mjs → HoverCopyableField-ClXBg_ld.mjs} +8 -8
- package/dist/HoverCopyableField-ClXBg_ld.mjs.map +1 -0
- package/dist/HoverCopyableField.d.mts +1 -1
- package/dist/{IconButton-DggxojBH.d.mts → IconButton-BSES_-6g.d.mts} +2 -2
- package/dist/{IconButton-DC4rh6ow.mjs → IconButton-CIWiEsS-.mjs} +5 -5
- package/dist/{IconButton-DC4rh6ow.mjs.map → IconButton-CIWiEsS-.mjs.map} +1 -1
- package/dist/{IconButton-DNy7g5zh.cjs → IconButton-nlgjJQCS.cjs} +4 -4
- package/dist/{IconButton-DNy7g5zh.cjs.map → IconButton-nlgjJQCS.cjs.map} +1 -1
- package/dist/IconButton.d.mts +1 -1
- package/dist/ImageTile.d.cts +1 -1
- package/dist/ImageTile.d.mts +2 -2
- package/dist/InlineCombobox.d.mts +6 -3
- package/dist/InlineInput.d.mts +4 -1
- package/dist/{Input-Bl7633Ux.mjs → Input-BFI_e7aU.mjs} +5 -5
- package/dist/{Input-Bl7633Ux.mjs.map → Input-BFI_e7aU.mjs.map} +1 -1
- package/dist/{Input-XppkvfUf.d.cts → Input-BM0DzWEf.d.cts} +2 -2
- package/dist/{Input-DW7oacjc.d.mts → Input-BPClVzwD.d.mts} +4 -4
- package/dist/{Input-DQS-BEym.cjs → Input-OJPQ07TW.cjs} +5 -5
- package/dist/{Input-DQS-BEym.cjs.map → Input-OJPQ07TW.cjs.map} +1 -1
- package/dist/Input.d.cts +1 -1
- package/dist/Input.d.mts +1 -1
- package/dist/{InputProps-7rEMxBED.d.cts → InputProps-BnjxrdWQ.d.mts} +2 -2
- package/dist/{InputProps-DQpb2_E3.d.mts → InputProps-CoVNpQSj.d.cts} +2 -2
- package/dist/InputProps.d.cts +1 -1
- package/dist/InputProps.d.mts +1 -1
- package/dist/IntegerValueControl.d.mts +39 -0
- package/dist/LayoutLoadingShimmer.d.cts +20 -0
- package/dist/LayoutLoadingShimmer.d.mts +20 -0
- package/dist/Link.d.mts +1 -1
- package/dist/{ListBox-B4uoo_PT.cjs → ListBox-BP1eaG7L.cjs} +84 -15
- package/dist/ListBox-BP1eaG7L.cjs.map +1 -0
- package/dist/{ListBox-B7sbubm5.mjs → ListBox-BwID8jpk.mjs} +84 -15
- package/dist/ListBox-BwID8jpk.mjs.map +1 -0
- package/dist/{ListBox-DeVmbXeC.d.cts → ListBox-QaeRQBSC.d.cts} +2 -2
- package/dist/{ListBox-CVvKa5sc.d.mts → ListBox-_fcSPynx.d.mts} +5 -5
- package/dist/ListBox.d.cts +1 -1
- package/dist/ListBox.d.mts +1 -1
- package/dist/ListBoxField.d.cts +2 -2
- package/dist/ListBoxField.d.mts +3 -3
- package/dist/{LoadingShimmer-b430vgof.mjs → LoadingShimmer-Dsc_RCCf.mjs} +1 -1
- package/dist/{LoadingShimmer-b430vgof.mjs.map → LoadingShimmer-Dsc_RCCf.mjs.map} +1 -1
- package/dist/{LoadingShimmer-uG2UzYQd.cjs → LoadingShimmer-Dx6ncVUV.cjs} +1 -1
- package/dist/{LoadingShimmer-uG2UzYQd.cjs.map → LoadingShimmer-Dx6ncVUV.cjs.map} +1 -1
- package/dist/LoadingShimmer.d.mts +2 -2
- package/dist/LogicRow-BtCKGX_j.d.mts +40 -0
- package/dist/LogicRow-C6lrFIq0.d.cts +40 -0
- package/dist/LogicRow.d.cts +2 -0
- package/dist/LogicRow.d.mts +2 -0
- package/dist/MaskedInput.d.cts +1 -1
- package/dist/MaskedInput.d.mts +1 -1
- package/dist/{Menu-BbSyWxFD.mjs → Menu-CPYXo61N.mjs} +5 -5
- package/dist/{Menu-BbSyWxFD.mjs.map → Menu-CPYXo61N.mjs.map} +1 -1
- package/dist/{Menu-CSgCXX0k.d.mts → Menu-CUp_9HgC.d.mts} +4 -4
- package/dist/{Menu-C_NOsHAm.d.cts → Menu-fUnbIYr5.d.cts} +2 -2
- package/dist/{Menu-BLbEcodU.cjs → Menu-t2q8NrV0.cjs} +5 -5
- package/dist/{Menu-BLbEcodU.cjs.map → Menu-t2q8NrV0.cjs.map} +1 -1
- package/dist/Menu.d.cts +1 -1
- package/dist/Menu.d.mts +1 -1
- package/dist/{MiddleTruncatedText-BIzKECv9.cjs → MiddleTruncatedText-CO76xIqP.cjs} +2 -2
- package/dist/{MiddleTruncatedText-BIzKECv9.cjs.map → MiddleTruncatedText-CO76xIqP.cjs.map} +1 -1
- package/dist/{MiddleTruncatedText-Bzpg3zAU.mjs → MiddleTruncatedText-GXI-CPvs.mjs} +3 -3
- package/dist/{MiddleTruncatedText-Bzpg3zAU.mjs.map → MiddleTruncatedText-GXI-CPvs.mjs.map} +1 -1
- package/dist/Modal.d.cts +10 -5
- package/dist/Modal.d.mts +13 -8
- package/dist/PageHeader-CUDnarkt.cjs +77 -0
- package/dist/PageHeader-CUDnarkt.cjs.map +1 -0
- package/dist/PageHeader-D-6W61E_.mjs +64 -0
- package/dist/PageHeader-D-6W61E_.mjs.map +1 -0
- package/dist/PageHeader.d.cts +11 -2
- package/dist/PageHeader.d.mts +12 -3
- package/dist/{PageSelector-COqR1tdA.d.cts → PageSelector-CNnVp3Al.d.cts} +3 -3
- package/dist/{PageSelector-mn6q4SKY.d.mts → PageSelector-vay4jpMp.d.mts} +3 -3
- package/dist/PageSelector.d.cts +1 -1
- package/dist/PageSelector.d.mts +1 -1
- package/dist/PageSizeSelector.d.mts +7 -1
- package/dist/{Pagination-DEZFb552.cjs → Pagination-2Yo1vRJZ.cjs} +13 -9
- package/dist/Pagination-2Yo1vRJZ.cjs.map +1 -0
- package/dist/{Pagination-CeoHVtYD.d.cts → Pagination-D04tn-tf.d.cts} +9 -3
- package/dist/{Pagination-BUjpYIwq.d.mts → Pagination-ygLutOst.d.mts} +9 -3
- package/dist/{Pagination-F8ofIWnG.mjs → Pagination-ztqhywAP.mjs} +14 -10
- package/dist/Pagination-ztqhywAP.mjs.map +1 -0
- package/dist/Pagination.d.cts +1 -1
- package/dist/Pagination.d.mts +1 -1
- package/dist/{Pii--c8IxKI0.cjs → Pii-DHTb3ewO.cjs} +2 -2
- package/dist/{Pii--c8IxKI0.cjs.map → Pii-DHTb3ewO.cjs.map} +1 -1
- package/dist/{Pii-B_gBVAak.mjs → Pii-DrrtEz7U.mjs} +2 -2
- package/dist/{Pii-B_gBVAak.mjs.map → Pii-DrrtEz7U.mjs.map} +1 -1
- package/dist/Pii.d.mts +1 -1
- package/dist/PillShell.d.mts +85 -0
- package/dist/{Popover-D4_aqKlm.mjs → Popover-BkDpDdaO.mjs} +5 -5
- package/dist/{Popover-D4_aqKlm.mjs.map → Popover-BkDpDdaO.mjs.map} +1 -1
- package/dist/{Popover-jHZICnQt.cjs → Popover-BzgMAhsX.cjs} +4 -4
- package/dist/{Popover-jHZICnQt.cjs.map → Popover-BzgMAhsX.cjs.map} +1 -1
- package/dist/Popover.d.mts +1 -1
- package/dist/ProgressBar.d.mts +1 -1
- package/dist/ProgressIndicator.d.mts +1 -1
- package/dist/{PseudoClassProps--MiDp2l2.d.mts → PseudoClassProps-DLxPxo7T.d.mts} +1 -1
- package/dist/PseudoClassProps.d.mts +1 -1
- package/dist/{Radio-BN9FLRHy.cjs → Radio-BrTzy7-C.cjs} +3 -3
- package/dist/{Radio-BN9FLRHy.cjs.map → Radio-BrTzy7-C.cjs.map} +1 -1
- package/dist/{Radio-DnnJl87b.mjs → Radio-CSX2eO-O.mjs} +3 -3
- package/dist/{Radio-DnnJl87b.mjs.map → Radio-CSX2eO-O.mjs.map} +1 -1
- package/dist/{RadioGroup-BDHhFlmy.mjs → RadioGroup-CnK0opBd.mjs} +3 -3
- package/dist/{RadioGroup-BDHhFlmy.mjs.map → RadioGroup-CnK0opBd.mjs.map} +1 -1
- package/dist/{RadioGroup-D28hdlhz.cjs → RadioGroup-CriF2InQ.cjs} +3 -3
- package/dist/{RadioGroup-D28hdlhz.cjs.map → RadioGroup-CriF2InQ.cjs.map} +1 -1
- package/dist/{RadioGroup-BDO3pTgP.d.cts → RadioGroup-DKqbSfju.d.mts} +1 -1
- package/dist/{RadioGroup-DfhvXpi3.d.mts → RadioGroup-XYWjprsv.d.cts} +1 -1
- package/dist/RadioGroup.d.cts +1 -1
- package/dist/RadioGroup.d.mts +1 -1
- package/dist/RangeCalendar.d.mts +1 -1
- package/dist/RangeCalendarPresets.d.mts +1 -1
- package/dist/RuleEditorFields.d.mts +37 -0
- package/dist/RulesPill.d.mts +65 -0
- package/dist/{SearchInput-2lsv5_R6.d.mts → SearchInput-Bp2yjaE1.d.mts} +3 -3
- package/dist/{SearchInput-B6d2Qyzb.d.cts → SearchInput-CTI59-NW.d.cts} +2 -2
- package/dist/SearchInput.d.cts +1 -1
- package/dist/SearchInput.d.mts +1 -1
- package/dist/Section.d.mts +1 -1
- package/dist/{SectionHeading-BLDimf5d.d.mts → SectionHeading-C6hjGdK-.d.cts} +2 -2
- package/dist/{SectionHeading-DZyfNPn0.d.cts → SectionHeading-Q-rx2LEd.d.mts} +2 -2
- package/dist/SectionHeading.d.cts +1 -1
- package/dist/SectionHeading.d.mts +1 -1
- package/dist/{SegmentedControl-DTkFgjac.cjs → SegmentedControl-C2XZF0ys.cjs} +8 -7
- package/dist/SegmentedControl-C2XZF0ys.cjs.map +1 -0
- package/dist/{SegmentedControl-pRkMcMXe.mjs → SegmentedControl-CgDQIVll.mjs} +8 -7
- package/dist/SegmentedControl-CgDQIVll.mjs.map +1 -0
- package/dist/{SegmentedControl-1QD2zH3l.d.mts → SegmentedControl-DrjdUOU9.d.mts} +2 -2
- package/dist/{SegmentedControl-C51htGBp.d.cts → SegmentedControl-nHIK1ZvR.d.cts} +1 -1
- package/dist/SegmentedControl.d.cts +1 -1
- package/dist/SegmentedControl.d.mts +1 -1
- package/dist/{Select-XN23Ui_j.d.cts → Select-2KbtKawr.d.mts} +11 -5
- package/dist/{Select-BysJW9mH.d.mts → Select-BH3hXMxp.d.cts} +11 -5
- package/dist/{Select-CowngLd7.cjs → Select-BurtT6bN.cjs} +13 -10
- package/dist/Select-BurtT6bN.cjs.map +1 -0
- package/dist/{Select-Fg2z5J-p.mjs → Select-cPEORy70.mjs} +14 -11
- package/dist/Select-cPEORy70.mjs.map +1 -0
- package/dist/Select.d.cts +1 -1
- package/dist/Select.d.mts +1 -1
- package/dist/Slider.d.mts +1 -1
- package/dist/SliderRHF.d.mts +1 -1
- package/dist/SliderThumb.d.mts +1 -1
- package/dist/{Spacer-GYHbk-dS.cjs → Spacer-B2CerL6e.cjs} +1 -1
- package/dist/{Spacer-GYHbk-dS.cjs.map → Spacer-B2CerL6e.cjs.map} +1 -1
- package/dist/{Spacer-Ln3KChb5.mjs → Spacer-CJp0lwkL.mjs} +1 -1
- package/dist/{Spacer-Ln3KChb5.mjs.map → Spacer-CJp0lwkL.mjs.map} +1 -1
- package/dist/{Spinner-DaSlM4kU.cjs → Spinner-B6bx70yR.cjs} +1 -1
- package/dist/{Spinner-DaSlM4kU.cjs.map → Spinner-B6bx70yR.cjs.map} +1 -1
- package/dist/{Spinner-D9-u_5zS.mjs → Spinner-BEPF42RW.mjs} +1 -1
- package/dist/{Spinner-D9-u_5zS.mjs.map → Spinner-BEPF42RW.mjs.map} +1 -1
- package/dist/{Stack-ckRN7LrP.mjs → Stack-Bl54WmhY.mjs} +1 -1
- package/dist/{Stack-ckRN7LrP.mjs.map → Stack-Bl54WmhY.mjs.map} +1 -1
- package/dist/{Stack-B5VYkPBe.d.cts → Stack-BzVkf3cz.d.cts} +1 -1
- package/dist/{Stack-Du7tLSPC.d.mts → Stack-CkV7k7TE.d.mts} +2 -2
- package/dist/{Stack-BF-9YjA1.cjs → Stack-UeifHn3c.cjs} +1 -1
- package/dist/{Stack-BF-9YjA1.cjs.map → Stack-UeifHn3c.cjs.map} +1 -1
- package/dist/Stack.d.cts +1 -1
- package/dist/Stack.d.mts +1 -1
- package/dist/StatusIndicator.d.cts +31 -3
- package/dist/StatusIndicator.d.mts +32 -4
- package/dist/{Sticker-XfyoDEod.d.mts → Sticker-Bs25ISz7.d.mts} +5 -5
- package/dist/{Sticker-D9HjFQ6e.d.cts → Sticker-CI-XxUmM.d.cts} +3 -3
- package/dist/{Sticker-D0jIU2Dt.cjs → Sticker-CIoseh9f.cjs} +3 -3
- package/dist/{Sticker-D0jIU2Dt.cjs.map → Sticker-CIoseh9f.cjs.map} +1 -1
- package/dist/{Sticker-B0TbkV4o.mjs → Sticker-DbqKLe33.mjs} +3 -3
- package/dist/{Sticker-B0TbkV4o.mjs.map → Sticker-DbqKLe33.mjs.map} +1 -1
- package/dist/Sticker.d.cts +1 -1
- package/dist/Sticker.d.mts +1 -1
- package/dist/StringValueControl.d.mts +39 -0
- package/dist/SwatchPicker.d.mts +1 -1
- package/dist/Tab.d.mts +2 -2
- package/dist/{TabBar-D8WCGYd5.cjs → TabBar-PFaDNRw0.cjs} +6 -4
- package/dist/TabBar-PFaDNRw0.cjs.map +1 -0
- package/dist/{TabBar-CAv10XAF.mjs → TabBar-zSA8kyE6.mjs} +6 -4
- package/dist/TabBar-zSA8kyE6.mjs.map +1 -0
- package/dist/TabBarIconButton.d.mts +1 -1
- package/dist/{Table-D4SMuVIR.d.cts → Table-BNScLj9g.d.mts} +1 -1
- package/dist/{Table-CGtyWI6V.mjs → Table-D8IcpACv.mjs} +6 -6
- package/dist/{Table-CGtyWI6V.mjs.map → Table-D8IcpACv.mjs.map} +1 -1
- package/dist/{Table-C8D4lpSa.d.mts → Table-DXqyNohc.d.cts} +1 -1
- package/dist/{Table-B3FJsvXP.cjs → Table-DxLvJYWK.cjs} +6 -6
- package/dist/{Table-B3FJsvXP.cjs.map → Table-DxLvJYWK.cjs.map} +1 -1
- package/dist/Table.d.cts +1 -1
- package/dist/Table.d.mts +1 -1
- package/dist/{TableBody-0cd50RuX.d.mts → TableBody-CrDNMyT8.d.mts} +1 -1
- package/dist/{TableBody-BLmn5h3y.d.cts → TableBody-CxwHmdNb.d.cts} +1 -1
- package/dist/TableBody.d.cts +1 -1
- package/dist/TableBody.d.mts +1 -1
- package/dist/{TableBox-D_B9atn2.cjs → TableBox-CiuXCXyv.cjs} +229 -61
- package/dist/TableBox-CiuXCXyv.cjs.map +1 -0
- package/dist/{TableBox-CPCWzwSl.mjs → TableBox-luasMC73.mjs} +230 -62
- package/dist/TableBox-luasMC73.mjs.map +1 -0
- package/dist/TableBox.d.cts +2 -2
- package/dist/TableBox.d.mts +2 -2
- package/dist/{TableBoxCell-CEvOcGYa.d.mts → TableBoxCell-By1xE6_Q.d.mts} +28 -11
- package/dist/{TableBoxCell-DJz423uN.d.cts → TableBoxCell-DIMenSwX.d.cts} +27 -10
- package/dist/TableBoxCell.d.cts +1 -1
- package/dist/TableBoxCell.d.mts +1 -1
- package/dist/TableBoxField.d.cts +20 -5
- package/dist/TableBoxField.d.mts +20 -6
- package/dist/{TableBoxRow-LyHvITwZ.d.mts → TableBoxRow-CsRPRPQ-.d.mts} +13 -4
- package/dist/{TableBoxRow-CZwVgei6.d.cts → TableBoxRow-RNQ6wJLh.d.cts} +12 -3
- package/dist/TableBoxRow.d.cts +1 -1
- package/dist/TableBoxRow.d.mts +1 -1
- package/dist/{TableBoxRowActions-VDAOxNDG.d.cts → TableBoxRowActions-CYpoPhYZ.d.cts} +2 -2
- package/dist/{TableBoxRowActions-C8SAxrYG.d.mts → TableBoxRowActions-DMYOI8Do.d.mts} +2 -2
- package/dist/TableBoxRowActions.d.cts +1 -1
- package/dist/TableBoxRowActions.d.mts +1 -1
- package/dist/TableBoxRowContext.d.mts +5 -3
- package/dist/TableCell.d.cts +1 -1
- package/dist/TableCell.d.mts +1 -1
- package/dist/{TableControls-B4gpAvl7.d.mts → TableControls-BehR7CKS.d.mts} +4 -4
- package/dist/TableControls-BtXK7Ils.cjs +3995 -0
- package/dist/TableControls-BtXK7Ils.cjs.map +1 -0
- package/dist/{TableControls-BG0OKwjj.d.cts → TableControls-CLNF0AJG.d.cts} +3 -3
- package/dist/TableControls-DHMs7o58.mjs +3859 -0
- package/dist/TableControls-DHMs7o58.mjs.map +1 -0
- package/dist/TableControls.d.cts +1 -1
- package/dist/TableControls.d.mts +1 -1
- package/dist/{TableControlsContext-NdzzGevw.d.mts → TableControlsContext-DAZx6Rrj.d.cts} +2 -2
- package/dist/{TableControlsContext-CanIAaLW.d.cts → TableControlsContext-D_SBFZN1.d.mts} +2 -2
- package/dist/TableControlsContext.d.cts +1 -1
- package/dist/TableControlsContext.d.mts +1 -1
- package/dist/{TableHead-CuHNOeCj.d.mts → TableHead-Ch4Ho3LW.d.cts} +1 -1
- package/dist/{TableHead-roexW17v.d.cts → TableHead-LxvG0e9k.d.mts} +1 -1
- package/dist/TableHead.d.cts +1 -1
- package/dist/TableHead.d.mts +1 -1
- package/dist/{TableHeaderCell-Cflho9R2.d.mts → TableHeaderCell-Br8ZE3Xe.d.mts} +1 -1
- package/dist/{TableHeaderCell-BTGuqVXy.d.cts → TableHeaderCell-Crsa2R2g.d.cts} +1 -1
- package/dist/TableHeaderCell.d.cts +1 -1
- package/dist/TableHeaderCell.d.mts +1 -1
- package/dist/{TableLayout-BvVsuUVb.d.cts → TableLayout-Ct0kepcA.d.cts} +1 -1
- package/dist/{TableLayout-D9BGrjRs.d.mts → TableLayout-nwy094C_.d.mts} +1 -1
- package/dist/TableLayout.d.cts +1 -1
- package/dist/TableLayout.d.mts +1 -1
- package/dist/{TableRow-CjQmDmfx.d.mts → TableRow-BvS4yjo6.d.mts} +2 -2
- package/dist/{TableRow-BfGJSGZH.d.cts → TableRow-DVTPqT4w.d.cts} +1 -1
- package/dist/TableRow.d.cts +1 -1
- package/dist/TableRow.d.mts +1 -1
- package/dist/TableTH.d.cts +1 -1
- package/dist/TableTH.d.mts +1 -1
- package/dist/{TableViewConfigurationDropdown-DMeFkVUa.d.mts → TableViewConfigurationDropdown-BYPh4dIP.d.mts} +2 -2
- package/dist/{TableViewConfigurationDropdown-BaQ1IsYM.d.cts → TableViewConfigurationDropdown-CaiOGyrU.d.cts} +2 -2
- package/dist/TableViewConfigurationDropdown.d.cts +1 -1
- package/dist/TableViewConfigurationDropdown.d.mts +1 -1
- package/dist/TechnicalSticker.d.mts +1 -1
- package/dist/{Text-CPd0r0w2.d.mts → Text-DNPbAuUG.d.mts} +3 -3
- package/dist/{Text-CzN0DOXV.cjs → Text-G9QmYf0P.cjs} +1 -1
- package/dist/{Text-CzN0DOXV.cjs.map → Text-G9QmYf0P.cjs.map} +1 -1
- package/dist/{Text-hEoPeOc9.mjs → Text-RcEfNFLx.mjs} +1 -1
- package/dist/{Text-hEoPeOc9.mjs.map → Text-RcEfNFLx.mjs.map} +1 -1
- package/dist/Text.d.mts +1 -1
- package/dist/{TextArea-Dl9_Zizx.d.cts → TextArea-B89wtTsF.d.mts} +2 -2
- package/dist/{TextArea-p3oek3Zq.cjs → TextArea-BNiipQDb.cjs} +3 -3
- package/dist/{TextArea-p3oek3Zq.cjs.map → TextArea-BNiipQDb.cjs.map} +1 -1
- package/dist/{TextArea-J1MD_8rK.d.mts → TextArea-CHW9FKM4.d.cts} +2 -2
- package/dist/{TextArea-CJJlw3rV.mjs → TextArea-NCLsW-03.mjs} +3 -3
- package/dist/{TextArea-CJJlw3rV.mjs.map → TextArea-NCLsW-03.mjs.map} +1 -1
- package/dist/TextArea.d.cts +1 -1
- package/dist/TextArea.d.mts +1 -1
- package/dist/{TextUnderlineTooltip-D8GFsk5C.d.mts → TextUnderlineTooltip-5-0D8s4z.d.mts} +3 -3
- package/dist/{TextUnderlineTooltip-BDMs4iXn.d.cts → TextUnderlineTooltip-DMEyOu8C.d.cts} +2 -2
- package/dist/TextUnderlineTooltip.d.cts +1 -1
- package/dist/TextUnderlineTooltip.d.mts +1 -1
- package/dist/Tile.d.cts +1 -1
- package/dist/Tile.d.mts +2 -2
- package/dist/Toast.d.cts +1 -1
- package/dist/Toast.d.mts +1 -1
- package/dist/{Toggle-DOo0cLmI.mjs → Toggle-Bie9zCem.mjs} +5 -5
- package/dist/{Toggle-DOo0cLmI.mjs.map → Toggle-Bie9zCem.mjs.map} +1 -1
- package/dist/{Toggle-7o-n5vF6.cjs → Toggle-Ce-rF8Xp.cjs} +5 -5
- package/dist/{Toggle-7o-n5vF6.cjs.map → Toggle-Ce-rF8Xp.cjs.map} +1 -1
- package/dist/{Toggle-CY67yh4T.d.mts → Toggle-DzYLgxGk.d.mts} +1 -1
- package/dist/{Toggle-Dw4hisXm.d.cts → Toggle-tbIebQWC.d.cts} +1 -1
- package/dist/Toggle.d.cts +1 -1
- package/dist/Toggle.d.mts +1 -1
- package/dist/{Tooltip-CE1oH6Iz.d.cts → Tooltip--eDrrk2r.d.cts} +2 -2
- package/dist/{Tooltip-CDvOu1UN.mjs → Tooltip-C6AR1xT-.mjs} +3 -3
- package/dist/{Tooltip-CDvOu1UN.mjs.map → Tooltip-C6AR1xT-.mjs.map} +1 -1
- package/dist/{Tooltip-DtWJO_kU.d.mts → Tooltip-CUC-JuRL.d.mts} +3 -3
- package/dist/{Tooltip-vylydKVv.cjs → Tooltip-olP3rdUO.cjs} +3 -3
- package/dist/{Tooltip-vylydKVv.cjs.map → Tooltip-olP3rdUO.cjs.map} +1 -1
- package/dist/Tooltip.d.cts +1 -1
- package/dist/Tooltip.d.mts +1 -1
- package/dist/{TruncatedText-BBoWmFii.d.mts → TruncatedText-BJnowVTx.d.mts} +1 -1
- package/dist/{TruncatedText-DMpR-yaJ.d.cts → TruncatedText-Dit2NJI6.d.cts} +1 -1
- package/dist/components/Attribute/index.cjs +6 -6
- package/dist/components/Attribute/index.mjs +7 -7
- package/dist/components/Attribute/index.mjs.map +1 -1
- package/dist/components/Badge/index.cjs +1 -1
- package/dist/components/Badge/index.mjs +1 -1
- package/dist/components/Banner/index.cjs +1 -1
- package/dist/components/Banner/index.mjs +1 -1
- package/dist/components/Breadcrumbs/index.cjs +7 -0
- package/dist/components/Breadcrumbs/index.d.cts +2 -0
- package/dist/components/Breadcrumbs/index.d.mts +2 -0
- package/dist/components/Breadcrumbs/index.mjs +2 -0
- package/dist/components/Button/index.cjs +1 -1
- package/dist/components/Button/index.d.mts +2 -2
- package/dist/components/Button/index.mjs +1 -1
- package/dist/components/ButtonGroup/index.cjs +3 -3
- package/dist/components/ButtonGroup/index.mjs +3 -3
- package/dist/components/Card/index.cjs +1 -1
- package/dist/components/Card/index.d.cts +2 -2
- package/dist/components/Card/index.d.mts +2 -2
- package/dist/components/Card/index.mjs +1 -1
- package/dist/components/CardV2/index.cjs +3 -432
- package/dist/components/CardV2/index.d.cts +1 -1
- package/dist/components/CardV2/index.d.mts +1 -1
- package/dist/components/CardV2/index.mjs +1 -427
- package/dist/components/Checkbox/index.cjs +1 -1
- package/dist/components/Checkbox/index.d.cts +1 -1
- package/dist/components/Checkbox/index.d.mts +1 -1
- package/dist/components/Checkbox/index.mjs +1 -1
- package/dist/components/Combobox/index.cjs +1 -1
- package/dist/components/Combobox/index.d.cts +2 -2
- package/dist/components/Combobox/index.d.mts +2 -2
- package/dist/components/Combobox/index.mjs +1 -1
- package/dist/components/ConfigFormGroup/index.cjs +2 -2
- package/dist/components/ConfigFormGroup/index.mjs +2 -2
- package/dist/components/DataTable/TableControls/index.cjs +15 -1
- package/dist/components/DataTable/TableControls/index.d.cts +16 -6
- package/dist/components/DataTable/TableControls/index.d.mts +16 -6
- package/dist/components/DataTable/TableControls/index.mjs +2 -2
- package/dist/components/DataTable/index.cjs +15 -16
- package/dist/components/DataTable/index.cjs.map +1 -1
- package/dist/components/DataTable/index.mjs +25 -26
- package/dist/components/DataTable/index.mjs.map +1 -1
- package/dist/components/DataTable/types.d.cts +2 -2
- package/dist/components/DataTable/types.d.mts +2 -2
- package/dist/components/DatePicker/index.cjs +6 -898
- package/dist/components/DatePicker/index.mjs +1 -890
- package/dist/components/DropdownButton/index.cjs +1 -1
- package/dist/components/DropdownButton/index.mjs +1 -1
- package/dist/components/DropdownMenu/index.cjs +1 -1
- package/dist/components/DropdownMenu/index.d.cts +1 -1
- package/dist/components/DropdownMenu/index.d.mts +1 -1
- package/dist/components/DropdownMenu/index.mjs +1 -1
- package/dist/components/FormControl/index.cjs +2 -2
- package/dist/components/FormControl/index.d.cts +2 -2
- package/dist/components/FormControl/index.d.mts +2 -2
- package/dist/components/FormControl/index.mjs +2 -2
- package/dist/components/FormField/index.cjs +15 -468
- package/dist/components/FormField/index.d.cts +3 -3
- package/dist/components/FormField/index.d.mts +3 -3
- package/dist/components/FormField/index.mjs +1 -452
- package/dist/components/HoverCopyableField/index.cjs +1 -1
- package/dist/components/HoverCopyableField/index.mjs +1 -1
- package/dist/components/ImageTile/index.cjs +8 -8
- package/dist/components/ImageTile/index.mjs +8 -8
- package/dist/components/Input/index.cjs +1 -1
- package/dist/components/Input/index.d.cts +1 -1
- package/dist/components/Input/index.d.mts +1 -1
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Link/index.cjs +1 -1
- package/dist/components/Link/index.mjs +1 -1
- package/dist/components/ListBox/index.cjs +1 -1
- package/dist/components/ListBox/index.d.cts +4 -2
- package/dist/components/ListBox/index.d.mts +4 -2
- package/dist/components/ListBox/index.mjs +1 -1
- package/dist/components/LoadingShimmer/index.cjs +1 -1
- package/dist/components/LoadingShimmer/index.mjs +1 -1
- package/dist/components/MaskedInput/index.cjs +2 -2
- package/dist/components/MaskedInput/index.mjs +2 -2
- package/dist/components/Menu/index.cjs +1 -1
- package/dist/components/Menu/index.d.cts +1 -1
- package/dist/components/Menu/index.d.mts +1 -1
- package/dist/components/Menu/index.mjs +1 -1
- package/dist/components/Modal/index.cjs +13 -9
- package/dist/components/Modal/index.cjs.map +1 -1
- package/dist/components/Modal/index.d.cts +2 -2
- package/dist/components/Modal/index.d.mts +2 -2
- package/dist/components/Modal/index.mjs +13 -9
- package/dist/components/Modal/index.mjs.map +1 -1
- package/dist/components/PageHeader/index.cjs +3 -67
- package/dist/components/PageHeader/index.mjs +1 -63
- package/dist/components/Pagination/index.cjs +1 -1
- package/dist/components/Pagination/index.d.cts +3 -3
- package/dist/components/Pagination/index.d.mts +3 -3
- package/dist/components/Pagination/index.mjs +1 -1
- package/dist/components/Pii/index.cjs +1 -1
- package/dist/components/Pii/index.mjs +1 -1
- package/dist/components/Popover/index.cjs +1 -1
- package/dist/components/Popover/index.mjs +1 -1
- package/dist/components/ProgressBar/index.cjs +1 -1
- package/dist/components/ProgressBar/index.mjs +1 -1
- package/dist/components/Radio/index.cjs +1 -1
- package/dist/components/Radio/index.mjs +1 -1
- package/dist/components/RadioGroup/index.cjs +1 -1
- package/dist/components/RadioGroup/index.d.cts +1 -1
- package/dist/components/RadioGroup/index.d.mts +1 -1
- package/dist/components/RadioGroup/index.mjs +1 -1
- package/dist/components/SegmentedControl/index.cjs +1 -1
- package/dist/components/SegmentedControl/index.d.cts +1 -1
- package/dist/components/SegmentedControl/index.d.mts +1 -1
- package/dist/components/SegmentedControl/index.mjs +1 -1
- package/dist/components/Select/index.cjs +1 -1
- package/dist/components/Select/index.d.cts +1 -1
- package/dist/components/Select/index.d.mts +1 -1
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/Slider/index.cjs +2 -2
- package/dist/components/Slider/index.mjs +2 -2
- package/dist/components/Spacer/index.cjs +1 -1
- package/dist/components/Spacer/index.mjs +1 -1
- package/dist/components/Spinner/index.cjs +1 -1
- package/dist/components/Spinner/index.mjs +1 -1
- package/dist/components/Stack/index.cjs +1 -1
- package/dist/components/Stack/index.d.cts +1 -1
- package/dist/components/Stack/index.d.mts +1 -1
- package/dist/components/Stack/index.mjs +1 -1
- package/dist/components/StatusIndicator/index.cjs +60 -10
- package/dist/components/StatusIndicator/index.cjs.map +1 -1
- package/dist/components/StatusIndicator/index.d.cts +2 -2
- package/dist/components/StatusIndicator/index.d.mts +2 -2
- package/dist/components/StatusIndicator/index.mjs +61 -12
- package/dist/components/StatusIndicator/index.mjs.map +1 -1
- package/dist/components/Sticker/index.cjs +1 -1
- package/dist/components/Sticker/index.d.cts +1 -1
- package/dist/components/Sticker/index.d.mts +1 -1
- package/dist/components/Sticker/index.mjs +1 -1
- package/dist/components/TabBar/index.cjs +1 -1
- package/dist/components/TabBar/index.mjs +1 -1
- package/dist/components/Table/index.cjs +1 -1
- package/dist/components/Table/index.d.cts +7 -7
- package/dist/components/Table/index.d.mts +7 -7
- package/dist/components/Table/index.mjs +1 -1
- package/dist/components/TableBox/index.cjs +1 -1
- package/dist/components/TableBox/index.d.cts +2 -2
- package/dist/components/TableBox/index.d.mts +2 -2
- package/dist/components/TableBox/index.mjs +1 -1
- package/dist/components/TechnicalSticker/index.cjs +4 -4
- package/dist/components/TechnicalSticker/index.mjs +4 -4
- package/dist/components/Text/index.cjs +1 -1
- package/dist/components/Text/index.d.mts +1 -1
- package/dist/components/Text/index.mjs +1 -1
- package/dist/components/TextArea/index.cjs +1 -1
- package/dist/components/TextArea/index.d.cts +1 -1
- package/dist/components/TextArea/index.d.mts +1 -1
- package/dist/components/TextArea/index.mjs +1 -1
- package/dist/components/Tile/index.cjs +4 -4
- package/dist/components/Tile/index.mjs +4 -4
- package/dist/components/Toast/index.cjs +1 -1
- package/dist/components/Toast/index.mjs +1 -1
- package/dist/components/Toggle/index.cjs +1 -1
- package/dist/components/Toggle/index.d.cts +1 -1
- package/dist/components/Toggle/index.d.mts +1 -1
- package/dist/components/Toggle/index.mjs +1 -1
- package/dist/components/Tooltip/index.cjs +1 -1
- package/dist/components/Tooltip/index.d.cts +3 -3
- package/dist/components/Tooltip/index.d.mts +3 -3
- package/dist/components/Tooltip/index.mjs +1 -1
- package/dist/compound-expression.d.mts +9 -0
- package/dist/{constants-D5CkrHza.d.cts → constants-B6c8S033.d.cts} +1 -1
- package/dist/{constants-CnkpDWTv.d.mts → constants-BASogfT_.d.mts} +1 -1
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.mts +1 -1
- package/dist/containers.d.mts +8 -0
- package/dist/display.d.mts +8 -0
- package/dist/fieldPickerOptions.d.mts +29 -0
- package/dist/filter-size-context-Blw6Sd69.d.mts +52 -0
- package/dist/filter-size-context-CIw0Zi6r.d.cts +52 -0
- package/dist/filter-size-context.d.cts +2 -0
- package/dist/filter-size-context.d.mts +2 -0
- package/dist/helpers.d.cts +1 -1
- package/dist/helpers.d.mts +1 -1
- package/dist/index-4_B2yRzD.d.mts +7 -0
- package/dist/{index-Bp3vEph6.d.cts → index-Bw8QVu_o.d.cts} +3 -3
- package/dist/index-C9EIpBh8.d.cts +7 -0
- package/dist/index-D34XP8vp.d.cts +54 -0
- package/dist/{index-BwWgmaXZ.d.mts → index-DDbjWdk0.d.mts} +4 -4
- package/dist/index-IlwGkCAe2.d.mts +54 -0
- package/dist/index-sQecLSpR.d.cts +1 -0
- package/dist/index-sViox9YW.d.mts +1 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index2.d.cts +1 -1
- package/dist/index2.d.mts +1 -1
- package/dist/index3.d.cts +4 -1
- package/dist/index3.d.mts +4 -1
- package/dist/index4.d.cts +11 -0
- package/dist/index4.d.mts +11 -0
- package/dist/index5.d.cts +1 -0
- package/dist/index5.d.mts +2 -0
- package/dist/index6.d.mts +1 -0
- package/dist/{input-FEaQ66an.d.mts → input-Bv5fKt5J.d.mts} +3 -3
- package/dist/{input-Bm_anD8X.d.cts → input-DPB0cX2m.d.cts} +2 -2
- package/dist/inputFields.d.cts +10 -10
- package/dist/inputFields.d.mts +11 -11
- package/dist/intersperse-_0nQM5Rb.cjs +26 -0
- package/dist/intersperse-_0nQM5Rb.cjs.map +1 -0
- package/dist/intersperse-vOYvFOfF.mjs +21 -0
- package/dist/intersperse-vOYvFOfF.mjs.map +1 -0
- package/dist/layouts/LayoutLoadingShimmer/index.cjs +139 -0
- package/dist/layouts/LayoutLoadingShimmer/index.cjs.map +1 -0
- package/dist/layouts/LayoutLoadingShimmer/index.d.cts +2 -0
- package/dist/layouts/LayoutLoadingShimmer/index.d.mts +2 -0
- package/dist/layouts/LayoutLoadingShimmer/index.mjs +133 -0
- package/dist/layouts/LayoutLoadingShimmer/index.mjs.map +1 -0
- package/dist/lib/MiddleTruncatedText.cjs +1 -1
- package/dist/lib/MiddleTruncatedText.mjs +1 -1
- package/dist/lib/PDSProvider.d.mts +1 -1
- package/dist/lib/TruncatedText.cjs +1 -1
- package/dist/lib/TruncatedText.d.cts +1 -1
- package/dist/lib/TruncatedText.d.mts +1 -1
- package/dist/lib/TruncatedText.mjs +1 -1
- package/dist/lib/TruncatedTextWithTooltip.cjs +2 -2
- package/dist/lib/TruncatedTextWithTooltip.d.cts +1 -1
- package/dist/lib/TruncatedTextWithTooltip.d.mts +1 -1
- package/dist/lib/TruncatedTextWithTooltip.mjs +2 -2
- package/dist/lib/message.d.cts +1 -1
- package/dist/lib/message.d.mts +1 -1
- package/dist/lib/pseudoClass.d.mts +1 -1
- package/dist/{message-SITKO6JZ.d.mts → message-BEgtEjQC.d.cts} +1 -1
- package/dist/{message-CWEGi3Xg.d.cts → message-CMHvlPGn.d.mts} +1 -1
- package/dist/mixins/focus.d.mts +1 -1
- package/dist/mixins/hoverable.d.mts +2 -2
- package/dist/mixins/input.d.cts +1 -1
- package/dist/mixins/input.d.mts +1 -1
- package/dist/mixins/menuItem.d.mts +2 -2
- package/dist/mixins/text.d.mts +1 -1
- package/dist/operators-1qE2GpC7.d.cts +43 -0
- package/dist/operators-Bo31xlc2.d.mts +43 -0
- package/dist/operators.d.cts +2 -0
- package/dist/operators.d.mts +2 -0
- package/dist/{text-BEKhEWTa.d.mts → text-B21s9mRZ.d.mts} +1 -1
- package/dist/{theme-q9fNLtcA.d.mts → theme-BzBpJXhO.d.mts} +1 -1
- package/dist/theme.d.mts +1 -1
- package/dist/types-B_HHNlia.d.cts +158 -0
- package/dist/types-CCvc590y.d.cts +45 -0
- package/dist/{types-CmnKGG5I.d.cts → types-CkiXVJeR.d.cts} +1 -1
- package/dist/types-D58IoRx6.d.mts +158 -0
- package/dist/types-D7ppqnNj.d.mts +45 -0
- package/dist/{types-BG21GgBe.d.cts → types-DEh_pXgS.d.mts} +1 -1
- package/dist/{types-ChCqSD9N.d.mts → types-SYSKcZKW.d.cts} +1 -1
- package/dist/{types-DMjr-u_o.d.mts → types-TV9nVfSe.d.mts} +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types2.d.cts +2 -2
- package/dist/types2.d.mts +2 -2
- package/dist/types3.d.cts +2 -0
- package/dist/types3.d.mts +2 -0
- package/dist/types4.d.cts +2 -0
- package/dist/types4.d.mts +2 -0
- package/dist/use-rules-popover-selection.d.mts +19 -0
- package/dist/useColumnWidthLock.d.mts +2 -2
- package/dist/useComboboxFooterAction.d.mts +47 -0
- package/dist/useDelayedInlineEditError.d.mts +12 -0
- package/dist/useFilterStateV2-DCQghouq.d.mts +93 -0
- package/dist/useFilterStateV2-DbPwX5N1.d.cts +93 -0
- package/dist/useFilterStateV2.d.cts +2 -0
- package/dist/useFilterStateV2.d.mts +2 -0
- package/dist/{useFormField-DLGEZ1kD.d.cts → useFormField--Q8ZdpW5.d.cts} +2 -2
- package/dist/{useFormField-BpYf3CAW.cjs → useFormField-BZlArnsI.cjs} +2 -2
- package/dist/{useFormField-BpYf3CAW.cjs.map → useFormField-BZlArnsI.cjs.map} +1 -1
- package/dist/{useFormField-CVmt-ti2.d.mts → useFormField-D8mLsiQc.d.mts} +2 -2
- package/dist/{useFormField-D0RTrPld.mjs → useFormField-DhYd6bNn.mjs} +2 -2
- package/dist/{useFormField-D0RTrPld.mjs.map → useFormField-DhYd6bNn.mjs.map} +1 -1
- package/dist/useFormField.d.cts +1 -1
- package/dist/useFormField.d.mts +1 -1
- package/dist/{useFormGroup-DQJdKaL9.cjs → useFormGroup-Bmnzgq0S.cjs} +1 -1
- package/dist/{useFormGroup-DQJdKaL9.cjs.map → useFormGroup-Bmnzgq0S.cjs.map} +1 -1
- package/dist/{useFormGroup-z0epBxXn.mjs → useFormGroup-DWVW7A9f.mjs} +1 -1
- package/dist/{useFormGroup-z0epBxXn.mjs.map → useFormGroup-DWVW7A9f.mjs.map} +1 -1
- package/dist/{useTableBoxDragAndDrop-DXqy_AMP.d.mts → useTableBoxDragAndDrop-BMo-iaUF.d.mts} +1 -1
- package/dist/{useTableBoxDragAndDrop-hrESBhKb.d.cts → useTableBoxDragAndDrop-DnbUToce.d.cts} +1 -1
- package/dist/useTableBoxDragAndDrop.d.cts +1 -1
- package/dist/useTableBoxDragAndDrop.d.mts +1 -1
- package/dist/{useToggle-3k3EkV8V.mjs → useToggle-Bo3yd14Y.mjs} +1 -1
- package/dist/{useToggle-3k3EkV8V.mjs.map → useToggle-Bo3yd14Y.mjs.map} +1 -1
- package/dist/{useToggle-CSkZWXtQ.cjs → useToggle-DARO917w.cjs} +1 -1
- package/dist/{useToggle-CSkZWXtQ.cjs.map → useToggle-DARO917w.cjs.map} +1 -1
- package/dist/useTruncation.d.mts +1 -1
- package/dist/{utilities-C8Jf-xpi.d.cts → utilities-BO_95qFA.d.mts} +1 -1
- package/dist/{utilities-DT-Hh45R.d.mts → utilities-mSlaTrjB.d.cts} +1 -1
- package/dist/utilities.d.cts +1 -1
- package/dist/utilities.d.mts +1 -1
- package/dist/utils/storybook.cjs +1 -1
- package/dist/utils/storybook.mjs +1 -1
- package/dist/utils/testing.cjs +1 -1
- package/dist/utils/testing.d.mts +1 -1
- package/dist/utils/testing.mjs +1 -1
- package/dist/utils.d.mts +22 -5
- package/dist/utils2.d.mts +9 -0
- package/dist/validation-CJymv6JE.d.cts +51 -0
- package/dist/validation-vLh3t2dk.d.mts +51 -0
- package/dist/validation.d.cts +2 -0
- package/dist/validation.d.mts +2 -0
- package/dist/value-control-resolver-B9p25q3G.d.cts +46 -0
- package/dist/value-control-resolver-CE-bqdAl.d.mts +46 -0
- package/dist/value-control-resolver.d.cts +2 -0
- package/dist/value-control-resolver.d.mts +2 -0
- package/dist/variables/spacing.cjs +1 -1
- package/dist/variables/spacing.cjs.map +1 -1
- package/dist/variables/spacing.d.cts +1 -1
- package/dist/variables/spacing.d.mts +1 -1
- package/dist/variables/spacing.mjs +1 -1
- package/dist/variables/spacing.mjs.map +1 -1
- package/package.json +22 -4
- package/dist/Combobox-I44W5oX0.mjs.map +0 -1
- package/dist/Combobox-R3_NDBi3.cjs.map +0 -1
- package/dist/HoverCopyableField-DBkYvwii.mjs.map +0 -1
- package/dist/HoverCopyableField-DyW2iZuo.cjs.map +0 -1
- package/dist/ListBox-B4uoo_PT.cjs.map +0 -1
- package/dist/ListBox-B7sbubm5.mjs.map +0 -1
- package/dist/Pagination-DEZFb552.cjs.map +0 -1
- package/dist/Pagination-F8ofIWnG.mjs.map +0 -1
- package/dist/SegmentedControl-DTkFgjac.cjs.map +0 -1
- package/dist/SegmentedControl-pRkMcMXe.mjs.map +0 -1
- package/dist/Select-CowngLd7.cjs.map +0 -1
- package/dist/Select-Fg2z5J-p.mjs.map +0 -1
- package/dist/TabBar-CAv10XAF.mjs.map +0 -1
- package/dist/TabBar-D8WCGYd5.cjs.map +0 -1
- package/dist/TableBox-CPCWzwSl.mjs.map +0 -1
- package/dist/TableBox-D_B9atn2.cjs.map +0 -1
- package/dist/TableControls-B2ZsNlr6.mjs +0 -1029
- package/dist/TableControls-B2ZsNlr6.mjs.map +0 -1
- package/dist/TableControls-B7QEAzru.cjs +0 -1080
- package/dist/TableControls-B7QEAzru.cjs.map +0 -1
- package/dist/components/CardV2/index.cjs.map +0 -1
- package/dist/components/CardV2/index.mjs.map +0 -1
- package/dist/components/DatePicker/index.cjs.map +0 -1
- package/dist/components/DatePicker/index.mjs.map +0 -1
- package/dist/components/FormField/index.cjs.map +0 -1
- package/dist/components/FormField/index.mjs.map +0 -1
- package/dist/components/PageHeader/index.cjs.map +0 -1
- package/dist/components/PageHeader/index.mjs.map +0 -1
- /package/dist/{index-1-AkepUA.d.mts → index--p6oQT9I.d.mts} +0 -0
- /package/dist/{index-8SLBz2NH.d.mts → index-BL32-cvv.d.cts} +0 -0
- /package/dist/{index-BSVhZrWN.d.mts → index-BR1oNnaF.d.cts} +0 -0
- /package/dist/{index-C4zERU4O.d.cts → index-BXpMZvwA.d.cts} +0 -0
- /package/dist/{index-C6yvNuzO.d.cts → index-BYd3Btr1.d.mts} +0 -0
- /package/dist/{index-CIABef8t.d.mts → index-BhY1qu3m.d.cts} +0 -0
- /package/dist/{index-CP2eJYlK.d.mts → index-C0NRIDsj2.d.cts} +0 -0
- /package/dist/{index-CTBW75wG2.d.cts → index-C1ihAKnV.d.cts} +0 -0
- /package/dist/{index-CiBIKhMu.d.cts → index-CDGG7lCB.d.mts} +0 -0
- /package/dist/{index-Cii4Qb1X.d.mts → index-CFG0_wK4.d.cts} +0 -0
- /package/dist/{index-CspKFJM1.d.cts → index-CKKoxA9V.d.mts} +0 -0
- /package/dist/{index-CswGToRr2.d.mts → index-CNxS4Tlu.d.mts} +0 -0
- /package/dist/{index-D4ELpJXS.d.cts → index-CQ25UCod.d.cts} +0 -0
- /package/dist/{index-D8dPsry7.d.mts → index-CWB6exYm.d.mts} +0 -0
- /package/dist/{index-D9XihFV1.d.mts → index-Cv0jeUQf2.d.cts} +0 -0
- /package/dist/{index-DBQaKYAL2.d.cts → index-CwSIy_W-.d.cts} +0 -0
- /package/dist/{index-DLoAMD9J.d.cts → index-CzItj62a.d.mts} +0 -0
- /package/dist/{index-DZlqSwCF.d.mts → index-D-BciAtf.d.cts} +0 -0
- /package/dist/{index-Dflz2i1X.d.mts → index-D4DUvwPf.d.mts} +0 -0
- /package/dist/{index-Dpmi5zcN.d.cts → index-D5tSVhTd.d.mts} +0 -0
- /package/dist/{index-DwBYcw1r.d.cts → index-D9IqtUDs.d.cts} +0 -0
- /package/dist/{index-LhFpnU-f.d.mts → index-DGsJdI5l.d.mts} +0 -0
- /package/dist/{index-N-OgGgfF.d.mts → index-DM6vVDZD.d.mts} +0 -0
- /package/dist/{index-VmEFGBxN.d.cts → index-DXJd7-2Z.d.mts} +0 -0
- /package/dist/{index-_1bfRgi2.d.cts → index-DkrC-i1D.d.mts} +0 -0
- /package/dist/{index-c55Utzva.d.mts → index-DpEKQcoR.d.cts} +0 -0
- /package/dist/{index-gpCH5158.d.mts → index-DvuJXuAN.d.mts} +0 -0
- /package/dist/{index-kDNN3kX_2.d.mts → index-Iujpc9_6.d.mts} +0 -0
- /package/dist/{index-luywJTzJ.d.mts → index-Oio5ygqN.d.mts} +0 -0
- /package/dist/{index-qCd8f7Um.d.cts → index-_wQ5ClJU.d.cts} +0 -0
- /package/dist/{index-uTS5iDq_.d.cts → index-lIMqGGJz.d.mts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox-R3_NDBi3.cjs","names":["Fuse","MenuHeading","Fragment","Input","Spacing","focusStyle","Button","Color","FloatingCard","Z_INDICES","MenuList","Paragraph","Typography","EXTERNAL_TRIGGER_DROPDOWN_MIN_WIDTH","Spacing","Sticker","StyledMenuItem","MenuItem","Color","Typography","useFormField","useMultipleSelection","useCombobox","Stack","Checkbox","CircleXInverseIcon","CaretDownIcon","InputGroup","SearchIcon","Spinner","MenuItem","Spacing","MenuItemIconContainer","Color","Typography","Sticker","useFormField","Fuse","useCombobox","ChevronRightIcon","Fragment","MenuHeading","CaretDownIcon","InputGroup","SearchIcon","ArrowLeftIcon","Spinner"],"sources":["../components/Combobox/ComboboxBase.tsx","../components/Combobox/useTruncation.ts","../components/Combobox/ComboboxMultiSelect.tsx","../components/Combobox/ComboboxSingleSelect.tsx","../components/Combobox/Combobox.tsx"],"sourcesContent":["import type { Virtualizer } from '@tanstack/react-virtual';\nimport Fuse, { type IFuseOptions } from 'fuse.js';\nimport { type CSSProperties, Fragment, useEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\nimport Button from 'design-system/components/Button';\nimport Input from 'design-system/components/Input';\nimport { FloatingCard, MenuHeading, MenuList } from 'design-system/components/Menu';\nimport type { StickerProps } from 'design-system/components/Sticker/Sticker';\nimport { Paragraph } from 'design-system/components/Text';\nimport { Z_INDICES } from 'design-system/lib/zindex';\nimport { focusStyle } from 'design-system/mixins/focus';\nimport type { InputSizes } from 'design-system/mixins/input';\n\n/**\n * In the future, we may extend this to include other style properties\n * like fontWeight, fontStyle, etc. if needed.\n */\ntype LabelStyle = Pick<CSSProperties, 'fontFamily'>;\n\n// Re-export ComboboxOption type that both components need\nexport interface ComboboxOption<T = string> {\n label: string;\n /**\n * Description of the option that will be displayed below the label. Will not be rendered when labelStickerVariant is provided.\n */\n description?: string;\n value: T;\n /**\n * Sticker variant to render the label within.\n */\n labelStickerVariant?: StickerProps['variant'];\n /**\n * Optional style properties to apply to the option label currently limited to fontFamily.\n * This should only be used as a one-off for font dropdowns and most comboboxes should use the default fontFamily.\n */\n PLEASE_DO_NOT_USE_labelFontStyle?: LabelStyle;\n}\n\n// Group type — either an inline section header (the default) or a\n// nested submenu the user navigates into (`nested: true`).\nexport interface ComboboxOptionGroup<T = string> {\n readonly label: string;\n readonly options: ComboboxOptionsOrGroups<T>;\n /**\n * When `true`, the group renders as a single navigation row with a\n * trailing chevron. Clicking it descends into a submenu whose\n * contents are this group's `options`; the group itself never\n * commits a value via `onChange`. The `label` becomes the\n * breadcrumb crumb shown alongside any leaf inside in search mode.\n *\n * When omitted (or `false`), the group renders inline as a section\n * header above its options — the legacy `MenuHeading` behavior.\n *\n * Today only single-select Combobox honors the nested-navigation\n * UX. Multi-select degrades gracefully: it strips the `nested`\n * flag from every group at the top of the component (treating the\n * tree as inline section headers + leaves), so every leaf stays\n * reachable with checkboxes — just without the chevron / Back-row\n * navigation. Nested-nav for multi-select can be added once we\n * have customer demand without changing this API.\n */\n readonly nested?: boolean;\n}\n\n// Type guard using structural typing (like react-select's GroupBase)\nexport function isOptionGroup<T>(\n item: ComboboxOption<T> | ComboboxOptionGroup<T>,\n): item is ComboboxOptionGroup<T> {\n return 'options' in item && Array.isArray((item as ComboboxOptionGroup<T>).options);\n}\n\n/** True when a group renders as a navigation row rather than a section header. */\nexport function isNestedGroup<T>(\n item: ComboboxOption<T> | ComboboxOptionGroup<T>,\n): item is ComboboxOptionGroup<T> & { nested: true } {\n return isOptionGroup(item) && item.nested === true;\n}\n\n// Union type for options prop — supports flat options, inline groups\n// (section headers), nested groups (submenu entries), or any mix.\nexport type ComboboxOptionsOrGroups<T = string> = readonly (\n | ComboboxOption<T>\n | ComboboxOptionGroup<T>\n)[];\n\n/**\n * Flatten the visible leaves at the current navigation level. Inline\n * (non-nested) groups are walked through transparently — their leaves\n * surface at this level. Nested groups are skipped along with their\n * contents — those leaves live behind a navigation step in single-\n * select. Multi-select doesn't reach this code with nested groups\n * intact (it inlines them at the component boundary), so the skip\n * here is the single-select-only contract.\n */\nexport function flattenOptions<T>(items: ComboboxOptionsOrGroups<T>): ComboboxOption<T>[] {\n const out: ComboboxOption<T>[] = [];\n for (const item of items) {\n if (isOptionGroup(item)) {\n if (!item.nested) {\n out.push(...flattenOptions(item.options));\n }\n } else {\n out.push(item);\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Nested-navigation helpers\n//\n// A single-select Combobox can act as a cascading menu by tagging\n// groups with `nested: true`: those groups render as navigation rows\n// (chevron) that descend into a submenu showing the group's `options`.\n// The functions below resolve the items visible at a given navigation\n// path and flatten the tree to its leaves for search-mode fallback.\n// ---------------------------------------------------------------------------\n\n/**\n * Recurse through the entire option tree looking for any nested\n * group. Used to gate nested-mode behavior so trees that don't opt\n * in (the overwhelmingly common case) skip the extra book-keeping\n * entirely. Single-select uses this to switch between its nested-nav\n * render path and the legacy renderer; multi-select uses it to\n * short-circuit its `nested → inline` transform when there's nothing\n * to convert.\n */\nexport function containsNestedGroup<T>(\n items: readonly (ComboboxOption<T> | ComboboxOptionGroup<T>)[],\n): boolean {\n for (const item of items) {\n if (isOptionGroup(item)) {\n if (item.nested) {\n return true;\n }\n if (containsNestedGroup(item.options)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Find a nested-group child of `items` whose `label` matches `label`.\n * Walks transparently through inline (non-nested) groups at the same\n * level — they don't add a navigation step, so a nested submenu\n * declared inside an inline section header is still \"at this level\"\n * for descent purposes. Returns `null` if no match.\n */\nfunction findNestedGroupByLabel<T>(\n items: ComboboxOptionsOrGroups<T>,\n label: string,\n): ComboboxOptionGroup<T> | null {\n for (const item of items) {\n if (!isOptionGroup(item)) {\n continue;\n }\n if (item.nested) {\n if (item.label === label) {\n return item;\n }\n } else {\n const found = findNestedGroupByLabel(item.options, label);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\n/**\n * Walk the option tree by following `path` step-by-step. Each entry\n * in `path` is the `label` of a nested group at that level; we\n * descend into its `options` at each step. Returns the items visible\n * at the resolved level (a mix of leaves, inline groups, and further\n * nested groups).\n *\n * - Empty `path` returns the original top-level items unchanged.\n * - If any step doesn't resolve to a known nested group (e.g. stale\n * state after the registry changes), returns an empty list so the\n * consumer can fall back to the root view.\n */\nexport function getOptionsAtPath<T>(\n options: ComboboxOptionsOrGroups<T>,\n path: readonly string[],\n): ComboboxOptionsOrGroups<T> {\n let scope = options;\n for (const label of path) {\n const found = findNestedGroupByLabel(scope, label);\n if (!found) {\n return [];\n }\n scope = found.options;\n }\n return scope;\n}\n\n/**\n * One leaf hit returned by `flattenLeafOptions`. Carries the leaf's\n * `option` alongside the labels of every nested-group ancestor\n * (top-down). Used as the search-results data shape so each hit can\n * render with a breadcrumb (e.g. \"Business Account\" for a custom\n * field that lives under that parent record type's submenu).\n */\nexport interface LeafOptionEntry<T = string> {\n option: ComboboxOption<T>;\n breadcrumb: readonly string[];\n}\n\n/**\n * Recursively walk the tree and return every leaf option, each paired\n * with the labels of its nested-group ancestors. Used by single-select\n * Combobox to populate the search-results view: the search query\n * bypasses the active navigation path and matches against every leaf\n * in the tree, with the breadcrumb surfacing parent context in each\n * hit.\n *\n * Inline (non-nested) groups are walked through transparently — their\n * `label` isn't a breadcrumb crumb because they don't correspond to a\n * navigation step. Only nested groups contribute a crumb.\n */\nexport function flattenLeafOptions<T>(\n options: ComboboxOptionsOrGroups<T>,\n breadcrumb: readonly string[] = [],\n): LeafOptionEntry<T>[] {\n const result: LeafOptionEntry<T>[] = [];\n for (const item of options) {\n if (isOptionGroup(item)) {\n const nextBreadcrumb = item.nested ? [...breadcrumb, item.label] : breadcrumb;\n result.push(...flattenLeafOptions(item.options, nextBreadcrumb));\n } else {\n result.push({ option: item, breadcrumb });\n }\n }\n return result;\n}\n\n/**\n * Discriminated tagged item for single-select's downshift items list\n * in nested-navigation mode. Leaves are selectable and commit via\n * `onChange`; groups are navigable and descend into a submenu instead.\n */\nexport type NavigableItem<T> =\n | { readonly kind: 'leaf'; readonly option: ComboboxOption<T> }\n | { readonly kind: 'group'; readonly group: ComboboxOptionGroup<T> };\n\n/**\n * Build the flat list of navigable items at the current navigation\n * level, in document order. Inline (non-nested) groups are walked\n * through transparently; their leaves and any nested subgroups\n * contribute at this level. Nested groups become a `kind: 'group'`\n * entry that the renderer turns into a navigation row.\n */\nexport function getNavigableItemsAtLevel<T>(items: ComboboxOptionsOrGroups<T>): NavigableItem<T>[] {\n const out: NavigableItem<T>[] = [];\n for (const item of items) {\n if (isOptionGroup(item)) {\n if (item.nested) {\n out.push({ kind: 'group', group: item });\n } else {\n out.push(...getNavigableItemsAtLevel(item.options));\n }\n } else {\n out.push({ kind: 'leaf', option: item });\n }\n }\n return out;\n}\n\n/**\n * A hook which provides the caller with dynamically filtered options\n *\n * @param options - The options to filter (can be flat or grouped)\n * @param inputValue - The input value to filter the options by\n * @returns The subset of the options that match the input value according to the fuse.js library\n */\nexport function useFilteredOptions<T = string>(\n options: ComboboxOptionsOrGroups<T>,\n inputValue: string,\n) {\n return useMemo(() => {\n // Flatten grouped options for filtering\n const flatOptions = flattenOptions(options);\n\n const fuseOptions: IFuseOptions<ComboboxOption<T>> = {\n shouldSort: false,\n threshold: 0.0,\n ignoreLocation: true,\n minMatchCharLength: 1,\n keys: ['label', 'description'],\n };\n\n const fuse = new Fuse<ComboboxOption<T>>(flatOptions, fuseOptions);\n\n return inputValue === ''\n ? flatOptions\n : Array.from(new Set(fuse.search(inputValue).map(({ item }) => item)).values());\n }, [options, inputValue]);\n}\n\n// A row in the virtualized list — either a group label or an option\ntype VirtualRow<T> =\n | { kind: 'group-header'; label: string }\n | { kind: 'option'; option: ComboboxOption<T>; index: number };\n\nexport function buildVirtualRows<T>(\n options: ComboboxOptionsOrGroups<T>,\n filteredOptions: ComboboxOption<T>[],\n indexRealToIndexVirtual: Map<number, number>,\n): VirtualRow<T>[] {\n const rows: VirtualRow<T>[] = [];\n // idx counts only option rows — matches navigableItems indices (no group headers)\n let idx = 0;\n\n for (const item of options) {\n if (isOptionGroup(item)) {\n // Nested groups belong to the single-select nested-nav render\n // path. Multi-select (the only `buildVirtualRows` caller)\n // inlines its nested groups at the component boundary, so any\n // group reaching here with `nested: true` is unexpected — skip\n // defensively rather than render a header without a row.\n if (item.nested) {\n continue;\n }\n const groupLeaves = flattenOptions(item.options);\n const visibleLeaves = groupLeaves.filter((opt) =>\n filteredOptions.some((f) => f.value === opt.value),\n );\n if (visibleLeaves.length > 0) {\n rows.push({ kind: 'group-header', label: item.label });\n for (const opt of visibleLeaves) {\n indexRealToIndexVirtual.set(idx, rows.length);\n rows.push({ kind: 'option', option: opt, index: idx++ });\n }\n }\n } else {\n if (filteredOptions.some((f) => f.value === item.value)) {\n indexRealToIndexVirtual.set(idx, rows.length);\n rows.push({ kind: 'option', option: item, index: idx++ });\n }\n }\n }\n\n return rows;\n}\n\ninterface RenderOptionsWithGroupsParams<T> {\n options: ComboboxOptionsOrGroups<T>;\n filteredOptions: ComboboxOption<T>[];\n virtualizer?: Virtualizer<HTMLDivElement, Element>;\n virtualRows?: VirtualRow<T>[];\n renderOption: (option: ComboboxOption<T>, flatIndex: number) => React.ReactNode;\n}\n\n/**\n * Renders options with support for groups, handling filtering and proper indexing\n *\n * @param params - Object containing options, filteredOptions, and renderOption\n * @param params.options - The original options array (can include groups)\n * @param params.filteredOptions - The flat filtered options to display\n * @param params.virtualizer - Optional virtualizer for large lists\n * @param params.virtualRows - Pre-built flat rows list (required when virtualizer is provided)\n * @param params.renderOption - Callback to render each individual option with its flat index\n * @returns React nodes with properly grouped and filtered options\n */\nexport function renderOptionsWithGroups<T>({\n options,\n filteredOptions,\n renderOption,\n virtualizer,\n virtualRows,\n}: RenderOptionsWithGroupsParams<T>): React.ReactNode {\n if (virtualizer && virtualRows) {\n const rows = virtualRows;\n const vItems = virtualizer.getVirtualItems();\n return (\n <div\n style={{\n height: `${virtualizer.getTotalSize()}px`,\n width: '100%',\n position: 'relative',\n }}\n >\n {vItems.map((vItem) => {\n const row = rows[vItem.index];\n if (!row) {\n return null;\n }\n\n return (\n <div\n key={String(vItem.key)}\n data-index={vItem.index}\n ref={virtualizer.measureElement}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${vItem.start}px)`,\n }}\n >\n {row.kind === 'group-header' ? (\n <MenuHeading as='div'>{row.label}</MenuHeading>\n ) : (\n renderOption(row.option, row.index)\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n let flatIndex = -1;\n\n return options.map((item, groupIndex) => {\n if (isOptionGroup(item)) {\n // Nested groups belong to the single-select nested-nav code\n // path, which renders them via its own local helper. Multi-\n // select inlines nested groups at the component boundary\n // before calling this renderer, so a group reaching here with\n // `nested: true` is single-select's responsibility — skip it.\n if (item.nested) {\n return null;\n }\n const groupLeaves = flattenOptions(item.options);\n const visibleLeaves = groupLeaves.filter((opt) =>\n filteredOptions.some((filtered) => filtered.value === opt.value),\n );\n\n if (visibleLeaves.length === 0) {\n return null;\n }\n\n return (\n <Fragment key={`group-${groupIndex}`}>\n <MenuHeading>{item.label}</MenuHeading>\n {visibleLeaves.map((option) => {\n flatIndex++;\n return renderOption(option, flatIndex);\n })}\n </Fragment>\n );\n } else {\n // This is a flat option\n if (!filteredOptions.some((filtered) => filtered.value === item.value)) {\n return null;\n }\n\n flatIndex++;\n return renderOption(item, flatIndex);\n }\n });\n}\n\n// Base interface with common props\nexport interface ComboboxBaseProps<T = string> {\n /**\n * Size of the combobox input\n */\n size?: InputSizes;\n\n /**\n * Array of options to display in the dropdown\n * Can be flat options, grouped options, or a mix of both\n */\n options: ComboboxOptionsOrGroups<T>;\n\n /**\n * If true, the options are currently being loaded\n */\n isOptionsLoading?: boolean;\n\n /**\n * Callback when input value changes (for filtering)\n * In single this is the main input, in multi this is the search input\n * In both cases this corresponds to the input the user can type into to filter the options\n */\n onInputChange?: (value: string) => void;\n\n /**\n * Callback when dropdown open state changes\n */\n onOpenChange?: (isOpen: boolean) => void;\n\n /**\n * Custom empty state message when no options match filter\n */\n emptyStateMessage?: string;\n\n /**\n * Whether the combobox is disabled\n */\n disabled?: boolean;\n\n /**\n * ID of the label for the combobox input\n */\n labelId?: string;\n\n /**\n * Aria label for accessibility when no visible label is provided\n */\n 'aria-label'?: string;\n\n /**\n * Placeholder text when no option is selected\n */\n placeholder?: string;\n\n /**\n * Whether the combobox has a warning state\n */\n hasWarning?: boolean;\n\n /**\n * Whether the combobox has an error state\n */\n hasError?: boolean;\n\n /**\n * ID for the combobox input\n */\n id?: string;\n\n /**\n * Whether to render the dropdown in a portal (breaks out of overflow containers)\n */\n portal?: boolean;\n\n /**\n * Reference to the container element for portal rendering.\n * When provided, the dropdown will use this element's dimensions for positioning.\n */\n portalContainerRef?: React.RefObject<HTMLElement>;\n\n /**\n * Optional external trigger (e.g. an \"Add\" button or icon-only menu opener).\n * When provided, the Combobox clones it with downshift's toggle props and\n * renders it in place of the default input + caret; the search input moves\n * inside the dropdown.\n */\n trigger?: React.ReactElement;\n\n /**\n * Render the searchable option list inline without a trigger or floating\n * dropdown. Use when another component already owns the containing popover.\n *\n * When `true`, the in-panel search uses bordered `Input` chrome and the\n * embedder owns all surrounding spacing; when `false`, the floating-dropdown\n * borderless search strip is preserved.\n */\n embedded?: boolean;\n}\n\n// Shared constants\nexport const MAX_DROPDOWN_HEIGHT = '300px';\n\n// Shared styled components\nexport const Container = styled.div`\n display: flex;\n position: relative;\n width: 100%;\n`;\n\nexport const InputContainer = styled.div`\n position: relative;\n width: 100%;\n`;\n\n// Interface for ComboboxInput props\ninterface ComboboxInputProps {\n $isOpen?: boolean;\n hasError?: boolean;\n hasWarning?: boolean;\n $selectedItemStyle?: LabelStyle;\n}\n\nexport const ComboboxInput = styled(Input)<ComboboxInputProps>`\n padding-right: ${({ size }) =>\n size === 'sm' ? Spacing[5] : Spacing[6]}; /* Space for caret icon */\n\n ${({ $isOpen }) =>\n $isOpen &&\n css`\n ${focusStyle}\n `}\n\n /* Apply custom font family from selected item when dropdown is closed */\n ${({ $selectedItemStyle, $isOpen }) =>\n !$isOpen &&\n $selectedItemStyle?.fontFamily &&\n css`\n && {\n font-family: ${$selectedItemStyle.fontFamily};\n }\n `}\n`;\n\nexport const CaretButton = styled(Button).attrs({ width: 'icon' })`\n background-color: transparent;\n border: none;\n color: ${Color.BorderIconPrimary};\n\n &:hover:not(:disabled),\n &:active:not(:disabled) {\n color: ${Color.BorderIconPrimary};\n background-color: transparent;\n border: none;\n }\n\n &:disabled {\n color: ${Color.BorderIconDisabled};\n background-color: transparent;\n border: none;\n }\n\n position: absolute;\n right: 0;\n top: 0;\n`;\n\ninterface DropdownContainerProps {\n $isOpen?: boolean;\n $portal?: boolean;\n $embedded?: boolean;\n $top?: number;\n $left?: number;\n $width?: number;\n /** Minimum dropdown width (decouples from a narrow trigger). */\n $minWidth?: string;\n}\n\nexport const DropdownContainer = styled(FloatingCard)<DropdownContainerProps>`\n ${({ $portal, $embedded, $top, $left, $width }) =>\n $embedded\n ? css`\n position: static;\n width: 100%;\n min-width: 0;\n border: 0;\n border-radius: 0;\n box-shadow: none;\n background: transparent;\n margin: 0;\n `\n : $portal\n ? css`\n position: fixed;\n top: ${$top != null ? `${$top}px` : '0'};\n left: ${$left != null ? `${$left}px` : '0'};\n width: ${$width != null ? `${$width}px` : 'auto'};\n `\n : css`\n position: absolute;\n top: calc(100% + ${Spacing[2]});\n left: 0;\n right: 0;\n width: 100%;\n `}\n\n ${({ $minWidth }) =>\n $minWidth &&\n css`\n min-width: ${$minWidth};\n `}\n\n display: flex;\n flex-direction: column;\n ${({ $embedded }) =>\n $embedded &&\n css`\n gap: ${Spacing[2]};\n `}\n overflow: ${({ $embedded }) =>\n $embedded\n ? 'visible'\n : 'hidden'}; /* Prevent floating menu overflow while preserving embedded focus rings */\n box-sizing: border-box;\n z-index: ${Z_INDICES.modalDropdown}; /* Ensure portal dropdown appears above other content */\n\n ${({ $isOpen }) =>\n !$isOpen &&\n css`\n display: none;\n `}\n`;\n\nexport const ScrollableMenuList = styled(MenuList)`\n max-height: ${MAX_DROPDOWN_HEIGHT};\n overflow-y: auto;\n overflow-x: hidden; /* Prevent horizontal scrolling */\n width: 100%; /* Ensure full width is used */\n box-sizing: border-box;\n`;\n\n// In-dropdown search chrome, shared by any Combobox-family component that\n// renders a search row inside the dropdown panel.\nexport const SearchInputContainer = styled.div<{ $embedded?: boolean }>`\n flex-shrink: 0;\n ${({ $embedded }) =>\n $embedded\n ? css`\n padding: 0;\n `\n : css`\n padding: ${Spacing[1]} ${Spacing[2]};\n border-bottom: 1px solid ${({ theme }) => theme.color.border.primary};\n `}\n`;\n\nexport const SearchInput = styled(Input)<{ $embedded?: boolean }>`\n ${({ $embedded }) =>\n !$embedded &&\n css`\n /* Borderless strip inside floating menus */\n border: none;\n padding-top: ${Spacing[1]};\n padding-bottom: ${Spacing[1]};\n\n &:focus {\n outline: none !important;\n }\n `}\n`;\n\nexport const EmptyState = styled(Paragraph).attrs<{ size: InputSizes }>(({ size }) => ({\n size,\n}))`\n padding: 0 ${({ size }) => (size === 'sm' ? Spacing[1] : Spacing[2])};\n color: ${({ theme }) => theme.color.text.tertiary};\n ${({ theme }) => theme.text.paragraph.md};\n`;\n\nexport const LoadingContainer = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 136px;\n padding: ${Spacing[3]};\n`;\n\nexport const OptionLabel = styled.div<{ $labelStyle?: LabelStyle }>`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0; /* Allow flex item to shrink below content size */\n\n /* Apply custom font family if provided */\n ${({ $labelStyle }) =>\n $labelStyle?.fontFamily &&\n css`\n font-family: ${$labelStyle.fontFamily};\n `}\n`;\n\nexport const Description = styled.p`\n ${Typography.TextSmall};\n color: ${Color.TextSecondary};\n margin: 0;\n\n /* Multi-line truncation with 3-line limit */\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n\n /* Fallback for browsers that don't support -webkit-line-clamp */\n max-height: calc(${Typography.TextSmall.lineHeight} * 3); /* line-height * 3 lines */\n`;\n\n// Hook to calculate dropdown position for portal rendering\nexport function useDropdownPosition(\n portalContainerRef: React.RefObject<HTMLElement>,\n isOpen: boolean,\n portal?: boolean,\n) {\n const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });\n\n useEffect(() => {\n if (!portal || !isOpen || !portalContainerRef.current) {\n return;\n }\n\n const updatePosition = () => {\n const rect = portalContainerRef.current!.getBoundingClientRect();\n const spacing = parseInt(Spacing[2]);\n setPosition({\n top: rect.bottom + spacing,\n left: rect.left,\n width: rect.width,\n });\n };\n\n updatePosition();\n\n // Update position on scroll and resize\n window.addEventListener('scroll', updatePosition, true);\n window.addEventListener('resize', updatePosition);\n\n return () => {\n window.removeEventListener('scroll', updatePosition, true);\n window.removeEventListener('resize', updatePosition);\n };\n }, [portalContainerRef, isOpen, portal]);\n\n return position;\n}\n\n// Wrapper component for portal rendering\nexport interface DropdownPortalWrapperProps {\n children: React.ReactNode;\n portal?: boolean;\n}\n\nexport function DropdownPortalWrapper({ children, portal }: DropdownPortalWrapperProps) {\n const portalRoot = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (portal) {\n portalRoot.current = document.body;\n }\n }, [portal]);\n\n if (portal && portalRoot.current) {\n return createPortal(\n // data-react-aria-top-layer='true': FocusScope contain allows focus here\n // (presence selector). ariaHideOutside's MutationObserver only exempts\n // newly added nodes when the dataset value is the string 'true'.\n <div id='combobox-dropdown-portal-wrapper' data-react-aria-top-layer='true'>\n {children}\n </div>,\n portalRoot.current,\n );\n }\n\n return <>{children}</>;\n}\n","import { type MutableRefObject, type RefObject, useEffect, useState } from 'react';\n\nimport type { ComboboxOption } from 'design-system/components/Combobox';\n\n/**\n * Custom hook for calculating truncation when multi-select items are restricted to a single line using actual DOM measurements\n * Ensures at least one item is always visible\n */\nexport function useTruncation<T>(\n selectedItems: ComboboxOption<T>[],\n stickerRefs: MutableRefObject<(HTMLElement | null)[]>,\n truncatorRef: RefObject<HTMLElement>,\n containerRef: RefObject<HTMLDivElement>,\n truncate: boolean,\n) {\n const [visibleCount, setVisibleCount] = useState<number>(selectedItems.length);\n\n useEffect(() => {\n if (!truncate || selectedItems.length === 0 || !containerRef.current) {\n setVisibleCount(selectedItems.length);\n return;\n }\n\n const calculateVisibleCount = () => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n // Check if all refs are populated\n const allRefsReady =\n selectedItems.every((_, i) => stickerRefs.current[i] != null) &&\n truncatorRef.current != null;\n if (!allRefsReady) {\n return;\n }\n\n // Get actual content width by subtracting padding\n const computedStyle = window.getComputedStyle(container);\n const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0;\n const paddingRight = parseFloat(computedStyle.paddingRight) || 0;\n const availableWidth = container.offsetWidth - paddingLeft - paddingRight;\n\n const gap = 4; // Spacing[1] = 4px\n const truncatorWidth = truncatorRef.current!.offsetWidth;\n\n // Simple algorithm: Start with 1 item, keep adding while they fit\n let count = 1;\n let totalWidth = stickerRefs.current[0]!.offsetWidth;\n\n // Try to add more items\n for (let i = 1; i < selectedItems.length; i++) {\n const itemWidth = stickerRefs.current[i]!.offsetWidth;\n const wouldBeLastItem = i === selectedItems.length - 1;\n\n // Calculate required width if we add this item\n const widthWithItem = totalWidth + gap + itemWidth;\n const widthWithTruncator = wouldBeLastItem ? 0 : gap + truncatorWidth;\n const requiredWidth = widthWithItem + widthWithTruncator;\n\n if (requiredWidth <= availableWidth) {\n totalWidth = widthWithItem;\n count++;\n } else {\n // Can't fit this item, stop\n break;\n }\n }\n\n // Update state only if changed\n setVisibleCount((prev) => (prev === count ? prev : count));\n };\n\n // Recalculate on resize\n const resizeObserver = new ResizeObserver(calculateVisibleCount);\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [selectedItems, stickerRefs, truncatorRef, containerRef, truncate]);\n\n return visibleCount;\n}\n","import { useVirtualizer } from '@tanstack/react-virtual';\nimport { useCombobox, useMultipleSelection } from 'downshift';\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\nimport { CaretDownIcon, CircleXInverseIcon, SearchIcon } from '@persona/icons';\nimport Checkbox from 'design-system/components/Checkbox';\nimport {\n CaretButton,\n type ComboboxBaseProps,\n ComboboxInput,\n type ComboboxOption,\n type ComboboxOptionsOrGroups,\n containsNestedGroup,\n Container,\n Description,\n DropdownContainer,\n DropdownPortalWrapper,\n EmptyState,\n flattenOptions,\n InputContainer,\n isOptionGroup,\n LoadingContainer,\n MAX_DROPDOWN_HEIGHT,\n OptionLabel,\n renderOptionsWithGroups,\n ScrollableMenuList,\n SearchInput,\n SearchInputContainer,\n useDropdownPosition,\n useFilteredOptions,\n buildVirtualRows,\n} from 'design-system/components/Combobox/ComboboxBase';\nimport { useTruncation } from 'design-system/components/Combobox/useTruncation';\nimport useFormField from 'design-system/components/FormControl/useFormField';\nimport { InputGroup } from 'design-system/components/Input';\nimport { MenuItem } from 'design-system/components/Menu';\nimport Spinner from 'design-system/components/Spinner/Spinner';\nimport Stack from 'design-system/components/Stack';\nimport Sticker from 'design-system/components/Sticker';\nimport { useOutsideClick } from 'design-system/lib/useOutsideClick';\nimport type { InputSizes } from 'design-system/mixins/input';\n\n// Constants\nconst SELECT_ALL_VALUE = '__SELECT_ALL__';\nconst EXTERNAL_TRIGGER_DROPDOWN_MIN_WIDTH = '240px';\n\n/**\n * Recursively drop the `nested: true` flag from every group in the\n * tree, converting nested-navigation groups into inline section-\n * header groups. Multi-select doesn't implement the nested-nav UX\n * (chevron rows, Back row, descent), so this graceful-degradation\n * transform keeps every leaf reachable as a checkable option under\n * its parent's section header — instead of having `flattenOptions` /\n * `renderOptionsWithGroups` silently drop them along with their\n * descendants. Single-select Combobox is unaffected; it owns its own\n * nested-nav render path.\n *\n * For a multi-level tree (`{nested, options: [{nested, options}]}`),\n * the inner inline group is walked through by `flattenOptions` so\n * its leaves surface under the outer header — the inner label is\n * lost, but all leaves stay reachable. Acceptable for the\n * graceful-degradation goal; nested-nav can be added later without\n * changing this API.\n */\nfunction inlineNestedGroups<T>(items: ComboboxOptionsOrGroups<T>): ComboboxOptionsOrGroups<T> {\n return items.map((item) => {\n if (!isOptionGroup(item)) {\n return item;\n }\n return {\n label: item.label,\n options: inlineNestedGroups(item.options),\n };\n });\n}\n\n// Multi-select specific props\nexport interface ComboboxMultiSelectProps<T = string> extends ComboboxBaseProps<T> {\n /**\n * Multi-select mode\n */\n multiple: true;\n\n /**\n * Selected values\n */\n values?: T[];\n\n /**\n * Callback when selection changes\n */\n onValuesChange?: (values: T[]) => void;\n\n /**\n * Placeholder for search input in dropdown\n */\n searchPlaceholder?: string;\n\n /**\n * If true, the combobox will truncate the selected items to a single line with overflow indicator.\n */\n truncate?: boolean;\n\n /**\n * If true, the combobox will show a special option to select or deselect all items in the current list\n */\n selectAll?: boolean;\n\n /**\n * When `true`, options keep their given order instead of floating\n * currently-selected options to the top. Toggling a value no longer\n * reorders the list under the pointer — important for surfaces like filter\n * value pickers, where the just-clicked row visibly jumping to another\n * position reads as \"the wrong item toggled\". Defaults to `false`\n * (selected-first).\n */\n stableOptionOrder?: boolean;\n\n // Explicitly exclude single-select props to prevent usage\n value?: never;\n onChange?: never;\n virtualize?: boolean;\n}\n\n// Multi-select specific extensions of base components\nconst MultiSelectComboboxInput = styled(ComboboxInput)`\n position: absolute;\n inset: 0;\n height: auto;\n caret-color: transparent; /* Hide cursor in multi-select mode because we use stickers and focus into the search input */\n`;\n\n// Multi-select specific ScrollableMenuList that accounts for search bar\nconst MultiSelectScrollableMenuList = styled(ScrollableMenuList)<{ $embedded?: boolean }>`\n max-height: calc(${MAX_DROPDOWN_HEIGHT} - 60px); /* Subtract approximate search bar height */\n overflow-x: hidden; /* Prevent horizontal scrolling */\n width: 100%; /* Ensure full width is used */\n box-sizing: border-box;\n ${({ $embedded }) =>\n $embedded &&\n css`\n padding: 0;\n `}\n`;\n\nconst SelectedItemsContainer = styled.div<{ $size: InputSizes; $truncate?: boolean }>`\n position: relative; /* Establish positioning context */\n box-sizing: border-box;\n min-height: ${({ $size }) => ($size === 'sm' ? Spacing[5] : Spacing[6])};\n max-height: ${({ $truncate, $size }) =>\n $truncate ? ($size === 'sm' ? Spacing[5] : Spacing[6]) : 'none'};\n padding-left: ${Spacing[2]};\n padding-right: ${({ $size }) =>\n $size === 'sm' ? Spacing[5] : Spacing[6]}; /* Leave space for caret button. */\n padding-top: ${({ $size }) => ($size === 'sm' ? Spacing[1] : Spacing[2])};\n padding-bottom: ${({ $size }) => ($size === 'sm' ? Spacing[1] : Spacing[2])};\n display: flex;\n flex-wrap: ${({ $truncate }) => ($truncate ? 'nowrap' : 'wrap')};\n gap: ${Spacing[1]};\n align-items: flex-start;\n align-content: flex-start;\n pointer-events: none; /* Allow clicks to pass through to underlying input */\n overflow: hidden; /* Required for truncation when truncate mode is enabled */\n\n /* Re-enable pointer events on stickers' dismiss buttons */\n button {\n pointer-events: auto;\n }\n`;\n\nconst TruncatedItemsWrapper = styled.div`\n display: flex;\n flex-wrap: nowrap;\n gap: ${Spacing[1]};\n overflow: hidden;\n flex: 1;\n min-width: 0; /* Allow shrinking below content size */\n pointer-events: none;\n`;\n\nconst TruncatedSticker = styled(Sticker)<{ $isOnlyItem: boolean }>`\n /* Allow first sticker to truncate its text only when it's the only item */\n flex-shrink: ${({ $isOnlyItem }) => ($isOnlyItem ? 1 : 0)};\n min-width: 0;\n max-width: 100%;\n /* If the sticker is an inline element it was causing the parent to gain an extra pixel of height */\n vertical-align: top;\n`;\n\nconst TruncatorSticker = styled(Sticker)`\n /* Truncator should never shrink */\n flex-shrink: 0;\n /* If the sticker is an inline element it was causing the parent to gain an extra pixel of height */\n vertical-align: top;\n`;\n\nconst HiddenMeasurementContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n visibility: hidden;\n display: flex;\n flex-wrap: nowrap;\n gap: ${Spacing[1]};\n pointer-events: none;\n overflow: hidden;\n max-width: 100%;\n`;\n\nconst StyledMenuItem = styled(MenuItem)<{ $size?: InputSizes }>`\n /* These heights should add up to 24 and 32 respectively and the content is 20 already */\n padding: ${({ $size }) => ($size === 'sm' ? `2px ${Spacing[2]}` : `6px ${Spacing[2]}`)};\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: ${Spacing[1]};\n min-width: 0; /* Allow content to shrink below natural size */\n width: 100%; /* Ensure full width of dropdown */\n box-sizing: border-box;\n\n /* Force all children to respect the container width */\n > * {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n }\n`;\n\nconst CheckboxLabel = styled.span<{ id?: string; $size?: InputSizes }>`\n color: ${Color.TextPrimary};\n ${({ $size }) => ($size === 'sm' ? Typography.TextSmall : Typography.TextMedium)};\n display: flex;\n flex-direction: column;\n gap: ${Spacing[1]};\n min-width: 0; /* Allow content to shrink below natural size */\n\n /** Nudge text for visual alignment */\n position: relative;\n bottom: -1px;\n`;\n\nfunction ComboboxMultiSelectComponent<T = string>(\n {\n size = 'md',\n options: rawOptions,\n isOptionsLoading,\n values = [],\n onValuesChange,\n searchPlaceholder = 'Search...',\n onInputChange,\n placeholder = 'Select an option...',\n emptyStateMessage = 'No options found',\n disabled = false,\n hasWarning,\n hasError,\n id,\n labelId,\n 'aria-label': ariaLabel,\n onOpenChange,\n truncate = false,\n selectAll = false,\n stableOptionOrder = false,\n portal = false,\n portalContainerRef: externalPortalContainerRef,\n trigger,\n embedded = false,\n virtualize = false,\n ...props\n }: ComboboxMultiSelectProps<T>,\n ref: React.Ref<HTMLInputElement>,\n) {\n // Normalize `nested: true` groups into inline section-header\n // groups before the rest of the component sees them, so the legacy\n // flatten / render / virtualization code paths work uniformly. The\n // common case (no nested groups anywhere) short-circuits via\n // `containsNestedGroup` and returns the prop value as-is, keeping\n // referential identity stable for downstream memoization.\n const options = useMemo(\n () => (containsNestedGroup(rawOptions) ? inlineNestedGroups(rawOptions) : rawOptions),\n [rawOptions],\n );\n\n const field = useFormField({ hasWarning, hasError, disabled, inputId: id });\n const [inputValue, setInputValue] = useState('');\n const searchInputRef = useRef<HTMLInputElement>(null);\n const comboboxInputRef = useRef<HTMLInputElement>(null);\n const caretButtonRef = useRef<HTMLButtonElement>(null);\n const comboboxContainerRef = useRef<HTMLDivElement>(null);\n const scrollableListRef = useRef<HTMLDivElement>(null);\n const selectedItemsContainerRef = useRef<HTMLDivElement>(null);\n const measurementStickerRefs = useRef<(HTMLElement | null)[]>([]);\n const measurementTruncatorRef = useRef<HTMLElement>(null);\n\n // Use external portalContainerRef if provided, otherwise use internal ref for portal positioning\n const portalContainerRef = externalPortalContainerRef || comboboxContainerRef;\n\n // Flatten options for working with downshift (which only works with flat arrays)\n const flatOptions = useMemo(() => flattenOptions(options), [options]);\n\n // Get selected items from flat options\n const selectedItems = flatOptions.filter((option) => values.includes(option.value));\n\n // Initialize measurement refs array\n useEffect(() => {\n measurementStickerRefs.current = measurementStickerRefs.current.slice(0, selectedItems.length);\n }, [selectedItems.length]);\n\n const visibleCount = useTruncation(\n selectedItems,\n measurementStickerRefs,\n measurementTruncatorRef,\n selectedItemsContainerRef,\n truncate,\n );\n\n // Expose methods to parent component\n useImperativeHandle(\n ref,\n () => ({\n ...comboboxInputRef.current!,\n focusSearchInput: () => {\n if (searchInputRef.current) {\n searchInputRef.current.focus();\n }\n },\n }),\n [],\n );\n\n // Filter options based on input value\n const filteredOptions = useFilteredOptions<T>(options, inputValue);\n\n // When options are not grouped, we float selected items to the top of the menu.\n // When grouped, we float selected items to the top within each group.\n const isGrouped = useMemo(() => options.some(isOptionGroup), [options]);\n\n // When grouped and there are selected values, reorder each group's options so selected come first\n const optionsWithSelectedFirstInGroups = useMemo(() => {\n if (!isGrouped || values.length === 0 || stableOptionOrder) {\n return options;\n }\n return options.map((item) => {\n if (isOptionGroup(item)) {\n // `options` has already been normalized to inline groups at\n // the component boundary (`inlineNestedGroups` above), so\n // flattening the group's contents here surfaces every leaf\n // under it — even ones that came from a nested-marked\n // subtree in the original prop. Sort selected-first within\n // the resulting flat list.\n const groupLeaves = flattenOptions(item.options);\n return {\n ...item,\n options: groupLeaves.toSorted((a, b) => {\n const aSelected = values.includes(a.value);\n const bSelected = values.includes(b.value);\n if (aSelected === bSelected) {\n return 0;\n }\n return aSelected ? -1 : 1;\n }),\n };\n }\n return item;\n });\n }, [options, isGrouped, values, stableOptionOrder]);\n\n // Create navigable items array that includes select all option for keyboard navigation.\n // When flat (not grouped): selected items first. When grouped: selected first within each group.\n const navigableItems = useMemo(() => {\n const items: ComboboxOption<T>[] = [];\n\n if (isGrouped && values.length > 0) {\n // Build flat list in render order: each group's options with selected first, only including filtered\n if (selectAll && filteredOptions.length > 0) {\n items.push({\n value: SELECT_ALL_VALUE as T,\n label: 'Select all',\n } satisfies ComboboxOption<T>);\n }\n for (const item of optionsWithSelectedFirstInGroups) {\n if (isOptionGroup(item)) {\n // `optionsWithSelectedFirstInGroups` flattens each group's\n // contents to leaves above; the inner iteration is safe to\n // treat as `ComboboxOption<T>[]` here.\n for (const opt of flattenOptions(item.options)) {\n if (filteredOptions.some((f) => f.value === opt.value)) {\n items.push(opt);\n }\n }\n } else {\n if (filteredOptions.some((f) => f.value === item.value)) {\n items.push(item);\n }\n }\n }\n return items;\n }\n\n const orderedFiltered =\n !isGrouped && values.length > 0 && !stableOptionOrder\n ? filteredOptions.toSorted((a, b) => {\n const aSelected = values.includes(a.value);\n const bSelected = values.includes(b.value);\n if (aSelected === bSelected) {\n return 0;\n }\n return aSelected ? -1 : 1;\n })\n : filteredOptions;\n\n // Add select all option if enabled and there are filtered options\n if (selectAll && orderedFiltered.length > 0) {\n items.push({\n value: SELECT_ALL_VALUE as T,\n label: 'Select all',\n } satisfies ComboboxOption<T>);\n }\n\n // Add regular filtered options (selected first when ungrouped)\n items.push(...orderedFiltered);\n\n return items;\n }, [\n selectAll,\n filteredOptions,\n isGrouped,\n values,\n optionsWithSelectedFirstInGroups,\n stableOptionOrder,\n ]);\n\n const optionsToRender = useMemo(() => {\n if (!isGrouped && values.length > 0) {\n return navigableItems;\n }\n\n const hasSelectAll =\n selectAll && filteredOptions.length > 0 && navigableItems[0]?.value === SELECT_ALL_VALUE;\n\n const baseOptions = isGrouped && values.length > 0 ? optionsWithSelectedFirstInGroups : options;\n\n return hasSelectAll ? [navigableItems[0], ...baseOptions] : baseOptions;\n }, [\n isGrouped,\n values,\n navigableItems,\n selectAll,\n filteredOptions,\n optionsWithSelectedFirstInGroups,\n options,\n ]);\n\n const navigableToVirtualRowRef = useRef(new Map<number, number>());\n\n const virtualRows = useMemo(() => {\n if (!virtualize) {\n return [];\n }\n const map = new Map<number, number>();\n const rows = buildVirtualRows(optionsToRender, navigableItems, map);\n navigableToVirtualRowRef.current = map;\n return rows;\n }, [optionsToRender, navigableItems, virtualize]);\n\n const virtualizer = useVirtualizer({\n count: virtualRows.length,\n getScrollElement: () => scrollableListRef.current,\n estimateSize: () => (size === 'sm' ? 24 : 32),\n overscan: 5,\n });\n\n const itemToString = useCallback((item: ComboboxOption<T> | null) => {\n return item ? item.label : '';\n }, []);\n\n // Multi-select hooks - pass selectedItems to initialize downshift state\n const {\n addSelectedItem,\n getSelectedItemProps,\n getDropdownProps,\n removeSelectedItem,\n reset,\n setSelectedItems,\n } = useMultipleSelection({\n selectedItems, // Pass selectedItems to initialize/control downshift state\n onStateChange: ({ selectedItems: newSelectedItems, type }) => {\n switch (type) {\n case useMultipleSelection.stateChangeTypes.SelectedItemKeyDownBackspace:\n case useMultipleSelection.stateChangeTypes.SelectedItemKeyDownDelete:\n case useMultipleSelection.stateChangeTypes.DropdownKeyDownBackspace:\n case useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem:\n case useMultipleSelection.stateChangeTypes.FunctionAddSelectedItem:\n case useMultipleSelection.stateChangeTypes.FunctionSetSelectedItems:\n if (onValuesChange && newSelectedItems) {\n const newValues = newSelectedItems.map((item) => item.value);\n onValuesChange?.(newValues);\n }\n break;\n case useMultipleSelection.stateChangeTypes.FunctionReset:\n if (onValuesChange) {\n onValuesChange([]);\n }\n break;\n default:\n break;\n }\n },\n });\n\n // Calculate selected state for filtered items (for select all checkbox state)\n const selectedState = useMemo(() => {\n const counts = filteredOptions.reduce(\n (acc, option) => {\n if (values.includes(option.value)) {\n acc.selected++;\n } else {\n acc.notSelected++;\n }\n return acc;\n },\n { selected: 0, notSelected: 0 },\n );\n return {\n allSelected: counts.selected === filteredOptions.length,\n allNotSelected: counts.notSelected === filteredOptions.length,\n indeterminate: counts.selected > 0 && counts.selected < filteredOptions.length,\n };\n }, [values, filteredOptions]);\n\n const handleSelectAllToggle = useCallback(() => {\n if (selectedState.allSelected || selectedState.indeterminate) {\n // Deselect all visible filtered items - keep only items not in filtered results\n const visibleValues = filteredOptions.map((option) => option.value);\n const remainingItems = selectedItems.filter((item) => !visibleValues.includes(item.value));\n setSelectedItems(remainingItems);\n } else {\n // Select all: combine existing + new filtered items\n const newItems = filteredOptions.filter((option) => !values.includes(option.value));\n setSelectedItems([...selectedItems, ...newItems]);\n }\n }, [\n selectedState.allSelected,\n selectedState.indeterminate,\n filteredOptions,\n selectedItems,\n values,\n setSelectedItems,\n ]);\n\n // Multi-select combobox hooks\n const {\n isOpen,\n getToggleButtonProps,\n getMenuProps,\n getInputProps,\n getItemProps,\n highlightedIndex,\n setHighlightedIndex,\n closeMenu,\n openMenu,\n } = useCombobox({\n items: navigableItems,\n itemToString,\n isOpen: embedded ? true : undefined,\n selectedItem: null,\n initialHighlightedIndex: 0,\n defaultHighlightedIndex: 0,\n onIsOpenChange({ isOpen: newIsOpen }) {\n // Clear search input when dropdown opens, but only if it has content\n // This prevents unnecessary recalculation when inputValue is already empty\n if (newIsOpen && inputValue !== '') {\n setInputValue('');\n }\n },\n onHighlightedIndexChange: ({ highlightedIndex, type }) => {\n if (\n virtualize &&\n type !== useCombobox.stateChangeTypes.MenuMouseLeave &&\n highlightedIndex >= 0\n ) {\n const rowIndex = navigableToVirtualRowRef.current.get(highlightedIndex);\n if (rowIndex != null) {\n virtualizer.scrollToIndex(rowIndex, { align: 'auto' });\n }\n }\n },\n onStateChange({ type, selectedItem: newSelectedItem, inputValue: newInputValue }) {\n switch (type) {\n case useCombobox.stateChangeTypes.InputChange:\n setInputValue(newInputValue || '');\n onInputChange?.(newInputValue || '');\n break;\n case useCombobox.stateChangeTypes.InputKeyDownEnter:\n case useCombobox.stateChangeTypes.ItemClick:\n // Handle select all option\n if (newSelectedItem && newSelectedItem.value === SELECT_ALL_VALUE) {\n handleSelectAllToggle();\n break;\n }\n\n // Handle regular multi-select logic\n if (newSelectedItem) {\n const isSelected = values.includes(newSelectedItem.value);\n if (isSelected) {\n removeSelectedItem(newSelectedItem);\n } else {\n addSelectedItem(newSelectedItem);\n }\n }\n break;\n default:\n break;\n }\n },\n stateReducer(state, actionAndChanges) {\n const { type, changes } = actionAndChanges;\n\n switch (type) {\n case useCombobox.stateChangeTypes.ItemClick:\n case useCombobox.stateChangeTypes.InputKeyDownEnter:\n // Keep menu open after selection and let Downshift manage highlighting\n return {\n ...changes,\n isOpen: true,\n inputValue: '', // Always keep input empty in multi-select mode\n highlightedIndex: state.highlightedIndex, // Not doing this resets the highlighted index to 0\n };\n case useCombobox.stateChangeTypes.InputBlur:\n // Prevent closing when focus moves to search input\n if (isOpen) {\n return {\n ...changes,\n isOpen: true, // Keep open, let search input onBlur handle external focus\n };\n }\n return changes;\n case useCombobox.stateChangeTypes.InputClick:\n case useCombobox.stateChangeTypes.ToggleButtonClick:\n return changes;\n default:\n return changes;\n }\n },\n });\n\n const renderOption = useCallback(\n (option: ComboboxOption<T>, currentIndex: number) => {\n const isHighlighted = highlightedIndex === currentIndex;\n const isSelected = values.includes(option.value);\n\n // Handle select all option\n if (option.value === SELECT_ALL_VALUE) {\n return (\n <StyledMenuItem\n key='select-all'\n {...getItemProps({\n item: option,\n index: currentIndex,\n })}\n focused={isHighlighted}\n selected={false}\n aria-labelledby={`combobox-option-label-${currentIndex}`}\n $size={size}\n tabIndex={-1}\n >\n <Stack direction='horizontal' align='center' spacing={Spacing[2]}>\n <Checkbox\n checked={selectedState.allSelected}\n indeterminate={selectedState.indeterminate}\n tabIndex={-1}\n />\n <CheckboxLabel id={`combobox-option-label-${currentIndex}`} $size={size}>\n <OptionLabel>{option.label}</OptionLabel>\n </CheckboxLabel>\n </Stack>\n </StyledMenuItem>\n );\n }\n\n // Handle regular options\n return (\n <StyledMenuItem\n key={`${option.value}-${currentIndex}`}\n {...getItemProps({\n item: option,\n index: currentIndex,\n 'aria-selected': isSelected,\n })}\n focused={isHighlighted}\n selected={false} // Don't use selected styling for multi-select items\n aria-labelledby={`combobox-option-label-${currentIndex}`}\n $size={size}\n tabIndex={-1}\n >\n <Stack direction='horizontal' align='center' spacing={Spacing[2]}>\n <Checkbox checked={isSelected} tabIndex={-1} />\n <CheckboxLabel id={`combobox-option-label-${currentIndex}`} $size={size}>\n {option.labelStickerVariant ? (\n <Sticker variant={option.labelStickerVariant}>{option.label}</Sticker>\n ) : (\n <>\n <OptionLabel\n title={option.label}\n $labelStyle={option.PLEASE_DO_NOT_USE_labelFontStyle}\n >\n {option.label}\n </OptionLabel>\n {option.description && (\n <Description title={option.description}>{option.description}</Description>\n )}\n </>\n )}\n </CheckboxLabel>\n </Stack>\n </StyledMenuItem>\n );\n },\n [highlightedIndex, values, getItemProps, size, selectedState],\n );\n\n // Downshift owns the open state; embedded mode controls Downshift open via\n // `isOpen: true` above so rendered UI and Downshift state stay synchronized.\n const isMenuOpen = isOpen;\n\n // Handle Enter key to open menu when closed\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && !isMenuOpen) {\n openMenu();\n }\n },\n [isMenuOpen, openMenu],\n );\n\n // Calculate dropdown position for portal rendering\n const dropdownPosition = useDropdownPosition(\n portalContainerRef,\n isMenuOpen,\n embedded ? false : portal,\n );\n\n // Call onOpenChange when dropdown state changes\n useEffect(() => {\n onOpenChange?.(isMenuOpen);\n }, [isMenuOpen, onOpenChange]);\n\n // Reset highlighted index when filtering changes options\n // We might need to remove this because it resets the highlighted index to 0 when the mouse leaves the menu\n useEffect(() => {\n if (isMenuOpen && navigableItems.length > 0) {\n if (highlightedIndex === -1 || highlightedIndex >= navigableItems.length) {\n setHighlightedIndex(0);\n }\n }\n }, [navigableItems, isMenuOpen, highlightedIndex, setHighlightedIndex]);\n\n // Generate unique ID for SearchInput component\n const searchInputId = `${field.inputId}-search`;\n\n // Simple focus management for multi-select search input\n useEffect(() => {\n if (isMenuOpen && searchInputRef.current) {\n // Focus search input when dropdown opens - downshift handles the rest\n searchInputRef.current.focus();\n }\n }, [isMenuOpen]);\n\n const handleSearchInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Handle arrow keys to navigate through options\n if (e.key === 'ArrowDown' && navigableItems.length > 0) {\n e.preventDefault();\n const nextIndex =\n highlightedIndex === -1 ? 0 : (highlightedIndex + 1) % navigableItems.length;\n setHighlightedIndex(nextIndex);\n }\n\n if (e.key === 'ArrowUp' && navigableItems.length > 0) {\n e.preventDefault();\n const prevIndex =\n highlightedIndex === -1\n ? navigableItems.length - 1\n : (highlightedIndex - 1 + navigableItems.length) % navigableItems.length;\n setHighlightedIndex(prevIndex);\n }\n\n if (e.key === 'Enter' && highlightedIndex >= 0 && navigableItems[highlightedIndex]) {\n e.preventDefault();\n const selectedItem = navigableItems[highlightedIndex];\n\n // Handle select all option\n if (selectedItem.value === SELECT_ALL_VALUE) {\n handleSelectAllToggle();\n return;\n }\n\n // Handle regular options\n const isSelected = values.includes(selectedItem.value);\n if (isSelected) {\n removeSelectedItem(selectedItem);\n } else {\n addSelectedItem(selectedItem);\n }\n }\n\n if (e.key === 'Escape') {\n closeMenu();\n // Restore focus to main input\n if (comboboxInputRef.current) {\n comboboxInputRef.current.focus();\n }\n }\n if (e.key === 'Tab' && highlightedIndex >= 0 && navigableItems[highlightedIndex]) {\n closeMenu();\n // Don't prevent default - let Tab continue to next element\n }\n },\n [\n navigableItems,\n highlightedIndex,\n setHighlightedIndex,\n values,\n addSelectedItem,\n removeSelectedItem,\n closeMenu,\n comboboxInputRef,\n handleSelectAllToggle,\n ],\n );\n\n const handleOutsideClick = useCallback(\n (e: MouseEvent) => {\n if (\n !embedded &&\n isMenuOpen &&\n !(e.target as HTMLElement)?.closest('#combobox-dropdown-portal-wrapper')\n ) {\n closeMenu();\n }\n },\n [embedded, isMenuOpen, closeMenu],\n );\n\n useOutsideClick({\n ref: comboboxContainerRef,\n onOutsideClick: handleOutsideClick,\n });\n\n const externalTrigger = (() => {\n if (embedded || trigger == null || !isValidElement(trigger)) {\n return null;\n }\n const triggerProps = trigger.props as Record<string, unknown> & { disabled?: unknown };\n return cloneElement(\n trigger,\n getToggleButtonProps({\n ...triggerProps,\n disabled: field.disabled || Boolean(triggerProps.disabled),\n }) as Record<string, unknown>,\n );\n })();\n\n const handleSearchInputBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n if (!isMenuOpen) {\n return;\n }\n\n const relatedTarget = e.relatedTarget as HTMLElement | null;\n const staysInCombobox =\n relatedTarget != null &&\n (Boolean(comboboxContainerRef.current?.contains(relatedTarget)) ||\n Boolean(relatedTarget.closest('#combobox-dropdown-portal-wrapper')));\n\n if (!embedded && !staysInCombobox) {\n closeMenu();\n }\n },\n [embedded, isMenuOpen, closeMenu],\n );\n\n return (\n <Container {...props} ref={comboboxContainerRef}>\n {embedded ? null : externalTrigger != null ? (\n externalTrigger\n ) : (\n <InputContainer>\n <MultiSelectComboboxInput\n {...getInputProps(\n getDropdownProps({\n ...props,\n ref: comboboxInputRef,\n id: field.inputId,\n placeholder: selectedItems.length === 0 ? placeholder : '',\n disabled: field.disabled,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelId,\n 'aria-describedby':\n [field.helperTextId, field.hasWarning ? field.warningTextId : null]\n .filter(Boolean)\n .join(' ') || undefined,\n 'aria-errormessage': field.hasError ? field.errorTextId : undefined,\n 'aria-invalid': field.hasError,\n preventKeyAction: isMenuOpen,\n onKeyDown: handleKeyDown,\n }),\n )}\n size={size}\n $isOpen={isMenuOpen}\n hasWarning={field.hasWarning}\n hasError={field.hasError}\n value='' // Always empty in multi-select mode\n />\n {/* Hidden measurement container - always renders all items for accurate measurements */}\n {truncate && selectedItems.length > 0 && (\n <HiddenMeasurementContainer aria-hidden='true'>\n {selectedItems.map((item, index) => {\n const selectedOption = flatOptions.find((opt) => opt.value === item.value);\n const stickerVariant = selectedOption?.labelStickerVariant || 'grey';\n return (\n <div\n key={`measurement-${item.value}-${index}`}\n ref={(el: HTMLDivElement | null) =>\n (measurementStickerRefs.current[index] = el)\n }\n >\n <Sticker variant={stickerVariant} disabled={field.disabled}>\n {item.label}\n </Sticker>\n </div>\n );\n })}\n <div ref={measurementTruncatorRef as React.RefObject<HTMLDivElement>}>\n <TruncatorSticker variant='grey' disabled={field.disabled}>\n +{selectedItems.length - visibleCount}\n </TruncatorSticker>\n </div>\n </HiddenMeasurementContainer>\n )}\n {/* Show selected items as stickers */}\n <SelectedItemsContainer $size={size} $truncate={truncate} ref={selectedItemsContainerRef}>\n {truncate ? (\n <TruncatedItemsWrapper>\n {selectedItems.slice(0, visibleCount).map((item, index) => {\n const { ref: _ref, ...stickerProps } = getSelectedItemProps({\n selectedItem: item,\n index,\n });\n const selectedOption = flatOptions.find((opt) => opt.value === item.value);\n const stickerVariant = selectedOption?.labelStickerVariant || 'grey';\n\n return (\n <TruncatedSticker\n key={`selected-${item.value}-${index}`}\n {...stickerProps}\n variant={stickerVariant}\n disabled={field.disabled}\n $isOnlyItem={visibleCount === 1}\n >\n {item.label}\n </TruncatedSticker>\n );\n })}\n {visibleCount < selectedItems.length && (\n <TruncatorSticker variant='grey' disabled={field.disabled}>\n +{selectedItems.length - visibleCount}\n </TruncatorSticker>\n )}\n </TruncatedItemsWrapper>\n ) : (\n selectedItems.map((item, index) => {\n const { ref, ...stickerProps } = getSelectedItemProps({\n selectedItem: item,\n index,\n });\n const selectedOption = flatOptions.find((opt) => opt.value === item.value);\n const stickerVariant = selectedOption?.labelStickerVariant || 'grey';\n return (\n <Sticker\n key={`selected-${item.value}-${index}`}\n {...stickerProps}\n variant={stickerVariant}\n onDismiss={(e) => {\n // Without this, clicking dismiss doesn't work due to event bubbling\n e.stopPropagation();\n removeSelectedItem(item);\n }}\n dismissButtonProps={{\n tabIndex: -1,\n }}\n disabled={field.disabled}\n tabIndex={-1}\n >\n {item.label}\n </Sticker>\n );\n })\n )}\n </SelectedItemsContainer>\n\n {selectedItems.length > 0 ? (\n <CaretButton\n id={`${field.inputId}__clear-all`}\n onClick={reset}\n size={size}\n disabled={field.disabled}\n aria-label='Clear all selected items'\n >\n <CircleXInverseIcon />\n </CaretButton>\n ) : (\n <CaretButton\n {...getToggleButtonProps({\n ref: caretButtonRef,\n })}\n size={size}\n disabled={field.disabled}\n aria-label={`${isMenuOpen ? 'Close' : 'Open'} options menu`}\n aria-haspopup='listbox'\n >\n <CaretDownIcon />\n </CaretButton>\n )}\n </InputContainer>\n )}\n\n <DropdownPortalWrapper portal={embedded ? false : portal}>\n <DropdownContainer\n $isOpen={isMenuOpen}\n $portal={embedded ? false : portal}\n $embedded={embedded}\n $top={dropdownPosition.top}\n $left={dropdownPosition.left}\n $width={dropdownPosition.width}\n $minWidth={externalTrigger ? EXTERNAL_TRIGGER_DROPDOWN_MIN_WIDTH : undefined}\n {...getMenuProps()}\n aria-multiselectable='true'\n >\n {/* Fixed search input */}\n {isMenuOpen && (\n <SearchInputContainer $embedded={embedded}>\n <InputGroup leftIcon={embedded ? undefined : <SearchIcon />} size={size}>\n <SearchInput\n $embedded={embedded}\n id={searchInputId}\n ref={searchInputRef}\n placeholder={searchPlaceholder}\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.target.value);\n onInputChange?.(e.target.value);\n }}\n onKeyDown={handleSearchInputKeyDown}\n onBlur={handleSearchInputBlur}\n disabled={field.disabled}\n aria-label={embedded ? 'Search options' : (ariaLabel ?? searchPlaceholder)}\n size={size}\n />\n </InputGroup>\n </SearchInputContainer>\n )}\n <MultiSelectScrollableMenuList $embedded={embedded} tabIndex={-1} ref={scrollableListRef}>\n {isMenuOpen && (\n <>\n {isOptionsLoading ? (\n <LoadingContainer>\n <Spinner size='md' />\n </LoadingContainer>\n ) : navigableItems.length > 0 ? (\n renderOptionsWithGroups({\n options: optionsToRender,\n filteredOptions: navigableItems,\n renderOption,\n virtualizer: virtualize ? virtualizer : undefined,\n virtualRows: virtualize ? virtualRows : undefined,\n })\n ) : (\n <EmptyState role='status' aria-live='polite' size={size}>\n {emptyStateMessage}\n </EmptyState>\n )}\n </>\n )}\n </MultiSelectScrollableMenuList>\n </DropdownContainer>\n </DropdownPortalWrapper>\n </Container>\n );\n}\n\nexport const ComboboxMultiSelect = forwardRef(ComboboxMultiSelectComponent) as <T = string>(\n props: ComboboxMultiSelectProps<T> & { ref?: React.Ref<HTMLInputElement> },\n) => React.ReactElement;\n\nexport default ComboboxMultiSelect;\n","import { useCombobox } from 'downshift';\nimport Fuse from 'fuse.js';\nimport {\n cloneElement,\n forwardRef,\n Fragment,\n isValidElement,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\nimport { ArrowLeftIcon, CaretDownIcon, ChevronRightIcon, SearchIcon } from '@persona/icons';\nimport {\n CaretButton,\n type ComboboxBaseProps,\n ComboboxInput,\n type ComboboxOption,\n type ComboboxOptionGroup,\n containsNestedGroup,\n Container,\n Description,\n DropdownContainer,\n DropdownPortalWrapper,\n EmptyState,\n flattenLeafOptions,\n flattenOptions,\n getNavigableItemsAtLevel,\n getOptionsAtPath,\n InputContainer,\n isOptionGroup,\n LoadingContainer,\n type NavigableItem,\n OptionLabel,\n renderOptionsWithGroups,\n ScrollableMenuList,\n SearchInput,\n SearchInputContainer,\n useDropdownPosition,\n useFilteredOptions,\n} from 'design-system/components/Combobox/ComboboxBase';\nimport useFormField from 'design-system/components/FormControl/useFormField';\nimport { InputGroup } from 'design-system/components/Input';\nimport {\n IconContainer as MenuItemIconContainer,\n MenuHeading,\n MenuItem,\n} from 'design-system/components/Menu';\nimport Spinner from 'design-system/components/Spinner/Spinner';\nimport Sticker from 'design-system/components/Sticker';\nimport type { InputSizes } from 'design-system/mixins/input';\n\nexport interface ComboboxSingleSelectProps<T = string> extends ComboboxBaseProps<T> {\n /**\n * Single-select mode\n */\n multiple?: false;\n\n /**\n * Selected value\n */\n value?: T | null;\n\n /**\n * Callback when selection changes\n */\n onChange?: (value: T | null) => void;\n\n // Explicitly exclude multi-select props to prevent usage\n values?: never;\n onValuesChange?: never;\n searchPlaceholder?: never;\n truncate?: never;\n selectAll?: never;\n stableOptionOrder?: never;\n}\n\nexport const StyledMenuItem = styled(MenuItem)<{ size?: InputSizes }>`\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: ${Spacing[1]};\n min-width: 0; /* Allow content to shrink below natural size */\n width: 100%; /* Ensure full width of dropdown */\n box-sizing: border-box;\n\n /* Force all children to respect the container width */\n > * {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n }\n`;\n\nconst ParentMenuItem = styled(MenuItem)<{ size?: InputSizes }>`\n ${MenuItemIconContainer} {\n margin-right: 0;\n }\n`;\n\nconst ParentChevron = styled.span`\n display: inline-flex;\n align-items: center;\n color: ${Color.BorderIconSecondary};\n`;\n\n// Minimum dropdown width when an external `trigger` is supplied —\n// keeps the dropdown readable even when the trigger is icon-sized.\nconst EXTERNAL_TRIGGER_DROPDOWN_MIN_WIDTH = '240px';\n\nconst SingleSelectScrollableMenuList = styled(ScrollableMenuList)<{ $embedded?: boolean }>`\n ${({ $embedded }) =>\n $embedded &&\n css`\n padding: 0;\n `}\n`;\n\n// Back-navigation affordance shown at the top of the dropdown whenever\n// the user has descended into a submenu. Click ascends one level; the\n// ← keyboard arrow does the same. The Back row is intentionally NOT\n// part of downshift's `items` list so it doesn't interfere with the\n// option highlight/keyboard nav across the level's real options.\nconst BackRow = styled.button<{ $size?: InputSizes }>`\n display: flex;\n align-items: center;\n gap: ${({ $size }) => ($size === 'sm' ? Spacing[1] : Spacing[2])};\n width: 100%;\n padding: ${({ $size }) => ($size === 'sm' ? `${Spacing[1]} ${Spacing[2]}` : Spacing[2])};\n background: transparent;\n border: 0;\n cursor: pointer;\n color: ${Color.TextPrimary};\n ${({ $size }) => ($size === 'sm' ? Typography.TextSmall : Typography.TextMedium)};\n\n svg {\n color: ${Color.BorderIconPrimary};\n }\n`;\n\nconst StickerDisplay = styled(Sticker)`\n position: absolute;\n left: ${Spacing[2]};\n top: 50%;\n transform: translateY(-50%);\n pointer-events: none;\n z-index: 1;\n`;\n\nconst StickerComboboxInput = styled(ComboboxInput)`\n /* Hide text when sticker is shown */\n color: transparent;\n caret-color: transparent;\n`;\n\nfunction ComboboxSingleSelectComponent<T = string>(\n {\n size = 'md',\n options,\n isOptionsLoading,\n value,\n onChange,\n onInputChange,\n placeholder = 'Select an option...',\n emptyStateMessage = 'No options found',\n disabled = false,\n hasWarning,\n hasError,\n id,\n labelId,\n 'aria-label': ariaLabel,\n onOpenChange,\n portal = false,\n portalContainerRef: externalPortalContainerRef,\n trigger,\n embedded = false,\n ...props\n }: ComboboxSingleSelectProps<T>,\n ref: React.Ref<HTMLInputElement>,\n) {\n const field = useFormField({ hasWarning, hasError, disabled, inputId: id });\n const [inputValue, setInputValue] = useState('');\n // Keep track of dropdown state to avoid filtering options when updating value while dropdown is open\n const [isDropdownOpen, setIsDropdownOpen] = useState(embedded);\n // Path of nested-group labels the user has descended into. Empty\n // when the dropdown is at the root. Reset on close so the next\n // open always lands at the top of the tree.\n const [navigationPath, setNavigationPath] = useState<string[]>([]);\n const comboboxInputRef = useRef<HTMLInputElement>(null);\n const internalContainerRef = useRef<HTMLDivElement>(null);\n // Descent triggered from `stateReducer` is queued here (a reducer\n // can't `setState`); the consumer effect drains it after render.\n const pendingDescentRef = useRef<string | null>(null);\n\n // Use external portalContainerRef if provided, otherwise use internal ref for portal positioning\n const portalContainerRef = externalPortalContainerRef || internalContainerRef;\n\n // Expose methods to parent component\n useImperativeHandle(\n ref,\n () => ({\n ...comboboxInputRef.current!,\n }),\n [],\n );\n\n // Active query — drives the search vs. nested mode switch. A non-empty\n // query flattens the tree and shows all leaves matching the query;\n // an empty query shows the level the navigation path resolves to.\n const trimmedQuery = inputValue.trim();\n const isSearching = trimmedQuery !== '';\n\n // The items visible at the current navigation depth: either the\n // original `options` at the root, or the contents of the nested\n // group `navigationPath` resolves to. Returns `[]` if the path is\n // stale (e.g. the group was removed from `options` mid-drill-down).\n const nestedOptions = useMemo(\n () => getOptionsAtPath(options, navigationPath),\n [options, navigationPath],\n );\n\n // True when at least one nested group exists anywhere in the tree.\n // Nested-navigation behavior (Back row, chevron, search-flattens-tree)\n // only activates for trees that actually use the new feature; legacy\n // flat or grouped option lists keep their original render unchanged.\n const hasNestedGroups = useMemo(() => containsNestedGroup(options), [options]);\n\n // Navigable items at the current nav level: leaves and nested groups\n // interleaved, in document order. Inline section-header groups are\n // walked through transparently (their leaves surface at this level).\n // This is the downshift `items` list in browse mode, and the order\n // matches what `renderNestedLevel` paints below.\n const navigableItems = useMemo(() => getNavigableItemsAtLevel(nestedOptions), [nestedOptions]);\n\n // Search-mode hits: every leaf in the tree (groups are unselectable).\n // Built only when the tree is nested; legacy flat/grouped lists keep\n // their original search render.\n const searchableLeaves = useMemo(() => {\n if (!isSearching || !hasNestedGroups) {\n return [] as ComboboxOption<T>[];\n }\n return flattenLeafOptions(options).map(({ option }) => option);\n }, [options, isSearching, hasNestedGroups]);\n\n // Separate Fuse index for nested-mode search that ALSO matches against\n // each leaf's ancestor labels — so typing a parent's label (e.g.\n // \"Business Account\") returns all of that parent's children. The\n // ancestor list is a search-only field carried alongside the option\n // (not on the option itself), so the leaf's rendered `description`\n // stays exactly what the consumer supplied.\n const searchableLeafFuse = useMemo(() => {\n if (!isSearching || !hasNestedGroups) {\n return null;\n }\n const entries = flattenLeafOptions(options).map(({ option, breadcrumb }) => ({\n option,\n label: String(option.label),\n description: option.description,\n ancestors: breadcrumb.join(' '),\n }));\n return new Fuse(entries, {\n shouldSort: false,\n threshold: 0,\n ignoreLocation: true,\n minMatchCharLength: 1,\n keys: ['label', 'description', 'ancestors'],\n });\n }, [options, isSearching, hasNestedGroups]);\n\n // The source the visible dropdown renders from. Nested-browse uses\n // whatever the navigation path resolves to. Search mode falls back to\n // the original `options` for flat/grouped lists (group headers stay\n // visible) and uses the flat-leaves overlay for nested trees.\n const renderSource = isSearching ? (hasNestedGroups ? searchableLeaves : options) : nestedOptions;\n\n // Filter the render source's LEAVES by the query. Nested+searching\n // uses the ancestor-aware Fuse so parent-label matches still surface\n // children; every other case (browse mode, flat/grouped search) goes\n // through the shared `useFilteredOptions` Fuse.\n const standardFilteredOptions = useFilteredOptions<T>(renderSource, inputValue);\n const filteredOptions = useMemo(() => {\n if (!isSearching || !hasNestedGroups || searchableLeafFuse == null) {\n return standardFilteredOptions;\n }\n if (inputValue === '') {\n return searchableLeaves;\n }\n return Array.from(\n new Set(searchableLeafFuse.search(inputValue).map(({ item }) => item.option)).values(),\n );\n }, [\n isSearching,\n hasNestedGroups,\n searchableLeafFuse,\n inputValue,\n searchableLeaves,\n standardFilteredOptions,\n ]);\n\n // Downshift `items` list. In search mode every item is a leaf\n // (groups never appear in search results). In browse mode the list\n // is `navigableItems` — leaves + nested groups, in render order —\n // so the highlightedIndex tracks both selectable and navigable rows.\n const downshiftItems = useMemo<NavigableItem<T>[]>(() => {\n if (isSearching) {\n return filteredOptions.map((option) => ({ kind: 'leaf', option }) as const);\n }\n // Browse-mode filter: navigable items whose leaf option is still\n // in `filteredOptions` (nested groups always pass through — they\n // aren't filtered by query because we'd flip to search mode).\n return navigableItems.filter(\n (item) => item.kind === 'group' || filteredOptions.some((f) => f.value === item.option.value),\n );\n }, [isSearching, filteredOptions, navigableItems]);\n\n // Lookup table for resolving the selected option's label when the\n // dropdown is closed. Walks the full tree so values stored deep in a\n // submenu still render their label in the input.\n const allLeaves = useMemo(() => flattenLeafOptions(options), [options]);\n const flatOptionsForFallback = useMemo(() => flattenOptions(options), [options]);\n const selectedOption =\n allLeaves.find(({ option }) => option.value === value)?.option ??\n flatOptionsForFallback.find((option) => option.value === value) ??\n null;\n\n // Downshift's `selectedItem` is a NavigableItem in nested mode. The\n // selected leaf is wrapped here so `itemToString` and the input's\n // displayed value resolve to the right label.\n //\n // Memoize on the committed value + label, NOT the `selectedOption` object\n // identity. Consumers that rebuild `options` on `onInputChange` produce a\n // fresh option object on every keystroke; keying off identity would make\n // Downshift treat the controlled `selectedItem` as changed and reset the\n // search input back to the selected label, clobbering an in-progress query.\n // The wrapper only needs to change when the committed selection does, and\n // Downshift only reads its label via `itemToString`.\n const selectedNavigableItem = useMemo<NavigableItem<T> | null>(\n () => (selectedOption ? { kind: 'leaf', option: selectedOption } : null),\n [selectedOption?.value, selectedOption?.label],\n );\n\n const itemToString = useCallback((item: NavigableItem<T> | null) => {\n if (!item) {\n return '';\n }\n return item.kind === 'leaf' ? item.option.label : item.group.label;\n }, []);\n\n const handleAscend = useCallback(() => {\n setNavigationPath((prev) => (prev.length > 0 ? prev.slice(0, -1) : prev));\n setInputValue('');\n }, []);\n\n const handleDescend = useCallback((groupLabel: string) => {\n setNavigationPath((prev) => [...prev, groupLabel]);\n setInputValue('');\n }, []);\n\n // Single-select combobox hooks\n const {\n isOpen,\n getToggleButtonProps,\n getMenuProps,\n getInputProps,\n getItemProps,\n highlightedIndex,\n setHighlightedIndex,\n openMenu,\n } = useCombobox<NavigableItem<T>>({\n items: downshiftItems,\n itemToString,\n isOpen: embedded ? true : undefined,\n selectedItem: isDropdownOpen ? null : selectedNavigableItem,\n inputValue: inputValue,\n onInputValueChange({ inputValue: newInputValue }) {\n if (newInputValue === '' && !embedded && trigger == null) {\n onChange?.(null);\n }\n setInputValue(newInputValue || '');\n onInputChange?.(newInputValue || '');\n },\n onIsOpenChange({ isOpen: newIsOpen }) {\n // Embedded menus are controlled open, so Downshift's attempted close\n // transitions must not put our mirrored open state out of sync.\n if (embedded) {\n return;\n }\n setIsDropdownOpen(newIsOpen); // Keep our state in sync\n if (newIsOpen) {\n // Clear input when opening dropdown\n const shouldClear =\n selectedOption ||\n (value &&\n inputValue === flatOptionsForFallback.find((opt) => opt.value === value)?.label);\n if (shouldClear) {\n setInputValue('');\n }\n } else {\n // Set input to selected option's label when closing dropdown\n setInputValue(selectedOption?.label || '');\n }\n },\n // Group items are intercepted by `stateReducer` below (descent\n // queued; selection preserved). Anything that lands here is a\n // leaf, which we commit.\n onSelectedItemChange: ({ selectedItem: newSelectedItem }) => {\n if (newSelectedItem == null || newSelectedItem.kind !== 'leaf') {\n return;\n }\n const leaf = newSelectedItem.option;\n onChange?.(leaf.value);\n setInputValue(leaf.label);\n },\n stateReducer(state, actionAndChanges) {\n const { changes, type } = actionAndChanges;\n\n switch (type) {\n case useCombobox.stateChangeTypes.InputBlur:\n // Close menu on blur but don't select highlighted item\n return {\n ...changes,\n selectedItem: state.selectedItem, // Keep current selection unchanged\n };\n case useCombobox.stateChangeTypes.ItemClick:\n case useCombobox.stateChangeTypes.InputKeyDownEnter: {\n // Intercept commits on nested-group items — descend into\n // their submenu instead of returning a value. The reducer\n // can't `setState`, so we queue the descent target via a\n // ref and let a consumer effect drain it after render.\n const candidate = changes.selectedItem;\n if (candidate && candidate.kind === 'group') {\n pendingDescentRef.current = candidate.group.label;\n return {\n ...changes,\n selectedItem: state.selectedItem, // preserve null in nested mode\n isOpen: true, // descent never closes the dropdown\n };\n }\n return changes;\n }\n default:\n return changes;\n }\n },\n });\n\n // Drain the pending-descent ref queued by `stateReducer`. Runs after\n // every render so a parent click → reducer queue → effect → state\n // update fires within one paint, before the user sees a stale view.\n useEffect(() => {\n if (pendingDescentRef.current != null) {\n const target = pendingDescentRef.current;\n pendingDescentRef.current = null;\n handleDescend(target);\n }\n });\n\n // Reset navigation path whenever the dropdown closes so the next open\n // always starts at the root. Without this the user re-opens the\n // dropdown deep in a submenu they were previously browsing, which\n // surprises both the keyboard-search and mouse-driven re-entry flows.\n useEffect(() => {\n if (!isOpen && !embedded && navigationPath.length > 0) {\n setNavigationPath([]);\n }\n }, [embedded, isOpen, navigationPath.length]);\n\n const renderLeaf = useCallback(\n (option: ComboboxOption<T>, currentIndex: number) => {\n const isHighlighted = highlightedIndex === currentIndex;\n const isSelected = selectedOption?.value === option.value;\n const itemProps = getItemProps({\n item: { kind: 'leaf', option } as NavigableItem<T>,\n index: currentIndex,\n // Override aria-selected to be true if the option is selected downshift has an open issue related to this https://github.com/downshift-js/downshift/issues/935\n 'aria-selected': isSelected,\n });\n\n const labelContent = option.labelStickerVariant ? (\n <Sticker variant={option.labelStickerVariant}>{option.label}</Sticker>\n ) : (\n <>\n <OptionLabel title={option.label} $labelStyle={option.PLEASE_DO_NOT_USE_labelFontStyle}>\n {option.label}\n </OptionLabel>\n {option.description && (\n <Description title={option.description}>{option.description}</Description>\n )}\n </>\n );\n\n return (\n <StyledMenuItem\n key={`leaf-${String(option.value)}-${currentIndex}`}\n {...itemProps}\n focused={isHighlighted}\n selected={isSelected}\n size={size}\n tabIndex={-1}\n >\n {labelContent}\n </StyledMenuItem>\n );\n },\n [highlightedIndex, selectedOption, getItemProps, size],\n );\n\n // Nested-group rows render with a trailing chevron in the MenuItem's\n // built-in `suffixIcon` slot — the DS layout owns the right-alignment\n // + spacing so we don't have to fight the `flex-direction: column` +\n // `> * { width: 100% }` rules baked into `StyledMenuItem`.\n // `stretchLabel` makes the label take the available row width so the\n // chevron sits flush against the right edge. `aria-haspopup` tells AT\n // that activating this row opens a submenu instead of committing a\n // value; the reducer queues a descent for `kind: 'group'` items to\n // match that contract.\n const renderNestedGroupRow = useCallback(\n (group: ComboboxOptionGroup<T>, currentIndex: number) => {\n const isHighlighted = highlightedIndex === currentIndex;\n const itemProps = getItemProps({\n item: { kind: 'group', group } as NavigableItem<T>,\n index: currentIndex,\n });\n return (\n <ParentMenuItem\n key={`group-${group.label}-${currentIndex}`}\n {...itemProps}\n aria-haspopup='menu'\n focused={isHighlighted}\n size={size}\n tabIndex={-1}\n stretchLabel\n suffixIcon={\n <ParentChevron aria-hidden='true'>\n <ChevronRightIcon />\n </ParentChevron>\n }\n >\n <OptionLabel title={group.label}>{group.label}</OptionLabel>\n </ParentMenuItem>\n );\n },\n [highlightedIndex, getItemProps, size],\n );\n\n // Browse-mode renderer for nested-nav trees. Walks the items at the\n // current navigation level, interleaving leaves (via `renderLeaf`),\n // nested-group nav rows (via `renderNestedGroupRow`), and inline\n // section headers (`MenuHeading`). `navIndex` advances in lockstep\n // with `downshiftItems` so highlightedIndex maps cleanly to what\n // gets painted.\n const renderNestedLevel = useCallback(\n (items: typeof nestedOptions) => {\n let navIndex = -1;\n const walk = (\n node: ComboboxOption<T> | ComboboxOptionGroup<T>,\n key: string,\n ): React.ReactNode => {\n if (isOptionGroup(node)) {\n if (node.nested) {\n // Only render if the node is in the filtered downshift\n // items list (browse mode keeps groups; search mode never\n // reaches this code path).\n if (!downshiftItems.some((i) => i.kind === 'group' && i.group === node)) {\n return null;\n }\n navIndex++;\n return <Fragment key={key}>{renderNestedGroupRow(node, navIndex)}</Fragment>;\n }\n // Inline section header: render header + walk children. Skip\n // entirely if no children would render (keeps the header from\n // floating above nothing).\n const childNodes: React.ReactNode[] = [];\n for (let i = 0; i < node.options.length; i++) {\n const rendered = walk(node.options[i]!, `${key}-${i}`);\n if (rendered != null) {\n childNodes.push(rendered);\n }\n }\n if (childNodes.length === 0) {\n return null;\n }\n return (\n <Fragment key={key}>\n <MenuHeading>{node.label}</MenuHeading>\n {childNodes}\n </Fragment>\n );\n }\n if (!downshiftItems.some((i) => i.kind === 'leaf' && i.option === node)) {\n return null;\n }\n navIndex++;\n return renderLeaf(node, navIndex);\n };\n return items.map((item, idx) => walk(item, `item-${idx}`));\n },\n [downshiftItems, renderLeaf, renderNestedGroupRow],\n );\n\n // Adapter wrapping `renderLeaf` for the legacy `renderOptionsWithGroups`\n // signature — the shared multi/single search-mode renderer expects\n // `(ComboboxOption<T>, flatIndex) => ReactNode`.\n const renderOption = useCallback(\n (option: ComboboxOption<T>, currentIndex: number) => renderLeaf(option, currentIndex),\n [renderLeaf],\n );\n\n // Downshift owns the open state; embedded mode controls Downshift open via\n // `isOpen: true` above so rendered UI and Downshift state stay synchronized.\n const isMenuOpen = isOpen;\n const dropdownPosition = useDropdownPosition(\n portalContainerRef,\n isMenuOpen,\n embedded ? false : portal,\n );\n\n // Keyboard:\n // - Enter on a closed input opens the menu (existing behavior)\n // - Right arrow on a highlighted parent option descends\n // - Left arrow at the start of the input (i.e. not text-navigating\n // within the query) ascends one level, when not at the root\n //\n // Nested-mode-only — search mode bypasses arrow navigation so the\n // arrow keys retain their normal text-caret semantics inside the\n // search query.\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && !isMenuOpen) {\n openMenu();\n return;\n }\n if (!isMenuOpen || isSearching) {\n return;\n }\n if (event.key === 'ArrowRight') {\n const highlighted = downshiftItems[highlightedIndex];\n if (highlighted && highlighted.kind === 'group') {\n event.preventDefault();\n handleDescend(highlighted.group.label);\n }\n return;\n }\n if (event.key === 'ArrowLeft' && navigationPath.length > 0) {\n const input = event.currentTarget;\n const caretAtStart = (input.selectionStart ?? 0) === 0 && (input.selectionEnd ?? 0) === 0;\n if (caretAtStart) {\n event.preventDefault();\n handleAscend();\n }\n }\n },\n [\n isMenuOpen,\n isSearching,\n downshiftItems,\n highlightedIndex,\n navigationPath.length,\n openMenu,\n handleDescend,\n handleAscend,\n ],\n );\n\n // Call onOpenChange when dropdown state changes\n useEffect(() => {\n onOpenChange?.(isMenuOpen);\n }, [isMenuOpen, onOpenChange]);\n\n // Keep inputValue in sync with selected option when dropdown is closed\n useEffect(() => {\n if (!isMenuOpen) {\n setInputValue(selectedOption?.label || '');\n }\n }, [selectedOption, isMenuOpen]);\n\n // Reset highlighted index when filtering changes options\n useEffect(() => {\n if (isMenuOpen && downshiftItems.length > 0) {\n if (highlightedIndex === -1 || highlightedIndex >= downshiftItems.length) {\n setHighlightedIndex(0);\n }\n }\n }, [downshiftItems, isMenuOpen, highlightedIndex, setHighlightedIndex]);\n\n const displayValue = isMenuOpen ? inputValue : selectedOption?.label || '';\n const hasSticker = !isMenuOpen && selectedOption?.labelStickerVariant;\n const InputComponent = hasSticker ? StickerComboboxInput : ComboboxInput;\n\n // Show the Back row only in nested mode at a non-root level. In\n // search mode the tree is flattened and breadcrumbs surface as\n // option `description`s, so a Back row would just be noise.\n const showBackRow = isMenuOpen && navigationPath.length > 0 && !isSearching;\n\n // External trigger mode: clone the consumer-supplied trigger with\n // downshift's toggle props so click / aria-expanded / aria-controls\n // wire up. The trigger's own props are passed through\n // `getToggleButtonProps` so downshift composes (rather than clobbers)\n // existing handlers like `onClick`. Falls back to the default\n // input + caret if a non-element was passed.\n const externalTrigger = (() => {\n if (embedded || trigger == null || !isValidElement(trigger)) {\n return null;\n }\n const triggerProps = trigger.props as Record<string, unknown> & { disabled?: unknown };\n return cloneElement(\n trigger,\n getToggleButtonProps({\n ...triggerProps,\n disabled: field.disabled || Boolean(triggerProps.disabled),\n }) as Record<string, unknown>,\n );\n })();\n\n // Pre-computed downshift-wrapped props for the in-dropdown search\n // input rendered in external-trigger mode (only used when\n // `externalTrigger` is non-null; cheap to compute either way).\n const searchInputProps = getInputProps({\n ref: comboboxInputRef,\n id: field.inputId,\n placeholder: 'Search…',\n disabled: field.disabled,\n 'aria-label': embedded ? 'Search options' : (ariaLabel ?? 'Search options'),\n 'aria-labelledby': embedded ? undefined : labelId,\n 'aria-describedby':\n [field.helperTextId, field.hasWarning ? field.warningTextId : null]\n .filter(Boolean)\n .join(' ') || undefined,\n 'aria-errormessage': field.hasError ? field.errorTextId : undefined,\n 'aria-invalid': field.hasError,\n onKeyDown: handleKeyDown,\n });\n\n return (\n <Container {...props} ref={internalContainerRef}>\n {embedded ? null : externalTrigger != null ? (\n externalTrigger\n ) : (\n <InputContainer>\n {hasSticker && (\n <StickerDisplay variant={selectedOption.labelStickerVariant}>\n {selectedOption.label}\n </StickerDisplay>\n )}\n <InputComponent\n {...getInputProps({\n ...props,\n ref: comboboxInputRef,\n id: field.inputId,\n placeholder,\n disabled: field.disabled,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelId,\n 'aria-describedby':\n [field.helperTextId, field.hasWarning ? field.warningTextId : null]\n .filter(Boolean)\n .join(' ') || undefined,\n 'aria-errormessage': field.hasError ? field.errorTextId : undefined,\n 'aria-invalid': field.hasError,\n onKeyDown: handleKeyDown,\n })}\n size={size}\n $isOpen={isMenuOpen}\n hasWarning={field.hasWarning}\n hasError={field.hasError}\n value={displayValue}\n $selectedItemStyle={selectedOption?.PLEASE_DO_NOT_USE_labelFontStyle}\n />\n\n <CaretButton\n {...getToggleButtonProps()}\n size={size}\n disabled={field.disabled}\n aria-label={`${isMenuOpen ? 'Close' : 'Open'} options menu`}\n aria-haspopup='listbox'\n >\n <CaretDownIcon />\n </CaretButton>\n </InputContainer>\n )}\n\n <DropdownPortalWrapper portal={embedded ? false : portal}>\n <DropdownContainer\n $isOpen={isMenuOpen}\n $portal={embedded ? false : portal}\n $embedded={embedded}\n $top={dropdownPosition.top}\n $left={dropdownPosition.left}\n $width={dropdownPosition.width}\n $minWidth={externalTrigger ? EXTERNAL_TRIGGER_DROPDOWN_MIN_WIDTH : undefined}\n {...getMenuProps()}\n >\n {(externalTrigger || embedded) && (\n // Search input moves into the dropdown when an external\n // trigger owns the closed state. Mounted unconditionally\n // so downshift's input ref stays stable across open/close\n // (the surrounding `DropdownContainer` handles visibility).\n <SearchInputContainer $embedded={embedded}>\n <InputGroup leftIcon={embedded ? undefined : <SearchIcon />} size={size}>\n <SearchInput\n $embedded={embedded}\n {...searchInputProps}\n size={size}\n hasWarning={field.hasWarning}\n hasError={field.hasError}\n value={inputValue}\n autoComplete='off'\n />\n </InputGroup>\n </SearchInputContainer>\n )}\n <SingleSelectScrollableMenuList $embedded={embedded} tabIndex={-1}>\n {isMenuOpen && (\n <>\n {showBackRow && (\n <BackRow\n type='button'\n // Removed from the Tab order: a Tab landing here\n // would blur the input and downshift would close\n // the menu before any handler could ascend. The\n // documented keyboard path is ArrowLeft from the\n // input (caret at position 0). The button stays\n // discoverable to assistive tech (screen-reader\n // cursors can still focus + activate it).\n tabIndex={-1}\n onMouseDown={(event) => {\n // Beat downshift's blur-on-mousedown by handling\n // the ascend here and preventing the input from\n // losing focus (which would close the dropdown).\n event.preventDefault();\n handleAscend();\n }}\n onClick={(event) => {\n // Assistive-tech activation (e.g. VoiceOver\n // VO+Space) dispatches `click` with `detail === 0`\n // without firing `mousedown` — handle it here so\n // a screen-reader user who activates the Back\n // affordance actually ascends. Mouse clicks\n // (`detail >= 1`) were already handled by\n // `onMouseDown`; skip them to avoid double-ascending.\n if (event.detail === 0) {\n handleAscend();\n }\n }}\n aria-label='Back to previous menu'\n $size={size}\n >\n <ArrowLeftIcon aria-hidden='true' size={size === 'sm' ? 12 : 16} />\n <span>Back</span>\n </BackRow>\n )}\n {isOptionsLoading ? (\n <LoadingContainer>\n <Spinner size='md' />\n </LoadingContainer>\n ) : downshiftItems.length > 0 ? (\n hasNestedGroups && !isSearching ? (\n // Browse-mode for nested-nav trees: render leaves +\n // nested-group nav rows + inline section headers in\n // document order; downshift's highlightedIndex maps\n // to this list via `downshiftItems`.\n renderNestedLevel(nestedOptions)\n ) : (\n // Legacy / flat / grouped search: the shared\n // renderer handles section headers and leaves.\n // `renderSource` is the flat-leaves overlay in\n // search mode and the original `options` (legacy\n // tree) otherwise.\n renderOptionsWithGroups({\n options: renderSource,\n filteredOptions,\n renderOption,\n })\n )\n ) : (\n <EmptyState role='status' aria-live='polite' size={size}>\n {emptyStateMessage}\n </EmptyState>\n )}\n </>\n )}\n </SingleSelectScrollableMenuList>\n </DropdownContainer>\n </DropdownPortalWrapper>\n </Container>\n );\n}\n\nexport const ComboboxSingleSelect = forwardRef(ComboboxSingleSelectComponent) as <T = string>(\n props: ComboboxSingleSelectProps<T> & { ref?: React.Ref<HTMLInputElement> },\n) => React.ReactElement;\n\nexport default ComboboxSingleSelect;\n","import { forwardRef } from 'react';\n\nimport { CaretButton } from './ComboboxBase';\nimport ComboboxMultiSelect, { type ComboboxMultiSelectProps } from './ComboboxMultiSelect';\nimport ComboboxSingleSelect, { type ComboboxSingleSelectProps } from './ComboboxSingleSelect';\n\n// Discriminated union type\nexport type ComboboxProps<T = string> = ComboboxSingleSelectProps<T> | ComboboxMultiSelectProps<T>;\n\nfunction ComboboxComponent<T = string>(props: ComboboxProps<T>, ref: React.Ref<HTMLInputElement>) {\n // Use discriminated union to determine which component to render\n if (props.multiple) {\n return <ComboboxMultiSelect<T> ref={ref} {...props} />;\n } else {\n return <ComboboxSingleSelect<T> ref={ref} {...props} />;\n }\n}\n\nexport const Combobox = forwardRef(ComboboxComponent) as <T = string>(\n props: ComboboxProps<T> & { ref?: React.Ref<HTMLInputElement> },\n) => React.ReactElement;\n\nexport { CaretButton };\n\nexport default Combobox;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCopyableField-DBkYvwii.mjs","names":["Card","Popover"],"sources":["../components/HoverCopyableField/HoverCopyableField.tsx","../components/HoverCopyableField/index.ts"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona-id/design-tokens';\nimport { CopyIcon } from '@persona-id/icons';\nimport Button from 'design-system/components/Button';\nimport Card from 'design-system/components/Card';\nimport Popover from 'design-system/components/Popover';\nimport { Paragraph } from 'design-system/components/Text';\nimport useToggle from 'design-system/lib/useToggle';\nimport { fadeIn } from 'design-system/variables/keyframes';\nimport { TransitionDuration } from 'design-system/variables/transitions';\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if ('clipboard' in navigator) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n return document.execCommand('copy', true, text);\n }\n } catch {\n return false;\n }\n};\n\nconst CopyableFieldContainer = styled.div`\n display: flex;\n gap: ${Spacing[1]};\n align-items: center;\n`;\n\nconst CopyButton = styled(Button).attrs(() => ({\n type: 'button',\n variant: 'inverse',\n width: 'icon',\n}))<{ isActive: boolean }>`\n height: ${Spacing[5]};\n width: ${Spacing[5]};\n visibility: ${({ isActive }) => (isActive ? 'visible' : 'hidden')};\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nconst StyledCard = styled(Card)`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n padding: 6px;\n margin: 0;\n`;\n\ninterface HoverCopyableFieldProps {\n copyValue: string | undefined;\n confirmationText?: string;\n children: ReactNode;\n}\n\nconst HoverCopyableField = ({\n copyValue,\n confirmationText = 'Copied',\n children,\n}: HoverCopyableFieldProps) => {\n const [copyButtonActive, { enable: showCopyButton, disable: hideCopyButton }] = useToggle(false);\n const [confirmationActive, { enable: showConfirmation, disable: hideConfirmation }] =\n useToggle(false);\n\n const copyTextToClipboard = async () => {\n if (copyValue == null) {\n return;\n }\n const copyWasSuccessful = await copyToClipboard(copyValue);\n\n if (copyWasSuccessful) {\n showConfirmation();\n setTimeout(() => {\n hideCopyButton();\n hideConfirmation();\n }, 1200);\n }\n };\n\n const copyField = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n copyTextToClipboard();\n };\n\n return copyValue != null && copyValue.trim().length > 0 ? (\n <CopyableFieldContainer onMouseEnter={showCopyButton} onMouseLeave={hideCopyButton}>\n {children}\n <Popover open={confirmationActive}>\n <Popover.Anchor asChild>\n <CopyButton\n id='hover-copyable-field__copy-button'\n isActive={copyButtonActive || confirmationActive}\n onClick={copyField}\n >\n <CopyIcon width={16} height={16} />\n </CopyButton>\n </Popover.Anchor>\n <Popover.Content side='top' align='center' style={{ zIndex: 2 }}>\n <StyledCard elevated>\n <Paragraph>{confirmationText}</Paragraph>\n </StyledCard>\n </Popover.Content>\n </Popover>\n </CopyableFieldContainer>\n ) : null;\n};\n\nexport default HoverCopyableField;\n","import HoverCopyableField from './HoverCopyableField';\n\nexport default HoverCopyableField;\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,kBAAkB,OAAO,SAAmC;AAChE,KAAI;AACF,MAAI,eAAe,WAAW;AAC5B,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAO;QAEP,QAAO,SAAS,YAAY,QAAQ,MAAM,KAAK;SAE3C;AACN,SAAO;;;AAIX,MAAM,yBAAyB,OAAO,GAAG;;SAEhC,QAAQ,GAAG;;;AAIpB,MAAM,aAAa,OAAO,OAAO,CAAC,aAAa;CAC7C,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAAE;YACS,QAAQ,GAAG;WACZ,QAAQ,GAAG;iBACL,EAAE,eAAgB,WAAW,YAAY,SAAU;eACrD,OAAO,GAAA,QAA6B;;;;;;AAOnD,MAAM,aAAa,OAAOA,aAAK;;;;;eAKhB,OAAO,GAAA,QAA6B;;;;AAWnD,MAAM,sBAAsB,EAC1B,WACA,mBAAmB,UACnB,eAC6B;CAC7B,MAAM,CAAC,kBAAkB,EAAE,QAAQ,gBAAgB,SAAS,oBAAoB,UAAU,MAAM;CAChG,MAAM,CAAC,oBAAoB,EAAE,QAAQ,kBAAkB,SAAS,sBAC9D,UAAU,MAAM;CAElB,MAAM,sBAAsB,YAAY;AACtC,MAAI,aAAa,KACf;AAIF,MAAI,MAF4B,gBAAgB,UAAU,EAEnC;AACrB,qBAAkB;AAClB,oBAAiB;AACf,oBAAgB;AAChB,sBAAkB;MACjB,KAAK;;;CAIZ,MAAM,aAAa,MAAqC;AACtD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACnB,uBAAqB;;AAGvB,QAAO,aAAa,QAAQ,UAAU,MAAM,CAAC,SAAS,IACpD,qBAAC,wBAAD;EAAwB,cAAc;EAAgB,cAAc;YAApE,CACG,UACD,qBAACC,iBAAD;GAAS,MAAM;aAAf,CACE,oBAACA,gBAAQ,QAAT;IAAgB,SAAA;cACd,oBAAC,YAAD;KACE,IAAG;KACH,UAAU,oBAAoB;KAC9B,SAAS;eAET,oBAAC,UAAD;MAAU,OAAO;MAAI,QAAQ;MAAM,CAAA;KACxB,CAAA;IACE,CAAA,EACjB,oBAACA,gBAAQ,SAAT;IAAiB,MAAK;IAAM,OAAM;IAAS,OAAO,EAAE,QAAQ,GAAG;cAC7D,oBAAC,YAAD;KAAY,UAAA;eACV,oBAAC,WAAD,EAAA,UAAY,kBAA6B,CAAA;KAC9B,CAAA;IACG,CAAA,CACV;KACa;MACvB;;;;AC/GN,IAAA,6BAAe"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCopyableField-DyW2iZuo.cjs","names":["Spacing","Button","fadeIn","Card","useToggle","Popover","CopyIcon","Paragraph"],"sources":["../components/HoverCopyableField/HoverCopyableField.tsx","../components/HoverCopyableField/index.ts"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona-id/design-tokens';\nimport { CopyIcon } from '@persona-id/icons';\nimport Button from 'design-system/components/Button';\nimport Card from 'design-system/components/Card';\nimport Popover from 'design-system/components/Popover';\nimport { Paragraph } from 'design-system/components/Text';\nimport useToggle from 'design-system/lib/useToggle';\nimport { fadeIn } from 'design-system/variables/keyframes';\nimport { TransitionDuration } from 'design-system/variables/transitions';\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if ('clipboard' in navigator) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n return document.execCommand('copy', true, text);\n }\n } catch {\n return false;\n }\n};\n\nconst CopyableFieldContainer = styled.div`\n display: flex;\n gap: ${Spacing[1]};\n align-items: center;\n`;\n\nconst CopyButton = styled(Button).attrs(() => ({\n type: 'button',\n variant: 'inverse',\n width: 'icon',\n}))<{ isActive: boolean }>`\n height: ${Spacing[5]};\n width: ${Spacing[5]};\n visibility: ${({ isActive }) => (isActive ? 'visible' : 'hidden')};\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nconst StyledCard = styled(Card)`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n padding: 6px;\n margin: 0;\n`;\n\ninterface HoverCopyableFieldProps {\n copyValue: string | undefined;\n confirmationText?: string;\n children: ReactNode;\n}\n\nconst HoverCopyableField = ({\n copyValue,\n confirmationText = 'Copied',\n children,\n}: HoverCopyableFieldProps) => {\n const [copyButtonActive, { enable: showCopyButton, disable: hideCopyButton }] = useToggle(false);\n const [confirmationActive, { enable: showConfirmation, disable: hideConfirmation }] =\n useToggle(false);\n\n const copyTextToClipboard = async () => {\n if (copyValue == null) {\n return;\n }\n const copyWasSuccessful = await copyToClipboard(copyValue);\n\n if (copyWasSuccessful) {\n showConfirmation();\n setTimeout(() => {\n hideCopyButton();\n hideConfirmation();\n }, 1200);\n }\n };\n\n const copyField = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n copyTextToClipboard();\n };\n\n return copyValue != null && copyValue.trim().length > 0 ? (\n <CopyableFieldContainer onMouseEnter={showCopyButton} onMouseLeave={hideCopyButton}>\n {children}\n <Popover open={confirmationActive}>\n <Popover.Anchor asChild>\n <CopyButton\n id='hover-copyable-field__copy-button'\n isActive={copyButtonActive || confirmationActive}\n onClick={copyField}\n >\n <CopyIcon width={16} height={16} />\n </CopyButton>\n </Popover.Anchor>\n <Popover.Content side='top' align='center' style={{ zIndex: 2 }}>\n <StyledCard elevated>\n <Paragraph>{confirmationText}</Paragraph>\n </StyledCard>\n </Popover.Content>\n </Popover>\n </CopyableFieldContainer>\n ) : null;\n};\n\nexport default HoverCopyableField;\n","import HoverCopyableField from './HoverCopyableField';\n\nexport default HoverCopyableField;\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAM,kBAAkB,OAAO,SAAmC;AAChE,KAAI;AACF,MAAI,eAAe,WAAW;AAC5B,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAO;QAEP,QAAO,SAAS,YAAY,QAAQ,MAAM,KAAK;SAE3C;AACN,SAAO;;;AAIX,MAAM,yBAAyB,kBAAA,QAAO,GAAG;;SAEhCA,0BAAAA,QAAQ,GAAG;;;AAIpB,MAAM,aAAa,CAAA,GAAA,kBAAA,SAAOC,mBAAAA,OAAO,CAAC,aAAa;CAC7C,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAAE;YACSD,0BAAAA,QAAQ,GAAG;WACZA,0BAAAA,QAAQ,GAAG;iBACL,EAAE,eAAgB,WAAW,YAAY,SAAU;eACrDE,4BAAAA,OAAO,GAAA,QAA6B;;;;;;AAOnD,MAAM,aAAa,CAAA,GAAA,kBAAA,SAAOC,aAAAA,aAAK;;;;;eAKhBD,4BAAAA,OAAO,GAAA,QAA6B;;;;AAWnD,MAAM,sBAAsB,EAC1B,WACA,mBAAmB,UACnB,eAC6B;CAC7B,MAAM,CAAC,kBAAkB,EAAE,QAAQ,gBAAgB,SAAS,oBAAoBE,kBAAAA,UAAU,MAAM;CAChG,MAAM,CAAC,oBAAoB,EAAE,QAAQ,kBAAkB,SAAS,sBAC9DA,kBAAAA,UAAU,MAAM;CAElB,MAAM,sBAAsB,YAAY;AACtC,MAAI,aAAa,KACf;AAIF,MAAI,MAF4B,gBAAgB,UAAU,EAEnC;AACrB,qBAAkB;AAClB,oBAAiB;AACf,oBAAgB;AAChB,sBAAkB;MACjB,KAAK;;;CAIZ,MAAM,aAAa,MAAqC;AACtD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACnB,uBAAqB;;AAGvB,QAAO,aAAa,QAAQ,UAAU,MAAM,CAAC,SAAS,IACpD,iBAAA,GAAA,kBAAA,MAAC,wBAAD;EAAwB,cAAc;EAAgB,cAAc;YAApE,CACG,UACD,iBAAA,GAAA,kBAAA,MAACC,gBAAAA,iBAAD;GAAS,MAAM;aAAf,CACE,iBAAA,GAAA,kBAAA,KAACA,gBAAAA,gBAAQ,QAAT;IAAgB,SAAA;cACd,iBAAA,GAAA,kBAAA,KAAC,YAAD;KACE,IAAG;KACH,UAAU,oBAAoB;KAC9B,SAAS;eAET,iBAAA,GAAA,kBAAA,KAACC,kBAAAA,UAAD;MAAU,OAAO;MAAI,QAAQ;MAAM,CAAA;KACxB,CAAA;IACE,CAAA,EACjB,iBAAA,GAAA,kBAAA,KAACD,gBAAAA,gBAAQ,SAAT;IAAiB,MAAK;IAAM,OAAM;IAAS,OAAO,EAAE,QAAQ,GAAG;cAC7D,iBAAA,GAAA,kBAAA,KAAC,YAAD;KAAY,UAAA;eACV,iBAAA,GAAA,kBAAA,KAACE,aAAAA,WAAD,EAAA,UAAY,kBAA6B,CAAA;KAC9B,CAAA;IACG,CAAA,CACV;KACa;MACvB;;;;AC/GN,IAAA,6BAAe"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ListBox-B4uoo_PT.cjs","names":["GridList","paragraphMixins","Color","BorderRadius","Spacing","DropIndicator","findIndexByKey","moveItemByIndex","Stack","Button","ListItem","isNotDisabled","isHovered","isFocused","HeadlessAriaButton","Typography","FormControlContainer","GridListItem","DragIcon","DropdownMenu","IconButton","MoreIcon","MenuItem","XIcon","Popover","Z_INDICES","FormGroupContext","MenuHeading","Header","Section"],"sources":["../components/ListBox/ListBox.tsx"],"sourcesContent":["import uniqueId from 'lodash/fp/uniqueId';\nimport {\n type ComponentPropsWithoutRef,\n createContext,\n type PropsWithChildren,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n DropIndicator,\n type DroppableCollectionReorderEvent,\n GridList,\n GridListItem,\n Header,\n ListBoxSection as Section,\n useDragAndDrop,\n} from 'react-aria-components';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius, Color, Spacing, Typography } from '@persona/design-tokens';\nimport { DragIcon } from '@persona/icons';\nimport { MoreIcon, XIcon } from '@persona/icons/12px';\nimport Button, { type ButtonProps, IconButton } from 'design-system/components/Button';\nimport { FormGroupContext } from 'design-system/components/ConfigFormGroup/useFormGroup';\nimport DropdownMenu from 'design-system/components/DropdownMenu';\nimport { Container as FormControlContainer } from 'design-system/components/FormControl';\nimport { ListItem, MenuHeading, MenuItem, type MenuItemProps } from 'design-system/components/Menu';\nimport Popover from 'design-system/components/Popover/Popover';\nimport Stack from 'design-system/components/Stack';\nimport { HeadlessAriaButton } from 'design-system/lib/HeadlessAriaButton';\nimport { isFocused, isHovered, isNotDisabled } from 'design-system/lib/pseudoClass';\nimport { findIndexByKey, moveItemByIndex } from 'design-system/lib/reorderItems';\nimport { Z_INDICES } from 'design-system/lib/zindex';\nimport { paragraphMixins } from 'design-system/mixins/text';\n\n// Context for sharing ListBox configuration with child items\ninterface ListBoxContextValue {\n size: 'sm' | 'md';\n listBoxId: string;\n setItemHasActionsOrDelete: (value: boolean) => void;\n}\n\nconst ListBoxContext = createContext<ListBoxContextValue | null>(null);\n\n/**\n * Hook to access ListBox context values (like size) from child components\n */\nexport const useListBoxContext = () => {\n return useContext(ListBoxContext);\n};\n\nexport interface ListBoxProps<T extends object> extends Omit<\n ComponentPropsWithoutRef<typeof GridList<T>>,\n 'slot' | 'autoFocus' | 'orientation' | 'shouldFocusWrap' | 'dragAndDropHooks' | 'layout'\n> {\n /**\n * Called when \"Add\" button is clicked. Only renders \"Add\" button if this prop is present.\n */\n onAdd?: ButtonProps['onClick'];\n\n /**\n * Called when \"Delete\" button is clicked. Only renders \"Delete\" button if this prop is present.\n */\n onDelete?: (selectedKeys: ListBoxProps<T>['selectedKeys']) => void;\n\n /**\n * Whether or not delete button should be disabled.\n */\n deleteDisabled?: boolean;\n\n /**\n * Whether or not the Add/Delete buttons should be shown.\n */\n editable?: boolean;\n\n /**\n * Text to display if no options are available.\n */\n emptyText?: string;\n\n /**\n * Whether or not to expand the box to the full width of the container.\n */\n fullWidth?: boolean;\n\n /**\n * When provided, enables drag and drop functionality.\n */\n reorderConfig?: {\n /**\n * Called when items are reordered via drag and drop. Receives the reordered\n * array of items when an item is dropped.\n */\n onReorder: (reorderedItems: T[]) => void;\n /**\n * The name of the property on the item that was passed as the key to\n * `ListBox.Item`. For exanple, if the item is`{ id: '1', name: 'First Item' }`,\n * and you passed ListBox.Item `key={item.id}`, then the `itemKeyPath`\n * should be `'id'`.\n */\n itemKeyPath: string;\n };\n\n /**\n * Size of the list box.\n */\n size?: 'sm' | 'md';\n}\n\nconst StyledListBox = styled(GridList)<{ fullWidth?: boolean; $size?: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n\n box-sizing: border-box;\n background: ${Color.BackgroundPrimary};\n border-radius: ${BorderRadius.Md};\n border: 1px solid ${Color.BorderDivider};\n padding: ${Spacing[1]};\n\n ${({ fullWidth }) =>\n !fullWidth &&\n css`\n width: 204px;\n `}\n`;\n\nconst StyledDropIndicator = styled(DropIndicator)`\n height: 2px;\n background: ${({ theme }) => theme.color.text.brand};\n`;\n\nconst ListBoxEmptyState = styled.button<{ $size?: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n\n background-color: transparent;\n outline: none;\n border: none;\n padding: ${Spacing[1]};\n color: ${Color.TextSecondary};\n`;\n\nconst ListBoxEmptyStateButton = styled(ListBoxEmptyState)`\n &:hover {\n cursor: pointer;\n }\n`;\n\nexport const ListBox = <T extends object>({\n children,\n onAdd,\n onDelete,\n emptyText,\n deleteDisabled,\n selectedKeys,\n onSelectionChange,\n editable = true,\n size = 'md',\n reorderConfig,\n items,\n ...props\n}: PropsWithChildren<ListBoxProps<T>>) => {\n const listBoxRef = useRef<HTMLDivElement>(null);\n const listBoxId = useMemo(() => uniqueId('listbox-'), []);\n const rowDropdownId = `${listBoxId}-row-dropdown`;\n const [itemHasActionsOrDelete, setItemHasActionsOrDelete] = useState(false);\n\n const { dragAndDropHooks } = useDragAndDrop({\n getItems: (keys) =>\n Array.from(keys).map((key) => ({\n 'text/plain': String(key),\n })),\n getAllowedDropOperations: () => ['move'],\n onReorder: (e: DroppableCollectionReorderEvent) => {\n if (!reorderConfig || !items) {\n return;\n }\n const { onReorder, itemKeyPath } = reorderConfig;\n if (!onReorder || !itemKeyPath) {\n return;\n }\n\n const draggedKey = Array.from(e.keys)[0];\n if (draggedKey == null) {\n return;\n }\n\n const itemsArr = Array.from(items);\n const fromIndex = findIndexByKey(itemsArr, itemKeyPath, String(draggedKey));\n const targetIndex = findIndexByKey(itemsArr, itemKeyPath, String(e.target.key));\n if (fromIndex === -1 || targetIndex === -1) {\n return;\n }\n\n // After removing the dragged item, a target that sat after it shifts down by one.\n const targetIndexAfterRemoval = fromIndex < targetIndex ? targetIndex - 1 : targetIndex;\n const toIndex =\n e.target.dropPosition === 'before' ? targetIndexAfterRemoval : targetIndexAfterRemoval + 1;\n\n onReorder(moveItemByIndex(itemsArr, fromIndex, toIndex));\n },\n renderDropIndicator: (target) => <StyledDropIndicator target={target} />,\n });\n\n // If row dropdowns are open, deselect items (which also closes the dropdown) when clicking outside the ListBox\n const handleOutsideClick = useCallback(\n (event: MouseEvent) => {\n const rowDropdownIsOpen = document.querySelector(\n `[id=\"${rowDropdownId}\"][data-state=\"open\"]`,\n );\n if (!rowDropdownIsOpen) {\n return;\n }\n\n const target = event.target as HTMLElement;\n const isOutsideListBox = listBoxRef.current && !listBoxRef.current.contains(target);\n const isOnRowDropdownContent = target.closest(`[id=\"${rowDropdownId}\"]`);\n\n // Only deselect if:\n // 1. Click is outside the ListBox\n // 2. Click is not on popover content\n // 3. There are selected items\n // 4. onSelectionChange is available (to allow deselection)\n if (\n isOutsideListBox &&\n !isOnRowDropdownContent &&\n selectedKeys != null &&\n selectedKeys !== 'all' &&\n Array.from(selectedKeys).length > 0 &&\n onSelectionChange\n ) {\n // Deselect all items when clicking outside (but not on popover content)\n onSelectionChange(new Set());\n }\n },\n [selectedKeys, onSelectionChange, rowDropdownId],\n );\n\n // Set up outside click listener\n useEffect(() => {\n document.addEventListener('mousedown', handleOutsideClick);\n return () => {\n document.removeEventListener('mousedown', handleOutsideClick);\n };\n }, [handleOutsideClick]);\n\n return (\n <ListBoxContext.Provider value={{ size, listBoxId, setItemHasActionsOrDelete }}>\n <Stack spacing={Spacing[1]}>\n <StyledListBox\n ref={listBoxRef}\n onSelectionChange={onSelectionChange}\n renderEmptyState={() =>\n onAdd ? (\n <ListBoxEmptyStateButton as='button' onClick={onAdd} $size={size}>\n {emptyText || 'Click to add an option'}\n </ListBoxEmptyStateButton>\n ) : (\n <ListBoxEmptyState type='button' $size={size}>\n {emptyText || 'No options.'}\n </ListBoxEmptyState>\n )\n }\n selectedKeys={selectedKeys}\n $size={size}\n items={items}\n // Without this, clicking delete triggers item selection (on press down)\n // before the delete/action callback fires (on click/press up)\n {...(itemHasActionsOrDelete && { shouldSelectOnPressUp: true })}\n {...(reorderConfig && { dragAndDropHooks })}\n {...props}\n >\n {children}\n </StyledListBox>\n {editable && (onAdd || onDelete) && (\n <Stack direction='horizontal' spacing={Spacing[1]}>\n {onAdd && (\n <Button size='sm' variant='basic' width='auto' onClick={onAdd}>\n Add\n </Button>\n )}\n {onDelete && (\n <Button\n size='sm'\n variant='basic'\n width='auto'\n onClick={() => onDelete?.(selectedKeys)}\n disabled={deleteDisabled || selectedKeys == null}\n >\n Delete\n </Button>\n )}\n </Stack>\n )}\n </Stack>\n </ListBoxContext.Provider>\n );\n};\n\nconst IconButtonWidth = 16;\nconst BackgroundFadeWidth = parseInt(Spacing[3]);\n\nconst RowActionsContainer = styled('div')`\n width: ${BackgroundFadeWidth + parseInt(Spacing[1]) + IconButtonWidth + parseInt(Spacing[2])}px;\n position: absolute;\n right: 0;\n top: 0;\n height: 100%;\n padding-right: ${Spacing[2]};\n display: flex;\n align-items: center;\n justify-content: end;\n`;\n\nconst StyledItem = styled(ListItem)<{\n $hasActions?: boolean;\n $hasDelete?: boolean;\n}>`\n position: relative;\n padding: ${Spacing[1]} ${Spacing[2]};\n overflow: hidden;\n white-space: nowrap;\n\n ${RowActionsContainer} {\n background: linear-gradient(\n to right,\n transparent,\n ${Color.BackgroundPrimary} ${BackgroundFadeWidth}px\n );\n }\n\n // If both actions and delete are present or only delete is present, hide actions by default, show on hover\n ${({ $hasActions, $hasDelete }) =>\n (($hasActions && $hasDelete) || (!$hasActions && $hasDelete)) &&\n css`\n ${RowActionsContainer} {\n opacity: 0;\n }\n `}\n\n // increase the width of the row actions container when both actions and delete are present\n ${({ $hasActions, $hasDelete }) =>\n $hasActions &&\n $hasDelete &&\n css`\n ${RowActionsContainer} {\n width: ${\n BackgroundFadeWidth + parseInt(Spacing[1]) + IconButtonWidth * 2 + parseInt(Spacing[2])\n }px;\n }\n `}\n\n &${isNotDisabled}${isHovered}:not([data-selected], [data-dragging]),\n &${isNotDisabled}${isFocused}:not([data-selected], [data-dragging]),\n &[data-hovered]:not([data-selected], [data-dragging]) {\n cursor: pointer;\n color: ${({ theme }) => theme.color.text.primary};\n background-color: ${Color.BackgroundSecondary};\n\n ${RowActionsContainer} {\n opacity: 1;\n background: linear-gradient(\n to right,\n transparent,\n ${Color.BackgroundSecondary} ${BackgroundFadeWidth}px\n );\n }\n }\n\n &[data-selected],\n &[data-selected]${isFocused}, &[data-selected]:focus,\n &${isNotDisabled}${isHovered}[data-selected] {\n outline: none;\n color: ${({ theme }) => theme.color.text.brand};\n background-color: ${({ theme }) => theme.color.background.highlight};\n\n ${RowActionsContainer} {\n opacity: 1;\n background: linear-gradient(\n to right,\n transparent,\n ${({ theme }) => theme.color.background.highlight} ${BackgroundFadeWidth}px\n );\n }\n }\n\n &[data-dragging] {\n opacity: 0.5;\n background-color: ${Color.BackgroundPrimary};\n }\n\n .react-aria-Section:not(:first-child) {\n margin-top: ${Spacing[1]};\n }\n`;\n\nconst ContentContainer = styled.div`\n width: 100%;\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n`;\n\n// The drag handle wraps a 16x16 icon in an HTML <button>. Without this, the\n// button inherits the row's line-height and the icon aligns to the text\n// baseline, leaving a descender gap below it — so the icon visually sits\n// above the row's center. Making the button itself a flex container forces\n// the icon to be centered within the button's box.\nconst DragHandle = styled(HeadlessAriaButton)`\n display: flex;\n align-items: center;\n`;\n\nconst TextContent = styled.span`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst DropdownPopoverHeading = styled.div<{ $size: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'md' ? Typography.TextMediumBold : Typography.TextSmallBold)};\n border-bottom: 1px solid ${Color.BorderHairline};\n padding: ${Spacing[2]} ${Spacing[3]} ${Spacing[1]};\n`;\n\nconst DropdownPopoverContent = styled(Stack)`\n min-width: var(--radix-popover-trigger-width);\n padding: ${Spacing[3]};\n\n ${FormControlContainer} {\n min-width: 0;\n }\n`;\n\nconst DropdownPopoverFooter = styled.div`\n border-top: 1px solid ${Color.BorderHairline};\n padding: ${Spacing[1]};\n`;\n\nexport interface ListBoxItemProps extends ComponentPropsWithoutRef<typeof GridListItem> {\n /**\n * Actions to display in a dropdown menu.\n * Supports all props from `MenuItem`.\n */\n actions?: Array<\n {\n label: string;\n onClick: () => void;\n } & Omit<MenuItemProps, 'children'>\n >;\n\n /**\n * Called when the delete (X) icon is clicked. Only renders item-level delete icon if this prop is present.\n * Receives the item's id and the click event as parameters.\n */\n onDelete?: (id: string | number, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Size of the list box item.\n */\n size?: 'sm' | 'md';\n\n /**\n * Form fields to be rendered inside a row dropdown popover.\n * The configField prop will be set to true for all fields via FormGroupContext.\n * Dropdown will be opened when the item is selected.\n */\n dropdownFormFields?: ReactNode;\n\n /**\n * Content to be rendered inside the row dropdown popover.\n * Dropdown will be opened when the item is selected.\n */\n dropdownContent?: ReactNode;\n\n /**\n * Optional heading text to display in the row dropdown popover.\n * Either dropdownFormFields or dropdownContent must also be provided,\n * otherwise the dropdown will not be rendered.\n */\n dropdownHeadingText?: string;\n\n /**\n * Footer to be rendered inside the row dropdown popover.\n * Either dropdownFormFields or dropdownContent must also be provided,\n * otherwise the dropdown will not be rendered.\n */\n dropdownFooter?: ReactNode;\n}\n\nconst ListBoxItem = ({\n children,\n actions,\n onDelete,\n size,\n dropdownHeadingText,\n dropdownFormFields,\n dropdownContent,\n dropdownFooter,\n ...props\n}: ListBoxItemProps) => {\n const context = useListBoxContext();\n // Use explicit prop if provided, otherwise fall back to context value, then default to 'md'\n const effectiveSize = size ?? context?.size ?? 'md';\n\n // Update context if this item has actions or onDelete\n useEffect(() => {\n if (context && (actions || onDelete)) {\n context.setItemHasActionsOrDelete(true);\n }\n }, [context, actions, onDelete]);\n\n // Only render dropdown if there are form fields or content provided, not if there's just a header or footer.\n const shouldRenderDropdown = dropdownFormFields || dropdownContent;\n\n const handleDelete = (e: React.MouseEvent<HTMLButtonElement>) => {\n // avoid triggering row selection\n e.preventDefault();\n e.stopPropagation();\n\n if (onDelete && props.id != null) {\n onDelete(props.id, e);\n }\n };\n\n return (\n <StyledItem\n as={GridListItem}\n $hasActions={actions && actions.length > 0}\n $hasDelete={!!onDelete}\n textValue={typeof children === 'string' ? children : undefined}\n size={effectiveSize}\n {...props}\n >\n {({ isSelected, allowsDragging }) => {\n const contentWithDragHandle = (\n <ContentContainer>\n {allowsDragging && (\n <DragHandle slot='drag' aria-label='Drag to reorder'>\n <DragIcon />\n </DragHandle>\n )}\n {typeof children === 'string' || typeof children === 'number' ? (\n <TextContent>{children}</TextContent>\n ) : (\n children\n )}\n {(onDelete || actions) && (\n <RowActionsContainer>\n {actions && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions'>\n <MoreIcon />\n </IconButton>\n }\n align='start'\n portal\n >\n {actions.map((action) => (\n <MenuItem\n key={action.label}\n {...action}\n onClick={action.onClick}\n size={effectiveSize}\n >\n {action.label}\n </MenuItem>\n ))}\n </DropdownMenu>\n )}\n {onDelete && (\n <IconButton aria-label='Delete' onClick={handleDelete}>\n <XIcon />\n </IconButton>\n )}\n </RowActionsContainer>\n )}\n </ContentContainer>\n );\n\n return shouldRenderDropdown ? (\n <Popover trigger={contentWithDragHandle} open={isSelected}>\n <Popover.Card\n id={`${context?.listBoxId}-row-dropdown`}\n noPadding\n style={{ zIndex: Z_INDICES.modalDropdown }}\n >\n {dropdownHeadingText && (\n <DropdownPopoverHeading $size={effectiveSize}>\n {dropdownHeadingText}\n </DropdownPopoverHeading>\n )}\n {dropdownFormFields && (\n <DropdownPopoverContent spacing={Spacing[2]}>\n <FormGroupContext.Provider\n value={{\n configField: true,\n labelTooltipZIndex: Z_INDICES.modalDropdownTooltip,\n }}\n >\n {dropdownFormFields}\n </FormGroupContext.Provider>\n </DropdownPopoverContent>\n )}\n {dropdownContent && (\n <DropdownPopoverContent spacing={Spacing[3]}>\n {dropdownContent}\n </DropdownPopoverContent>\n )}\n {dropdownFooter && <DropdownPopoverFooter>{dropdownFooter}</DropdownPopoverFooter>}\n </Popover.Card>\n </Popover>\n ) : (\n contentWithDragHandle\n );\n }}\n </StyledItem>\n );\n};\n\nconst StyledMenuHeading = styled(MenuHeading)`\n padding: ${Spacing[1]} ${Spacing[2]};\n`;\n\nconst ListBoxHeader = (props: ComponentPropsWithoutRef<typeof Header>) => {\n return <StyledMenuHeading as={Header} {...props} />;\n};\n\nListBox.Item = ListBoxItem;\n\nListBox.Section = Section;\n\nListBox.Header = ListBoxHeader;\n\nexport default ListBox;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA+CA,MAAM,kBAAA,GAAA,MAAA,eAA2D,KAAK;;;;AAKtE,MAAa,0BAA0B;AACrC,SAAA,GAAA,MAAA,YAAkB,eAAe;;AA6DnC,MAAM,gBAAgB,CAAA,GAAA,kBAAA,SAAOA,sBAAAA,SAAS;KACjC,EAAE,YAAa,UAAU,OAAOC,oBAAAA,gBAAgB,KAAKA,oBAAAA,gBAAgB,GAAI;;;gBAG9DC,uBAAAA,MAAM,kBAAkB;mBACrBC,uBAAAA,aAAa,GAAG;sBACbD,uBAAAA,MAAM,cAAc;aAC7BE,uBAAAA,QAAQ,GAAG;;KAEnB,EAAE,gBACH,CAAC,aACD,kBAAA,GAAG;;MAED;;AAGN,MAAM,sBAAsB,CAAA,GAAA,kBAAA,SAAOC,sBAAAA,cAAc;;iBAEhC,EAAE,YAAY,MAAM,MAAM,KAAK,MAAM;;AAGtD,MAAM,oBAAoB,kBAAA,QAAO,MAA+B;KAC3D,EAAE,YAAa,UAAU,OAAOJ,oBAAAA,gBAAgB,KAAKA,oBAAAA,gBAAgB,GAAI;;;;;aAKjEG,uBAAAA,QAAQ,GAAG;WACbF,uBAAAA,MAAM,cAAc;;AAG/B,MAAM,0BAA0B,CAAA,GAAA,kBAAA,SAAO,kBAAkB;;;;;AAMzD,MAAa,WAA6B,EACxC,UACA,OACA,UACA,WACA,gBACA,cACA,mBACA,WAAW,MACX,OAAO,MACP,eACA,OACA,GAAG,YACqC;CACxC,MAAM,cAAA,GAAA,MAAA,QAAoC,KAAK;CAC/C,MAAM,aAAA,GAAA,MAAA,gBAAA,GAAA,sBAAA,SAAmC,WAAW,EAAE,EAAE,CAAC;CACzD,MAAM,gBAAgB,GAAG,UAAU;CACnC,MAAM,CAAC,wBAAwB,8BAAA,GAAA,MAAA,UAAsC,MAAM;CAE3E,MAAM,EAAE,sBAAA,GAAA,sBAAA,gBAAoC;EAC1C,WAAW,SACT,MAAM,KAAK,KAAK,CAAC,KAAK,SAAS,EAC7B,cAAc,OAAO,IAAI,EAC1B,EAAE;EACL,gCAAgC,CAAC,OAAO;EACxC,YAAY,MAAuC;AACjD,OAAI,CAAC,iBAAiB,CAAC,MACrB;GAEF,MAAM,EAAE,WAAW,gBAAgB;AACnC,OAAI,CAAC,aAAa,CAAC,YACjB;GAGF,MAAM,aAAa,MAAM,KAAK,EAAE,KAAK,CAAC;AACtC,OAAI,cAAc,KAChB;GAGF,MAAM,WAAW,MAAM,KAAK,MAAM;GAClC,MAAM,YAAYI,yBAAAA,eAAe,UAAU,aAAa,OAAO,WAAW,CAAC;GAC3E,MAAM,cAAcA,yBAAAA,eAAe,UAAU,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AAC/E,OAAI,cAAc,MAAM,gBAAgB,GACtC;GAIF,MAAM,0BAA0B,YAAY,cAAc,cAAc,IAAI;AAI5E,aAAUC,yBAAAA,gBAAgB,UAAU,WAFlC,EAAE,OAAO,iBAAiB,WAAW,0BAA0B,0BAA0B,EAEpC,CAAC;;EAE1D,sBAAsB,WAAW,iBAAA,GAAA,kBAAA,KAAC,qBAAD,EAA6B,QAAU,CAAA;EACzE,CAAC;CAGF,MAAM,sBAAA,GAAA,MAAA,cACH,UAAsB;AAIrB,MAAI,CAHsB,SAAS,cACjC,QAAQ,cAAc,uBAEF,CACpB;EAGF,MAAM,SAAS,MAAM;EACrB,MAAM,mBAAmB,WAAW,WAAW,CAAC,WAAW,QAAQ,SAAS,OAAO;EACnF,MAAM,yBAAyB,OAAO,QAAQ,QAAQ,cAAc,IAAI;AAOxE,MACE,oBACA,CAAC,0BACD,gBAAgB,QAChB,iBAAiB,SACjB,MAAM,KAAK,aAAa,CAAC,SAAS,KAClC,kBAGA,mCAAkB,IAAI,KAAK,CAAC;IAGhC;EAAC;EAAc;EAAmB;EAAc,CACjD;AAGD,EAAA,GAAA,MAAA,iBAAgB;AACd,WAAS,iBAAiB,aAAa,mBAAmB;AAC1D,eAAa;AACX,YAAS,oBAAoB,aAAa,mBAAmB;;IAE9D,CAAC,mBAAmB,CAAC;AAExB,QACE,iBAAA,GAAA,kBAAA,KAAC,eAAe,UAAhB;EAAyB,OAAO;GAAE;GAAM;GAAW;GAA2B;YAC5E,iBAAA,GAAA,kBAAA,MAACC,cAAAA,OAAD;GAAO,SAASJ,uBAAAA,QAAQ;aAAxB,CACE,iBAAA,GAAA,kBAAA,KAAC,eAAD;IACE,KAAK;IACc;IACnB,wBACE,QACE,iBAAA,GAAA,kBAAA,KAAC,yBAAD;KAAyB,IAAG;KAAS,SAAS;KAAO,OAAO;eACzD,aAAa;KACU,CAAA,GAE1B,iBAAA,GAAA,kBAAA,KAAC,mBAAD;KAAmB,MAAK;KAAS,OAAO;eACrC,aAAa;KACI,CAAA;IAGV;IACd,OAAO;IACA;IAGP,GAAK,0BAA0B,EAAE,uBAAuB,MAAM;IAC9D,GAAK,iBAAiB,EAAE,kBAAkB;IAC1C,GAAI;IAEH;IACa,CAAA,EACf,aAAa,SAAS,aACrB,iBAAA,GAAA,kBAAA,MAACI,cAAAA,OAAD;IAAO,WAAU;IAAa,SAASJ,uBAAAA,QAAQ;cAA/C,CACG,SACC,iBAAA,GAAA,kBAAA,KAACK,mBAAAA,QAAD;KAAQ,MAAK;KAAK,SAAQ;KAAQ,OAAM;KAAO,SAAS;eAAO;KAEtD,CAAA,EAEV,YACC,iBAAA,GAAA,kBAAA,KAACA,mBAAAA,QAAD;KACE,MAAK;KACL,SAAQ;KACR,OAAM;KACN,eAAe,WAAW,aAAa;KACvC,UAAU,kBAAkB,gBAAgB;eAC7C;KAEQ,CAAA,CAEL;MAEJ;;EACgB,CAAA;;AAI9B,MAAM,kBAAkB;AACxB,MAAM,sBAAsB,SAASL,uBAAAA,QAAQ,GAAG;AAEhD,MAAM,sBAAsB,CAAA,GAAA,kBAAA,SAAO,MAAM;WAC9B,sBAAsB,SAASA,uBAAAA,QAAQ,GAAG,GAAG,kBAAkB,SAASA,uBAAAA,QAAQ,GAAG,CAAC;;;;;mBAK5EA,uBAAAA,QAAQ,GAAG;;;;;AAM9B,MAAM,aAAa,CAAA,GAAA,kBAAA,SAAOM,aAAAA,SAAS;;aAKtBN,uBAAAA,QAAQ,GAAG,GAAGA,uBAAAA,QAAQ,GAAG;;;;IAIlC,oBAAoB;;;;QAIhBF,uBAAAA,MAAM,kBAAkB,GAAG,oBAAoB;;;;;KAKlD,EAAE,aAAa,kBACd,eAAe,cAAgB,CAAC,eAAe,eACjD,kBAAA,GAAG;QACC,oBAAoB;;;MAGtB;;;KAGD,EAAE,aAAa,iBAChB,eACA,cACA,kBAAA,GAAG;QACC,oBAAoB;iBAElB,sBAAsB,SAASE,uBAAAA,QAAQ,GAAG,GAAG,kBAAkB,IAAI,SAASA,uBAAAA,QAAQ,GAAG,CACxF;;MAEH;;KAEDO,wBAAAA,gBAAgBC,wBAAAA,UAAU;KAC1BD,wBAAAA,gBAAgBE,wBAAAA,UAAU;;;cAGjB,EAAE,YAAY,MAAM,MAAM,KAAK,QAAQ;wBAC7BX,uBAAAA,MAAM,oBAAoB;;MAE5C,oBAAoB;;;;;UAKhBA,uBAAAA,MAAM,oBAAoB,GAAG,oBAAoB;;;;;;oBAMvCW,wBAAAA,UAAU;KACzBF,wBAAAA,gBAAgBC,wBAAAA,UAAU;;cAEjB,EAAE,YAAY,MAAM,MAAM,KAAK,MAAM;yBAC1B,EAAE,YAAY,MAAM,MAAM,WAAW,UAAU;;MAElE,oBAAoB;;;;;WAKf,EAAE,YAAY,MAAM,MAAM,WAAW,UAAU,GAAG,oBAAoB;;;;;;;wBAOzDV,uBAAAA,MAAM,kBAAkB;;;;kBAI9BE,uBAAAA,QAAQ,GAAG;;;AAI7B,MAAM,mBAAmB,kBAAA,QAAO,GAAG;;;;SAI1BA,uBAAAA,QAAQ,GAAG;;AAQpB,MAAM,aAAa,CAAA,GAAA,kBAAA,SAAOU,+BAAAA,mBAAmB;;;;AAK7C,MAAM,cAAc,kBAAA,QAAO,IAAI;;;;;;;AAQ/B,MAAM,yBAAyB,kBAAA,QAAO,GAA2B;KAC5D,EAAE,YAAa,UAAU,OAAOC,uBAAAA,WAAW,iBAAiBA,uBAAAA,WAAW,cAAe;6BAC9Db,uBAAAA,MAAM,eAAe;aACrCE,uBAAAA,QAAQ,GAAG,GAAGA,uBAAAA,QAAQ,GAAG,GAAGA,uBAAAA,QAAQ,GAAG;;AAGpD,MAAM,yBAAyB,CAAA,GAAA,kBAAA,SAAOI,cAAAA,MAAM;;aAE/BJ,uBAAAA,QAAQ,GAAG;;IAEpBY,oBAAAA,UAAqB;;;;AAKzB,MAAM,wBAAwB,kBAAA,QAAO,GAAG;0BACdd,uBAAAA,MAAM,eAAe;aAClCE,uBAAAA,QAAQ,GAAG;;AAsDxB,MAAM,eAAe,EACnB,UACA,SACA,UACA,MACA,qBACA,oBACA,iBACA,gBACA,GAAG,YACmB;CACtB,MAAM,UAAU,mBAAmB;CAEnC,MAAM,gBAAgB,QAAQ,SAAS,QAAQ;AAG/C,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,YAAY,WAAW,UACzB,SAAQ,0BAA0B,KAAK;IAExC;EAAC;EAAS;EAAS;EAAS,CAAC;CAGhC,MAAM,uBAAuB,sBAAsB;CAEnD,MAAM,gBAAgB,MAA2C;AAE/D,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AAEnB,MAAI,YAAY,MAAM,MAAM,KAC1B,UAAS,MAAM,IAAI,EAAE;;AAIzB,QACE,iBAAA,GAAA,kBAAA,KAAC,YAAD;EACE,IAAIa,sBAAAA;EACJ,aAAa,WAAW,QAAQ,SAAS;EACzC,YAAY,CAAC,CAAC;EACd,WAAW,OAAO,aAAa,WAAW,WAAW,KAAA;EACrD,MAAM;EACN,GAAI;aAEF,EAAE,YAAY,qBAAqB;GACnC,MAAM,wBACJ,iBAAA,GAAA,kBAAA,MAAC,kBAAD,EAAA,UAAA;IACG,kBACC,iBAAA,GAAA,kBAAA,KAAC,YAAD;KAAY,MAAK;KAAO,cAAW;eACjC,iBAAA,GAAA,kBAAA,KAACC,eAAAA,UAAD,EAAY,CAAA;KACD,CAAA;IAEd,OAAO,aAAa,YAAY,OAAO,aAAa,WACnD,iBAAA,GAAA,kBAAA,KAAC,aAAD,EAAc,UAAuB,CAAA,GAErC;KAEA,YAAY,YACZ,iBAAA,GAAA,kBAAA,MAAC,qBAAD,EAAA,UAAA,CACG,WACC,iBAAA,GAAA,kBAAA,KAACC,qBAAAA,sBAAD;KACE,SACE,iBAAA,GAAA,kBAAA,KAACC,mBAAAA,YAAD;MAAY,cAAW;gBACrB,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,UAAD,EAAY,CAAA;MACD,CAAA;KAEf,OAAM;KACN,QAAA;eAEC,QAAQ,KAAK,WACZ,iBAAA,GAAA,kBAAA,KAACC,aAAAA,UAAD;MAEE,GAAI;MACJ,SAAS,OAAO;MAChB,MAAM;gBAEL,OAAO;MACC,EANJ,OAAO,MAMH,CACX;KACW,CAAA,EAEhB,YACC,iBAAA,GAAA,kBAAA,KAACF,mBAAAA,YAAD;KAAY,cAAW;KAAS,SAAS;eACvC,iBAAA,GAAA,kBAAA,KAACG,oBAAAA,OAAD,EAAS,CAAA;KACE,CAAA,CAEK,EAAA,CAAA;IAEP,EAAA,CAAA;AAGrB,UAAO,uBACL,iBAAA,GAAA,kBAAA,KAACC,gBAAAA,iBAAD;IAAS,SAAS;IAAuB,MAAM;cAC7C,iBAAA,GAAA,kBAAA,MAACA,gBAAAA,gBAAQ,MAAT;KACE,IAAI,GAAG,SAAS,UAAU;KAC1B,WAAA;KACA,OAAO,EAAE,QAAQC,mBAAAA,UAAU,eAAe;eAH5C;MAKG,uBACC,iBAAA,GAAA,kBAAA,KAAC,wBAAD;OAAwB,OAAO;iBAC5B;OACsB,CAAA;MAE1B,sBACC,iBAAA,GAAA,kBAAA,KAAC,wBAAD;OAAwB,SAASrB,uBAAAA,QAAQ;iBACvC,iBAAA,GAAA,kBAAA,KAACsB,qBAAAA,iBAAiB,UAAlB;QACE,OAAO;SACL,aAAa;SACb,oBAAoBD,mBAAAA,UAAU;SAC/B;kBAEA;QACyB,CAAA;OACL,CAAA;MAE1B,mBACC,iBAAA,GAAA,kBAAA,KAAC,wBAAD;OAAwB,SAASrB,uBAAAA,QAAQ;iBACtC;OACsB,CAAA;MAE1B,kBAAkB,iBAAA,GAAA,kBAAA,KAAC,uBAAD,EAAA,UAAwB,gBAAuC,CAAA;MACrE;;IACP,CAAA,GAEV;;EAGO,CAAA;;AAIjB,MAAM,oBAAoB,CAAA,GAAA,kBAAA,SAAOuB,aAAAA,YAAY;aAChCvB,uBAAAA,QAAQ,GAAG,GAAGA,uBAAAA,QAAQ,GAAG;;AAGtC,MAAM,iBAAiB,UAAmD;AACxE,QAAO,iBAAA,GAAA,kBAAA,KAAC,mBAAD;EAAmB,IAAIwB,sBAAAA;EAAQ,GAAI;EAAS,CAAA;;AAGrD,QAAQ,OAAO;AAEf,QAAQ,UAAUC,sBAAAA;AAElB,QAAQ,SAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ListBox-B7sbubm5.mjs","names":["Button","FormControlContainer","DropdownMenu","MoreIcon","XIcon","Popover","Section"],"sources":["../components/ListBox/ListBox.tsx"],"sourcesContent":["import uniqueId from 'lodash/fp/uniqueId';\nimport {\n type ComponentPropsWithoutRef,\n createContext,\n type PropsWithChildren,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n DropIndicator,\n type DroppableCollectionReorderEvent,\n GridList,\n GridListItem,\n Header,\n ListBoxSection as Section,\n useDragAndDrop,\n} from 'react-aria-components';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius, Color, Spacing, Typography } from '@persona/design-tokens';\nimport { DragIcon } from '@persona/icons';\nimport { MoreIcon, XIcon } from '@persona/icons/12px';\nimport Button, { type ButtonProps, IconButton } from 'design-system/components/Button';\nimport { FormGroupContext } from 'design-system/components/ConfigFormGroup/useFormGroup';\nimport DropdownMenu from 'design-system/components/DropdownMenu';\nimport { Container as FormControlContainer } from 'design-system/components/FormControl';\nimport { ListItem, MenuHeading, MenuItem, type MenuItemProps } from 'design-system/components/Menu';\nimport Popover from 'design-system/components/Popover/Popover';\nimport Stack from 'design-system/components/Stack';\nimport { HeadlessAriaButton } from 'design-system/lib/HeadlessAriaButton';\nimport { isFocused, isHovered, isNotDisabled } from 'design-system/lib/pseudoClass';\nimport { findIndexByKey, moveItemByIndex } from 'design-system/lib/reorderItems';\nimport { Z_INDICES } from 'design-system/lib/zindex';\nimport { paragraphMixins } from 'design-system/mixins/text';\n\n// Context for sharing ListBox configuration with child items\ninterface ListBoxContextValue {\n size: 'sm' | 'md';\n listBoxId: string;\n setItemHasActionsOrDelete: (value: boolean) => void;\n}\n\nconst ListBoxContext = createContext<ListBoxContextValue | null>(null);\n\n/**\n * Hook to access ListBox context values (like size) from child components\n */\nexport const useListBoxContext = () => {\n return useContext(ListBoxContext);\n};\n\nexport interface ListBoxProps<T extends object> extends Omit<\n ComponentPropsWithoutRef<typeof GridList<T>>,\n 'slot' | 'autoFocus' | 'orientation' | 'shouldFocusWrap' | 'dragAndDropHooks' | 'layout'\n> {\n /**\n * Called when \"Add\" button is clicked. Only renders \"Add\" button if this prop is present.\n */\n onAdd?: ButtonProps['onClick'];\n\n /**\n * Called when \"Delete\" button is clicked. Only renders \"Delete\" button if this prop is present.\n */\n onDelete?: (selectedKeys: ListBoxProps<T>['selectedKeys']) => void;\n\n /**\n * Whether or not delete button should be disabled.\n */\n deleteDisabled?: boolean;\n\n /**\n * Whether or not the Add/Delete buttons should be shown.\n */\n editable?: boolean;\n\n /**\n * Text to display if no options are available.\n */\n emptyText?: string;\n\n /**\n * Whether or not to expand the box to the full width of the container.\n */\n fullWidth?: boolean;\n\n /**\n * When provided, enables drag and drop functionality.\n */\n reorderConfig?: {\n /**\n * Called when items are reordered via drag and drop. Receives the reordered\n * array of items when an item is dropped.\n */\n onReorder: (reorderedItems: T[]) => void;\n /**\n * The name of the property on the item that was passed as the key to\n * `ListBox.Item`. For exanple, if the item is`{ id: '1', name: 'First Item' }`,\n * and you passed ListBox.Item `key={item.id}`, then the `itemKeyPath`\n * should be `'id'`.\n */\n itemKeyPath: string;\n };\n\n /**\n * Size of the list box.\n */\n size?: 'sm' | 'md';\n}\n\nconst StyledListBox = styled(GridList)<{ fullWidth?: boolean; $size?: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n\n box-sizing: border-box;\n background: ${Color.BackgroundPrimary};\n border-radius: ${BorderRadius.Md};\n border: 1px solid ${Color.BorderDivider};\n padding: ${Spacing[1]};\n\n ${({ fullWidth }) =>\n !fullWidth &&\n css`\n width: 204px;\n `}\n`;\n\nconst StyledDropIndicator = styled(DropIndicator)`\n height: 2px;\n background: ${({ theme }) => theme.color.text.brand};\n`;\n\nconst ListBoxEmptyState = styled.button<{ $size?: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n\n background-color: transparent;\n outline: none;\n border: none;\n padding: ${Spacing[1]};\n color: ${Color.TextSecondary};\n`;\n\nconst ListBoxEmptyStateButton = styled(ListBoxEmptyState)`\n &:hover {\n cursor: pointer;\n }\n`;\n\nexport const ListBox = <T extends object>({\n children,\n onAdd,\n onDelete,\n emptyText,\n deleteDisabled,\n selectedKeys,\n onSelectionChange,\n editable = true,\n size = 'md',\n reorderConfig,\n items,\n ...props\n}: PropsWithChildren<ListBoxProps<T>>) => {\n const listBoxRef = useRef<HTMLDivElement>(null);\n const listBoxId = useMemo(() => uniqueId('listbox-'), []);\n const rowDropdownId = `${listBoxId}-row-dropdown`;\n const [itemHasActionsOrDelete, setItemHasActionsOrDelete] = useState(false);\n\n const { dragAndDropHooks } = useDragAndDrop({\n getItems: (keys) =>\n Array.from(keys).map((key) => ({\n 'text/plain': String(key),\n })),\n getAllowedDropOperations: () => ['move'],\n onReorder: (e: DroppableCollectionReorderEvent) => {\n if (!reorderConfig || !items) {\n return;\n }\n const { onReorder, itemKeyPath } = reorderConfig;\n if (!onReorder || !itemKeyPath) {\n return;\n }\n\n const draggedKey = Array.from(e.keys)[0];\n if (draggedKey == null) {\n return;\n }\n\n const itemsArr = Array.from(items);\n const fromIndex = findIndexByKey(itemsArr, itemKeyPath, String(draggedKey));\n const targetIndex = findIndexByKey(itemsArr, itemKeyPath, String(e.target.key));\n if (fromIndex === -1 || targetIndex === -1) {\n return;\n }\n\n // After removing the dragged item, a target that sat after it shifts down by one.\n const targetIndexAfterRemoval = fromIndex < targetIndex ? targetIndex - 1 : targetIndex;\n const toIndex =\n e.target.dropPosition === 'before' ? targetIndexAfterRemoval : targetIndexAfterRemoval + 1;\n\n onReorder(moveItemByIndex(itemsArr, fromIndex, toIndex));\n },\n renderDropIndicator: (target) => <StyledDropIndicator target={target} />,\n });\n\n // If row dropdowns are open, deselect items (which also closes the dropdown) when clicking outside the ListBox\n const handleOutsideClick = useCallback(\n (event: MouseEvent) => {\n const rowDropdownIsOpen = document.querySelector(\n `[id=\"${rowDropdownId}\"][data-state=\"open\"]`,\n );\n if (!rowDropdownIsOpen) {\n return;\n }\n\n const target = event.target as HTMLElement;\n const isOutsideListBox = listBoxRef.current && !listBoxRef.current.contains(target);\n const isOnRowDropdownContent = target.closest(`[id=\"${rowDropdownId}\"]`);\n\n // Only deselect if:\n // 1. Click is outside the ListBox\n // 2. Click is not on popover content\n // 3. There are selected items\n // 4. onSelectionChange is available (to allow deselection)\n if (\n isOutsideListBox &&\n !isOnRowDropdownContent &&\n selectedKeys != null &&\n selectedKeys !== 'all' &&\n Array.from(selectedKeys).length > 0 &&\n onSelectionChange\n ) {\n // Deselect all items when clicking outside (but not on popover content)\n onSelectionChange(new Set());\n }\n },\n [selectedKeys, onSelectionChange, rowDropdownId],\n );\n\n // Set up outside click listener\n useEffect(() => {\n document.addEventListener('mousedown', handleOutsideClick);\n return () => {\n document.removeEventListener('mousedown', handleOutsideClick);\n };\n }, [handleOutsideClick]);\n\n return (\n <ListBoxContext.Provider value={{ size, listBoxId, setItemHasActionsOrDelete }}>\n <Stack spacing={Spacing[1]}>\n <StyledListBox\n ref={listBoxRef}\n onSelectionChange={onSelectionChange}\n renderEmptyState={() =>\n onAdd ? (\n <ListBoxEmptyStateButton as='button' onClick={onAdd} $size={size}>\n {emptyText || 'Click to add an option'}\n </ListBoxEmptyStateButton>\n ) : (\n <ListBoxEmptyState type='button' $size={size}>\n {emptyText || 'No options.'}\n </ListBoxEmptyState>\n )\n }\n selectedKeys={selectedKeys}\n $size={size}\n items={items}\n // Without this, clicking delete triggers item selection (on press down)\n // before the delete/action callback fires (on click/press up)\n {...(itemHasActionsOrDelete && { shouldSelectOnPressUp: true })}\n {...(reorderConfig && { dragAndDropHooks })}\n {...props}\n >\n {children}\n </StyledListBox>\n {editable && (onAdd || onDelete) && (\n <Stack direction='horizontal' spacing={Spacing[1]}>\n {onAdd && (\n <Button size='sm' variant='basic' width='auto' onClick={onAdd}>\n Add\n </Button>\n )}\n {onDelete && (\n <Button\n size='sm'\n variant='basic'\n width='auto'\n onClick={() => onDelete?.(selectedKeys)}\n disabled={deleteDisabled || selectedKeys == null}\n >\n Delete\n </Button>\n )}\n </Stack>\n )}\n </Stack>\n </ListBoxContext.Provider>\n );\n};\n\nconst IconButtonWidth = 16;\nconst BackgroundFadeWidth = parseInt(Spacing[3]);\n\nconst RowActionsContainer = styled('div')`\n width: ${BackgroundFadeWidth + parseInt(Spacing[1]) + IconButtonWidth + parseInt(Spacing[2])}px;\n position: absolute;\n right: 0;\n top: 0;\n height: 100%;\n padding-right: ${Spacing[2]};\n display: flex;\n align-items: center;\n justify-content: end;\n`;\n\nconst StyledItem = styled(ListItem)<{\n $hasActions?: boolean;\n $hasDelete?: boolean;\n}>`\n position: relative;\n padding: ${Spacing[1]} ${Spacing[2]};\n overflow: hidden;\n white-space: nowrap;\n\n ${RowActionsContainer} {\n background: linear-gradient(\n to right,\n transparent,\n ${Color.BackgroundPrimary} ${BackgroundFadeWidth}px\n );\n }\n\n // If both actions and delete are present or only delete is present, hide actions by default, show on hover\n ${({ $hasActions, $hasDelete }) =>\n (($hasActions && $hasDelete) || (!$hasActions && $hasDelete)) &&\n css`\n ${RowActionsContainer} {\n opacity: 0;\n }\n `}\n\n // increase the width of the row actions container when both actions and delete are present\n ${({ $hasActions, $hasDelete }) =>\n $hasActions &&\n $hasDelete &&\n css`\n ${RowActionsContainer} {\n width: ${\n BackgroundFadeWidth + parseInt(Spacing[1]) + IconButtonWidth * 2 + parseInt(Spacing[2])\n }px;\n }\n `}\n\n &${isNotDisabled}${isHovered}:not([data-selected], [data-dragging]),\n &${isNotDisabled}${isFocused}:not([data-selected], [data-dragging]),\n &[data-hovered]:not([data-selected], [data-dragging]) {\n cursor: pointer;\n color: ${({ theme }) => theme.color.text.primary};\n background-color: ${Color.BackgroundSecondary};\n\n ${RowActionsContainer} {\n opacity: 1;\n background: linear-gradient(\n to right,\n transparent,\n ${Color.BackgroundSecondary} ${BackgroundFadeWidth}px\n );\n }\n }\n\n &[data-selected],\n &[data-selected]${isFocused}, &[data-selected]:focus,\n &${isNotDisabled}${isHovered}[data-selected] {\n outline: none;\n color: ${({ theme }) => theme.color.text.brand};\n background-color: ${({ theme }) => theme.color.background.highlight};\n\n ${RowActionsContainer} {\n opacity: 1;\n background: linear-gradient(\n to right,\n transparent,\n ${({ theme }) => theme.color.background.highlight} ${BackgroundFadeWidth}px\n );\n }\n }\n\n &[data-dragging] {\n opacity: 0.5;\n background-color: ${Color.BackgroundPrimary};\n }\n\n .react-aria-Section:not(:first-child) {\n margin-top: ${Spacing[1]};\n }\n`;\n\nconst ContentContainer = styled.div`\n width: 100%;\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n`;\n\n// The drag handle wraps a 16x16 icon in an HTML <button>. Without this, the\n// button inherits the row's line-height and the icon aligns to the text\n// baseline, leaving a descender gap below it — so the icon visually sits\n// above the row's center. Making the button itself a flex container forces\n// the icon to be centered within the button's box.\nconst DragHandle = styled(HeadlessAriaButton)`\n display: flex;\n align-items: center;\n`;\n\nconst TextContent = styled.span`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst DropdownPopoverHeading = styled.div<{ $size: 'sm' | 'md' }>`\n ${({ $size }) => ($size === 'md' ? Typography.TextMediumBold : Typography.TextSmallBold)};\n border-bottom: 1px solid ${Color.BorderHairline};\n padding: ${Spacing[2]} ${Spacing[3]} ${Spacing[1]};\n`;\n\nconst DropdownPopoverContent = styled(Stack)`\n min-width: var(--radix-popover-trigger-width);\n padding: ${Spacing[3]};\n\n ${FormControlContainer} {\n min-width: 0;\n }\n`;\n\nconst DropdownPopoverFooter = styled.div`\n border-top: 1px solid ${Color.BorderHairline};\n padding: ${Spacing[1]};\n`;\n\nexport interface ListBoxItemProps extends ComponentPropsWithoutRef<typeof GridListItem> {\n /**\n * Actions to display in a dropdown menu.\n * Supports all props from `MenuItem`.\n */\n actions?: Array<\n {\n label: string;\n onClick: () => void;\n } & Omit<MenuItemProps, 'children'>\n >;\n\n /**\n * Called when the delete (X) icon is clicked. Only renders item-level delete icon if this prop is present.\n * Receives the item's id and the click event as parameters.\n */\n onDelete?: (id: string | number, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Size of the list box item.\n */\n size?: 'sm' | 'md';\n\n /**\n * Form fields to be rendered inside a row dropdown popover.\n * The configField prop will be set to true for all fields via FormGroupContext.\n * Dropdown will be opened when the item is selected.\n */\n dropdownFormFields?: ReactNode;\n\n /**\n * Content to be rendered inside the row dropdown popover.\n * Dropdown will be opened when the item is selected.\n */\n dropdownContent?: ReactNode;\n\n /**\n * Optional heading text to display in the row dropdown popover.\n * Either dropdownFormFields or dropdownContent must also be provided,\n * otherwise the dropdown will not be rendered.\n */\n dropdownHeadingText?: string;\n\n /**\n * Footer to be rendered inside the row dropdown popover.\n * Either dropdownFormFields or dropdownContent must also be provided,\n * otherwise the dropdown will not be rendered.\n */\n dropdownFooter?: ReactNode;\n}\n\nconst ListBoxItem = ({\n children,\n actions,\n onDelete,\n size,\n dropdownHeadingText,\n dropdownFormFields,\n dropdownContent,\n dropdownFooter,\n ...props\n}: ListBoxItemProps) => {\n const context = useListBoxContext();\n // Use explicit prop if provided, otherwise fall back to context value, then default to 'md'\n const effectiveSize = size ?? context?.size ?? 'md';\n\n // Update context if this item has actions or onDelete\n useEffect(() => {\n if (context && (actions || onDelete)) {\n context.setItemHasActionsOrDelete(true);\n }\n }, [context, actions, onDelete]);\n\n // Only render dropdown if there are form fields or content provided, not if there's just a header or footer.\n const shouldRenderDropdown = dropdownFormFields || dropdownContent;\n\n const handleDelete = (e: React.MouseEvent<HTMLButtonElement>) => {\n // avoid triggering row selection\n e.preventDefault();\n e.stopPropagation();\n\n if (onDelete && props.id != null) {\n onDelete(props.id, e);\n }\n };\n\n return (\n <StyledItem\n as={GridListItem}\n $hasActions={actions && actions.length > 0}\n $hasDelete={!!onDelete}\n textValue={typeof children === 'string' ? children : undefined}\n size={effectiveSize}\n {...props}\n >\n {({ isSelected, allowsDragging }) => {\n const contentWithDragHandle = (\n <ContentContainer>\n {allowsDragging && (\n <DragHandle slot='drag' aria-label='Drag to reorder'>\n <DragIcon />\n </DragHandle>\n )}\n {typeof children === 'string' || typeof children === 'number' ? (\n <TextContent>{children}</TextContent>\n ) : (\n children\n )}\n {(onDelete || actions) && (\n <RowActionsContainer>\n {actions && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions'>\n <MoreIcon />\n </IconButton>\n }\n align='start'\n portal\n >\n {actions.map((action) => (\n <MenuItem\n key={action.label}\n {...action}\n onClick={action.onClick}\n size={effectiveSize}\n >\n {action.label}\n </MenuItem>\n ))}\n </DropdownMenu>\n )}\n {onDelete && (\n <IconButton aria-label='Delete' onClick={handleDelete}>\n <XIcon />\n </IconButton>\n )}\n </RowActionsContainer>\n )}\n </ContentContainer>\n );\n\n return shouldRenderDropdown ? (\n <Popover trigger={contentWithDragHandle} open={isSelected}>\n <Popover.Card\n id={`${context?.listBoxId}-row-dropdown`}\n noPadding\n style={{ zIndex: Z_INDICES.modalDropdown }}\n >\n {dropdownHeadingText && (\n <DropdownPopoverHeading $size={effectiveSize}>\n {dropdownHeadingText}\n </DropdownPopoverHeading>\n )}\n {dropdownFormFields && (\n <DropdownPopoverContent spacing={Spacing[2]}>\n <FormGroupContext.Provider\n value={{\n configField: true,\n labelTooltipZIndex: Z_INDICES.modalDropdownTooltip,\n }}\n >\n {dropdownFormFields}\n </FormGroupContext.Provider>\n </DropdownPopoverContent>\n )}\n {dropdownContent && (\n <DropdownPopoverContent spacing={Spacing[3]}>\n {dropdownContent}\n </DropdownPopoverContent>\n )}\n {dropdownFooter && <DropdownPopoverFooter>{dropdownFooter}</DropdownPopoverFooter>}\n </Popover.Card>\n </Popover>\n ) : (\n contentWithDragHandle\n );\n }}\n </StyledItem>\n );\n};\n\nconst StyledMenuHeading = styled(MenuHeading)`\n padding: ${Spacing[1]} ${Spacing[2]};\n`;\n\nconst ListBoxHeader = (props: ComponentPropsWithoutRef<typeof Header>) => {\n return <StyledMenuHeading as={Header} {...props} />;\n};\n\nListBox.Item = ListBoxItem;\n\nListBox.Section = Section;\n\nListBox.Header = ListBoxHeader;\n\nexport default ListBox;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination-DEZFb552.cjs","names":["HStack","Spacing","Input","Button","Spacing","Color","Typography","Select","Option","Color"],"sources":["../components/Pagination/constants.ts","../components/Pagination/PageSelector.tsx","../components/Pagination/PageSizeSelector.tsx","../components/Pagination/Pagination.tsx","../components/Pagination/index.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 300];\nexport const MIN_PAGE_SIZE = 10;\n","import { debounce } from 'lodash/fp';\nimport { useEffect, useMemo, useState } from 'react';\nimport styled from 'styled-components';\n\nimport Button from '@persona/design-system/components/Button';\nimport { Input } from '@persona/design-system/components/Input';\nimport { HStack } from '@persona/design-system/components/Stack';\nimport { Spacing } from '@persona/design-tokens';\n\nimport type { PaginationParams } from './types';\n\n// After a certain limit, it no longer makes sense for someone\n// to jump to the last page. Deep paging has performance limitations.\nexport const PAGE_LIMIT_BEFORE_SCROLL_MODE = 100;\n\nconst PageSelectorStack = styled(HStack).attrs({ justify: 'flex-end' })`\n padding: ${Spacing[2]};\n`;\n\nexport const PageInput = styled(HStack).attrs({ align: 'center' })`\n white-space: nowrap;\n`;\n\ninterface PageSelectorProps {\n paginationParams: PaginationParams;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n /**\n * Called with the new page number after the page changes (next, prev, or\n * typed input). Lets the consumer react to page changes -- e.g. scroll the\n * page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n}\n\nexport default function PageSelector({\n paginationParams,\n handlePageLinkClick,\n isLoading,\n onPageChange,\n}: PageSelectorProps) {\n const {\n 'current-page': currentPage,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams ?? {};\n const [selectedPage, setSelectedPage] = useState<number | undefined>(currentPage);\n\n // We don't use useDebounced to avoid function object reference issues.\n const handlePageLinkClickDebounced = useMemo(\n () => debounce(500, handlePageLinkClick),\n [handlePageLinkClick],\n );\n\n // Keep input state synced to pagination state when other user action changes\n // pagination state.\n useEffect(() => {\n if (currentPage != null) {\n setSelectedPage(currentPage);\n }\n }, [currentPage]);\n\n if (!paginationParams) {\n return <div />;\n }\n\n return (\n <PageSelectorStack data-test='pagination__page-selector' id='pagination__page-selector'>\n <PageInput>\n {totalPages < PAGE_LIMIT_BEFORE_SCROLL_MODE && !lowerBound ? (\n <Input\n aria-label='Go to page number'\n size='sm'\n inputSize={2}\n onChange={(e) => {\n const value = e.target.valueAsNumber;\n if (Number.isNaN(value)) {\n setSelectedPage(undefined);\n } else {\n // Setting unbounded value feels smoother as the value is not corrected until after the fetch via useEffect.\n setSelectedPage(value);\n const boundedValue = Math.min(Math.max(e.target.valueAsNumber, 1), totalPages);\n handlePageLinkClickDebounced(boundedValue);\n onPageChange?.(boundedValue);\n }\n }}\n onBlur={(e) => {\n // Fill blank value on blur.\n if (Number.isNaN(e.target.valueAsNumber)) {\n setSelectedPage(currentPage);\n }\n }}\n min={1}\n max={totalPages}\n type='number'\n disabled={isLoading}\n value={selectedPage ?? ''}\n />\n ) : (\n currentPage + ' '\n )}\n of {lowerBound ? 'many' : totalPages} pages\n </PageInput>\n <Button\n id='pagination__page-selector--left'\n disabled={currentPage === 1 || isLoading}\n onClick={() => {\n if (currentPage !== 1) {\n const prevPageNum = currentPage - 1;\n setSelectedPage(prevPageNum);\n handlePageLinkClick(prevPageNum);\n onPageChange?.(prevPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-left'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label='Previous page'\n >\n Prev\n </Button>\n <Button\n id='pagination__page-selector--right'\n disabled={(currentPage === totalPages && !lowerBound) || isLoading}\n onClick={() => {\n if (currentPage !== totalPages || lowerBound) {\n const nextPageNum = currentPage + 1;\n setSelectedPage(nextPageNum);\n handlePageLinkClick(nextPageNum);\n onPageChange?.(nextPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-right'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label='Next page'\n >\n Next\n </Button>\n </PageSelectorStack>\n );\n}\n","import styled from 'styled-components';\n\nimport Select, { Option } from '@persona/design-system/components/Select';\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nconst Selector = styled('div')`\n padding: ${Spacing[2]};\n display: flex;\n justify-content: flex-end;\n`;\n\nconst Label = styled.label`\n display: flex;\n align-items: center;\n white-space: nowrap;\n gap: ${Spacing[2]};\n padding: ${Spacing[2]};\n`;\n\ninterface PageSizeOptionProps {\n currentPageSize: number;\n pageSizeOption: number;\n}\n\nexport const PageSizeOption = styled('div')<PageSizeOptionProps>`\n padding: 0 ${Spacing[1]};\n color: ${Color.PrimaryPurple};\n cursor: pointer;\n\n ${({ currentPageSize, pageSizeOption }) => {\n if (currentPageSize === pageSizeOption) {\n return `\n ${Typography.TextMediumBold};\n text-decoration: underline;\n `;\n }\n }};\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\ninterface PageSizeSelectorProps {\n pageSize: number;\n pageSizeOptions: number[];\n handlePageSizeClick: (pageSize: number) => void;\n}\n\nconst PageSizeSelector = ({\n pageSize,\n pageSizeOptions,\n handlePageSizeClick,\n}: PageSizeSelectorProps) => {\n // Add pageSize to selector just in case it isn't part of the options so UI doesn't look weird\n const pageSizes = [\n ...pageSizeOptions,\n ...(pageSizeOptions.includes(pageSize) ? [] : [pageSize]),\n ].sort((a, b) => a - b);\n\n return (\n <Selector data-test='pagination__page-size-selector'>\n <Label>\n Items per page:\n <Select\n value={pageSize.toString()}\n onValueChange={(val) => handlePageSizeClick(Number(val))}\n size='sm'\n >\n {pageSizes.map((size) => (\n <Option key={size} value={size.toString()}>\n {size}\n </Option>\n ))}\n </Select>\n </Label>\n </Selector>\n );\n};\n\nexport default PageSizeSelector;\n","import styled from 'styled-components';\n\nimport { Color } from '@persona/design-tokens';\n\nimport { DEFAULT_PAGE_SIZE_OPTIONS } from './constants';\nimport PageSelector from './PageSelector';\nimport PageSizeSelector from './PageSizeSelector';\nimport type { PaginationParams } from './types';\n\n// NB: this is configured in config/initializers/kaminari.rb\nconst MAX_PAGES = 100;\n\nconst Container = styled('nav')`\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\n\nexport const PaginationInfo = styled('div')`\n display: flex;\n align-items: center;\n\n color: ${Color.TextPrimary};\n`;\n\ninterface PaginationProps {\n pageSize?: number;\n pageSizeOptions?: number[];\n paginationParams?: PaginationParams;\n handlePageSizeClick: (pageSize: number) => void;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n showPageSizeSelector?: boolean;\n /**\n * Called with the new page number after the page changes. Lets the consumer\n * react to page changes -- e.g. scroll the page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n}\n\nconst Pagination = ({\n pageSize,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationParams,\n handlePageSizeClick,\n handlePageLinkClick,\n isLoading,\n showPageSizeSelector = true,\n onPageChange,\n}: PaginationProps) => {\n if (!paginationParams || !pageSize) {\n return <div />;\n }\n\n const {\n 'current-page': currentPage,\n 'total-count': totalCount,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams;\n\n // If the total number of pages is the same as MAX_PAGES, we guess that the total number of\n // items might be limited by max pages, and that the total could change based on page size.\n // To limit user confusion here, we use 'many' instead of a specific number.\n const totalCountDisplay = lowerBound || totalPages >= MAX_PAGES ? 'many' : totalCount;\n\n const lastItemIndex = lowerBound\n ? currentPage * pageSize\n : Math.min(currentPage * pageSize, totalCount);\n const firstItemIndex = pageSize * (currentPage - 1) + 1;\n\n return (\n <Container role='navigation' aria-label='pagination'>\n {showPageSizeSelector && (\n <PageSizeSelector\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n handlePageSizeClick={handlePageSizeClick}\n />\n )}\n {totalCount > 0 && (\n <>\n <div>\n Showing {firstItemIndex}-{lastItemIndex} of {totalCountDisplay} items\n </div>\n <PaginationInfo>\n <PageSelector\n paginationParams={paginationParams}\n handlePageLinkClick={handlePageLinkClick}\n isLoading={isLoading}\n onPageChange={onPageChange}\n />\n </PaginationInfo>\n </>\n )}\n </Container>\n );\n};\n\nexport default Pagination;\n","import Pagination from './Pagination';\n\nexport { default as PageSelector, PAGE_LIMIT_BEFORE_SCROLL_MODE } from './PageSelector';\nexport * from './constants';\nexport default Pagination;\n"],"mappings":";;;;;;;;;;;;AAAA,MAAa,4BAA4B;CAAC;CAAI;CAAI;CAAI;CAAK;CAAI;AAC/D,MAAa,gBAAgB;;;ACY7B,MAAa,gCAAgC;AAE7C,MAAM,oBAAoB,CAAA,GAAA,kBAAA,SAAOA,cAAAA,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC;aAC1DC,uBAAAA,QAAQ,GAAG;;AAGxB,MAAa,YAAY,CAAA,GAAA,kBAAA,SAAOD,cAAAA,OAAO,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC;;;AAgBlE,SAAwB,aAAa,EACnC,kBACA,qBACA,WACA,gBACoB;CACpB,MAAM,EACJ,gBAAgB,aAChB,eAAe,YACf,eAAe,eACb,oBAAoB,EAAE;CAC1B,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,UAAgD,YAAY;CAGjF,MAAM,gCAAA,GAAA,MAAA,gBAAA,GAAA,aAAA,UACW,KAAK,oBAAoB,EACxC,CAAC,oBAAoB,CACtB;AAID,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,eAAe,KACjB,iBAAgB,YAAY;IAE7B,CAAC,YAAY,CAAC;AAEjB,KAAI,CAAC,iBACH,QAAO,iBAAA,GAAA,kBAAA,KAAC,OAAD,EAAO,CAAA;AAGhB,QACE,iBAAA,GAAA,kBAAA,MAAC,mBAAD;EAAmB,aAAU;EAA4B,IAAG;YAA5D;GACE,iBAAA,GAAA,kBAAA,MAAC,WAAD,EAAA,UAAA;IACG,aAAA,OAA8C,CAAC,aAC9C,iBAAA,GAAA,kBAAA,KAACE,cAAAA,OAAD;KACE,cAAW;KACX,MAAK;KACL,WAAW;KACX,WAAW,MAAM;MACf,MAAM,QAAQ,EAAE,OAAO;AACvB,UAAI,OAAO,MAAM,MAAM,CACrB,iBAAgB,KAAA,EAAU;WACrB;AAEL,uBAAgB,MAAM;OACtB,MAAM,eAAe,KAAK,IAAI,KAAK,IAAI,EAAE,OAAO,eAAe,EAAE,EAAE,WAAW;AAC9E,oCAA6B,aAAa;AAC1C,sBAAe,aAAa;;;KAGhC,SAAS,MAAM;AAEb,UAAI,OAAO,MAAM,EAAE,OAAO,cAAc,CACtC,iBAAgB,YAAY;;KAGhC,KAAK;KACL,KAAK;KACL,MAAK;KACL,UAAU;KACV,OAAO,gBAAgB;KACvB,CAAA,GAEF,cAAc;IACd;IACE,aAAa,SAAS;IAAW;IAC3B,EAAA,CAAA;GACZ,iBAAA,GAAA,kBAAA,KAACC,mBAAAA,QAAD;IACE,IAAG;IACH,UAAU,gBAAgB,KAAK;IAC/B,eAAe;AACb,SAAI,gBAAgB,GAAG;MACrB,MAAM,cAAc,cAAc;AAClC,sBAAgB,YAAY;AAC5B,0BAAoB,YAAY;AAChC,qBAAe,YAAY;;;IAG/B,aAAU;IACV,SAAQ;IACR,MAAK;IACL,OAAM;IACN,cAAW;cACZ;IAEQ,CAAA;GACT,iBAAA,GAAA,kBAAA,KAACA,mBAAAA,QAAD;IACE,IAAG;IACH,UAAW,gBAAgB,cAAc,CAAC,cAAe;IACzD,eAAe;AACb,SAAI,gBAAgB,cAAc,YAAY;MAC5C,MAAM,cAAc,cAAc;AAClC,sBAAgB,YAAY;AAC5B,0BAAoB,YAAY;AAChC,qBAAe,YAAY;;;IAG/B,aAAU;IACV,SAAQ;IACR,MAAK;IACL,OAAM;IACN,cAAW;cACZ;IAEQ,CAAA;GACS;;;;;ACxIxB,MAAM,WAAW,CAAA,GAAA,kBAAA,SAAO,MAAM;aACjBC,uBAAAA,QAAQ,GAAG;;;;AAKxB,MAAM,QAAQ,kBAAA,QAAO,KAAK;;;;SAIjBA,uBAAAA,QAAQ,GAAG;aACPA,uBAAAA,QAAQ,GAAG;;AAQM,CAAA,GAAA,kBAAA,SAAO,MAAM;eAC5BA,uBAAAA,QAAQ,GAAG;WACfC,uBAAAA,MAAM,cAAc;;;KAG1B,EAAE,iBAAiB,qBAAqB;AACzC,KAAI,oBAAoB,eACtB,QAAO;UACHC,uBAAAA,WAAW,eAAe;;;EAIhC;;;;;;AAaJ,MAAM,oBAAoB,EACxB,UACA,iBACA,0BAC2B;CAE3B,MAAM,YAAY,CAChB,GAAG,iBACH,GAAI,gBAAgB,SAAS,SAAS,GAAG,EAAE,GAAG,CAAC,SAAS,CACzD,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAEvB,QACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;EAAU,aAAU;YAClB,iBAAA,GAAA,kBAAA,MAAC,OAAD,EAAA,UAAA,CAAO,mBAEL,iBAAA,GAAA,kBAAA,KAACC,eAAAA,QAAD;GACE,OAAO,SAAS,UAAU;GAC1B,gBAAgB,QAAQ,oBAAoB,OAAO,IAAI,CAAC;GACxD,MAAK;aAEJ,UAAU,KAAK,SACd,iBAAA,GAAA,kBAAA,KAACC,eAAAA,QAAD;IAAmB,OAAO,KAAK,UAAU;cACtC;IACM,EAFI,KAEJ,CACT;GACK,CAAA,CACH,EAAA,CAAA;EACC,CAAA;;;;AClEf,MAAM,YAAY;AAElB,MAAM,YAAY,CAAA,GAAA,kBAAA,SAAO,MAAM;;;;;AAM/B,MAAa,iBAAiB,CAAA,GAAA,kBAAA,SAAO,MAAM;;;;WAIhCC,uBAAAA,MAAM,YAAY;;AAkB7B,MAAM,cAAc,EAClB,UACA,kBAAkB,2BAClB,kBACA,qBACA,qBACA,WACA,uBAAuB,MACvB,mBACqB;AACrB,KAAI,CAAC,oBAAoB,CAAC,SACxB,QAAO,iBAAA,GAAA,kBAAA,KAAC,OAAD,EAAO,CAAA;CAGhB,MAAM,EACJ,gBAAgB,aAChB,eAAe,YACf,eAAe,YACf,eAAe,eACb;CAKJ,MAAM,oBAAoB,cAAc,cAAc,YAAY,SAAS;CAE3E,MAAM,gBAAgB,aAClB,cAAc,WACd,KAAK,IAAI,cAAc,UAAU,WAAW;CAChD,MAAM,iBAAiB,YAAY,cAAc,KAAK;AAEtD,QACE,iBAAA,GAAA,kBAAA,MAAC,WAAD;EAAW,MAAK;EAAa,cAAW;YAAxC,CACG,wBACC,iBAAA,GAAA,kBAAA,KAAC,kBAAD;GACY;GACO;GACI;GACrB,CAAA,EAEH,aAAa,KACZ,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,MAAC,OAAD,EAAA,UAAA;GAAK;GACM;GAAe;GAAE;GAAc;GAAK;GAAkB;GAC3D,EAAA,CAAA,EACN,iBAAA,GAAA,kBAAA,KAAC,gBAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,cAAD;GACoB;GACG;GACV;GACG;GACd,CAAA,EACa,CAAA,CAChB,EAAA,CAAA,CAEK;;;;;AC3FhB,IAAA,qBAAe"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination-F8ofIWnG.mjs","names":[],"sources":["../components/Pagination/constants.ts","../components/Pagination/PageSelector.tsx","../components/Pagination/PageSizeSelector.tsx","../components/Pagination/Pagination.tsx","../components/Pagination/index.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 300];\nexport const MIN_PAGE_SIZE = 10;\n","import { debounce } from 'lodash/fp';\nimport { useEffect, useMemo, useState } from 'react';\nimport styled from 'styled-components';\n\nimport Button from '@persona/design-system/components/Button';\nimport { Input } from '@persona/design-system/components/Input';\nimport { HStack } from '@persona/design-system/components/Stack';\nimport { Spacing } from '@persona/design-tokens';\n\nimport type { PaginationParams } from './types';\n\n// After a certain limit, it no longer makes sense for someone\n// to jump to the last page. Deep paging has performance limitations.\nexport const PAGE_LIMIT_BEFORE_SCROLL_MODE = 100;\n\nconst PageSelectorStack = styled(HStack).attrs({ justify: 'flex-end' })`\n padding: ${Spacing[2]};\n`;\n\nexport const PageInput = styled(HStack).attrs({ align: 'center' })`\n white-space: nowrap;\n`;\n\ninterface PageSelectorProps {\n paginationParams: PaginationParams;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n /**\n * Called with the new page number after the page changes (next, prev, or\n * typed input). Lets the consumer react to page changes -- e.g. scroll the\n * page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n}\n\nexport default function PageSelector({\n paginationParams,\n handlePageLinkClick,\n isLoading,\n onPageChange,\n}: PageSelectorProps) {\n const {\n 'current-page': currentPage,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams ?? {};\n const [selectedPage, setSelectedPage] = useState<number | undefined>(currentPage);\n\n // We don't use useDebounced to avoid function object reference issues.\n const handlePageLinkClickDebounced = useMemo(\n () => debounce(500, handlePageLinkClick),\n [handlePageLinkClick],\n );\n\n // Keep input state synced to pagination state when other user action changes\n // pagination state.\n useEffect(() => {\n if (currentPage != null) {\n setSelectedPage(currentPage);\n }\n }, [currentPage]);\n\n if (!paginationParams) {\n return <div />;\n }\n\n return (\n <PageSelectorStack data-test='pagination__page-selector' id='pagination__page-selector'>\n <PageInput>\n {totalPages < PAGE_LIMIT_BEFORE_SCROLL_MODE && !lowerBound ? (\n <Input\n aria-label='Go to page number'\n size='sm'\n inputSize={2}\n onChange={(e) => {\n const value = e.target.valueAsNumber;\n if (Number.isNaN(value)) {\n setSelectedPage(undefined);\n } else {\n // Setting unbounded value feels smoother as the value is not corrected until after the fetch via useEffect.\n setSelectedPage(value);\n const boundedValue = Math.min(Math.max(e.target.valueAsNumber, 1), totalPages);\n handlePageLinkClickDebounced(boundedValue);\n onPageChange?.(boundedValue);\n }\n }}\n onBlur={(e) => {\n // Fill blank value on blur.\n if (Number.isNaN(e.target.valueAsNumber)) {\n setSelectedPage(currentPage);\n }\n }}\n min={1}\n max={totalPages}\n type='number'\n disabled={isLoading}\n value={selectedPage ?? ''}\n />\n ) : (\n currentPage + ' '\n )}\n of {lowerBound ? 'many' : totalPages} pages\n </PageInput>\n <Button\n id='pagination__page-selector--left'\n disabled={currentPage === 1 || isLoading}\n onClick={() => {\n if (currentPage !== 1) {\n const prevPageNum = currentPage - 1;\n setSelectedPage(prevPageNum);\n handlePageLinkClick(prevPageNum);\n onPageChange?.(prevPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-left'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label='Previous page'\n >\n Prev\n </Button>\n <Button\n id='pagination__page-selector--right'\n disabled={(currentPage === totalPages && !lowerBound) || isLoading}\n onClick={() => {\n if (currentPage !== totalPages || lowerBound) {\n const nextPageNum = currentPage + 1;\n setSelectedPage(nextPageNum);\n handlePageLinkClick(nextPageNum);\n onPageChange?.(nextPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-right'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label='Next page'\n >\n Next\n </Button>\n </PageSelectorStack>\n );\n}\n","import styled from 'styled-components';\n\nimport Select, { Option } from '@persona/design-system/components/Select';\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nconst Selector = styled('div')`\n padding: ${Spacing[2]};\n display: flex;\n justify-content: flex-end;\n`;\n\nconst Label = styled.label`\n display: flex;\n align-items: center;\n white-space: nowrap;\n gap: ${Spacing[2]};\n padding: ${Spacing[2]};\n`;\n\ninterface PageSizeOptionProps {\n currentPageSize: number;\n pageSizeOption: number;\n}\n\nexport const PageSizeOption = styled('div')<PageSizeOptionProps>`\n padding: 0 ${Spacing[1]};\n color: ${Color.PrimaryPurple};\n cursor: pointer;\n\n ${({ currentPageSize, pageSizeOption }) => {\n if (currentPageSize === pageSizeOption) {\n return `\n ${Typography.TextMediumBold};\n text-decoration: underline;\n `;\n }\n }};\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\ninterface PageSizeSelectorProps {\n pageSize: number;\n pageSizeOptions: number[];\n handlePageSizeClick: (pageSize: number) => void;\n}\n\nconst PageSizeSelector = ({\n pageSize,\n pageSizeOptions,\n handlePageSizeClick,\n}: PageSizeSelectorProps) => {\n // Add pageSize to selector just in case it isn't part of the options so UI doesn't look weird\n const pageSizes = [\n ...pageSizeOptions,\n ...(pageSizeOptions.includes(pageSize) ? [] : [pageSize]),\n ].sort((a, b) => a - b);\n\n return (\n <Selector data-test='pagination__page-size-selector'>\n <Label>\n Items per page:\n <Select\n value={pageSize.toString()}\n onValueChange={(val) => handlePageSizeClick(Number(val))}\n size='sm'\n >\n {pageSizes.map((size) => (\n <Option key={size} value={size.toString()}>\n {size}\n </Option>\n ))}\n </Select>\n </Label>\n </Selector>\n );\n};\n\nexport default PageSizeSelector;\n","import styled from 'styled-components';\n\nimport { Color } from '@persona/design-tokens';\n\nimport { DEFAULT_PAGE_SIZE_OPTIONS } from './constants';\nimport PageSelector from './PageSelector';\nimport PageSizeSelector from './PageSizeSelector';\nimport type { PaginationParams } from './types';\n\n// NB: this is configured in config/initializers/kaminari.rb\nconst MAX_PAGES = 100;\n\nconst Container = styled('nav')`\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\n\nexport const PaginationInfo = styled('div')`\n display: flex;\n align-items: center;\n\n color: ${Color.TextPrimary};\n`;\n\ninterface PaginationProps {\n pageSize?: number;\n pageSizeOptions?: number[];\n paginationParams?: PaginationParams;\n handlePageSizeClick: (pageSize: number) => void;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n showPageSizeSelector?: boolean;\n /**\n * Called with the new page number after the page changes. Lets the consumer\n * react to page changes -- e.g. scroll the page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n}\n\nconst Pagination = ({\n pageSize,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationParams,\n handlePageSizeClick,\n handlePageLinkClick,\n isLoading,\n showPageSizeSelector = true,\n onPageChange,\n}: PaginationProps) => {\n if (!paginationParams || !pageSize) {\n return <div />;\n }\n\n const {\n 'current-page': currentPage,\n 'total-count': totalCount,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams;\n\n // If the total number of pages is the same as MAX_PAGES, we guess that the total number of\n // items might be limited by max pages, and that the total could change based on page size.\n // To limit user confusion here, we use 'many' instead of a specific number.\n const totalCountDisplay = lowerBound || totalPages >= MAX_PAGES ? 'many' : totalCount;\n\n const lastItemIndex = lowerBound\n ? currentPage * pageSize\n : Math.min(currentPage * pageSize, totalCount);\n const firstItemIndex = pageSize * (currentPage - 1) + 1;\n\n return (\n <Container role='navigation' aria-label='pagination'>\n {showPageSizeSelector && (\n <PageSizeSelector\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n handlePageSizeClick={handlePageSizeClick}\n />\n )}\n {totalCount > 0 && (\n <>\n <div>\n Showing {firstItemIndex}-{lastItemIndex} of {totalCountDisplay} items\n </div>\n <PaginationInfo>\n <PageSelector\n paginationParams={paginationParams}\n handlePageLinkClick={handlePageLinkClick}\n isLoading={isLoading}\n onPageChange={onPageChange}\n />\n </PaginationInfo>\n </>\n )}\n </Container>\n );\n};\n\nexport default Pagination;\n","import Pagination from './Pagination';\n\nexport { default as PageSelector, PAGE_LIMIT_BEFORE_SCROLL_MODE } from './PageSelector';\nexport * from './constants';\nexport default Pagination;\n"],"mappings":"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"}
|