@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,237 @@
|
|
|
1
|
+
// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
|
|
4
|
+
import { Check, Minus } from "lucide-react"
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
import type { FieldMode, FieldVariant } from "@/design-system/components/Field/field-types"
|
|
9
|
+
import { useFieldContext } from "@/design-system/components/Field/field-context"
|
|
10
|
+
import { SelectionItem } from "@/design-system/components/SelectionControl/selection-item"
|
|
11
|
+
import { CheckboxGroupContext } from "./checkbox-group"
|
|
12
|
+
|
|
13
|
+
// ── Variants ────────────────────────────────────────────────────────────────
|
|
14
|
+
// 三種尺寸(sm/md=16px, lg=20px),對齊 icon 系統與 SelectionItem。
|
|
15
|
+
|
|
16
|
+
const checkboxVariants = cva(
|
|
17
|
+
[
|
|
18
|
+
'grid place-content-center shrink-0 rounded-md',
|
|
19
|
+
'border border-border bg-surface',
|
|
20
|
+
'transition-colors duration-150',
|
|
21
|
+
'hover:border-border-hover',
|
|
22
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
|
|
23
|
+
'data-[state=checked]:bg-primary data-[state=checked]:text-on-emphasis data-[state=checked]:border-primary',
|
|
24
|
+
'data-[state=checked]:hover:bg-primary-hover data-[state=checked]:hover:border-primary-hover',
|
|
25
|
+
'data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-on-emphasis data-[state=indeterminate]:border-primary',
|
|
26
|
+
'data-[state=indeterminate]:hover:bg-primary-hover data-[state=indeterminate]:hover:border-primary-hover',
|
|
27
|
+
'disabled:cursor-not-allowed disabled:bg-disabled disabled:border-transparent disabled:hover:border-transparent',
|
|
28
|
+
'disabled:data-[state=checked]:bg-disabled disabled:data-[state=checked]:text-fg-disabled disabled:data-[state=checked]:border-transparent',
|
|
29
|
+
'disabled:data-[state=indeterminate]:bg-disabled disabled:data-[state=indeterminate]:text-fg-disabled disabled:data-[state=indeterminate]:border-transparent',
|
|
30
|
+
// readOnly:鎖定互動但維持 checked/unchecked 視覺
|
|
31
|
+
'data-[readonly=true]:pointer-events-none data-[readonly=true]:cursor-default',
|
|
32
|
+
'data-[readonly=true]:hover:border-border',
|
|
33
|
+
],
|
|
34
|
+
{
|
|
35
|
+
variants: {
|
|
36
|
+
size: {
|
|
37
|
+
sm: 'h-4 w-4',
|
|
38
|
+
md: 'h-4 w-4',
|
|
39
|
+
lg: 'h-5 w-5',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
defaultVariants: {
|
|
43
|
+
size: 'md',
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
// ── Check Icon Size ─────────────────────────────────────────────────────────
|
|
49
|
+
const checkIconSize: Record<string, number> = { sm: 12, md: 12, lg: 16 }
|
|
50
|
+
|
|
51
|
+
// ── Check Icon Stroke Weight ────────────────────────────────────────────────
|
|
52
|
+
// 16px 以下 icon 視覺不夠顯眼 → 用較粗 stroke 補償。Lucide 預設 strokeWidth=2 在
|
|
53
|
+
// 12px 下 render 約 1px 線寬,視覺偏細;加粗到 3.5(render ≈ 1.75px)才有足夠視覺權重。
|
|
54
|
+
// 16px 用 2.5(render ≈ 1.67px)讓 checked 態的 check icon 夠顯眼。
|
|
55
|
+
//
|
|
56
|
+
// 為什麼不是 3 / 2:本 session 實測 3 / 2 在 storybook 上兩個 size 的 render 線寬差僅
|
|
57
|
+
// 0.17px(1.5 vs 1.33),使用者肉眼看不出差異(image #64 回報)。改為 3.5 / 2.5:
|
|
58
|
+
// - md 12px × 3.5 → 1.75px 線寬
|
|
59
|
+
// - lg 16px × 2.5 → 1.67px 線寬
|
|
60
|
+
// 兩者仍接近但 md 的線寬 **絕對值** 跟 16px 預設(1.33)有更明顯差異,視覺上「小 check 更粗」。
|
|
61
|
+
//
|
|
62
|
+
// 世界級對照:iOS HIG / Material 3 / Polaris 的 checkmark 在 <16px 下皆加粗 compensate。
|
|
63
|
+
// 為什麼不用 Lucide absoluteStrokeWidth:那保持「絕對 px 粗細」,我們反而要「小尺寸比例更粗」。
|
|
64
|
+
//
|
|
65
|
+
// Check 與 Minus(indeterminate)共用此規則;Switch 的 SPECS.checkStroke 採同樣值。
|
|
66
|
+
// 2026-05-18 簡化 per user 視覺證「sm/md 3.5 vs lg 2.5 看不出差別」(image #64 + 2nd round
|
|
67
|
+
// 圖一 video proof)+「做完」approval:
|
|
68
|
+
// - 原 {3.5, 3.5, 2.5} → effective render thickness 1.75 / 1.75 / 1.67 = 跨 size 差 0.08px(視覺看不出)
|
|
69
|
+
// - 改 {3, 3, 2.5} 保留 sm/md 小尺寸 legibility insurance(per iOS HIG / Material 3 cite)
|
|
70
|
+
// + lg 仍稍粗於 Lucide default 2(保留 compensation 主旨,但不過度差異化)
|
|
71
|
+
const checkStrokeWidth: Record<string, number> = { sm: 3, md: 3, lg: 2.5 }
|
|
72
|
+
|
|
73
|
+
// ── Types ───────────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
export interface CheckboxProps
|
|
76
|
+
extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,
|
|
77
|
+
VariantProps<typeof checkboxVariants> {
|
|
78
|
+
/**
|
|
79
|
+
* Inline label。提供時 Checkbox 自動透過 SelectionItem 包裝,
|
|
80
|
+
* 套用 text-body / text-foreground / disabled 色 的 codified 樣式。
|
|
81
|
+
* 在 <Field> context 內時此 prop 會被忽略(由 FieldLabel 接管)。
|
|
82
|
+
*/
|
|
83
|
+
label?: React.ReactNode
|
|
84
|
+
/**
|
|
85
|
+
* Inline description(secondary 文字)。須與 label 搭配使用。
|
|
86
|
+
* 套用 text-body / text-fg-secondary 樣式。
|
|
87
|
+
* 在 <Field> context 內時此 prop 會被忽略(由 FieldDescription 接管)。
|
|
88
|
+
*/
|
|
89
|
+
description?: React.ReactNode
|
|
90
|
+
/**
|
|
91
|
+
* readonly 模式:鎖定互動但維持 checked/unchecked 視覺正確。
|
|
92
|
+
* 與 disabled 的差異:readonly 不降色(可讀),disabled 降色(弱化)。
|
|
93
|
+
* 用於表單 readonly 呈現、DataTable cell 非編輯態。
|
|
94
|
+
*/
|
|
95
|
+
readOnly?: boolean
|
|
96
|
+
/**
|
|
97
|
+
* Field mode(2026-05-05 Phase B3 align):
|
|
98
|
+
* edit — 一般可互動 checkbox(預設)
|
|
99
|
+
* display — **純展示**:渲染 ✓ / —(無互動 primitive、無 input chrome);
|
|
100
|
+
* 對齊 Carbon read-only / DataTable boolean cell 場景。取代既有 BooleanDisplay。
|
|
101
|
+
* readonly — 同 readOnly prop:checkbox 視覺保留 + 鎖互動 + a11y readonly signal
|
|
102
|
+
* disabled — 同 disabled prop:降色 + 鎖互動
|
|
103
|
+
*/
|
|
104
|
+
mode?: FieldMode
|
|
105
|
+
/**
|
|
106
|
+
* Visual chrome — checkbox 本體無 input wrapper variant,本 prop 對 checkbox 主體無視覺影響;
|
|
107
|
+
* 為對齊 Field 4-mode + chrome 透傳契約而保留(M19 一致性)。
|
|
108
|
+
*/
|
|
109
|
+
variant?: FieldVariant
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Component ───────────────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
const Checkbox = React.forwardRef<
|
|
115
|
+
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
|
116
|
+
CheckboxProps
|
|
117
|
+
>(
|
|
118
|
+
(
|
|
119
|
+
{
|
|
120
|
+
className,
|
|
121
|
+
size,
|
|
122
|
+
label,
|
|
123
|
+
description,
|
|
124
|
+
readOnly = false,
|
|
125
|
+
disabled,
|
|
126
|
+
mode,
|
|
127
|
+
// chrome 對 Checkbox 主體無視覺影響(無 input wrapper)— 接收純為 prop 一致性;destructure 防 leak 到 DOM。
|
|
128
|
+
variant: _chrome,
|
|
129
|
+
id: idProp,
|
|
130
|
+
...props
|
|
131
|
+
},
|
|
132
|
+
ref
|
|
133
|
+
) => {
|
|
134
|
+
const sizeKey = size ?? 'md'
|
|
135
|
+
const iconPx = checkIconSize[sizeKey]
|
|
136
|
+
const iconStrokeWidth = checkStrokeWidth[sizeKey]
|
|
137
|
+
|
|
138
|
+
// ── mode='display' ─────────────────────────────────────────────────────
|
|
139
|
+
// 純展示模式:無互動 primitive、無 input variant,渲染 ✓ / —。
|
|
140
|
+
// 取代既有 BooleanDisplay(2026-05-05 Phase B3 retire)— 該 helper 已併入 Checkbox。
|
|
141
|
+
// 顯示規則:checked=true → ✓(foreground);其他(false / null / undefined / indeterminate)→ —(fg-muted)
|
|
142
|
+
if (mode === 'display') {
|
|
143
|
+
const isChecked = props.checked === true
|
|
144
|
+
return isChecked
|
|
145
|
+
? <span className="text-foreground">✓</span>
|
|
146
|
+
: <span className="text-fg-muted">—</span>
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Field context:Checkbox 單獨塞進 Field(binary toggle)時,忽略自己的 label 讓 FieldLabel 接管
|
|
150
|
+
//
|
|
151
|
+
// **例外**:Checkbox 是 CheckboxGroup 的 child 時(multi-select 情境),**每個 checkbox
|
|
152
|
+
// 的 label 是它自己的選項名**,FieldLabel 只是群組名稱 — 此時 label **必須保留**,
|
|
153
|
+
// 不能被 Field context 吞掉。AR50 的根因就是這個 branch 之前誤把 group 內的 checkbox
|
|
154
|
+
// label 全清空,導致 sheet 內 3 個 checkbox 沒 label。
|
|
155
|
+
const fieldCtx = useFieldContext()
|
|
156
|
+
const checkboxGroupCtx = React.useContext(CheckboxGroupContext)
|
|
157
|
+
const insideField = fieldCtx?.hasFieldWrapper === true
|
|
158
|
+
const insideGroup = checkboxGroupCtx?.inGroup === true
|
|
159
|
+
const shouldSuppressLabel = insideField && !insideGroup
|
|
160
|
+
const effectiveLabel = shouldSuppressLabel ? undefined : label
|
|
161
|
+
const effectiveDescription = shouldSuppressLabel ? undefined : description
|
|
162
|
+
|
|
163
|
+
// Id 連結
|
|
164
|
+
//
|
|
165
|
+
// ── 2026-04-21 bug fix ──
|
|
166
|
+
// 原本:`idProp ?? fieldCtx?.id ?? generatedId`。
|
|
167
|
+
// 在 Field 內 fieldCtx.id 存在,CheckboxGroup 所有 children 共用同一個 id →
|
|
168
|
+
// 每個 checkbox 的 `<label htmlFor={sameId}>` 全指向第一個 checkbox →
|
|
169
|
+
// **點任何 label 都只開關第一個 checkbox(real bug)**。
|
|
170
|
+
//
|
|
171
|
+
// 修法:group 內的 checkbox 強制用 generatedId(唯一),不沿用 Field id;
|
|
172
|
+
// solo in Field(binary toggle)才沿用 fieldCtx.id 讓 FieldLabel htmlFor 生效。
|
|
173
|
+
const generatedId = React.useId()
|
|
174
|
+
const inputId = idProp ?? (insideGroup ? generatedId : (fieldCtx?.id ?? generatedId))
|
|
175
|
+
|
|
176
|
+
const rootEl = (
|
|
177
|
+
<CheckboxPrimitive.Root
|
|
178
|
+
id={inputId}
|
|
179
|
+
ref={ref}
|
|
180
|
+
disabled={disabled}
|
|
181
|
+
aria-readonly={readOnly || undefined}
|
|
182
|
+
data-readonly={readOnly || undefined}
|
|
183
|
+
tabIndex={readOnly ? -1 : undefined}
|
|
184
|
+
aria-describedby={fieldCtx?.descriptionId}
|
|
185
|
+
className={cn(checkboxVariants({ size }), className)}
|
|
186
|
+
{...props}
|
|
187
|
+
>
|
|
188
|
+
<CheckboxPrimitive.Indicator className="grid place-content-center text-current">
|
|
189
|
+
{props.checked === 'indeterminate'
|
|
190
|
+
? <Minus style={{ width: iconPx, height: iconPx }} strokeWidth={iconStrokeWidth} />
|
|
191
|
+
: <Check style={{ width: iconPx, height: iconPx }} strokeWidth={iconStrokeWidth} />
|
|
192
|
+
}
|
|
193
|
+
</CheckboxPrimitive.Indicator>
|
|
194
|
+
</CheckboxPrimitive.Root>
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
// 無 label → 只渲染 checkbox 本體
|
|
198
|
+
if (effectiveLabel == null) return rootEl
|
|
199
|
+
|
|
200
|
+
// 有 label → 透過 SelectionItem 包裝(control 在左、label+description 在右)
|
|
201
|
+
return (
|
|
202
|
+
<SelectionItem
|
|
203
|
+
control={rootEl}
|
|
204
|
+
label={effectiveLabel}
|
|
205
|
+
description={effectiveDescription}
|
|
206
|
+
htmlFor={inputId}
|
|
207
|
+
disabled={disabled}
|
|
208
|
+
size={sizeKey}
|
|
209
|
+
/>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
|
214
|
+
|
|
215
|
+
// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
|
|
216
|
+
// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
|
|
217
|
+
export const checkboxMeta = {
|
|
218
|
+
component: 'Checkbox',
|
|
219
|
+
family: 4,
|
|
220
|
+
variants: {
|
|
221
|
+
|
|
222
|
+
},
|
|
223
|
+
sizes: {
|
|
224
|
+
sm: { fieldHeight: 28, iconSize: 16, typography: 'body' },
|
|
225
|
+
md: { fieldHeight: 32, iconSize: 16, typography: 'body' },
|
|
226
|
+
lg: { fieldHeight: 40, iconSize: 20, typography: 'body' },
|
|
227
|
+
},
|
|
228
|
+
states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
|
|
229
|
+
tokens: {
|
|
230
|
+
bg: ['bg-disabled', 'bg-primary', 'bg-primary-hover', 'bg-surface'],
|
|
231
|
+
fg: ['text-fg-disabled', 'text-fg-secondary', 'text-foreground'],
|
|
232
|
+
ring: ['ring-ring'],
|
|
233
|
+
},
|
|
234
|
+
defaultSize: 'md',
|
|
235
|
+
} as const
|
|
236
|
+
|
|
237
|
+
export { Checkbox, checkboxVariants }
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'
|
|
4
|
+
import { cva } from 'class-variance-authority'
|
|
5
|
+
import type { LucideIcon } from 'lucide-react'
|
|
6
|
+
import { cn } from '@/lib/utils'
|
|
7
|
+
import {
|
|
8
|
+
DropdownMenu,
|
|
9
|
+
DropdownMenuTrigger,
|
|
10
|
+
DropdownMenuContent,
|
|
11
|
+
DropdownMenuCheckboxItem,
|
|
12
|
+
} from '@/design-system/components/DropdownMenu/dropdown-menu'
|
|
13
|
+
import {
|
|
14
|
+
useScrollEdges,
|
|
15
|
+
useScrollByPage,
|
|
16
|
+
buildFadeMask,
|
|
17
|
+
ARROW_BUTTON_WIDTH,
|
|
18
|
+
OverflowScrollArrow,
|
|
19
|
+
OverflowMenuTriggerButton,
|
|
20
|
+
} from '@/design-system/patterns/horizontal-overflow/horizontal-overflow'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Chip — Material Design Filter Chip
|
|
24
|
+
*
|
|
25
|
+
* 基於 Radix ToggleGroup,橋接設計系統 token。
|
|
26
|
+
* 必須在 <ChipGroup> 內使用。
|
|
27
|
+
*
|
|
28
|
+
* ── 內部結構(鏡射 Button)──
|
|
29
|
+
* [startIcon?] [<span px-1>label</span>] [<span gap-1>badge? + endIcon?</span>]
|
|
30
|
+
*
|
|
31
|
+
* ── Size ──
|
|
32
|
+
* 單一 size = h-field-sm(28/32 density-aware)
|
|
33
|
+
* 對齊 Material 3 / Atlassian / Polaris 世界級共識
|
|
34
|
+
*
|
|
35
|
+
* ── State ──
|
|
36
|
+
* default bg-surface border-border text-foreground
|
|
37
|
+
* hover border-border-hover(對齊 Input / SegmentedControl)
|
|
38
|
+
* selected bg-primary-subtle border-primary-hover text-primary-hover
|
|
39
|
+
* disabled cursor-not-allowed text-fg-disabled
|
|
40
|
+
*
|
|
41
|
+
* ── 詳見 chip.spec.md ──
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
// ── Chip item ────────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
const chipVariants = cva(
|
|
47
|
+
[
|
|
48
|
+
'inline-flex items-center justify-center',
|
|
49
|
+
'h-field-sm px-3 gap-1',
|
|
50
|
+
'rounded-full border border-border',
|
|
51
|
+
// 預設文字: text-fg-secondary (neutral-8) — 對齊 SegmentedControl / Tabs 未選狀態
|
|
52
|
+
'bg-surface text-fg-secondary',
|
|
53
|
+
'text-body leading-compact font-medium whitespace-nowrap',
|
|
54
|
+
'transition-colors duration-150',
|
|
55
|
+
'cursor-pointer select-none',
|
|
56
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
|
|
57
|
+
// hover(未選):border 加深一階 + 文字轉深,對齊 Input / SegmentedControl hover
|
|
58
|
+
'hover:border-border-hover hover:text-foreground',
|
|
59
|
+
// selected: 文字 + 邊框都用 primary-hover,底色維持 bg-surface 不變
|
|
60
|
+
// ── pill 風格 canonical 選中規則,跟 SegmentedControl 完全一致:
|
|
61
|
+
// primary-hover 同時染文字和線條;底色不改 (不用 primary-subtle)。
|
|
62
|
+
'data-[state=on]:border-primary-hover data-[state=on]:text-primary-hover',
|
|
63
|
+
// disabled:cursor-not-allowed + 鎖 hover 不變色
|
|
64
|
+
// 不用 pointer-events-none(否則 cursor-not-allowed 不會顯示)
|
|
65
|
+
'disabled:cursor-not-allowed disabled:text-fg-disabled',
|
|
66
|
+
'disabled:hover:border-border disabled:hover:text-fg-disabled',
|
|
67
|
+
]
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
export interface ChipProps
|
|
71
|
+
extends React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> {
|
|
72
|
+
/** 左側 icon(LucideIcon),最多一個 */
|
|
73
|
+
startIcon?: LucideIcon
|
|
74
|
+
/** 右側 badge(通常是計數指示器)*/
|
|
75
|
+
badge?: React.ReactNode
|
|
76
|
+
/** 右側 icon(少見,通常是 ChevronDown 指示可展開)*/
|
|
77
|
+
endIcon?: LucideIcon
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const Chip = React.forwardRef<
|
|
81
|
+
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
|
|
82
|
+
ChipProps
|
|
83
|
+
>(({ className, startIcon: StartIcon, badge, endIcon: EndIcon, children, ...props }, ref) => {
|
|
84
|
+
const hasSuffix = badge != null || EndIcon !== undefined
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<ToggleGroupPrimitive.Item
|
|
88
|
+
ref={ref}
|
|
89
|
+
className={cn(chipVariants(), className)}
|
|
90
|
+
{...props}
|
|
91
|
+
>
|
|
92
|
+
{StartIcon && <StartIcon size={16} aria-hidden />}
|
|
93
|
+
{children != null && <span className="px-1">{children}</span>}
|
|
94
|
+
{hasSuffix && (
|
|
95
|
+
<span className="inline-flex items-center gap-1">
|
|
96
|
+
{badge}
|
|
97
|
+
{EndIcon && <EndIcon size={16} aria-hidden />}
|
|
98
|
+
</span>
|
|
99
|
+
)}
|
|
100
|
+
</ToggleGroupPrimitive.Item>
|
|
101
|
+
)
|
|
102
|
+
})
|
|
103
|
+
Chip.displayName = 'Chip'
|
|
104
|
+
|
|
105
|
+
// ── ChipGroup ────────────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
export type ChipGroupLayout = 'wrap' | 'scroll' | 'menu'
|
|
108
|
+
|
|
109
|
+
export type ChipGroupProps = React.ComponentPropsWithoutRef<
|
|
110
|
+
typeof ToggleGroupPrimitive.Root
|
|
111
|
+
> & {
|
|
112
|
+
/** Overflow 處理模式。預設 `wrap`(塞不下換行)。詳見 chip.spec.md */
|
|
113
|
+
layout?: ChipGroupLayout
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const ChipGroup = React.forwardRef<HTMLDivElement, ChipGroupProps>(
|
|
117
|
+
({ layout = 'wrap', className, children, ...props }, ref) => {
|
|
118
|
+
if (layout === 'scroll') {
|
|
119
|
+
return (
|
|
120
|
+
<ScrollChipGroup ref={ref} className={className} {...props}>
|
|
121
|
+
{children}
|
|
122
|
+
</ScrollChipGroup>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
if (layout === 'menu') {
|
|
126
|
+
return (
|
|
127
|
+
<MenuChipGroup ref={ref} className={className} {...props}>
|
|
128
|
+
{children}
|
|
129
|
+
</MenuChipGroup>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
// wrap(預設)
|
|
133
|
+
return (
|
|
134
|
+
<ToggleGroupPrimitive.Root
|
|
135
|
+
ref={ref}
|
|
136
|
+
className={cn('flex flex-wrap gap-2', className)}
|
|
137
|
+
{...props}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</ToggleGroupPrimitive.Root>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
ChipGroup.displayName = 'ChipGroup'
|
|
145
|
+
|
|
146
|
+
// ── Scroll / Menu modes ──
|
|
147
|
+
// Fade mask / arrows / menu trigger 全部從 horizontal-overflow pattern module 取用。
|
|
148
|
+
// 詳見 `patterns/horizontal-overflow/horizontal-overflow.spec.md`。
|
|
149
|
+
//
|
|
150
|
+
// Canonical 規則:所有 overflow affordance 一律是 Button text sm iconOnly,
|
|
151
|
+
// 不論在 Chip / Tab / Step / SegmentedControl。Chip menu trigger 曾經用
|
|
152
|
+
// chip-shape 圓形 button,已改回 text button 對齊 mental model。
|
|
153
|
+
|
|
154
|
+
// ── ScrollChipGroup ──────────────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
const ScrollChipGroup = React.forwardRef<
|
|
157
|
+
HTMLDivElement,
|
|
158
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>
|
|
159
|
+
>(({ className, children, ...props }, ref) => {
|
|
160
|
+
const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges<HTMLDivElement>()
|
|
161
|
+
const scrollByPage = useScrollByPage(scrollRef)
|
|
162
|
+
const maskImage = buildFadeMask({
|
|
163
|
+
canScroll,
|
|
164
|
+
atStart,
|
|
165
|
+
atEnd,
|
|
166
|
+
reserveArrowWidth: ARROW_BUTTON_WIDTH,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<div className="relative">
|
|
171
|
+
<div
|
|
172
|
+
ref={scrollRef}
|
|
173
|
+
className="overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
174
|
+
style={{ maskImage, WebkitMaskImage: maskImage }}
|
|
175
|
+
>
|
|
176
|
+
<ToggleGroupPrimitive.Root
|
|
177
|
+
ref={ref}
|
|
178
|
+
className={cn('flex flex-nowrap gap-2 w-fit', className)}
|
|
179
|
+
{...props}
|
|
180
|
+
>
|
|
181
|
+
{children}
|
|
182
|
+
</ToggleGroupPrimitive.Root>
|
|
183
|
+
</div>
|
|
184
|
+
{!atStart && canScroll && (
|
|
185
|
+
<OverflowScrollArrow direction="left" onClick={() => scrollByPage('left')} />
|
|
186
|
+
)}
|
|
187
|
+
{!atEnd && canScroll && (
|
|
188
|
+
<OverflowScrollArrow direction="right" onClick={() => scrollByPage('right')} />
|
|
189
|
+
)}
|
|
190
|
+
</div>
|
|
191
|
+
)
|
|
192
|
+
})
|
|
193
|
+
ScrollChipGroup.displayName = 'ScrollChipGroup'
|
|
194
|
+
|
|
195
|
+
// ── MenuChipGroup ────────────────────────────────────────────────────────────
|
|
196
|
+
// Show-all navigator pattern (Chrome tab dropdown / VS Code editor tabs):
|
|
197
|
+
// - Menu 永遠顯示全部 chips,每個都用 DropdownMenuCheckboxItem + checked 反映 selection
|
|
198
|
+
// - 點 menu item = toggle selection + scrollIntoView,把該 chip 捲到中央
|
|
199
|
+
// - 不用動態 overflow 計算,menu 內容穩定
|
|
200
|
+
//
|
|
201
|
+
// Menu trigger 使用 canonical `<OverflowMenuTriggerButton>`(= Button text sm iconOnly
|
|
202
|
+
// + ChevronDown),跟 Tabs menu trigger 完全同一套——overflow affordance 屬於工具層,
|
|
203
|
+
// 不該用 chip 自己的視覺語言(圓形 outlined)去渲染,否則 mental model 錯誤(使用者
|
|
204
|
+
// 會誤以為是第 N+1 個可選 chip)。
|
|
205
|
+
//
|
|
206
|
+
// 過去 Chip menu trigger 曾用 `chipVariants() + aspect-square + p-0` 做成圓形 pill,
|
|
207
|
+
// 已按 `horizontal-overflow.spec.md` 的 canonical 規則改回 text button。
|
|
208
|
+
//
|
|
209
|
+
// Fade mask 仍保留(reserveArrowWidth: 0),軟化內容硬邊。
|
|
210
|
+
|
|
211
|
+
// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding
|
|
212
|
+
const MenuChipGroup = React.forwardRef<
|
|
213
|
+
HTMLDivElement,
|
|
214
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>
|
|
215
|
+
>(({ className, children, ...props }, ref) => {
|
|
216
|
+
const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges<HTMLDivElement>()
|
|
217
|
+
|
|
218
|
+
// Local ref map — 追蹤每個 chip 的 DOM 元素供 scrollIntoView 使用。
|
|
219
|
+
// 不用 useOverflowIndices 因為 menu 永遠顯示全部, 不需要動態 overflow 計算。
|
|
220
|
+
// code-quality-allow: long-function — helper fn 結構緊密,拆 sub-fn 會跨 fn 傳 state 反而複雜
|
|
221
|
+
const itemRefs = React.useRef<Map<number, HTMLElement>>(new Map())
|
|
222
|
+
// 2026-05-16 audit codex Round 6:capture rAF + cancel on unmount(defensive hygiene)
|
|
223
|
+
const scrollRafIdRef = React.useRef<number>(0)
|
|
224
|
+
React.useEffect(() => () => { if (scrollRafIdRef.current) cancelAnimationFrame(scrollRafIdRef.current) }, [])
|
|
225
|
+
const registerItem = React.useCallback(
|
|
226
|
+
(index: number) => (el: HTMLElement | null) => {
|
|
227
|
+
if (el) itemRefs.current.set(index, el)
|
|
228
|
+
else itemRefs.current.delete(index)
|
|
229
|
+
},
|
|
230
|
+
[]
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
const menuMaskImage = buildFadeMask({ canScroll, atStart, atEnd, reserveArrowWidth: 0 })
|
|
234
|
+
|
|
235
|
+
const items = React.useMemo(
|
|
236
|
+
() => React.Children.toArray(children).filter(React.isValidElement) as React.ReactElement[],
|
|
237
|
+
[children]
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const groupType = (props as { type?: 'single' | 'multiple' }).type ?? 'single'
|
|
241
|
+
const groupValue = (props as { value?: string | string[] }).value
|
|
242
|
+
const groupOnValueChange = (
|
|
243
|
+
props as { onValueChange?: (value: string | string[]) => void }
|
|
244
|
+
).onValueChange
|
|
245
|
+
|
|
246
|
+
// code-quality-allow: long-function — helper fn 結構緊密,拆 sub-fn 會跨 fn 傳 state 反而複雜
|
|
247
|
+
const isSelected = React.useCallback(
|
|
248
|
+
(chipValue: string): boolean => {
|
|
249
|
+
if (groupType === 'multiple') {
|
|
250
|
+
return Array.isArray(groupValue) && groupValue.includes(chipValue)
|
|
251
|
+
}
|
|
252
|
+
return groupValue === chipValue
|
|
253
|
+
},
|
|
254
|
+
[groupType, groupValue]
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
// code-quality-allow: long-function — multi / single / none selection mode each has 事務性 branch,拆 fn 會跨 fn 傳 chipValue/index/groupOnValueChange state 反而難讀
|
|
258
|
+
const toggleFromMenu = React.useCallback(
|
|
259
|
+
(chipValue: string, index: number) => {
|
|
260
|
+
if (!groupOnValueChange) {
|
|
261
|
+
if (import.meta.env?.DEV) {
|
|
262
|
+
console.warn(
|
|
263
|
+
'[ChipGroup] layout="menu" 需要 controlled 使用(請傳 value + onValueChange),否則 menu items 無法同步主 chip 選擇狀態。'
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
if (groupType === 'multiple') {
|
|
269
|
+
const current = (Array.isArray(groupValue) ? groupValue : []) as string[]
|
|
270
|
+
const next = current.includes(chipValue)
|
|
271
|
+
? current.filter((v) => v !== chipValue)
|
|
272
|
+
: [...current, chipValue]
|
|
273
|
+
;(groupOnValueChange as (v: string[]) => void)(next)
|
|
274
|
+
} else {
|
|
275
|
+
;(groupOnValueChange as (v: string) => void)(chipValue)
|
|
276
|
+
}
|
|
277
|
+
// scrollIntoView: 讓剛選中的 chip 出現在視圖中央
|
|
278
|
+
if (scrollRafIdRef.current) cancelAnimationFrame(scrollRafIdRef.current)
|
|
279
|
+
scrollRafIdRef.current = requestAnimationFrame(() => {
|
|
280
|
+
scrollRafIdRef.current = 0
|
|
281
|
+
itemRefs.current.get(index)?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' })
|
|
282
|
+
})
|
|
283
|
+
},
|
|
284
|
+
[groupType, groupValue, groupOnValueChange]
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
const enhancedItems = items.map((child, i) =>
|
|
288
|
+
React.cloneElement(
|
|
289
|
+
child as React.ReactElement<{ ref?: React.Ref<HTMLElement> }>,
|
|
290
|
+
{ ref: registerItem(i) }
|
|
291
|
+
)
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<div className="flex items-center gap-2">
|
|
296
|
+
<div
|
|
297
|
+
ref={scrollRef}
|
|
298
|
+
className="flex-1 min-w-0 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
299
|
+
style={{ maskImage: menuMaskImage, WebkitMaskImage: menuMaskImage }}
|
|
300
|
+
>
|
|
301
|
+
<ToggleGroupPrimitive.Root
|
|
302
|
+
ref={ref}
|
|
303
|
+
className={cn('flex flex-nowrap gap-2 w-fit', className)}
|
|
304
|
+
{...props}
|
|
305
|
+
>
|
|
306
|
+
{enhancedItems}
|
|
307
|
+
</ToggleGroupPrimitive.Root>
|
|
308
|
+
</div>
|
|
309
|
+
{canScroll && (
|
|
310
|
+
<DropdownMenu>
|
|
311
|
+
<DropdownMenuTrigger asChild>
|
|
312
|
+
<OverflowMenuTriggerButton
|
|
313
|
+
aria-label={`選項選單(共 ${items.length} 個)`}
|
|
314
|
+
/>
|
|
315
|
+
</DropdownMenuTrigger>
|
|
316
|
+
<DropdownMenuContent align="end">
|
|
317
|
+
{items.map((chip, index) => {
|
|
318
|
+
const chipProps = chip.props as { value?: string; children?: React.ReactNode; disabled?: boolean }
|
|
319
|
+
const chipValue = chipProps.value
|
|
320
|
+
if (typeof chipValue !== 'string') return null
|
|
321
|
+
return (
|
|
322
|
+
<DropdownMenuCheckboxItem
|
|
323
|
+
key={chipValue}
|
|
324
|
+
checked={isSelected(chipValue)}
|
|
325
|
+
disabled={chipProps.disabled}
|
|
326
|
+
onCheckedChange={() => toggleFromMenu(chipValue, index)}
|
|
327
|
+
>
|
|
328
|
+
{chipProps.children}
|
|
329
|
+
</DropdownMenuCheckboxItem>
|
|
330
|
+
)
|
|
331
|
+
})}
|
|
332
|
+
</DropdownMenuContent>
|
|
333
|
+
</DropdownMenu>
|
|
334
|
+
)}
|
|
335
|
+
</div>
|
|
336
|
+
)
|
|
337
|
+
})
|
|
338
|
+
MenuChipGroup.displayName = 'MenuChipGroup'
|
|
339
|
+
|
|
340
|
+
// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
|
|
341
|
+
// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
|
|
342
|
+
export const chipMeta = {
|
|
343
|
+
component: 'Chip',
|
|
344
|
+
family: 3,
|
|
345
|
+
variants: {
|
|
346
|
+
|
|
347
|
+
},
|
|
348
|
+
sizes: {
|
|
349
|
+
|
|
350
|
+
},
|
|
351
|
+
states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
|
|
352
|
+
tokens: {
|
|
353
|
+
bg: ['bg-primary-subtle', 'bg-surface'],
|
|
354
|
+
fg: ['text-fg-disabled', 'text-fg-secondary', 'text-foreground'],
|
|
355
|
+
ring: ['ring-ring'],
|
|
356
|
+
},
|
|
357
|
+
} as const
|
|
358
|
+
|
|
359
|
+
export { Chip, ChipGroup, chipVariants }
|