@qijenchen/design-system 0.1.0-beta.10
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/README.md +163 -0
- package/dist/components/Accordion/accordion.d.ts +37 -0
- package/dist/components/Accordion/accordion.d.ts.map +1 -0
- package/dist/components/Accordion/accordion.js +78 -0
- package/dist/components/Accordion/accordion.js.map +1 -0
- package/dist/components/Alert/alert.d.ts +47 -0
- package/dist/components/Alert/alert.d.ts.map +1 -0
- package/dist/components/Alert/alert.js +132 -0
- package/dist/components/Alert/alert.js.map +1 -0
- package/dist/components/AppShell/_demo-helpers.d.ts +49 -0
- package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -0
- package/dist/components/AppShell/app-shell.d.ts +76 -0
- package/dist/components/AppShell/app-shell.d.ts.map +1 -0
- package/dist/components/AppShell/app-shell.js +214 -0
- package/dist/components/AppShell/app-shell.js.map +1 -0
- package/dist/components/AspectRatio/aspect-ratio.d.ts +40 -0
- package/dist/components/AspectRatio/aspect-ratio.d.ts.map +1 -0
- package/dist/components/AspectRatio/aspect-ratio.js +23 -0
- package/dist/components/AspectRatio/aspect-ratio.js.map +1 -0
- package/dist/components/Avatar/avatar.d.ts +85 -0
- package/dist/components/Avatar/avatar.d.ts.map +1 -0
- package/dist/components/Avatar/avatar.js +195 -0
- package/dist/components/Avatar/avatar.js.map +1 -0
- package/dist/components/Badge/badge.d.ts +43 -0
- package/dist/components/Badge/badge.d.ts.map +1 -0
- package/dist/components/Badge/badge.js +69 -0
- package/dist/components/Badge/badge.js.map +1 -0
- package/dist/components/Breadcrumb/breadcrumb.d.ts +163 -0
- package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb/breadcrumb.js +300 -0
- package/dist/components/Breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts +46 -0
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -0
- package/dist/components/BulkActionBar/bulk-action-bar.js +78 -0
- package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -0
- package/dist/components/Button/button-group.d.ts +49 -0
- package/dist/components/Button/button-group.d.ts.map +1 -0
- package/dist/components/Button/button-group.js +46 -0
- package/dist/components/Button/button-group.js.map +1 -0
- package/dist/components/Button/button.d.ts +203 -0
- package/dist/components/Button/button.d.ts.map +1 -0
- package/dist/components/Button/button.js +309 -0
- package/dist/components/Button/button.js.map +1 -0
- package/dist/components/Calendar/calendar.d.ts +81 -0
- package/dist/components/Calendar/calendar.d.ts.map +1 -0
- package/dist/components/Calendar/calendar.js +282 -0
- package/dist/components/Calendar/calendar.js.map +1 -0
- package/dist/components/Carousel/carousel.d.ts +61 -0
- package/dist/components/Carousel/carousel.d.ts.map +1 -0
- package/dist/components/Carousel/carousel.js +276 -0
- package/dist/components/Carousel/carousel.js.map +1 -0
- package/dist/components/Chart/chart.d.ts +94 -0
- package/dist/components/Chart/chart.d.ts.map +1 -0
- package/dist/components/Chart/chart.js +233 -0
- package/dist/components/Chart/chart.js.map +1 -0
- package/dist/components/Checkbox/checkbox-group.d.ts +58 -0
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -0
- package/dist/components/Checkbox/checkbox-group.js +28 -0
- package/dist/components/Checkbox/checkbox-group.js.map +1 -0
- package/dist/components/Checkbox/checkbox.d.ts +73 -0
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/checkbox.js +125 -0
- package/dist/components/Checkbox/checkbox.js.map +1 -0
- package/dist/components/Chip/chip.d.ts +54 -0
- package/dist/components/Chip/chip.d.ts.map +1 -0
- package/dist/components/Chip/chip.js +224 -0
- package/dist/components/Chip/chip.js.map +1 -0
- package/dist/components/CircularProgress/circular-progress.d.ts +40 -0
- package/dist/components/CircularProgress/circular-progress.d.ts.map +1 -0
- package/dist/components/CircularProgress/circular-progress.js +118 -0
- package/dist/components/CircularProgress/circular-progress.js.map +1 -0
- package/dist/components/Coachmark/coachmark.d.ts +100 -0
- package/dist/components/Coachmark/coachmark.d.ts.map +1 -0
- package/dist/components/Coachmark/coachmark.js +107 -0
- package/dist/components/Coachmark/coachmark.js.map +1 -0
- package/dist/components/Combobox/combobox.d.ts +150 -0
- package/dist/components/Combobox/combobox.d.ts.map +1 -0
- package/dist/components/Combobox/combobox.js +595 -0
- package/dist/components/Combobox/combobox.js.map +1 -0
- package/dist/components/Command/command.d.ts +106 -0
- package/dist/components/Command/command.d.ts.map +1 -0
- package/dist/components/Command/command.js +123 -0
- package/dist/components/Command/command.js.map +1 -0
- package/dist/components/DataTable/active-editor-controller.d.ts +66 -0
- package/dist/components/DataTable/active-editor-controller.d.ts.map +1 -0
- package/dist/components/DataTable/cell-registry.d.ts +37 -0
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -0
- package/dist/components/DataTable/cell-registry.js +377 -0
- package/dist/components/DataTable/cell-registry.js.map +1 -0
- package/dist/components/DataTable/column-types.d.ts +145 -0
- package/dist/components/DataTable/column-types.d.ts.map +1 -0
- package/dist/components/DataTable/column-types.js +17 -0
- package/dist/components/DataTable/column-types.js.map +1 -0
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +49 -0
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts +30 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-interaction-layer.d.ts +78 -0
- package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-interaction-layer.js +220 -0
- package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -0
- package/dist/components/DataTable/data-table-sort-manager.d.ts +19 -0
- package/dist/components/DataTable/data-table-sort-manager.d.ts.map +1 -0
- package/dist/components/DataTable/data-table.d.ts +181 -0
- package/dist/components/DataTable/data-table.d.ts.map +1 -0
- package/dist/components/DataTable/data-table.js +1851 -0
- package/dist/components/DataTable/data-table.js.map +1 -0
- package/dist/components/DataTable/filter-operators.d.ts +116 -0
- package/dist/components/DataTable/filter-operators.d.ts.map +1 -0
- package/dist/components/DataTable/filter-tree.d.ts +66 -0
- package/dist/components/DataTable/filter-tree.d.ts.map +1 -0
- package/dist/components/DataTable/lib/column-meta.d.ts +49 -0
- package/dist/components/DataTable/lib/column-meta.d.ts.map +1 -0
- package/dist/components/DateGrid/date-grid.d.ts +61 -0
- package/dist/components/DateGrid/date-grid.d.ts.map +1 -0
- package/dist/components/DateGrid/date-grid.js +168 -0
- package/dist/components/DateGrid/date-grid.js.map +1 -0
- package/dist/components/DatePicker/date-picker.d.ts +119 -0
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -0
- package/dist/components/DatePicker/date-picker.js +743 -0
- package/dist/components/DatePicker/date-picker.js.map +1 -0
- package/dist/components/DescriptionList/description-list.d.ts +60 -0
- package/dist/components/DescriptionList/description-list.d.ts.map +1 -0
- package/dist/components/DescriptionList/description-list.js +77 -0
- package/dist/components/DescriptionList/description-list.js.map +1 -0
- package/dist/components/Dialog/dialog.d.ts +54 -0
- package/dist/components/Dialog/dialog.d.ts.map +1 -0
- package/dist/components/Dialog/dialog.js +151 -0
- package/dist/components/Dialog/dialog.js.map +1 -0
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +111 -0
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -0
- package/dist/components/DropdownMenu/dropdown-menu.js +288 -0
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -0
- package/dist/components/Empty/empty.d.ts +40 -0
- package/dist/components/Empty/empty.d.ts.map +1 -0
- package/dist/components/Empty/empty.js +66 -0
- package/dist/components/Empty/empty.js.map +1 -0
- package/dist/components/Field/field-context.d.ts +77 -0
- package/dist/components/Field/field-context.d.ts.map +1 -0
- package/dist/components/Field/field-context.js +37 -0
- package/dist/components/Field/field-context.js.map +1 -0
- package/dist/components/Field/field-types.d.ts +5 -0
- package/dist/components/Field/field-types.d.ts.map +1 -0
- package/dist/components/Field/field-types.js +13 -0
- package/dist/components/Field/field-types.js.map +1 -0
- package/dist/components/Field/field-wrapper.d.ts +17 -0
- package/dist/components/Field/field-wrapper.d.ts.map +1 -0
- package/dist/components/Field/field-wrapper.js +252 -0
- package/dist/components/Field/field-wrapper.js.map +1 -0
- package/dist/components/Field/field.d.ts +127 -0
- package/dist/components/Field/field.d.ts.map +1 -0
- package/dist/components/Field/field.js +295 -0
- package/dist/components/Field/field.js.map +1 -0
- package/dist/components/FieldControlGroup/field-control-group.d.ts +74 -0
- package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -0
- package/dist/components/FieldControlGroup/field-control-group.js +62 -0
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -0
- package/dist/components/FileItem/file-item.d.ts +44 -0
- package/dist/components/FileItem/file-item.d.ts.map +1 -0
- package/dist/components/FileItem/file-item.js +202 -0
- package/dist/components/FileItem/file-item.js.map +1 -0
- package/dist/components/FileUpload/file-upload.d.ts +97 -0
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -0
- package/dist/components/FileUpload/file-upload.js +231 -0
- package/dist/components/FileUpload/file-upload.js.map +1 -0
- package/dist/components/FileViewer/file-viewer-types.d.ts +73 -0
- package/dist/components/FileViewer/file-viewer-types.d.ts.map +1 -0
- package/dist/components/FileViewer/file-viewer.d.ts +82 -0
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -0
- package/dist/components/FileViewer/file-viewer.js +752 -0
- package/dist/components/FileViewer/file-viewer.js.map +1 -0
- package/dist/components/FileViewer/image-renderer.d.ts +9 -0
- package/dist/components/FileViewer/image-renderer.d.ts.map +1 -0
- package/dist/components/FileViewer/image-renderer.js +165 -0
- package/dist/components/FileViewer/image-renderer.js.map +1 -0
- package/dist/components/HoverCard/hover-card.d.ts +30 -0
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -0
- package/dist/components/HoverCard/hover-card.js +61 -0
- package/dist/components/HoverCard/hover-card.js.map +1 -0
- package/dist/components/Input/input.d.ts +72 -0
- package/dist/components/Input/input.d.ts.map +1 -0
- package/dist/components/Input/input.js +148 -0
- package/dist/components/Input/input.js.map +1 -0
- package/dist/components/LinkInput/link-input.d.ts +46 -0
- package/dist/components/LinkInput/link-input.d.ts.map +1 -0
- package/dist/components/LinkInput/link-input.js +215 -0
- package/dist/components/LinkInput/link-input.js.map +1 -0
- package/dist/components/Menu/menu-item.d.ts +83 -0
- package/dist/components/Menu/menu-item.d.ts.map +1 -0
- package/dist/components/Menu/menu-item.js +209 -0
- package/dist/components/Menu/menu-item.js.map +1 -0
- package/dist/components/NameCard/name-card.d.ts +85 -0
- package/dist/components/NameCard/name-card.d.ts.map +1 -0
- package/dist/components/NameCard/name-card.js +153 -0
- package/dist/components/NameCard/name-card.js.map +1 -0
- package/dist/components/Notice/notice.d.ts +69 -0
- package/dist/components/Notice/notice.d.ts.map +1 -0
- package/dist/components/Notice/notice.js +121 -0
- package/dist/components/Notice/notice.js.map +1 -0
- package/dist/components/NumberInput/number-input.d.ts +57 -0
- package/dist/components/NumberInput/number-input.d.ts.map +1 -0
- package/dist/components/NumberInput/number-input.js +131 -0
- package/dist/components/NumberInput/number-input.js.map +1 -0
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts +23 -0
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -0
- package/dist/components/OverflowIndicator/overflow-indicator.js +111 -0
- package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -0
- package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +57 -0
- package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts.map +1 -0
- package/dist/components/PeoplePicker/avatar-stack-overflow.js +35 -0
- package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -0
- package/dist/components/PeoplePicker/people-picker-helpers.d.ts +7 -0
- package/dist/components/PeoplePicker/people-picker-helpers.d.ts.map +1 -0
- package/dist/components/PeoplePicker/people-picker-helpers.js +25 -0
- package/dist/components/PeoplePicker/people-picker-helpers.js.map +1 -0
- package/dist/components/PeoplePicker/people-picker.d.ts +77 -0
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -0
- package/dist/components/PeoplePicker/people-picker.js +263 -0
- package/dist/components/PeoplePicker/people-picker.js.map +1 -0
- package/dist/components/PeoplePicker/person-display.d.ts +66 -0
- package/dist/components/PeoplePicker/person-display.d.ts.map +1 -0
- package/dist/components/PeoplePicker/person-display.js +203 -0
- package/dist/components/PeoplePicker/person-display.js.map +1 -0
- package/dist/components/Popover/popover.d.ts +50 -0
- package/dist/components/Popover/popover.d.ts.map +1 -0
- package/dist/components/Popover/popover.js +113 -0
- package/dist/components/Popover/popover.js.map +1 -0
- package/dist/components/ProgressBar/progress-bar.d.ts +37 -0
- package/dist/components/ProgressBar/progress-bar.d.ts.map +1 -0
- package/dist/components/ProgressBar/progress-bar.js +86 -0
- package/dist/components/ProgressBar/progress-bar.js.map +1 -0
- package/dist/components/RadioGroup/radio-group.d.ts +78 -0
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -0
- package/dist/components/RadioGroup/radio-group.js +153 -0
- package/dist/components/RadioGroup/radio-group.js.map +1 -0
- package/dist/components/Rating/rating.d.ts +46 -0
- package/dist/components/Rating/rating.d.ts.map +1 -0
- package/dist/components/Rating/rating.js +179 -0
- package/dist/components/Rating/rating.js.map +1 -0
- package/dist/components/ScrollArea/scroll-area.d.ts +45 -0
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -0
- package/dist/components/ScrollArea/scroll-area.js +65 -0
- package/dist/components/ScrollArea/scroll-area.js.map +1 -0
- package/dist/components/SegmentedControl/segmented-control.d.ts +102 -0
- package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -0
- package/dist/components/SegmentedControl/segmented-control.js +171 -0
- package/dist/components/SegmentedControl/segmented-control.js.map +1 -0
- package/dist/components/Select/select.d.ts +102 -0
- package/dist/components/Select/select.d.ts.map +1 -0
- package/dist/components/Select/select.js +435 -0
- package/dist/components/Select/select.js.map +1 -0
- package/dist/components/SelectMenu/select-menu.d.ts +103 -0
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -0
- package/dist/components/SelectMenu/select-menu.js +239 -0
- package/dist/components/SelectMenu/select-menu.js.map +1 -0
- package/dist/components/SelectionControl/selection-item.d.ts +69 -0
- package/dist/components/SelectionControl/selection-item.d.ts.map +1 -0
- package/dist/components/SelectionControl/selection-item.js +142 -0
- package/dist/components/SelectionControl/selection-item.js.map +1 -0
- package/dist/components/Separator/separator.d.ts +17 -0
- package/dist/components/Separator/separator.d.ts.map +1 -0
- package/dist/components/Separator/separator.js +39 -0
- package/dist/components/Separator/separator.js.map +1 -0
- package/dist/components/Sheet/sheet.d.ts +56 -0
- package/dist/components/Sheet/sheet.d.ts.map +1 -0
- package/dist/components/Sheet/sheet.js +145 -0
- package/dist/components/Sheet/sheet.js.map +1 -0
- package/dist/components/Sidebar/sidebar.d.ts +195 -0
- package/dist/components/Sidebar/sidebar.d.ts.map +1 -0
- package/dist/components/Sidebar/sidebar.js +826 -0
- package/dist/components/Sidebar/sidebar.js.map +1 -0
- package/dist/components/Skeleton/skeleton.d.ts +16 -0
- package/dist/components/Skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton/skeleton.js +30 -0
- package/dist/components/Skeleton/skeleton.js.map +1 -0
- package/dist/components/Slider/slider.d.ts +48 -0
- package/dist/components/Slider/slider.d.ts.map +1 -0
- package/dist/components/Slider/slider.js +108 -0
- package/dist/components/Slider/slider.js.map +1 -0
- package/dist/components/Steps/steps.d.ts +71 -0
- package/dist/components/Steps/steps.d.ts.map +1 -0
- package/dist/components/Steps/steps.js +583 -0
- package/dist/components/Steps/steps.js.map +1 -0
- package/dist/components/Switch/switch.d.ts +112 -0
- package/dist/components/Switch/switch.d.ts.map +1 -0
- package/dist/components/Switch/switch.js +179 -0
- package/dist/components/Switch/switch.js.map +1 -0
- package/dist/components/Tabs/tabs.d.ts +104 -0
- package/dist/components/Tabs/tabs.d.ts.map +1 -0
- package/dist/components/Tabs/tabs.js +316 -0
- package/dist/components/Tabs/tabs.js.map +1 -0
- package/dist/components/Tag/tag.d.ts +86 -0
- package/dist/components/Tag/tag.d.ts.map +1 -0
- package/dist/components/Tag/tag.js +172 -0
- package/dist/components/Tag/tag.js.map +1 -0
- package/dist/components/Textarea/textarea.d.ts +74 -0
- package/dist/components/Textarea/textarea.d.ts.map +1 -0
- package/dist/components/Textarea/textarea.js +224 -0
- package/dist/components/Textarea/textarea.js.map +1 -0
- package/dist/components/TimePicker/time-columns.d.ts +46 -0
- package/dist/components/TimePicker/time-columns.d.ts.map +1 -0
- package/dist/components/TimePicker/time-columns.js +173 -0
- package/dist/components/TimePicker/time-columns.js.map +1 -0
- package/dist/components/TimePicker/time-picker.d.ts +94 -0
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -0
- package/dist/components/TimePicker/time-picker.js +253 -0
- package/dist/components/TimePicker/time-picker.js.map +1 -0
- package/dist/components/Toast/toast.d.ts +61 -0
- package/dist/components/Toast/toast.d.ts.map +1 -0
- package/dist/components/Toast/toast.js +76 -0
- package/dist/components/Toast/toast.js.map +1 -0
- package/dist/components/Tooltip/tooltip.d.ts +20 -0
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip/tooltip.js +53 -0
- package/dist/components/Tooltip/tooltip.js.map +1 -0
- package/dist/components/TreeView/tree-view.d.ts +166 -0
- package/dist/components/TreeView/tree-view.d.ts.map +1 -0
- package/dist/components/TreeView/tree-view.js +617 -0
- package/dist/components/TreeView/tree-view.js.map +1 -0
- package/dist/hooks/use-controllable.d.ts +16 -0
- package/dist/hooks/use-controllable.d.ts.map +1 -0
- package/dist/hooks/use-controllable.js +26 -0
- package/dist/hooks/use-controllable.js.map +1 -0
- package/dist/hooks/use-is-narrow-viewport.d.ts +2 -0
- package/dist/hooks/use-is-narrow-viewport.d.ts.map +1 -0
- package/dist/hooks/use-is-narrow-viewport.js +19 -0
- package/dist/hooks/use-is-narrow-viewport.js.map +1 -0
- package/dist/hooks/use-is-touch-device.d.ts +8 -0
- package/dist/hooks/use-is-touch-device.d.ts.map +1 -0
- package/dist/hooks/use-is-touch-device.js +16 -0
- package/dist/hooks/use-is-touch-device.js.map +1 -0
- package/dist/hooks/use-overflow-items.d.ts +124 -0
- package/dist/hooks/use-overflow-items.d.ts.map +1 -0
- package/dist/hooks/use-overflow-items.js +97 -0
- package/dist/hooks/use-overflow-items.js.map +1 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/drag-visual.d.ts +158 -0
- package/dist/lib/drag-visual.d.ts.map +1 -0
- package/dist/lib/drag-visual.js +96 -0
- package/dist/lib/drag-visual.js.map +1 -0
- package/dist/lib/i18n/i18n-context.d.ts +105 -0
- package/dist/lib/i18n/i18n-context.d.ts.map +1 -0
- package/dist/lib/multi-select-ordering.d.ts +54 -0
- package/dist/lib/multi-select-ordering.d.ts.map +1 -0
- package/dist/lib/multi-select-ordering.js +13 -0
- package/dist/lib/multi-select-ordering.js.map +1 -0
- package/dist/lib/utils.d.ts +12 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +79 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +370 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -0
- package/dist/patterns/element-anatomy/item-anatomy.js +272 -0
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -0
- package/dist/patterns/header-canonical/chrome-header.d.ts +80 -0
- package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -0
- package/dist/patterns/header-canonical/chrome-header.js +75 -0
- package/dist/patterns/header-canonical/chrome-header.js.map +1 -0
- package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts +101 -0
- package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts.map +1 -0
- package/dist/patterns/horizontal-overflow/horizontal-overflow.js +105 -0
- package/dist/patterns/horizontal-overflow/horizontal-overflow.js.map +1 -0
- package/dist/patterns/overlay-surface/overlay-surface.d.ts +28 -0
- package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -0
- package/dist/patterns/overlay-surface/overlay-surface.js +85 -0
- package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -0
- package/dist/patterns/resize-handle/resize-handle.d.ts +102 -0
- package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -0
- package/dist/patterns/resize-handle/resize-handle.js +74 -0
- package/dist/patterns/resize-handle/resize-handle.js.map +1 -0
- package/dist/react-day-picker.css +457 -0
- package/dist/stories-helpers/anatomy/anatomy-utils.d.ts +40 -0
- package/dist/stories-helpers/anatomy/anatomy-utils.d.ts.map +1 -0
- package/dist/tokens/elevation/overlay-geometry.d.ts +12 -0
- package/dist/tokens/elevation/overlay-geometry.d.ts.map +1 -0
- package/dist/tokens/elevation/overlay-geometry.js +7 -0
- package/dist/tokens/elevation/overlay-geometry.js.map +1 -0
- package/dist/tokens/motion/motion.d.ts +15 -0
- package/dist/tokens/motion/motion.d.ts.map +1 -0
- package/dist/tokens/motion/motion.js +9 -0
- package/dist/tokens/motion/motion.js.map +1 -0
- package/dist/tokens/uiSize/icon-size.d.ts +53 -0
- package/dist/tokens/uiSize/icon-size.d.ts.map +1 -0
- package/package.json +92 -0
- package/src/README.md +32 -0
- package/src/components/Accordion/accordion.tsx +104 -0
- package/src/components/Alert/alert.tsx +188 -0
- package/src/components/AppShell/_demo-helpers.tsx +198 -0
- package/src/components/AppShell/app-shell.tsx +364 -0
- package/src/components/AspectRatio/aspect-ratio.tsx +58 -0
- package/src/components/Avatar/avatar.tsx +368 -0
- package/src/components/Badge/badge.tsx +104 -0
- package/src/components/Breadcrumb/breadcrumb.tsx +619 -0
- package/src/components/BulkActionBar/bulk-action-bar.tsx +156 -0
- package/src/components/Button/button-group.tsx +96 -0
- package/src/components/Button/button.tsx +539 -0
- package/src/components/Calendar/calendar.tsx +411 -0
- package/src/components/Carousel/carousel.tsx +371 -0
- package/src/components/Chart/chart.tsx +376 -0
- package/src/components/Checkbox/checkbox-group.tsx +94 -0
- package/src/components/Checkbox/checkbox.tsx +237 -0
- package/src/components/Chip/chip.tsx +359 -0
- package/src/components/CircularProgress/circular-progress.tsx +204 -0
- package/src/components/Coachmark/coachmark.tsx +255 -0
- package/src/components/Combobox/combobox.tsx +826 -0
- package/src/components/Command/command.tsx +187 -0
- package/src/components/DataTable/active-editor-controller.ts +72 -0
- package/src/components/DataTable/cell-registry.tsx +520 -0
- package/src/components/DataTable/column-types.ts +180 -0
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +261 -0
- package/src/components/DataTable/data-table-filter-panel.tsx +813 -0
- package/src/components/DataTable/data-table-interaction-layer.tsx +483 -0
- package/src/components/DataTable/data-table-sort-manager.tsx +210 -0
- package/src/components/DataTable/data-table.css +165 -0
- package/src/components/DataTable/data-table.tsx +2924 -0
- package/src/components/DataTable/filter-operators.ts +225 -0
- package/src/components/DataTable/filter-tree.ts +313 -0
- package/src/components/DataTable/lib/column-meta.ts +79 -0
- package/src/components/DateGrid/date-grid.tsx +209 -0
- package/src/components/DatePicker/date-picker.tsx +1114 -0
- package/src/components/DescriptionList/description-list.tsx +141 -0
- package/src/components/Dialog/dialog.tsx +267 -0
- package/src/components/DropdownMenu/dropdown-menu.tsx +475 -0
- package/src/components/Empty/empty.tsx +108 -0
- package/src/components/Field/field-context.ts +136 -0
- package/src/components/Field/field-types.ts +52 -0
- package/src/components/Field/field-wrapper.tsx +348 -0
- package/src/components/Field/field.tsx +535 -0
- package/src/components/FieldControlGroup/field-control-group.tsx +136 -0
- package/src/components/FileItem/file-item.tsx +322 -0
- package/src/components/FileUpload/file-upload.tsx +326 -0
- package/src/components/FileViewer/file-viewer-types.ts +76 -0
- package/src/components/FileViewer/file-viewer.tsx +1065 -0
- package/src/components/FileViewer/image-renderer.tsx +256 -0
- package/src/components/HoverCard/hover-card.tsx +79 -0
- package/src/components/Input/input.tsx +233 -0
- package/src/components/LinkInput/link-input.tsx +304 -0
- package/src/components/Menu/menu-item.tsx +334 -0
- package/src/components/NameCard/name-card.tsx +319 -0
- package/src/components/Notice/notice.tsx +196 -0
- package/src/components/NumberInput/number-input.tsx +203 -0
- package/src/components/OverflowIndicator/overflow-indicator.tsx +156 -0
- package/src/components/PeoplePicker/avatar-stack-overflow.ts +100 -0
- package/src/components/PeoplePicker/people-picker-helpers.ts +76 -0
- package/src/components/PeoplePicker/people-picker.tsx +455 -0
- package/src/components/PeoplePicker/person-display.tsx +358 -0
- package/src/components/Popover/popover.tsx +183 -0
- package/src/components/ProgressBar/progress-bar.tsx +157 -0
- package/src/components/README.md +58 -0
- package/src/components/RadioGroup/radio-group.tsx +261 -0
- package/src/components/Rating/rating.tsx +295 -0
- package/src/components/ScrollArea/scroll-area.tsx +110 -0
- package/src/components/SegmentedControl/segmented-control.tsx +304 -0
- package/src/components/Select/select.tsx +658 -0
- package/src/components/SelectMenu/select-menu.tsx +430 -0
- package/src/components/SelectionControl/selection-item.tsx +261 -0
- package/src/components/Separator/separator.tsx +48 -0
- package/src/components/Sheet/sheet.tsx +240 -0
- package/src/components/Sidebar/sidebar.tsx +1280 -0
- package/src/components/Skeleton/skeleton.tsx +35 -0
- package/src/components/Slider/slider.tsx +158 -0
- package/src/components/Steps/steps.tsx +850 -0
- package/src/components/Switch/switch.tsx +285 -0
- package/src/components/Tabs/tabs.tsx +515 -0
- package/src/components/Tag/tag.tsx +246 -0
- package/src/components/Textarea/textarea.tsx +280 -0
- package/src/components/TimePicker/time-columns.tsx +260 -0
- package/src/components/TimePicker/time-picker.tsx +419 -0
- package/src/components/Toast/toast.tsx +129 -0
- package/src/components/Tooltip/tooltip.tsx +68 -0
- package/src/components/TreeView/tree-view.tsx +1031 -0
- package/src/hooks/use-controllable.ts +40 -0
- package/src/hooks/use-is-narrow-viewport.ts +19 -0
- package/src/hooks/use-is-touch-device.ts +21 -0
- package/src/hooks/use-overflow-items.ts +256 -0
- package/src/index.ts +85 -0
- package/src/lib/README.md +82 -0
- package/src/lib/drag-visual.ts +272 -0
- package/src/lib/i18n/README.md +60 -0
- package/src/lib/i18n/i18n-context.tsx +129 -0
- package/src/lib/multi-select-ordering.ts +61 -0
- package/src/lib/utils.ts +93 -0
- package/src/patterns/README.md +67 -0
- package/src/patterns/element-anatomy/item-anatomy.tsx +744 -0
- package/src/patterns/header-canonical/chrome-header.tsx +175 -0
- package/src/patterns/header-canonical/header-canonical.css +27 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.tsx +217 -0
- package/src/patterns/overlay-surface/overlay-surface.tsx +191 -0
- package/src/patterns/resize-handle/resize-handle.tsx +188 -0
- package/src/stories-helpers/anatomy/anatomy-utils.tsx +64 -0
- package/src/styles/preset.css +31 -0
- package/src/styles/tokens.css +35 -0
- package/src/tokens/README.md +53 -0
- package/src/tokens/color/primitives.css +429 -0
- package/src/tokens/color/semantic.css +539 -0
- package/src/tokens/elevation/overlay-geometry.ts +13 -0
- package/src/tokens/layoutSpace/layoutSpace.css +36 -0
- package/src/tokens/motion/motion.css +30 -0
- package/src/tokens/motion/motion.ts +17 -0
- package/src/tokens/opacity/opacity.css +23 -0
- package/src/tokens/radius/radius.css +19 -0
- package/src/tokens/typography/typography.css +118 -0
- package/src/tokens/uiSize/icon-size.ts +52 -0
- package/src/tokens/uiSize/uiSize.css +125 -0
|
@@ -0,0 +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'\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 DropPosition = '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: DropPosition\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)— 2026-05-04 升 SSOT 為 token `--tree-indent-{sm,md,lg}`\n// 在 `tokens/uiSize/uiSize.css`。DataTable nested rows 共用此 SSOT,跨元件視覺一致。\n// 結構對齊:子 chevron 對齊父 icon,子 icon 對齊父 label。\n// Numeric value 此處保留(drop indicator JS px 計算需 number),Tailwind class 走 token。\nconst INDENT_STEP: Record<SizeKey, number> = { sm: 24, md: 24, lg: 28 }\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 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: DropPosition; 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'`(預設):頁面側邊欄,px-2(8px)\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 * 啟用後每個 TreeItem 左側出現 drag handle(GripVertical icon),\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 /** 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 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 // ── 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: DropPosition; 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 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 if (!over || over.id === 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: DropPosition\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({ id: parentId, position: 'after', depth: parentDepth })\n return\n }\n }\n }\n }\n\n setDropTarget({ id: String(over.id), position, depth: finalDepth })\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])\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 if (over && active.id !== over.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])\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 // ── Node registry ──\n const { registerNode, unregisterNode, getNodeInfo } = useNodeRegistry()\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 // ── Context value ──\n const contextValue = React.useMemo<TreeViewContextValue>(\n () => ({\n size,\n context,\n selectionMode,\n expandOnSelect,\n draggable,\n isKeyboardRef,\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 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 // 取得所有可見的 treeitem\n const items = Array.from(\n treeRef.current.querySelectorAll<HTMLElement>('[role=\"treeitem\"]:not([hidden])')\n )\n const currentIndex = items.findIndex(\n (el) => el.dataset.treeId === focusedId\n )\n if (currentIndex < 0 && items.length > 0 && ['ArrowDown', 'ArrowUp', '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]\n )\n\n const treeEl = (\n <div\n ref={treeRef}\n role=\"tree\"\n aria-multiselectable={selectionMode === 'multiple' || undefined}\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 tabIndex={0}\n {...props}\n >\n {children}\n </div>\n )\n\n return (\n <TreeViewContext.Provider value={contextValue}>\n {/* RowSizeProvider:讓 TreeView 子樹內任何 <ItemIcon> / <ItemAvatar> /\n <ItemInlineAction> 自動讀到對的 size,跟 SidebarProvider 同一條規則。\n 未來 TreeView 接 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 <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)。對齊 `uiSize.spec.md`「Inline Action」\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 實作在 `item-layout.tsx`)\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_l3_primitive_import.sh`)。\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 * 取代 chevron 的位置。用於 stepper 的 status indicator(●/○/✓)。\n * 設定後 chevron 不渲染,改渲染 indicator。\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 } = 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 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 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 // 預設文字色 neutral-8 (fg-secondary),選中後變 neutral-9 (foreground)\n // icon 透過 currentColor 繼承,不需要另外設\n !disabled && !isSelected && 'text-fg-secondary',\n !disabled && isSelected && 'text-foreground',\n // inside: 資料夾背景高亮(Figma 風格),不用 ring/border\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 {...(draggable ? { ...dragListeners, ...dragAttrs } : {})}\n {...props}\n >\n {chevronSlot}\n\n {/* Checkbox 在 icon 前——消費 `<ItemPrefix>` 對齊第一行 */}\n {checkbox && (\n <ItemPrefix className=\"pointer-events-none\">\n {checkbox}\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 {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: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-neutral-hover', 'bg-primary', 'bg-primary-subtle', '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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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controlled / Uncontrolled dual-mode state hook。
|
|
3
|
+
*
|
|
4
|
+
* 對齊 Radix `useControllableState` 慣例:
|
|
5
|
+
* - 提供 `value` → controlled,setter 純 callback,內部不存 state
|
|
6
|
+
* - 不提供 `value`(or undefined)→ uncontrolled,內部 state + callback 同步
|
|
7
|
+
*
|
|
8
|
+
* 使用情境:Field / Switch / Checkbox / DataTable selection / DropdownMenu open 等
|
|
9
|
+
* 雙模式 prop。
|
|
10
|
+
*/
|
|
11
|
+
export declare function useControllable<T>({ value, defaultValue, onChange, }: {
|
|
12
|
+
value?: T;
|
|
13
|
+
defaultValue: T;
|
|
14
|
+
onChange?: (next: T) => void;
|
|
15
|
+
}): [T, (next: T | ((prev: T) => T)) => void];
|
|
16
|
+
//# sourceMappingURL=use-controllable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-controllable.d.ts","sourceRoot":"","sources":["../../src/hooks/use-controllable.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,EACjC,KAAK,EACL,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,KAAK,CAAC,EAAE,CAAC,CAAA;IACT,YAAY,EAAE,CAAC,CAAA;IACf,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;CAC7B,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAmB5C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from "react";
|
|
2
|
+
function useControllable({
|
|
3
|
+
value,
|
|
4
|
+
defaultValue,
|
|
5
|
+
onChange
|
|
6
|
+
}) {
|
|
7
|
+
const isControlled = value !== void 0;
|
|
8
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
9
|
+
const onChangeRef = useRef(onChange);
|
|
10
|
+
onChangeRef.current = onChange;
|
|
11
|
+
const current = isControlled ? value : internal;
|
|
12
|
+
const setValue = useCallback(
|
|
13
|
+
(next) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const computed = typeof next === "function" ? next(current) : next;
|
|
16
|
+
if (!isControlled) setInternal(computed);
|
|
17
|
+
(_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, computed);
|
|
18
|
+
},
|
|
19
|
+
[isControlled, current]
|
|
20
|
+
);
|
|
21
|
+
return [current, setValue];
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
useControllable
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=use-controllable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-controllable.js","sources":["../../src/hooks/use-controllable.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react'\n\n/**\n * Controlled / Uncontrolled dual-mode state hook。\n *\n * 對齊 Radix `useControllableState` 慣例:\n * - 提供 `value` → controlled,setter 純 callback,內部不存 state\n * - 不提供 `value`(or undefined)→ uncontrolled,內部 state + callback 同步\n *\n * 使用情境:Field / Switch / Checkbox / DataTable selection / DropdownMenu open 等\n * 雙模式 prop。\n */\nexport function useControllable<T>({\n value,\n defaultValue,\n onChange,\n}: {\n value?: T\n defaultValue: T\n onChange?: (next: T) => void\n}): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = value !== undefined\n const [internal, setInternal] = useState<T>(defaultValue)\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n\n const current = isControlled ? (value as T) : internal\n\n const setValue = useCallback(\n (next: T | ((prev: T) => T)) => {\n const computed =\n typeof next === 'function' ? (next as (prev: T) => T)(current) : next\n if (!isControlled) setInternal(computed)\n onChangeRef.current?.(computed)\n },\n [isControlled, current]\n )\n\n return [current, setValue]\n}\n"],"names":[],"mappings":";AAYO,SAAS,gBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAI8C;AAC5C,QAAM,eAAe,UAAU;AAC/B,QAAM,CAAC,UAAU,WAAW,IAAI,SAAY,YAAY;AACxD,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,QAAM,UAAU,eAAgB,QAAc;AAE9C,QAAM,WAAW;AAAA,IACf,CAAC,SAA+B;;AAC9B,YAAM,WACJ,OAAO,SAAS,aAAc,KAAwB,OAAO,IAAI;AACnE,UAAI,CAAC,aAAc,aAAY,QAAQ;AACvC,wBAAY,YAAZ,qCAAsB;AAAA,IACxB;AAAA,IACA,CAAC,cAAc,OAAO;AAAA,EAAA;AAGxB,SAAO,CAAC,SAAS,QAAQ;AAC3B;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-narrow-viewport.d.ts","sourceRoot":"","sources":["../../src/hooks/use-is-narrow-viewport.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,YAclC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
const MOBILE_BREAKPOINT = 768;
|
|
3
|
+
function useIsNarrowViewport() {
|
|
4
|
+
const [isNarrow, setIsNarrow] = React.useState(void 0);
|
|
5
|
+
React.useEffect(() => {
|
|
6
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
7
|
+
const onChange = () => {
|
|
8
|
+
setIsNarrow(window.innerWidth < MOBILE_BREAKPOINT);
|
|
9
|
+
};
|
|
10
|
+
mql.addEventListener("change", onChange);
|
|
11
|
+
setIsNarrow(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
+
return () => mql.removeEventListener("change", onChange);
|
|
13
|
+
}, []);
|
|
14
|
+
return !!isNarrow;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
useIsNarrowViewport
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=use-is-narrow-viewport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-narrow-viewport.js","sources":["../../src/hooks/use-is-narrow-viewport.ts"],"sourcesContent":["import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsNarrowViewport() {\n const [isNarrow, setIsNarrow] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsNarrow(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsNarrow(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isNarrow\n}\n"],"names":[],"mappings":";AAEA,MAAM,oBAAoB;AAEnB,SAAS,sBAAsB;AACpC,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAA8B,MAAS;AAE7E,QAAM,UAAU,MAAM;AACpB,UAAM,MAAM,OAAO,WAAW,eAAe,oBAAoB,CAAC,KAAK;AACvE,UAAM,WAAW,MAAM;AACrB,kBAAY,OAAO,aAAa,iBAAiB;AAAA,IACnD;AACA,QAAI,iBAAiB,UAAU,QAAQ;AACvC,gBAAY,OAAO,aAAa,iBAAiB;AACjD,WAAO,MAAM,IAAI,oBAAoB,UAAU,QAAQ;AAAA,EACzD,GAAG,CAAA,CAAE;AAEL,SAAO,CAAC,CAAC;AACX;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-touch-device.d.ts","sourceRoot":"","sources":["../../src/hooks/use-is-touch-device.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gBAAgB,YAY/B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
function useIsTouchDevice() {
|
|
3
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const mq = window.matchMedia("(pointer: coarse)");
|
|
6
|
+
setIsMobile(mq.matches);
|
|
7
|
+
const handler = (e) => setIsMobile(e.matches);
|
|
8
|
+
mq.addEventListener("change", handler);
|
|
9
|
+
return () => mq.removeEventListener("change", handler);
|
|
10
|
+
}, []);
|
|
11
|
+
return isMobile;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
useIsTouchDevice
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=use-is-touch-device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-touch-device.js","sources":["../../src/hooks/use-is-touch-device.ts"],"sourcesContent":["import { useState, useEffect } from 'react'\n\n/**\n * useIsMobile — 偵測觸控裝置(mobile / tablet)\n *\n * 使用 `pointer: coarse` media query,正確區分觸控 vs 精確指標裝置。\n * 用途:Select 等元件在 mobile 退回原生 picker。\n */\nexport function useIsTouchDevice() {\n const [isMobile, setIsMobile] = useState(false)\n\n useEffect(() => {\n const mq = window.matchMedia('(pointer: coarse)')\n setIsMobile(mq.matches)\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches)\n mq.addEventListener('change', handler)\n return () => mq.removeEventListener('change', handler)\n }, [])\n\n return isMobile\n}\n"],"names":[],"mappings":";AAQO,SAAS,mBAAmB;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,KAAK,OAAO,WAAW,mBAAmB;AAChD,gBAAY,GAAG,OAAO;AACtB,UAAM,UAAU,CAAC,MAA2B,YAAY,EAAE,OAAO;AACjE,OAAG,iBAAiB,UAAU,OAAO;AACrC,WAAO,MAAM,GAAG,oBAAoB,UAAU,OAAO;AAAA,EACvD,GAAG,CAAA,CAAE;AAEL,SAAO;AACT;"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 水平溢出追蹤 hooks — 給 Tabs / ChipGroup 等「一排水平 items 塞不下父容器」的元件共用。
|
|
4
|
+
*
|
|
5
|
+
* ── 設計原則 ──
|
|
6
|
+
* Scroll 模式與 Menu 模式是兩種處理策略:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Scroll 模式**(Material / Polaris / Primer / iOS 作法)
|
|
9
|
+
* items 用原生 overflow-x-auto 水平滾動,邊緣 fade mask 指示還有內容。
|
|
10
|
+
* 使用 `useScrollEdges()`:回傳 atStart / atEnd / canScroll,讓消費端
|
|
11
|
+
* 決定 mask-image / scroll arrow 的顯示。
|
|
12
|
+
*
|
|
13
|
+
* 2. **Menu 模式**(Ant Design / Atlassian 作法)
|
|
14
|
+
* 塞不下的 items 收進 DropdownMenu。**所有 items 都渲染在 DOM 中**
|
|
15
|
+
* (只視覺隱藏溢出的)以保留 Radix 的 roving tabindex / roving focus 等
|
|
16
|
+
* a11y 語意。使用 `useOverflowIndices()`:回傳 overflowIndices
|
|
17
|
+
* 供消費端渲染對應的 menu items(通常是 click proxy,觸發同一個
|
|
18
|
+
* onValueChange)。
|
|
19
|
+
*
|
|
20
|
+
* ── 為什麼分兩個 hook,不合一 ──
|
|
21
|
+
* Scroll 的計算依據是 scroll 事件與 client/scroll width;Menu 的計算依據是
|
|
22
|
+
* items 的 offsetLeft/offsetWidth 相對容器 clientWidth。訂閱的事件不同
|
|
23
|
+
* (scroll vs resize),回傳的資料形狀不同。合一會讓 API 有一半是 noise。
|
|
24
|
+
*/
|
|
25
|
+
export interface UseScrollEdgesResult<T extends HTMLElement> {
|
|
26
|
+
/** 綁在 scroll container 上的 ref */
|
|
27
|
+
scrollRef: React.RefObject<T>;
|
|
28
|
+
/** scroll 位置在最左側(無法再往左)*/
|
|
29
|
+
atStart: boolean;
|
|
30
|
+
/** scroll 位置在最右側(無法再往右)*/
|
|
31
|
+
atEnd: boolean;
|
|
32
|
+
/** 內容總寬度超過可視寬度,有滾動空間 */
|
|
33
|
+
canScroll: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 追蹤 scroll container 的滾動位置,用來決定左右 fade mask 是否顯示。
|
|
37
|
+
*
|
|
38
|
+
* 典型用法:
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges<HTMLDivElement>()
|
|
41
|
+
* const maskImage = canScroll
|
|
42
|
+
* ? `linear-gradient(to right,
|
|
43
|
+
* ${atStart ? 'black' : 'transparent'} 0,
|
|
44
|
+
* black 16px,
|
|
45
|
+
* black calc(100% - 16px),
|
|
46
|
+
* ${atEnd ? 'black' : 'transparent'} 100%)`
|
|
47
|
+
* : undefined
|
|
48
|
+
* return <div ref={scrollRef} className="overflow-x-auto" style={{ maskImage, WebkitMaskImage: maskImage }}>
|
|
49
|
+
* {items}
|
|
50
|
+
* </div>
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function useScrollEdges<T extends HTMLElement = HTMLElement>(): UseScrollEdgesResult<T>;
|
|
54
|
+
export interface UseOverflowIndicesOptions {
|
|
55
|
+
/**
|
|
56
|
+
* 預留給 overflow trigger(如 "More" 按鈕)的右側寬度(px)。
|
|
57
|
+
* 計算 items 是否溢出時會從 container clientWidth 扣掉這個值。
|
|
58
|
+
*/
|
|
59
|
+
reserveTriggerWidth?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface UseOverflowIndicesResult<C extends HTMLElement> {
|
|
62
|
+
/** 綁在 items 的父容器上 */
|
|
63
|
+
containerRef: React.RefObject<C>;
|
|
64
|
+
/** 為每個 item 註冊 ref(回傳 callback ref)*/
|
|
65
|
+
registerItem: (index: number) => (el: HTMLElement | null) => void;
|
|
66
|
+
/** DOM 順序上溢出的 item 索引(連續區間,從某個 index 到尾端)*/
|
|
67
|
+
overflowIndices: number[];
|
|
68
|
+
/** 至少有一個 item 溢出 */
|
|
69
|
+
hasOverflow: boolean;
|
|
70
|
+
/** 依 index 取得對應 item 的 DOM 元素,供 scrollIntoView 等操作使用 */
|
|
71
|
+
getItemAt: (index: number) => HTMLElement | undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 追蹤一排水平 items 裡哪些「當前不在可視範圍內」。
|
|
75
|
+
*
|
|
76
|
+
* ── 演算法 ──
|
|
77
|
+
* 對每個 item 檢查 `[offsetLeft, offsetLeft+offsetWidth]` 是否完全落在
|
|
78
|
+
* `[scrollLeft, scrollLeft + clientWidth - reserveTriggerWidth]` 範圍內。
|
|
79
|
+
* 沒完全落在內的就算溢出。
|
|
80
|
+
*
|
|
81
|
+
* **關鍵**:overflow 集合跟 scrollLeft 連動,不是靜態「原始佈局不 fit」集合。
|
|
82
|
+
* 這是 Ant Design / Atlassian 世界級作法 —— menu 顯示「當下看不到的 items」,
|
|
83
|
+
* 不是「原始溢出的 items」。
|
|
84
|
+
*
|
|
85
|
+
* 為什麼這樣對:
|
|
86
|
+
* - 使用者點 menu item → `scrollIntoView` → 原本 overflow 的 item 進入視圖,
|
|
87
|
+
* 原本可見的 items 被推出去 → 下次開 menu 看到的是「剛被推出去的 items」,
|
|
88
|
+
* 永遠能找到所有當前看不到的 items,不會卡住。
|
|
89
|
+
* - 靜態 overflow (只算原始佈局) 會造成 scroll 後無法回到前面的 items。
|
|
90
|
+
*
|
|
91
|
+
* ── 觸發重算 ──
|
|
92
|
+
* - ResizeObserver: 容器寬度變化 / item 尺寸變化
|
|
93
|
+
* - scroll event: scroll 位置變化
|
|
94
|
+
*
|
|
95
|
+
* ── 前提 ──
|
|
96
|
+
* items 在 DOM 裡始終存在 (不可 conditional render),並用 `registerItem(i)` 綁 ref。
|
|
97
|
+
* 容器要可以 scroll (overflow-x-auto 或類似),否則 scrollLeft 永遠 0。
|
|
98
|
+
*
|
|
99
|
+
* 典型用法:
|
|
100
|
+
* ```tsx
|
|
101
|
+
* const { containerRef, registerItem, overflowIndices, hasOverflow, getItemAt } =
|
|
102
|
+
* useOverflowIndices<HTMLDivElement>({ reserveTriggerWidth: 0 })
|
|
103
|
+
*
|
|
104
|
+
* const handleMenuSelect = (value: string, index: number) => {
|
|
105
|
+
* onValueChange?.(value)
|
|
106
|
+
* requestAnimationFrame(() => {
|
|
107
|
+
* getItemAt(index)?.scrollIntoView({ behavior: 'smooth', inline: 'center' })
|
|
108
|
+
* })
|
|
109
|
+
* }
|
|
110
|
+
*
|
|
111
|
+
* return (
|
|
112
|
+
* <div className="flex items-center">
|
|
113
|
+
* <div ref={containerRef} className="flex-1 min-w-0 overflow-x-auto">
|
|
114
|
+
* <ItemList>
|
|
115
|
+
* {items.map((item, i) => React.cloneElement(item, { ref: registerItem(i) }))}
|
|
116
|
+
* </ItemList>
|
|
117
|
+
* </div>
|
|
118
|
+
* {hasOverflow && <OverflowMenu items={overflowIndices.map(i => items[i])} />}
|
|
119
|
+
* </div>
|
|
120
|
+
* )
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function useOverflowIndices<C extends HTMLElement = HTMLElement>(options?: UseOverflowIndicesOptions): UseOverflowIndicesResult<C>;
|
|
124
|
+
//# sourceMappingURL=use-overflow-items.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-overflow-items.d.ts","sourceRoot":"","sources":["../../src/hooks/use-overflow-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,WAAW;IACzD,iCAAiC;IACjC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAC7B,0BAA0B;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,0BAA0B;IAC1B,KAAK,EAAE,OAAO,CAAA;IACd,wBAAwB;IACxB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,KAAK,oBAAoB,CAAC,CAAC,CAAC,CAmC7F;AAMD,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAGD,MAAM,WAAW,wBAAwB,CAAC,CAAC,SAAS,WAAW;IAC7D,qBAAqB;IACrB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAChC,sCAAsC;IACtC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IACjE,4CAA4C;IAC5C,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,oBAAoB;IACpB,WAAW,EAAE,OAAO,CAAA;IACpB,wDAAwD;IACxD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAA;CACtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EACpE,OAAO,GAAE,yBAA8B,GACtC,wBAAwB,CAAC,CAAC,CAAC,CAgF7B"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
function useScrollEdges() {
|
|
3
|
+
const scrollRef = React.useRef(null);
|
|
4
|
+
const [state, setState] = React.useState({ atStart: true, atEnd: true, canScroll: false });
|
|
5
|
+
React.useEffect(() => {
|
|
6
|
+
const el = scrollRef.current;
|
|
7
|
+
if (!el) return;
|
|
8
|
+
const update = () => {
|
|
9
|
+
const canScroll = el.scrollWidth > el.clientWidth + 1;
|
|
10
|
+
const atStart = el.scrollLeft <= 0;
|
|
11
|
+
const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;
|
|
12
|
+
setState(
|
|
13
|
+
(prev) => prev.atStart === atStart && prev.atEnd === atEnd && prev.canScroll === canScroll ? prev : { atStart, atEnd, canScroll }
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
update();
|
|
17
|
+
el.addEventListener("scroll", update, { passive: true });
|
|
18
|
+
const ro = new ResizeObserver(update);
|
|
19
|
+
ro.observe(el);
|
|
20
|
+
const mo = new MutationObserver(update);
|
|
21
|
+
mo.observe(el, { childList: true, subtree: true, characterData: true });
|
|
22
|
+
return () => {
|
|
23
|
+
el.removeEventListener("scroll", update);
|
|
24
|
+
ro.disconnect();
|
|
25
|
+
mo.disconnect();
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
return { scrollRef, ...state };
|
|
29
|
+
}
|
|
30
|
+
function useOverflowIndices(options = {}) {
|
|
31
|
+
const { reserveTriggerWidth = 0 } = options;
|
|
32
|
+
const containerRef = React.useRef(null);
|
|
33
|
+
const itemRefsMap = React.useRef(/* @__PURE__ */ new Map());
|
|
34
|
+
const [overflowIndices, setOverflowIndices] = React.useState([]);
|
|
35
|
+
const registerItem = React.useCallback((index) => {
|
|
36
|
+
return (el) => {
|
|
37
|
+
if (el) {
|
|
38
|
+
itemRefsMap.current.set(index, el);
|
|
39
|
+
} else {
|
|
40
|
+
itemRefsMap.current.delete(index);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}, []);
|
|
44
|
+
React.useEffect(() => {
|
|
45
|
+
const container = containerRef.current;
|
|
46
|
+
if (!container) return;
|
|
47
|
+
const compute = () => {
|
|
48
|
+
const containerWidth = container.clientWidth;
|
|
49
|
+
if (containerWidth === 0) return;
|
|
50
|
+
const scrollLeft = container.scrollLeft;
|
|
51
|
+
const visibleStart = scrollLeft;
|
|
52
|
+
const visibleEnd = scrollLeft + containerWidth - reserveTriggerWidth;
|
|
53
|
+
const tolerance = 1;
|
|
54
|
+
const indices = Array.from(itemRefsMap.current.keys()).sort((a, b) => a - b);
|
|
55
|
+
const overflow = [];
|
|
56
|
+
for (const i of indices) {
|
|
57
|
+
const el = itemRefsMap.current.get(i);
|
|
58
|
+
if (!el) continue;
|
|
59
|
+
const left = el.offsetLeft;
|
|
60
|
+
const right = left + el.offsetWidth;
|
|
61
|
+
const fullyVisible = left >= visibleStart - tolerance && right <= visibleEnd + tolerance;
|
|
62
|
+
if (!fullyVisible) overflow.push(i);
|
|
63
|
+
}
|
|
64
|
+
setOverflowIndices((prev) => {
|
|
65
|
+
if (prev.length === overflow.length && prev.every((v, i) => v === overflow[i])) {
|
|
66
|
+
return prev;
|
|
67
|
+
}
|
|
68
|
+
return overflow;
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
compute();
|
|
72
|
+
const ro = new ResizeObserver(compute);
|
|
73
|
+
ro.observe(container);
|
|
74
|
+
itemRefsMap.current.forEach((el) => ro.observe(el));
|
|
75
|
+
container.addEventListener("scroll", compute, { passive: true });
|
|
76
|
+
return () => {
|
|
77
|
+
ro.disconnect();
|
|
78
|
+
container.removeEventListener("scroll", compute);
|
|
79
|
+
};
|
|
80
|
+
}, [reserveTriggerWidth]);
|
|
81
|
+
const getItemAt = React.useCallback(
|
|
82
|
+
(index) => itemRefsMap.current.get(index),
|
|
83
|
+
[]
|
|
84
|
+
);
|
|
85
|
+
return {
|
|
86
|
+
containerRef,
|
|
87
|
+
registerItem,
|
|
88
|
+
overflowIndices,
|
|
89
|
+
hasOverflow: overflowIndices.length > 0,
|
|
90
|
+
getItemAt
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
useOverflowIndices,
|
|
95
|
+
useScrollEdges
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=use-overflow-items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-overflow-items.js","sources":["../../src/hooks/use-overflow-items.ts"],"sourcesContent":["import * as React from 'react'\n\n/**\n * 水平溢出追蹤 hooks — 給 Tabs / ChipGroup 等「一排水平 items 塞不下父容器」的元件共用。\n *\n * ── 設計原則 ──\n * Scroll 模式與 Menu 模式是兩種處理策略:\n *\n * 1. **Scroll 模式**(Material / Polaris / Primer / iOS 作法)\n * items 用原生 overflow-x-auto 水平滾動,邊緣 fade mask 指示還有內容。\n * 使用 `useScrollEdges()`:回傳 atStart / atEnd / canScroll,讓消費端\n * 決定 mask-image / scroll arrow 的顯示。\n *\n * 2. **Menu 模式**(Ant Design / Atlassian 作法)\n * 塞不下的 items 收進 DropdownMenu。**所有 items 都渲染在 DOM 中**\n * (只視覺隱藏溢出的)以保留 Radix 的 roving tabindex / roving focus 等\n * a11y 語意。使用 `useOverflowIndices()`:回傳 overflowIndices\n * 供消費端渲染對應的 menu items(通常是 click proxy,觸發同一個\n * onValueChange)。\n *\n * ── 為什麼分兩個 hook,不合一 ──\n * Scroll 的計算依據是 scroll 事件與 client/scroll width;Menu 的計算依據是\n * items 的 offsetLeft/offsetWidth 相對容器 clientWidth。訂閱的事件不同\n * (scroll vs resize),回傳的資料形狀不同。合一會讓 API 有一半是 noise。\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useScrollEdges — 給 scroll 模式\n// ─────────────────────────────────────────────────────────────────────────────\n\n// code-quality-allow: dead-export — hook return type — API surface for consumers who want to annotate\nexport interface UseScrollEdgesResult<T extends HTMLElement> {\n /** 綁在 scroll container 上的 ref */\n scrollRef: React.RefObject<T>\n /** scroll 位置在最左側(無法再往左)*/\n atStart: boolean\n /** scroll 位置在最右側(無法再往右)*/\n atEnd: boolean\n /** 內容總寬度超過可視寬度,有滾動空間 */\n canScroll: boolean\n}\n\n/**\n * 追蹤 scroll container 的滾動位置,用來決定左右 fade mask 是否顯示。\n *\n * 典型用法:\n * ```tsx\n * const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges<HTMLDivElement>()\n * const maskImage = canScroll\n * ? `linear-gradient(to right,\n * ${atStart ? 'black' : 'transparent'} 0,\n * black 16px,\n * black calc(100% - 16px),\n * ${atEnd ? 'black' : 'transparent'} 100%)`\n * : undefined\n * return <div ref={scrollRef} className=\"overflow-x-auto\" style={{ maskImage, WebkitMaskImage: maskImage }}>\n * {items}\n * </div>\n * ```\n */\nexport function useScrollEdges<T extends HTMLElement = HTMLElement>(): UseScrollEdgesResult<T> {\n const scrollRef = React.useRef<T | null>(null)\n const [state, setState] = React.useState({ atStart: true, atEnd: true, canScroll: false })\n\n React.useEffect(() => {\n const el = scrollRef.current\n if (!el) return\n\n const update = () => {\n const canScroll = el.scrollWidth > el.clientWidth + 1\n const atStart = el.scrollLeft <= 0\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1\n setState((prev) =>\n prev.atStart === atStart && prev.atEnd === atEnd && prev.canScroll === canScroll\n ? prev\n : { atStart, atEnd, canScroll }\n )\n }\n\n update()\n el.addEventListener('scroll', update, { passive: true })\n const ro = new ResizeObserver(update)\n ro.observe(el)\n // 監聽 children 變化(items 增減、字體載入)\n const mo = new MutationObserver(update)\n mo.observe(el, { childList: true, subtree: true, characterData: true })\n\n return () => {\n el.removeEventListener('scroll', update)\n ro.disconnect()\n mo.disconnect()\n }\n }, [])\n\n return { scrollRef, ...state }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useOverflowIndices — 給 menu 模式\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface UseOverflowIndicesOptions {\n /**\n * 預留給 overflow trigger(如 \"More\" 按鈕)的右側寬度(px)。\n * 計算 items 是否溢出時會從 container clientWidth 扣掉這個值。\n */\n reserveTriggerWidth?: number\n}\n\n// code-quality-allow: dead-export — hook return type — API surface for consumers who want to annotate\nexport interface UseOverflowIndicesResult<C extends HTMLElement> {\n /** 綁在 items 的父容器上 */\n containerRef: React.RefObject<C>\n /** 為每個 item 註冊 ref(回傳 callback ref)*/\n registerItem: (index: number) => (el: HTMLElement | null) => void\n /** DOM 順序上溢出的 item 索引(連續區間,從某個 index 到尾端)*/\n overflowIndices: number[]\n /** 至少有一個 item 溢出 */\n hasOverflow: boolean\n /** 依 index 取得對應 item 的 DOM 元素,供 scrollIntoView 等操作使用 */\n getItemAt: (index: number) => HTMLElement | undefined\n}\n\n/**\n * 追蹤一排水平 items 裡哪些「當前不在可視範圍內」。\n *\n * ── 演算法 ──\n * 對每個 item 檢查 `[offsetLeft, offsetLeft+offsetWidth]` 是否完全落在\n * `[scrollLeft, scrollLeft + clientWidth - reserveTriggerWidth]` 範圍內。\n * 沒完全落在內的就算溢出。\n *\n * **關鍵**:overflow 集合跟 scrollLeft 連動,不是靜態「原始佈局不 fit」集合。\n * 這是 Ant Design / Atlassian 世界級作法 —— menu 顯示「當下看不到的 items」,\n * 不是「原始溢出的 items」。\n *\n * 為什麼這樣對:\n * - 使用者點 menu item → `scrollIntoView` → 原本 overflow 的 item 進入視圖,\n * 原本可見的 items 被推出去 → 下次開 menu 看到的是「剛被推出去的 items」,\n * 永遠能找到所有當前看不到的 items,不會卡住。\n * - 靜態 overflow (只算原始佈局) 會造成 scroll 後無法回到前面的 items。\n *\n * ── 觸發重算 ──\n * - ResizeObserver: 容器寬度變化 / item 尺寸變化\n * - scroll event: scroll 位置變化\n *\n * ── 前提 ──\n * items 在 DOM 裡始終存在 (不可 conditional render),並用 `registerItem(i)` 綁 ref。\n * 容器要可以 scroll (overflow-x-auto 或類似),否則 scrollLeft 永遠 0。\n *\n * 典型用法:\n * ```tsx\n * const { containerRef, registerItem, overflowIndices, hasOverflow, getItemAt } =\n * useOverflowIndices<HTMLDivElement>({ reserveTriggerWidth: 0 })\n *\n * const handleMenuSelect = (value: string, index: number) => {\n * onValueChange?.(value)\n * requestAnimationFrame(() => {\n * getItemAt(index)?.scrollIntoView({ behavior: 'smooth', inline: 'center' })\n * })\n * }\n *\n * return (\n * <div className=\"flex items-center\">\n * <div ref={containerRef} className=\"flex-1 min-w-0 overflow-x-auto\">\n * <ItemList>\n * {items.map((item, i) => React.cloneElement(item, { ref: registerItem(i) }))}\n * </ItemList>\n * </div>\n * {hasOverflow && <OverflowMenu items={overflowIndices.map(i => items[i])} />}\n * </div>\n * )\n * ```\n */\nexport function useOverflowIndices<C extends HTMLElement = HTMLElement>(\n options: UseOverflowIndicesOptions = {}\n): UseOverflowIndicesResult<C> {\n const { reserveTriggerWidth = 0 } = options\n const containerRef = React.useRef<C | null>(null)\n const itemRefsMap = React.useRef<Map<number, HTMLElement>>(new Map())\n const [overflowIndices, setOverflowIndices] = React.useState<number[]>([])\n\n const registerItem = React.useCallback((index: number) => {\n return (el: HTMLElement | null) => {\n if (el) {\n itemRefsMap.current.set(index, el)\n } else {\n itemRefsMap.current.delete(index)\n }\n }\n }, [])\n\n React.useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const compute = () => {\n const containerWidth = container.clientWidth\n if (containerWidth === 0) return\n\n const scrollLeft = container.scrollLeft\n const visibleStart = scrollLeft\n const visibleEnd = scrollLeft + containerWidth - reserveTriggerWidth\n\n // 容許 1px 的像素取整誤差,避免邊界 item 被誤判為 overflow\n const tolerance = 1\n\n const indices = Array.from(itemRefsMap.current.keys()).sort((a, b) => a - b)\n\n const overflow: number[] = []\n for (const i of indices) {\n const el = itemRefsMap.current.get(i)\n if (!el) continue\n\n const left = el.offsetLeft\n const right = left + el.offsetWidth\n // 完全可見條件: item 的左右邊都在可視窗口內\n const fullyVisible =\n left >= visibleStart - tolerance && right <= visibleEnd + tolerance\n if (!fullyVisible) overflow.push(i)\n }\n\n setOverflowIndices((prev) => {\n if (prev.length === overflow.length && prev.every((v, i) => v === overflow[i])) {\n return prev\n }\n return overflow\n })\n }\n\n compute()\n const ro = new ResizeObserver(compute)\n ro.observe(container)\n // 也觀察每個 item 的尺寸變化(字體載入、label 更新等)\n itemRefsMap.current.forEach((el) => ro.observe(el))\n // Scroll event: overflow 集合隨 scroll 位置變化\n container.addEventListener('scroll', compute, { passive: true })\n\n return () => {\n ro.disconnect()\n container.removeEventListener('scroll', compute)\n }\n }, [reserveTriggerWidth])\n\n const getItemAt = React.useCallback(\n (index: number) => itemRefsMap.current.get(index),\n []\n )\n\n return {\n containerRef,\n registerItem,\n overflowIndices,\n hasOverflow: overflowIndices.length > 0,\n getItemAt,\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export * from './components/Accordion/accordion';
|
|
2
|
+
export * from './components/Alert/alert';
|
|
3
|
+
export * from './components/AppShell/app-shell';
|
|
4
|
+
export * from './components/AspectRatio/aspect-ratio';
|
|
5
|
+
export * from './components/Avatar/avatar';
|
|
6
|
+
export * from './components/Badge/badge';
|
|
7
|
+
export * from './components/Breadcrumb/breadcrumb';
|
|
8
|
+
export * from './components/BulkActionBar/bulk-action-bar';
|
|
9
|
+
export * from './components/Button/button';
|
|
10
|
+
export * from './components/Calendar/calendar';
|
|
11
|
+
export * from './components/Carousel/carousel';
|
|
12
|
+
export * from './components/Chart/chart';
|
|
13
|
+
export * from './components/Checkbox/checkbox';
|
|
14
|
+
export * from './components/Chip/chip';
|
|
15
|
+
export * from './components/CircularProgress/circular-progress';
|
|
16
|
+
export * from './components/Coachmark/coachmark';
|
|
17
|
+
export { Combobox } from './components/Combobox/combobox';
|
|
18
|
+
export type { ComboboxProps } from './components/Combobox/combobox';
|
|
19
|
+
export * from './components/Command/command';
|
|
20
|
+
export * from './components/DataTable/data-table';
|
|
21
|
+
export * from './components/DateGrid/date-grid';
|
|
22
|
+
export * from './components/DatePicker/date-picker';
|
|
23
|
+
export * from './components/DescriptionList/description-list';
|
|
24
|
+
export * from './components/Dialog/dialog';
|
|
25
|
+
export * from './components/DropdownMenu/dropdown-menu';
|
|
26
|
+
export * from './components/Empty/empty';
|
|
27
|
+
export * from './components/Field/field';
|
|
28
|
+
export * from './components/FieldControlGroup/field-control-group';
|
|
29
|
+
export * from './components/FileItem/file-item';
|
|
30
|
+
export * from './components/FileUpload/file-upload';
|
|
31
|
+
export * from './components/FileViewer/file-viewer';
|
|
32
|
+
export * from './components/HoverCard/hover-card';
|
|
33
|
+
export * from './components/Input/input';
|
|
34
|
+
export * from './components/LinkInput/link-input';
|
|
35
|
+
export * from './components/Menu/menu-item';
|
|
36
|
+
export * from './components/NameCard/name-card';
|
|
37
|
+
export * from './components/Notice/notice';
|
|
38
|
+
export * from './components/NumberInput/number-input';
|
|
39
|
+
export * from './components/OverflowIndicator/overflow-indicator';
|
|
40
|
+
export * from './components/PeoplePicker/people-picker';
|
|
41
|
+
export * from './components/Popover/popover';
|
|
42
|
+
export * from './components/ProgressBar/progress-bar';
|
|
43
|
+
export * from './components/RadioGroup/radio-group';
|
|
44
|
+
export * from './components/Rating/rating';
|
|
45
|
+
export * from './components/ScrollArea/scroll-area';
|
|
46
|
+
export * from './components/SegmentedControl/segmented-control';
|
|
47
|
+
export * from './components/Select/select';
|
|
48
|
+
export * from './components/SelectMenu/select-menu';
|
|
49
|
+
export * from './components/SelectionControl/selection-item';
|
|
50
|
+
export * from './components/Separator/separator';
|
|
51
|
+
export * from './components/Sheet/sheet';
|
|
52
|
+
export * from './components/Sidebar/sidebar';
|
|
53
|
+
export * from './components/Skeleton/skeleton';
|
|
54
|
+
export * from './components/Slider/slider';
|
|
55
|
+
export * from './components/Steps/steps';
|
|
56
|
+
export * from './components/Switch/switch';
|
|
57
|
+
export * from './components/Tabs/tabs';
|
|
58
|
+
export * from './components/Tag/tag';
|
|
59
|
+
export * from './components/Textarea/textarea';
|
|
60
|
+
export * from './components/TimePicker/time-picker';
|
|
61
|
+
export * from './components/Toast/toast';
|
|
62
|
+
export * from './components/Tooltip/tooltip';
|
|
63
|
+
export { TreeView, TreeItem } from './components/TreeView/tree-view';
|
|
64
|
+
export type { TreeViewProps, TreeItemProps, TreeDragEndEvent } from './components/TreeView/tree-view';
|
|
65
|
+
export * from './patterns/horizontal-overflow/horizontal-overflow';
|
|
66
|
+
export * from './patterns/overlay-surface/overlay-surface';
|
|
67
|
+
export * from './patterns/resize-handle/resize-handle';
|
|
68
|
+
export * from './hooks/use-controllable';
|
|
69
|
+
export * from './hooks/use-is-narrow-viewport';
|
|
70
|
+
export * from './hooks/use-is-touch-device';
|
|
71
|
+
export * from './hooks/use-overflow-items';
|
|
72
|
+
export * from './lib/drag-visual';
|
|
73
|
+
export * from './lib/multi-select-ordering';
|
|
74
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,uCAAuC,CAAA;AACrD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,oCAAoC,CAAA;AAClD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,iDAAiD,CAAA;AAC/D,cAAc,kCAAkC,CAAA;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAA;AACzD,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACnE,cAAc,8BAA8B,CAAA;AAC5C,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,qCAAqC,CAAA;AACnD,cAAc,+CAA+C,CAAA;AAC7D,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yCAAyC,CAAA;AACvD,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oDAAoD,CAAA;AAClE,cAAc,iCAAiC,CAAA;AAC/C,cAAc,qCAAqC,CAAA;AACnD,cAAc,qCAAqC,CAAA;AACnD,cAAc,mCAAmC,CAAA;AACjD,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uCAAuC,CAAA;AACrD,cAAc,mDAAmD,CAAA;AACjE,cAAc,yCAAyC,CAAA;AACvD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uCAAuC,CAAA;AACrD,cAAc,qCAAqC,CAAA;AACnD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qCAAqC,CAAA;AACnD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qCAAqC,CAAA;AACnD,cAAc,8CAA8C,CAAA;AAC5D,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,qCAAqC,CAAA;AACnD,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAE5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AACpE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAGrG,cAAc,oDAAoD,CAAA;AAClE,cAAc,4CAA4C,CAAA;AAC1D,cAAc,wCAAwC,CAAA;AAGtD,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAG1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,6BAA6B,CAAA"}
|