@accelint/design-toolkit 9.9.2 → 9.11.0
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/catalog-info.yaml +3 -3
- package/dist/components/accordion/context.d.ts +3 -3
- package/dist/components/accordion/context.js.map +1 -1
- package/dist/components/accordion/group.d.ts +2 -2
- package/dist/components/accordion/group.js +2 -1
- package/dist/components/accordion/group.js.map +1 -1
- package/dist/components/accordion/header.d.ts +2 -2
- package/dist/components/accordion/header.js +2 -1
- package/dist/components/accordion/header.js.map +1 -1
- package/dist/components/accordion/index.d.ts +2 -2
- package/dist/components/accordion/index.js +3 -1
- package/dist/components/accordion/index.js.map +1 -1
- package/dist/components/accordion/panel.d.ts +2 -2
- package/dist/components/accordion/panel.js +2 -1
- package/dist/components/accordion/panel.js.map +1 -1
- package/dist/components/accordion/styles.module.css +19 -3
- package/dist/components/accordion/trigger.d.ts +2 -2
- package/dist/components/accordion/trigger.js +4 -3
- package/dist/components/accordion/trigger.js.map +1 -1
- package/dist/components/accordion/types.d.ts +3 -1
- package/dist/components/action-bar/index.d.ts +2 -2
- package/dist/components/action-bar/index.js +1 -1
- package/dist/components/action-bar/index.js.map +1 -1
- package/dist/components/audio/index.d.ts +2 -2
- package/dist/components/avatar/context.d.ts +5 -5
- package/dist/components/avatar/context.js.map +1 -1
- package/dist/components/avatar/index.d.ts +2 -2
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/badge/context.d.ts +5 -5
- package/dist/components/badge/context.js.map +1 -1
- package/dist/components/badge/index.d.ts +2 -2
- package/dist/components/badge/index.js +1 -1
- package/dist/components/badge/index.js.map +1 -1
- package/dist/components/breadcrumbs/index.d.ts +3 -3
- package/dist/components/breadcrumbs/index.js +1 -1
- package/dist/components/breadcrumbs/index.js.map +1 -1
- package/dist/components/breadcrumbs/item.d.ts +2 -2
- package/dist/components/breadcrumbs/item.js +3 -1
- package/dist/components/breadcrumbs/item.js.map +1 -1
- package/dist/components/breadcrumbs/types.d.ts +2 -1
- package/dist/components/button/__internal__/clear.js +2 -1
- package/dist/components/button/__internal__/clear.js.map +1 -1
- package/dist/components/button/context.d.ts +10 -10
- package/dist/components/button/context.js.map +1 -1
- package/dist/components/button/index.d.ts +2 -2
- package/dist/components/button/index.js +3 -1
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/link.d.ts +2 -2
- package/dist/components/button/link.js +3 -1
- package/dist/components/button/link.js.map +1 -1
- package/dist/components/button/styles.module.css +16 -0
- package/dist/components/button/toggle.d.ts +2 -2
- package/dist/components/button/toggle.js +3 -1
- package/dist/components/button/toggle.js.map +1 -1
- package/dist/components/button/types.d.ts +3 -1
- package/dist/components/carousel/context.d.ts +40 -0
- package/dist/components/carousel/context.js +55 -0
- package/dist/components/carousel/context.js.map +1 -0
- package/dist/components/carousel/gallery.d.ts +38 -0
- package/dist/components/carousel/gallery.js +84 -0
- package/dist/components/carousel/gallery.js.map +1 -0
- package/dist/components/carousel/index.d.ts +56 -0
- package/dist/components/carousel/index.js +66 -0
- package/dist/components/carousel/index.js.map +1 -0
- package/dist/components/carousel/navigation.d.ts +51 -0
- package/dist/components/carousel/navigation.js +82 -0
- package/dist/components/carousel/navigation.js.map +1 -0
- package/dist/components/carousel/position.d.ts +33 -0
- package/dist/components/carousel/position.js +48 -0
- package/dist/components/carousel/position.js.map +1 -0
- package/dist/components/carousel/select.d.ts +38 -0
- package/dist/components/carousel/select.js +69 -0
- package/dist/components/carousel/select.js.map +1 -0
- package/dist/components/carousel/style.module.css +62 -0
- package/dist/components/carousel/types.d.ts +87 -0
- package/dist/components/carousel/types.js +12 -0
- package/dist/components/carousel/viewer.d.ts +40 -0
- package/dist/components/carousel/viewer.js +75 -0
- package/dist/components/carousel/viewer.js.map +1 -0
- package/dist/components/checkbox/context.d.ts +5 -5
- package/dist/components/checkbox/context.js.map +1 -1
- package/dist/components/checkbox/group.d.ts +2 -2
- package/dist/components/checkbox/group.js +5 -3
- package/dist/components/checkbox/group.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +2 -2
- package/dist/components/checkbox/index.js +3 -1
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/types.d.ts +4 -3
- package/dist/components/chip/context.d.ts +3 -3
- package/dist/components/chip/context.js.map +1 -1
- package/dist/components/chip/deletable.d.ts +2 -2
- package/dist/components/chip/deletable.js +5 -3
- package/dist/components/chip/deletable.js.map +1 -1
- package/dist/components/chip/index.d.ts +2 -2
- package/dist/components/chip/index.js +2 -1
- package/dist/components/chip/index.js.map +1 -1
- package/dist/components/chip/list.d.ts +4 -4
- package/dist/components/chip/list.js +3 -1
- package/dist/components/chip/list.js.map +1 -1
- package/dist/components/chip/selectable.d.ts +2 -2
- package/dist/components/chip/selectable.js +3 -1
- package/dist/components/chip/selectable.js.map +1 -1
- package/dist/components/chip/types.d.ts +3 -2
- package/dist/components/classification-badge/context.d.ts +5 -5
- package/dist/components/classification-badge/context.js.map +1 -1
- package/dist/components/classification-badge/index.d.ts +2 -2
- package/dist/components/classification-badge/index.js +1 -1
- package/dist/components/classification-badge/index.js.map +1 -1
- package/dist/components/classification-banner/context.d.ts +5 -5
- package/dist/components/classification-banner/context.js.map +1 -1
- package/dist/components/classification-banner/index.d.ts +2 -2
- package/dist/components/classification-banner/index.js +1 -1
- package/dist/components/classification-banner/index.js.map +1 -1
- package/dist/components/clock/index.d.ts +2 -2
- package/dist/components/color-picker/index.d.ts +2 -2
- package/dist/components/color-picker/index.js +4 -3
- package/dist/components/color-picker/index.js.map +1 -1
- package/dist/components/color-picker/types.d.ts +2 -1
- package/dist/components/combobox-field/context.d.ts +5 -5
- package/dist/components/combobox-field/context.js.map +1 -1
- package/dist/components/combobox-field/index.d.ts +2 -2
- package/dist/components/combobox-field/index.js +12 -12
- package/dist/components/combobox-field/index.js.map +1 -1
- package/dist/components/combobox-field/styles.module.css +12 -0
- package/dist/components/combobox-field/types.d.ts +8 -4
- package/dist/components/coordinate-field/context.d.ts +7 -7
- package/dist/components/coordinate-field/context.js.map +1 -1
- package/dist/components/coordinate-field/index.d.ts +2 -2
- package/dist/components/coordinate-field/index.js +28 -23
- package/dist/components/coordinate-field/index.js.map +1 -1
- package/dist/components/coordinate-field/segment.d.ts +2 -2
- package/dist/components/coordinate-field/types.d.ts +3 -1
- package/dist/components/coordinate-field/types.js.map +1 -1
- package/dist/components/date-field/index.d.ts +2 -2
- package/dist/components/date-field/index.js +4 -3
- package/dist/components/date-field/index.js.map +1 -1
- package/dist/components/date-field/types.d.ts +1 -1
- package/dist/components/deferred-collection/index.d.ts +2 -2
- package/dist/components/details-list/context.d.ts +5 -5
- package/dist/components/details-list/context.js.map +1 -1
- package/dist/components/details-list/index.d.ts +2 -2
- package/dist/components/details-list/index.js +2 -1
- package/dist/components/details-list/index.js.map +1 -1
- package/dist/components/details-list/label.d.ts +2 -2
- package/dist/components/details-list/label.js +1 -1
- package/dist/components/details-list/label.js.map +1 -1
- package/dist/components/details-list/types.d.ts +1 -1
- package/dist/components/details-list/value.d.ts +2 -2
- package/dist/components/details-list/value.js +1 -1
- package/dist/components/details-list/value.js.map +1 -1
- package/dist/components/dialog/content.d.ts +2 -2
- package/dist/components/dialog/context.d.ts +4 -4
- package/dist/components/dialog/context.js.map +1 -1
- package/dist/components/dialog/footer.d.ts +2 -2
- package/dist/components/dialog/footer.js +1 -1
- package/dist/components/dialog/footer.js.map +1 -1
- package/dist/components/dialog/index.d.ts +2 -2
- package/dist/components/dialog/index.js +3 -1
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/styles.module.css +23 -0
- package/dist/components/dialog/title.d.ts +3 -3
- package/dist/components/dialog/title.js +1 -1
- package/dist/components/dialog/title.js.map +1 -1
- package/dist/components/dialog/trigger.d.ts +1 -1
- package/dist/components/dialog/trigger.js +1 -1
- package/dist/components/dialog/trigger.js.map +1 -1
- package/dist/components/dialog/types.d.ts +1 -1
- package/dist/components/divider/context.d.ts +5 -5
- package/dist/components/divider/context.js.map +1 -1
- package/dist/components/divider/index.d.ts +2 -2
- package/dist/components/divider/index.js +1 -1
- package/dist/components/divider/index.js.map +1 -1
- package/dist/components/drawer/back.d.ts +2 -2
- package/dist/components/drawer/close.d.ts +2 -2
- package/dist/components/drawer/content.d.ts +2 -2
- package/dist/components/drawer/context.d.ts +2 -2
- package/dist/components/drawer/footer.d.ts +2 -2
- package/dist/components/drawer/header-title.d.ts +2 -2
- package/dist/components/drawer/header-title.js +1 -1
- package/dist/components/drawer/header-title.js.map +1 -1
- package/dist/components/drawer/header.d.ts +2 -2
- package/dist/components/drawer/header.js +3 -3
- package/dist/components/drawer/header.js.map +1 -1
- package/dist/components/drawer/index.d.ts +2 -2
- package/dist/components/drawer/layout-main.d.ts +2 -2
- package/dist/components/drawer/layout.d.ts +2 -2
- package/dist/components/drawer/menu-item.d.ts +2 -2
- package/dist/components/drawer/menu-item.js +7 -7
- package/dist/components/drawer/menu-item.js.map +1 -1
- package/dist/components/drawer/menu.d.ts +2 -2
- package/dist/components/drawer/panel.d.ts +2 -2
- package/dist/components/drawer/styles.module.css +54 -2
- package/dist/components/drawer/trigger.d.ts +2 -2
- package/dist/components/drawer/trigger.js +1 -1
- package/dist/components/drawer/trigger.js.map +1 -1
- package/dist/components/drawer/types.d.ts +3 -3
- package/dist/components/drawer/view.d.ts +2 -2
- package/dist/components/flashcard/index.d.ts +9 -9
- package/dist/components/flashcard/index.js +2 -1
- package/dist/components/flashcard/index.js.map +1 -1
- package/dist/components/floating-card/context.d.ts +22 -15
- package/dist/components/floating-card/context.js +18 -3
- package/dist/components/floating-card/context.js.map +1 -1
- package/dist/components/floating-card/index.d.ts +32 -27
- package/dist/components/floating-card/index.js +41 -11
- package/dist/components/floating-card/index.js.map +1 -1
- package/dist/components/floating-card/provider.d.ts +30 -32
- package/dist/components/floating-card/provider.js +110 -49
- package/dist/components/floating-card/provider.js.map +1 -1
- package/dist/components/floating-card/styles.module.css +20 -2
- package/dist/components/floating-card/types.d.ts +161 -0
- package/dist/components/floating-card/types.js +12 -0
- package/dist/components/floating-card/utils.d.ts +104 -0
- package/dist/components/floating-card/utils.js +60 -0
- package/dist/components/floating-card/utils.js.map +1 -0
- package/dist/components/gantt/components/base-elements/point.d.ts +28 -0
- package/dist/components/gantt/components/base-elements/point.js +44 -0
- package/dist/components/gantt/components/base-elements/point.js.map +1 -0
- package/dist/components/gantt/components/base-elements/range.d.ts +30 -0
- package/dist/components/gantt/components/base-elements/range.js +51 -0
- package/dist/components/gantt/components/base-elements/range.js.map +1 -0
- package/dist/components/gantt/components/base-elements/use-point-element-layout/index.d.ts +12 -0
- package/dist/components/gantt/components/base-elements/use-point-element-layout/index.js +42 -0
- package/dist/components/gantt/components/base-elements/use-point-element-layout/index.js.map +1 -0
- package/dist/components/gantt/components/base-elements/use-range-element-layout/index.d.ts +23 -0
- package/dist/components/gantt/components/base-elements/use-range-element-layout/index.js +50 -0
- package/dist/components/gantt/components/base-elements/use-range-element-layout/index.js.map +1 -0
- package/dist/components/gantt/components/containers/external/gantt-content-container/index.d.ts +23 -0
- package/dist/components/gantt/components/containers/external/gantt-content-container/index.js +40 -0
- package/dist/components/gantt/components/containers/external/gantt-content-container/index.js.map +1 -0
- package/dist/components/gantt/components/containers/external/gantt-panel-container/index.d.ts +23 -0
- package/dist/components/gantt/components/containers/external/gantt-panel-container/index.js +33 -0
- package/dist/components/gantt/components/containers/external/gantt-panel-container/index.js.map +1 -0
- package/dist/components/gantt/components/containers/external/styles.module.css +32 -0
- package/dist/components/gantt/components/containers/internal/index.d.ts +22 -0
- package/dist/components/gantt/components/containers/internal/index.js +35 -0
- package/dist/components/gantt/components/containers/internal/index.js.map +1 -0
- package/dist/components/gantt/components/containers/internal/layout-container/index.d.ts +22 -0
- package/dist/components/gantt/components/containers/internal/layout-container/index.js +27 -0
- package/dist/components/gantt/components/containers/internal/layout-container/index.js.map +1 -0
- package/dist/components/gantt/components/containers/internal/styles.module.css +35 -0
- package/dist/components/gantt/components/containers/internal/virtualized-content-height-container/index.d.ts +22 -0
- package/dist/components/gantt/components/containers/internal/virtualized-content-height-container/index.js +38 -0
- package/dist/components/gantt/components/containers/internal/virtualized-content-height-container/index.js.map +1 -0
- package/dist/components/gantt/components/content-row/block.d.ts +27 -0
- package/dist/components/gantt/components/content-row/block.js +39 -0
- package/dist/components/gantt/components/content-row/block.js.map +1 -0
- package/dist/components/gantt/components/content-row/bracket.d.ts +23 -0
- package/dist/components/gantt/components/content-row/bracket.js +48 -0
- package/dist/components/gantt/components/content-row/bracket.js.map +1 -0
- package/dist/components/gantt/components/content-row/icon-marker.d.ts +27 -0
- package/dist/components/gantt/components/content-row/icon-marker.js +41 -0
- package/dist/components/gantt/components/content-row/icon-marker.js.map +1 -0
- package/dist/components/gantt/components/content-row/index.d.ts +24 -0
- package/dist/components/gantt/components/content-row/index.js +32 -0
- package/dist/components/gantt/components/content-row/index.js.map +1 -0
- package/dist/components/gantt/components/content-row/marker.d.ts +21 -0
- package/dist/components/gantt/components/content-row/marker.js +35 -0
- package/dist/components/gantt/components/content-row/marker.js.map +1 -0
- package/dist/components/gantt/components/content-row/spacer.d.ts +23 -0
- package/dist/components/gantt/components/content-row/spacer.js +35 -0
- package/dist/components/gantt/components/content-row/spacer.js.map +1 -0
- package/dist/components/gantt/components/content-row/styles.module.css +198 -0
- package/dist/components/gantt/components/content-row/use-elapsed-percentage/index.d.ts +19 -0
- package/dist/components/gantt/components/content-row/use-elapsed-percentage/index.js +27 -0
- package/dist/components/gantt/components/content-row/use-elapsed-percentage/index.js.map +1 -0
- package/dist/components/gantt/components/content-row/use-is-elapsed/index.d.ts +10 -0
- package/dist/components/gantt/components/content-row/use-is-elapsed/index.js +24 -0
- package/dist/components/gantt/components/content-row/use-is-elapsed/index.js.map +1 -0
- package/dist/components/gantt/components/current-time/index.d.ts +28 -0
- package/dist/components/gantt/components/current-time/index.js +63 -0
- package/dist/components/gantt/components/current-time/index.js.map +1 -0
- package/dist/components/gantt/components/current-time/styles.module.css +42 -0
- package/dist/components/gantt/components/current-time/use-current-time-layout/index.d.ts +31 -0
- package/dist/components/gantt/components/current-time/use-current-time-layout/index.js +58 -0
- package/dist/components/gantt/components/current-time/use-current-time-layout/index.js.map +1 -0
- package/dist/components/gantt/components/header/index.d.ts +25 -0
- package/dist/components/gantt/components/header/index.js +41 -0
- package/dist/components/gantt/components/header/index.js.map +1 -0
- package/dist/components/gantt/components/header/styles.module.css +23 -0
- package/dist/components/gantt/components/panel-row/index.d.ts +24 -0
- package/dist/components/gantt/components/panel-row/index.js +33 -0
- package/dist/components/gantt/components/panel-row/index.js.map +1 -0
- package/dist/components/gantt/components/panel-row/styles.module.css +24 -0
- package/dist/components/gantt/components/rows-virtualizer/index.d.ts +25 -0
- package/dist/components/gantt/components/rows-virtualizer/index.js +67 -0
- package/dist/components/gantt/components/rows-virtualizer/index.js.map +1 -0
- package/dist/components/gantt/components/rows-virtualizer/styles.module.css +30 -0
- package/dist/components/gantt/components/rows-virtualizer/use-rendered-rows/index.d.ts +29 -0
- package/dist/components/gantt/components/rows-virtualizer/use-rendered-rows/index.js +57 -0
- package/dist/components/gantt/components/rows-virtualizer/use-rendered-rows/index.js.map +1 -0
- package/dist/components/gantt/components/rows-virtualizer/use-scroll-sync/index.d.ts +10 -0
- package/dist/components/gantt/components/rows-virtualizer/use-scroll-sync/index.js +58 -0
- package/dist/components/gantt/components/rows-virtualizer/use-scroll-sync/index.js.map +1 -0
- package/dist/components/gantt/components/styles.module.css +46 -0
- package/dist/components/gantt/components/timeline/index.d.ts +19 -0
- package/dist/components/gantt/components/timeline/index.js +45 -0
- package/dist/components/gantt/components/timeline/index.js.map +1 -0
- package/dist/components/gantt/components/timeline/use-timeline-transform/index.d.ts +29 -0
- package/dist/components/gantt/components/timeline/use-timeline-transform/index.js +33 -0
- package/dist/components/gantt/components/timeline/use-timeline-transform/index.js.map +1 -0
- package/dist/components/gantt/components/timeline-chunk/index.d.ts +25 -0
- package/dist/components/gantt/components/timeline-chunk/index.js +43 -0
- package/dist/components/gantt/components/timeline-chunk/index.js.map +1 -0
- package/dist/components/gantt/constants.d.ts +31 -0
- package/dist/components/gantt/constants.js +57 -0
- package/dist/components/gantt/constants.js.map +1 -0
- package/dist/components/gantt/context/index.d.ts +60 -0
- package/dist/components/gantt/context/index.js +78 -0
- package/dist/components/gantt/context/index.js.map +1 -0
- package/dist/components/gantt/context/store/index.d.ts +45 -0
- package/dist/components/gantt/context/store/index.js +42 -0
- package/dist/components/gantt/context/store/index.js.map +1 -0
- package/dist/components/gantt/context/temporal-data/index.d.ts +48 -0
- package/dist/components/gantt/context/temporal-data/index.js +80 -0
- package/dist/components/gantt/context/temporal-data/index.js.map +1 -0
- package/dist/components/gantt/gantt.d.ts +50 -0
- package/dist/components/gantt/gantt.js +51 -0
- package/dist/components/gantt/gantt.js.map +1 -0
- package/dist/components/gantt/hooks/use-horizontal-scroll-update/index.d.ts +22 -0
- package/dist/components/gantt/hooks/use-horizontal-scroll-update/index.js +36 -0
- package/dist/components/gantt/hooks/use-horizontal-scroll-update/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-layout-subscription/index.d.ts +26 -0
- package/dist/components/gantt/hooks/use-layout-subscription/index.js +45 -0
- package/dist/components/gantt/hooks/use-layout-subscription/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-resize-intersection-effect/index.d.ts +26 -0
- package/dist/components/gantt/hooks/use-resize-intersection-effect/index.js +50 -0
- package/dist/components/gantt/hooks/use-resize-intersection-effect/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-root-element-height/index.d.ts +5 -0
- package/dist/components/gantt/hooks/use-root-element-height/index.js +24 -0
- package/dist/components/gantt/hooks/use-root-element-height/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-scrollbar-height/index.d.ts +5 -0
- package/dist/components/gantt/hooks/use-scrollbar-height/index.js +40 -0
- package/dist/components/gantt/hooks/use-scrollbar-height/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-total-data-region-thresholds/index.d.ts +19 -0
- package/dist/components/gantt/hooks/use-total-data-region-thresholds/index.js +87 -0
- package/dist/components/gantt/hooks/use-total-data-region-thresholds/index.js.map +1 -0
- package/dist/components/gantt/hooks/use-vertical-scroll-update/index.d.ts +22 -0
- package/dist/components/gantt/hooks/use-vertical-scroll-update/index.js +38 -0
- package/dist/components/gantt/hooks/use-vertical-scroll-update/index.js.map +1 -0
- package/dist/components/gantt/public-types.d.ts +31 -0
- package/dist/components/gantt/public-types.js +12 -0
- package/dist/components/gantt/store.d.ts +51 -0
- package/dist/components/gantt/store.js +46 -0
- package/dist/components/gantt/store.js.map +1 -0
- package/dist/components/gantt/styles.module.css +30 -0
- package/dist/components/gantt/types.d.ts +67 -0
- package/dist/components/gantt/types.js +12 -0
- package/dist/components/gantt/utils/conversions.d.ts +23 -0
- package/dist/components/gantt/utils/conversions.js +34 -0
- package/dist/components/gantt/utils/conversions.js.map +1 -0
- package/dist/components/gantt/utils/dates.d.ts +11 -0
- package/dist/components/gantt/utils/dates.js +41 -0
- package/dist/components/gantt/utils/dates.js.map +1 -0
- package/dist/components/gantt/utils/formatting.d.ts +5 -0
- package/dist/components/gantt/utils/formatting.js +54 -0
- package/dist/components/gantt/utils/formatting.js.map +1 -0
- package/dist/components/gantt/utils/generation.d.ts +19 -0
- package/dist/components/gantt/utils/generation.js +37 -0
- package/dist/components/gantt/utils/generation.js.map +1 -0
- package/dist/components/gantt/utils/helpers.d.ts +26 -0
- package/dist/components/gantt/utils/helpers.js +55 -0
- package/dist/components/gantt/utils/helpers.js.map +1 -0
- package/dist/components/gantt/utils/layout.d.ts +32 -0
- package/dist/components/gantt/utils/layout.js +55 -0
- package/dist/components/gantt/utils/layout.js.map +1 -0
- package/dist/components/gantt/utils/thresholds.d.ts +52 -0
- package/dist/components/gantt/utils/thresholds.js +116 -0
- package/dist/components/gantt/utils/thresholds.js.map +1 -0
- package/dist/components/hero/context.d.ts +3 -3
- package/dist/components/hero/context.js.map +1 -1
- package/dist/components/hero/index.d.ts +2 -2
- package/dist/components/hero/index.js +4 -1
- package/dist/components/hero/index.js.map +1 -1
- package/dist/components/hero/subtitle.d.ts +3 -3
- package/dist/components/hero/subtitle.js +1 -1
- package/dist/components/hero/subtitle.js.map +1 -1
- package/dist/components/hero/title.d.ts +3 -3
- package/dist/components/hero/title.js +1 -1
- package/dist/components/hero/title.js.map +1 -1
- package/dist/components/hotkey/context.d.ts +5 -5
- package/dist/components/hotkey/context.js.map +1 -1
- package/dist/components/hotkey/index.d.ts +2 -2
- package/dist/components/hotkey/index.js +2 -1
- package/dist/components/hotkey/index.js.map +1 -1
- package/dist/components/hotkey/set.d.ts +2 -2
- package/dist/components/icon/context.d.ts +5 -5
- package/dist/components/icon/context.js.map +1 -1
- package/dist/components/icon/index.d.ts +2 -2
- package/dist/components/icon/index.js +1 -1
- package/dist/components/icon/index.js.map +1 -1
- package/dist/components/input/context.d.ts +4 -4
- package/dist/components/input/context.js.map +1 -1
- package/dist/components/input/index.d.ts +2 -2
- package/dist/components/input/index.js +4 -2
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/types.d.ts +3 -3
- package/dist/components/kanban/card-body.d.ts +2 -2
- package/dist/components/kanban/card-header-actions.d.ts +2 -2
- package/dist/components/kanban/card-header-title.d.ts +2 -2
- package/dist/components/kanban/card-header.d.ts +2 -2
- package/dist/components/kanban/card.d.ts +2 -2
- package/dist/components/kanban/column-actions.d.ts +2 -2
- package/dist/components/kanban/column-container.d.ts +2 -2
- package/dist/components/kanban/column-content.d.ts +2 -2
- package/dist/components/kanban/column-header-actions.d.ts +2 -2
- package/dist/components/kanban/column-header-drag-handle.d.ts +2 -2
- package/dist/components/kanban/column-header-title.d.ts +2 -2
- package/dist/components/kanban/column-header.d.ts +2 -2
- package/dist/components/kanban/column.d.ts +2 -2
- package/dist/components/kanban/context.d.ts +2 -2
- package/dist/components/kanban/header-actions.d.ts +2 -2
- package/dist/components/kanban/header-search.d.ts +2 -2
- package/dist/components/kanban/header-title.d.ts +2 -2
- package/dist/components/kanban/header-title.js +1 -1
- package/dist/components/kanban/header-title.js.map +1 -1
- package/dist/components/kanban/header.d.ts +2 -2
- package/dist/components/kanban/kanban.d.ts +4 -4
- package/dist/components/label/context.d.ts +6 -6
- package/dist/components/label/context.js.map +1 -1
- package/dist/components/label/index.d.ts +2 -2
- package/dist/components/label/index.js +2 -1
- package/dist/components/label/index.js.map +1 -1
- package/dist/components/label/types.d.ts +1 -1
- package/dist/components/lines/index.d.ts +2 -2
- package/dist/components/link/context.d.ts +2 -2
- package/dist/components/link/context.js +1 -1
- package/dist/components/link/context.js.map +1 -1
- package/dist/components/link/index.d.ts +2 -2
- package/dist/components/link/index.js +3 -1
- package/dist/components/link/index.js.map +1 -1
- package/dist/components/link/types.d.ts +1 -1
- package/dist/components/list/context.d.ts +3 -3
- package/dist/components/list/context.js.map +1 -1
- package/dist/components/list/index.d.ts +2 -2
- package/dist/components/list/index.js +3 -1
- package/dist/components/list/index.js.map +1 -1
- package/dist/components/list/item-content.d.ts +2 -2
- package/dist/components/list/item-description.d.ts +2 -2
- package/dist/components/list/item-title.d.ts +2 -2
- package/dist/components/list/item.d.ts +2 -2
- package/dist/components/list/item.js +2 -1
- package/dist/components/list/item.js.map +1 -1
- package/dist/components/list/types.d.ts +1 -1
- package/dist/components/media-controls/context.d.ts +4 -4
- package/dist/components/media-controls/fullscreen-button.d.ts +2 -2
- package/dist/components/media-controls/index.d.ts +2 -2
- package/dist/components/media-controls/mute-button.d.ts +2 -2
- package/dist/components/media-controls/play-button.d.ts +2 -2
- package/dist/components/media-controls/playback-rate.d.ts +2 -2
- package/dist/components/media-controls/seek-button.d.ts +2 -2
- package/dist/components/media-controls/time-display.d.ts +2 -2
- package/dist/components/media-controls/time-range.d.ts +2 -2
- package/dist/components/media-controls/volume-slider.d.ts +2 -2
- package/dist/components/menu/context.d.ts +4 -4
- package/dist/components/menu/context.js.map +1 -1
- package/dist/components/menu/index.d.ts +2 -2
- package/dist/components/menu/index.js +4 -1
- package/dist/components/menu/index.js.map +1 -1
- package/dist/components/menu/item-description.d.ts +3 -3
- package/dist/components/menu/item-description.js +1 -1
- package/dist/components/menu/item-description.js.map +1 -1
- package/dist/components/menu/item-label.d.ts +3 -3
- package/dist/components/menu/item-label.js +1 -1
- package/dist/components/menu/item-label.js.map +1 -1
- package/dist/components/menu/item.d.ts +2 -2
- package/dist/components/menu/item.js +5 -1
- package/dist/components/menu/item.js.map +1 -1
- package/dist/components/menu/section.d.ts +2 -2
- package/dist/components/menu/section.js +1 -1
- package/dist/components/menu/section.js.map +1 -1
- package/dist/components/menu/separator.d.ts +3 -3
- package/dist/components/menu/separator.js +1 -1
- package/dist/components/menu/separator.js.map +1 -1
- package/dist/components/menu/styles.module.css +12 -0
- package/dist/components/menu/submenu.d.ts +3 -3
- package/dist/components/menu/submenu.js +1 -1
- package/dist/components/menu/submenu.js.map +1 -1
- package/dist/components/menu/trigger.d.ts +1 -1
- package/dist/components/menu/trigger.js +1 -1
- package/dist/components/menu/trigger.js.map +1 -1
- package/dist/components/menu/types.d.ts +1 -1
- package/dist/components/notice/index.d.ts +2 -2
- package/dist/components/notice/index.js +6 -5
- package/dist/components/notice/index.js.map +1 -1
- package/dist/components/notice/list.d.ts +2 -2
- package/dist/components/notice/list.js +16 -6
- package/dist/components/notice/list.js.map +1 -1
- package/dist/components/notice/notice-icon.d.ts +2 -2
- package/dist/components/notice/styles.module.css +27 -0
- package/dist/components/notice/types.d.ts +4 -4
- package/dist/components/options/context.d.ts +3 -3
- package/dist/components/options/context.js.map +1 -1
- package/dist/components/options/index.d.ts +2 -2
- package/dist/components/options/index.js +3 -1
- package/dist/components/options/index.js.map +1 -1
- package/dist/components/options/item-content.d.ts +3 -3
- package/dist/components/options/item-content.js.map +1 -1
- package/dist/components/options/item-description.d.ts +3 -3
- package/dist/components/options/item-description.js +1 -1
- package/dist/components/options/item-description.js.map +1 -1
- package/dist/components/options/item-label.d.ts +3 -3
- package/dist/components/options/item-label.js +2 -1
- package/dist/components/options/item-label.js.map +1 -1
- package/dist/components/options/item.d.ts +2 -2
- package/dist/components/options/item.js +2 -1
- package/dist/components/options/item.js.map +1 -1
- package/dist/components/options/section.d.ts +2 -2
- package/dist/components/options/section.js +1 -1
- package/dist/components/options/section.js.map +1 -1
- package/dist/components/options/types.d.ts +2 -2
- package/dist/components/pagination/context.d.ts +2 -2
- package/dist/components/pagination/index.d.ts +2 -2
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/pagination/index.js.map +1 -1
- package/dist/components/pagination/next.d.ts +2 -2
- package/dist/components/pagination/next.js +3 -3
- package/dist/components/pagination/next.js.map +1 -1
- package/dist/components/pagination/pages.d.ts +2 -2
- package/dist/components/pagination/pages.js +3 -3
- package/dist/components/pagination/pages.js.map +1 -1
- package/dist/components/pagination/prev.d.ts +2 -2
- package/dist/components/pagination/prev.js +3 -3
- package/dist/components/pagination/prev.js.map +1 -1
- package/dist/components/popover/content.d.ts +2 -2
- package/dist/components/popover/footer.d.ts +2 -2
- package/dist/components/popover/index.d.ts +2 -2
- package/dist/components/popover/index.js +1 -1
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/styles.module.css +34 -0
- package/dist/components/popover/title.d.ts +3 -3
- package/dist/components/popover/title.js +1 -1
- package/dist/components/popover/title.js.map +1 -1
- package/dist/components/popover/trigger.d.ts +2 -2
- package/dist/components/popover/trigger.js +3 -3
- package/dist/components/popover/trigger.js.map +1 -1
- package/dist/components/popover/types.d.ts +1 -1
- package/dist/components/query-builder/action-element.d.ts +2 -2
- package/dist/components/query-builder/actions.d.ts +4 -4
- package/dist/components/query-builder/combinator-selector.d.ts +2 -2
- package/dist/components/query-builder/index.d.ts +2 -2
- package/dist/components/query-builder/rule-group.d.ts +4 -4
- package/dist/components/query-builder/rule.d.ts +2 -2
- package/dist/components/query-builder/value-editor.d.ts +2 -2
- package/dist/components/query-builder/value-selector.d.ts +2 -2
- package/dist/components/query-builder/value-selector.js +1 -1
- package/dist/components/radio/context.d.ts +5 -5
- package/dist/components/radio/context.js.map +1 -1
- package/dist/components/radio/group.d.ts +2 -2
- package/dist/components/radio/group.js +5 -3
- package/dist/components/radio/group.js.map +1 -1
- package/dist/components/radio/index.d.ts +2 -2
- package/dist/components/radio/index.js +3 -1
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/types.d.ts +3 -3
- package/dist/components/search-field/context.d.ts +6 -6
- package/dist/components/search-field/context.js.map +1 -1
- package/dist/components/search-field/index.d.ts +2 -2
- package/dist/components/search-field/index.js +3 -1
- package/dist/components/search-field/index.js.map +1 -1
- package/dist/components/search-field/types.d.ts +3 -3
- package/dist/components/select-field/context.d.ts +5 -5
- package/dist/components/select-field/context.js.map +1 -1
- package/dist/components/select-field/index.d.ts +2 -2
- package/dist/components/select-field/index.js +6 -3
- package/dist/components/select-field/index.js.map +1 -1
- package/dist/components/select-field/types.d.ts +8 -5
- package/dist/components/sidenav/avatar.d.ts +2 -2
- package/dist/components/sidenav/avatar.js +3 -1
- package/dist/components/sidenav/avatar.js.map +1 -1
- package/dist/components/sidenav/content.d.ts +2 -2
- package/dist/components/sidenav/content.js +1 -1
- package/dist/components/sidenav/content.js.map +1 -1
- package/dist/components/sidenav/context.d.ts +2 -2
- package/dist/components/sidenav/footer.d.ts +2 -2
- package/dist/components/sidenav/header.d.ts +2 -2
- package/dist/components/sidenav/header.js +3 -1
- package/dist/components/sidenav/header.js.map +1 -1
- package/dist/components/sidenav/index.d.ts +2 -2
- package/dist/components/sidenav/index.js +2 -1
- package/dist/components/sidenav/index.js.map +1 -1
- package/dist/components/sidenav/item.d.ts +2 -2
- package/dist/components/sidenav/item.js +8 -5
- package/dist/components/sidenav/item.js.map +1 -1
- package/dist/components/sidenav/link.d.ts +2 -2
- package/dist/components/sidenav/link.js +8 -5
- package/dist/components/sidenav/link.js.map +1 -1
- package/dist/components/sidenav/menu-item.d.ts +2 -2
- package/dist/components/sidenav/menu-item.js +2 -1
- package/dist/components/sidenav/menu-item.js.map +1 -1
- package/dist/components/sidenav/menu.d.ts +2 -2
- package/dist/components/sidenav/menu.js +10 -5
- package/dist/components/sidenav/menu.js.map +1 -1
- package/dist/components/sidenav/styles.module.css +10 -2
- package/dist/components/sidenav/trigger.d.ts +2 -2
- package/dist/components/sidenav/trigger.js +1 -1
- package/dist/components/sidenav/trigger.js.map +1 -1
- package/dist/components/sidenav/types.d.ts +6 -1
- package/dist/components/skeleton/index.d.ts +2 -2
- package/dist/components/slider/index.d.ts +2 -2
- package/dist/components/slider/index.js +9 -6
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/types.d.ts +1 -1
- package/dist/components/status-indicator/index.d.ts +2 -2
- package/dist/components/switch/context.d.ts +6 -6
- package/dist/components/switch/context.js.map +1 -1
- package/dist/components/switch/index.d.ts +2 -2
- package/dist/components/switch/index.js +3 -1
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/styles.module.css +8 -0
- package/dist/components/switch/types.d.ts +1 -1
- package/dist/components/table/body.d.ts +2 -2
- package/dist/components/table/cell.d.ts +2 -2
- package/dist/components/table/context.d.ts +2 -2
- package/dist/components/table/header-cell.d.ts +2 -2
- package/dist/components/table/header.d.ts +2 -2
- package/dist/components/table/index.d.ts +2 -2
- package/dist/components/table/index.js +4 -4
- package/dist/components/table/index.js.map +1 -1
- package/dist/components/table/row.d.ts +2 -2
- package/dist/components/tabs/context.d.ts +8 -8
- package/dist/components/tabs/context.js.map +1 -1
- package/dist/components/tabs/index.d.ts +2 -2
- package/dist/components/tabs/index.js +3 -1
- package/dist/components/tabs/index.js.map +1 -1
- package/dist/components/tabs/list.d.ts +3 -3
- package/dist/components/tabs/list.js +2 -1
- package/dist/components/tabs/list.js.map +1 -1
- package/dist/components/tabs/panel.d.ts +3 -3
- package/dist/components/tabs/panel.js +2 -1
- package/dist/components/tabs/panel.js.map +1 -1
- package/dist/components/tabs/tab.d.ts +2 -2
- package/dist/components/tabs/tab.js +3 -1
- package/dist/components/tabs/tab.js.map +1 -1
- package/dist/components/tabs/types.d.ts +1 -1
- package/dist/components/text-area-field/context.d.ts +5 -5
- package/dist/components/text-area-field/context.js.map +1 -1
- package/dist/components/text-area-field/index.d.ts +2 -2
- package/dist/components/text-area-field/index.js +8 -3
- package/dist/components/text-area-field/index.js.map +1 -1
- package/dist/components/text-area-field/types.d.ts +3 -1
- package/dist/components/text-field/context.d.ts +6 -6
- package/dist/components/text-field/context.js.map +1 -1
- package/dist/components/text-field/index.d.ts +2 -2
- package/dist/components/text-field/index.js +9 -5
- package/dist/components/text-field/index.js.map +1 -1
- package/dist/components/text-field/types.d.ts +7 -6
- package/dist/components/time-field/index.d.ts +3 -3
- package/dist/components/time-field/index.js +4 -3
- package/dist/components/time-field/index.js.map +1 -1
- package/dist/components/time-field/types.d.ts +1 -1
- package/dist/components/tooltip/context.d.ts +3 -3
- package/dist/components/tooltip/context.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +2 -2
- package/dist/components/tooltip/index.js +3 -2
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/styles.module.css +35 -0
- package/dist/components/tooltip/trigger.d.ts +2 -2
- package/dist/components/tooltip/trigger.js +6 -3
- package/dist/components/tooltip/trigger.js.map +1 -1
- package/dist/components/tooltip/types.d.ts +8 -3
- package/dist/components/tree/context.d.ts +3 -3
- package/dist/components/tree/index.d.ts +4 -2
- package/dist/components/tree/index.js +31 -16
- package/dist/components/tree/index.js.map +1 -1
- package/dist/components/tree/item-actions.d.ts +2 -2
- package/dist/components/tree/item-content.d.ts +2 -2
- package/dist/components/tree/item-content.js +10 -9
- package/dist/components/tree/item-content.js.map +1 -1
- package/dist/components/tree/item-description.d.ts +3 -3
- package/dist/components/tree/item-description.js +1 -1
- package/dist/components/tree/item-description.js.map +1 -1
- package/dist/components/tree/item-label.d.ts +3 -3
- package/dist/components/tree/item-label.js +1 -1
- package/dist/components/tree/item-label.js.map +1 -1
- package/dist/components/tree/item-prefix-icon.d.ts +2 -2
- package/dist/components/tree/item.d.ts +2 -2
- package/dist/components/tree/item.js +14 -7
- package/dist/components/tree/item.js.map +1 -1
- package/dist/components/tree/lines.d.ts +2 -2
- package/dist/components/tree/types.d.ts +30 -15
- package/dist/components/video/index.d.ts +2 -2
- package/dist/components/view-stack/context.d.ts +2 -2
- package/dist/components/view-stack/index.d.ts +2 -2
- package/dist/components/view-stack/trigger.d.ts +2 -2
- package/dist/components/view-stack/trigger.js +1 -1
- package/dist/components/view-stack/trigger.js.map +1 -1
- package/dist/components/view-stack/types.d.ts +1 -1
- package/dist/components/view-stack/view.d.ts +2 -2
- package/dist/hooks/coordinate-field/use-coordinate-field.d.ts +1 -1
- package/dist/hooks/coordinate-field/use-coordinate-field.js +1 -1
- package/dist/hooks/coordinate-field/use-coordinate-field.js.map +1 -1
- package/dist/hooks/use-tree/actions/cache.d.ts +406 -17
- package/dist/hooks/use-tree/actions/cache.js +488 -16
- package/dist/hooks/use-tree/actions/cache.js.map +1 -1
- package/dist/hooks/use-tree/actions/index.d.ts +36 -22
- package/dist/hooks/use-tree/actions/index.js +103 -36
- package/dist/hooks/use-tree/actions/index.js.map +1 -1
- package/dist/hooks/use-tree/state/index.d.ts +25 -2
- package/dist/hooks/use-tree/state/index.js +27 -3
- package/dist/hooks/use-tree/state/index.js.map +1 -1
- package/dist/hooks/use-tree/state/utils.d.ts +28 -0
- package/dist/hooks/use-tree/state/utils.js +29 -1
- package/dist/hooks/use-tree/state/utils.js.map +1 -1
- package/dist/hooks/use-tree/types.d.ts +66 -24
- package/dist/index.d.ts +27 -7
- package/dist/index.js +27 -10
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/providers/portal.d.ts +2 -2
- package/dist/providers/portal.js +2 -2
- package/dist/providers/portal.js.map +1 -1
- package/dist/providers/theme-provider.d.ts +4 -4
- package/dist/providers/theme-provider.js +6 -7
- package/dist/providers/theme-provider.js.map +1 -1
- package/package.json +77 -36
- package/dist/node_modules/.pnpm/@react-aria_collections@3.0.0-rc.7_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/collections/dist/BaseCollection.js +0 -134
- package/dist/node_modules/.pnpm/@react-aria_collections@3.0.0-rc.7_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/collections/dist/BaseCollection.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","names":["index: number","parentKey: Key | null","key"],"sources":["../../../../src/hooks/use-tree/actions/cache.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { Key } from '@react-types/shared';\nimport type { TreeNode } from '../types';\n\ntype CacheTreeNode<T> = Omit<TreeNode<T>, 'children'> & {\n children?: Key[];\n};\n\n/**\n * This is a cache created only for performance reasons and is considered\n * to be only a temporary mirror of the data. The data is *always* correct\n * cache should be updated according to the data, only. If the data and\n * the cache do not match, the cache is invalidated and rebuilt.\n *\n * This will initialize once on load with data, then\n * updated with each tree operation.\n */\nexport class Cache<T> {\n protected cache: { lookup: Map<Key, CacheTreeNode<T>>; roots: Key[] } = {\n lookup: new Map(),\n roots: [],\n };\n\n constructor(nodes: TreeNode<T>[] = []) {\n this.rebuild(nodes);\n }\n\n /**\n * Recursively creates the cache object from tree data\n */\n rebuild(\n nodes: TreeNode<T>[],\n lookup: Map<Key, CacheTreeNode<T>> = new Map(),\n parentKey: Key | null = null,\n ) {\n nodes.forEach((node) => {\n const { children, ...rest } = node;\n\n lookup.set(node.key, {\n isDisabled: false,\n isExpanded: false,\n isSelected: false,\n isVisible: false,\n isVisibleComputed: false,\n ...rest,\n parentKey,\n ...(children ? { children: children.map((child) => child.key) } : {}),\n });\n\n if (node.children) {\n this.rebuild(node.children, lookup, node.key);\n }\n });\n\n const cache = { lookup, roots: nodes.map((node) => node.key) };\n\n if (!parentKey) {\n this.cache = cache;\n }\n\n this.deriveVisibility();\n return cache;\n }\n\n protected get(key: Key) {\n const node = this.cache.lookup.get(key);\n\n if (node === undefined) {\n throw new Error(`Key of ${key} does not exist in tree`);\n }\n\n return node;\n }\n\n protected set(key: Key, node: CacheTreeNode<T>) {\n this.cache.lookup.set(key, node);\n }\n\n protected delete(key: Key) {\n this.cache.lookup.delete(key);\n }\n\n protected addToParent(parentKey: Key, childKey: Key, idx: number) {\n const parent = this.get(parentKey);\n const child = this.get(childKey);\n const index = Math.max(0, idx);\n\n this.set(childKey, {\n ...child,\n parentKey,\n });\n\n const children = (parent.children ?? []).slice(0);\n\n children.splice(index, 0, childKey);\n\n this.set(parentKey, {\n ...parent,\n children,\n });\n }\n\n protected addToRoot(key: Key, idx: number) {\n const node = this.get(key);\n const index = Math.max(0, idx);\n\n this.set(key, {\n ...node,\n parentKey: null,\n });\n\n this.cache.roots.splice(index, 0, key);\n }\n\n protected removeFromParent(parentKey: Key, childKey: Key) {\n const parent = this.get(parentKey);\n const child = this.get(childKey);\n\n this.set(childKey, {\n ...child,\n parentKey: null,\n });\n\n this.cache.lookup.set(parentKey, {\n ...parent,\n children: parent.children?.filter((key) => key !== childKey),\n });\n }\n\n protected removeFromRoot(key: Key) {\n const node = this.get(key);\n const idx = this.cache.roots.indexOf(key);\n\n if (idx >= 0) {\n this.set(key, {\n ...node,\n parentKey: null,\n });\n\n this.cache.roots.splice(idx, 1);\n }\n }\n\n protected parentOrSibling(target: Key | null, position: 'before' | 'after') {\n let index: number;\n let parentKey: Key | null = null;\n\n if (target === null) {\n index = position === 'before' ? 0 : this.cache.roots.length;\n } else {\n const targetNode = this.get(target);\n\n if (targetNode.parentKey) {\n const parent = this.get(targetNode.parentKey);\n\n parentKey = parent.key;\n index = parent.children?.indexOf(target) ?? 0;\n } else {\n index = this.cache.roots.indexOf(target);\n }\n }\n\n return { parentKey, index };\n }\n\n protected traverse(key: Key) {\n const node = this.get(key);\n\n this.cache.lookup.set(key, {\n ...node,\n isVisibleComputed: this.calculateVisibility(key),\n });\n\n node.children?.map((child) => this.traverse(child));\n }\n\n protected calculateVisibility(key: Key) {\n let current = this.get(key);\n const ancestry = [current];\n\n while (current.parentKey) {\n const parent = this.get(current.parentKey);\n if (parent) {\n ancestry.push(parent);\n }\n current = parent;\n }\n\n return ancestry.every((n) => n.isVisible);\n }\n\n protected deriveVisibility() {\n return this.cache.roots.map((key) => this.traverse(key));\n }\n /**\n * Recursively builds a TreeNode from a key\n *\n * @param key\n */\n protected buildNode(key: Key): TreeNode<T> {\n const node = this.get(key);\n\n const children = (node.children ?? []).reduce(\n (acc: TreeNode<T>[], child) => {\n const childNode = this.cache.lookup.get(child);\n\n if (childNode && childNode.parentKey === key) {\n acc.push(this.buildNode(child));\n }\n\n return acc;\n },\n [],\n );\n\n return {\n ...node,\n children,\n };\n }\n\n /**\n * Builds a tree structure from cache\n *\n * TODO: optimization - rebuild only from change to root\n * Rebuild only from the changed node up the tree to avoid\n * rebuilding the entire tree\n *\n * @param deriveVisible boolean - if true, will recompute visibility for nodes based on ancestry\n */\n toTree(deriveVisible?: boolean): TreeNode<T>[] {\n if (deriveVisible) {\n this.deriveVisibility();\n }\n return this.cache.roots.map((key) => this.buildNode(key));\n }\n\n /**\n * CACHE FUNCTIONS\n * These manage cache operations. No cache operations should ever be done\n * outside this file.\n **/\n getNode(key: Key): TreeNode<T> {\n const node = this.get(key);\n\n return {\n ...node,\n children: node.children?.map((key) => this.buildNode(key)),\n };\n }\n\n getAllKeys() {\n return this.cache.lookup.keys();\n }\n\n getAllNodes() {\n return this.cache.lookup.values();\n }\n\n setNode(key: Key, node: TreeNode<T>) {\n this.set(key, {\n ...node,\n children: (node.children ?? []).map((child) => child.key),\n });\n }\n\n setAllNodes({ parentKey, children, ...rest }: Partial<TreeNode<T>>) {\n for (const node of this.cache.lookup.values()) {\n this.set(node.key, {\n ...node,\n ...rest,\n });\n }\n }\n\n deleteNode(key: Key) {\n const node = this.cache.lookup.get(key);\n\n if (!node) {\n return;\n }\n\n // remove children\n node.children?.map((key) => this.deleteNode(key));\n\n // remove node from previous parent or root\n node.parentKey\n ? this.removeFromParent(node.parentKey, key)\n : this.removeFromRoot(key);\n\n // remove the actual node\n this.delete(key);\n }\n\n addNodes(\n target: Key | null,\n nodes: TreeNode<T>[],\n position: 'before' | 'after',\n ) {\n const { parentKey, index } = this.parentOrSibling(target, position);\n const idx = index + (position === 'before' ? 0 : 1);\n\n nodes.map((node, i) => this.insertNode(parentKey, node, idx + i));\n }\n\n insertNode(parentKey: Key | null, node: TreeNode<T>, idx: number) {\n const { children, ...rest } = node;\n\n this.set(node.key, {\n isDisabled: false,\n isExpanded: false,\n isSelected: false,\n isVisible: false,\n isVisibleComputed: false,\n ...rest,\n parentKey,\n ...(children ? { children: children.map((child) => child.key) } : {}),\n });\n\n node.children?.map((child, i) => this.insertNode(node.key, child, i));\n\n parentKey === null\n ? this.addToRoot(node.key, idx)\n : this.addToParent(parentKey, node.key, idx);\n }\n\n moveNodes(target: Key | null, nodes: Set<Key>, position: 'before' | 'after') {\n const { parentKey, index } = this.parentOrSibling(target, position);\n const idx = index + (position === 'before' ? 0 : 1);\n\n Array.from(nodes).map((key, i) => this.moveNode(parentKey, key, idx + i));\n }\n\n moveNode(parentKey: Key | null, key: Key, idx: number) {\n const node = this.get(key);\n\n // remove from previous parent\n node.parentKey\n ? this.removeFromParent(node.parentKey, key)\n : this.removeFromRoot(key);\n\n // add as child to new parent or root at position\n parentKey\n ? this.addToParent(parentKey, key, idx)\n : this.addToRoot(key, idx);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,QAAb,MAAsB;CACpB,AAAU,QAA8D;EACtE,wBAAQ,IAAI,KAAK;EACjB,OAAO,EAAE;EACV;CAED,YAAY,QAAuB,EAAE,EAAE;AACrC,OAAK,QAAQ,MAAM;;;;;CAMrB,QACE,OACA,yBAAqC,IAAI,KAAK,EAC9C,YAAwB,MACxB;AACA,QAAM,SAAS,SAAS;GACtB,MAAM,EAAE,UAAU,GAAG,SAAS;AAE9B,UAAO,IAAI,KAAK,KAAK;IACnB,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,mBAAmB;IACnB,GAAG;IACH;IACA,GAAI,WAAW,EAAE,UAAU,SAAS,KAAK,UAAU,MAAM,IAAI,EAAE,GAAG,EAAE;IACrE,CAAC;AAEF,OAAI,KAAK,SACP,MAAK,QAAQ,KAAK,UAAU,QAAQ,KAAK,IAAI;IAE/C;EAEF,MAAM,QAAQ;GAAE;GAAQ,OAAO,MAAM,KAAK,SAAS,KAAK,IAAI;GAAE;AAE9D,MAAI,CAAC,UACH,MAAK,QAAQ;AAGf,OAAK,kBAAkB;AACvB,SAAO;;CAGT,AAAU,IAAI,KAAU;EACtB,MAAM,OAAO,KAAK,MAAM,OAAO,IAAI,IAAI;AAEvC,MAAI,SAAS,OACX,OAAM,IAAI,MAAM,UAAU,IAAI,yBAAyB;AAGzD,SAAO;;CAGT,AAAU,IAAI,KAAU,MAAwB;AAC9C,OAAK,MAAM,OAAO,IAAI,KAAK,KAAK;;CAGlC,AAAU,OAAO,KAAU;AACzB,OAAK,MAAM,OAAO,OAAO,IAAI;;CAG/B,AAAU,YAAY,WAAgB,UAAe,KAAa;EAChE,MAAM,SAAS,KAAK,IAAI,UAAU;EAClC,MAAM,QAAQ,KAAK,IAAI,SAAS;EAChC,MAAM,QAAQ,KAAK,IAAI,GAAG,IAAI;AAE9B,OAAK,IAAI,UAAU;GACjB,GAAG;GACH;GACD,CAAC;EAEF,MAAM,YAAY,OAAO,YAAY,EAAE,EAAE,MAAM,EAAE;AAEjD,WAAS,OAAO,OAAO,GAAG,SAAS;AAEnC,OAAK,IAAI,WAAW;GAClB,GAAG;GACH;GACD,CAAC;;CAGJ,AAAU,UAAU,KAAU,KAAa;EACzC,MAAM,OAAO,KAAK,IAAI,IAAI;EAC1B,MAAM,QAAQ,KAAK,IAAI,GAAG,IAAI;AAE9B,OAAK,IAAI,KAAK;GACZ,GAAG;GACH,WAAW;GACZ,CAAC;AAEF,OAAK,MAAM,MAAM,OAAO,OAAO,GAAG,IAAI;;CAGxC,AAAU,iBAAiB,WAAgB,UAAe;EACxD,MAAM,SAAS,KAAK,IAAI,UAAU;EAClC,MAAM,QAAQ,KAAK,IAAI,SAAS;AAEhC,OAAK,IAAI,UAAU;GACjB,GAAG;GACH,WAAW;GACZ,CAAC;AAEF,OAAK,MAAM,OAAO,IAAI,WAAW;GAC/B,GAAG;GACH,UAAU,OAAO,UAAU,QAAQ,QAAQ,QAAQ,SAAS;GAC7D,CAAC;;CAGJ,AAAU,eAAe,KAAU;EACjC,MAAM,OAAO,KAAK,IAAI,IAAI;EAC1B,MAAM,MAAM,KAAK,MAAM,MAAM,QAAQ,IAAI;AAEzC,MAAI,OAAO,GAAG;AACZ,QAAK,IAAI,KAAK;IACZ,GAAG;IACH,WAAW;IACZ,CAAC;AAEF,QAAK,MAAM,MAAM,OAAO,KAAK,EAAE;;;CAInC,AAAU,gBAAgB,QAAoB,UAA8B;EAC1E,IAAIA;EACJ,IAAIC,YAAwB;AAE5B,MAAI,WAAW,KACb,SAAQ,aAAa,WAAW,IAAI,KAAK,MAAM,MAAM;OAChD;GACL,MAAM,aAAa,KAAK,IAAI,OAAO;AAEnC,OAAI,WAAW,WAAW;IACxB,MAAM,SAAS,KAAK,IAAI,WAAW,UAAU;AAE7C,gBAAY,OAAO;AACnB,YAAQ,OAAO,UAAU,QAAQ,OAAO,IAAI;SAE5C,SAAQ,KAAK,MAAM,MAAM,QAAQ,OAAO;;AAI5C,SAAO;GAAE;GAAW;GAAO;;CAG7B,AAAU,SAAS,KAAU;EAC3B,MAAM,OAAO,KAAK,IAAI,IAAI;AAE1B,OAAK,MAAM,OAAO,IAAI,KAAK;GACzB,GAAG;GACH,mBAAmB,KAAK,oBAAoB,IAAI;GACjD,CAAC;AAEF,OAAK,UAAU,KAAK,UAAU,KAAK,SAAS,MAAM,CAAC;;CAGrD,AAAU,oBAAoB,KAAU;EACtC,IAAI,UAAU,KAAK,IAAI,IAAI;EAC3B,MAAM,WAAW,CAAC,QAAQ;AAE1B,SAAO,QAAQ,WAAW;GACxB,MAAM,SAAS,KAAK,IAAI,QAAQ,UAAU;AAC1C,OAAI,OACF,UAAS,KAAK,OAAO;AAEvB,aAAU;;AAGZ,SAAO,SAAS,OAAO,MAAM,EAAE,UAAU;;CAG3C,AAAU,mBAAmB;AAC3B,SAAO,KAAK,MAAM,MAAM,KAAK,QAAQ,KAAK,SAAS,IAAI,CAAC;;;;;;;CAO1D,AAAU,UAAU,KAAuB;EACzC,MAAM,OAAO,KAAK,IAAI,IAAI;EAE1B,MAAM,YAAY,KAAK,YAAY,EAAE,EAAE,QACpC,KAAoB,UAAU;GAC7B,MAAM,YAAY,KAAK,MAAM,OAAO,IAAI,MAAM;AAE9C,OAAI,aAAa,UAAU,cAAc,IACvC,KAAI,KAAK,KAAK,UAAU,MAAM,CAAC;AAGjC,UAAO;KAET,EAAE,CACH;AAED,SAAO;GACL,GAAG;GACH;GACD;;;;;;;;;;;CAYH,OAAO,eAAwC;AAC7C,MAAI,cACF,MAAK,kBAAkB;AAEzB,SAAO,KAAK,MAAM,MAAM,KAAK,QAAQ,KAAK,UAAU,IAAI,CAAC;;;;;;;CAQ3D,QAAQ,KAAuB;EAC7B,MAAM,OAAO,KAAK,IAAI,IAAI;AAE1B,SAAO;GACL,GAAG;GACH,UAAU,KAAK,UAAU,KAAK,UAAQ,KAAK,UAAUC,MAAI,CAAC;GAC3D;;CAGH,aAAa;AACX,SAAO,KAAK,MAAM,OAAO,MAAM;;CAGjC,cAAc;AACZ,SAAO,KAAK,MAAM,OAAO,QAAQ;;CAGnC,QAAQ,KAAU,MAAmB;AACnC,OAAK,IAAI,KAAK;GACZ,GAAG;GACH,WAAW,KAAK,YAAY,EAAE,EAAE,KAAK,UAAU,MAAM,IAAI;GAC1D,CAAC;;CAGJ,YAAY,EAAE,WAAW,UAAU,GAAG,QAA8B;AAClE,OAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,QAAQ,CAC3C,MAAK,IAAI,KAAK,KAAK;GACjB,GAAG;GACH,GAAG;GACJ,CAAC;;CAIN,WAAW,KAAU;EACnB,MAAM,OAAO,KAAK,MAAM,OAAO,IAAI,IAAI;AAEvC,MAAI,CAAC,KACH;AAIF,OAAK,UAAU,KAAK,UAAQ,KAAK,WAAWA,MAAI,CAAC;AAGjD,OAAK,YACD,KAAK,iBAAiB,KAAK,WAAW,IAAI,GAC1C,KAAK,eAAe,IAAI;AAG5B,OAAK,OAAO,IAAI;;CAGlB,SACE,QACA,OACA,UACA;EACA,MAAM,EAAE,WAAW,UAAU,KAAK,gBAAgB,QAAQ,SAAS;EACnE,MAAM,MAAM,SAAS,aAAa,WAAW,IAAI;AAEjD,QAAM,KAAK,MAAM,MAAM,KAAK,WAAW,WAAW,MAAM,MAAM,EAAE,CAAC;;CAGnE,WAAW,WAAuB,MAAmB,KAAa;EAChE,MAAM,EAAE,UAAU,GAAG,SAAS;AAE9B,OAAK,IAAI,KAAK,KAAK;GACjB,YAAY;GACZ,YAAY;GACZ,YAAY;GACZ,WAAW;GACX,mBAAmB;GACnB,GAAG;GACH;GACA,GAAI,WAAW,EAAE,UAAU,SAAS,KAAK,UAAU,MAAM,IAAI,EAAE,GAAG,EAAE;GACrE,CAAC;AAEF,OAAK,UAAU,KAAK,OAAO,MAAM,KAAK,WAAW,KAAK,KAAK,OAAO,EAAE,CAAC;AAErE,gBAAc,OACV,KAAK,UAAU,KAAK,KAAK,IAAI,GAC7B,KAAK,YAAY,WAAW,KAAK,KAAK,IAAI;;CAGhD,UAAU,QAAoB,OAAiB,UAA8B;EAC3E,MAAM,EAAE,WAAW,UAAU,KAAK,gBAAgB,QAAQ,SAAS;EACnE,MAAM,MAAM,SAAS,aAAa,WAAW,IAAI;AAEjD,QAAM,KAAK,MAAM,CAAC,KAAK,KAAK,MAAM,KAAK,SAAS,WAAW,KAAK,MAAM,EAAE,CAAC;;CAG3E,SAAS,WAAuB,KAAU,KAAa;EACrD,MAAM,OAAO,KAAK,IAAI,IAAI;AAG1B,OAAK,YACD,KAAK,iBAAiB,KAAK,WAAW,IAAI,GAC1C,KAAK,eAAe,IAAI;AAG5B,cACI,KAAK,YAAY,WAAW,KAAK,IAAI,GACrC,KAAK,UAAU,KAAK,IAAI"}
|
|
1
|
+
{"version":3,"file":"cache.js","names":["index: number","parentKey: Key | null","key"],"sources":["../../../../src/hooks/use-tree/actions/cache.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { Key } from '@react-types/shared';\nimport type { TreeNode } from '../types';\n\n/**\n * Internal cache representation of a tree node.\n *\n * Differs from TreeNode by storing only child keys (not full child objects)\n * for efficient cache lookups and memory usage.\n *\n * @template T - The type of data stored in the node.\n */\nexport type CacheTreeNode<T> = Omit<TreeNode<T>, 'children'> & {\n children?: Key[];\n};\n\n/**\n * Performance-optimized cache for tree node operations.\n *\n * Maintains a flat lookup map and roots array for O(1) node access. The cache\n * is a temporary mirror of tree data and must stay synchronized with the source\n * tree structure. If inconsistencies occur, the cache is invalidated and rebuilt.\n *\n * Initializes once on construction with tree data, then updates incrementally\n * with each tree operation (add, move, delete, select).\n *\n * @template T - The type of data stored in tree nodes.\n *\n * @example\n * ```typescript\n * const cache = new Cache<UserData>(initialNodes);\n *\n * // Get a node\n * const node = cache.getNode('node-1');\n *\n * // Update selection\n * cache.cascadeSelection('node-1', true);\n *\n * // Rebuild tree structure\n * const tree = cache.toTree();\n * ```\n */\nexport class Cache<T> {\n protected cache: { lookup: Map<Key, CacheTreeNode<T>>; roots: Key[] } = {\n lookup: new Map(),\n roots: [],\n };\n\n /**\n * Creates a new cache instance and populates it with tree nodes.\n *\n * @param nodes - Initial tree nodes to cache (defaults to empty array).\n *\n * @example\n * ```typescript\n * const cache = new Cache(treeData);\n * ```\n */\n constructor(nodes: TreeNode<T>[] = []) {\n this.rebuild(nodes);\n }\n\n /**\n * Rebuilds the entire cache from tree nodes.\n *\n * Recursively flattens the tree structure into a lookup map and roots array.\n * Initializes all node properties with defaults (isDisabled: false, isExpanded: false, etc.)\n * and converts nested children to key references. After rebuilding, recomputes visibility\n * for all nodes based on ancestor state.\n *\n * Called automatically in the constructor and whenever external tree state changes.\n * This is an expensive operation - prefer incremental cache updates when possible.\n *\n * @param nodes - Tree nodes to build cache from.\n * @param lookup - Internal lookup map (used for recursion, typically omitted).\n * @param parentKey - Parent key for current recursion level (used for recursion, typically omitted).\n *\n * @example\n * ```typescript\n * // Rebuild cache from new tree data\n * cache.rebuild(newTreeNodes);\n * ```\n */\n rebuild(\n nodes: TreeNode<T>[],\n lookup: Map<Key, CacheTreeNode<T>> = new Map(),\n parentKey: Key | null = null,\n ) {\n nodes.forEach((node) => {\n const { children, ...rest } = node;\n\n lookup.set(node.key, {\n isDisabled: false,\n isExpanded: false,\n isSelected: false,\n isVisible: false,\n isVisibleComputed: false,\n isIndeterminate: false,\n ...rest,\n parentKey,\n ...(children ? { children: children.map((child) => child.key) } : {}),\n });\n\n if (node.children) {\n this.rebuild(node.children, lookup, node.key);\n }\n });\n\n const cache = { lookup, roots: nodes.map((node) => node.key) };\n\n if (!parentKey) {\n this.cache = cache;\n }\n\n this.deriveVisibility();\n return cache;\n }\n\n /**\n * Retrieves a cache node by key.\n *\n * @param key - The node key to retrieve.\n * @returns The cached node.\n * @throws {Error} If key is null/undefined or doesn't exist in cache.\n */\n protected get(key: Key) {\n if (key == null) {\n throw new Error(`Key is ${key} (null/undefined) - this is invalid`);\n }\n\n const node = this.cache.lookup.get(key);\n\n if (node === undefined) {\n throw new Error(`Key of ${key} does not exist in tree`);\n }\n\n return node;\n }\n\n /**\n * Updates a cache node by key.\n *\n * @param key - The node key to update.\n * @param node - The cache node data to store.\n */\n protected set(key: Key, node: CacheTreeNode<T>) {\n this.cache.lookup.set(key, node);\n }\n\n /**\n * Removes a node from the cache lookup.\n *\n * @param key - The node key to remove.\n */\n protected delete(key: Key) {\n this.cache.lookup.delete(key);\n }\n\n /**\n * Adds a child key to a parent's children array at a specific index.\n *\n * @param parentKey - The parent node key.\n * @param childKey - The child node key to add.\n * @param idx - The index position within parent's children.\n */\n protected addToParent(parentKey: Key, childKey: Key, idx: number) {\n const parent = this.get(parentKey);\n const child = this.get(childKey);\n const index = Math.max(0, idx);\n\n this.set(childKey, {\n ...child,\n parentKey,\n });\n\n const children = (parent.children ?? []).slice(0);\n\n children.splice(index, 0, childKey);\n\n this.set(parentKey, {\n ...parent,\n children,\n });\n }\n\n /**\n * Adds a node key to the roots array at a specific index.\n *\n * @param key - The node key to add to roots.\n * @param idx - The index position within roots array.\n */\n protected addToRoot(key: Key, idx: number) {\n const node = this.get(key);\n const index = Math.max(0, idx);\n\n this.set(key, {\n ...node,\n parentKey: null,\n });\n\n this.cache.roots.splice(index, 0, key);\n }\n\n /**\n * Removes a child key from a parent's children array.\n *\n * @param parentKey - The parent node key.\n * @param childKey - The child node key to remove.\n */\n protected removeFromParent(parentKey: Key, childKey: Key) {\n const parent = this.get(parentKey);\n const child = this.get(childKey);\n\n this.set(childKey, {\n ...child,\n parentKey: null,\n });\n\n this.cache.lookup.set(parentKey, {\n ...parent,\n children: parent.children?.filter((key) => key !== childKey),\n });\n }\n\n /**\n * Removes a node key from the roots array.\n *\n * @param key - The node key to remove from roots.\n */\n protected removeFromRoot(key: Key) {\n const node = this.get(key);\n const idx = this.cache.roots.indexOf(key);\n\n if (idx >= 0) {\n this.set(key, {\n ...node,\n parentKey: null,\n });\n\n this.cache.roots.splice(idx, 1);\n }\n }\n\n /**\n * Calculates parent key and index for positioning relative to a target.\n *\n * @param target - The target node key, or null for root level.\n * @param position - Whether positioning before or after target.\n * @returns Object with parentKey and index for insertion.\n */\n protected parentOrSibling(target: Key | null, position: 'before' | 'after') {\n let index: number;\n let parentKey: Key | null = null;\n\n if (target === null) {\n index = position === 'before' ? 0 : this.cache.roots.length;\n } else {\n const targetNode = this.get(target);\n\n if (targetNode.parentKey) {\n const parent = this.get(targetNode.parentKey);\n\n parentKey = parent.key;\n index = parent.children?.indexOf(target) ?? 0;\n } else {\n index = this.cache.roots.indexOf(target);\n }\n }\n\n return { parentKey, index };\n }\n\n /**\n * Recursively updates computed visibility for a node and all descendants.\n *\n * @param key - The node key to traverse from.\n */\n protected traverse(key: Key) {\n const node = this.get(key);\n\n this.cache.lookup.set(key, {\n ...node,\n isVisibleComputed: this.calculateVisibility(key),\n });\n\n node.children?.map((child) => this.traverse(child));\n }\n\n /**\n * Calculates if a node is actually visible based on all ancestors' visibility.\n *\n * @param key - The node key to calculate visibility for.\n * @returns True if node and all ancestors have isVisible: true.\n */\n protected calculateVisibility(key: Key) {\n let current = this.get(key);\n const ancestry = [current];\n\n while (current.parentKey) {\n const parent = this.get(current.parentKey);\n if (parent) {\n ancestry.push(parent);\n }\n current = parent;\n }\n\n return ancestry.every((n) => n.isVisible);\n }\n\n /**\n * Recomputes visibility for all nodes in the tree.\n */\n protected deriveVisibility() {\n return this.cache.roots.map((key) => this.traverse(key));\n }\n\n /**\n * Recursively builds a TreeNode from a cache key.\n *\n * Converts the flat cache representation back into nested TreeNode structure\n * by recursively building child nodes from child keys.\n *\n * @param key - The node key to build from.\n * @returns Complete TreeNode with nested children.\n */\n protected buildNode(key: Key): TreeNode<T> {\n const node = this.get(key);\n\n const children = (node.children ?? []).reduce(\n (acc: TreeNode<T>[], child) => {\n const childNode = this.cache.lookup.get(child);\n\n if (childNode && childNode.parentKey === key) {\n acc.push(this.buildNode(child));\n }\n\n return acc;\n },\n [],\n );\n\n return {\n ...node,\n children,\n };\n }\n\n /**\n * Rebuilds the tree structure from the flattened cache.\n *\n * Converts the internal flat lookup map back into hierarchical TreeNode objects.\n * Optionally recomputes visibility state based on ancestor expansion before building.\n *\n * @param deriveVisible - If true, recomputes visibility for all nodes based on ancestry before building.\n * @returns Array of root TreeNode objects with nested children.\n *\n * @example\n * ```typescript\n * // Build tree with current visibility\n * const tree = cache.toTree();\n *\n * // Build tree and recompute visibility\n * const tree = cache.toTree(true);\n * ```\n */\n toTree(deriveVisible?: boolean): TreeNode<T>[] {\n if (deriveVisible) {\n this.deriveVisibility();\n }\n return this.cache.roots.map((key) => this.buildNode(key));\n }\n\n /**\n * CACHE FUNCTIONS\n * These are the public functions to manage cache operations. No cache operations should ever be done\n * outside this file since it risks corruption of the data.\n **/\n\n /**\n * Retrieves a node from cache and builds its full TreeNode representation.\n *\n * Differs from internal `get()` by recursively building child nodes into\n * full TreeNode objects instead of returning just child keys.\n *\n * @param key - The unique key of the node to retrieve.\n * @returns The full TreeNode with nested children.\n * @throws {Error} If key doesn't exist in cache.\n *\n * @example\n * ```typescript\n * const node = cache.getNode('node-1');\n * console.log(node.children); // Full TreeNode objects, not keys\n * ```\n */\n getNode(key: Key): TreeNode<T> {\n const node = this.get(key);\n\n return {\n ...node,\n children: node.children?.map((key) => this.buildNode(key)),\n };\n }\n\n /**\n * Returns an iterator of all node keys in the cache.\n *\n * @returns Iterator over all cached node keys.\n *\n * @example\n * ```typescript\n * for (const key of cache.getAllKeys()) {\n * console.log(key);\n * }\n * ```\n */\n getAllKeys() {\n return this.cache.lookup.keys();\n }\n\n /**\n * Returns an iterator of all cached nodes.\n *\n * Note: Returns CacheTreeNode objects (with child keys, not full children objects).\n *\n * @returns Iterator over all cached nodes.\n *\n * @example\n * ```typescript\n * for (const node of cache.getAllNodes()) {\n * if (node.isSelected) {\n * console.log(node.key);\n * }\n * }\n * ```\n */\n getAllNodes() {\n return this.cache.lookup.values();\n }\n\n /**\n * Determines the parent key for inserting a node at a position relative to a target.\n *\n * Used to calculate where a new node should be inserted when positioned\n * 'before' or 'after' a target node.\n *\n * @param target - The target node key to position relative to, or null for root level.\n * @param position - Whether to position before or after the target.\n * @returns The parent key where insertion should occur, or null for root level.\n *\n * @example\n * ```typescript\n * // Find parent for inserting before node-2\n * const parent = cache.getParentForPosition('node-2', 'before');\n * ```\n */\n getParentForPosition(\n target: Key | null,\n position: 'before' | 'after',\n ): Key | null {\n const { parentKey } = this.parentOrSibling(target, position);\n return parentKey;\n }\n\n /**\n * Updates a node in the cache.\n *\n * Accepts a TreeNode<T>. Automatically converts TreeNode children to keys for\n * internal cache storage.\n *\n * @param key - The unique key of the node to update.\n * @param node - The node data to store.\n *\n * @example\n * ```typescript\n * // Update with TreeNode\n * cache.setNode('node-1', { key: 'node-1', isSelected: true, children: [...] });\n *\n * // Update with CacheTreeNode (child keys)\n * cache.setNode('node-1', { key: 'node-1', isSelected: true, children: ['child-1', 'child-2'] });\n * ```\n */\n setNode(key: Key, node: TreeNode<T>) {\n this.set(key, {\n ...node,\n children: (node.children ?? []).map((child) => child.key),\n });\n }\n\n /**\n * Updates all nodes in the cache with shared properties.\n *\n * Applies partial updates to every cached node. Useful for bulk operations\n * like clearing all selections or resetting visibility states.\n *\n * Note: `parentKey` and `children` properties are ignored (not applied to nodes).\n *\n * @param props - Partial node properties to apply to all nodes.\n *\n * @example\n * ```typescript\n * // Clear all selections\n * cache.setAllNodes({ isSelected: false, isIndeterminate: false });\n *\n * // Reset visibility\n * cache.setAllNodes({ isVisible: false });\n * ```\n */\n setAllNodes({ parentKey, children, ...rest }: Partial<TreeNode<T>>) {\n for (const node of this.cache.lookup.values()) {\n this.set(node.key, {\n ...node,\n ...rest,\n });\n }\n }\n\n /**\n * Removes a node and all its descendants from the cache.\n *\n * Recursively deletes the node and all child nodes, then removes\n * the node from its parent's children array (or roots array if top-level).\n * Silently returns if the node doesn't exist.\n *\n * @param key - The unique key of the node to delete.\n *\n * @example\n * ```typescript\n * // Delete node and all its children\n * cache.deleteNode('node-1');\n * ```\n */\n deleteNode(key: Key) {\n const node = this.cache.lookup.get(key);\n\n if (!node) {\n return;\n }\n\n // remove children\n node.children?.map((key) => this.deleteNode(key));\n\n // remove node from previous parent or root\n node.parentKey\n ? this.removeFromParent(node.parentKey, key)\n : this.removeFromRoot(key);\n\n // remove the actual node\n this.delete(key);\n }\n\n /**\n * Inserts multiple nodes at a position relative to a target node.\n *\n * Nodes are inserted in array order at the calculated position. If target is null,\n * nodes are inserted at root level.\n *\n * @param target - The target node key to position relative to, or null for root level.\n * @param nodes - Array of TreeNode objects to insert.\n * @param position - Whether to insert before or after the target.\n *\n * @example\n * ```typescript\n * // Insert nodes before node-2\n * cache.addNodes('node-2', [newNode1, newNode2], 'before');\n *\n * // Insert nodes at end of root level\n * cache.addNodes(null, [newNode], 'after');\n * ```\n */\n addNodes(\n target: Key | null,\n nodes: TreeNode<T>[],\n position: 'before' | 'after',\n ) {\n const { parentKey, index } = this.parentOrSibling(target, position);\n const idx = index + (position === 'before' ? 0 : 1);\n\n nodes.map((node, i) => this.insertNode(parentKey, node, idx + i));\n }\n\n /**\n * Inserts a node and its descendants into the cache at a specific index.\n *\n * Initializes node with default property values (isDisabled: false, isSelected: false, etc.)\n * and recursively inserts all child nodes. Children are converted to key references\n * for internal cache storage.\n *\n * @param parentKey - The parent node key, or null to insert at root level.\n * @param node - The TreeNode to insert (with nested children).\n * @param idx - The index position to insert at within the parent's children.\n *\n * @example\n * ```typescript\n * // Insert as first child of parent-1\n * cache.insertNode('parent-1', newNode, 0);\n *\n * // Insert at root level\n * cache.insertNode(null, newNode, 0);\n * ```\n */\n insertNode(parentKey: Key | null, node: TreeNode<T>, idx: number) {\n const { children, ...rest } = node;\n\n this.set(node.key, {\n isDisabled: false,\n isExpanded: false,\n isSelected: false,\n isVisible: false,\n isVisibleComputed: false,\n isIndeterminate: false,\n ...rest,\n parentKey,\n ...(children\n ? {\n children: children.map((child) => child.key),\n }\n : {}),\n });\n\n node.children?.map((child, i) => this.insertNode(node.key, child, i));\n\n parentKey === null\n ? this.addToRoot(node.key, idx)\n : this.addToParent(parentKey, node.key, idx);\n }\n\n /**\n * Moves multiple nodes to a position relative to a target node.\n *\n * Nodes are moved in Set iteration order to the calculated position.\n * Each node is removed from its current parent and added to the new parent.\n *\n * @param target - The target node key to position relative to, or null for root level.\n * @param nodes - Set of node keys to move.\n * @param position - Whether to position before or after the target.\n *\n * @example\n * ```typescript\n * // Move nodes before node-5\n * cache.moveNodes('node-5', new Set(['node-1', 'node-2']), 'before');\n *\n * // Move to end of root level\n * cache.moveNodes(null, new Set(['node-3']), 'after');\n * ```\n */\n moveNodes(target: Key | null, nodes: Set<Key>, position: 'before' | 'after') {\n const { parentKey, index } = this.parentOrSibling(target, position);\n const idx = index + (position === 'before' ? 0 : 1);\n\n Array.from(nodes).map((key, i) => this.moveNode(parentKey, key, idx + i));\n }\n\n /**\n * Moves a single node to a new parent and position.\n *\n * First removes the node from its current parent (or roots), then inserts\n * it at the specified index under the new parent. The node's parentKey is updated.\n *\n * @param parentKey - The new parent node key, or null to move to root level.\n * @param key - The node key to move.\n * @param idx - The index position within the new parent's children.\n *\n * @example\n * ```typescript\n * // Move node-1 to be first child of parent-2\n * cache.moveNode('parent-2', 'node-1', 0);\n *\n * // Move node-1 to root level\n * cache.moveNode(null, 'node-1', 0);\n * ```\n */\n moveNode(parentKey: Key | null, key: Key, idx: number) {\n const node = this.get(key);\n\n // remove from previous parent\n node.parentKey\n ? this.removeFromParent(node.parentKey, key)\n : this.removeFromRoot(key);\n\n // add as child to new parent or root at position\n parentKey\n ? this.addToParent(parentKey, key, idx)\n : this.addToRoot(key, idx);\n }\n\n /**\n * Recursively applies selection state to a node and all its descendants.\n *\n * Disabled nodes are skipped (their selection state is not changed).\n * Indeterminate state is cleared when selection is applied.\n *\n * @param key - The node key to cascade selection from.\n * @param selected - Whether to select (true) or deselect (false).\n *\n * @example\n * ```typescript\n * // Select node and all children\n * cache.cascadeSelection('node-1', true);\n *\n * // Deselect node and all children\n * cache.cascadeSelection('node-1', false);\n * ```\n */\n cascadeSelection(key: Key, selected: boolean): void {\n try {\n const node = this.get(key);\n\n // Update this node (skip if disabled)\n if (!node.isDisabled) {\n this.set(key, {\n ...node,\n isSelected: selected,\n isIndeterminate: false,\n });\n }\n\n // Recurse to children\n if (node.children) {\n for (const childKey of node.children) {\n if (childKey != null) {\n this.cascadeSelection(childKey, selected);\n }\n }\n }\n } catch {\n // Key doesn't exist, skip\n return;\n }\n }\n\n /**\n * Propagates selection state changes up through all ancestor nodes.\n *\n * Starting from a node, walks up the ancestor chain and recomputes each\n * parent's selection state based on its children (all selected → selected,\n * some selected → indeterminate, none selected → deselected).\n *\n * Includes early termination: stops walking up when a parent's state doesn't\n * change, since ancestors won't be affected.\n *\n * @param key - The node key to bubble selection from.\n *\n * @example\n * ```typescript\n * // After updating a child's selection, update parents\n * cache.setNode('child-1', { ...node, isSelected: true });\n * cache.bubbleUpSelection('child-1');\n * ```\n */\n bubbleUpSelection(key: Key): void {\n try {\n let current = this.get(key);\n\n while (current.parentKey) {\n const parent = this.get(current.parentKey);\n const newState = this.computeSelectionState(parent);\n\n // Early termination: if parent state unchanged, ancestors won't change\n if (\n parent.isSelected === newState.isSelected &&\n parent.isIndeterminate === newState.isIndeterminate\n ) {\n break;\n }\n\n this.set(parent.key, {\n ...parent,\n isSelected: newState.isSelected,\n isIndeterminate: newState.isIndeterminate,\n });\n\n current = parent;\n }\n } catch {\n // Key doesn't exist, skip\n return;\n }\n }\n\n /**\n * Computes selection state for a node based on its children's states.\n *\n * Returns selected if all selectable children are selected, indeterminate if some\n * are selected, and deselected if none are selected. Disabled children are excluded\n * from computation. Leaf nodes use their own selection state.\n *\n * @param node - The node to compute state for.\n * @returns Object with isSelected and isIndeterminate flags.\n */\n private computeSelectionState(node: CacheTreeNode<T>): {\n isSelected: boolean;\n isIndeterminate: boolean;\n } {\n // Leaf nodes: use their own state\n if (!node.children || node.children.length === 0) {\n return {\n isSelected: node.isSelected ?? false,\n isIndeterminate: false,\n };\n }\n\n // Get selectable children (exclude disabled)\n const selectableChildren = node.children\n .filter((k) => {\n try {\n const child = this.get(k);\n return !child.isDisabled;\n } catch {\n return false;\n }\n })\n .map((k) => this.get(k));\n\n // If all children disabled, treat as leaf\n if (selectableChildren.length === 0) {\n return {\n isSelected: node.isSelected ?? false,\n isIndeterminate: false,\n };\n }\n\n // Check if all/none/some selected\n const selectedCount = selectableChildren.filter((c) => c.isSelected).length;\n const indeterminateCount = selectableChildren.filter(\n (c) => c.isIndeterminate,\n ).length;\n\n // If any child is indeterminate, parent is indeterminate\n if (indeterminateCount > 0) {\n return {\n isSelected: false,\n isIndeterminate: true,\n };\n }\n\n // All children selected\n if (selectedCount === selectableChildren.length) {\n return {\n isSelected: true,\n isIndeterminate: false,\n };\n }\n\n // No children selected\n if (selectedCount === 0) {\n return {\n isSelected: false,\n isIndeterminate: false,\n };\n }\n\n // Some children selected (indeterminate)\n return {\n isSelected: false,\n isIndeterminate: true,\n };\n }\n\n /**\n * Updates selection state for all affected parents after moving nodes.\n *\n * When nodes are moved, both old parents (lost children) and new parent (gained children)\n * may have their selection state invalidated. This method recomputes selection state\n * for all affected parents and bubbles changes up the ancestor chain.\n *\n * @param oldParents - Set of parent keys that lost children during the move.\n * @param newParent - The parent key that gained children, or null if moved to root.\n *\n * @example\n * ```typescript\n * // After moving nodes from parent-1 to parent-2\n * cache.syncParentsAfterMove(new Set(['parent-1']), 'parent-2');\n *\n * // After moving nodes to root level\n * cache.syncParentsAfterMove(new Set(['parent-1']), null);\n * ```\n */\n syncParentsAfterMove(oldParents: Set<Key>, newParent: Key | null): void {\n // Update old parents (lost children)\n for (const parentKey of oldParents) {\n try {\n const parent = this.get(parentKey);\n const newState = this.computeSelectionState(parent);\n\n this.set(parentKey, {\n ...parent,\n isSelected: newState.isSelected,\n isIndeterminate: newState.isIndeterminate,\n });\n\n // Bubble up to ancestors\n if (parent.parentKey) {\n this.bubbleUpSelection(parentKey);\n }\n } catch {\n // Parent doesn't exist, skip\n }\n }\n\n // Update new parent (gained children)\n if (newParent) {\n try {\n const parent = this.get(newParent);\n const newState = this.computeSelectionState(parent);\n\n this.set(newParent, {\n ...parent,\n isSelected: newState.isSelected,\n isIndeterminate: newState.isIndeterminate,\n });\n\n // Bubble up to ancestors\n if (parent.parentKey) {\n this.bubbleUpSelection(newParent);\n }\n } catch {\n // Parent doesn't exist, skip\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -16,39 +16,53 @@ import "client-only";
|
|
|
16
16
|
//#region src/hooks/use-tree/actions/index.d.ts
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Stateless hook that
|
|
20
|
-
* it takes in nodes and returns a new version of the tree.
|
|
19
|
+
* Stateless hook that provides tree transformation operations without managing state.
|
|
21
20
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* Returns pure functions that accept tree nodes and return new transformed tree nodes.
|
|
22
|
+
* Does not modify the input tree - all operations are immutable transformations.
|
|
23
|
+
* Each operation returns the complete updated tree structure. Use this hook when you
|
|
24
|
+
* want to manage tree state yourself, or when integrating with external state management.
|
|
25
|
+
* For complete state management, use {@link useTreeState} instead.
|
|
24
26
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* Note: Each operation returns the whole tree. Future iterations might return only
|
|
28
|
+
* the changed portion of the tree for performance optimization.
|
|
29
|
+
*
|
|
30
|
+
* @template T - The type of custom values stored in tree nodes (accessed via `node.values`).
|
|
31
|
+
*
|
|
32
|
+
* @param options - Configuration options for tree actions.
|
|
33
|
+
* @param options.nodes - Current tree nodes to operate on. Used to build internal cache for operations.
|
|
34
|
+
* @param options.selectionCascade - Enable cascade selection mode. When true, selection operations
|
|
35
|
+
* automatically propagate to descendants and update parent indeterminate states. Default: false.
|
|
36
|
+
* @returns Object containing all tree manipulation functions (insert, move, remove, select, expand, etc.).
|
|
28
37
|
*
|
|
29
38
|
* @example
|
|
30
39
|
* ```tsx
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* key: 'root',
|
|
35
|
-
* label: 'Root',
|
|
36
|
-
* children: [
|
|
37
|
-
* { key: 'child1', label: 'Child 1' },
|
|
38
|
-
* { key: 'child2', label: 'Child 2' }
|
|
39
|
-
* ]
|
|
40
|
-
* }
|
|
41
|
-
* ]
|
|
42
|
-
* });
|
|
40
|
+
* // Basic usage with custom state management
|
|
41
|
+
* const [tree, setTree] = useState(initialTree);
|
|
42
|
+
* const actions = useTreeActions({ nodes: tree });
|
|
43
43
|
*
|
|
44
|
-
* //
|
|
45
|
-
* const updatedTree =
|
|
44
|
+
* // Insert a new node
|
|
45
|
+
* const updatedTree = actions.insertAfter('child1', [
|
|
46
46
|
* { key: 'newChild', label: 'New Child' }
|
|
47
47
|
* ]);
|
|
48
|
+
* setTree(updatedTree);
|
|
49
|
+
*
|
|
50
|
+
* // Move nodes
|
|
51
|
+
* const movedTree = actions.moveInto('parent', new Set(['child1', 'child2']));
|
|
52
|
+
* setTree(movedTree);
|
|
53
|
+
*
|
|
54
|
+
* // Cascade selection
|
|
55
|
+
* const actionsWithCascade = useTreeActions({
|
|
56
|
+
* nodes: tree,
|
|
57
|
+
* selectionCascade: true
|
|
58
|
+
* });
|
|
59
|
+
* const selectedTree = actionsWithCascade.onSelectionChange(new Set(['parent']));
|
|
60
|
+
* // All descendants of 'parent' are now selected too
|
|
48
61
|
* ```
|
|
49
62
|
*/
|
|
50
63
|
declare function useTreeActions<T>({
|
|
51
|
-
nodes
|
|
64
|
+
nodes,
|
|
65
|
+
selectionCascade
|
|
52
66
|
}: UseTreeActionsOptions<T>): TreeActions<T>;
|
|
53
67
|
//#endregion
|
|
54
68
|
export { useTreeActions };
|
|
@@ -16,46 +16,84 @@
|
|
|
16
16
|
import { Cache } from "./cache.js";
|
|
17
17
|
import "client-only";
|
|
18
18
|
import { useRef } from "react";
|
|
19
|
-
import { useUpdateEffect } from "@react-aria/utils";
|
|
20
19
|
|
|
21
20
|
//#region src/hooks/use-tree/actions/index.ts
|
|
22
21
|
/**
|
|
23
|
-
* Stateless hook that
|
|
24
|
-
* it takes in nodes and returns a new version of the tree.
|
|
22
|
+
* Stateless hook that provides tree transformation operations without managing state.
|
|
25
23
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
24
|
+
* Returns pure functions that accept tree nodes and return new transformed tree nodes.
|
|
25
|
+
* Does not modify the input tree - all operations are immutable transformations.
|
|
26
|
+
* Each operation returns the complete updated tree structure. Use this hook when you
|
|
27
|
+
* want to manage tree state yourself, or when integrating with external state management.
|
|
28
|
+
* For complete state management, use {@link useTreeState} instead.
|
|
28
29
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Note: Each operation returns the whole tree. Future iterations might return only
|
|
31
|
+
* the changed portion of the tree for performance optimization.
|
|
32
|
+
*
|
|
33
|
+
* @template T - The type of custom values stored in tree nodes (accessed via `node.values`).
|
|
34
|
+
*
|
|
35
|
+
* @param options - Configuration options for tree actions.
|
|
36
|
+
* @param options.nodes - Current tree nodes to operate on. Used to build internal cache for operations.
|
|
37
|
+
* @param options.selectionCascade - Enable cascade selection mode. When true, selection operations
|
|
38
|
+
* automatically propagate to descendants and update parent indeterminate states. Default: false.
|
|
39
|
+
* @returns Object containing all tree manipulation functions (insert, move, remove, select, expand, etc.).
|
|
32
40
|
*
|
|
33
41
|
* @example
|
|
34
42
|
* ```tsx
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* key: 'root',
|
|
39
|
-
* label: 'Root',
|
|
40
|
-
* children: [
|
|
41
|
-
* { key: 'child1', label: 'Child 1' },
|
|
42
|
-
* { key: 'child2', label: 'Child 2' }
|
|
43
|
-
* ]
|
|
44
|
-
* }
|
|
45
|
-
* ]
|
|
46
|
-
* });
|
|
43
|
+
* // Basic usage with custom state management
|
|
44
|
+
* const [tree, setTree] = useState(initialTree);
|
|
45
|
+
* const actions = useTreeActions({ nodes: tree });
|
|
47
46
|
*
|
|
48
|
-
* //
|
|
49
|
-
* const updatedTree =
|
|
47
|
+
* // Insert a new node
|
|
48
|
+
* const updatedTree = actions.insertAfter('child1', [
|
|
50
49
|
* { key: 'newChild', label: 'New Child' }
|
|
51
50
|
* ]);
|
|
51
|
+
* setTree(updatedTree);
|
|
52
|
+
*
|
|
53
|
+
* // Move nodes
|
|
54
|
+
* const movedTree = actions.moveInto('parent', new Set(['child1', 'child2']));
|
|
55
|
+
* setTree(movedTree);
|
|
56
|
+
*
|
|
57
|
+
* // Cascade selection
|
|
58
|
+
* const actionsWithCascade = useTreeActions({
|
|
59
|
+
* nodes: tree,
|
|
60
|
+
* selectionCascade: true
|
|
61
|
+
* });
|
|
62
|
+
* const selectedTree = actionsWithCascade.onSelectionChange(new Set(['parent']));
|
|
63
|
+
* // All descendants of 'parent' are now selected too
|
|
52
64
|
* ```
|
|
53
65
|
*/
|
|
54
|
-
function useTreeActions({ nodes }) {
|
|
66
|
+
function useTreeActions({ nodes, selectionCascade = false }) {
|
|
55
67
|
const cache = useRef(new Cache(nodes)).current;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Collects parent keys for a set of nodes before a move operation
|
|
70
|
+
*/
|
|
71
|
+
function getParents(keys) {
|
|
72
|
+
const prevParents = /* @__PURE__ */ new Set();
|
|
73
|
+
for (const key of keys) {
|
|
74
|
+
const node = cache.getNode(key);
|
|
75
|
+
if (node.parentKey) prevParents.add(node.parentKey);
|
|
76
|
+
}
|
|
77
|
+
return prevParents;
|
|
78
|
+
}
|
|
79
|
+
/** CASCADE SELECTION **/
|
|
80
|
+
/**
|
|
81
|
+
* Selection change with cascade logic
|
|
82
|
+
*/
|
|
83
|
+
function onSelectionChangeCascade(keys) {
|
|
84
|
+
const previouslySelected = /* @__PURE__ */ new Set();
|
|
85
|
+
for (const k of cache.getAllKeys()) try {
|
|
86
|
+
if (cache.getNode(k).isSelected) previouslySelected.add(k);
|
|
87
|
+
} catch {}
|
|
88
|
+
const validKeys = [...keys].filter((k) => k != null);
|
|
89
|
+
const added = validKeys.filter((k) => !previouslySelected.has(k));
|
|
90
|
+
const removed = [...previouslySelected].filter((k) => !validKeys.includes(k));
|
|
91
|
+
for (const key of added) cache.cascadeSelection(key, true);
|
|
92
|
+
for (const key of removed) cache.cascadeSelection(key, false);
|
|
93
|
+
const affectedKeys = new Set([...added, ...removed]);
|
|
94
|
+
for (const key of affectedKeys) cache.bubbleUpSelection(key);
|
|
95
|
+
return cache.toTree();
|
|
96
|
+
}
|
|
59
97
|
/** GET NODE **/
|
|
60
98
|
function getNode(key) {
|
|
61
99
|
return cache.getNode(key);
|
|
@@ -75,15 +113,35 @@ function useTreeActions({ nodes }) {
|
|
|
75
113
|
}
|
|
76
114
|
/** MOVE NODES **/
|
|
77
115
|
function moveAfter(target, keys) {
|
|
116
|
+
if (!selectionCascade) {
|
|
117
|
+
cache.moveNodes(target, keys, "after");
|
|
118
|
+
return cache.toTree();
|
|
119
|
+
}
|
|
120
|
+
const prevParents = getParents(keys);
|
|
121
|
+
const newParent = cache.getParentForPosition(target, "after");
|
|
78
122
|
cache.moveNodes(target, keys, "after");
|
|
123
|
+
cache.syncParentsAfterMove(prevParents, newParent);
|
|
79
124
|
return cache.toTree();
|
|
80
125
|
}
|
|
81
126
|
function moveBefore(target, keys) {
|
|
127
|
+
if (!selectionCascade) {
|
|
128
|
+
cache.moveNodes(target, keys, "before");
|
|
129
|
+
return cache.toTree();
|
|
130
|
+
}
|
|
131
|
+
const prevParents = getParents(keys);
|
|
132
|
+
const newParent = cache.getParentForPosition(target, "before");
|
|
82
133
|
cache.moveNodes(target, keys, "before");
|
|
134
|
+
cache.syncParentsAfterMove(prevParents, newParent);
|
|
83
135
|
return cache.toTree();
|
|
84
136
|
}
|
|
85
137
|
function moveInto(target, keys) {
|
|
138
|
+
if (!selectionCascade) {
|
|
139
|
+
for (const key of keys) cache.moveNode(target, key, 0);
|
|
140
|
+
return cache.toTree();
|
|
141
|
+
}
|
|
142
|
+
const prevParents = getParents(keys);
|
|
86
143
|
for (const key of keys) cache.moveNode(target, key, 0);
|
|
144
|
+
cache.syncParentsAfterMove(prevParents, target);
|
|
87
145
|
return cache.toTree();
|
|
88
146
|
}
|
|
89
147
|
/** UPDATE NODES **/
|
|
@@ -99,22 +157,31 @@ function useTreeActions({ nodes }) {
|
|
|
99
157
|
}
|
|
100
158
|
/** SELECTION **/
|
|
101
159
|
function onSelectionChange(keys) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
160
|
+
if (!selectionCascade) {
|
|
161
|
+
unselectAll();
|
|
162
|
+
for (const key of keys) {
|
|
163
|
+
const node = cache.getNode(key);
|
|
164
|
+
cache.setNode(node.key, {
|
|
165
|
+
...node,
|
|
166
|
+
isSelected: true
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return cache.toTree();
|
|
109
170
|
}
|
|
110
|
-
return
|
|
171
|
+
return onSelectionChangeCascade(keys);
|
|
111
172
|
}
|
|
112
173
|
function selectAll() {
|
|
113
|
-
cache.setAllNodes({
|
|
174
|
+
cache.setAllNodes({
|
|
175
|
+
isSelected: true,
|
|
176
|
+
isIndeterminate: false
|
|
177
|
+
});
|
|
114
178
|
return cache.toTree();
|
|
115
179
|
}
|
|
116
180
|
function unselectAll() {
|
|
117
|
-
cache.setAllNodes({
|
|
181
|
+
cache.setAllNodes({
|
|
182
|
+
isSelected: false,
|
|
183
|
+
isIndeterminate: false
|
|
184
|
+
});
|
|
118
185
|
return cache.toTree();
|
|
119
186
|
}
|
|
120
187
|
/** EXPANSION **/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["nodes"],"sources":["../../../../src/hooks/use-tree/actions/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n'use client';\n\nimport 'client-only';\nimport { useUpdateEffect } from '@react-aria/utils';\nimport { useRef } from 'react';\nimport { Cache } from './cache';\nimport type { Key } from '@react-types/shared';\nimport type {\n TreeActions,\n TreeData,\n TreeNode,\n TreeNodeBase,\n UseTreeActionsOptions,\n} from '../types';\n\n/**\n * Stateless hook that transforms tree data according to actions\n * it takes in nodes and returns a new version of the tree.\n *\n * Note: each operation returns the whole tree. Future iterations\n * might want to return only the changed portion of the tree.\n *\n * @param options - {@link UseTreeActionsOptions}\n * @param options.nodes - Current tree nodes to operate on.\n * @returns {@link TreeActions} Object containing all tree manipulation functions.\n *\n * @example\n * ```tsx\n * const treeActions = useTreeActions({\n * nodes: [\n * {\n * key: 'root',\n * label: 'Root',\n * children: [\n * { key: 'child1', label: 'Child 1' },\n * { key: 'child2', label: 'Child 2' }\n * ]\n * }\n * ]\n * });\n *\n * // Use tree actions\n * const updatedTree = treeActions.insertAfter('child1', [\n * { key: 'newChild', label: 'New Child' }\n * ]);\n * ```\n */\nexport function useTreeActions<T>({\n nodes,\n}: UseTreeActionsOptions<T>): TreeActions<T> {\n const cache = useRef(new Cache<T>(nodes)).current;\n\n useUpdateEffect(() => {\n cache.rebuild(nodes);\n }, [nodes]);\n\n /** GET NODE **/\n function getNode(key: Key) {\n return cache.getNode(key);\n }\n\n /** INSERT NODES **/\n function insertAfter(\n target: Key | null,\n nodes: TreeNode<T>[],\n ): TreeNode<T>[] {\n cache.addNodes(target, nodes, 'after');\n\n return cache.toTree(true);\n }\n\n function insertBefore(\n target: Key | null,\n nodes: TreeNode<T>[],\n ): TreeNode<T>[] {\n cache.addNodes(target, nodes, 'before');\n\n return cache.toTree(true);\n }\n\n function insertInto(target: Key | null, nodes: TreeNode<T>[]): TreeNode<T>[] {\n for (const node of nodes) {\n cache.insertNode(target, node, 0);\n }\n\n return cache.toTree(true);\n }\n\n /** MOVE NODES **/\n function moveAfter(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n cache.moveNodes(target, keys, 'after');\n\n return cache.toTree();\n }\n\n function moveBefore(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n cache.moveNodes(target, keys, 'before');\n\n return cache.toTree();\n }\n\n function moveInto(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n for (const key of keys) {\n cache.moveNode(target, key, 0);\n }\n\n return cache.toTree();\n }\n\n /** UPDATE NODES **/\n function updateNode(\n key: Key,\n callback: (node: TreeNodeBase<T>) => TreeNodeBase<T>,\n ): TreeNode<T>[] {\n const node = cache.getNode(key);\n\n cache.setNode(key, callback(node));\n\n return cache.toTree(true);\n }\n\n /** REMOVE NODES **/\n function remove(keys: Set<Key>): TreeNode<T>[] {\n for (const key of keys.values()) {\n cache.deleteNode(key);\n }\n\n return cache.toTree(true);\n }\n\n /** SELECTION **/\n function onSelectionChange(keys: Set<Key>): TreeNode<T>[] {\n unselectAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n\n cache.setNode(node.key, {\n ...node,\n isSelected: true,\n });\n }\n\n return cache.toTree();\n }\n\n function selectAll(): TreeNode<T>[] {\n cache.setAllNodes({ isSelected: true });\n\n return cache.toTree();\n }\n\n function unselectAll(): TreeNode<T>[] {\n cache.setAllNodes({ isSelected: false });\n\n return cache.toTree();\n }\n\n /** EXPANSION **/\n function onExpandedChange(keys: Set<Key>): TreeNode<T>[] {\n collapseAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n\n cache.setNode(node.key, {\n ...node,\n isExpanded: true,\n });\n }\n\n return cache.toTree();\n }\n\n function expandAll(): TreeNode<T>[] {\n cache.setAllNodes({ isExpanded: true });\n\n return cache.toTree();\n }\n\n function collapseAll(): TreeNode<T>[] {\n cache.setAllNodes({ isExpanded: false });\n\n return cache.toTree();\n }\n\n /** VISIBILITY **/\n function onVisibilityChange(keys: Set<Key>): TreeData<T> {\n hideAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n cache.setNode(node.key, {\n ...node,\n isVisible: true,\n });\n }\n return cache.toTree(true);\n }\n\n function revealAll(): TreeNode<T>[] {\n cache.setAllNodes({ isVisible: true });\n\n return cache.toTree(true);\n }\n\n function hideAll(): TreeNode<T>[] {\n cache.setAllNodes({ isVisible: false });\n\n return cache.toTree(true);\n }\n\n return {\n getNode,\n insertAfter,\n insertBefore,\n insertInto,\n moveAfter,\n moveBefore,\n moveInto,\n remove,\n updateNode,\n\n // Expansion\n collapseAll,\n expandAll,\n onExpandedChange,\n\n // Selection\n selectAll,\n unselectAll,\n onSelectionChange,\n\n // Visibility\n hideAll,\n revealAll,\n onVisibilityChange,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["nodes"],"sources":["../../../../src/hooks/use-tree/actions/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n'use client';\n\nimport 'client-only';\nimport { useRef } from 'react';\nimport { Cache } from './cache';\nimport type { Key } from '@react-types/shared';\nimport type {\n TreeActions,\n TreeData,\n TreeNode,\n TreeNodeBase,\n UseTreeActionsOptions,\n} from '../types';\n\n/**\n * Stateless hook that provides tree transformation operations without managing state.\n *\n * Returns pure functions that accept tree nodes and return new transformed tree nodes.\n * Does not modify the input tree - all operations are immutable transformations.\n * Each operation returns the complete updated tree structure. Use this hook when you\n * want to manage tree state yourself, or when integrating with external state management.\n * For complete state management, use {@link useTreeState} instead.\n *\n * Note: Each operation returns the whole tree. Future iterations might return only\n * the changed portion of the tree for performance optimization.\n *\n * @template T - The type of custom values stored in tree nodes (accessed via `node.values`).\n *\n * @param options - Configuration options for tree actions.\n * @param options.nodes - Current tree nodes to operate on. Used to build internal cache for operations.\n * @param options.selectionCascade - Enable cascade selection mode. When true, selection operations\n * automatically propagate to descendants and update parent indeterminate states. Default: false.\n * @returns Object containing all tree manipulation functions (insert, move, remove, select, expand, etc.).\n *\n * @example\n * ```tsx\n * // Basic usage with custom state management\n * const [tree, setTree] = useState(initialTree);\n * const actions = useTreeActions({ nodes: tree });\n *\n * // Insert a new node\n * const updatedTree = actions.insertAfter('child1', [\n * { key: 'newChild', label: 'New Child' }\n * ]);\n * setTree(updatedTree);\n *\n * // Move nodes\n * const movedTree = actions.moveInto('parent', new Set(['child1', 'child2']));\n * setTree(movedTree);\n *\n * // Cascade selection\n * const actionsWithCascade = useTreeActions({\n * nodes: tree,\n * selectionCascade: true\n * });\n * const selectedTree = actionsWithCascade.onSelectionChange(new Set(['parent']));\n * // All descendants of 'parent' are now selected too\n * ```\n */\nexport function useTreeActions<T>({\n nodes,\n selectionCascade = false,\n}: UseTreeActionsOptions<T>): TreeActions<T> {\n const cache = useRef(new Cache<T>(nodes)).current;\n\n /**\n * Collects parent keys for a set of nodes before a move operation\n */\n function getParents(keys: Set<Key>): Set<Key> {\n const prevParents = new Set<Key>();\n for (const key of keys) {\n const node = cache.getNode(key);\n if (node.parentKey) {\n prevParents.add(node.parentKey);\n }\n }\n return prevParents;\n }\n\n /** CASCADE SELECTION **/\n\n /**\n * Selection change with cascade logic\n */\n function onSelectionChangeCascade(keys: Set<Key>): TreeNode<T>[] {\n // Detect changes\n const previouslySelected = new Set<Key>();\n for (const k of cache.getAllKeys()) {\n try {\n const node = cache.getNode(k);\n if (node.isSelected) {\n previouslySelected.add(k);\n }\n } catch {\n // Skip invalid keys\n }\n }\n\n const validKeys = [...keys].filter((k) => k != null);\n const added = validKeys.filter((k) => !previouslySelected.has(k));\n const removed = [...previouslySelected].filter(\n (k) => !validKeys.includes(k),\n );\n\n // Cascade down\n for (const key of added) {\n cache.cascadeSelection(key, true);\n }\n\n for (const key of removed) {\n cache.cascadeSelection(key, false);\n }\n\n // Bubble up\n const affectedKeys = new Set([...added, ...removed]);\n for (const key of affectedKeys) {\n cache.bubbleUpSelection(key);\n }\n\n return cache.toTree();\n }\n\n /** GET NODE **/\n function getNode(key: Key) {\n return cache.getNode(key);\n }\n\n /** INSERT NODES **/\n function insertAfter(\n target: Key | null,\n nodes: TreeNode<T>[],\n ): TreeNode<T>[] {\n cache.addNodes(target, nodes, 'after');\n\n return cache.toTree(true);\n }\n\n function insertBefore(\n target: Key | null,\n nodes: TreeNode<T>[],\n ): TreeNode<T>[] {\n cache.addNodes(target, nodes, 'before');\n\n return cache.toTree(true);\n }\n\n function insertInto(target: Key | null, nodes: TreeNode<T>[]): TreeNode<T>[] {\n for (const node of nodes) {\n cache.insertNode(target, node, 0);\n }\n\n return cache.toTree(true);\n }\n\n /** MOVE NODES **/\n function moveAfter(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n if (!selectionCascade) {\n cache.moveNodes(target, keys, 'after');\n return cache.toTree();\n }\n\n // Collect old parents before move\n const prevParents = getParents(keys);\n\n // Get new parent before move\n const newParent = cache.getParentForPosition(target, 'after');\n\n // Perform move\n cache.moveNodes(target, keys, 'after');\n\n // Sync cascade state\n cache.syncParentsAfterMove(prevParents, newParent);\n\n return cache.toTree();\n }\n\n function moveBefore(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n if (!selectionCascade) {\n cache.moveNodes(target, keys, 'before');\n return cache.toTree();\n }\n\n // Collect old parents before move\n const prevParents = getParents(keys);\n\n // Get new parent before move\n const newParent = cache.getParentForPosition(target, 'before');\n\n // Perform move\n cache.moveNodes(target, keys, 'before');\n\n // Sync cascade state\n cache.syncParentsAfterMove(prevParents, newParent);\n\n return cache.toTree();\n }\n\n function moveInto(target: Key | null, keys: Set<Key>): TreeNode<T>[] {\n if (!selectionCascade) {\n for (const key of keys) {\n cache.moveNode(target, key, 0);\n }\n return cache.toTree();\n }\n\n // Collect old parents before move\n const prevParents = getParents(keys);\n\n // Perform move\n for (const key of keys) {\n cache.moveNode(target, key, 0);\n }\n\n // Sync cascade state (target IS the new parent for moveInto)\n cache.syncParentsAfterMove(prevParents, target);\n\n return cache.toTree();\n }\n\n /** UPDATE NODES **/\n function updateNode(\n key: Key,\n callback: (node: TreeNodeBase<T>) => TreeNodeBase<T>,\n ): TreeNode<T>[] {\n const node = cache.getNode(key);\n\n cache.setNode(key, callback(node));\n\n return cache.toTree(true);\n }\n\n /** REMOVE NODES **/\n function remove(keys: Set<Key>): TreeNode<T>[] {\n for (const key of keys.values()) {\n cache.deleteNode(key);\n }\n\n return cache.toTree(true);\n }\n\n /** SELECTION **/\n function onSelectionChange(keys: Set<Key>): TreeNode<T>[] {\n if (!selectionCascade) {\n // Current behavior (no cascade)\n unselectAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n\n cache.setNode(node.key, {\n ...node,\n isSelected: true,\n });\n }\n\n return cache.toTree();\n }\n\n // Cascade behavior\n return onSelectionChangeCascade(keys);\n }\n\n function selectAll(): TreeNode<T>[] {\n cache.setAllNodes({ isSelected: true, isIndeterminate: false });\n\n return cache.toTree();\n }\n\n function unselectAll(): TreeNode<T>[] {\n cache.setAllNodes({ isSelected: false, isIndeterminate: false });\n\n return cache.toTree();\n }\n\n /** EXPANSION **/\n function onExpandedChange(keys: Set<Key>): TreeNode<T>[] {\n collapseAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n\n cache.setNode(node.key, {\n ...node,\n isExpanded: true,\n });\n }\n\n return cache.toTree();\n }\n\n function expandAll(): TreeNode<T>[] {\n cache.setAllNodes({ isExpanded: true });\n\n return cache.toTree();\n }\n\n function collapseAll(): TreeNode<T>[] {\n cache.setAllNodes({ isExpanded: false });\n\n return cache.toTree();\n }\n\n /** VISIBILITY **/\n function onVisibilityChange(keys: Set<Key>): TreeData<T> {\n hideAll();\n\n for (const key of keys) {\n const node = cache.getNode(key);\n cache.setNode(node.key, {\n ...node,\n isVisible: true,\n });\n }\n return cache.toTree(true);\n }\n\n function revealAll(): TreeNode<T>[] {\n cache.setAllNodes({ isVisible: true });\n\n return cache.toTree(true);\n }\n\n function hideAll(): TreeNode<T>[] {\n cache.setAllNodes({ isVisible: false });\n\n return cache.toTree(true);\n }\n\n return {\n getNode,\n insertAfter,\n insertBefore,\n insertInto,\n moveAfter,\n moveBefore,\n moveInto,\n remove,\n updateNode,\n\n // Expansion\n collapseAll,\n expandAll,\n onExpandedChange,\n\n // Selection\n selectAll,\n unselectAll,\n onSelectionChange,\n\n // Visibility\n hideAll,\n revealAll,\n onVisibilityChange,\n };\n}\n"],"mappings":"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"}
|
|
@@ -14,15 +14,38 @@ import { UseTreeState, UseTreeStateOptions } from "../types.js";
|
|
|
14
14
|
import "client-only";
|
|
15
15
|
|
|
16
16
|
//#region src/hooks/use-tree/state/index.d.ts
|
|
17
|
+
|
|
17
18
|
/**
|
|
18
|
-
* Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls
|
|
19
|
+
* Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls.
|
|
20
|
+
*
|
|
21
|
+
* Manages tree state internally using React hooks. Returns tree nodes, manipulation actions,
|
|
22
|
+
* and drag-and-drop configuration. Use this hook when you need a complete tree solution with
|
|
23
|
+
* built-in state management. For stateless transformations, use {@link useTreeActions} instead.
|
|
19
24
|
*
|
|
20
25
|
* @param options - {@link UseTreeStateOptions}
|
|
21
26
|
* @param options.items - Initial tree node items.
|
|
27
|
+
* @param options.selectionCascade - Enable cascade selection mode. When true, selecting a parent
|
|
28
|
+
* automatically selects all descendants, and parent checkboxes show indeterminate state when
|
|
29
|
+
* partially selected. Default: false.
|
|
22
30
|
* @returns {@link UseTreeState} Tree state, actions, and drag-and-drop configuration.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // Basic tree without cascade
|
|
35
|
+
* const { nodes, actions } = useTreeState({
|
|
36
|
+
* items: myTree,
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Tree with cascade selection (file system-like behavior)
|
|
40
|
+
* const { nodes, actions } = useTreeState({
|
|
41
|
+
* items: fileSystemTree,
|
|
42
|
+
* selectionCascade: true,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
23
45
|
*/
|
|
24
46
|
declare function useTreeState<T>({
|
|
25
|
-
items
|
|
47
|
+
items,
|
|
48
|
+
selectionCascade
|
|
26
49
|
}: UseTreeStateOptions<T>): UseTreeState<T>;
|
|
27
50
|
//#endregion
|
|
28
51
|
export { useTreeState };
|
|
@@ -20,15 +20,39 @@ import { useState } from "react";
|
|
|
20
20
|
|
|
21
21
|
//#region src/hooks/use-tree/state/index.ts
|
|
22
22
|
/**
|
|
23
|
-
* Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls
|
|
23
|
+
* Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls.
|
|
24
|
+
*
|
|
25
|
+
* Manages tree state internally using React hooks. Returns tree nodes, manipulation actions,
|
|
26
|
+
* and drag-and-drop configuration. Use this hook when you need a complete tree solution with
|
|
27
|
+
* built-in state management. For stateless transformations, use {@link useTreeActions} instead.
|
|
24
28
|
*
|
|
25
29
|
* @param options - {@link UseTreeStateOptions}
|
|
26
30
|
* @param options.items - Initial tree node items.
|
|
31
|
+
* @param options.selectionCascade - Enable cascade selection mode. When true, selecting a parent
|
|
32
|
+
* automatically selects all descendants, and parent checkboxes show indeterminate state when
|
|
33
|
+
* partially selected. Default: false.
|
|
27
34
|
* @returns {@link UseTreeState} Tree state, actions, and drag-and-drop configuration.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // Basic tree without cascade
|
|
39
|
+
* const { nodes, actions } = useTreeState({
|
|
40
|
+
* items: myTree,
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Tree with cascade selection (file system-like behavior)
|
|
44
|
+
* const { nodes, actions } = useTreeState({
|
|
45
|
+
* items: fileSystemTree,
|
|
46
|
+
* selectionCascade: true,
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
28
49
|
*/
|
|
29
|
-
function useTreeState({ items }) {
|
|
50
|
+
function useTreeState({ items, selectionCascade = false }) {
|
|
30
51
|
const [nodes, setNodes] = useState(items);
|
|
31
|
-
const actions = useTreeActions({
|
|
52
|
+
const actions = useTreeActions({
|
|
53
|
+
nodes,
|
|
54
|
+
selectionCascade
|
|
55
|
+
});
|
|
32
56
|
const dragAndDropConfig = {
|
|
33
57
|
getItems: (keys) => [...keys].map((key) => {
|
|
34
58
|
const node = actions.getNode(key);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["dragAndDropConfig: DragAndDropConfig","items"],"sources":["../../../../src/hooks/use-tree/state/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n'use client';\n\nimport 'client-only';\nimport { useState } from 'react';\nimport { useTreeActions } from '../actions';\nimport { processDroppedItems } from './utils';\nimport type {\n DragItem,\n DroppableCollectionInsertDropEvent,\n DroppableCollectionRootDropEvent,\n Key,\n Selection,\n} from '@react-types/shared';\nimport type {\n DragAndDropConfig,\n UseTreeState,\n UseTreeStateOptions,\n} from '../types';\n\n/**\n * Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls\n *\n * @param options - {@link UseTreeStateOptions}\n * @param options.items - Initial tree node items.\n * @returns {@link UseTreeState} Tree state, actions, and drag-and-drop configuration.\n */\nexport function useTreeState<T>({\n items,\n}: UseTreeStateOptions<T>): UseTreeState<T> {\n const [nodes, setNodes] = useState(items);\n const actions = useTreeActions<T>({ nodes });\n\n const dragAndDropConfig: DragAndDropConfig = {\n getItems: (keys: Set<Key>): DragItem[] =>\n [...keys].map((key) => {\n const node = actions.getNode(key);\n\n return {\n key: `${key}`,\n 'text/plain': JSON.stringify(node),\n };\n }),\n onInsert: ({ items, target }: DroppableCollectionInsertDropEvent) => {\n (async () => {\n const processedItems = await processDroppedItems(\n items,\n dragAndDropConfig.acceptedDragTypes ?? [],\n );\n\n setNodes(\n actions.remove(new Set(processedItems.map((item) => item.id))),\n );\n\n if (target.dropPosition === 'before') {\n setNodes(actions.insertBefore(target.key, processedItems));\n } else if (target.dropPosition === 'after') {\n setNodes(actions.insertAfter(target.key, processedItems));\n }\n })();\n },\n onRootDrop: ({ items }: DroppableCollectionRootDropEvent) => {\n (async () => {\n const processedItems = await processDroppedItems(\n items,\n dragAndDropConfig.acceptedDragTypes ?? [],\n );\n\n setNodes(\n actions.remove(new Set(processedItems.map((item) => item.key))),\n );\n setNodes(actions.insertAfter(null, processedItems));\n })();\n },\n onMove: (e) => {\n if (e.target.dropPosition === 'before') {\n setNodes(actions.moveBefore(e.target.key, e.keys));\n } else if (e.target.dropPosition === 'after') {\n setNodes(actions.moveAfter(e.target.key, e.keys));\n } else if (e.target.dropPosition === 'on') {\n const targetNode = actions.getNode(e.target.key);\n if (targetNode) {\n setNodes(actions.moveInto(e.target.key, e.keys));\n }\n }\n },\n };\n\n function collapseAll() {\n setNodes(actions.collapseAll());\n }\n\n function expandAll() {\n setNodes(actions.expandAll());\n }\n\n function onExpandedChange(keys: Set<Key>) {\n setNodes(actions.onExpandedChange(keys));\n }\n\n function selectAll() {\n setNodes(actions.selectAll());\n }\n\n function unselectAll() {\n setNodes(actions.unselectAll());\n }\n\n function onSelectionChange(keys: Selection) {\n if (keys === 'all') {\n return selectAll();\n }\n\n setNodes(actions.onSelectionChange(keys));\n }\n\n function hideAll() {\n setNodes(actions.hideAll());\n }\n\n function revealAll() {\n setNodes(actions.revealAll());\n }\n\n function onVisibilityChange(keys: Set<Key>) {\n setNodes(actions.onVisibilityChange(keys));\n }\n\n return {\n nodes,\n actions: {\n // Expansion\n collapseAll,\n expandAll,\n onExpandedChange,\n\n // Selection\n selectAll,\n unselectAll,\n onSelectionChange,\n\n // Visibility\n hideAll,\n revealAll,\n onVisibilityChange,\n },\n dragAndDropConfig,\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":["dragAndDropConfig: DragAndDropConfig","items"],"sources":["../../../../src/hooks/use-tree/state/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n'use client';\n\nimport 'client-only';\nimport { useState } from 'react';\nimport { useTreeActions } from '../actions';\nimport { processDroppedItems } from './utils';\nimport type {\n DragItem,\n DroppableCollectionInsertDropEvent,\n DroppableCollectionRootDropEvent,\n Key,\n Selection,\n} from '@react-types/shared';\nimport type {\n DragAndDropConfig,\n UseTreeState,\n UseTreeStateOptions,\n} from '../types';\n\n/**\n * Stateful tree manager with drag-and-drop, selection, expansion, and visibility controls.\n *\n * Manages tree state internally using React hooks. Returns tree nodes, manipulation actions,\n * and drag-and-drop configuration. Use this hook when you need a complete tree solution with\n * built-in state management. For stateless transformations, use {@link useTreeActions} instead.\n *\n * @param options - {@link UseTreeStateOptions}\n * @param options.items - Initial tree node items.\n * @param options.selectionCascade - Enable cascade selection mode. When true, selecting a parent\n * automatically selects all descendants, and parent checkboxes show indeterminate state when\n * partially selected. Default: false.\n * @returns {@link UseTreeState} Tree state, actions, and drag-and-drop configuration.\n *\n * @example\n * ```tsx\n * // Basic tree without cascade\n * const { nodes, actions } = useTreeState({\n * items: myTree,\n * });\n *\n * // Tree with cascade selection (file system-like behavior)\n * const { nodes, actions } = useTreeState({\n * items: fileSystemTree,\n * selectionCascade: true,\n * });\n * ```\n */\nexport function useTreeState<T>({\n items,\n selectionCascade = false,\n}: UseTreeStateOptions<T>): UseTreeState<T> {\n const [nodes, setNodes] = useState(items);\n const actions = useTreeActions<T>({ nodes, selectionCascade });\n\n const dragAndDropConfig: DragAndDropConfig = {\n getItems: (keys: Set<Key>): DragItem[] =>\n [...keys].map((key) => {\n const node = actions.getNode(key);\n\n return {\n key: `${key}`,\n 'text/plain': JSON.stringify(node),\n };\n }),\n onInsert: ({ items, target }: DroppableCollectionInsertDropEvent) => {\n (async () => {\n const processedItems = await processDroppedItems(\n items,\n dragAndDropConfig.acceptedDragTypes ?? [],\n );\n\n setNodes(\n actions.remove(new Set(processedItems.map((item) => item.id))),\n );\n\n if (target.dropPosition === 'before') {\n setNodes(actions.insertBefore(target.key, processedItems));\n } else if (target.dropPosition === 'after') {\n setNodes(actions.insertAfter(target.key, processedItems));\n }\n })();\n },\n onRootDrop: ({ items }: DroppableCollectionRootDropEvent) => {\n (async () => {\n const processedItems = await processDroppedItems(\n items,\n dragAndDropConfig.acceptedDragTypes ?? [],\n );\n\n setNodes(\n actions.remove(new Set(processedItems.map((item) => item.key))),\n );\n setNodes(actions.insertAfter(null, processedItems));\n })();\n },\n onMove: (e) => {\n if (e.target.dropPosition === 'before') {\n setNodes(actions.moveBefore(e.target.key, e.keys));\n } else if (e.target.dropPosition === 'after') {\n setNodes(actions.moveAfter(e.target.key, e.keys));\n } else if (e.target.dropPosition === 'on') {\n const targetNode = actions.getNode(e.target.key);\n if (targetNode) {\n setNodes(actions.moveInto(e.target.key, e.keys));\n }\n }\n },\n };\n\n function collapseAll() {\n setNodes(actions.collapseAll());\n }\n\n function expandAll() {\n setNodes(actions.expandAll());\n }\n\n function onExpandedChange(keys: Set<Key>) {\n setNodes(actions.onExpandedChange(keys));\n }\n\n function selectAll() {\n setNodes(actions.selectAll());\n }\n\n function unselectAll() {\n setNodes(actions.unselectAll());\n }\n\n function onSelectionChange(keys: Selection) {\n if (keys === 'all') {\n return selectAll();\n }\n\n setNodes(actions.onSelectionChange(keys));\n }\n\n function hideAll() {\n setNodes(actions.hideAll());\n }\n\n function revealAll() {\n setNodes(actions.revealAll());\n }\n\n function onVisibilityChange(keys: Set<Key>) {\n setNodes(actions.onVisibilityChange(keys));\n }\n\n return {\n nodes,\n actions: {\n // Expansion\n collapseAll,\n expandAll,\n onExpandedChange,\n\n // Selection\n selectAll,\n unselectAll,\n onSelectionChange,\n\n // Visibility\n hideAll,\n revealAll,\n onVisibilityChange,\n },\n dragAndDropConfig,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,SAAgB,aAAgB,EAC9B,OACA,mBAAmB,SACuB;CAC1C,MAAM,CAAC,OAAO,YAAY,SAAS,MAAM;CACzC,MAAM,UAAU,eAAkB;EAAE;EAAO;EAAkB,CAAC;CAE9D,MAAMA,oBAAuC;EAC3C,WAAW,SACT,CAAC,GAAG,KAAK,CAAC,KAAK,QAAQ;GACrB,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAEjC,UAAO;IACL,KAAK,GAAG;IACR,cAAc,KAAK,UAAU,KAAK;IACnC;IACD;EACJ,WAAW,EAAE,gBAAO,aAAiD;AACnE,IAAC,YAAY;IACX,MAAM,iBAAiB,MAAM,oBAC3BC,SACA,kBAAkB,qBAAqB,EAAE,CAC1C;AAED,aACE,QAAQ,OAAO,IAAI,IAAI,eAAe,KAAK,SAAS,KAAK,GAAG,CAAC,CAAC,CAC/D;AAED,QAAI,OAAO,iBAAiB,SAC1B,UAAS,QAAQ,aAAa,OAAO,KAAK,eAAe,CAAC;aACjD,OAAO,iBAAiB,QACjC,UAAS,QAAQ,YAAY,OAAO,KAAK,eAAe,CAAC;OAEzD;;EAEN,aAAa,EAAE,qBAA8C;AAC3D,IAAC,YAAY;IACX,MAAM,iBAAiB,MAAM,oBAC3BA,SACA,kBAAkB,qBAAqB,EAAE,CAC1C;AAED,aACE,QAAQ,OAAO,IAAI,IAAI,eAAe,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CAChE;AACD,aAAS,QAAQ,YAAY,MAAM,eAAe,CAAC;OACjD;;EAEN,SAAS,MAAM;AACb,OAAI,EAAE,OAAO,iBAAiB,SAC5B,UAAS,QAAQ,WAAW,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC;YACzC,EAAE,OAAO,iBAAiB,QACnC,UAAS,QAAQ,UAAU,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC;YACxC,EAAE,OAAO,iBAAiB,MAEnC;QADmB,QAAQ,QAAQ,EAAE,OAAO,IAAI,CAE9C,UAAS,QAAQ,SAAS,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC;;;EAIvD;CAED,SAAS,cAAc;AACrB,WAAS,QAAQ,aAAa,CAAC;;CAGjC,SAAS,YAAY;AACnB,WAAS,QAAQ,WAAW,CAAC;;CAG/B,SAAS,iBAAiB,MAAgB;AACxC,WAAS,QAAQ,iBAAiB,KAAK,CAAC;;CAG1C,SAAS,YAAY;AACnB,WAAS,QAAQ,WAAW,CAAC;;CAG/B,SAAS,cAAc;AACrB,WAAS,QAAQ,aAAa,CAAC;;CAGjC,SAAS,kBAAkB,MAAiB;AAC1C,MAAI,SAAS,MACX,QAAO,WAAW;AAGpB,WAAS,QAAQ,kBAAkB,KAAK,CAAC;;CAG3C,SAAS,UAAU;AACjB,WAAS,QAAQ,SAAS,CAAC;;CAG7B,SAAS,YAAY;AACnB,WAAS,QAAQ,WAAW,CAAC;;CAG/B,SAAS,mBAAmB,MAAgB;AAC1C,WAAS,QAAQ,mBAAmB,KAAK,CAAC;;AAG5C,QAAO;EACL;EACA,SAAS;GAEP;GACA;GACA;GAGA;GACA;GACA;GAGA;GACA;GACA;GACD;EACD;EACD"}
|
|
@@ -13,8 +13,36 @@
|
|
|
13
13
|
import { DropItem, TextDropItem } from "@react-types/shared";
|
|
14
14
|
|
|
15
15
|
//#region src/hooks/use-tree/state/utils.d.ts
|
|
16
|
+
/**
|
|
17
|
+
* Filters and processes an array of drop items into parsed tree node data.
|
|
18
|
+
*
|
|
19
|
+
* Filters to text items only, then processes each using supported drag types.
|
|
20
|
+
*
|
|
21
|
+
* @param items - Drop items from a drag-and-drop event.
|
|
22
|
+
* @param acceptedDragTypes - MIME types to accept when reading item payloads.
|
|
23
|
+
* @returns Array of parsed node objects from the dropped items.
|
|
24
|
+
*/
|
|
16
25
|
declare function processDroppedItems(items: DropItem[], acceptedDragTypes: string[]): Promise<any[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Processes a single text drop item into parsed tree node data.
|
|
28
|
+
*
|
|
29
|
+
* @param item - A text drop item from a drag-and-drop event.
|
|
30
|
+
* @param acceptedDragTypes - MIME types to attempt reading from the item.
|
|
31
|
+
* @returns Parsed node object from the first matching drag type payload.
|
|
32
|
+
* @throws {Error} When no payload matching any accepted drag type is found.
|
|
33
|
+
*/
|
|
17
34
|
declare function processDroppedItem(item: TextDropItem, acceptedDragTypes: string[]): Promise<any>;
|
|
35
|
+
/**
|
|
36
|
+
* Reads the text payload from a drop item for the first matching drag type.
|
|
37
|
+
*
|
|
38
|
+
* Uses `Promise.any` — returns the payload from whichever accepted drag type
|
|
39
|
+
* resolves first.
|
|
40
|
+
*
|
|
41
|
+
* @param item - A text drop item from a drag-and-drop event.
|
|
42
|
+
* @param acceptedDragTypes - MIME types to attempt reading in order.
|
|
43
|
+
* @returns The raw text payload string for the first matching drag type.
|
|
44
|
+
* @throws {AggregateError} When no accepted drag type has a payload.
|
|
45
|
+
*/
|
|
18
46
|
declare function getDroppedItemPayload(item: TextDropItem, acceptedDragTypes: string[]): Promise<string>;
|
|
19
47
|
//#endregion
|
|
20
48
|
export { getDroppedItemPayload, processDroppedItem, processDroppedItems };
|