@servicetitan/anvil2 3.0.7 → 3.0.9
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 +42 -0
- package/dist/{AiMark-BXL0sWIV.js → AiMark-CS6MvraM.js} +5 -4
- package/dist/{AiMark-BXL0sWIV.js.map → AiMark-CS6MvraM.js.map} +1 -1
- package/dist/AiMark.js +1 -1
- package/dist/{Alert-BNH0UD2s.js → Alert-CNDLoh6b.js} +2 -2
- package/dist/{Alert-BNH0UD2s.js.map → Alert-CNDLoh6b.js.map} +1 -1
- package/dist/Alert.js +1 -1
- package/dist/{AnvilProvider-J9DjoJiB.js → AnvilProvider-BFK29dL5.js} +3 -2
- package/dist/{AnvilProvider-J9DjoJiB.js.map → AnvilProvider-BFK29dL5.js.map} +1 -1
- package/dist/AnvilProvider.js +1 -1
- package/dist/{Avatar-FDHyqiCy.js → Avatar-Bl-Dxbhf.js} +7 -2
- package/dist/Avatar-Bl-Dxbhf.js.map +1 -0
- package/dist/{Avatar-B_cRQqKR.js → Avatar-CdAIJ5VK.js} +2 -2
- package/dist/{Avatar-B_cRQqKR.js.map → Avatar-CdAIJ5VK.js.map} +1 -1
- package/dist/Avatar.js +2 -2
- package/dist/{Breadcrumbs-Bzxbdu-S.js → Breadcrumbs--Xt6l_2L.js} +2 -2
- package/dist/{Breadcrumbs-Bzxbdu-S.js.map → Breadcrumbs--Xt6l_2L.js.map} +1 -1
- package/dist/Breadcrumbs.js +1 -1
- package/dist/{Calendar-DS5eWpGF.js → Calendar-5mAxtdNh.js} +2 -2
- package/dist/{Calendar-DS5eWpGF.js.map → Calendar-5mAxtdNh.js.map} +1 -1
- package/dist/{Calendar-BYNFAWpZ.js → Calendar-rITorBvD.js} +5 -3
- package/dist/{Calendar-BYNFAWpZ.js.map → Calendar-rITorBvD.js.map} +1 -1
- package/dist/Calendar.js +2 -2
- package/dist/{Checkbox-BeIzx_ZX.js → Checkbox-BYWhkYoK.js} +2 -2
- package/dist/{Checkbox-BeIzx_ZX.js.map → Checkbox-BYWhkYoK.js.map} +1 -1
- package/dist/{Checkbox-BB3BDJsK.js → Checkbox-DTzoDcJl.js} +3 -3
- package/dist/{Checkbox-BB3BDJsK.js.map → Checkbox-DTzoDcJl.js.map} +1 -1
- package/dist/Checkbox.js +1 -1
- package/dist/{Chip-D2k5X_wX.js → Chip-CyMNyEPR.js} +3 -3
- package/dist/{Chip-D2k5X_wX.js.map → Chip-CyMNyEPR.js.map} +1 -1
- package/dist/Chip.js +1 -1
- package/dist/Combobox.js +1 -1
- package/dist/{DataTable-E8z0H8c7.js → DataTable-FG0Kjx0d.js} +1206 -445
- package/dist/DataTable-FG0Kjx0d.js.map +1 -0
- package/dist/DataTable.css +301 -233
- package/dist/{DateFieldRange-BN_uIvHI.js → DateFieldRange-BUug1tUy.js} +4 -4
- package/dist/{DateFieldRange-BN_uIvHI.js.map → DateFieldRange-BUug1tUy.js.map} +1 -1
- package/dist/DateFieldRange.js +1 -1
- package/dist/{DateFieldSingle-h3YkdwPo.js → DateFieldSingle-DR7faQGD.js} +4 -4
- package/dist/{DateFieldSingle-h3YkdwPo.js.map → DateFieldSingle-DR7faQGD.js.map} +1 -1
- package/dist/DateFieldSingle.js +1 -1
- package/dist/{DateFieldYearless-m_Hl2gMY.js → DateFieldYearless-7MFcR7L6.js} +4 -4
- package/dist/{DateFieldYearless-m_Hl2gMY.js.map → DateFieldYearless-7MFcR7L6.js.map} +1 -1
- package/dist/DateFieldYearless.js +1 -1
- package/dist/{DateFieldYearlessRange-DNqSTBDr.js → DateFieldYearlessRange-DGtdyISH.js} +3 -3
- package/dist/{DateFieldYearlessRange-DNqSTBDr.js.map → DateFieldYearlessRange-DGtdyISH.js.map} +1 -1
- package/dist/DateFieldYearlessRange.js +1 -1
- package/dist/{DaysOfTheWeek-D58z_eF3.js → DaysOfTheWeek-C7oN9nIe.js} +3 -3
- package/dist/{DaysOfTheWeek-D58z_eF3.js.map → DaysOfTheWeek-C7oN9nIe.js.map} +1 -1
- package/dist/DaysOfTheWeek.js +1 -1
- package/dist/{Dialog-CvYSMvfD.js → Dialog-dE9c90iR.js} +3 -3
- package/dist/{Dialog-CvYSMvfD.js.map → Dialog-dE9c90iR.js.map} +1 -1
- package/dist/Dialog.js +1 -1
- package/dist/{Divider-CxtTyw8_.js → Divider-Dz27DFuE.js} +17 -17
- package/dist/{Divider-CxtTyw8_.js.map → Divider-Dz27DFuE.js.map} +1 -1
- package/dist/Divider.css +21 -24
- package/dist/Divider.js +1 -1
- package/dist/Dnd.js +2 -2
- package/dist/{DndHandleButton-CHTOYRlq.js → DndHandleButton-BW9xLWQm.js} +2 -4
- package/dist/DndHandleButton-BW9xLWQm.js.map +1 -0
- package/dist/DndSort.js +2 -2
- package/dist/{Drawer-s2y0xcgV.js → Drawer-Dk0MsaOU.js} +3 -3
- package/dist/{Drawer-s2y0xcgV.js.map → Drawer-Dk0MsaOU.js.map} +1 -1
- package/dist/Drawer.js +1 -1
- package/dist/DrillDown.js +1 -1
- package/dist/{EditCard-B25pj0Jx.js → EditCard-DV2N7zWr.js} +2 -2
- package/dist/{EditCard-B25pj0Jx.js.map → EditCard-DV2N7zWr.js.map} +1 -1
- package/dist/EditCard.js +1 -1
- package/dist/{FieldLabel-D1qPAGtB.js → FieldLabel-VVn8GR64.js} +3 -3
- package/dist/{FieldLabel-D1qPAGtB.js.map → FieldLabel-VVn8GR64.js.map} +1 -1
- package/dist/FieldLabel.js +1 -1
- package/dist/{FilterBar-B4ZAs73g.js → FilterBar-B3c_VGDk.js} +6 -5
- package/dist/{FilterBar-B4ZAs73g.js.map → FilterBar-B3c_VGDk.js.map} +1 -1
- package/dist/FilterBar.js +1 -1
- package/dist/{InputMask-BDl09V4u.js → InputMask-VBHWGZGN.js} +3 -3
- package/dist/{InputMask-BDl09V4u.js.map → InputMask-VBHWGZGN.js.map} +1 -1
- package/dist/InputMask.js +1 -1
- package/dist/{ListView-DO5psxd4.js → ListView-BUrfz75g.js} +2 -2
- package/dist/{ListView-DO5psxd4.js.map → ListView-BUrfz75g.js.map} +1 -1
- package/dist/ListView.js +1 -1
- package/dist/{Listbox-CvQHBFWb.js → Listbox-CRY-0BkS.js} +2 -2
- package/dist/{Listbox-CvQHBFWb.js.map → Listbox-CRY-0BkS.js.map} +1 -1
- package/dist/Listbox.js +1 -1
- package/dist/{Menu-W0c-xKdX.js → Menu-DNJ0YqjA.js} +11 -7
- package/dist/Menu-DNJ0YqjA.js.map +1 -0
- package/dist/Menu.js +1 -1
- package/dist/MenuFooter-CrsZdXvN.js +115 -0
- package/dist/MenuFooter-CrsZdXvN.js.map +1 -0
- package/dist/MultiSelectField.js +1 -1
- package/dist/{MultiSelectFieldSync-CXX2F0ru.js → MultiSelectFieldSync-CzHj9Qvy.js} +8 -53
- package/dist/MultiSelectFieldSync-CzHj9Qvy.js.map +1 -0
- package/dist/MultiSelectMenu.js +1 -1
- package/dist/{MultiSelectMenuSync-EKtvlL62.js → MultiSelectMenuSync-BGcrYjby.js} +9 -76
- package/dist/MultiSelectMenuSync-BGcrYjby.js.map +1 -0
- package/dist/{NumberField-BymFZhIJ.js → NumberField-bgYX7JGs.js} +3 -3
- package/dist/{NumberField-BymFZhIJ.js.map → NumberField-bgYX7JGs.js.map} +1 -1
- package/dist/NumberField.js +1 -1
- package/dist/{Page-C2_Hm27h.js → Page-BSHydn4p.js} +9 -9
- package/dist/{Page-C2_Hm27h.js.map → Page-BSHydn4p.js.map} +1 -1
- package/dist/Page.js +1 -1
- package/dist/{Pagination-Bmd4JORe.js → Pagination-CAeyJ7Pl.js} +192 -26
- package/dist/Pagination-CAeyJ7Pl.js.map +1 -0
- package/dist/Pagination.css +4 -2
- package/dist/Pagination.js +1 -1
- package/dist/{Popover-8mTJoMy7.js → Popover-Cq5tirFz.js} +11 -5
- package/dist/Popover-Cq5tirFz.js.map +1 -0
- package/dist/Popover.js +1 -1
- package/dist/{ProgressBar-C1CkQHV5.js → ProgressBar-ByR50ln7.js} +2 -2
- package/dist/{ProgressBar-C1CkQHV5.js.map → ProgressBar-ByR50ln7.js.map} +1 -1
- package/dist/ProgressBar.js +1 -1
- package/dist/{Radio-BcHMk8dD.js → Radio-CPuctRpl.js} +2 -2
- package/dist/{Radio-BcHMk8dD.js.map → Radio-CPuctRpl.js.map} +1 -1
- package/dist/{Radio-D5WyQN2i.js → Radio-WlsZFRzX.js} +3 -3
- package/dist/{Radio-D5WyQN2i.js.map → Radio-WlsZFRzX.js.map} +1 -1
- package/dist/Radio.js +1 -1
- package/dist/{RichTextEditor-DstVbYch.js → RichTextEditor-FSWAVmTe.js} +80 -44
- package/dist/RichTextEditor-FSWAVmTe.js.map +1 -0
- package/dist/RichTextEditor.js +1 -1
- package/dist/{SavedFiltersButton-2qba2Cgu.js → SavedFiltersButton-Cr829guv.js} +12 -11
- package/dist/SavedFiltersButton-Cr829guv.js.map +1 -0
- package/dist/SavedFiltersButton.js +1 -1
- package/dist/{SelectCard-BN-LI14f.js → SelectCard-DLWLHi_i.js} +3 -3
- package/dist/{SelectCard-BN-LI14f.js.map → SelectCard-DLWLHi_i.js.map} +1 -1
- package/dist/SelectCard.js +1 -1
- package/dist/SelectField.js +1 -1
- package/dist/{SelectFieldLabel-UbQT7fDD.js → SelectFieldLabel-vemffdmu.js} +2 -2
- package/dist/{SelectFieldLabel-UbQT7fDD.js.map → SelectFieldLabel-vemffdmu.js.map} +1 -1
- package/dist/{SelectFieldSync-DykGkR_w.js → SelectFieldSync-C65VFWGm.js} +5 -4
- package/dist/{SelectFieldSync-DykGkR_w.js.map → SelectFieldSync-C65VFWGm.js.map} +1 -1
- package/dist/SelectMenu.js +1 -1
- package/dist/{SelectMenuSync-DTQ8Ofoz.js → SelectMenuSync-CF49L12-.js} +6 -4
- package/dist/{SelectMenuSync-DTQ8Ofoz.js.map → SelectMenuSync-CF49L12-.js.map} +1 -1
- package/dist/{SelectOptions-DVSOJwRy.js → SelectOptions-C7skDFj2.js} +2 -2
- package/dist/{SelectOptions-DVSOJwRy.js.map → SelectOptions-C7skDFj2.js.map} +1 -1
- package/dist/{SelectTrigger-CHk0KO-P.js → SelectTrigger-BbneVXMz.js} +3 -3
- package/dist/{SelectTrigger-CHk0KO-P.js.map → SelectTrigger-BbneVXMz.js.map} +1 -1
- package/dist/SelectTrigger.js +1 -1
- package/dist/{SelectTriggerBase-B2S5SOZr.js → SelectTriggerBase-BjIOERXr.js} +3 -3
- package/dist/{SelectTriggerBase-B2S5SOZr.js.map → SelectTriggerBase-BjIOERXr.js.map} +1 -1
- package/dist/{Switch-onmiKoRd.js → Switch-B6bKmpwN.js} +3 -3
- package/dist/{Switch-onmiKoRd.js.map → Switch-B6bKmpwN.js.map} +1 -1
- package/dist/Switch.js +1 -1
- package/dist/Table.js +1 -1
- package/dist/{Text-BTzgTpqu.js → Text-w2gWn4K6.js} +2 -2
- package/dist/{Text-BTzgTpqu.js.map → Text-w2gWn4K6.js.map} +1 -1
- package/dist/Text.js +1 -1
- package/dist/{TextField-WTYZJlX3.js → TextField-BQsCh5Nb.js} +2 -2
- package/dist/{TextField-WTYZJlX3.js.map → TextField-BQsCh5Nb.js.map} +1 -1
- package/dist/{TextField-rVfctM1E.js → TextField-DJ3gEIP6.js} +3 -3
- package/dist/{TextField-rVfctM1E.js.map → TextField-DJ3gEIP6.js.map} +1 -1
- package/dist/TextField.js +1 -1
- package/dist/{Textarea-PXjppEQ6.js → Textarea-BK4Vf84K.js} +3 -3
- package/dist/{Textarea-PXjppEQ6.js.map → Textarea-BK4Vf84K.js.map} +1 -1
- package/dist/Textarea.js +1 -1
- package/dist/{ThemeProvider-D4KdGCaP.js → ThemeProvider-BC6wbuLU.js} +4 -9
- package/dist/{ThemeProvider-D4KdGCaP.js.map → ThemeProvider-BC6wbuLU.js.map} +1 -1
- package/dist/ThemeProvider.js +1 -1
- package/dist/ThemeProvider.module-D9pNGYjP.js +8 -0
- package/dist/ThemeProvider.module-D9pNGYjP.js.map +1 -0
- package/dist/{TimeField-BJPXIv6W.js → TimeField-B4IW2B_o.js} +4 -4
- package/dist/{TimeField-BJPXIv6W.js.map → TimeField-B4IW2B_o.js.map} +1 -1
- package/dist/TimeField.js +1 -1
- package/dist/Toast.js +2 -2
- package/dist/{Toaster-CoChsMD0.js → Toaster-BGY2IzF5.js} +53 -48
- package/dist/Toaster-BGY2IzF5.js.map +1 -0
- package/dist/{Toaster-DXLc86VD.js → Toaster-DTF9qnTy.js} +2 -2
- package/dist/{Toaster-DXLc86VD.js.map → Toaster-DTF9qnTy.js.map} +1 -1
- package/dist/{Toolbar-Bt3kShho.js → Toolbar-DObrJ_S5.js} +5 -4
- package/dist/{Toolbar-Bt3kShho.js.map → Toolbar-DObrJ_S5.js.map} +1 -1
- package/dist/{Toolbar-DaUKbbsL.js → Toolbar-DRJGKk8D.js} +6 -5
- package/dist/{Toolbar-DaUKbbsL.js.map → Toolbar-DRJGKk8D.js.map} +1 -1
- package/dist/Toolbar.js +2 -2
- package/dist/{ToolbarButtonToggle-BPu81Wuv.js → ToolbarButtonToggle-BCKgA8FE.js} +2 -2
- package/dist/{ToolbarButtonToggle-BPu81Wuv.js.map → ToolbarButtonToggle-BCKgA8FE.js.map} +1 -1
- package/dist/{Tooltip-yr1D06BE.js → Tooltip-DqS6xDUf.js} +27 -25
- package/dist/Tooltip-DqS6xDUf.js.map +1 -0
- package/dist/Tooltip.js +1 -1
- package/dist/TreeSelectField.d.ts +1 -0
- package/dist/TreeSelectField.js +2 -0
- package/dist/TreeSelectField.js.map +1 -0
- package/dist/TreeSelectFieldSync-Do5ffU0b.js +609 -0
- package/dist/TreeSelectFieldSync-Do5ffU0b.js.map +1 -0
- package/dist/TreeSelectFieldSync.css +173 -0
- package/dist/TreeSelectMenu.d.ts +1 -0
- package/dist/TreeSelectMenu.js +2 -0
- package/dist/TreeSelectMenu.js.map +1 -0
- package/dist/TreeSelectMenuSync-s05Ly6lj.js +413 -0
- package/dist/TreeSelectMenuSync-s05Ly6lj.js.map +1 -0
- package/dist/{YearlessDateInputWithPicker-BIcVgz-J.js → YearlessDateInputWithPicker-BHfFjCqE.js} +2 -2
- package/dist/{YearlessDateInputWithPicker-BIcVgz-J.js.map → YearlessDateInputWithPicker-BHfFjCqE.js.map} +1 -1
- package/dist/beta.js +15 -13
- package/dist/beta.js.map +1 -1
- package/dist/confirmationTypes-CG7xl50f.js +75 -0
- package/dist/confirmationTypes-CG7xl50f.js.map +1 -0
- package/dist/drag_indicator-BRHAPLSJ.js +6 -0
- package/dist/drag_indicator-BRHAPLSJ.js.map +1 -0
- package/dist/{filter-state-Bx3aYS1r.js → filter-state-CE8t3-Q7.js} +324 -84
- package/dist/filter-state-CE8t3-Q7.js.map +1 -0
- package/dist/{floating-ui.react-dom-CHrYz13o.js → floating-ui.react-dom-BIKT960u.js} +2 -2
- package/dist/{floating-ui.react-dom-CHrYz13o.js.map → floating-ui.react-dom-BIKT960u.js.map} +1 -1
- package/dist/{index-CukEaIHB.js → index-CKdC7x1S.js} +2 -2
- package/dist/{index-CukEaIHB.js.map → index-CKdC7x1S.js.map} +1 -1
- package/dist/{index-DVYRUKtW.js → index-DN_iqxhF.js} +79 -109
- package/dist/{index-DVYRUKtW.js.map → index-DN_iqxhF.js.map} +1 -1
- package/dist/index.js +44 -44
- package/dist/keyboard_arrow_left-CiE1n99w.js +6 -0
- package/dist/keyboard_arrow_left-CiE1n99w.js.map +1 -0
- package/dist/keyboard_arrow_right-DMloHg_F.js +6 -0
- package/dist/keyboard_arrow_right-DMloHg_F.js.map +1 -0
- package/dist/portalScopeClassNames-jlZkdug_.js +7 -0
- package/dist/portalScopeClassNames-jlZkdug_.js.map +1 -0
- package/dist/src/beta/components/FilterBar/FilterTextInput.d.ts +29 -0
- package/dist/src/beta/components/FilterBar/index.d.ts +1 -1
- package/dist/src/beta/components/FilterBar/internal/adapters/asyncTree.d.ts +6 -0
- package/dist/src/beta/components/FilterBar/internal/adapters/textInput.d.ts +3 -0
- package/dist/src/beta/components/FilterBar/internal/adapters/tree.d.ts +6 -0
- package/dist/src/beta/components/FilterBar/internal/adapters/types.d.ts +4 -1
- package/dist/src/beta/components/FilterBar/internal/types.d.ts +69 -12
- package/dist/src/beta/components/FilterBar/internal/utils/test.d.ts +4 -1
- package/dist/src/beta/components/Table/DataTable/DataTable.d.ts +8 -31
- package/dist/src/beta/components/Table/DataTable/internal/DataTableBody.d.ts +2 -19
- package/dist/src/beta/components/Table/DataTable/internal/DataTableBodyRow.d.ts +17 -13
- package/dist/src/beta/components/Table/DataTable/internal/context/focus/DTFocusContext.d.ts +1 -11
- package/dist/src/beta/components/Table/DataTable/internal/context/focus/useDTFocusDispatchContext.d.ts +0 -2
- package/dist/src/beta/components/Table/DataTable/internal/context/surface/DataTableSurfaceCoordinatorContext.d.ts +13 -0
- package/dist/src/beta/components/Table/DataTable/internal/context/surface/DataTableSurfaceCoordinatorProvider.d.ts +7 -0
- package/dist/src/beta/components/Table/DataTable/internal/context/surface/useDataTableSurfaceCoordinator.d.ts +1 -0
- package/dist/src/beta/components/Table/DataTable/internal/editable-cells/useCustomEditHelpers.d.ts +8 -6
- package/dist/src/beta/components/Table/DataTable/internal/useColumnOrder.d.ts +1 -0
- package/dist/src/beta/components/Table/createColumnHelper.d.ts +4 -2
- package/dist/src/beta/components/Table/formatters/htmlFormatter.d.ts +4 -2
- package/dist/src/beta/components/Table/formatters/htmlToMarkdown.d.ts +5 -2
- package/dist/src/beta/components/Table/formatters/markdownFormatter.d.ts +3 -2
- package/dist/src/beta/components/Table/types.d.ts +47 -30
- package/dist/src/beta/components/TreeSelectField/TreeSelectField.d.ts +68 -0
- package/dist/src/beta/components/TreeSelectField/TreeSelectFieldSync.d.ts +64 -0
- package/dist/src/beta/components/TreeSelectField/index.d.ts +3 -0
- package/dist/src/beta/components/TreeSelectField/internal/TreeContent.d.ts +31 -0
- package/dist/src/beta/components/TreeSelectField/internal/TreePanel.d.ts +56 -0
- package/dist/src/beta/components/TreeSelectField/internal/TreeRow.d.ts +56 -0
- package/dist/src/beta/components/TreeSelectField/internal/TreeSelectFieldInput.d.ts +82 -0
- package/dist/src/beta/components/TreeSelectField/internal/VirtualizedTreePanel.d.ts +57 -0
- package/dist/src/beta/components/TreeSelectField/internal/treeSync.d.ts +33 -0
- package/dist/src/beta/components/TreeSelectField/internal/treeUtils.d.ts +25 -0
- package/dist/src/beta/components/TreeSelectField/internal/types.d.ts +12 -0
- package/dist/src/beta/components/TreeSelectField/internal/useTree.d.ts +99 -0
- package/dist/src/beta/components/TreeSelectField/internal/useTreeCascade.d.ts +93 -0
- package/dist/src/beta/components/TreeSelectField/internal/useTreeKeyboard.d.ts +42 -0
- package/dist/src/beta/components/TreeSelectField/internal/useTreeLazyCascade.d.ts +56 -0
- package/dist/src/beta/components/TreeSelectField/internal/useTreeLoader.d.ts +58 -0
- package/dist/src/beta/components/TreeSelectField/stories/TreeSelectField.stories.data.d.ts +21 -0
- package/dist/src/beta/components/TreeSelectField/types.d.ts +124 -0
- package/dist/src/beta/components/TreeSelectMenu/TreeSelectMenu.d.ts +29 -0
- package/dist/src/beta/components/TreeSelectMenu/TreeSelectMenuSync.d.ts +65 -0
- package/dist/src/beta/components/TreeSelectMenu/index.d.ts +4 -0
- package/dist/src/beta/components/TreeSelectMenu/types.d.ts +103 -0
- package/dist/src/beta/components/index.d.ts +2 -0
- package/dist/src/components/Pagination/internal/Pagination.d.ts +1 -0
- package/dist/src/components/Pagination/internal/PaginationOverflowMenu.d.ts +12 -1
- package/dist/src/internal/components/Surface/Surface.d.ts +4 -0
- package/dist/src/internal/components/Surface/surfaceGeometry.d.ts +31 -0
- package/dist/src/internal/functions/portalScopeClassNames.d.ts +14 -0
- package/dist/src/internal/utils/arrayIdsEqual.d.ts +10 -0
- package/dist/src/internal/utils/index.d.ts +1 -0
- package/dist/{stripInlineMarkdown-C5DNxxwf.js → stripInlineMarkdown-C0bVmYgG.js} +2 -2
- package/dist/{stripInlineMarkdown-C5DNxxwf.js.map → stripInlineMarkdown-C0bVmYgG.js.map} +1 -1
- package/dist/{syncFilterUtils-BEKek64h.js → syncFilterUtils-CgHB-l6A.js} +35 -410
- package/dist/syncFilterUtils-CgHB-l6A.js.map +1 -0
- package/dist/syncFilterUtils.css +0 -180
- package/dist/treeSync-Cz3H08cr.js +1453 -0
- package/dist/treeSync-Cz3H08cr.js.map +1 -0
- package/dist/treeSync.css +40 -0
- package/dist/useAdaptiveView-CeYKH0Me.js +386 -0
- package/dist/useAdaptiveView-CeYKH0Me.js.map +1 -0
- package/dist/useAdaptiveView.css +181 -0
- package/dist/useChipLayout-BWZfKDgd.js +51 -0
- package/dist/useChipLayout-BWZfKDgd.js.map +1 -0
- package/dist/{useDrilldown-KZ9rRsXQ.js → useDrilldown-BJ2dHHKV.js} +2 -2
- package/dist/{useDrilldown-KZ9rRsXQ.js.map → useDrilldown-BJ2dHHKV.js.map} +1 -1
- package/dist/{useInfiniteCombobox-CknXmqlQ.js → useInfiniteCombobox-BqJm-CdN.js} +24 -24
- package/dist/useInfiniteCombobox-BqJm-CdN.js.map +1 -0
- package/dist/{useMenuInteraction-CpAOHSJu.js → useMenuInteraction-NEJXUD4I.js} +2 -114
- package/dist/useMenuInteraction-NEJXUD4I.js.map +1 -0
- package/dist/{useToggleSelection-B-Z80gy2.js → useToggleSelection-BGc5OiZF.js} +2 -2
- package/dist/{useToggleSelection-B-Z80gy2.js.map → useToggleSelection-BGc5OiZF.js.map} +1 -1
- package/package.json +5 -7
- package/dist/Avatar-FDHyqiCy.js.map +0 -1
- package/dist/DataTable-E8z0H8c7.js.map +0 -1
- package/dist/DndHandleButton-CHTOYRlq.js.map +0 -1
- package/dist/Menu-W0c-xKdX.js.map +0 -1
- package/dist/MultiSelectFieldSync-CXX2F0ru.js.map +0 -1
- package/dist/MultiSelectMenuSync-EKtvlL62.js.map +0 -1
- package/dist/Pagination-Bmd4JORe.js.map +0 -1
- package/dist/Popover-8mTJoMy7.js.map +0 -1
- package/dist/RichTextEditor-DstVbYch.js.map +0 -1
- package/dist/SavedFiltersButton-2qba2Cgu.js.map +0 -1
- package/dist/Toaster-CoChsMD0.js.map +0 -1
- package/dist/Tooltip-yr1D06BE.js.map +0 -1
- package/dist/filter-state-Bx3aYS1r.js.map +0 -1
- package/dist/keyboard_arrow_right-DZWNVytH.js +0 -8
- package/dist/keyboard_arrow_right-DZWNVytH.js.map +0 -1
- package/dist/syncFilterUtils-BEKek64h.js.map +0 -1
- package/dist/useInfiniteCombobox-CknXmqlQ.js.map +0 -1
- package/dist/useMenuInteraction-CpAOHSJu.js.map +0 -1
- /package/dist/{useMenuInteraction.css → MenuFooter.css} +0 -0
|
@@ -0,0 +1,1453 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect, useMemo, forwardRef } from 'react';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { S as Spinner } from './Spinner-B7tTWcP6.js';
|
|
4
|
+
import { T as Text } from './Text-w2gWn4K6.js';
|
|
5
|
+
import { c as cx } from './index-De1g9FRV.js';
|
|
6
|
+
import { I as Icon } from './Icon-feeG7gXA.js';
|
|
7
|
+
import { S as SvgKeyboardArrowRight } from './keyboard_arrow_right-DMloHg_F.js';
|
|
8
|
+
import { S as SvgKeyboardArrowDown } from './keyboard_arrow_down-C8WQ38p1.js';
|
|
9
|
+
import { b as OptionRow, c as OptionRowSideContent, d as OptionCheckbox, e as OptionContentArea } from './useAdaptiveView-CeYKH0Me.js';
|
|
10
|
+
import { u as useVirtualizer } from './index-DXeGMe23.js';
|
|
11
|
+
import { m as matchSorter } from './match-sorter.esm-CGAauEiU.js';
|
|
12
|
+
|
|
13
|
+
import './treeSync.css';function createLruCache(maxSize) {
|
|
14
|
+
const map = /* @__PURE__ */ new Map();
|
|
15
|
+
return {
|
|
16
|
+
get(key) {
|
|
17
|
+
if (!map.has(key)) return void 0;
|
|
18
|
+
const value = map.get(key);
|
|
19
|
+
map.delete(key);
|
|
20
|
+
map.set(key, value);
|
|
21
|
+
return value;
|
|
22
|
+
},
|
|
23
|
+
set(key, value) {
|
|
24
|
+
if (map.has(key)) {
|
|
25
|
+
map.delete(key);
|
|
26
|
+
} else if (map.size >= maxSize) {
|
|
27
|
+
const firstKey = map.keys().next().value;
|
|
28
|
+
if (firstKey !== void 0) map.delete(firstKey);
|
|
29
|
+
}
|
|
30
|
+
map.set(key, value);
|
|
31
|
+
},
|
|
32
|
+
has(key) {
|
|
33
|
+
return map.has(key);
|
|
34
|
+
},
|
|
35
|
+
delete(key) {
|
|
36
|
+
map.delete(key);
|
|
37
|
+
},
|
|
38
|
+
clear() {
|
|
39
|
+
map.clear();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function mergeChildren(nodes, parentId, children) {
|
|
44
|
+
return nodes.map((node) => {
|
|
45
|
+
if (node.id === parentId) {
|
|
46
|
+
return { ...node, children };
|
|
47
|
+
}
|
|
48
|
+
if (node.children && node.children.length > 0) {
|
|
49
|
+
return {
|
|
50
|
+
...node,
|
|
51
|
+
children: mergeChildren(node.children, parentId, children)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return node;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function useTreeLoader(options) {
|
|
58
|
+
const {
|
|
59
|
+
loadOptions,
|
|
60
|
+
cache: cacheConfig,
|
|
61
|
+
initialLoad = "auto",
|
|
62
|
+
debounceMs = 200
|
|
63
|
+
} = options;
|
|
64
|
+
const cacheEnabled = cacheConfig?.enabled !== false;
|
|
65
|
+
const cacheMaxSize = cacheConfig?.maxSize ?? 15;
|
|
66
|
+
const [nodes, setNodes] = useState([]);
|
|
67
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
68
|
+
const [isLoadingChildren, setIsLoadingChildren] = useState(/* @__PURE__ */ new Set());
|
|
69
|
+
const [ancestry, setAncestry] = useState(() => /* @__PURE__ */ new Map());
|
|
70
|
+
const recordAncestry = useCallback(
|
|
71
|
+
(parentId, children) => {
|
|
72
|
+
setAncestry((prev) => {
|
|
73
|
+
let changed = false;
|
|
74
|
+
const next = new Map(prev);
|
|
75
|
+
for (const child of children) {
|
|
76
|
+
if (next.get(child.id) !== parentId) {
|
|
77
|
+
next.set(child.id, parentId);
|
|
78
|
+
changed = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return changed ? next : prev;
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
[]
|
|
85
|
+
);
|
|
86
|
+
const hasOpenedRef = useRef(false);
|
|
87
|
+
const currentSearchRef = useRef("");
|
|
88
|
+
const searchCacheRef = useRef(
|
|
89
|
+
createLruCache(cacheMaxSize)
|
|
90
|
+
);
|
|
91
|
+
const childrenCacheRef = useRef(
|
|
92
|
+
createLruCache(cacheMaxSize)
|
|
93
|
+
);
|
|
94
|
+
const loadOptionsRef = useRef(loadOptions);
|
|
95
|
+
loadOptionsRef.current = loadOptions;
|
|
96
|
+
const loadRootSeqRef = useRef(0);
|
|
97
|
+
const loadRoot = useCallback(
|
|
98
|
+
async (searchValue, bypassCache = false) => {
|
|
99
|
+
currentSearchRef.current = searchValue;
|
|
100
|
+
hasOpenedRef.current = true;
|
|
101
|
+
const seq = ++loadRootSeqRef.current;
|
|
102
|
+
const cached = !bypassCache && cacheEnabled ? searchCacheRef.current.get(searchValue) : void 0;
|
|
103
|
+
if (cached !== void 0) {
|
|
104
|
+
setNodes(cached);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
setIsLoading(true);
|
|
108
|
+
try {
|
|
109
|
+
const result = await loadOptionsRef.current(searchValue, void 0);
|
|
110
|
+
if (seq !== loadRootSeqRef.current) return;
|
|
111
|
+
if (!bypassCache && cacheEnabled) {
|
|
112
|
+
searchCacheRef.current.set(searchValue, result);
|
|
113
|
+
}
|
|
114
|
+
setNodes(result);
|
|
115
|
+
} finally {
|
|
116
|
+
if (seq === loadRootSeqRef.current) {
|
|
117
|
+
setIsLoading(false);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
[cacheEnabled]
|
|
122
|
+
);
|
|
123
|
+
const debounceTimerRef = useRef(null);
|
|
124
|
+
const search = useCallback(
|
|
125
|
+
(searchValue) => {
|
|
126
|
+
if (debounceTimerRef.current !== null) {
|
|
127
|
+
clearTimeout(debounceTimerRef.current);
|
|
128
|
+
}
|
|
129
|
+
if (debounceMs === 0) {
|
|
130
|
+
void loadRoot(searchValue);
|
|
131
|
+
} else {
|
|
132
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
133
|
+
void loadRoot(searchValue);
|
|
134
|
+
}, debounceMs);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
[loadRoot, debounceMs]
|
|
138
|
+
);
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
return () => {
|
|
141
|
+
if (debounceTimerRef.current !== null) {
|
|
142
|
+
clearTimeout(debounceTimerRef.current);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}, []);
|
|
146
|
+
const loadChildren = useCallback(
|
|
147
|
+
async (parentNode) => {
|
|
148
|
+
const parentId = parentNode.id;
|
|
149
|
+
if (cacheEnabled) {
|
|
150
|
+
const cached = childrenCacheRef.current.get(parentId);
|
|
151
|
+
if (cached !== void 0) {
|
|
152
|
+
setNodes((prev) => mergeChildren(prev, parentId, cached));
|
|
153
|
+
recordAncestry(parentId, cached);
|
|
154
|
+
return cached;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
setIsLoadingChildren((prev) => {
|
|
158
|
+
const next = new Set(prev);
|
|
159
|
+
next.add(parentId);
|
|
160
|
+
return next;
|
|
161
|
+
});
|
|
162
|
+
try {
|
|
163
|
+
const result = await loadOptionsRef.current("", parentNode);
|
|
164
|
+
if (cacheEnabled) {
|
|
165
|
+
childrenCacheRef.current.set(parentId, result);
|
|
166
|
+
}
|
|
167
|
+
setNodes((prev) => mergeChildren(prev, parentId, result));
|
|
168
|
+
recordAncestry(parentId, result);
|
|
169
|
+
return result;
|
|
170
|
+
} finally {
|
|
171
|
+
setIsLoadingChildren((prev) => {
|
|
172
|
+
const next = new Set(prev);
|
|
173
|
+
next.delete(parentId);
|
|
174
|
+
return next;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
[cacheEnabled, recordAncestry]
|
|
179
|
+
);
|
|
180
|
+
const clearCache = useCallback(() => {
|
|
181
|
+
searchCacheRef.current.clear();
|
|
182
|
+
childrenCacheRef.current.clear();
|
|
183
|
+
setAncestry((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
184
|
+
}, []);
|
|
185
|
+
const invalidate = useCallback(() => {
|
|
186
|
+
searchCacheRef.current.clear();
|
|
187
|
+
childrenCacheRef.current.clear();
|
|
188
|
+
setAncestry((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
189
|
+
void loadRoot(currentSearchRef.current, true);
|
|
190
|
+
}, [loadRoot]);
|
|
191
|
+
const onOpen = useCallback(() => {
|
|
192
|
+
if (hasOpenedRef.current) return;
|
|
193
|
+
hasOpenedRef.current = true;
|
|
194
|
+
void loadRoot("");
|
|
195
|
+
}, [loadRoot]);
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
if (initialLoad === "immediate" || initialLoad === "auto") {
|
|
198
|
+
void loadRoot("");
|
|
199
|
+
}
|
|
200
|
+
}, []);
|
|
201
|
+
return {
|
|
202
|
+
nodes,
|
|
203
|
+
ancestry,
|
|
204
|
+
isLoading,
|
|
205
|
+
isLoadingChildren,
|
|
206
|
+
loadChildren,
|
|
207
|
+
search,
|
|
208
|
+
clearCache,
|
|
209
|
+
invalidate,
|
|
210
|
+
onOpen
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function buildNodeMap(nodes) {
|
|
215
|
+
const map = /* @__PURE__ */ new Map();
|
|
216
|
+
const visit = (list) => {
|
|
217
|
+
for (const node of list) {
|
|
218
|
+
map.set(node.id, node);
|
|
219
|
+
if (node.children) visit(node.children);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
visit(nodes);
|
|
223
|
+
return map;
|
|
224
|
+
}
|
|
225
|
+
function buildParentMap(nodes) {
|
|
226
|
+
const parents = /* @__PURE__ */ new Map();
|
|
227
|
+
const visit = (list, parentId) => {
|
|
228
|
+
for (const node of list) {
|
|
229
|
+
if (parentId !== void 0) parents.set(node.id, parentId);
|
|
230
|
+
if (node.children) visit(node.children, node.id);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
visit(nodes);
|
|
234
|
+
return parents;
|
|
235
|
+
}
|
|
236
|
+
function resolvePath(nodeId, parents) {
|
|
237
|
+
const path = [];
|
|
238
|
+
let current = parents.get(nodeId);
|
|
239
|
+
const seen = /* @__PURE__ */ new Set();
|
|
240
|
+
while (current !== void 0 && !seen.has(current)) {
|
|
241
|
+
seen.add(current);
|
|
242
|
+
path.unshift(current);
|
|
243
|
+
current = parents.get(current);
|
|
244
|
+
}
|
|
245
|
+
return path.length > 0 ? path : void 0;
|
|
246
|
+
}
|
|
247
|
+
function isBranch(node) {
|
|
248
|
+
return node.children !== void 0;
|
|
249
|
+
}
|
|
250
|
+
function expandBranchIds(ids, nodes) {
|
|
251
|
+
const nodeMap = buildNodeMap(nodes);
|
|
252
|
+
const expanded = new Set(ids);
|
|
253
|
+
const addDescendants = (node) => {
|
|
254
|
+
if (node.disabled) return;
|
|
255
|
+
expanded.add(node.id);
|
|
256
|
+
if (node.children) {
|
|
257
|
+
for (const child of node.children) {
|
|
258
|
+
addDescendants(child);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
for (const id of ids) {
|
|
263
|
+
const node = nodeMap.get(id);
|
|
264
|
+
if (node && isBranch(node)) {
|
|
265
|
+
addDescendants(node);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return expanded;
|
|
269
|
+
}
|
|
270
|
+
function computeCheckStates(nodes, value, selectionMode, valueConsistsOf, orphanAncestorIds = /* @__PURE__ */ new Set()) {
|
|
271
|
+
const rawIds = new Set(value.map((v) => v.id));
|
|
272
|
+
const checkedIdSet = selectionMode === "linked" && (valueConsistsOf === "BRANCH_PRIORITY" || valueConsistsOf === "ALL") ? expandBranchIds(rawIds, nodes) : rawIds;
|
|
273
|
+
const states = /* @__PURE__ */ new Map();
|
|
274
|
+
const computeNode = (node) => {
|
|
275
|
+
if (selectionMode === "independent" || selectionMode === "single" || valueConsistsOf === "BRANCH_ONLY") {
|
|
276
|
+
const state2 = checkedIdSet.has(node.id) ? "checked" : "unchecked";
|
|
277
|
+
states.set(node.id, state2);
|
|
278
|
+
if (node.children) {
|
|
279
|
+
for (const child of node.children) {
|
|
280
|
+
computeNode(child);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return state2;
|
|
284
|
+
}
|
|
285
|
+
const loadedChildren = Array.isArray(node.children) ? node.children : [];
|
|
286
|
+
const isUnloaded = node.children === null;
|
|
287
|
+
const isPartiallyLoaded = node.childCount !== void 0 && loadedChildren.length < node.childCount;
|
|
288
|
+
const underRepresented = isUnloaded || isPartiallyLoaded;
|
|
289
|
+
if (loadedChildren.length === 0 && !underRepresented) {
|
|
290
|
+
const state2 = checkedIdSet.has(node.id) ? "checked" : "unchecked";
|
|
291
|
+
states.set(node.id, state2);
|
|
292
|
+
return state2;
|
|
293
|
+
}
|
|
294
|
+
const childStates = loadedChildren.map(computeNode);
|
|
295
|
+
const hasAnyChecked = childStates.some(
|
|
296
|
+
(s) => s === "checked" || s === "indeterminate"
|
|
297
|
+
);
|
|
298
|
+
if (underRepresented) {
|
|
299
|
+
let state2;
|
|
300
|
+
if (checkedIdSet.has(node.id)) {
|
|
301
|
+
state2 = "checked";
|
|
302
|
+
} else if (hasAnyChecked || orphanAncestorIds.has(node.id)) {
|
|
303
|
+
state2 = "indeterminate";
|
|
304
|
+
} else {
|
|
305
|
+
state2 = "unchecked";
|
|
306
|
+
}
|
|
307
|
+
states.set(node.id, state2);
|
|
308
|
+
return state2;
|
|
309
|
+
}
|
|
310
|
+
const enabledChildren = loadedChildren.filter((c) => !c.disabled);
|
|
311
|
+
const enabledChildStates = enabledChildren.map(
|
|
312
|
+
(c) => states.get(c.id) ?? "unchecked"
|
|
313
|
+
);
|
|
314
|
+
const disabledChildren = loadedChildren.filter((c) => c.disabled);
|
|
315
|
+
const disabledChildStates = disabledChildren.map(
|
|
316
|
+
(c) => states.get(c.id) ?? "unchecked"
|
|
317
|
+
);
|
|
318
|
+
const allEnabledChecked = enabledChildren.length === 0 ? (
|
|
319
|
+
// No enabled children — only disabled children matter
|
|
320
|
+
disabledChildStates.every((s) => s === "checked")
|
|
321
|
+
) : enabledChildStates.every((s) => s === "checked");
|
|
322
|
+
let state;
|
|
323
|
+
if (allEnabledChecked && (enabledChildren.length > 0 || disabledChildStates.every((s) => s === "checked"))) {
|
|
324
|
+
state = "checked";
|
|
325
|
+
} else if (hasAnyChecked) {
|
|
326
|
+
state = "indeterminate";
|
|
327
|
+
} else {
|
|
328
|
+
state = "unchecked";
|
|
329
|
+
}
|
|
330
|
+
states.set(node.id, state);
|
|
331
|
+
return state;
|
|
332
|
+
};
|
|
333
|
+
for (const node of nodes) {
|
|
334
|
+
computeNode(node);
|
|
335
|
+
}
|
|
336
|
+
return states;
|
|
337
|
+
}
|
|
338
|
+
function computeValue(nodes, checkedIds, valueConsistsOf) {
|
|
339
|
+
const result = [];
|
|
340
|
+
const included = /* @__PURE__ */ new Set();
|
|
341
|
+
const allNonDisabledChildrenChecked = (node) => {
|
|
342
|
+
if (!node.children || node.children.length === 0) return false;
|
|
343
|
+
const nonDisabled = node.children.filter((c) => !c.disabled);
|
|
344
|
+
if (nonDisabled.length === 0) return false;
|
|
345
|
+
return nonDisabled.every((c) => {
|
|
346
|
+
if (!isBranch(c)) return checkedIds.has(c.id);
|
|
347
|
+
return allNonDisabledChildrenChecked(c) || checkedIds.has(c.id);
|
|
348
|
+
});
|
|
349
|
+
};
|
|
350
|
+
const toValue = (node, ancestors) => ({
|
|
351
|
+
id: node.id,
|
|
352
|
+
label: node.label,
|
|
353
|
+
extra: node.extra,
|
|
354
|
+
...ancestors.length > 0 ? { path: [...ancestors] } : {}
|
|
355
|
+
});
|
|
356
|
+
const visit = (node, ancestors) => {
|
|
357
|
+
if (!checkedIds.has(node.id) && !isBranch(node)) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const childAncestors = [...ancestors, node.id];
|
|
361
|
+
switch (valueConsistsOf) {
|
|
362
|
+
case "ALL": {
|
|
363
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
364
|
+
included.add(node.id);
|
|
365
|
+
result.push(toValue(node, ancestors));
|
|
366
|
+
}
|
|
367
|
+
if (node.children) {
|
|
368
|
+
for (const child of node.children) {
|
|
369
|
+
visit(child, childAncestors);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
case "BRANCH_ONLY": {
|
|
375
|
+
if (isBranch(node)) {
|
|
376
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
377
|
+
included.add(node.id);
|
|
378
|
+
result.push(toValue(node, ancestors));
|
|
379
|
+
}
|
|
380
|
+
if (node.children) {
|
|
381
|
+
for (const child of node.children) {
|
|
382
|
+
visit(child, childAncestors);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
case "LEAF_ONLY": {
|
|
389
|
+
if (!isBranch(node)) {
|
|
390
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
391
|
+
included.add(node.id);
|
|
392
|
+
result.push(toValue(node, ancestors));
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
if (node.children) {
|
|
396
|
+
for (const child of node.children) {
|
|
397
|
+
visit(child, childAncestors);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
case "LEAF_PRIORITY": {
|
|
404
|
+
if (!isBranch(node)) {
|
|
405
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
406
|
+
included.add(node.id);
|
|
407
|
+
result.push(toValue(node, ancestors));
|
|
408
|
+
}
|
|
409
|
+
} else if (!node.children || node.children.length === 0) {
|
|
410
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
411
|
+
included.add(node.id);
|
|
412
|
+
result.push(toValue(node, ancestors));
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
for (const child of node.children) {
|
|
416
|
+
visit(child, childAncestors);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
case "BRANCH_PRIORITY": {
|
|
422
|
+
if (!isBranch(node)) {
|
|
423
|
+
if (checkedIds.has(node.id) && !included.has(node.id)) {
|
|
424
|
+
included.add(node.id);
|
|
425
|
+
result.push(toValue(node, ancestors));
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
if (allNonDisabledChildrenChecked(node)) {
|
|
429
|
+
if (!included.has(node.id)) {
|
|
430
|
+
included.add(node.id);
|
|
431
|
+
result.push(toValue(node, ancestors));
|
|
432
|
+
if (node.children) {
|
|
433
|
+
for (const child of node.children) {
|
|
434
|
+
markDescendantsIncluded(child);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
if (node.children) {
|
|
440
|
+
for (const child of node.children) {
|
|
441
|
+
visit(child, childAncestors);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
const markDescendantsIncluded = (node) => {
|
|
451
|
+
included.add(node.id);
|
|
452
|
+
if (node.children) {
|
|
453
|
+
for (const child of node.children) {
|
|
454
|
+
markDescendantsIncluded(child);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
for (const node of nodes) {
|
|
459
|
+
visit(node, []);
|
|
460
|
+
}
|
|
461
|
+
return result;
|
|
462
|
+
}
|
|
463
|
+
function toggleNodeSelection(nodes, currentValue, nodeId, selectionMode, valueConsistsOf) {
|
|
464
|
+
const nodeMap = buildNodeMap(nodes);
|
|
465
|
+
const targetNode = nodeMap.get(nodeId);
|
|
466
|
+
if (!targetNode) return currentValue;
|
|
467
|
+
const currentCheckedIds = new Set(currentValue.map((v) => v.id));
|
|
468
|
+
const isCurrentlySelected = currentCheckedIds.has(nodeId);
|
|
469
|
+
const parentMap = buildParentMap(nodes);
|
|
470
|
+
if (selectionMode === "single") {
|
|
471
|
+
if (isCurrentlySelected) return [];
|
|
472
|
+
const path = resolvePath(targetNode.id, parentMap);
|
|
473
|
+
return [
|
|
474
|
+
{
|
|
475
|
+
id: targetNode.id,
|
|
476
|
+
label: targetNode.label,
|
|
477
|
+
extra: targetNode.extra,
|
|
478
|
+
...path ? { path } : {}
|
|
479
|
+
}
|
|
480
|
+
];
|
|
481
|
+
}
|
|
482
|
+
if (selectionMode === "independent") {
|
|
483
|
+
const next = new Set(currentCheckedIds);
|
|
484
|
+
if (isCurrentlySelected) {
|
|
485
|
+
next.delete(nodeId);
|
|
486
|
+
} else {
|
|
487
|
+
next.add(nodeId);
|
|
488
|
+
}
|
|
489
|
+
return buildValueFromIds(next, currentValue, nodeMap, parentMap);
|
|
490
|
+
}
|
|
491
|
+
const checkStates = computeCheckStates(
|
|
492
|
+
nodes,
|
|
493
|
+
currentValue,
|
|
494
|
+
selectionMode,
|
|
495
|
+
valueConsistsOf
|
|
496
|
+
);
|
|
497
|
+
const currentCheckState = checkStates.get(nodeId) ?? "unchecked";
|
|
498
|
+
const shouldDeselect = currentCheckState === "checked" || currentCheckState === "indeterminate";
|
|
499
|
+
const expandedIds = valueConsistsOf === "BRANCH_PRIORITY" || valueConsistsOf === "ALL" ? expandBranchIds(currentCheckedIds, nodes) : currentCheckedIds;
|
|
500
|
+
const nextCheckedIds = new Set(expandedIds);
|
|
501
|
+
if (shouldDeselect) {
|
|
502
|
+
const idsToDeselect = getNonDisabledDescendantIds(targetNode);
|
|
503
|
+
for (const id of idsToDeselect) {
|
|
504
|
+
nextCheckedIds.delete(id);
|
|
505
|
+
}
|
|
506
|
+
} else {
|
|
507
|
+
const idsToSelect = getNonDisabledDescendantIds(targetNode);
|
|
508
|
+
for (const id of idsToSelect) {
|
|
509
|
+
nextCheckedIds.add(id);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (valueConsistsOf !== "BRANCH_ONLY") {
|
|
513
|
+
bubbleUpCheckedParents(nodes, nextCheckedIds);
|
|
514
|
+
}
|
|
515
|
+
const computed = computeValue(nodes, nextCheckedIds, valueConsistsOf);
|
|
516
|
+
const emittedIds = new Set(computed.map((v) => v.id));
|
|
517
|
+
const carriedForward = currentValue.filter(
|
|
518
|
+
(v) => nextCheckedIds.has(v.id) && !emittedIds.has(v.id) && !nodeMap.has(v.id)
|
|
519
|
+
);
|
|
520
|
+
return [...computed, ...carriedForward];
|
|
521
|
+
}
|
|
522
|
+
function bubbleUpCheckedParents(nodes, checkedIds) {
|
|
523
|
+
const visit = (list) => {
|
|
524
|
+
for (const node of list) {
|
|
525
|
+
if (node.children && node.children.length > 0) {
|
|
526
|
+
visit(node.children);
|
|
527
|
+
const nonDisabled = node.children.filter((c) => !c.disabled);
|
|
528
|
+
if (nonDisabled.length > 0 && nonDisabled.every((c) => checkedIds.has(c.id))) {
|
|
529
|
+
if (!node.disabled) checkedIds.add(node.id);
|
|
530
|
+
} else {
|
|
531
|
+
checkedIds.delete(node.id);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
visit(nodes);
|
|
537
|
+
}
|
|
538
|
+
function getNonDisabledDescendantIds(node) {
|
|
539
|
+
if (node.disabled) return [];
|
|
540
|
+
const result = [node.id];
|
|
541
|
+
if (node.children) {
|
|
542
|
+
for (const child of node.children) {
|
|
543
|
+
result.push(...getNonDisabledDescendantIds(child));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
548
|
+
function buildValueFromIds(checkedIds, currentValue, nodeMap, parentMap) {
|
|
549
|
+
const existingMap = new Map(currentValue.map((v) => [v.id, v]));
|
|
550
|
+
const result = [];
|
|
551
|
+
for (const id of checkedIds) {
|
|
552
|
+
const existing = existingMap.get(id);
|
|
553
|
+
if (existing) {
|
|
554
|
+
result.push(existing);
|
|
555
|
+
} else {
|
|
556
|
+
const node = nodeMap.get(id);
|
|
557
|
+
if (node) {
|
|
558
|
+
const path = resolvePath(node.id, parentMap);
|
|
559
|
+
result.push({
|
|
560
|
+
id: node.id,
|
|
561
|
+
label: node.label,
|
|
562
|
+
extra: node.extra,
|
|
563
|
+
...path ? { path } : {}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return result;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function handleTreeKeyDown(e, options) {
|
|
572
|
+
const {
|
|
573
|
+
visibleNodes,
|
|
574
|
+
activeIndex,
|
|
575
|
+
setActiveIndex,
|
|
576
|
+
isExpanded,
|
|
577
|
+
toggleExpand,
|
|
578
|
+
toggleNode
|
|
579
|
+
} = options;
|
|
580
|
+
if (visibleNodes.length === 0) return false;
|
|
581
|
+
switch (e.key) {
|
|
582
|
+
case "ArrowDown": {
|
|
583
|
+
e.preventDefault();
|
|
584
|
+
if (activeIndex === -1) {
|
|
585
|
+
setActiveIndex(0);
|
|
586
|
+
} else {
|
|
587
|
+
setActiveIndex(Math.min(activeIndex + 1, visibleNodes.length - 1));
|
|
588
|
+
}
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
case "ArrowUp": {
|
|
592
|
+
e.preventDefault();
|
|
593
|
+
if (activeIndex === -1) {
|
|
594
|
+
setActiveIndex(visibleNodes.length - 1);
|
|
595
|
+
} else {
|
|
596
|
+
setActiveIndex(Math.max(activeIndex - 1, 0));
|
|
597
|
+
}
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
case "ArrowRight": {
|
|
601
|
+
if (activeIndex === -1) return false;
|
|
602
|
+
const rightNode = visibleNodes[activeIndex];
|
|
603
|
+
if (!rightNode.isBranch) return false;
|
|
604
|
+
if (!isExpanded(rightNode.node.id)) {
|
|
605
|
+
e.preventDefault();
|
|
606
|
+
toggleExpand(rightNode.node.id);
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
const nextIndex = activeIndex + 1;
|
|
610
|
+
if (nextIndex < visibleNodes.length) {
|
|
611
|
+
e.preventDefault();
|
|
612
|
+
setActiveIndex(nextIndex);
|
|
613
|
+
return true;
|
|
614
|
+
}
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
case "ArrowLeft": {
|
|
618
|
+
if (activeIndex === -1) return false;
|
|
619
|
+
const leftNode = visibleNodes[activeIndex];
|
|
620
|
+
if (leftNode.isBranch && isExpanded(leftNode.node.id)) {
|
|
621
|
+
e.preventDefault();
|
|
622
|
+
toggleExpand(leftNode.node.id);
|
|
623
|
+
return true;
|
|
624
|
+
}
|
|
625
|
+
const currentDepth = leftNode.depth;
|
|
626
|
+
if (currentDepth === 0) return false;
|
|
627
|
+
for (let i = activeIndex - 1; i >= 0; i--) {
|
|
628
|
+
if (visibleNodes[i].depth < currentDepth) {
|
|
629
|
+
e.preventDefault();
|
|
630
|
+
setActiveIndex(i);
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
case "Home": {
|
|
637
|
+
e.preventDefault();
|
|
638
|
+
setActiveIndex(0);
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
case "End": {
|
|
642
|
+
e.preventDefault();
|
|
643
|
+
setActiveIndex(visibleNodes.length - 1);
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
case "Enter": {
|
|
647
|
+
if (activeIndex === -1) return false;
|
|
648
|
+
e.preventDefault();
|
|
649
|
+
const activeNode = visibleNodes[activeIndex];
|
|
650
|
+
toggleNode(activeNode.node.id);
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
default:
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const EMPTY_PLACEHOLDER_PREFIX = "\0__tsf_empty__";
|
|
659
|
+
function collectAllBranchIds(nodes) {
|
|
660
|
+
const result = [];
|
|
661
|
+
const visit = (list) => {
|
|
662
|
+
for (const node of list) {
|
|
663
|
+
if (node.children !== void 0) {
|
|
664
|
+
result.push(node.id);
|
|
665
|
+
if (node.children) visit(node.children);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
visit(nodes);
|
|
670
|
+
return result;
|
|
671
|
+
}
|
|
672
|
+
function buildDefaultExpanded(nodes, defaultExpandLevel) {
|
|
673
|
+
const result = /* @__PURE__ */ new Set();
|
|
674
|
+
const visit = (list, depth) => {
|
|
675
|
+
if (depth >= defaultExpandLevel) return;
|
|
676
|
+
for (const node of list) {
|
|
677
|
+
if (node.children !== void 0) {
|
|
678
|
+
result.add(node.id);
|
|
679
|
+
if (node.children) visit(node.children, depth + 1);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
visit(nodes, 0);
|
|
684
|
+
return result;
|
|
685
|
+
}
|
|
686
|
+
function isBranchNode(node) {
|
|
687
|
+
return node.children !== void 0;
|
|
688
|
+
}
|
|
689
|
+
function nodeMatchesSearch(node, search) {
|
|
690
|
+
const labelMatch = node.label.toLowerCase().includes(search);
|
|
691
|
+
const searchTextMatch = node.searchText ? node.searchText.toLowerCase().includes(search) : false;
|
|
692
|
+
if (labelMatch || searchTextMatch) return true;
|
|
693
|
+
if (node.children) {
|
|
694
|
+
return node.children.some((child) => nodeMatchesSearch(child, search));
|
|
695
|
+
}
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
function flattenTree(nodes, expandedIds, search, depth) {
|
|
699
|
+
const result = [];
|
|
700
|
+
for (const node of nodes) {
|
|
701
|
+
const isBranch = isBranchNode(node);
|
|
702
|
+
if (search !== void 0) {
|
|
703
|
+
if (!nodeMatchesSearch(node, search)) continue;
|
|
704
|
+
}
|
|
705
|
+
const expanded = isBranch ? search !== void 0 ? (
|
|
706
|
+
// During search, auto-expand branches that have matching descendants
|
|
707
|
+
nodeMatchesSearch(node, search)
|
|
708
|
+
) : expandedIds.has(node.id) : false;
|
|
709
|
+
result.push({
|
|
710
|
+
node,
|
|
711
|
+
depth,
|
|
712
|
+
isExpanded: expanded,
|
|
713
|
+
isBranch,
|
|
714
|
+
isLoading: false
|
|
715
|
+
});
|
|
716
|
+
if (isBranch && expanded) {
|
|
717
|
+
if (node.children && node.children.length > 0) {
|
|
718
|
+
result.push(
|
|
719
|
+
...flattenTree(node.children, expandedIds, search, depth + 1)
|
|
720
|
+
);
|
|
721
|
+
} else if (node.children && node.children.length === 0) {
|
|
722
|
+
result.push({
|
|
723
|
+
node: {
|
|
724
|
+
id: `${EMPTY_PLACEHOLDER_PREFIX}${node.id}`,
|
|
725
|
+
label: "No items"
|
|
726
|
+
},
|
|
727
|
+
depth: depth + 1,
|
|
728
|
+
isExpanded: false,
|
|
729
|
+
isBranch: false,
|
|
730
|
+
isLoading: false,
|
|
731
|
+
isEmptyPlaceholder: true
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return result;
|
|
737
|
+
}
|
|
738
|
+
function useTree(options) {
|
|
739
|
+
const {
|
|
740
|
+
nodes,
|
|
741
|
+
value,
|
|
742
|
+
onSelectedOptionsChange,
|
|
743
|
+
selectionMode = "linked",
|
|
744
|
+
valueConsistsOf = "LEAF_PRIORITY",
|
|
745
|
+
defaultExpandLevel = 0,
|
|
746
|
+
expandedIds: controlledExpandedIds,
|
|
747
|
+
onExpandedIdsChange,
|
|
748
|
+
searchValue,
|
|
749
|
+
ancestry,
|
|
750
|
+
loadingChildrenIds
|
|
751
|
+
} = options;
|
|
752
|
+
const isControlled = controlledExpandedIds !== void 0;
|
|
753
|
+
const [uncontrolledExpandedIds, setUncontrolledExpandedIds] = useState(() => buildDefaultExpanded(nodes, defaultExpandLevel));
|
|
754
|
+
const appliedDefaultExpandRef = useRef(nodes.length > 0);
|
|
755
|
+
useEffect(() => {
|
|
756
|
+
if (!appliedDefaultExpandRef.current && nodes.length > 0 && !isControlled) {
|
|
757
|
+
appliedDefaultExpandRef.current = true;
|
|
758
|
+
setUncontrolledExpandedIds(
|
|
759
|
+
buildDefaultExpanded(nodes, defaultExpandLevel)
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
}, [nodes, defaultExpandLevel, isControlled]);
|
|
763
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
764
|
+
const expandedIds = isControlled ? controlledExpandedIds : uncontrolledExpandedIds;
|
|
765
|
+
const isExpanded = useCallback(
|
|
766
|
+
(id) => expandedIds.has(id),
|
|
767
|
+
[expandedIds]
|
|
768
|
+
);
|
|
769
|
+
const setExpandedIds = useCallback(
|
|
770
|
+
(next) => {
|
|
771
|
+
if (isControlled) {
|
|
772
|
+
onExpandedIdsChange?.(next);
|
|
773
|
+
} else {
|
|
774
|
+
setUncontrolledExpandedIds(next);
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
[isControlled, onExpandedIdsChange]
|
|
778
|
+
);
|
|
779
|
+
const toggleExpand = useCallback(
|
|
780
|
+
(id) => {
|
|
781
|
+
const next = new Set(expandedIds);
|
|
782
|
+
if (next.has(id)) {
|
|
783
|
+
next.delete(id);
|
|
784
|
+
} else {
|
|
785
|
+
next.add(id);
|
|
786
|
+
}
|
|
787
|
+
setExpandedIds(next);
|
|
788
|
+
},
|
|
789
|
+
[expandedIds, setExpandedIds]
|
|
790
|
+
);
|
|
791
|
+
const expandAll = useCallback(() => {
|
|
792
|
+
const allBranchIds = collectAllBranchIds(nodes);
|
|
793
|
+
setExpandedIds(new Set(allBranchIds));
|
|
794
|
+
}, [nodes, setExpandedIds]);
|
|
795
|
+
const collapseAll = useCallback(() => {
|
|
796
|
+
setExpandedIds(/* @__PURE__ */ new Set());
|
|
797
|
+
}, [setExpandedIds]);
|
|
798
|
+
const normalizedSearch = searchValue?.trim().toLowerCase() || void 0;
|
|
799
|
+
const visibleNodes = useMemo(() => {
|
|
800
|
+
const flat = flattenTree(nodes, expandedIds, normalizedSearch, 0);
|
|
801
|
+
if (!loadingChildrenIds || loadingChildrenIds.size === 0) return flat;
|
|
802
|
+
return flat.map(
|
|
803
|
+
(vn) => loadingChildrenIds.has(vn.node.id) ? { ...vn, isLoading: true } : vn
|
|
804
|
+
);
|
|
805
|
+
}, [nodes, expandedIds, normalizedSearch, loadingChildrenIds]);
|
|
806
|
+
const visibleNodeMap = useMemo(() => {
|
|
807
|
+
const map = /* @__PURE__ */ new Map();
|
|
808
|
+
for (const vn of visibleNodes) {
|
|
809
|
+
map.set(vn.node.id, vn);
|
|
810
|
+
}
|
|
811
|
+
return map;
|
|
812
|
+
}, [visibleNodes]);
|
|
813
|
+
const visibleSiblingsMap = useMemo(() => {
|
|
814
|
+
const map = /* @__PURE__ */ new Map();
|
|
815
|
+
const groups = /* @__PURE__ */ new Map();
|
|
816
|
+
const parentStack = [];
|
|
817
|
+
for (const vn of visibleNodes) {
|
|
818
|
+
if (vn.isEmptyPlaceholder) continue;
|
|
819
|
+
while (parentStack.length > 0 && parentStack[parentStack.length - 1].depth >= vn.depth) {
|
|
820
|
+
parentStack.pop();
|
|
821
|
+
}
|
|
822
|
+
const parentKey = parentStack.length > 0 ? parentStack[parentStack.length - 1].id : "__root__";
|
|
823
|
+
let group = groups.get(parentKey);
|
|
824
|
+
if (!group) {
|
|
825
|
+
group = [];
|
|
826
|
+
groups.set(parentKey, group);
|
|
827
|
+
}
|
|
828
|
+
group.push(vn.node.id);
|
|
829
|
+
if (vn.isBranch && vn.isExpanded) {
|
|
830
|
+
parentStack.push({ id: vn.node.id, depth: vn.depth });
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
for (const group of groups.values()) {
|
|
834
|
+
for (let i = 0; i < group.length; i++) {
|
|
835
|
+
map.set(group[i], { setSize: group.length, posInSet: i + 1 });
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return map;
|
|
839
|
+
}, [visibleNodes]);
|
|
840
|
+
const orphanAncestorIds = useMemo(() => {
|
|
841
|
+
const loadedIds = /* @__PURE__ */ new Set();
|
|
842
|
+
const collect = (list) => {
|
|
843
|
+
for (const n of list) {
|
|
844
|
+
loadedIds.add(n.id);
|
|
845
|
+
if (n.children) collect(n.children);
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
collect(nodes);
|
|
849
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
850
|
+
for (const v of value) {
|
|
851
|
+
if (loadedIds.has(v.id)) continue;
|
|
852
|
+
if (v.path && v.path.length > 0) {
|
|
853
|
+
for (const ancestorId of v.path) ancestors.add(ancestorId);
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
if (ancestry) {
|
|
857
|
+
const seen = /* @__PURE__ */ new Set();
|
|
858
|
+
let parent = ancestry.get(v.id);
|
|
859
|
+
while (parent !== void 0 && !seen.has(parent)) {
|
|
860
|
+
seen.add(parent);
|
|
861
|
+
ancestors.add(parent);
|
|
862
|
+
parent = ancestry.get(parent);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return ancestors;
|
|
867
|
+
}, [nodes, value, ancestry]);
|
|
868
|
+
const checkStates = useMemo(
|
|
869
|
+
() => computeCheckStates(
|
|
870
|
+
nodes,
|
|
871
|
+
value,
|
|
872
|
+
selectionMode,
|
|
873
|
+
valueConsistsOf,
|
|
874
|
+
orphanAncestorIds
|
|
875
|
+
),
|
|
876
|
+
[nodes, value, selectionMode, valueConsistsOf, orphanAncestorIds]
|
|
877
|
+
);
|
|
878
|
+
const getCheckState = useCallback(
|
|
879
|
+
(id) => checkStates.get(id) ?? "unchecked",
|
|
880
|
+
[checkStates]
|
|
881
|
+
);
|
|
882
|
+
const toggleNode = useCallback(
|
|
883
|
+
(id) => {
|
|
884
|
+
const newValue = toggleNodeSelection(
|
|
885
|
+
nodes,
|
|
886
|
+
value,
|
|
887
|
+
id,
|
|
888
|
+
selectionMode,
|
|
889
|
+
valueConsistsOf
|
|
890
|
+
);
|
|
891
|
+
onSelectedOptionsChange(newValue);
|
|
892
|
+
},
|
|
893
|
+
[nodes, value, selectionMode, valueConsistsOf, onSelectedOptionsChange]
|
|
894
|
+
);
|
|
895
|
+
const onKeyDown = useCallback(
|
|
896
|
+
(e) => {
|
|
897
|
+
return handleTreeKeyDown(e, {
|
|
898
|
+
visibleNodes,
|
|
899
|
+
activeIndex,
|
|
900
|
+
setActiveIndex,
|
|
901
|
+
isExpanded,
|
|
902
|
+
toggleExpand,
|
|
903
|
+
toggleNode
|
|
904
|
+
});
|
|
905
|
+
},
|
|
906
|
+
[visibleNodes, activeIndex, isExpanded, toggleExpand, toggleNode]
|
|
907
|
+
);
|
|
908
|
+
const activeDescendantId = activeIndex >= 0 && activeIndex < visibleNodes.length ? `treeitem-${visibleNodes[activeIndex].node.id}` : void 0;
|
|
909
|
+
const setActiveNodeId = useCallback(
|
|
910
|
+
(id) => {
|
|
911
|
+
const idx = visibleNodes.findIndex((vn) => vn.node.id === id);
|
|
912
|
+
if (idx !== -1) setActiveIndex(idx);
|
|
913
|
+
},
|
|
914
|
+
[visibleNodes]
|
|
915
|
+
);
|
|
916
|
+
const getTreeItemProps = useCallback(
|
|
917
|
+
(id) => {
|
|
918
|
+
const visibleNode = visibleNodeMap.get(id);
|
|
919
|
+
const depth = visibleNode?.depth ?? 0;
|
|
920
|
+
const isBranch = visibleNode?.isBranch ?? false;
|
|
921
|
+
const expanded = isBranch ? visibleNode?.isExpanded ?? isExpanded(id) : void 0;
|
|
922
|
+
const siblingInfo = visibleSiblingsMap.get(id);
|
|
923
|
+
const setSize = siblingInfo?.setSize ?? 1;
|
|
924
|
+
const posInSet = siblingInfo?.posInSet ?? 1;
|
|
925
|
+
const checkState = getCheckState(id);
|
|
926
|
+
const isSelected = checkState === "checked";
|
|
927
|
+
const props = {
|
|
928
|
+
id: `treeitem-${id}`,
|
|
929
|
+
role: "treeitem",
|
|
930
|
+
"aria-level": depth + 1,
|
|
931
|
+
"aria-setsize": setSize,
|
|
932
|
+
"aria-posinset": posInSet,
|
|
933
|
+
"aria-selected": isSelected
|
|
934
|
+
};
|
|
935
|
+
if (isBranch) {
|
|
936
|
+
props["aria-expanded"] = expanded;
|
|
937
|
+
}
|
|
938
|
+
return props;
|
|
939
|
+
},
|
|
940
|
+
[visibleNodeMap, isExpanded, visibleSiblingsMap, getCheckState]
|
|
941
|
+
);
|
|
942
|
+
const treeProps = useMemo(
|
|
943
|
+
() => ({
|
|
944
|
+
role: "tree",
|
|
945
|
+
"aria-activedescendant": activeDescendantId,
|
|
946
|
+
"aria-multiselectable": selectionMode !== "single"
|
|
947
|
+
}),
|
|
948
|
+
[activeDescendantId, selectionMode]
|
|
949
|
+
);
|
|
950
|
+
return {
|
|
951
|
+
nodes,
|
|
952
|
+
visibleNodes,
|
|
953
|
+
getCheckState,
|
|
954
|
+
toggleNode,
|
|
955
|
+
isExpanded,
|
|
956
|
+
toggleExpand,
|
|
957
|
+
expandAll,
|
|
958
|
+
collapseAll,
|
|
959
|
+
activeDescendantId,
|
|
960
|
+
setActiveNodeId,
|
|
961
|
+
onKeyDown,
|
|
962
|
+
getTreeItemProps,
|
|
963
|
+
treeProps
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const active = "_active_r0ti0_40";
|
|
968
|
+
const styles$1 = {
|
|
969
|
+
"tree-row": "_tree-row_r0ti0_2",
|
|
970
|
+
"expand-icon": "_expand-icon_r0ti0_8",
|
|
971
|
+
"label-container": "_label-container_r0ti0_29",
|
|
972
|
+
active: active
|
|
973
|
+
};
|
|
974
|
+
|
|
975
|
+
const INDENT_BASE = 16;
|
|
976
|
+
const INDENT_PER_DEPTH = 24;
|
|
977
|
+
const EXPAND_ICON_WIDTH = 32;
|
|
978
|
+
function TreeRow({
|
|
979
|
+
visible,
|
|
980
|
+
checkState,
|
|
981
|
+
itemProps,
|
|
982
|
+
branchesSelectable = true,
|
|
983
|
+
leavesSelectable = true,
|
|
984
|
+
emptyBranchesSelectable = true,
|
|
985
|
+
readOnly = false,
|
|
986
|
+
isActive,
|
|
987
|
+
onToggleNode,
|
|
988
|
+
onToggleExpand,
|
|
989
|
+
onHover,
|
|
990
|
+
onLoadChildren,
|
|
991
|
+
depth
|
|
992
|
+
}) {
|
|
993
|
+
const { node, isExpanded, isBranch, isLoading, isEmptyPlaceholder } = visible;
|
|
994
|
+
if (isEmptyPlaceholder) {
|
|
995
|
+
return /* @__PURE__ */ jsx(
|
|
996
|
+
OptionRow,
|
|
997
|
+
{
|
|
998
|
+
disabled: true,
|
|
999
|
+
className: styles$1["tree-row"],
|
|
1000
|
+
style: {
|
|
1001
|
+
paddingInlineStart: INDENT_BASE + depth * INDENT_PER_DEPTH + EXPAND_ICON_WIDTH
|
|
1002
|
+
},
|
|
1003
|
+
children: /* @__PURE__ */ jsx("span", { className: styles$1["label-container"], children: /* @__PURE__ */ jsx(Text, { children: node.label }) })
|
|
1004
|
+
}
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
const isDisabled = node.disabled === true;
|
|
1008
|
+
const isEmptyBranch = isBranch && Array.isArray(node.children) && node.children.length === 0;
|
|
1009
|
+
const isSelectable = (() => {
|
|
1010
|
+
if (!isBranch) return leavesSelectable;
|
|
1011
|
+
if (!branchesSelectable) return false;
|
|
1012
|
+
if (isEmptyBranch && !emptyBranchesSelectable) return false;
|
|
1013
|
+
return true;
|
|
1014
|
+
})();
|
|
1015
|
+
const showExpandIcon = isBranch;
|
|
1016
|
+
const paddingInlineStart = INDENT_BASE + depth * INDENT_PER_DEPTH + (showExpandIcon ? 0 : EXPAND_ICON_WIDTH);
|
|
1017
|
+
const rowDisabled = readOnly || isDisabled || !isSelectable && !isBranch;
|
|
1018
|
+
const expandNode = () => {
|
|
1019
|
+
onToggleExpand(node.id);
|
|
1020
|
+
if (node.children === null) onLoadChildren?.(node);
|
|
1021
|
+
};
|
|
1022
|
+
const handleExpandClick = (e) => {
|
|
1023
|
+
e.stopPropagation();
|
|
1024
|
+
if (isDisabled) return;
|
|
1025
|
+
expandNode();
|
|
1026
|
+
};
|
|
1027
|
+
const handleRowClick = () => {
|
|
1028
|
+
if (isDisabled) return;
|
|
1029
|
+
if (isBranch) {
|
|
1030
|
+
if (isSelectable) {
|
|
1031
|
+
onToggleNode(node.id);
|
|
1032
|
+
} else {
|
|
1033
|
+
expandNode();
|
|
1034
|
+
}
|
|
1035
|
+
} else if (isSelectable) {
|
|
1036
|
+
onToggleNode(node.id);
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
let expandIconElement = null;
|
|
1040
|
+
if (showExpandIcon) {
|
|
1041
|
+
if (isLoading && checkState !== "loading") {
|
|
1042
|
+
expandIconElement = /* @__PURE__ */ jsx(Spinner, { size: "small", "aria-hidden": "true" });
|
|
1043
|
+
} else if (isExpanded) {
|
|
1044
|
+
expandIconElement = /* @__PURE__ */ jsx(Icon, { svg: SvgKeyboardArrowDown, size: "small", inherit: true, "aria-hidden": "true" });
|
|
1045
|
+
} else {
|
|
1046
|
+
expandIconElement = /* @__PURE__ */ jsx(
|
|
1047
|
+
Icon,
|
|
1048
|
+
{
|
|
1049
|
+
svg: SvgKeyboardArrowRight,
|
|
1050
|
+
size: "small",
|
|
1051
|
+
inherit: true,
|
|
1052
|
+
"aria-hidden": "true"
|
|
1053
|
+
}
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return /* @__PURE__ */ jsxs(
|
|
1058
|
+
OptionRow,
|
|
1059
|
+
{
|
|
1060
|
+
...itemProps,
|
|
1061
|
+
disabled: rowDisabled,
|
|
1062
|
+
style: { paddingInlineStart },
|
|
1063
|
+
className: cx(styles$1["tree-row"], {
|
|
1064
|
+
[styles$1["active"]]: isActive
|
|
1065
|
+
}),
|
|
1066
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
1067
|
+
onMouseEnter: () => onHover?.(node.id),
|
|
1068
|
+
onClick: handleRowClick,
|
|
1069
|
+
"aria-disabled": rowDisabled || void 0,
|
|
1070
|
+
children: [
|
|
1071
|
+
showExpandIcon && /* @__PURE__ */ jsx(
|
|
1072
|
+
"span",
|
|
1073
|
+
{
|
|
1074
|
+
className: styles$1["expand-icon"],
|
|
1075
|
+
onClick: handleExpandClick,
|
|
1076
|
+
"aria-hidden": "true",
|
|
1077
|
+
children: expandIconElement
|
|
1078
|
+
}
|
|
1079
|
+
),
|
|
1080
|
+
isSelectable && /* @__PURE__ */ jsx(OptionRowSideContent, { children: /* @__PURE__ */ jsx(OptionCheckbox, { checkState }) }),
|
|
1081
|
+
/* @__PURE__ */ jsx(OptionContentArea, { label: node.label, content: node.content })
|
|
1082
|
+
]
|
|
1083
|
+
}
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
const panel = "_panel_1nd4g_1";
|
|
1088
|
+
const styles = {
|
|
1089
|
+
panel: panel
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
const TreePanel = forwardRef(
|
|
1093
|
+
function TreePanelInner({
|
|
1094
|
+
visibleNodes,
|
|
1095
|
+
getCheckState,
|
|
1096
|
+
toggleNode,
|
|
1097
|
+
toggleExpand,
|
|
1098
|
+
getTreeItemProps,
|
|
1099
|
+
treeProps,
|
|
1100
|
+
activeDescendantId,
|
|
1101
|
+
branchesSelectable,
|
|
1102
|
+
leavesSelectable,
|
|
1103
|
+
emptyBranchesSelectable,
|
|
1104
|
+
readOnly,
|
|
1105
|
+
onHover,
|
|
1106
|
+
onLoadChildren
|
|
1107
|
+
}, ref) {
|
|
1108
|
+
return /* @__PURE__ */ jsx(
|
|
1109
|
+
"div",
|
|
1110
|
+
{
|
|
1111
|
+
ref,
|
|
1112
|
+
...treeProps,
|
|
1113
|
+
className: cx(styles.panel, treeProps.className),
|
|
1114
|
+
children: visibleNodes.map((visible) => /* @__PURE__ */ jsx(
|
|
1115
|
+
TreeRow,
|
|
1116
|
+
{
|
|
1117
|
+
visible,
|
|
1118
|
+
checkState: getCheckState(visible.node.id),
|
|
1119
|
+
itemProps: getTreeItemProps(visible.node.id),
|
|
1120
|
+
isActive: activeDescendantId === `treeitem-${visible.node.id}`,
|
|
1121
|
+
branchesSelectable,
|
|
1122
|
+
leavesSelectable,
|
|
1123
|
+
emptyBranchesSelectable,
|
|
1124
|
+
readOnly,
|
|
1125
|
+
onToggleNode: toggleNode,
|
|
1126
|
+
onToggleExpand: toggleExpand,
|
|
1127
|
+
onHover,
|
|
1128
|
+
onLoadChildren,
|
|
1129
|
+
depth: visible.depth
|
|
1130
|
+
},
|
|
1131
|
+
visible.node.id
|
|
1132
|
+
))
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
);
|
|
1137
|
+
TreePanel.displayName = "TreePanel";
|
|
1138
|
+
|
|
1139
|
+
const EST_PADDING_BLOCK = 16;
|
|
1140
|
+
const EST_LINE_HEIGHT = 18;
|
|
1141
|
+
const EST_CHIP_ROW_HEIGHT = 28;
|
|
1142
|
+
const EST_SIDE_CONTENT_HEIGHT = 40;
|
|
1143
|
+
const EST_BASE_ROW_HEIGHT = EST_PADDING_BLOCK + EST_LINE_HEIGHT;
|
|
1144
|
+
function estimateTreeRowHeight(visible) {
|
|
1145
|
+
const content = visible.node.content;
|
|
1146
|
+
if (!content) return EST_BASE_ROW_HEIGHT;
|
|
1147
|
+
let contentHeight = EST_LINE_HEIGHT;
|
|
1148
|
+
if (content.description) contentHeight += EST_LINE_HEIGHT;
|
|
1149
|
+
if (content.chips?.length) contentHeight += EST_CHIP_ROW_HEIGHT;
|
|
1150
|
+
if (content.avatar || content.icon)
|
|
1151
|
+
contentHeight = Math.max(contentHeight, EST_SIDE_CONTENT_HEIGHT);
|
|
1152
|
+
return EST_PADDING_BLOCK + contentHeight;
|
|
1153
|
+
}
|
|
1154
|
+
const VirtualizedTreePanel = forwardRef(function VirtualizedTreePanelInner(props, ref) {
|
|
1155
|
+
const {
|
|
1156
|
+
visibleNodes,
|
|
1157
|
+
getCheckState,
|
|
1158
|
+
toggleNode,
|
|
1159
|
+
toggleExpand,
|
|
1160
|
+
getTreeItemProps,
|
|
1161
|
+
treeProps,
|
|
1162
|
+
activeDescendantId,
|
|
1163
|
+
branchesSelectable = true,
|
|
1164
|
+
leavesSelectable = true,
|
|
1165
|
+
emptyBranchesSelectable = true,
|
|
1166
|
+
readOnly = false,
|
|
1167
|
+
onHover,
|
|
1168
|
+
onLoadChildren
|
|
1169
|
+
} = props;
|
|
1170
|
+
const scrollRef = useRef(null);
|
|
1171
|
+
const estimateSize = useCallback(
|
|
1172
|
+
(index) => estimateTreeRowHeight(visibleNodes[index]),
|
|
1173
|
+
[visibleNodes]
|
|
1174
|
+
);
|
|
1175
|
+
const virtualizer = useVirtualizer({
|
|
1176
|
+
count: visibleNodes.length,
|
|
1177
|
+
getScrollElement: () => scrollRef.current,
|
|
1178
|
+
estimateSize,
|
|
1179
|
+
overscan: 5
|
|
1180
|
+
});
|
|
1181
|
+
const virtualItems = virtualizer.getVirtualItems();
|
|
1182
|
+
return /* @__PURE__ */ jsx(
|
|
1183
|
+
"div",
|
|
1184
|
+
{
|
|
1185
|
+
ref: (node) => {
|
|
1186
|
+
scrollRef.current = node;
|
|
1187
|
+
if (typeof ref === "function") ref(node);
|
|
1188
|
+
else if (ref) ref.current = node;
|
|
1189
|
+
},
|
|
1190
|
+
...treeProps,
|
|
1191
|
+
className: cx(styles.panel, treeProps.className),
|
|
1192
|
+
children: /* @__PURE__ */ jsx(
|
|
1193
|
+
"div",
|
|
1194
|
+
{
|
|
1195
|
+
style: {
|
|
1196
|
+
height: virtualizer.getTotalSize(),
|
|
1197
|
+
width: "100%",
|
|
1198
|
+
position: "relative"
|
|
1199
|
+
},
|
|
1200
|
+
children: virtualItems.map((virtualItem) => {
|
|
1201
|
+
const visible = visibleNodes[virtualItem.index];
|
|
1202
|
+
return /* @__PURE__ */ jsx(
|
|
1203
|
+
"div",
|
|
1204
|
+
{
|
|
1205
|
+
style: {
|
|
1206
|
+
position: "absolute",
|
|
1207
|
+
top: 0,
|
|
1208
|
+
left: 0,
|
|
1209
|
+
width: "100%",
|
|
1210
|
+
height: `${virtualItem.size}px`,
|
|
1211
|
+
transform: `translateY(${virtualItem.start}px)`
|
|
1212
|
+
},
|
|
1213
|
+
children: /* @__PURE__ */ jsx(
|
|
1214
|
+
TreeRow,
|
|
1215
|
+
{
|
|
1216
|
+
visible,
|
|
1217
|
+
checkState: getCheckState(visible.node.id),
|
|
1218
|
+
itemProps: getTreeItemProps(visible.node.id),
|
|
1219
|
+
isActive: activeDescendantId === `treeitem-${visible.node.id}`,
|
|
1220
|
+
branchesSelectable,
|
|
1221
|
+
leavesSelectable,
|
|
1222
|
+
emptyBranchesSelectable,
|
|
1223
|
+
readOnly,
|
|
1224
|
+
onToggleNode: toggleNode,
|
|
1225
|
+
onToggleExpand: toggleExpand,
|
|
1226
|
+
onHover,
|
|
1227
|
+
onLoadChildren,
|
|
1228
|
+
depth: visible.depth
|
|
1229
|
+
}
|
|
1230
|
+
)
|
|
1231
|
+
},
|
|
1232
|
+
visible.node.id
|
|
1233
|
+
);
|
|
1234
|
+
})
|
|
1235
|
+
}
|
|
1236
|
+
)
|
|
1237
|
+
}
|
|
1238
|
+
);
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
const TreeContent = forwardRef(
|
|
1242
|
+
function TreeContent2({ loading, hasNoVisibleNodes, virtualize, panelProps }, ref) {
|
|
1243
|
+
if (loading) {
|
|
1244
|
+
return /* @__PURE__ */ jsx(
|
|
1245
|
+
"div",
|
|
1246
|
+
{
|
|
1247
|
+
style: {
|
|
1248
|
+
padding: "var(--a2-spacing-200)",
|
|
1249
|
+
display: "flex",
|
|
1250
|
+
justifyContent: "center"
|
|
1251
|
+
},
|
|
1252
|
+
children: /* @__PURE__ */ jsx(Spinner, { size: "medium" })
|
|
1253
|
+
}
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
if (hasNoVisibleNodes) {
|
|
1257
|
+
return /* @__PURE__ */ jsx(
|
|
1258
|
+
"div",
|
|
1259
|
+
{
|
|
1260
|
+
role: "presentation",
|
|
1261
|
+
style: {
|
|
1262
|
+
display: "flex",
|
|
1263
|
+
alignItems: "center",
|
|
1264
|
+
justifyContent: "center",
|
|
1265
|
+
padding: "1rem",
|
|
1266
|
+
textAlign: "center"
|
|
1267
|
+
},
|
|
1268
|
+
children: /* @__PURE__ */ jsx(Text, { subdued: true, size: "small", children: "No match found" })
|
|
1269
|
+
}
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
return virtualize ? /* @__PURE__ */ jsx(VirtualizedTreePanel, { ref, ...panelProps }) : /* @__PURE__ */ jsx(TreePanel, { ref, ...panelProps });
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
TreeContent.displayName = "TreeContent";
|
|
1276
|
+
|
|
1277
|
+
function findNode(nodes, id) {
|
|
1278
|
+
for (const node of nodes) {
|
|
1279
|
+
if (node.id === id) return node;
|
|
1280
|
+
if (node.children) {
|
|
1281
|
+
const found = findNode(node.children, id);
|
|
1282
|
+
if (found) return found;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
return void 0;
|
|
1286
|
+
}
|
|
1287
|
+
function hasUnloadedDescendants(node) {
|
|
1288
|
+
if (node.children === null) return true;
|
|
1289
|
+
if (!node.children) return false;
|
|
1290
|
+
return node.children.some(hasUnloadedDescendants);
|
|
1291
|
+
}
|
|
1292
|
+
function findUnloadedDescendants(node) {
|
|
1293
|
+
const result = [];
|
|
1294
|
+
if (!node.children) return result;
|
|
1295
|
+
for (const child of node.children) {
|
|
1296
|
+
if (child.children === null) {
|
|
1297
|
+
result.push(child);
|
|
1298
|
+
} else if (child.children) {
|
|
1299
|
+
result.push(...findUnloadedDescendants(child));
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return result;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
function useTreeLazyCascade(options) {
|
|
1306
|
+
const {
|
|
1307
|
+
tree,
|
|
1308
|
+
loader,
|
|
1309
|
+
isSingleSelect,
|
|
1310
|
+
branchesSelectable,
|
|
1311
|
+
leavesSelectable,
|
|
1312
|
+
emptyBranchesSelectable,
|
|
1313
|
+
readOnly = false,
|
|
1314
|
+
onCloseAfterSingleSelect
|
|
1315
|
+
} = options;
|
|
1316
|
+
const pendingToggleRef = useRef(null);
|
|
1317
|
+
const loadedForToggleRef = useRef(/* @__PURE__ */ new Set());
|
|
1318
|
+
const [pendingToggleNodeId, setPendingToggleNodeId] = useState(null);
|
|
1319
|
+
useEffect(() => {
|
|
1320
|
+
if (pendingToggleRef.current === null) return;
|
|
1321
|
+
const nodeId = pendingToggleRef.current;
|
|
1322
|
+
const node = findNode(tree.nodes, nodeId);
|
|
1323
|
+
if (!node) return;
|
|
1324
|
+
if (node.children === null) return;
|
|
1325
|
+
if (loader.isLoadingChildren.size > 0) return;
|
|
1326
|
+
const unloaded = findUnloadedDescendants(node).filter(
|
|
1327
|
+
(n) => !loadedForToggleRef.current.has(n.id)
|
|
1328
|
+
);
|
|
1329
|
+
if (unloaded.length > 0) {
|
|
1330
|
+
for (const n of unloaded) {
|
|
1331
|
+
loadedForToggleRef.current.add(n.id);
|
|
1332
|
+
void loader.loadChildren(n);
|
|
1333
|
+
}
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
pendingToggleRef.current = null;
|
|
1337
|
+
loadedForToggleRef.current = /* @__PURE__ */ new Set();
|
|
1338
|
+
setPendingToggleNodeId(null);
|
|
1339
|
+
tree.toggleNode(nodeId);
|
|
1340
|
+
if (isSingleSelect) {
|
|
1341
|
+
onCloseAfterSingleSelect?.();
|
|
1342
|
+
}
|
|
1343
|
+
}, [tree, isSingleSelect, onCloseAfterSingleSelect, loader]);
|
|
1344
|
+
const handleToggleNode = useCallback(
|
|
1345
|
+
(nodeId) => {
|
|
1346
|
+
if (readOnly) return;
|
|
1347
|
+
const node = findNode(tree.nodes, nodeId);
|
|
1348
|
+
if (!node) return;
|
|
1349
|
+
const isBranch = node.children !== void 0;
|
|
1350
|
+
const isEmptyBranch = isBranch && Array.isArray(node.children) && node.children.length === 0;
|
|
1351
|
+
const isNodeSelectable = isBranch ? branchesSelectable && (isEmptyBranch ? emptyBranchesSelectable : true) : leavesSelectable;
|
|
1352
|
+
if (!isNodeSelectable) {
|
|
1353
|
+
if (isBranch) {
|
|
1354
|
+
tree.toggleExpand(nodeId);
|
|
1355
|
+
if (node.children === null) {
|
|
1356
|
+
void loader.loadChildren(node);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (hasUnloadedDescendants(node)) {
|
|
1362
|
+
pendingToggleRef.current = nodeId;
|
|
1363
|
+
loadedForToggleRef.current = /* @__PURE__ */ new Set();
|
|
1364
|
+
setPendingToggleNodeId(nodeId);
|
|
1365
|
+
if (node.children === null) {
|
|
1366
|
+
loadedForToggleRef.current.add(node.id);
|
|
1367
|
+
void loader.loadChildren(node);
|
|
1368
|
+
} else {
|
|
1369
|
+
const unloaded = findUnloadedDescendants(node);
|
|
1370
|
+
for (const n of unloaded) {
|
|
1371
|
+
loadedForToggleRef.current.add(n.id);
|
|
1372
|
+
void loader.loadChildren(n);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
tree.toggleNode(nodeId);
|
|
1378
|
+
if (isSingleSelect) {
|
|
1379
|
+
onCloseAfterSingleSelect?.();
|
|
1380
|
+
}
|
|
1381
|
+
},
|
|
1382
|
+
[
|
|
1383
|
+
tree,
|
|
1384
|
+
isSingleSelect,
|
|
1385
|
+
onCloseAfterSingleSelect,
|
|
1386
|
+
loader,
|
|
1387
|
+
readOnly,
|
|
1388
|
+
branchesSelectable,
|
|
1389
|
+
leavesSelectable,
|
|
1390
|
+
emptyBranchesSelectable
|
|
1391
|
+
]
|
|
1392
|
+
);
|
|
1393
|
+
const reset = useCallback(() => {
|
|
1394
|
+
pendingToggleRef.current = null;
|
|
1395
|
+
loadedForToggleRef.current = /* @__PURE__ */ new Set();
|
|
1396
|
+
setPendingToggleNodeId(null);
|
|
1397
|
+
}, []);
|
|
1398
|
+
return { handleToggleNode, pendingToggleNodeId, reset };
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
function applyChildCounts(nodes) {
|
|
1402
|
+
return nodes.map((node) => {
|
|
1403
|
+
if (!Array.isArray(node.children)) return node;
|
|
1404
|
+
const children = applyChildCounts(node.children);
|
|
1405
|
+
return {
|
|
1406
|
+
...node,
|
|
1407
|
+
children,
|
|
1408
|
+
childCount: node.childCount ?? children.length
|
|
1409
|
+
};
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
function flattenNodes(nodes) {
|
|
1413
|
+
return nodes.flatMap((node) => [
|
|
1414
|
+
node,
|
|
1415
|
+
...node.children ? flattenNodes(node.children) : []
|
|
1416
|
+
]);
|
|
1417
|
+
}
|
|
1418
|
+
function pruneTree(nodes, matchedIds) {
|
|
1419
|
+
const result = [];
|
|
1420
|
+
for (const node of nodes) {
|
|
1421
|
+
if (matchedIds.has(node.id)) {
|
|
1422
|
+
result.push(node);
|
|
1423
|
+
} else if (node.children && node.children.length > 0) {
|
|
1424
|
+
const filteredChildren = pruneTree(node.children, matchedIds);
|
|
1425
|
+
if (filteredChildren.length > 0) {
|
|
1426
|
+
result.push({ ...node, children: filteredChildren });
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return result;
|
|
1431
|
+
}
|
|
1432
|
+
function defaultTreeSyncFilter(nodes, searchValue) {
|
|
1433
|
+
if (!searchValue) return nodes;
|
|
1434
|
+
const flat = flattenNodes(nodes);
|
|
1435
|
+
const matched = matchSorter(flat, searchValue, {
|
|
1436
|
+
keys: ["label", "searchText"]
|
|
1437
|
+
});
|
|
1438
|
+
const matchedIds = new Set(matched.map((n) => n.id));
|
|
1439
|
+
return pruneTree(nodes, matchedIds);
|
|
1440
|
+
}
|
|
1441
|
+
function toTreeSyncFilterFn(filter) {
|
|
1442
|
+
if (typeof filter === "function") return filter;
|
|
1443
|
+
return (nodes, searchValue) => {
|
|
1444
|
+
if (!searchValue) return nodes;
|
|
1445
|
+
const flat = flattenNodes(nodes);
|
|
1446
|
+
const matched = matchSorter(flat, searchValue, filter);
|
|
1447
|
+
const matchedIds = new Set(matched.map((n) => n.id));
|
|
1448
|
+
return pruneTree(nodes, matchedIds);
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
export { TreeContent as T, useTree as a, useTreeLazyCascade as b, applyChildCounts as c, defaultTreeSyncFilter as d, findNode as f, toTreeSyncFilterFn as t, useTreeLoader as u };
|
|
1453
|
+
//# sourceMappingURL=treeSync-Cz3H08cr.js.map
|