@qijenchen/design-system 0.1.0-beta.85 → 0.1.0-beta.87
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/AGENTS.md +210 -0
- package/CLAUDE.md +17 -191
- package/cli-init.mjs +30 -2
- package/dist/components/Accordion/accordion.d.ts +2 -2
- package/dist/components/Accordion/accordion.d.ts.map +1 -1
- package/dist/components/Accordion/accordion.js.map +1 -1
- package/dist/components/Avatar/avatar.js +1 -1
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
- package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
- package/dist/components/Button/button-group.d.ts +2 -2
- package/dist/components/Button/button-group.d.ts.map +1 -1
- package/dist/components/Button/button-group.js +2 -2
- package/dist/components/Button/button-group.js.map +1 -1
- package/dist/components/Button/button.d.ts +2 -1
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +1 -1
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Carousel/carousel.d.ts +14 -8
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +64 -37
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox-group.js +21 -14
- package/dist/components/Checkbox/checkbox-group.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +2 -2
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +49 -10
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts +15 -6
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +13 -7
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js +11 -2
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts +5 -5
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +41 -38
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/column-types.d.ts +1 -17
- package/dist/components/DataTable/column-types.d.ts.map +1 -1
- package/dist/components/DataTable/column-types.js.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
- package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +3 -4
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
- package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
- package/dist/components/DataTable/data-table-sort-manager.js +2 -2
- package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +44 -32
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts +3 -3
- package/dist/components/DatePicker/date-picker.js +4 -4
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/DescriptionList/description-list.d.ts +3 -3
- package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
- package/dist/components/DescriptionList/description-list.js +6 -6
- package/dist/components/DescriptionList/description-list.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +2 -2
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +16 -10
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-types.d.ts +2 -2
- package/dist/components/Field/field-types.d.ts.map +1 -1
- package/dist/components/Field/field-types.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts +20 -4
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +30 -31
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +25 -3
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/Field/use-form-validation.d.ts +1 -1
- package/dist/components/Field/use-form-validation.js.map +1 -1
- package/dist/components/FileItem/file-item.d.ts.map +1 -1
- package/dist/components/FileItem/file-item.js +2 -5
- package/dist/components/FileItem/file-item.js.map +1 -1
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
- package/dist/components/FileUpload/file-upload.js +5 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +2 -1
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/HoverCard/hover-card.d.ts +2 -2
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +4 -2
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
- package/dist/components/InlineEdit/inline-edit.js +104 -62
- package/dist/components/InlineEdit/inline-edit.js.map +1 -1
- package/dist/components/Input/input.d.ts +1 -1
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +6 -6
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts +5 -5
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +3 -3
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Notice/notice.d.ts +17 -1
- package/dist/components/Notice/notice.d.ts.map +1 -1
- package/dist/components/Notice/notice.js +7 -1
- package/dist/components/Notice/notice.js.map +1 -1
- package/dist/components/NumberInput/number-input.d.ts +1 -1
- package/dist/components/NumberInput/number-input.d.ts.map +1 -1
- package/dist/components/NumberInput/number-input.js +12 -1
- package/dist/components/NumberInput/number-input.js.map +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +7 -5
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/PeoplePicker/person-display.d.ts +1 -1
- package/dist/components/PeoplePicker/person-display.js.map +1 -1
- package/dist/components/ProfileCard/profile-card.d.ts +1 -1
- package/dist/components/ProfileCard/profile-card.js.map +1 -1
- package/dist/components/RadioGroup/radio-group.d.ts +3 -3
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +1 -1
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/Rating/rating.d.ts.map +1 -1
- package/dist/components/Rating/rating.js +4 -0
- package/dist/components/Rating/rating.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
- package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
- package/dist/components/Select/select.d.ts +16 -6
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +17 -5
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +17 -1
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +17 -3
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
- package/dist/components/SelectionControl/boolean-value.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +2 -2
- package/dist/components/Sheet/sheet.d.ts.map +1 -1
- package/dist/components/Sheet/sheet.js.map +1 -1
- package/dist/components/Sidebar/sidebar.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.js +2 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js +6 -3
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Steps/steps.d.ts +6 -4
- package/dist/components/Steps/steps.d.ts.map +1 -1
- package/dist/components/Steps/steps.js +19 -5
- package/dist/components/Steps/steps.js.map +1 -1
- package/dist/components/Switch/switch.d.ts +4 -4
- package/dist/components/Switch/switch.d.ts.map +1 -1
- package/dist/components/Switch/switch.js +3 -1
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +73 -23
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/tag.d.ts +3 -1
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +2 -2
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +4 -4
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +15 -15
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts +4 -4
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +8 -5
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +27 -23
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +16 -0
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/drag-visual.d.ts +2 -2
- package/dist/lib/drag-visual.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +21 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/tokens/categorical-color.d.ts +3 -3
- package/dist/tokens/categorical-color.d.ts.map +1 -1
- package/dist/tokens/categorical-color.js +2 -2
- package/dist/tokens/categorical-color.js.map +1 -1
- package/ds-canonical/fork/AGENTS.md +213 -0
- package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
- package/ds-canonical/fork/codex/hooks.json +16 -0
- package/ds-canonical/fork/governance.lock +22 -7
- package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/fork/manifest.json +10 -1
- package/ds-canonical/fork/preamble.md +3 -2
- package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
- package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +19 -2
- package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
- package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
- package/ds-canonical/references/certified-surfaces.md +20 -0
- package/ds-canonical/references/preflight-gate-baseline.json +5 -0
- package/ds-canonical/references/principle-dim-map.json +20 -2
- package/ds-canonical/references/props-naming.md +2 -1
- package/ds-canonical/references/ssot-index.md +2 -2
- package/ds-canonical/references/story-baseline-registry.json +2 -2
- package/ds-canonical/rules/story-rules.md +1 -1
- package/ds-canonical/rules/ui-development.md +2 -1
- package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
- package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
- package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
- package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
- package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
- package/ds-story-manifest.json +21 -21
- package/llms-full.txt +3 -3
- package/llms.txt +1 -1
- package/package.json +2 -1
- package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
- package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
- package/src/components/Accordion/accordion.spec.md +10 -1
- package/src/components/Accordion/accordion.stories.tsx +10 -5
- package/src/components/Accordion/accordion.tsx +7 -2
- package/src/components/Alert/alert.principles.stories.tsx +2 -8
- package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
- package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
- package/src/components/AppShell/app-shell.spec.md +4 -0
- package/src/components/AppShell/app-shell.stories.tsx +4 -5
- package/src/components/Avatar/avatar.tsx +1 -1
- package/src/components/Badge/badge.spec.md +2 -2
- package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
- package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
- package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
- package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
- package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
- package/src/components/Button/button-group.tsx +4 -4
- package/src/components/Button/button.anatomy.stories.tsx +26 -7
- package/src/components/Button/button.principles.stories.tsx +1 -1
- package/src/components/Button/button.spec.md +2 -2
- package/src/components/Button/button.stories.tsx +22 -28
- package/src/components/Button/button.tsx +2 -1
- package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
- package/src/components/Calendar/calendar.spec.md +1 -1
- package/src/components/Carousel/carousel.spec.md +17 -1
- package/src/components/Carousel/carousel.tsx +93 -42
- package/src/components/Checkbox/checkbox-group.tsx +26 -15
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
- package/src/components/Checkbox/checkbox.spec.md +12 -3
- package/src/components/Checkbox/checkbox.stories.tsx +4 -4
- package/src/components/Checkbox/checkbox.tsx +79 -19
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
- package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
- package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
- package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
- package/src/components/Combobox/combobox.spec.md +6 -2
- package/src/components/Combobox/combobox.stories.tsx +9 -36
- package/src/components/Combobox/combobox.tsx +42 -27
- package/src/components/Command/command.spec.md +3 -3
- package/src/components/Command/command.tsx +9 -2
- package/src/components/DataTable/cell-registry.tsx +75 -76
- package/src/components/DataTable/column-types.ts +4 -17
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
- package/src/components/DataTable/data-table-filter-panel.tsx +6 -6
- package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
- package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
- package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
- package/src/components/DataTable/data-table.css +2 -3
- package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
- package/src/components/DataTable/data-table.spec.md +8 -7
- package/src/components/DataTable/data-table.stories.tsx +39 -29
- package/src/components/DataTable/data-table.tsx +90 -67
- package/src/components/DataTable/filter-operators.spec.md +2 -0
- package/src/components/DateGrid/date-grid.spec.md +1 -1
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
- package/src/components/DatePicker/date-picker.spec.md +10 -9
- package/src/components/DatePicker/date-picker.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.tsx +13 -13
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
- package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
- package/src/components/DescriptionList/description-list.spec.md +12 -12
- package/src/components/DescriptionList/description-list.stories.tsx +3 -3
- package/src/components/DescriptionList/description-list.tsx +10 -10
- package/src/components/Dialog/dialog.tsx +4 -1
- package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
- package/src/components/Empty/empty.spec.md +0 -1
- package/src/components/Field/field-context.ts +17 -11
- package/src/components/Field/field-controls.spec.md +46 -37
- package/src/components/Field/field-types.ts +14 -12
- package/src/components/Field/field-wrapper.tsx +59 -43
- package/src/components/Field/field.anatomy.stories.tsx +6 -6
- package/src/components/Field/field.principles.stories.tsx +5 -28
- package/src/components/Field/field.spec.md +5 -4
- package/src/components/Field/field.stories.tsx +103 -72
- package/src/components/Field/field.tsx +36 -4
- package/src/components/Field/form-validation.spec.md +4 -0
- package/src/components/Field/use-form-validation.ts +1 -1
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
- package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
- package/src/components/FileItem/file-item.tsx +10 -8
- package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
- package/src/components/FileUpload/file-upload.spec.md +3 -2
- package/src/components/FileUpload/file-upload.tsx +5 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.spec.md +1 -1
- package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.tsx +3 -2
- package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
- package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
- package/src/components/HoverCard/hover-card.spec.md +2 -2
- package/src/components/HoverCard/hover-card.tsx +4 -2
- package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
- package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
- package/src/components/InlineEdit/inline-edit.spec.md +71 -46
- package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
- package/src/components/InlineEdit/inline-edit.tsx +211 -125
- package/src/components/Input/input.anatomy.stories.tsx +15 -15
- package/src/components/Input/input.principles.stories.tsx +3 -3
- package/src/components/Input/input.spec.md +4 -4
- package/src/components/Input/input.stories.tsx +3 -3
- package/src/components/Input/input.tsx +13 -13
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
- package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
- package/src/components/LinkInput/link-input.spec.md +6 -2
- package/src/components/LinkInput/link-input.stories.tsx +8 -8
- package/src/components/LinkInput/link-input.tsx +21 -19
- package/src/components/Notice/notice.principles.stories.tsx +1 -1
- package/src/components/Notice/notice.tsx +8 -2
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
- package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.spec.md +6 -6
- package/src/components/NumberInput/number-input.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.tsx +17 -5
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
- package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
- package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
- package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
- package/src/components/PeoplePicker/people-picker.tsx +39 -20
- package/src/components/PeoplePicker/person-display.tsx +3 -3
- package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
- package/src/components/Popover/popover.principles.stories.tsx +49 -28
- package/src/components/Popover/popover.spec.md +4 -2
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
- package/src/components/ProfileCard/profile-card.tsx +1 -1
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
- package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
- package/src/components/README.md +1 -0
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
- package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
- package/src/components/RadioGroup/radio-group.tsx +19 -14
- package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
- package/src/components/Rating/rating.principles.stories.tsx +3 -3
- package/src/components/Rating/rating.spec.md +2 -2
- package/src/components/Rating/rating.stories.tsx +4 -18
- package/src/components/Rating/rating.tsx +5 -1
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +1 -1
- package/src/components/ScrollArea/scroll-area.tsx +5 -2
- package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
- package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
- package/src/components/SegmentedControl/segmented-control.tsx +6 -3
- package/src/components/Select/select.anatomy.stories.tsx +13 -7
- package/src/components/Select/select.principles.stories.tsx +3 -3
- package/src/components/Select/select.spec.md +10 -1
- package/src/components/Select/select.stories.tsx +41 -27
- package/src/components/Select/select.tsx +44 -26
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
- package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
- package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
- package/src/components/SelectMenu/select-menu.tsx +38 -5
- package/src/components/SelectionControl/boolean-value.tsx +2 -2
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
- package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
- package/src/components/Separator/separator.principles.stories.tsx +1 -1
- package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
- package/src/components/Sheet/sheet.tsx +4 -1
- package/src/components/Sidebar/sidebar.tsx +1 -1
- package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
- package/src/components/Slider/slider.principles.stories.tsx +6 -6
- package/src/components/Slider/slider.spec.md +13 -1
- package/src/components/Slider/slider.stories.tsx +44 -32
- package/src/components/Slider/slider.tsx +13 -4
- package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
- package/src/components/Steps/steps.principles.stories.tsx +1 -1
- package/src/components/Steps/steps.spec.md +4 -2
- package/src/components/Steps/steps.stories.tsx +4 -56
- package/src/components/Steps/steps.tsx +31 -7
- package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
- package/src/components/Switch/switch.principles.stories.tsx +1 -1
- package/src/components/Switch/switch.spec.md +4 -4
- package/src/components/Switch/switch.stories.tsx +3 -3
- package/src/components/Switch/switch.tsx +16 -10
- package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
- package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
- package/src/components/Tabs/tabs.spec.md +5 -2
- package/src/components/Tabs/tabs.stories.tsx +36 -44
- package/src/components/Tabs/tabs.tsx +101 -36
- package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
- package/src/components/Tag/tag.principles.stories.tsx +4 -4
- package/src/components/Tag/tag.spec.md +4 -1
- package/src/components/Tag/tag.tsx +5 -3
- package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
- package/src/components/Textarea/textarea.spec.md +5 -5
- package/src/components/Textarea/textarea.tsx +24 -24
- package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
- package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
- package/src/components/TimePicker/time-picker.spec.md +6 -5
- package/src/components/TimePicker/time-picker.stories.tsx +3 -3
- package/src/components/TimePicker/time-picker.tsx +24 -14
- package/src/components/Toast/toast.principles.stories.tsx +1 -1
- package/src/components/Toast/toast.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
- package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
- package/src/components/Tooltip/tooltip.spec.md +9 -3
- package/src/components/Tooltip/tooltip.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.tsx +12 -2
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
- package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
- package/src/components/TreeView/tree-view.spec.md +8 -6
- package/src/components/TreeView/tree-view.stories.tsx +9 -43
- package/src/components/TreeView/tree-view.tsx +36 -0
- package/src/index.ts +13 -10
- package/src/lib/drag-visual.ts +2 -2
- package/src/lib/utils.ts +19 -0
- package/src/patterns/action-bar/action-bar.spec.md +1 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
- package/src/patterns/element-anatomy/item-anatomy.spec.md +4 -0
- package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
- package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
- package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
- package/src/tokens/categorical-color.ts +5 -5
- package/src/tokens/color/color.spec.md +4 -4
- package/src/tokens/color/primitives.css +9 -2
- package/src/tokens/motion/motion.spec.md +6 -7
- package/src/tokens/opacity/opacity.spec.md +1 -1
- package/src/tokens/orphan-tokens.spec.md +1 -1
- package/src/tokens/typography/typography.spec.md +2 -0
- package/src/tokens/uiSize/uiSize.css +5 -0
- package/src/tokens/uiSize/uiSize.spec.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view.js","sources":["../../../src/components/TreeView/tree-view.tsx"],"sourcesContent":["// code-quality-allow: file-size — foundational composite(TreeView owns tree logic + TreeItem + drag-drop + keyboard;拆 sub-component 會把 register/unregister 跨檔傳 ref 複雜化超過可讀性 gain)\nimport * as React from 'react'\nimport * as CollapsiblePrimitive from '@radix-ui/react-collapsible'\nimport {\n DndContext,\n DragOverlay,\n useDraggable,\n useDroppable,\n PointerSensor,\n useSensor,\n useSensors,\n type DragStartEvent,\n type DragEndEvent,\n type DragOverEvent,\n} from '@dnd-kit/core'\nimport { ChevronRight } from 'lucide-react'\nimport { cva } from 'class-variance-authority'\nimport type { LucideIcon } from 'lucide-react'\nimport { dragSourceClass, dropIndicatorRow, dropIndicatorInside } from '@/design-system/lib/drag-visual'\nimport { cn } from '@/lib/utils'\nimport { Checkbox } from '@/design-system/components/Checkbox/checkbox'\n// Row primitive 共用常數——單一 source of truth\nimport {\n ICON_SIZE,\n RowSizeProvider,\n ItemIcon,\n ItemPrefix,\n ItemSuffix,\n ItemInlineAction,\n ROW_PADDING_BY_SIZE,\n type InlineActionConfig,\n} from '@/design-system/patterns/element-anatomy/item-anatomy'\n\n/**\n * TreeView — 階層結構的遞迴元件\n *\n * 一個 TreeItem 就是一個 node——有 children 就可展開,沒有就是 leaf。\n * 沒有第二個概念(沒有 TreeGroup)。\n *\n * TreeView 負責:\n * 1. 遞迴渲染 + indent\n * 2. 展開/收合狀態管理\n * 3. 鍵盤導覽 + ARIA tree\n *\n * 它不管 node 裡面長什麼樣——icon、badge、status indicator 等\n * 由 consumer 透過 props / slots 決定。\n *\n * 詳見 tree-view.spec.md。\n */\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ntype SizeKey = 'sm' | 'md' | 'lg'\ntype SelectionMode = 'single' | 'multiple' | 'none'\n/**\n * TreeView 的使用脈絡,決定 item 的水平 padding:\n * - `'sidebar'`:頁面側邊欄,用 `--layout-space-loose` token(md=16px / lg=24px,跟 density 連動)\n * - `'menu'`:浮層選單 / dropdown,px-3(12px),對齊 MenuItem / DropdownMenu\n */\ntype TreeContext = 'sidebar' | 'menu'\n\n// Base horizontal padding per context — 用 CSS variable 注入到 TreeView 容器,\n// TreeItem 用 calc(var(--tree-px) + indent) 算出最終 paddingLeft。\nconst CONTEXT_PX_VAR: Record<TreeContext, string> = {\n sidebar: 'var(--layout-space-loose)', // md=16px, lg=24px(density 連動)\n menu: '12px', // px-3,對齊 MenuItem / DropdownMenu\n}\n\n/** Drag drop position — 拖放目標的三種位置 */\n// code-quality-allow: dead-export — public event/state type — consumer event handler parameter type\nexport type TreeDropPosition = 'before' | 'after' | 'inside'\n\n/** onDragEnd callback 的參數 */\n// code-quality-allow: dead-export — public event/state type — consumer event handler parameter type\nexport interface TreeDragEndEvent {\n /** 被拖曳的 node id */\n sourceId: string\n /** 目標 node id */\n targetId: string\n /** 放置位置:before(同層上方)/ after(同層下方)/ inside(成為子 node) */\n position: TreeDropPosition\n}\n\n/**\n * 鍵盤重排(`Cmd/Ctrl+Shift+方向鍵`,2026-07-14 v1)的 SR 播報文案 — zh-TW 預設,\n * per-key merge 覆寫(i18n 覆寫點)。詳 tree-view.spec.md「鍵盤重排」。\n * @public\n */\n// code-quality-allow: dead-export — public prop type — consumer 覆寫播報文案的參數型別\nexport interface TreeReorderAnnouncements {\n /** 同層上/下移完成。`index` / `count` = 移動後在同層的 1-based 序數 / 同層總數 */\n moved?: (args: { label: string; targetLabel: string; position: 'before' | 'after'; index: number; count: number }) => string\n /** 移入 folder 完成。folder 原本收合(children 尚未 mount)時序數不可知 → `index` / `count` 為 undefined */\n movedInside?: (args: { label: string; folderLabel: string; index?: number; count?: number }) => string\n /** 移出到上層完成。`level` = 移動後所在層(1-based,同 aria-level 語意) */\n movedOut?: (args: { label: string; parentLabel: string; level: number }) => string\n /** 邊界 no-op:top(已在最上方)/ bottom(已在最下方)/ not-folder(無可移入的 folder)/ root(已在最外層) */\n blocked?: (args: { reason: 'top' | 'bottom' | 'not-folder' | 'root'; label: string; targetLabel?: string }) => string\n /** sr-only 操作說明(tree 容器 `aria-describedby` 指向;僅 `draggable` 時渲染) */\n instructions?: string\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Constants\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Icon / chevron 尺寸——從 item-layout pattern module 引入(在檔頂 import),\n// 這裡本地不再宣告。所有 row primitives 共用同一個常數。\n\n// indentStep = chevronSize + gap-2(8px)。值 {24,24,28} 與 CSS token `--tree-indent-{sm,md,lg}`\n// (`tokens/uiSize/uiSize.css`)**完全一致、必須同步維護**(改一處要兩處一起改;非「token 取代 literal」)。\n// 為何兩源並存:本元件 render 用此 JS literal 算 `indentPx`(TreeItem inline calc 需 number)+ drop-indicator\n// pointer 數學(handleDragOver px 命中判斷,CSS var 在 JS 計算層拿不到);DataTable nested rows\n// 則走 CSS token 的 Tailwind class(跨元件視覺一致)。結構對齊:子 chevron 對齊父 icon,子 icon 對齊父 label。\nconst INDENT_STEP: Record<SizeKey, number> = { sm: 24, md: 24, lg: 28 }\n\n// ── 鍵盤重排(keyboard reorder,2026-07-14 v1)常數 ──\n// 鍵位 = Cmd/Ctrl+Shift+方向鍵,對齊 Notion 移動 block 鍵位(https://www.notion.com/help/keyboard-shortcuts,\n// WebFetch 驗證紀錄 .claude/logs/treeview-keyboard-dnd-design.md#L25);\n// modifier 層與 APG tree 導覽鍵(無 modifier 的 ↑↓→←)完全正交,零衝突。\nconst REORDER_ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']\ntype ReorderArrowKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight'\n\n// 鍵盤重排 SR 播報預設文案(zh-TW;consumer 經 `reorderAnnouncements` prop per-key 覆寫)。\n// 格式 =「結果 + 序數位置」— 非視覺使用者靠「第 n 項,共 m 項」建立位置模型\n// (世界級 cite 詳 tree-view.spec.md「鍵盤重排」段,M22)。\n// i18n-allow-block: DS default SR-only 播報文案,prop 可覆寫(同 select-menu.tsx SelectMenuLiveStatus 先例)\nconst DEFAULT_REORDER_ANNOUNCEMENTS: Required<TreeReorderAnnouncements> = {\n moved: ({ label, targetLabel, position, index, count }) =>\n `已將『${label}』移到『${targetLabel}』${position === 'before' ? '之前' : '之後'},第 ${index} 項,共 ${count} 項`,\n movedInside: ({ label, folderLabel, index, count }) =>\n index !== undefined && count !== undefined\n ? `已將『${label}』移入『${folderLabel}』,第 ${index} 項,共 ${count} 項`\n : `已將『${label}』移入『${folderLabel}』`,\n movedOut: ({ label, parentLabel, level }) =>\n `已將『${label}』移出到『${parentLabel}』之後,第 ${level} 層`,\n blocked: ({ reason, targetLabel }) => {\n switch (reason) {\n case 'top': return '已在最上方'\n case 'bottom': return '已在最下方'\n case 'not-folder': return targetLabel ? `無法移入:『${targetLabel}』不是資料夾` : '無法移入'\n case 'root': return '已在最外層'\n }\n },\n instructions: '按 Cmd(Ctrl)+Shift+方向鍵可重新排列項目',\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Context\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface TreeViewContextValue {\n size: SizeKey\n context: TreeContext\n selectionMode: SelectionMode\n expandOnSelect: boolean\n draggable: boolean\n isKeyboardRef: React.RefObject<boolean>\n /**\n * Per-tree instance 前綴(React.useId),用來組每個 treeitem 的 DOM `id`\n * (`${prefix}treeitem-${nodeId}`),讓容器的 `aria-activedescendant` 能指向目前 focused node。\n * 多棵 TreeView 同頁 / node id 跨樹重複時不會撞 DOM id。\n */\n activeDescendantPrefix: string\n expandedIds: Set<string>\n selectedIds: Set<string>\n focusedId: string | null\n /** 目前拖曳中的 node id(null = 沒在拖) */\n draggingId: string | null\n /** 目前 drop indicator 的位置 + depth(用於 line indent) */\n dropTarget: { id: string; position: TreeDropPosition; depth: number } | null\n toggleExpand: (id: string) => void\n select: (id: string) => void\n setFocusedId: (id: string | null) => void\n registerNode: (id: string, parentId: string | null, hasChildren: boolean, label?: React.ReactNode, icon?: LucideIcon) => void\n getNodeInfo: (id: string) => NodeInfo | undefined\n unregisterNode: (id: string) => void\n}\n\nconst TreeViewContext = React.createContext<TreeViewContextValue | null>(null)\n\nfunction useTreeView(): TreeViewContextValue {\n const ctx = React.useContext(TreeViewContext)\n if (!ctx) throw new Error('TreeItem must be used within TreeView')\n return ctx\n}\n\n// TreeItem depth context(遞迴 depth tracking)\nconst DepthContext = React.createContext(0)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Node registry — 追蹤所有 node 的 parent/children 關係,用於鍵盤導覽\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface NodeInfo {\n id: string\n parentId: string | null\n hasChildren: boolean\n /** 用於 DragOverlay ghost 渲染 */\n label?: React.ReactNode\n icon?: LucideIcon\n}\n\nfunction useNodeRegistry() {\n const nodesRef = React.useRef(new Map<string, NodeInfo>())\n\n const registerNode = React.useCallback(\n (id: string, parentId: string | null, hasChildren: boolean, label?: React.ReactNode, icon?: LucideIcon) => {\n nodesRef.current.set(id, { id, parentId, hasChildren, label, icon })\n },\n []\n )\n\n const unregisterNode = React.useCallback((id: string) => {\n nodesRef.current.delete(id)\n }, [])\n\n const getNodeInfo = React.useCallback((id: string) => nodesRef.current.get(id), [])\n\n return { nodesRef, registerNode, unregisterNode, getNodeInfo }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeView\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onDragEnd'> {\n /** 元件尺寸,影響 node 高度、icon 大小、indent 寬度 */\n size?: SizeKey\n /**\n * 使用脈絡,決定 item 的水平 padding:\n * - `'sidebar'`(預設):頁面側邊欄,`--layout-space-loose`(md=16px / lg=24px,隨 density 連動)\n * - `'menu'`:浮層選單 / dropdown,px-3(12px),對齊 MenuItem\n */\n context?: TreeContext\n /** 選取模式。預設 'single'(sidebar nav / stepper) */\n selectionMode?: SelectionMode\n /** 點擊 label 時是否同時展開 children。預設 false(chevron 是展開的唯一控件) */\n expandOnSelect?: boolean\n /** 受控:展開的 node id 集合 */\n expandedIds?: Set<string>\n /** 受控:展開狀態變更 callback */\n onExpandedChange?: (ids: Set<string>) => void\n /** 受控:選取的 node id 集合 */\n selectedIds?: Set<string>\n /** 受控:選取狀態變更 callback */\n onSelectedChange?: (ids: Set<string>) => void\n /** 非受控:預設展開的 node id 陣列 */\n defaultExpandedIds?: string[]\n /** 非受控:預設選取的 node id 陣列 */\n defaultSelectedIds?: string[]\n /**\n * 啟用拖曳排序。預設 false。\n * 啟用後整列可拖(Figma 風格,無 grip handle;靠 distance:5 區分 click vs drag),\n * 拖曳時顯示 drop indicator(before / after / inside 三種位置)。\n * Consumer 透過 `onDragEnd` callback 接收 reorder 事件,自行更新 data。\n */\n draggable?: boolean\n /** Drag 結束時觸發,提供 sourceId、targetId、position。Consumer 負責 reorder。 */\n onDragEnd?: (event: TreeDragEndEvent) => void\n /**\n * 鍵盤重排(`Cmd/Ctrl+Shift+方向鍵`)的 SR 播報文案覆寫(per-key merge;zh-TW 預設)。\n * 僅在 `draggable` 時生效;含 `instructions`(sr-only 操作說明)。\n * @public\n */\n reorderAnnouncements?: TreeReorderAnnouncements\n /** ARIA label */\n 'aria-label'?: string\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TreeView = React.forwardRef<HTMLDivElement, TreeViewProps>(\n (\n {\n size = 'md',\n context = 'sidebar',\n selectionMode = 'single',\n expandOnSelect = false,\n draggable = false,\n onDragEnd: onDragEndProp,\n reorderAnnouncements: reorderAnnouncementsProp,\n expandedIds: controlledExpanded,\n onExpandedChange,\n selectedIds: controlledSelected,\n onSelectedChange,\n defaultExpandedIds = [],\n defaultSelectedIds = [],\n className,\n children,\n ...props\n },\n ref\n ) => {\n // ── Expand state(受控 / 非受控) ──\n const [internalExpanded, setInternalExpanded] = React.useState(\n () => new Set(defaultExpandedIds)\n )\n const expandedIds = controlledExpanded ?? internalExpanded\n const setExpandedIds = React.useCallback(\n (updater: (prev: Set<string>) => Set<string>) => {\n const update = (prev: Set<string>) => {\n const next = updater(prev)\n onExpandedChange?.(next)\n return next\n }\n if (controlledExpanded) {\n update(controlledExpanded)\n } else {\n setInternalExpanded(update)\n }\n },\n [controlledExpanded, onExpandedChange]\n )\n\n // ── Selection state(受控 / 非受控) ──\n const [internalSelected, setInternalSelected] = React.useState(\n () => new Set(defaultSelectedIds)\n )\n const selectedIds = controlledSelected ?? internalSelected\n const setSelectedIds = React.useCallback(\n (updater: (prev: Set<string>) => Set<string>) => {\n const update = (prev: Set<string>) => {\n const next = updater(prev)\n onSelectedChange?.(next)\n return next\n }\n if (controlledSelected) {\n update(controlledSelected)\n } else {\n setInternalSelected(update)\n }\n },\n [controlledSelected, onSelectedChange]\n )\n\n // ── Focus state ──\n const [focusedId, setFocusedId] = React.useState<string | null>(null)\n\n // ── Virtual focus id prefix ──\n // DOM focus 永遠停在 role=tree 容器(單一 tab stop);目前 node 透過 aria-activedescendant\n // 告知 AT(對齊 DS 既有 cmdk virtual-focus canonical:SelectMenu / Command listbox)。\n // useId 確保多棵 TreeView 同頁 / node id 跨樹重複時 DOM id 不撞。\n const activeDescendantPrefix = React.useId()\n\n // ── 鍵盤重排 SR 播報(2026-07-14 v1;詳 spec「鍵盤重排」)──\n // 單一 polite live region 覆寫式更新(textContent 替換非 append → 快速連按天然只播最新)。\n // 不可借 dnd-kit DndContext 內建 live region — 它只播 dnd-kit 管理的 drag session,\n // 自建鍵盤路徑觸不到。消費 select-menu.tsx SelectMenuLiveStatus role=\"status\" 先例。\n const [reorderAnnouncement, setReorderAnnouncement] = React.useState('')\n const announcements = React.useMemo(\n () => ({ ...DEFAULT_REORDER_ANNOUNCEMENTS, ...reorderAnnouncementsProp }),\n [reorderAnnouncementsProp]\n )\n // sr-only 操作說明節點 id(tree 容器 aria-describedby 指向;僅 draggable 渲染)\n const reorderInstructionsId = `${activeDescendantPrefix}tree-reorder-instructions`\n\n // ── Keyboard vs mouse detection ──\n // focus ring 只在鍵盤操作時顯示,滑鼠點擊用 bg-neutral-selected 表達選中,不顯示 ring\n const isKeyboardRef = React.useRef(false)\n\n // ── Drag state ──\n const [draggingId, setDraggingId] = React.useState<string | null>(null)\n const [dropTarget, setDropTarget] = React.useState<{ id: string; position: TreeDropPosition; depth: number } | null>(null)\n const autoExpandTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n // 2026-05-16 audit codex Round 6:unmount cleanup(原 cleanup 只在 dragEnd/dragCancel,unmount-during-drag 漏 cancel)\n React.useEffect(() => () => { if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current) }, [])\n // Ref for toggleExpand — handleDragOver 定義在 toggleExpand 之前(hook 順序限制),\n // 用 ref 打斷 temporal dead zone。\n const toggleExpandRef = React.useRef<(id: string) => void>(() => {})\n\n // ── Node registry ──(2026-07-14 上移至 drag handlers 之前:isInSubtree 消費 getNodeInfo,\n // 而 handleDragOver / handleDragEnd / 鍵盤 reorder 都消費 isInSubtree)\n const { registerNode, unregisterNode, getNodeInfo } = useNodeRegistry()\n\n // 子樹判定:candidate 是否位於 rootId 的子樹內(含相等)。沿 registry parentId 鏈上溯。\n // 雙路共用 SSOT:pointer 路徑 descendant drop guard(2026-07-14 R6 修:原 handleDragOver 只擋\n // `over.id === active.id` 未擋 descendants → 可發出 targetId ∈ source 子樹的非法事件,\n // consumer 按 remove→insert 實作會讓整個子樹靜默消失)+ 鍵盤 reorder commit 前防禦 assert。\n const isInSubtree = React.useCallback(\n (candidateId: string, rootId: string): boolean => {\n let cur: string | null = candidateId\n while (cur != null) {\n if (cur === rootId) return true\n cur = getNodeInfo(cur)?.parentId ?? null\n }\n return false\n },\n [getNodeInfo]\n )\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } })\n )\n\n const handleDragStart = React.useCallback((event: DragStartEvent) => {\n setDraggingId(String(event.active.id))\n }, [])\n\n // ── Figma-style drop detection(X + Y 雙軸)──\n //\n // Y 軸:決定在哪個 item 附近\n // - item 上 25% = before\n // - item 中 50% = inside(只有 folder)\n // - item 下 25% = after\n //\n // X 軸:決定 nesting 深度(Figma 核心邏輯)\n // - 滑鼠越左 = 越淺層(放在 parent 層級)\n // - 滑鼠越右 = 越深層(放進 folder)\n // - 用 pointer X 相對於 tree 左邊界計算 indent level\n //\n const handleDragOver = React.useCallback((event: DragOverEvent) => {\n const { over, active } = event\n // 2026-07-14 R6 descendant guard:over 是 active 自己「或其子樹內節點」→ 無效目標,\n // 不設 dropTarget(拖 folder 進自己子樹會發出非法 TreeDragEndEvent;guard SSOT = isInSubtree,\n // 鍵盤 reorder 路徑共用同一 helper)。\n if (!over || isInSubtree(String(over.id), String(active.id))) {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n setDropTarget(null)\n return\n }\n\n const rowEl = document.querySelector(`[data-tree-row=\"${over.id}\"]`) as HTMLElement | null\n const targetEl = document.querySelector(`[data-tree-id=\"${over.id}\"]`) as HTMLElement | null\n if (!rowEl || !targetEl) { setDropTarget(null); return }\n\n // 實際指標位置\n const startX = (event.activatorEvent as PointerEvent)?.clientX ?? 0\n const startY = (event.activatorEvent as PointerEvent)?.clientY ?? 0\n const currentX = startX + (event.delta?.x ?? 0)\n const currentY = startY + (event.delta?.y ?? 0)\n\n const rect = rowEl.getBoundingClientRect()\n const offsetY = currentY - rect.top\n const height = rect.height || 32\n const ratio = Math.max(0, Math.min(1, offsetY / height))\n\n const hasChildren = targetEl.dataset.treeHasChildren === 'true'\n const targetDepth = Number(targetEl.getAttribute('aria-level') ?? 1) - 1\n\n // ── X 軸:計算指標在哪個 indent level ──\n const treeEl = treeRef.current\n const treeLeft = treeEl?.getBoundingClientRect().left ?? 0\n const indentStep = INDENT_STEP[size]\n const pointerIndentLevel = Math.max(0, Math.floor((currentX - treeLeft) / indentStep))\n\n let position: TreeDropPosition\n let finalDepth = targetDepth\n\n if (hasChildren) {\n // Folder node\n if (ratio < 0.25) {\n position = 'before'\n } else if (ratio > 0.75) {\n // after folder: 如果指標在 folder 層級或更淺 = after(同層)\n // 如果指標更深 = inside(放進 folder)\n position = pointerIndentLevel > targetDepth ? 'inside' : 'after'\n } else {\n position = 'inside'\n }\n } else {\n // Leaf node\n if (ratio < 0.5) {\n position = 'before'\n } else {\n position = 'after'\n // X 軸:如果指標在比 target 更淺的層級,提升 drop depth\n // 例:Contact(depth 1)的 after,如果滑鼠在 depth 0 → 變成「after Pages」\n if (pointerIndentLevel < targetDepth) {\n // 找 parent 來放\n const groupEl = targetEl.closest('[role=\"group\"]')\n const parentTreeItem = groupEl?.parentElement?.closest('[role=\"treeitem\"]')\n const parentId = parentTreeItem?.getAttribute('data-tree-id')\n if (parentId && parentId !== String(active.id)) {\n const parentDepth = Number(parentTreeItem?.getAttribute('aria-level') ?? 1) - 1\n finalDepth = parentDepth\n setDropTarget(prev => prev && prev.id === parentId && prev.position === 'after' && prev.depth === parentDepth ? prev : { id: parentId, position: 'after', depth: parentDepth })\n return\n }\n }\n }\n }\n\n // 2026-07-06 D3 perf:bail-out — drop target 未變(每 dragOver 跨 row 才變)時回傳 prev,\n // React 對相同 reference bail out,避免每次 over 事件重建 contextValue → 全樹 TreeItem re-render。\n setDropTarget(prev => {\n const id = String(over.id)\n return prev && prev.id === id && prev.position === position && prev.depth === finalDepth ? prev : { id, position, depth: finalDepth }\n })\n\n // Auto-expand collapsed folder after 500ms hover (Figma behavior)\n if (position === 'inside' && hasChildren && !expandedIds.has(String(over.id))) {\n if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current)\n autoExpandTimerRef.current = setTimeout(() => {\n toggleExpandRef.current(String(over.id))\n }, 500)\n } else {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n }\n }, [expandedIds, isInSubtree])\n\n const dropTargetRef = React.useRef(dropTarget)\n dropTargetRef.current = dropTarget\n\n const handleDragEnd = React.useCallback((event: DragEndEvent) => {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n const { active, over } = event\n const dt = dropTargetRef.current\n // descendant guard 同 handleDragOver(dt 已由 dragOver guard 保證為 null,此為 belt-and-braces)\n if (over && !isInSubtree(String(over.id), String(active.id)) && dt) {\n onDragEndProp?.({\n sourceId: String(active.id),\n targetId: String(over.id),\n position: dt.position,\n })\n }\n setDraggingId(null)\n setDropTarget(null)\n }, [onDragEndProp, isInSubtree])\n\n const handleDragCancel = React.useCallback(() => {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n setDraggingId(null)\n setDropTarget(null)\n }, [])\n\n // ── Actions ──\n const toggleExpand = React.useCallback(\n (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n },\n [setExpandedIds]\n )\n toggleExpandRef.current = toggleExpand\n\n const select = React.useCallback(\n (id: string) => {\n if (selectionMode === 'none') return\n setSelectedIds((prev) => {\n if (selectionMode === 'single') {\n return new Set([id])\n }\n // multiple\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n },\n [selectionMode, setSelectedIds]\n )\n\n // ── Keyboard reorder(Cmd/Ctrl+Shift+方向鍵,2026-07-14 v1)──\n // 設計 SSOT:tree-view.spec.md「鍵盤重排」。與 pointer 路徑共用 TreeDragEndEvent 契約 +\n // onDragEnd prop + registry(consumer API 零改動);每按一下立即 commit(無 grab-mode /\n // 無預覽,對齊 Notion Cmd/Ctrl+Shift+Arrow 移動 block:https://www.notion.com/help/keyboard-shortcuts,\n // WebFetch 驗證紀錄 .claude/logs/treeview-keyboard-dnd-design.md#L25)。\n // 不用 dnd-kit KeyboardSensor — 其 activator 需可接收 DOM focus\n // (https://dndkit.com/api-documentation/sensors/keyboard),與 row tabIndex={-1} +\n // aria-activedescendant 虛擬焦點模型結構性不相容(2026-07-05 D4 拍板不翻案)。\n\n // 播報用 label 文字:registry label 是 ReactNode — string 直接用,否則退 DOM row textContent。\n const getNodeLabelText = React.useCallback(\n (id: string): string => {\n const info = getNodeInfo(id)\n if (typeof info?.label === 'string') return info.label\n const rowEl = treeRef.current?.querySelector<HTMLElement>(`[data-tree-row=\"${id}\"]`)\n return rowEl?.textContent?.trim() || id\n },\n [getNodeInfo]\n )\n\n // code-quality-allow: long-function — 四鍵語意(同層上下 / 移入 / 移出)+ 邊界播報結構緊密,\n // 拆 sub-fn 會跨 fn 傳 siblings / announce state 反而複雜(同 handleKeyDown 先例)\n const handleKeyboardReorder = React.useCallback(\n (key: ReorderArrowKey) => {\n const tree = treeRef.current\n if (!tree || !focusedId) return\n const sourceId = focusedId\n const sourceEl = tree.querySelector<HTMLElement>(`[data-tree-id=\"${sourceId}\"]`)\n // disabled node 不可移(鍵盤導覽本就跳過 disabled,此為防禦 guard)\n if (!sourceEl || sourceEl.getAttribute('aria-disabled') === 'true') return\n\n const label = getNodeLabelText(sourceId)\n // 同層 siblings(DOM 序)。focused node 可見 ⇒ 其 parent 已展開 ⇒ 全 siblings 已 mount。\n const parentId = sourceEl.dataset.treeParentId || null\n const visibleItems = Array.from(\n tree.querySelectorAll<HTMLElement>('[role=\"treeitem\"]:not([hidden])')\n )\n const siblings = visibleItems.filter((el) => (el.dataset.treeParentId || null) === parentId)\n const sourceIndex = siblings.findIndex((el) => el.dataset.treeId === sourceId)\n if (sourceIndex < 0) return\n const isEnabled = (el: HTMLElement) => el.getAttribute('aria-disabled') !== 'true'\n\n // 發出與 pointer 路徑同型的 TreeDragEndEvent,並排定 re-render 後 scrollIntoView\n // (既有 effect 只在 isFocused 變化時跑;同 id 移動不 re-fire,故此處補)。\n const commit = (targetId: string, position: TreeDropPosition): boolean => {\n // 結構安全 assert:四鍵語意(sibling 間 / 進 prev sibling / 出 parent)結構上\n // 不可能移進自己子樹;防禦性仍擋(與 pointer descendant guard 共用 isInSubtree SSOT)。\n if (targetId === sourceId || isInSubtree(targetId, sourceId)) return false\n onDragEndProp?.({ sourceId, targetId, position })\n requestAnimationFrame(() => {\n treeRef.current\n ?.querySelector<HTMLElement>(`[data-tree-id=\"${sourceId}\"]`)\n ?.scrollIntoView({ block: 'nearest' })\n })\n return true\n }\n\n // 同層移動後的 1-based 新序數(播報用):移除 source 再插入的模擬;同層總數不變。\n const movedIndex = (targetId: string, position: 'before' | 'after'): number => {\n const order = siblings.map((el) => el.dataset.treeId).filter((id) => id !== sourceId)\n const tIdx = order.indexOf(targetId)\n return (position === 'before' ? tIdx : tIdx + 1) + 1\n }\n\n switch (key) {\n case 'ArrowUp':\n case 'ArrowDown': {\n // disabled sibling 不可當 target 錨點(pointer useDroppable 同樣 disable)——\n // 相鄰 sibling disabled 時錨到最近 enabled sibling 並翻轉 before/after 表達同一插槽\n // (可達位置與 pointer 一致);整個方向皆無 enabled sibling → 視同邊界。\n const dir = key === 'ArrowUp' ? -1 : 1\n const boundary = dir < 0 ? ('top' as const) : ('bottom' as const)\n const adjacent = siblings[sourceIndex + dir]\n if (!adjacent) {\n setReorderAnnouncement(announcements.blocked({ reason: boundary, label }))\n return\n }\n let target: HTMLElement | undefined\n let position: 'before' | 'after' = dir < 0 ? 'before' : 'after'\n if (isEnabled(adjacent)) {\n target = adjacent\n } else {\n for (let i = sourceIndex + dir; i >= 0 && i < siblings.length; i += dir) {\n if (isEnabled(siblings[i])) { target = siblings[i]; break }\n }\n position = dir < 0 ? 'after' : 'before' // 錨到最近 enabled sibling 的另一側 = 相鄰插槽\n }\n if (!target) {\n setReorderAnnouncement(announcements.blocked({ reason: boundary, label }))\n return\n }\n const targetId = target.dataset.treeId!\n if (commit(targetId, position)) {\n setReorderAnnouncement(\n announcements.moved({\n label,\n targetLabel: getNodeLabelText(targetId),\n position,\n index: movedIndex(targetId, position),\n count: siblings.length,\n })\n )\n }\n return\n }\n case 'ArrowRight': {\n // 移入:成為最近 enabled 上一 sibling 的子項(沿用 pointer「inside 限 folder」規則)\n let target: HTMLElement | undefined\n for (let i = sourceIndex - 1; i >= 0; i--) {\n if (isEnabled(siblings[i])) { target = siblings[i]; break }\n }\n if (!target) {\n setReorderAnnouncement(announcements.blocked({ reason: 'not-folder', label }))\n return\n }\n const targetId = target.dataset.treeId!\n if (target.dataset.treeHasChildren !== 'true') {\n setReorderAnnouncement(\n announcements.blocked({ reason: 'not-folder', label, targetLabel: getNodeLabelText(targetId) })\n )\n return\n }\n const wasExpanded = expandedIds.has(targetId)\n if (commit(targetId, 'inside')) {\n // 移入 collapsed folder:允許 + 自動展開(pointer 500ms hover auto-expand 的鍵盤對應物)\n if (!wasExpanded) toggleExpand(targetId)\n // 序數:consumer 對 inside 的慣例語意 = append 到 children 尾端;\n // folder 原收合 → children 未 mount 無從計數 → 播報省略序數(誠實不猜)。\n const childCount = wasExpanded\n ? visibleItems.filter((el) => el.dataset.treeParentId === targetId).length\n : undefined\n setReorderAnnouncement(\n announcements.movedInside({\n label,\n folderLabel: getNodeLabelText(targetId),\n index: childCount !== undefined ? childCount + 1 : undefined,\n count: childCount !== undefined ? childCount + 1 : undefined,\n })\n )\n }\n return\n }\n case 'ArrowLeft': {\n // 移出:成為 parent 的下一個 sibling(outdent)\n if (!parentId) {\n setReorderAnnouncement(announcements.blocked({ reason: 'root', label }))\n return\n }\n const parentEl = tree.querySelector<HTMLElement>(`[data-tree-id=\"${parentId}\"]`)\n const level = Number(parentEl?.getAttribute('aria-level') ?? '1')\n if (commit(parentId, 'after')) {\n setReorderAnnouncement(\n announcements.movedOut({ label, parentLabel: getNodeLabelText(parentId), level })\n )\n }\n return\n }\n }\n },\n [focusedId, expandedIds, toggleExpand, onDragEndProp, getNodeLabelText, isInSubtree, announcements]\n )\n\n // ── Context value ──\n const contextValue = React.useMemo<TreeViewContextValue>(\n () => ({\n size,\n context,\n selectionMode,\n expandOnSelect,\n draggable,\n isKeyboardRef,\n activeDescendantPrefix,\n draggingId,\n dropTarget,\n expandedIds,\n selectedIds,\n focusedId,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n getNodeInfo,\n }),\n [\n size,\n context,\n selectionMode,\n expandOnSelect,\n draggable,\n isKeyboardRef,\n activeDescendantPrefix,\n draggingId,\n dropTarget,\n expandedIds,\n selectedIds,\n focusedId,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n getNodeInfo,\n ]\n )\n\n // ── Keyboard handler ──\n const treeRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => treeRef.current!)\n\n const handleMouseDown = React.useCallback(() => {\n isKeyboardRef.current = false\n }, [])\n\n // code-quality-allow: long-function — helper fn 結構緊密,拆 sub-fn 會跨 fn 傳 state 反而複雜\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n isKeyboardRef.current = true\n if (!treeRef.current) return\n\n // ── 鍵盤重排:Cmd/Ctrl+Shift+方向鍵(2026-07-14 v1,詳 spec「鍵盤重排」)──\n // 必排在下方「無焦點時方向鍵先聚焦第一項」分支之前(該分支不分 modifier 攔 Arrow*);\n // 非 modifier 導覽路徑(下方 switch)完全不變。\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && REORDER_ARROW_KEYS.includes(e.key)) {\n if (!draggable) return // 未啟用拖曳 → 整組 no-op(modifier 組合不落入導覽 switch)\n e.preventDefault() // 阻止瀏覽器原生行為(捲動 / 文字選取)\n if (draggingId !== null) return // pointer 拖曳進行中 → 互斥,忽略鍵盤重排\n handleKeyboardReorder(e.key as ReorderArrowKey)\n return\n }\n\n // 取得所有可見的 treeitem\n const items = Array.from(\n // a11y:排除 disabled 節點 → 鍵盤導覽/選取/展開全跳過(APG:disabled 不可鍵盤操作)\n treeRef.current.querySelectorAll<HTMLElement>('[role=\"treeitem\"]:not([hidden]):not([aria-disabled=\"true\"])')\n )\n const currentIndex = items.findIndex(\n (el) => el.dataset.treeId === focusedId\n )\n // a11y:沒焦點時任一方向鍵先聚焦第一個(含 ArrowLeft/Right,原漏 → AT 無 activedescendant 可讀)\n if (currentIndex < 0 && items.length > 0 && ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {\n // 沒有焦點時,任何方向鍵先聚焦第一個\n setFocusedId(items[0].dataset.treeId ?? null)\n e.preventDefault()\n return\n }\n\n const currentEl = items[currentIndex]\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const next = items[currentIndex + 1]\n if (next) setFocusedId(next.dataset.treeId ?? null)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prev = items[currentIndex - 1]\n if (prev) setFocusedId(prev.dataset.treeId ?? null)\n break\n }\n case 'ArrowRight': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (!id) break\n const isExpanded = expandedIds.has(id)\n const hasChildren = currentEl?.dataset.treeHasChildren === 'true'\n if (hasChildren && !isExpanded) {\n toggleExpand(id)\n } else if (hasChildren && isExpanded) {\n // 已展開 → 移到第一個 child\n const next = items[currentIndex + 1]\n if (next) setFocusedId(next.dataset.treeId ?? null)\n }\n break\n }\n case 'ArrowLeft': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (!id) break\n const isExpanded = expandedIds.has(id)\n const hasChildren = currentEl?.dataset.treeHasChildren === 'true'\n if (hasChildren && isExpanded) {\n toggleExpand(id)\n } else {\n // 收合狀態或 leaf → 移到 parent\n const parentId = currentEl?.dataset.treeParentId\n if (parentId) setFocusedId(parentId)\n }\n break\n }\n case 'Home': {\n e.preventDefault()\n if (items[0]) setFocusedId(items[0].dataset.treeId ?? null)\n break\n }\n case 'End': {\n e.preventDefault()\n const last = items[items.length - 1]\n if (last) setFocusedId(last.dataset.treeId ?? null)\n break\n }\n case 'Enter':\n case ' ': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (id) select(id)\n break\n }\n }\n },\n [focusedId, expandedIds, toggleExpand, select, setFocusedId, draggable, draggingId, handleKeyboardReorder]\n )\n\n const treeEl = (\n <div\n // {...props} 在最前:內部 role/style(--tree-px)/onKeyDown/tabIndex 必須勝過 consumer\n // 誤傳(原 spread 在最後 → consumer style 會整組蓋掉 --tree-px、onKeyDown 蓋掉鍵盤導覽)\n {...props}\n ref={treeRef}\n role=\"tree\"\n aria-multiselectable={selectionMode === 'multiple' || undefined}\n // Virtual focus:DOM focus 停在容器(單一 tab stop),aria-activedescendant 指向目前 node\n // 的 DOM id,讓 AT 朗讀目前焦點 node(對齊 WAI-ARIA TreeView APG aria-activedescendant 模式)。\n aria-activedescendant={focusedId ? `${activeDescendantPrefix}treeitem-${focusedId}` : undefined}\n // 鍵盤重排操作說明(sr-only,僅 draggable;與 consumer 傳入的 aria-describedby 合併)\n aria-describedby={\n [props['aria-describedby'], draggable ? reorderInstructionsId : undefined]\n .filter(Boolean)\n .join(' ') || undefined\n }\n className={cn(\n // TreeView root 不加任何 py——呼吸空間由外層容器負責:\n // - 在 SidebarGroup 內: SidebarGroup py-2 提供\n // - 在 DropdownMenuContent 內: content py-2 提供\n // - 獨立使用(story demo): consumer 自己加 py-2\n // 這樣才能跟 DropdownMenu / MenuGroup 的結構一致(group 是容器,row 是內容)。\n 'flex flex-col',\n className,\n )}\n style={{\n ['--tree-px' as string]: CONTEXT_PX_VAR[context],\n ...props.style,\n } as React.CSSProperties}\n onKeyDown={handleKeyDown}\n onMouseDown={handleMouseDown}\n // a11y APG:Tab 進入時初始化 virtual focus(優先 selected,其次第一個可用節點);\n // 原本無 onFocus init → focusedId=null → aria-activedescendant undefined,AT 讀不到目前節點\n onFocus={(e) => {\n ;(props as React.HTMLAttributes<HTMLDivElement>).onFocus?.(e)\n if (e.target === e.currentTarget && !focusedId && treeRef.current) {\n const first =\n treeRef.current.querySelector<HTMLElement>('[role=\"treeitem\"][aria-selected=\"true\"]:not([hidden]):not([aria-disabled=\"true\"])') ??\n treeRef.current.querySelector<HTMLElement>('[role=\"treeitem\"]:not([hidden]):not([aria-disabled=\"true\"])')\n if (first) setFocusedId(first.dataset.treeId ?? null)\n }\n }}\n tabIndex={0}\n >\n {children}\n </div>\n )\n\n return (\n <TreeViewContext.Provider value={contextValue}>\n {/* RowSizeProvider:讓 TreeView 子樹內任何 <ItemIcon> / <ItemAvatar> /\n <ItemInlineAction> 自動讀到對的 size,跟 SidebarProvider 同一條規則。\n inlineActions API 也吃這個 context。 */}\n <RowSizeProvider value={size}>\n {/* 永遠包 DndContext(hooks 不能 conditional call)。不 draggable 時無 sensors = 不可拖 */}\n <DndContext\n sensors={draggable ? sensors : undefined}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n {treeEl}\n {draggable && (\n <>\n {/* 鍵盤重排 SR 播報 — TreeView 自有 sr-only polite live region(單一節點覆寫式更新;\n 消費 select-menu.tsx SelectMenuLiveStatus 先例)。渲染在 role=\"tree\" 之外\n (tree 的合法 children 只有 treeitem / group);dnd-kit DndContext 內建 live region\n 只播 dnd-kit drag session,自建鍵盤路徑觸不到,故必須自有。 */}\n <div role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {reorderAnnouncement}\n </div>\n {/* 鍵盤重排操作說明 — tree 容器 aria-describedby 指向(對齊 dnd-kit\n screenReaderInstructions 慣例:https://dndkit.com/guides/accessibility) */}\n <div id={reorderInstructionsId} className=\"sr-only\">\n {announcements.instructions}\n </div>\n </>\n )}\n {draggable && (\n <DragOverlay dropAnimation={null}>\n {draggingId ? (() => {\n const info = getNodeInfo(draggingId)\n const IconComp = info?.icon\n return (\n <div className={cn(\n 'flex items-center gap-2 rounded-lg bg-surface border border-border pointer-events-none',\n 'shadow-[var(--elevation-200)]',\n size === 'lg' ? 'text-body-lg leading-compact px-4 py-2' : 'text-body leading-compact px-3 py-1.5',\n )}>\n {IconComp && <IconComp size={ICON_SIZE[size]} className=\"shrink-0\" aria-hidden />}\n <span className=\"text-foreground truncate max-w-[200px]\">{info?.label ?? draggingId}</span>\n </div>\n )\n })() : null}\n </DragOverlay>\n )}\n </DndContext>\n </RowSizeProvider>\n </TreeViewContext.Provider>\n )\n }\n)\nTreeView.displayName = 'TreeView'\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeItem variants\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst treeItemVariants = cva(\n [\n // items-start:多行 label 時 prefix 留在第一行(item-layout 規則)\n 'flex items-start gap-2 w-full',\n 'cursor-pointer select-none',\n 'transition-colors duration-150',\n 'outline-none',\n // Label 字重 500(跟 SidebarMenuButton 一致)\n 'font-medium',\n ],\n {\n variants: {\n // 消費 ROW_PADDING_BY_SIZE SSOT(item-anatomy.tsx)— drift risk 消除\n size: ROW_PADDING_BY_SIZE,\n },\n defaultVariants: {\n size: 'md',\n },\n }\n)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeItem\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TreeItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'id'> {\n /** 唯一 id。必填,用於 expand / select / keyboard 追蹤 */\n id: string\n /** 主要文字 */\n label: React.ReactNode\n /** 左側 icon(chevron 之後)。LucideIcon 型別,尺寸由 TreeView size 決定 */\n icon?: LucideIcon\n /**\n * Checkbox(多選模式,label 前方)。傳入 ReactNode(Checkbox 元件)。\n * 位置:在 icon 之後、label 之前。\n * 單選模式通常不需要(用 bg-neutral-selected 表達選中)。\n */\n checkbox?: React.ReactNode\n /**\n * 右側 inline actions(suffix slot,宣告式 API)。對齊 `patterns/element-anatomy/inline-action.spec.md`\n * 與 `SidebarMenuButton.inlineActions` 的同一條規格——TreeItem / SidebarMenuButton /\n * 未來的 row primitive 全部用同一個 declarative API。\n *\n * Consumer 只宣告 intent,TreeItem 用 `<ItemInlineAction>` 自動渲染:\n * - Icon 尺寸 = `ICON_SIZE[treeViewSize]`(自動)\n * - Hover bg、tooltip、aria-label、cursor-pointer 自動處理\n * - **不可以**手刻 button JSX(canonical 實作在 `patterns/element-anatomy/item-anatomy.tsx` `ItemInlineAction`)\n *\n * ```tsx\n * <TreeItem\n * id=\"inbox\"\n * icon={Inbox}\n * label=\"Inbox\"\n * inlineActions={[\n * { icon: MoreVertical, label: '更多', onClick: handleMore },\n * { icon: Plus, label: '新增', onClick: handleAdd },\n * ]}\n * actionsReveal=\"hover\"\n * />\n * ```\n *\n * 若需要永遠可見的 suffix(如 badge 計數),放在 `label` 內:\n * ```tsx\n * <TreeItem label={<>Inbox <Badge count={3} /></>} />\n * ```\n */\n inlineActions?: InlineActionConfig[]\n /**\n * 右側 actions slot(ReactNode)— escape hatch 供 consumer 放自訂元素\n * (如 DropdownMenu trigger / 自訂 popover / 多 tier 動作)。\n *\n * 跟 `inlineActions` 互斥(同時傳 `inlineActionsSlot` 會優先,`inlineActions` 被忽略)。\n *\n * 規則對齊 Input.endSlot canonical:90% case 用 `inlineActions` 宣告式 API,\n * 10% config 表達不出時走 slot。視覺一致性由 consumer 負責(可使用 host 內部 helper\n * — 但禁止 app-code 直接 import L3 primitive,見 `check_canonical_propagation.sh` E.2,原 `check_l3_primitive_import` 已 folded)。\n */\n inlineActionsSlot?: React.ReactNode\n /**\n * Inline actions 的顯示模式:\n * - `\"hover\"`(預設):row hover 或鍵盤 focus(focus-visible)時才淡入\n * - `false`:常駐顯示\n *\n * 對齊 `SidebarMenuButton.actionsReveal`,同一套規則。\n */\n actionsReveal?: false | \"hover\"\n /**\n * 取代 icon 的位置。用於 stepper 的 status indicator(●/○/✓)。\n * 設定後 icon 不渲染、改渲染 indicator;chevron 永遠保留(expandable=旋轉箭頭 / leaf=placeholder)。\n */\n indicator?: React.ReactNode\n /** 是否停用 */\n disabled?: boolean\n /** 子 TreeItem(有 children = expandable,沒有 = leaf) */\n children?: React.ReactNode\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TreeItem = React.forwardRef<HTMLDivElement, TreeItemProps>(\n ({ id, label, icon: Icon, checkbox, inlineActions, inlineActionsSlot, actionsReveal = 'hover', indicator, disabled, children, className, ...props }, ref) => {\n const ctx = useTreeView()\n const depth = React.useContext(DepthContext)\n const {\n size,\n selectionMode,\n expandOnSelect,\n draggable,\n expandedIds,\n selectedIds,\n focusedId,\n draggingId,\n dropTarget,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n isKeyboardRef,\n activeDescendantPrefix,\n } = ctx\n\n const hasChildren = React.Children.count(children) > 0\n const isExpanded = expandedIds.has(id)\n const isSelected = selectedIds.has(id)\n const isFocused = focusedId === id\n const showRing = isFocused && isKeyboardRef.current\n const isDragging = draggingId === id\n const isDropTarget = dropTarget?.id === id\n\n const iconPx = ICON_SIZE[size]\n const indentPx = depth * INDENT_STEP[size]\n\n // ── Drag hooks ──\n // Figma 風格:整列可拖(不用 grip handle),靠 distance:5 區分 click vs drag\n const { attributes: dragAttrs, listeners: dragListeners, setNodeRef: setDragRef } = useDraggable({\n id, disabled: !draggable || disabled,\n })\n const { setNodeRef: setDropRef } = useDroppable({\n id, disabled: !draggable || disabled,\n })\n\n // ── 找 parent id(from depth context chain)──\n const parentId = React.useContext(ParentIdContext)\n\n // ── Register / unregister ──\n React.useEffect(() => {\n registerNode(id, parentId, hasChildren, label, Icon)\n return () => unregisterNode(id)\n }, [id, parentId, hasChildren, label, Icon, registerNode, unregisterNode])\n\n // ── Focus scroll into view ──\n const itemRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => itemRef.current!)\n\n React.useEffect(() => {\n if (isFocused && itemRef.current) {\n itemRef.current.scrollIntoView({ block: 'nearest' })\n }\n }, [isFocused])\n\n // ── Handlers ──\n const handleRowClick = React.useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return\n e.stopPropagation()\n setFocusedId(id)\n select(id)\n if (expandOnSelect && hasChildren) {\n toggleExpand(id)\n }\n },\n [id, disabled, select, setFocusedId, expandOnSelect, hasChildren, toggleExpand]\n )\n\n const handleChevronClick = React.useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (disabled) return\n toggleExpand(id)\n },\n [id, disabled, toggleExpand]\n )\n\n // ── Chevron(永遠存在:expandable = 旋轉箭頭;leaf = placeholder 佔位) ──\n // 消費 `<ItemPrefix>` SSOT — 永遠 h-[1lh] 對齊 label 第一行中線(item-anatomy 對應)。\n // forced width 透過 style 鎖 chevron 槽寬,讓 sibling label 起點水平對齊(無 chevron leaf 佔位同寬)。\n const chevronSlot = (\n <ItemPrefix style={{ width: iconPx }}>\n {hasChildren ? (\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={handleChevronClick}\n className={cn(\n 'flex items-center justify-center rounded-md',\n 'text-fg-muted hover:text-foreground hover:bg-neutral-hover',\n 'transition-all duration-150',\n isExpanded && 'rotate-90',\n disabled && 'text-fg-disabled pointer-events-none',\n )}\n style={{ width: iconPx, height: iconPx }}\n aria-hidden\n >\n <ChevronRight size={iconPx} />\n </button>\n ) : (\n // Leaf placeholder\n <span style={{ width: iconPx }} aria-hidden />\n )}\n </ItemPrefix>\n )\n\n return (\n <ParentIdContext.Provider value={id}>\n <div\n ref={(node) => {\n (itemRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n // DOM id 供容器 aria-activedescendant 指向(virtual focus);與 data-tree-id 並存\n // (data-tree-id 給內部 querySelector / drag,id 給 AT)。\n id={`${activeDescendantPrefix}treeitem-${id}`}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={selectionMode !== 'none' ? isSelected : undefined}\n aria-level={depth + 1}\n aria-disabled={disabled || undefined}\n // 2026-07-05 D4 修:aria-roledescription 移到 treeitem(有 role 的元素才合法)—\n // 供 AT 提示此 node 可拖曳;值消費 dnd-kit attributes SSOT(預設 'draggable')。\n aria-roledescription={draggable && !disabled ? dragAttrs['aria-roledescription'] : undefined}\n data-tree-id={id}\n data-tree-parent-id={parentId ?? ''}\n data-tree-has-children={hasChildren}\n tabIndex={-1}\n className={cn('w-full min-w-0 relative', isDragging && dragSourceClass)}\n >\n {/* Drop indicator — before:水平 2px primary line(指 SSOT drag-visual.ts);\n indent 跟隨 depth(left 由 inline style override class 的 left-0)*/}\n {isDropTarget && dropTarget?.position === 'before' && (\n <div\n className={dropIndicatorRow.before}\n style={{ left: `calc(var(--tree-px) + ${indentPx}px)` }}\n />\n )}\n\n {/* Row: draggable + droppable 都在這一行(合併 ref),確保碰撞偵測只看行高 */}\n <div\n ref={(node) => {\n // 合併 drag + drop ref 到同一個 element\n if (draggable) setDragRef(node)\n setDropRef(node)\n }}\n data-tree-row={id}\n className={cn(\n 'group/tree-item',\n treeItemVariants({ size }),\n // 2026-05-26 SSOT lock(user explicit「multi 已有 checkbox 強信號,text 不該再變色」):\n // ── Single mode ──\n // - default text 預設 fg-secondary muted(hierarchy navigation 慣例,跟 Sidebar 一致)\n // - selected → text-foreground emphasis + bg-neutral-selected(無 checkbox,需 text+bg 雙信號)\n // ── Multi mode ──\n // - default text 維持 fg-secondary muted(跟 single 對齊 hierarchy)\n // - selected → 視覺信號只在 checkbox(auto-render below),text 不變、bg 不變\n // - 對齊 SelectMenu multi pattern(menu-item.tsx:194-195 selected → bg only;multi → checkbox only)\n // multi-selected 也維持 fg-secondary(上方註解「text 不變」;原 !isSelected 條件讓 multi-selected 掉到繼承色)\n !disabled && (!isSelected || selectionMode === 'multiple') && 'text-fg-secondary',\n !disabled && isSelected && selectionMode === 'single' && 'text-foreground',\n isDropTarget && dropTarget?.position === 'inside' && dropIndicatorInside,\n !disabled && 'hover:bg-neutral-hover hover:text-foreground',\n !disabled && isSelected && selectionMode === 'single' && 'bg-neutral-selected',\n showRing && 'ring-2 ring-ring ring-inset',\n disabled && 'pointer-events-none text-fg-disabled cursor-default',\n className,\n )}\n style={{\n paddingLeft: indentPx > 0\n ? `calc(var(--tree-px) + ${indentPx}px)`\n : 'var(--tree-px)',\n paddingRight: 'var(--tree-px)',\n }}\n onClick={handleRowClick}\n // 2026-07-05 D4 修:只 spread listeners,不 spread dnd-kit attributes —\n // useDraggable 預設 attributes 注入 role=\"button\" + tabIndex=0 + aria-pressed +\n // aria-describedby(鍵盤拖曳指示):role=button 污染 treeitem 語意、tabIndex=0\n // 讓每 row 變 DOM tab stop 破壞單一 tab stop 虛擬焦點模型(DOM focus 在 row 上按\n // Enter 會 bubble 到容器 handleKeyDown 但 handler 操作 state focusedId → 錯位);\n // sensors 僅 PointerSensor(無 KeyboardSensor),這些 attrs 換不到鍵盤拖曳能力;\n // 鍵盤重排(2026-07-14 v1)走容器 handleKeyDown 的 Cmd/Ctrl+Shift+Arrow 分支,非 dnd-kit sensor。\n // aria-roledescription 保留在上方 treeitem 元素(有 role 才合法)。\n {...(draggable ? dragListeners : {})}\n {...props}\n >\n {chevronSlot}\n\n {/* Checkbox 在 icon 前——消費 `<ItemPrefix>` 對齊第一行\n * 2026-05-26 SSOT lock(user explicit「多選的方式應該也是要跟 menu 一樣是出現 checkbox」):\n * - selectionMode='multiple' + 無 consumer checkbox prop → auto-render `<Checkbox>` reflect selectedIds\n * (對齊 SelectMenu multi pattern;consumer 不用手寫 checkbox)\n * - selectionMode='multiple' + consumer 傳 checkbox → 用 consumer 的(parent-child cascade 等 advanced)\n * - selectionMode='single' / 'none' → 不 render checkbox(text-foreground + bg 雙信號表 selected)\n * 對齊 cite:menu-item.tsx:194-195(MenuItem selected bg)+ select-menu.tsx:352-354(SelectMenu multi=checkbox) */}\n {(checkbox || selectionMode === 'multiple') && (\n <ItemPrefix className=\"pointer-events-none\">\n {/* 2026-07-05 D4 修:auto-render Checkbox 補 tabIndex={-1} — Radix Checkbox root\n * 是原生 button(預設可聚焦),aria-hidden + 可聚焦 = axe aria-hidden-focus,且\n * 破壞 tree 單一 tab stop 虛擬焦點模型(tree-view.spec.md「Focus」段);\n * ItemPrefix pointer-events-none 只擋滑鼠不擋鍵盤。選取語意由 treeitem\n * aria-selected 承載,checkbox 純視覺反映。 */}\n {checkbox || <Checkbox checked={isSelected} disabled={disabled} aria-hidden=\"true\" tabIndex={-1} />}\n </ItemPrefix>\n )}\n\n {/* indicator 取代 icon 的位置;h-[1lh] 對齊第一行\n indicator 是 escape hatch(stepper status dot 等客製內容),消費 `<ItemPrefix>` 鎖 chevron 槽寬;\n Icon 走 canonical `<ItemIcon>` helper——自動標 data-prefix-type=\"icon\",\n 讓 SidebarProvider 的全域 :has() prefix-mix 偵測能命中。 */}\n {indicator ? (\n <ItemPrefix style={{ width: iconPx }}>\n {indicator}\n </ItemPrefix>\n ) : Icon ? (\n <ItemIcon icon={Icon} className={disabled ? 'text-fg-disabled' : undefined} />\n ) : null}\n\n <span className={cn('flex-1 min-w-0 truncate', disabled && 'text-fg-disabled')}>\n {label}\n </span>\n\n {/* Suffix inline actions——宣告式 API,用 `<ItemInlineAction>` 渲染。\n 消費 `<ItemSuffix hoverReveal hoverGroup=\"tree-item\">` SSOT(2026-05-05 v8 group selector 參數化後)。\n actionsReveal=\"hover\"(預設):row hover 或 keyboard focus-visible 才顯示;\n actionsReveal=false:常駐顯示。跟 SidebarMenuButton 共用同一條規則,行為一致。\n inlineActionsSlot escape hatch 優先(consumer 自控 JSX,reveal 一樣套外層 group)。 */}\n {/* 2026-06-12 R2(同 sidebar.tsx 修):宿主 disabled 時 render 層擋 inline actions —\n inline-action.spec.md「宿主 disabled | 不渲染」;row pointer-events 蓋不住\n actionsReveal=false 常駐顯示的視覺暗示,必須 render 層 guard。 */}\n {disabled ? null : inlineActionsSlot ? (\n <ItemSuffix hoverReveal={actionsReveal === 'hover'} hoverGroup=\"tree-item\">\n {inlineActionsSlot}\n </ItemSuffix>\n ) : inlineActions && inlineActions.length > 0 ? (\n <ItemSuffix hoverReveal={actionsReveal === 'hover'} hoverGroup=\"tree-item\">\n {inlineActions.map((action, i) => (\n <ItemInlineAction key={action.label + i} action={action} />\n ))}\n </ItemSuffix>\n ) : null}\n </div>\n\n {/* Drop indicator — after:同 before mirror 到 bottom edge(SSOT drag-visual.ts)*/}\n {isDropTarget && dropTarget?.position === 'after' && (\n <div\n className={dropIndicatorRow.after}\n style={{ left: `calc(var(--tree-px) + ${indentPx}px)` }}\n />\n )}\n\n {/* Children: Collapsible 展開/收合 */}\n {hasChildren && (\n <CollapsiblePrimitive.Root open={isExpanded}>\n <CollapsiblePrimitive.Content\n className=\"overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down\"\n >\n <DepthContext.Provider value={depth + 1}>\n <div role=\"group\" className=\"flex flex-col w-full\">\n {children}\n </div>\n </DepthContext.Provider>\n </CollapsiblePrimitive.Content>\n </CollapsiblePrimitive.Root>\n )}\n </div>\n </ParentIdContext.Provider>\n )\n }\n)\nTreeItem.displayName = 'TreeItem'\n\n// Parent ID context for keyboard navigation (← to parent)\nconst ParentIdContext = React.createContext<string | null>(null)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Exports\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const treeViewMeta = {\n component: 'TreeView',\n family: 1, // Family 1(Menu item layout)消費者 — 對齊 tree-view.spec.md frontmatter family: 1\n variants: {\n\n },\n sizes: {\n // 對齊 tree-view.spec.md frontmatter(compile-stories --check 驗 key 一致)\n sm: { typography: 'body', indent: 24 },\n md: { typography: 'body', indent: 24 }, // default\n lg: { typography: 'body-lg', indent: 28 },\n },\n // 'selected' = single-selection 持續選中(bg-neutral-selected + aria-selected);'active' 移除 —\n // 全檔無 Tailwind 按壓 utility,無按壓專屬視覺態(2026-07-07 詞彙統一對抗稽核補修)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-neutral-hover', 'bg-neutral-selected', 'bg-surface'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-fg-secondary', 'text-foreground'],\n ring: ['ring-ring'],\n },\n defaultSize: 'md',\n} as const\n\nexport { TreeView, TreeItem, treeItemVariants }\n"],"names":["treeEl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tree-view.js","sources":["../../../src/components/TreeView/tree-view.tsx"],"sourcesContent":["// code-quality-allow: file-size — foundational composite(TreeView owns tree logic + TreeItem + drag-drop + keyboard;拆 sub-component 會把 register/unregister 跨檔傳 ref 複雜化超過可讀性 gain)\nimport * as React from 'react'\nimport * as CollapsiblePrimitive from '@radix-ui/react-collapsible'\nimport {\n DndContext,\n DragOverlay,\n useDraggable,\n useDroppable,\n PointerSensor,\n useSensor,\n useSensors,\n type DragStartEvent,\n type DragEndEvent,\n type DragOverEvent,\n} from '@dnd-kit/core'\nimport { ChevronRight } from 'lucide-react'\nimport { cva } from 'class-variance-authority'\nimport type { LucideIcon } from 'lucide-react'\nimport { dragSourceClass, dropIndicatorRow, dropIndicatorInside } from '@/design-system/lib/drag-visual'\nimport { cn } from '@/lib/utils'\nimport { Checkbox } from '@/design-system/components/Checkbox/checkbox'\n// Row primitive 共用常數——單一 source of truth\nimport {\n ICON_SIZE,\n RowSizeProvider,\n ItemIcon,\n ItemPrefix,\n ItemSuffix,\n ItemInlineAction,\n ROW_PADDING_BY_SIZE,\n type InlineActionConfig,\n} from '@/design-system/patterns/element-anatomy/item-anatomy'\n\n/**\n * TreeView — 階層結構的遞迴元件\n *\n * 一個 TreeItem 就是一個 node——有 children 就可展開,沒有就是 leaf。\n * 沒有第二個概念(沒有 TreeGroup)。\n *\n * TreeView 負責:\n * 1. 遞迴渲染 + indent\n * 2. 展開/收合狀態管理\n * 3. 鍵盤導覽 + ARIA tree\n *\n * 它不管 node 裡面長什麼樣——icon、badge、status indicator 等\n * 由 consumer 透過 props / slots 決定。\n *\n * 詳見 tree-view.spec.md。\n */\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ntype SizeKey = 'sm' | 'md' | 'lg'\ntype SelectionMode = 'single' | 'multiple' | 'none'\n/**\n * TreeView 的使用脈絡,決定 item 的水平 padding:\n * - `'sidebar'`:頁面側邊欄,用 `--layout-space-loose` token(md=16px / lg=24px,跟 density 連動)\n * - `'menu'`:浮層選單 / dropdown,px-3(12px),對齊 MenuItem / DropdownMenu\n */\ntype TreeContext = 'sidebar' | 'menu'\n\n// Base horizontal padding per context — 用 CSS variable 注入到 TreeView 容器,\n// TreeItem 用 calc(var(--tree-px) + indent) 算出最終 paddingLeft。\nconst CONTEXT_PX_VAR: Record<TreeContext, string> = {\n sidebar: 'var(--layout-space-loose)', // md=16px, lg=24px(density 連動)\n menu: '12px', // px-3,對齊 MenuItem / DropdownMenu\n}\n\n/** Drag drop position — 拖放目標的三種位置 */\n// code-quality-allow: dead-export — public event/state type — consumer event handler parameter type\nexport type TreeDropPosition = 'before' | 'after' | 'inside'\n\n/** onDragEnd callback 的參數 */\n// code-quality-allow: dead-export — public event/state type — consumer event handler parameter type\nexport interface TreeDragEndEvent {\n /** 被拖曳的 node id */\n sourceId: string\n /** 目標 node id */\n targetId: string\n /** 放置位置:before(同層上方)/ after(同層下方)/ inside(成為子 node) */\n position: TreeDropPosition\n}\n\n/**\n * 鍵盤重排(`Cmd/Ctrl+Shift+方向鍵`,2026-07-14 v1)的 SR 播報文案 — zh-TW 預設,\n * per-key merge 覆寫(i18n 覆寫點)。詳 tree-view.spec.md「鍵盤重排」。\n * @public\n */\n// code-quality-allow: dead-export — public prop type — consumer 覆寫播報文案的參數型別\nexport interface TreeReorderAnnouncements {\n /** 同層上/下移完成。`index` / `count` = 移動後在同層的 1-based 序數 / 同層總數 */\n moved?: (args: { label: string; targetLabel: string; position: 'before' | 'after'; index: number; count: number }) => string\n /** 移入 folder 完成。folder 原本收合(children 尚未 mount)時序數不可知 → `index` / `count` 為 undefined */\n movedInside?: (args: { label: string; folderLabel: string; index?: number; count?: number }) => string\n /** 移出到上層完成。`level` = 移動後所在層(1-based,同 aria-level 語意) */\n movedOut?: (args: { label: string; parentLabel: string; level: number }) => string\n /** 邊界 no-op:top(已在最上方)/ bottom(已在最下方)/ not-folder(無可移入的 folder)/ root(已在最外層) */\n blocked?: (args: { reason: 'top' | 'bottom' | 'not-folder' | 'root'; label: string; targetLabel?: string }) => string\n /** sr-only 操作說明(tree 容器 `aria-describedby` 指向;僅 `draggable` 時渲染) */\n instructions?: string\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Constants\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Icon / chevron 尺寸——從 item-layout pattern module 引入(在檔頂 import),\n// 這裡本地不再宣告。所有 row primitives 共用同一個常數。\n\n// indentStep = chevronSize + gap-2(8px)。值 {24,24,28} 與 CSS token `--tree-indent-{sm,md,lg}`\n// (`tokens/uiSize/uiSize.css`)**完全一致、必須同步維護**(改一處要兩處一起改;非「token 取代 literal」)。\n// 為何兩源並存:本元件 render 用此 JS literal 算 `indentPx`(TreeItem inline calc 需 number)+ drop-indicator\n// pointer 數學(handleDragOver px 命中判斷,CSS var 在 JS 計算層拿不到);DataTable nested rows\n// 則走 CSS token 的 Tailwind class(跨元件視覺一致)。結構對齊:子 chevron 對齊父 icon,子 icon 對齊父 label。\nconst INDENT_STEP: Record<SizeKey, number> = { sm: 24, md: 24, lg: 28 }\n\n// ── 鍵盤重排(keyboard reorder,2026-07-14 v1)常數 ──\n// 鍵位 = Cmd/Ctrl+Shift+方向鍵,對齊 Notion 移動 block 鍵位(https://www.notion.com/help/keyboard-shortcuts,\n// WebFetch 驗證紀錄 .claude/logs/treeview-keyboard-dnd-design.md#L25);\n// modifier 層與 APG tree 導覽鍵(無 modifier 的 ↑↓→←)完全正交,零衝突。\nconst REORDER_ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']\ntype ReorderArrowKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight'\n\n// 鍵盤重排 SR 播報預設文案(zh-TW;consumer 經 `reorderAnnouncements` prop per-key 覆寫)。\n// 格式 =「結果 + 序數位置」— 非視覺使用者靠「第 n 項,共 m 項」建立位置模型\n// (世界級 cite 詳 tree-view.spec.md「鍵盤重排」段,M22)。\n// i18n-allow-block: DS default SR-only 播報文案,prop 可覆寫(同 select-menu.tsx SelectMenuLiveStatus 先例)\nconst DEFAULT_REORDER_ANNOUNCEMENTS: Required<TreeReorderAnnouncements> = {\n moved: ({ label, targetLabel, position, index, count }) =>\n `已將『${label}』移到『${targetLabel}』${position === 'before' ? '之前' : '之後'},第 ${index} 項,共 ${count} 項`,\n movedInside: ({ label, folderLabel, index, count }) =>\n index !== undefined && count !== undefined\n ? `已將『${label}』移入『${folderLabel}』,第 ${index} 項,共 ${count} 項`\n : `已將『${label}』移入『${folderLabel}』`,\n movedOut: ({ label, parentLabel, level }) =>\n `已將『${label}』移出到『${parentLabel}』之後,第 ${level} 層`,\n blocked: ({ reason, targetLabel }) => {\n switch (reason) {\n case 'top': return '已在最上方'\n case 'bottom': return '已在最下方'\n case 'not-folder': return targetLabel ? `無法移入:『${targetLabel}』不是資料夾` : '無法移入'\n case 'root': return '已在最外層'\n }\n },\n instructions: '按 Cmd(Ctrl)+Shift+方向鍵可重新排列項目',\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Context\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface TreeViewContextValue {\n size: SizeKey\n context: TreeContext\n selectionMode: SelectionMode\n expandOnSelect: boolean\n draggable: boolean\n isKeyboardRef: React.RefObject<boolean>\n /**\n * Per-tree instance 前綴(React.useId),用來組每個 treeitem 的 DOM `id`\n * (`${prefix}treeitem-${nodeId}`),讓容器的 `aria-activedescendant` 能指向目前 focused node。\n * 多棵 TreeView 同頁 / node id 跨樹重複時不會撞 DOM id。\n */\n activeDescendantPrefix: string\n expandedIds: Set<string>\n selectedIds: Set<string>\n focusedId: string | null\n /** 目前拖曳中的 node id(null = 沒在拖) */\n draggingId: string | null\n /** 目前 drop indicator 的位置 + depth(用於 line indent) */\n dropTarget: { id: string; position: TreeDropPosition; depth: number } | null\n toggleExpand: (id: string) => void\n select: (id: string) => void\n setFocusedId: (id: string | null) => void\n registerNode: (id: string, parentId: string | null, hasChildren: boolean, label?: React.ReactNode, icon?: LucideIcon) => void\n getNodeInfo: (id: string) => NodeInfo | undefined\n unregisterNode: (id: string) => void\n}\n\nconst TreeViewContext = React.createContext<TreeViewContextValue | null>(null)\n\nfunction useTreeView(): TreeViewContextValue {\n const ctx = React.useContext(TreeViewContext)\n if (!ctx) throw new Error('TreeItem must be used within TreeView')\n return ctx\n}\n\n// TreeItem depth context(遞迴 depth tracking)\nconst DepthContext = React.createContext(0)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Node registry — 追蹤所有 node 的 parent/children 關係,用於鍵盤導覽\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface NodeInfo {\n id: string\n parentId: string | null\n hasChildren: boolean\n /** 用於 DragOverlay ghost 渲染 */\n label?: React.ReactNode\n icon?: LucideIcon\n}\n\nfunction useNodeRegistry() {\n const nodesRef = React.useRef(new Map<string, NodeInfo>())\n\n const registerNode = React.useCallback(\n (id: string, parentId: string | null, hasChildren: boolean, label?: React.ReactNode, icon?: LucideIcon) => {\n nodesRef.current.set(id, { id, parentId, hasChildren, label, icon })\n },\n []\n )\n\n const unregisterNode = React.useCallback((id: string) => {\n nodesRef.current.delete(id)\n }, [])\n\n const getNodeInfo = React.useCallback((id: string) => nodesRef.current.get(id), [])\n\n return { nodesRef, registerNode, unregisterNode, getNodeInfo }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeView\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onDragEnd'> {\n /** 元件尺寸,影響 node 高度、icon 大小、indent 寬度 */\n size?: SizeKey\n /**\n * 使用脈絡,決定 item 的水平 padding:\n * - `'sidebar'`(預設):頁面側邊欄,`--layout-space-loose`(md=16px / lg=24px,隨 density 連動)\n * - `'menu'`:浮層選單 / dropdown,px-3(12px),對齊 MenuItem\n */\n context?: TreeContext\n /** 選取模式。預設 'single'(sidebar nav / stepper) */\n selectionMode?: SelectionMode\n /** 點擊 label 時是否同時展開 children。預設 false(chevron 是展開的唯一控件) */\n expandOnSelect?: boolean\n /** 受控:展開的 node id 集合 */\n expandedIds?: Set<string>\n /** 受控:展開狀態變更 callback */\n onExpandedChange?: (ids: Set<string>) => void\n /** 受控:選取的 node id 集合 */\n selectedIds?: Set<string>\n /** 受控:選取狀態變更 callback */\n onSelectedChange?: (ids: Set<string>) => void\n /** 非受控:預設展開的 node id 陣列 */\n defaultExpandedIds?: string[]\n /** 非受控:預設選取的 node id 陣列 */\n defaultSelectedIds?: string[]\n /**\n * 啟用拖曳排序。預設 false。\n * 啟用後整列可拖(Figma 風格,無 grip handle;靠 distance:5 區分 click vs drag),\n * 拖曳時顯示 drop indicator(before / after / inside 三種位置)。\n * Consumer 透過 `onDragEnd` callback 接收 reorder 事件,自行更新 data。\n */\n draggable?: boolean\n /** Drag 結束時觸發,提供 sourceId、targetId、position。Consumer 負責 reorder。 */\n onDragEnd?: (event: TreeDragEndEvent) => void\n /**\n * 鍵盤重排(`Cmd/Ctrl+Shift+方向鍵`)的 SR 播報文案覆寫(per-key merge;zh-TW 預設)。\n * 僅在 `draggable` 時生效;含 `instructions`(sr-only 操作說明)。\n * @public\n */\n reorderAnnouncements?: TreeReorderAnnouncements\n /** ARIA label */\n 'aria-label'?: string\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TreeView = React.forwardRef<HTMLDivElement, TreeViewProps>(\n (\n {\n size = 'md',\n context = 'sidebar',\n selectionMode = 'single',\n expandOnSelect = false,\n draggable = false,\n onDragEnd: onDragEndProp,\n reorderAnnouncements: reorderAnnouncementsProp,\n expandedIds: controlledExpanded,\n onExpandedChange,\n selectedIds: controlledSelected,\n onSelectedChange,\n defaultExpandedIds = [],\n defaultSelectedIds = [],\n className,\n children,\n ...props\n },\n ref\n ) => {\n // ── Accessible name dev-warn(2026-07-18:兌現 spec「Accessible name 必填契約」段承諾 —\n // 原 spec 宣稱有此 console.warn 但 code 缺,spec-code drift;補上使兩者一致)──\n // role=\"tree\" 名稱無法從子節點推導,缺 aria-label / aria-labelledby → SR 只讀「tree」。\n // 對齊 Button / Tag 的 dev-only 誤用警告 idiom;production 不觸發。\n const ariaLabel = props['aria-label']\n const ariaLabelledby = props['aria-labelledby']\n React.useEffect(() => {\n if (\n process.env.NODE_ENV !== 'production' &&\n ariaLabel == null &&\n ariaLabelledby == null\n ) {\n console.warn(\n '[DS] TreeView:role=\"tree\" 缺 accessible name — 請傳 aria-label(直接字串)或 aria-labelledby(指向可見標題 id)其一。' +\n '兩者皆缺時螢幕閱讀器只讀出「tree」無法辨識用途(WAI-ARIA APG 要求 role=\"tree\" 具 accessible name)。',\n )\n }\n }, [ariaLabel, ariaLabelledby])\n\n // ── Expand state(受控 / 非受控) ──\n const [internalExpanded, setInternalExpanded] = React.useState(\n () => new Set(defaultExpandedIds)\n )\n const expandedIds = controlledExpanded ?? internalExpanded\n const setExpandedIds = React.useCallback(\n (updater: (prev: Set<string>) => Set<string>) => {\n const update = (prev: Set<string>) => {\n const next = updater(prev)\n onExpandedChange?.(next)\n return next\n }\n if (controlledExpanded) {\n update(controlledExpanded)\n } else {\n setInternalExpanded(update)\n }\n },\n [controlledExpanded, onExpandedChange]\n )\n\n // ── Selection state(受控 / 非受控) ──\n const [internalSelected, setInternalSelected] = React.useState(\n () => new Set(defaultSelectedIds)\n )\n const selectedIds = controlledSelected ?? internalSelected\n const setSelectedIds = React.useCallback(\n (updater: (prev: Set<string>) => Set<string>) => {\n const update = (prev: Set<string>) => {\n const next = updater(prev)\n onSelectedChange?.(next)\n return next\n }\n if (controlledSelected) {\n update(controlledSelected)\n } else {\n setInternalSelected(update)\n }\n },\n [controlledSelected, onSelectedChange]\n )\n\n // ── Focus state ──\n const [focusedId, setFocusedId] = React.useState<string | null>(null)\n\n // ── Virtual focus id prefix ──\n // DOM focus 永遠停在 role=tree 容器(單一 tab stop);目前 node 透過 aria-activedescendant\n // 告知 AT(對齊 DS 既有 cmdk virtual-focus canonical:SelectMenu / Command listbox)。\n // useId 確保多棵 TreeView 同頁 / node id 跨樹重複時 DOM id 不撞。\n const activeDescendantPrefix = React.useId()\n\n // ── 鍵盤重排 SR 播報(2026-07-14 v1;詳 spec「鍵盤重排」)──\n // 單一 polite live region 覆寫式更新(textContent 替換非 append → 快速連按天然只播最新)。\n // 不可借 dnd-kit DndContext 內建 live region — 它只播 dnd-kit 管理的 drag session,\n // 自建鍵盤路徑觸不到。消費 select-menu.tsx SelectMenuLiveStatus role=\"status\" 先例。\n const [reorderAnnouncement, setReorderAnnouncement] = React.useState('')\n const announcements = React.useMemo(\n () => ({ ...DEFAULT_REORDER_ANNOUNCEMENTS, ...reorderAnnouncementsProp }),\n [reorderAnnouncementsProp]\n )\n // sr-only 操作說明節點 id(tree 容器 aria-describedby 指向;僅 draggable 渲染)\n const reorderInstructionsId = `${activeDescendantPrefix}tree-reorder-instructions`\n\n // ── Keyboard vs mouse detection ──\n // focus ring 只在鍵盤操作時顯示,滑鼠點擊用 bg-neutral-selected 表達選中,不顯示 ring\n const isKeyboardRef = React.useRef(false)\n\n // ── Drag state ──\n const [draggingId, setDraggingId] = React.useState<string | null>(null)\n const [dropTarget, setDropTarget] = React.useState<{ id: string; position: TreeDropPosition; depth: number } | null>(null)\n const autoExpandTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n // 2026-05-16 audit codex Round 6:unmount cleanup(原 cleanup 只在 dragEnd/dragCancel,unmount-during-drag 漏 cancel)\n React.useEffect(() => () => { if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current) }, [])\n // Ref for toggleExpand — handleDragOver 定義在 toggleExpand 之前(hook 順序限制),\n // 用 ref 打斷 temporal dead zone。\n const toggleExpandRef = React.useRef<(id: string) => void>(() => {})\n\n // ── Node registry ──(2026-07-14 上移至 drag handlers 之前:isInSubtree 消費 getNodeInfo,\n // 而 handleDragOver / handleDragEnd / 鍵盤 reorder 都消費 isInSubtree)\n const { registerNode, unregisterNode, getNodeInfo } = useNodeRegistry()\n\n // 子樹判定:candidate 是否位於 rootId 的子樹內(含相等)。沿 registry parentId 鏈上溯。\n // 雙路共用 SSOT:pointer 路徑 descendant drop guard(2026-07-14 R6 修:原 handleDragOver 只擋\n // `over.id === active.id` 未擋 descendants → 可發出 targetId ∈ source 子樹的非法事件,\n // consumer 按 remove→insert 實作會讓整個子樹靜默消失)+ 鍵盤 reorder commit 前防禦 assert。\n const isInSubtree = React.useCallback(\n (candidateId: string, rootId: string): boolean => {\n let cur: string | null = candidateId\n while (cur != null) {\n if (cur === rootId) return true\n cur = getNodeInfo(cur)?.parentId ?? null\n }\n return false\n },\n [getNodeInfo]\n )\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } })\n )\n\n const handleDragStart = React.useCallback((event: DragStartEvent) => {\n setDraggingId(String(event.active.id))\n }, [])\n\n // ── Figma-style drop detection(X + Y 雙軸)──\n //\n // Y 軸:決定在哪個 item 附近\n // - item 上 25% = before\n // - item 中 50% = inside(只有 folder)\n // - item 下 25% = after\n //\n // X 軸:決定 nesting 深度(Figma 核心邏輯)\n // - 滑鼠越左 = 越淺層(放在 parent 層級)\n // - 滑鼠越右 = 越深層(放進 folder)\n // - 用 pointer X 相對於 tree 左邊界計算 indent level\n //\n const handleDragOver = React.useCallback((event: DragOverEvent) => {\n const { over, active } = event\n // 2026-07-14 R6 descendant guard:over 是 active 自己「或其子樹內節點」→ 無效目標,\n // 不設 dropTarget(拖 folder 進自己子樹會發出非法 TreeDragEndEvent;guard SSOT = isInSubtree,\n // 鍵盤 reorder 路徑共用同一 helper)。\n if (!over || isInSubtree(String(over.id), String(active.id))) {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n setDropTarget(null)\n return\n }\n\n const rowEl = document.querySelector(`[data-tree-row=\"${over.id}\"]`) as HTMLElement | null\n const targetEl = document.querySelector(`[data-tree-id=\"${over.id}\"]`) as HTMLElement | null\n if (!rowEl || !targetEl) { setDropTarget(null); return }\n\n // 實際指標位置\n const startX = (event.activatorEvent as PointerEvent)?.clientX ?? 0\n const startY = (event.activatorEvent as PointerEvent)?.clientY ?? 0\n const currentX = startX + (event.delta?.x ?? 0)\n const currentY = startY + (event.delta?.y ?? 0)\n\n const rect = rowEl.getBoundingClientRect()\n const offsetY = currentY - rect.top\n const height = rect.height || 32\n const ratio = Math.max(0, Math.min(1, offsetY / height))\n\n const hasChildren = targetEl.dataset.treeHasChildren === 'true'\n const targetDepth = Number(targetEl.getAttribute('aria-level') ?? 1) - 1\n\n // ── X 軸:計算指標在哪個 indent level ──\n const treeEl = treeRef.current\n const treeLeft = treeEl?.getBoundingClientRect().left ?? 0\n const indentStep = INDENT_STEP[size]\n const pointerIndentLevel = Math.max(0, Math.floor((currentX - treeLeft) / indentStep))\n\n let position: TreeDropPosition\n let finalDepth = targetDepth\n\n if (hasChildren) {\n // Folder node\n if (ratio < 0.25) {\n position = 'before'\n } else if (ratio > 0.75) {\n // after folder: 如果指標在 folder 層級或更淺 = after(同層)\n // 如果指標更深 = inside(放進 folder)\n position = pointerIndentLevel > targetDepth ? 'inside' : 'after'\n } else {\n position = 'inside'\n }\n } else {\n // Leaf node\n if (ratio < 0.5) {\n position = 'before'\n } else {\n position = 'after'\n // X 軸:如果指標在比 target 更淺的層級,提升 drop depth\n // 例:Contact(depth 1)的 after,如果滑鼠在 depth 0 → 變成「after Pages」\n if (pointerIndentLevel < targetDepth) {\n // 找 parent 來放\n const groupEl = targetEl.closest('[role=\"group\"]')\n const parentTreeItem = groupEl?.parentElement?.closest('[role=\"treeitem\"]')\n const parentId = parentTreeItem?.getAttribute('data-tree-id')\n if (parentId && parentId !== String(active.id)) {\n const parentDepth = Number(parentTreeItem?.getAttribute('aria-level') ?? 1) - 1\n finalDepth = parentDepth\n setDropTarget(prev => prev && prev.id === parentId && prev.position === 'after' && prev.depth === parentDepth ? prev : { id: parentId, position: 'after', depth: parentDepth })\n return\n }\n }\n }\n }\n\n // 2026-07-06 D3 perf:bail-out — drop target 未變(每 dragOver 跨 row 才變)時回傳 prev,\n // React 對相同 reference bail out,避免每次 over 事件重建 contextValue → 全樹 TreeItem re-render。\n setDropTarget(prev => {\n const id = String(over.id)\n return prev && prev.id === id && prev.position === position && prev.depth === finalDepth ? prev : { id, position, depth: finalDepth }\n })\n\n // Auto-expand collapsed folder after 500ms hover (Figma behavior)\n if (position === 'inside' && hasChildren && !expandedIds.has(String(over.id))) {\n if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current)\n autoExpandTimerRef.current = setTimeout(() => {\n toggleExpandRef.current(String(over.id))\n }, 500)\n } else {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n }\n }, [expandedIds, isInSubtree])\n\n const dropTargetRef = React.useRef(dropTarget)\n dropTargetRef.current = dropTarget\n\n const handleDragEnd = React.useCallback((event: DragEndEvent) => {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n const { active, over } = event\n const dt = dropTargetRef.current\n // descendant guard 同 handleDragOver(dt 已由 dragOver guard 保證為 null,此為 belt-and-braces)\n if (over && !isInSubtree(String(over.id), String(active.id)) && dt) {\n onDragEndProp?.({\n sourceId: String(active.id),\n targetId: String(over.id),\n position: dt.position,\n })\n }\n setDraggingId(null)\n setDropTarget(null)\n }, [onDragEndProp, isInSubtree])\n\n const handleDragCancel = React.useCallback(() => {\n if (autoExpandTimerRef.current) { clearTimeout(autoExpandTimerRef.current); autoExpandTimerRef.current = null }\n setDraggingId(null)\n setDropTarget(null)\n }, [])\n\n // ── Actions ──\n const toggleExpand = React.useCallback(\n (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n },\n [setExpandedIds]\n )\n toggleExpandRef.current = toggleExpand\n\n const select = React.useCallback(\n (id: string) => {\n if (selectionMode === 'none') return\n setSelectedIds((prev) => {\n if (selectionMode === 'single') {\n return new Set([id])\n }\n // multiple\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n },\n [selectionMode, setSelectedIds]\n )\n\n // ── Keyboard reorder(Cmd/Ctrl+Shift+方向鍵,2026-07-14 v1)──\n // 設計 SSOT:tree-view.spec.md「鍵盤重排」。與 pointer 路徑共用 TreeDragEndEvent 契約 +\n // onDragEnd prop + registry(consumer API 零改動);每按一下立即 commit(無 grab-mode /\n // 無預覽,對齊 Notion Cmd/Ctrl+Shift+Arrow 移動 block:https://www.notion.com/help/keyboard-shortcuts,\n // WebFetch 驗證紀錄 .claude/logs/treeview-keyboard-dnd-design.md#L25)。\n // 不用 dnd-kit KeyboardSensor — 其 activator 需可接收 DOM focus\n // (https://dndkit.com/api-documentation/sensors/keyboard),與 row tabIndex={-1} +\n // aria-activedescendant 虛擬焦點模型結構性不相容(2026-07-05 D4 拍板不翻案)。\n\n // 播報用 label 文字:registry label 是 ReactNode — string 直接用,否則退 DOM row textContent。\n const getNodeLabelText = React.useCallback(\n (id: string): string => {\n const info = getNodeInfo(id)\n if (typeof info?.label === 'string') return info.label\n const rowEl = treeRef.current?.querySelector<HTMLElement>(`[data-tree-row=\"${id}\"]`)\n return rowEl?.textContent?.trim() || id\n },\n [getNodeInfo]\n )\n\n // code-quality-allow: long-function — 四鍵語意(同層上下 / 移入 / 移出)+ 邊界播報結構緊密,\n // 拆 sub-fn 會跨 fn 傳 siblings / announce state 反而複雜(同 handleKeyDown 先例)\n const handleKeyboardReorder = React.useCallback(\n (key: ReorderArrowKey) => {\n const tree = treeRef.current\n if (!tree || !focusedId) return\n const sourceId = focusedId\n const sourceEl = tree.querySelector<HTMLElement>(`[data-tree-id=\"${sourceId}\"]`)\n // disabled node 不可移(鍵盤導覽本就跳過 disabled,此為防禦 guard)\n if (!sourceEl || sourceEl.getAttribute('aria-disabled') === 'true') return\n\n const label = getNodeLabelText(sourceId)\n // 同層 siblings(DOM 序)。focused node 可見 ⇒ 其 parent 已展開 ⇒ 全 siblings 已 mount。\n const parentId = sourceEl.dataset.treeParentId || null\n const visibleItems = Array.from(\n tree.querySelectorAll<HTMLElement>('[role=\"treeitem\"]:not([hidden])')\n )\n const siblings = visibleItems.filter((el) => (el.dataset.treeParentId || null) === parentId)\n const sourceIndex = siblings.findIndex((el) => el.dataset.treeId === sourceId)\n if (sourceIndex < 0) return\n const isEnabled = (el: HTMLElement) => el.getAttribute('aria-disabled') !== 'true'\n\n // 發出與 pointer 路徑同型的 TreeDragEndEvent,並排定 re-render 後 scrollIntoView\n // (既有 effect 只在 isFocused 變化時跑;同 id 移動不 re-fire,故此處補)。\n const commit = (targetId: string, position: TreeDropPosition): boolean => {\n // 結構安全 assert:四鍵語意(sibling 間 / 進 prev sibling / 出 parent)結構上\n // 不可能移進自己子樹;防禦性仍擋(與 pointer descendant guard 共用 isInSubtree SSOT)。\n if (targetId === sourceId || isInSubtree(targetId, sourceId)) return false\n onDragEndProp?.({ sourceId, targetId, position })\n requestAnimationFrame(() => {\n treeRef.current\n ?.querySelector<HTMLElement>(`[data-tree-id=\"${sourceId}\"]`)\n ?.scrollIntoView({ block: 'nearest' })\n })\n return true\n }\n\n // 同層移動後的 1-based 新序數(播報用):移除 source 再插入的模擬;同層總數不變。\n const movedIndex = (targetId: string, position: 'before' | 'after'): number => {\n const order = siblings.map((el) => el.dataset.treeId).filter((id) => id !== sourceId)\n const tIdx = order.indexOf(targetId)\n return (position === 'before' ? tIdx : tIdx + 1) + 1\n }\n\n switch (key) {\n case 'ArrowUp':\n case 'ArrowDown': {\n // disabled sibling 不可當 target 錨點(pointer useDroppable 同樣 disable)——\n // 相鄰 sibling disabled 時錨到最近 enabled sibling 並翻轉 before/after 表達同一插槽\n // (可達位置與 pointer 一致);整個方向皆無 enabled sibling → 視同邊界。\n const dir = key === 'ArrowUp' ? -1 : 1\n const boundary = dir < 0 ? ('top' as const) : ('bottom' as const)\n const adjacent = siblings[sourceIndex + dir]\n if (!adjacent) {\n setReorderAnnouncement(announcements.blocked({ reason: boundary, label }))\n return\n }\n let target: HTMLElement | undefined\n let position: 'before' | 'after' = dir < 0 ? 'before' : 'after'\n if (isEnabled(adjacent)) {\n target = adjacent\n } else {\n for (let i = sourceIndex + dir; i >= 0 && i < siblings.length; i += dir) {\n if (isEnabled(siblings[i])) { target = siblings[i]; break }\n }\n position = dir < 0 ? 'after' : 'before' // 錨到最近 enabled sibling 的另一側 = 相鄰插槽\n }\n if (!target) {\n setReorderAnnouncement(announcements.blocked({ reason: boundary, label }))\n return\n }\n const targetId = target.dataset.treeId!\n if (commit(targetId, position)) {\n setReorderAnnouncement(\n announcements.moved({\n label,\n targetLabel: getNodeLabelText(targetId),\n position,\n index: movedIndex(targetId, position),\n count: siblings.length,\n })\n )\n }\n return\n }\n case 'ArrowRight': {\n // 移入:成為最近 enabled 上一 sibling 的子項(沿用 pointer「inside 限 folder」規則)\n let target: HTMLElement | undefined\n for (let i = sourceIndex - 1; i >= 0; i--) {\n if (isEnabled(siblings[i])) { target = siblings[i]; break }\n }\n if (!target) {\n setReorderAnnouncement(announcements.blocked({ reason: 'not-folder', label }))\n return\n }\n const targetId = target.dataset.treeId!\n if (target.dataset.treeHasChildren !== 'true') {\n setReorderAnnouncement(\n announcements.blocked({ reason: 'not-folder', label, targetLabel: getNodeLabelText(targetId) })\n )\n return\n }\n const wasExpanded = expandedIds.has(targetId)\n if (commit(targetId, 'inside')) {\n // 移入 collapsed folder:允許 + 自動展開(pointer 500ms hover auto-expand 的鍵盤對應物)\n if (!wasExpanded) toggleExpand(targetId)\n // 序數:consumer 對 inside 的慣例語意 = append 到 children 尾端;\n // folder 原收合 → children 未 mount 無從計數 → 播報省略序數(誠實不猜)。\n const childCount = wasExpanded\n ? visibleItems.filter((el) => el.dataset.treeParentId === targetId).length\n : undefined\n setReorderAnnouncement(\n announcements.movedInside({\n label,\n folderLabel: getNodeLabelText(targetId),\n index: childCount !== undefined ? childCount + 1 : undefined,\n count: childCount !== undefined ? childCount + 1 : undefined,\n })\n )\n }\n return\n }\n case 'ArrowLeft': {\n // 移出:成為 parent 的下一個 sibling(outdent)\n if (!parentId) {\n setReorderAnnouncement(announcements.blocked({ reason: 'root', label }))\n return\n }\n const parentEl = tree.querySelector<HTMLElement>(`[data-tree-id=\"${parentId}\"]`)\n const level = Number(parentEl?.getAttribute('aria-level') ?? '1')\n if (commit(parentId, 'after')) {\n setReorderAnnouncement(\n announcements.movedOut({ label, parentLabel: getNodeLabelText(parentId), level })\n )\n }\n return\n }\n }\n },\n [focusedId, expandedIds, toggleExpand, onDragEndProp, getNodeLabelText, isInSubtree, announcements]\n )\n\n // ── Context value ──\n const contextValue = React.useMemo<TreeViewContextValue>(\n () => ({\n size,\n context,\n selectionMode,\n expandOnSelect,\n draggable,\n isKeyboardRef,\n activeDescendantPrefix,\n draggingId,\n dropTarget,\n expandedIds,\n selectedIds,\n focusedId,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n getNodeInfo,\n }),\n [\n size,\n context,\n selectionMode,\n expandOnSelect,\n draggable,\n isKeyboardRef,\n activeDescendantPrefix,\n draggingId,\n dropTarget,\n expandedIds,\n selectedIds,\n focusedId,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n getNodeInfo,\n ]\n )\n\n // ── Keyboard handler ──\n const treeRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => treeRef.current!)\n\n const handleMouseDown = React.useCallback(() => {\n isKeyboardRef.current = false\n }, [])\n\n // code-quality-allow: long-function — helper fn 結構緊密,拆 sub-fn 會跨 fn 傳 state 反而複雜\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n isKeyboardRef.current = true\n if (!treeRef.current) return\n\n // ── 互動 descendant 自理鍵盤(先於導覽 / 重排分支)──\n // 公開 inlineActions / inlineActionsSlot 經 <ItemInlineAction> 渲染的原生 <button>\n // (及 consumer slot 內的 link / field / role=button)是各自獨立的 tab stop(spec\n // A11y「單一 tab stop」段)。其 Enter/Space/方向鍵應由該控件自理——若冒泡到容器\n // handleKeyDown,下方 Enter/Space 分支的 e.preventDefault()+select() 會吃掉 button\n // 原生啟動並誤選 tree node。虛擬焦點模型下 tree 導覽/重排只在事件來自容器本身時處理\n // (DOM focus 停在 tree 容器;treeitem row / chevron / checkbox 皆 tabIndex=-1)。\n const keyTarget = e.target as HTMLElement | null\n if (keyTarget && keyTarget !== e.currentTarget) {\n const interactive = keyTarget.closest<HTMLElement>(\n 'a[href], button, input, select, textarea, [contenteditable=\"true\"], [tabindex]:not([tabindex=\"-1\"])'\n )\n // interactive === e.currentTarget:唯一可聚焦祖先是 tree 容器(tabIndex=0 單一 tab\n // stop 進出點)→ 屬非互動 descendant,照常走 tree 導覽。\n if (interactive && interactive !== e.currentTarget) return\n }\n\n // ── 鍵盤重排:Cmd/Ctrl+Shift+方向鍵(2026-07-14 v1,詳 spec「鍵盤重排」)──\n // 必排在下方「無焦點時方向鍵先聚焦第一項」分支之前(該分支不分 modifier 攔 Arrow*);\n // 非 modifier 導覽路徑(下方 switch)完全不變。\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && REORDER_ARROW_KEYS.includes(e.key)) {\n if (!draggable) return // 未啟用拖曳 → 整組 no-op(modifier 組合不落入導覽 switch)\n e.preventDefault() // 阻止瀏覽器原生行為(捲動 / 文字選取)\n if (draggingId !== null) return // pointer 拖曳進行中 → 互斥,忽略鍵盤重排\n handleKeyboardReorder(e.key as ReorderArrowKey)\n return\n }\n\n // 取得所有可見的 treeitem\n const items = Array.from(\n // a11y:排除 disabled 節點 → 鍵盤導覽/選取/展開全跳過(APG:disabled 不可鍵盤操作)\n treeRef.current.querySelectorAll<HTMLElement>('[role=\"treeitem\"]:not([hidden]):not([aria-disabled=\"true\"])')\n )\n const currentIndex = items.findIndex(\n (el) => el.dataset.treeId === focusedId\n )\n // a11y:沒焦點時任一方向鍵先聚焦第一個(含 ArrowLeft/Right,原漏 → AT 無 activedescendant 可讀)\n if (currentIndex < 0 && items.length > 0 && ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {\n // 沒有焦點時,任何方向鍵先聚焦第一個\n setFocusedId(items[0].dataset.treeId ?? null)\n e.preventDefault()\n return\n }\n\n const currentEl = items[currentIndex]\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const next = items[currentIndex + 1]\n if (next) setFocusedId(next.dataset.treeId ?? null)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prev = items[currentIndex - 1]\n if (prev) setFocusedId(prev.dataset.treeId ?? null)\n break\n }\n case 'ArrowRight': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (!id) break\n const isExpanded = expandedIds.has(id)\n const hasChildren = currentEl?.dataset.treeHasChildren === 'true'\n if (hasChildren && !isExpanded) {\n toggleExpand(id)\n } else if (hasChildren && isExpanded) {\n // 已展開 → 移到第一個 child\n const next = items[currentIndex + 1]\n if (next) setFocusedId(next.dataset.treeId ?? null)\n }\n break\n }\n case 'ArrowLeft': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (!id) break\n const isExpanded = expandedIds.has(id)\n const hasChildren = currentEl?.dataset.treeHasChildren === 'true'\n if (hasChildren && isExpanded) {\n toggleExpand(id)\n } else {\n // 收合狀態或 leaf → 移到 parent\n const parentId = currentEl?.dataset.treeParentId\n if (parentId) setFocusedId(parentId)\n }\n break\n }\n case 'Home': {\n e.preventDefault()\n if (items[0]) setFocusedId(items[0].dataset.treeId ?? null)\n break\n }\n case 'End': {\n e.preventDefault()\n const last = items[items.length - 1]\n if (last) setFocusedId(last.dataset.treeId ?? null)\n break\n }\n case 'Enter':\n case ' ': {\n e.preventDefault()\n const id = currentEl?.dataset.treeId\n if (id) select(id)\n break\n }\n }\n },\n [focusedId, expandedIds, toggleExpand, select, setFocusedId, draggable, draggingId, handleKeyboardReorder]\n )\n\n const treeEl = (\n <div\n // {...props} 在最前:內部 role/style(--tree-px)/onKeyDown/tabIndex 必須勝過 consumer\n // 誤傳(原 spread 在最後 → consumer style 會整組蓋掉 --tree-px、onKeyDown 蓋掉鍵盤導覽)\n {...props}\n ref={treeRef}\n role=\"tree\"\n aria-multiselectable={selectionMode === 'multiple' || undefined}\n // Virtual focus:DOM focus 停在容器(單一 tab stop),aria-activedescendant 指向目前 node\n // 的 DOM id,讓 AT 朗讀目前焦點 node(對齊 WAI-ARIA TreeView APG aria-activedescendant 模式)。\n aria-activedescendant={focusedId ? `${activeDescendantPrefix}treeitem-${focusedId}` : undefined}\n // 鍵盤重排操作說明(sr-only,僅 draggable;與 consumer 傳入的 aria-describedby 合併)\n aria-describedby={\n [props['aria-describedby'], draggable ? reorderInstructionsId : undefined]\n .filter(Boolean)\n .join(' ') || undefined\n }\n className={cn(\n // TreeView root 不加任何 py——呼吸空間由外層容器負責:\n // - 在 SidebarGroup 內: SidebarGroup py-2 提供\n // - 在 DropdownMenuContent 內: content py-2 提供\n // - 獨立使用(story demo): consumer 自己加 py-2\n // 這樣才能跟 DropdownMenu / MenuGroup 的結構一致(group 是容器,row 是內容)。\n 'flex flex-col',\n className,\n )}\n style={{\n ['--tree-px' as string]: CONTEXT_PX_VAR[context],\n ...props.style,\n } as React.CSSProperties}\n onKeyDown={handleKeyDown}\n onMouseDown={handleMouseDown}\n // a11y APG:Tab 進入時初始化 virtual focus(優先 selected,其次第一個可用節點);\n // 原本無 onFocus init → focusedId=null → aria-activedescendant undefined,AT 讀不到目前節點\n onFocus={(e) => {\n ;(props as React.HTMLAttributes<HTMLDivElement>).onFocus?.(e)\n if (e.target === e.currentTarget && !focusedId && treeRef.current) {\n const first =\n treeRef.current.querySelector<HTMLElement>('[role=\"treeitem\"][aria-selected=\"true\"]:not([hidden]):not([aria-disabled=\"true\"])') ??\n treeRef.current.querySelector<HTMLElement>('[role=\"treeitem\"]:not([hidden]):not([aria-disabled=\"true\"])')\n if (first) setFocusedId(first.dataset.treeId ?? null)\n }\n }}\n tabIndex={0}\n >\n {children}\n </div>\n )\n\n return (\n <TreeViewContext.Provider value={contextValue}>\n {/* RowSizeProvider:讓 TreeView 子樹內任何 <ItemIcon> / <ItemAvatar> /\n <ItemInlineAction> 自動讀到對的 size,跟 SidebarProvider 同一條規則。\n inlineActions API 也吃這個 context。 */}\n <RowSizeProvider value={size}>\n {/* 永遠包 DndContext(hooks 不能 conditional call)。不 draggable 時無 sensors = 不可拖 */}\n <DndContext\n sensors={draggable ? sensors : undefined}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n {treeEl}\n {draggable && (\n <>\n {/* 鍵盤重排 SR 播報 — TreeView 自有 sr-only polite live region(單一節點覆寫式更新;\n 消費 select-menu.tsx SelectMenuLiveStatus 先例)。渲染在 role=\"tree\" 之外\n (tree 的合法 children 只有 treeitem / group);dnd-kit DndContext 內建 live region\n 只播 dnd-kit drag session,自建鍵盤路徑觸不到,故必須自有。 */}\n <div role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {reorderAnnouncement}\n </div>\n {/* 鍵盤重排操作說明 — tree 容器 aria-describedby 指向(對齊 dnd-kit\n screenReaderInstructions 慣例:https://dndkit.com/guides/accessibility) */}\n <div id={reorderInstructionsId} className=\"sr-only\">\n {announcements.instructions}\n </div>\n </>\n )}\n {draggable && (\n <DragOverlay dropAnimation={null}>\n {draggingId ? (() => {\n const info = getNodeInfo(draggingId)\n const IconComp = info?.icon\n return (\n <div className={cn(\n 'flex items-center gap-2 rounded-lg bg-surface border border-border pointer-events-none',\n 'shadow-[var(--elevation-200)]',\n size === 'lg' ? 'text-body-lg leading-compact px-4 py-2' : 'text-body leading-compact px-3 py-1.5',\n )}>\n {IconComp && <IconComp size={ICON_SIZE[size]} className=\"shrink-0\" aria-hidden />}\n <span className=\"text-foreground truncate max-w-[200px]\">{info?.label ?? draggingId}</span>\n </div>\n )\n })() : null}\n </DragOverlay>\n )}\n </DndContext>\n </RowSizeProvider>\n </TreeViewContext.Provider>\n )\n }\n)\nTreeView.displayName = 'TreeView'\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeItem variants\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst treeItemVariants = cva(\n [\n // items-start:多行 label 時 prefix 留在第一行(item-layout 規則)\n 'flex items-start gap-2 w-full',\n 'cursor-pointer select-none',\n 'transition-colors duration-150',\n 'outline-none',\n // Label 字重 500(跟 SidebarMenuButton 一致)\n 'font-medium',\n ],\n {\n variants: {\n // 消費 ROW_PADDING_BY_SIZE SSOT(item-anatomy.tsx)— drift risk 消除\n size: ROW_PADDING_BY_SIZE,\n },\n defaultVariants: {\n size: 'md',\n },\n }\n)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TreeItem\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface TreeItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'id'> {\n /** 唯一 id。必填,用於 expand / select / keyboard 追蹤 */\n id: string\n /** 主要文字 */\n label: React.ReactNode\n /** 左側 icon(chevron 之後)。LucideIcon 型別,尺寸由 TreeView size 決定 */\n icon?: LucideIcon\n /**\n * Checkbox(多選模式,label 前方)。傳入 ReactNode(Checkbox 元件)。\n * 位置:在 icon 之後、label 之前。\n * 單選模式通常不需要(用 bg-neutral-selected 表達選中)。\n */\n checkbox?: React.ReactNode\n /**\n * 右側 inline actions(suffix slot,宣告式 API)。對齊 `patterns/element-anatomy/inline-action.spec.md`\n * 與 `SidebarMenuButton.inlineActions` 的同一條規格——TreeItem / SidebarMenuButton /\n * 未來的 row primitive 全部用同一個 declarative API。\n *\n * Consumer 只宣告 intent,TreeItem 用 `<ItemInlineAction>` 自動渲染:\n * - Icon 尺寸 = `ICON_SIZE[treeViewSize]`(自動)\n * - Hover bg、tooltip、aria-label、cursor-pointer 自動處理\n * - **不可以**手刻 button JSX(canonical 實作在 `patterns/element-anatomy/item-anatomy.tsx` `ItemInlineAction`)\n *\n * ```tsx\n * <TreeItem\n * id=\"inbox\"\n * icon={Inbox}\n * label=\"Inbox\"\n * inlineActions={[\n * { icon: MoreVertical, label: '更多', onClick: handleMore },\n * { icon: Plus, label: '新增', onClick: handleAdd },\n * ]}\n * actionsReveal=\"hover\"\n * />\n * ```\n *\n * 若需要永遠可見的 suffix(如 badge 計數),放在 `label` 內:\n * ```tsx\n * <TreeItem label={<>Inbox <Badge count={3} /></>} />\n * ```\n */\n inlineActions?: InlineActionConfig[]\n /**\n * 右側 actions slot(ReactNode)— escape hatch 供 consumer 放自訂元素\n * (如 DropdownMenu trigger / 自訂 popover / 多 tier 動作)。\n *\n * 跟 `inlineActions` 互斥(同時傳 `inlineActionsSlot` 會優先,`inlineActions` 被忽略)。\n *\n * 規則對齊 Input.endSlot canonical:90% case 用 `inlineActions` 宣告式 API,\n * 10% config 表達不出時走 slot。視覺一致性由 consumer 負責(可使用 host 內部 helper\n * — 但禁止 app-code 直接 import L3 primitive,見 `check_canonical_propagation.sh` E.2,原 `check_l3_primitive_import` 已 folded)。\n */\n inlineActionsSlot?: React.ReactNode\n /**\n * Inline actions 的顯示模式:\n * - `\"hover\"`(預設):row hover 或鍵盤 focus(focus-visible)時才淡入\n * - `false`:常駐顯示\n *\n * 對齊 `SidebarMenuButton.actionsReveal`,同一套規則。\n */\n actionsReveal?: false | \"hover\"\n /**\n * 取代 icon 的位置。用於 stepper 的 status indicator(●/○/✓)。\n * 設定後 icon 不渲染、改渲染 indicator;chevron 永遠保留(expandable=旋轉箭頭 / leaf=placeholder)。\n */\n indicator?: React.ReactNode\n /** 是否停用 */\n disabled?: boolean\n /** 子 TreeItem(有 children = expandable,沒有 = leaf) */\n children?: React.ReactNode\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TreeItem = React.forwardRef<HTMLDivElement, TreeItemProps>(\n ({ id, label, icon: Icon, checkbox, inlineActions, inlineActionsSlot, actionsReveal = 'hover', indicator, disabled, children, className, ...props }, ref) => {\n const ctx = useTreeView()\n const depth = React.useContext(DepthContext)\n const {\n size,\n selectionMode,\n expandOnSelect,\n draggable,\n expandedIds,\n selectedIds,\n focusedId,\n draggingId,\n dropTarget,\n toggleExpand,\n select,\n setFocusedId,\n registerNode,\n unregisterNode,\n isKeyboardRef,\n activeDescendantPrefix,\n } = ctx\n\n const hasChildren = React.Children.count(children) > 0\n const isExpanded = expandedIds.has(id)\n const isSelected = selectedIds.has(id)\n const isFocused = focusedId === id\n const showRing = isFocused && isKeyboardRef.current\n const isDragging = draggingId === id\n const isDropTarget = dropTarget?.id === id\n\n const iconPx = ICON_SIZE[size]\n const indentPx = depth * INDENT_STEP[size]\n\n // ── Drag hooks ──\n // Figma 風格:整列可拖(不用 grip handle),靠 distance:5 區分 click vs drag\n const { attributes: dragAttrs, listeners: dragListeners, setNodeRef: setDragRef } = useDraggable({\n id, disabled: !draggable || disabled,\n })\n const { setNodeRef: setDropRef } = useDroppable({\n id, disabled: !draggable || disabled,\n })\n\n // ── 找 parent id(from depth context chain)──\n const parentId = React.useContext(ParentIdContext)\n\n // ── Register / unregister ──\n React.useEffect(() => {\n registerNode(id, parentId, hasChildren, label, Icon)\n return () => unregisterNode(id)\n }, [id, parentId, hasChildren, label, Icon, registerNode, unregisterNode])\n\n // ── Focus scroll into view ──\n const itemRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => itemRef.current!)\n\n React.useEffect(() => {\n if (isFocused && itemRef.current) {\n itemRef.current.scrollIntoView({ block: 'nearest' })\n }\n }, [isFocused])\n\n // ── Handlers ──\n const handleRowClick = React.useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return\n e.stopPropagation()\n setFocusedId(id)\n select(id)\n if (expandOnSelect && hasChildren) {\n toggleExpand(id)\n }\n },\n [id, disabled, select, setFocusedId, expandOnSelect, hasChildren, toggleExpand]\n )\n\n const handleChevronClick = React.useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (disabled) return\n toggleExpand(id)\n },\n [id, disabled, toggleExpand]\n )\n\n // ── Chevron(永遠存在:expandable = 旋轉箭頭;leaf = placeholder 佔位) ──\n // 消費 `<ItemPrefix>` SSOT — 永遠 h-[1lh] 對齊 label 第一行中線(item-anatomy 對應)。\n // forced width 透過 style 鎖 chevron 槽寬,讓 sibling label 起點水平對齊(無 chevron leaf 佔位同寬)。\n const chevronSlot = (\n <ItemPrefix style={{ width: iconPx }}>\n {hasChildren ? (\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={handleChevronClick}\n className={cn(\n 'flex items-center justify-center rounded-md',\n 'text-fg-muted hover:text-foreground hover:bg-neutral-hover',\n 'transition-all duration-150',\n isExpanded && 'rotate-90',\n disabled && 'text-fg-disabled pointer-events-none',\n )}\n style={{ width: iconPx, height: iconPx }}\n aria-hidden\n >\n <ChevronRight size={iconPx} />\n </button>\n ) : (\n // Leaf placeholder\n <span style={{ width: iconPx }} aria-hidden />\n )}\n </ItemPrefix>\n )\n\n return (\n <ParentIdContext.Provider value={id}>\n <div\n ref={(node) => {\n (itemRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n // DOM id 供容器 aria-activedescendant 指向(virtual focus);與 data-tree-id 並存\n // (data-tree-id 給內部 querySelector / drag,id 給 AT)。\n id={`${activeDescendantPrefix}treeitem-${id}`}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={selectionMode !== 'none' ? isSelected : undefined}\n aria-level={depth + 1}\n aria-disabled={disabled || undefined}\n // 2026-07-05 D4 修:aria-roledescription 移到 treeitem(有 role 的元素才合法)—\n // 供 AT 提示此 node 可拖曳;值消費 dnd-kit attributes SSOT(預設 'draggable')。\n aria-roledescription={draggable && !disabled ? dragAttrs['aria-roledescription'] : undefined}\n data-tree-id={id}\n data-tree-parent-id={parentId ?? ''}\n data-tree-has-children={hasChildren}\n tabIndex={-1}\n className={cn('w-full min-w-0 relative', isDragging && dragSourceClass)}\n >\n {/* Drop indicator — before:水平 2px primary line(指 SSOT drag-visual.ts);\n indent 跟隨 depth(left 由 inline style override class 的 left-0)*/}\n {isDropTarget && dropTarget?.position === 'before' && (\n <div\n className={dropIndicatorRow.before}\n style={{ left: `calc(var(--tree-px) + ${indentPx}px)` }}\n />\n )}\n\n {/* Row: draggable + droppable 都在這一行(合併 ref),確保碰撞偵測只看行高 */}\n <div\n ref={(node) => {\n // 合併 drag + drop ref 到同一個 element\n if (draggable) setDragRef(node)\n setDropRef(node)\n }}\n data-tree-row={id}\n className={cn(\n 'group/tree-item',\n treeItemVariants({ size }),\n // 2026-05-26 SSOT lock(user explicit「multi 已有 checkbox 強信號,text 不該再變色」):\n // ── Single mode ──\n // - default text 預設 fg-secondary muted(hierarchy navigation 慣例,跟 Sidebar 一致)\n // - selected → text-foreground emphasis + bg-neutral-selected(無 checkbox,需 text+bg 雙信號)\n // ── Multi mode ──\n // - default text 維持 fg-secondary muted(跟 single 對齊 hierarchy)\n // - selected → 視覺信號只在 checkbox(auto-render below),text 不變、bg 不變\n // - 對齊 SelectMenu multi pattern(menu-item.tsx:194-195 selected → bg only;multi → checkbox only)\n // multi-selected 也維持 fg-secondary(上方註解「text 不變」;原 !isSelected 條件讓 multi-selected 掉到繼承色)\n !disabled && (!isSelected || selectionMode === 'multiple') && 'text-fg-secondary',\n !disabled && isSelected && selectionMode === 'single' && 'text-foreground',\n isDropTarget && dropTarget?.position === 'inside' && dropIndicatorInside,\n !disabled && 'hover:bg-neutral-hover hover:text-foreground',\n !disabled && isSelected && selectionMode === 'single' && 'bg-neutral-selected',\n showRing && 'ring-2 ring-ring ring-inset',\n disabled && 'pointer-events-none text-fg-disabled cursor-default',\n className,\n )}\n style={{\n paddingLeft: indentPx > 0\n ? `calc(var(--tree-px) + ${indentPx}px)`\n : 'var(--tree-px)',\n paddingRight: 'var(--tree-px)',\n }}\n onClick={handleRowClick}\n // 2026-07-05 D4 修:只 spread listeners,不 spread dnd-kit attributes —\n // useDraggable 預設 attributes 注入 role=\"button\" + tabIndex=0 + aria-pressed +\n // aria-describedby(鍵盤拖曳指示):role=button 污染 treeitem 語意、tabIndex=0\n // 讓每 row 變 DOM tab stop 破壞單一 tab stop 虛擬焦點模型(DOM focus 在 row 上按\n // Enter 會 bubble 到容器 handleKeyDown 但 handler 操作 state focusedId → 錯位);\n // sensors 僅 PointerSensor(無 KeyboardSensor),這些 attrs 換不到鍵盤拖曳能力;\n // 鍵盤重排(2026-07-14 v1)走容器 handleKeyDown 的 Cmd/Ctrl+Shift+Arrow 分支,非 dnd-kit sensor。\n // aria-roledescription 保留在上方 treeitem 元素(有 role 才合法)。\n {...(draggable ? dragListeners : {})}\n {...props}\n >\n {chevronSlot}\n\n {/* Checkbox 在 icon 前——消費 `<ItemPrefix>` 對齊第一行\n * 2026-05-26 SSOT lock(user explicit「多選的方式應該也是要跟 menu 一樣是出現 checkbox」):\n * - selectionMode='multiple' + 無 consumer checkbox prop → auto-render `<Checkbox>` reflect selectedIds\n * (對齊 SelectMenu multi pattern;consumer 不用手寫 checkbox)\n * - selectionMode='multiple' + consumer 傳 checkbox → 用 consumer 的(parent-child cascade 等 advanced)\n * - selectionMode='single' / 'none' → 不 render checkbox(text-foreground + bg 雙信號表 selected)\n * 對齊 cite:menu-item.tsx:194-195(MenuItem selected bg)+ select-menu.tsx:352-354(SelectMenu multi=checkbox) */}\n {(checkbox || selectionMode === 'multiple') && (\n <ItemPrefix className=\"pointer-events-none\">\n {/* 2026-07-05 D4 修:auto-render Checkbox 補 tabIndex={-1} — Radix Checkbox root\n * 是原生 button(預設可聚焦),aria-hidden + 可聚焦 = axe aria-hidden-focus,且\n * 破壞 tree 單一 tab stop 虛擬焦點模型(tree-view.spec.md「Focus」段);\n * ItemPrefix pointer-events-none 只擋滑鼠不擋鍵盤。選取語意由 treeitem\n * aria-selected 承載,checkbox 純視覺反映。 */}\n {checkbox || <Checkbox checked={isSelected} disabled={disabled} aria-hidden=\"true\" tabIndex={-1} />}\n </ItemPrefix>\n )}\n\n {/* indicator 取代 icon 的位置;h-[1lh] 對齊第一行\n indicator 是 escape hatch(stepper status dot 等客製內容),消費 `<ItemPrefix>` 鎖 chevron 槽寬;\n Icon 走 canonical `<ItemIcon>` helper——自動標 data-prefix-type=\"icon\",\n 讓 SidebarProvider 的全域 :has() prefix-mix 偵測能命中。 */}\n {indicator ? (\n <ItemPrefix style={{ width: iconPx }}>\n {indicator}\n </ItemPrefix>\n ) : Icon ? (\n <ItemIcon icon={Icon} className={disabled ? 'text-fg-disabled' : undefined} />\n ) : null}\n\n <span className={cn('flex-1 min-w-0 truncate', disabled && 'text-fg-disabled')}>\n {label}\n </span>\n\n {/* Suffix inline actions——宣告式 API,用 `<ItemInlineAction>` 渲染。\n 消費 `<ItemSuffix hoverReveal hoverGroup=\"tree-item\">` SSOT(2026-05-05 v8 group selector 參數化後)。\n actionsReveal=\"hover\"(預設):row hover 或 keyboard focus-visible 才顯示;\n actionsReveal=false:常駐顯示。跟 SidebarMenuButton 共用同一條規則,行為一致。\n inlineActionsSlot escape hatch 優先(consumer 自控 JSX,reveal 一樣套外層 group)。 */}\n {/* 2026-06-12 R2(同 sidebar.tsx 修):宿主 disabled 時 render 層擋 inline actions —\n inline-action.spec.md「宿主 disabled | 不渲染」;row pointer-events 蓋不住\n actionsReveal=false 常駐顯示的視覺暗示,必須 render 層 guard。 */}\n {disabled ? null : inlineActionsSlot ? (\n <ItemSuffix hoverReveal={actionsReveal === 'hover'} hoverGroup=\"tree-item\">\n {inlineActionsSlot}\n </ItemSuffix>\n ) : inlineActions && inlineActions.length > 0 ? (\n <ItemSuffix hoverReveal={actionsReveal === 'hover'} hoverGroup=\"tree-item\">\n {inlineActions.map((action, i) => (\n <ItemInlineAction key={action.label + i} action={action} />\n ))}\n </ItemSuffix>\n ) : null}\n </div>\n\n {/* Drop indicator — after:同 before mirror 到 bottom edge(SSOT drag-visual.ts)*/}\n {isDropTarget && dropTarget?.position === 'after' && (\n <div\n className={dropIndicatorRow.after}\n style={{ left: `calc(var(--tree-px) + ${indentPx}px)` }}\n />\n )}\n\n {/* Children: Collapsible 展開/收合 */}\n {hasChildren && (\n <CollapsiblePrimitive.Root open={isExpanded}>\n <CollapsiblePrimitive.Content\n className=\"overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down\"\n >\n <DepthContext.Provider value={depth + 1}>\n <div role=\"group\" className=\"flex flex-col w-full\">\n {children}\n </div>\n </DepthContext.Provider>\n </CollapsiblePrimitive.Content>\n </CollapsiblePrimitive.Root>\n )}\n </div>\n </ParentIdContext.Provider>\n )\n }\n)\nTreeItem.displayName = 'TreeItem'\n\n// Parent ID context for keyboard navigation (← to parent)\nconst ParentIdContext = React.createContext<string | null>(null)\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Exports\n// ═══════════════════════════════════════════════════════════════════════════\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const treeViewMeta = {\n component: 'TreeView',\n family: 1, // Family 1(Menu item layout)消費者 — 對齊 tree-view.spec.md frontmatter family: 1\n variants: {\n\n },\n sizes: {\n // 對齊 tree-view.spec.md frontmatter(compile-stories --check 驗 key 一致)\n sm: { typography: 'body', indent: 24 },\n md: { typography: 'body', indent: 24 }, // default\n lg: { typography: 'body-lg', indent: 28 },\n },\n // 'selected' = single-selection 持續選中(bg-neutral-selected + aria-selected);'active' 移除 —\n // 全檔無 Tailwind 按壓 utility,無按壓專屬視覺態(2026-07-07 詞彙統一對抗稽核補修)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-neutral-hover', 'bg-neutral-selected', 'bg-surface'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-fg-secondary', 'text-foreground'],\n ring: ['ring-ring'],\n },\n defaultSize: 'md',\n} as const\n\nexport { TreeView, TreeItem, treeItemVariants }\n"],"names":["treeEl"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, Breadcr
|
|
|
13
13
|
export type { BreadcrumbEllipsisProps, BreadcrumbItemSpec, BreadcrumbListProps, BreadcrumbSize, } from './components/Breadcrumb/index';
|
|
14
14
|
export { BULK_ACTION_BAR_DEFAULT_LABELS, BulkActionBar, } from './components/BulkActionBar/index';
|
|
15
15
|
export type { BulkActionBarLabels, BulkActionBarProps, } from './components/BulkActionBar/index';
|
|
16
|
-
export { Button, ButtonDivider, ButtonGroup,
|
|
16
|
+
export { Button, ButtonDivider, ButtonGroup, buttonVariants, } from './components/Button/index';
|
|
17
17
|
export type { ButtonProps, } from './components/Button/index';
|
|
18
18
|
export { Calendar, } from './components/Calendar/index';
|
|
19
19
|
export type { CalendarEvent, CalendarProps, CalendarView, } from './components/Calendar/index';
|
|
@@ -36,14 +36,14 @@ export type { Conjunction, DataTableColumnVisibilityPanelProps, DataTableFilterP
|
|
|
36
36
|
export { DatePicker, DatePickerRange, formatDate, } from './components/DatePicker/index';
|
|
37
37
|
export type { DateFormatOptions, DatePickerProps, DatePickerRangeProps, } from './components/DatePicker/index';
|
|
38
38
|
export { DescriptionItem, DescriptionList, } from './components/DescriptionList/index';
|
|
39
|
-
export type {
|
|
39
|
+
export type { DescriptionItemProps, DescriptionListOrientation, DescriptionListProps, } from './components/DescriptionList/index';
|
|
40
40
|
export { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, } from './components/Dialog/index';
|
|
41
41
|
export type { DialogHeaderProps, } from './components/Dialog/index';
|
|
42
|
-
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger,
|
|
42
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from './components/DropdownMenu/index';
|
|
43
43
|
export type { DropdownMenuItemProps, SizeKey, } from './components/DropdownMenu/index';
|
|
44
44
|
export { Empty, } from './components/Empty/index';
|
|
45
45
|
export type { EmptyProps, } from './components/Empty/index';
|
|
46
|
-
export { Field, FieldDescription, FieldError, FieldGroup, FieldLabel,
|
|
46
|
+
export { Field, FieldDescription, FieldError, FieldGroup, FieldLabel, useFormValidation, } from './components/Field/index';
|
|
47
47
|
export type { FieldGroupProps, FieldLabelProps, FieldMode, FieldProps, FieldVariant, FieldWidth, FormFieldInputProps, UseFormValidationOptions, UseFormValidationReturn, } from './components/Field/index';
|
|
48
48
|
export { FieldControlGroup, } from './components/FieldControlGroup/index';
|
|
49
49
|
export type { FieldControlGroupProps, } from './components/FieldControlGroup/index';
|
|
@@ -80,7 +80,7 @@ export type { SegmentedControlItemProps, SegmentedControlProps, SegmentedControl
|
|
|
80
80
|
export { Select, } from './components/Select/index';
|
|
81
81
|
export type { SelectGroupConfig, SelectOption, SelectProps, } from './components/Select/index';
|
|
82
82
|
export { Separator, } from './components/Separator/index';
|
|
83
|
-
export { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger,
|
|
83
|
+
export { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, sheetVariants, } from './components/Sheet/index';
|
|
84
84
|
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarProvider, SidebarSeparator, SidebarTrigger, useSidebar, } from './components/Sidebar/index';
|
|
85
85
|
export { Skeleton, } from './components/Skeleton/index';
|
|
86
86
|
export { Slider, sliderRootVariants, } from './components/Slider/index';
|
|
@@ -102,8 +102,8 @@ export type { ToastOptions, ToastVariant, ToasterProps, } from './components/Toa
|
|
|
102
102
|
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from './components/Tooltip/index';
|
|
103
103
|
export { TreeItem, TreeView, treeItemVariants, } from './components/TreeView/index';
|
|
104
104
|
export type { TreeDragEndEvent, TreeDropPosition, TreeItemProps, TreeReorderAnnouncements, TreeViewProps, } from './components/TreeView/index';
|
|
105
|
-
export { AVATAR_SIZE, ICON_SIZE, INLINE_ACTION_HOVER_BG_SIZE, ItemAvatar, ItemContent, ItemIcon,
|
|
106
|
-
export type { InlineActionConfig, ItemAvatarProps, ItemContentProps, ItemIconProps,
|
|
105
|
+
export { AVATAR_SIZE, ICON_SIZE, INLINE_ACTION_HOVER_BG_SIZE, ItemAvatar, ItemContent, ItemIcon, ItemLabel, ItemPrefix, ItemSuffix, ROW_PADDING_BY_SIZE, getUniformPrefixSlotStyle, itemPrefixAlignVariants, useRowSize, } from './patterns/element-anatomy/index';
|
|
106
|
+
export type { InlineActionConfig, ItemAvatarProps, ItemContentProps, ItemIconProps, ItemSuffixHoverGroup, ItemSuffixProps, RowSize, } from './patterns/element-anatomy/index';
|
|
107
107
|
export { ChromeHeader, HEADER_TABS_SLOT_WRAPPER_CLASS, } from './patterns/header-canonical/index';
|
|
108
108
|
export type { ChromeHeaderProps, } from './patterns/header-canonical/index';
|
|
109
109
|
export { ResizeHandle, } from './patterns/resize-handle/index';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACL,KAAK,EACL,aAAa,GACd,MAAM,0BAA0B,CAAA;AACjC,YAAY,EACV,UAAU,GACX,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,WAAW,GACZ,MAAM,gCAAgC,CAAA;AACvC,YAAY,EACV,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,MAAM,GACP,MAAM,2BAA2B,CAAA;AAClC,YAAY,EACV,UAAU,EACV,WAAW,GACZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,KAAK,EACL,aAAa,GACd,MAAM,0BAA0B,CAAA;AACjC,YAAY,EACV,eAAe,EACf,aAAa,EACb,UAAU,GACX,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,GACf,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,8BAA8B,EAC9B,aAAa,GACd,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|