@qijenchen/design-system 0.1.0-beta.85 → 0.1.0-beta.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +210 -0
- package/CLAUDE.md +17 -191
- package/cli-init.mjs +30 -2
- package/dist/components/Accordion/accordion.d.ts +2 -2
- package/dist/components/Accordion/accordion.d.ts.map +1 -1
- package/dist/components/Accordion/accordion.js.map +1 -1
- package/dist/components/Avatar/avatar.js +1 -1
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
- package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
- package/dist/components/Button/button-group.d.ts +2 -2
- package/dist/components/Button/button-group.d.ts.map +1 -1
- package/dist/components/Button/button-group.js +2 -2
- package/dist/components/Button/button-group.js.map +1 -1
- package/dist/components/Button/button.d.ts +2 -1
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +1 -1
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Carousel/carousel.d.ts +14 -8
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +64 -37
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox-group.js +21 -14
- package/dist/components/Checkbox/checkbox-group.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +2 -2
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +49 -10
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts +15 -6
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +13 -7
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js +11 -2
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts +5 -5
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +41 -38
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/column-types.d.ts +1 -17
- package/dist/components/DataTable/column-types.d.ts.map +1 -1
- package/dist/components/DataTable/column-types.js.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
- package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +3 -4
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
- package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
- package/dist/components/DataTable/data-table-sort-manager.js +2 -2
- package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +44 -32
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts +3 -3
- package/dist/components/DatePicker/date-picker.js +4 -4
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/DescriptionList/description-list.d.ts +3 -3
- package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
- package/dist/components/DescriptionList/description-list.js +6 -6
- package/dist/components/DescriptionList/description-list.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +2 -2
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +16 -10
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-types.d.ts +2 -2
- package/dist/components/Field/field-types.d.ts.map +1 -1
- package/dist/components/Field/field-types.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts +20 -4
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +30 -31
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +25 -3
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/Field/use-form-validation.d.ts +1 -1
- package/dist/components/Field/use-form-validation.js.map +1 -1
- package/dist/components/FileItem/file-item.d.ts.map +1 -1
- package/dist/components/FileItem/file-item.js +2 -5
- package/dist/components/FileItem/file-item.js.map +1 -1
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
- package/dist/components/FileUpload/file-upload.js +5 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +2 -1
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/HoverCard/hover-card.d.ts +2 -2
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +4 -2
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
- package/dist/components/InlineEdit/inline-edit.js +104 -62
- package/dist/components/InlineEdit/inline-edit.js.map +1 -1
- package/dist/components/Input/input.d.ts +1 -1
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +6 -6
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts +5 -5
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +3 -3
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Notice/notice.d.ts +17 -1
- package/dist/components/Notice/notice.d.ts.map +1 -1
- package/dist/components/Notice/notice.js +7 -1
- package/dist/components/Notice/notice.js.map +1 -1
- package/dist/components/NumberInput/number-input.d.ts +1 -1
- package/dist/components/NumberInput/number-input.d.ts.map +1 -1
- package/dist/components/NumberInput/number-input.js +12 -1
- package/dist/components/NumberInput/number-input.js.map +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
- package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +7 -5
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/PeoplePicker/person-display.d.ts +1 -1
- package/dist/components/PeoplePicker/person-display.js.map +1 -1
- package/dist/components/ProfileCard/profile-card.d.ts +1 -1
- package/dist/components/ProfileCard/profile-card.js.map +1 -1
- package/dist/components/RadioGroup/radio-group.d.ts +3 -3
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +1 -1
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/Rating/rating.d.ts.map +1 -1
- package/dist/components/Rating/rating.js +4 -0
- package/dist/components/Rating/rating.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
- package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
- package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
- package/dist/components/Select/select.d.ts +16 -6
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +17 -5
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +17 -1
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +17 -3
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
- package/dist/components/SelectionControl/boolean-value.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +2 -2
- package/dist/components/Sheet/sheet.d.ts.map +1 -1
- package/dist/components/Sheet/sheet.js.map +1 -1
- package/dist/components/Sidebar/sidebar.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.js +2 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js +6 -3
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Steps/steps.d.ts +6 -4
- package/dist/components/Steps/steps.d.ts.map +1 -1
- package/dist/components/Steps/steps.js +19 -5
- package/dist/components/Steps/steps.js.map +1 -1
- package/dist/components/Switch/switch.d.ts +4 -4
- package/dist/components/Switch/switch.d.ts.map +1 -1
- package/dist/components/Switch/switch.js +3 -1
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +73 -23
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/tag.d.ts +3 -1
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +2 -2
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +4 -4
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +15 -15
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts +4 -4
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +8 -5
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +27 -23
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +16 -0
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/drag-visual.d.ts +2 -2
- package/dist/lib/drag-visual.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +21 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/tokens/categorical-color.d.ts +3 -3
- package/dist/tokens/categorical-color.d.ts.map +1 -1
- package/dist/tokens/categorical-color.js +2 -2
- package/dist/tokens/categorical-color.js.map +1 -1
- package/ds-canonical/fork/AGENTS.md +213 -0
- package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
- package/ds-canonical/fork/codex/hooks.json +16 -0
- package/ds-canonical/fork/governance.lock +22 -7
- package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/fork/manifest.json +10 -1
- package/ds-canonical/fork/preamble.md +3 -2
- package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
- package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
- package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +19 -2
- package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
- package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
- package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
- package/ds-canonical/references/certified-surfaces.md +20 -0
- package/ds-canonical/references/preflight-gate-baseline.json +5 -0
- package/ds-canonical/references/principle-dim-map.json +20 -2
- package/ds-canonical/references/props-naming.md +2 -1
- package/ds-canonical/references/ssot-index.md +2 -2
- package/ds-canonical/references/story-baseline-registry.json +2 -2
- package/ds-canonical/rules/story-rules.md +1 -1
- package/ds-canonical/rules/ui-development.md +2 -1
- package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
- package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
- package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
- package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
- package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
- package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
- package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
- package/ds-story-manifest.json +21 -21
- package/llms-full.txt +3 -3
- package/llms.txt +1 -1
- package/package.json +2 -1
- package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
- package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
- package/src/components/Accordion/accordion.spec.md +10 -1
- package/src/components/Accordion/accordion.stories.tsx +10 -5
- package/src/components/Accordion/accordion.tsx +7 -2
- package/src/components/Alert/alert.principles.stories.tsx +2 -8
- package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
- package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
- package/src/components/AppShell/app-shell.spec.md +4 -0
- package/src/components/AppShell/app-shell.stories.tsx +4 -5
- package/src/components/Avatar/avatar.tsx +1 -1
- package/src/components/Badge/badge.spec.md +2 -2
- package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
- package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
- package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
- package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
- package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
- package/src/components/Button/button-group.tsx +4 -4
- package/src/components/Button/button.anatomy.stories.tsx +26 -7
- package/src/components/Button/button.principles.stories.tsx +1 -1
- package/src/components/Button/button.spec.md +2 -2
- package/src/components/Button/button.stories.tsx +22 -28
- package/src/components/Button/button.tsx +2 -1
- package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
- package/src/components/Calendar/calendar.spec.md +1 -1
- package/src/components/Carousel/carousel.spec.md +17 -1
- package/src/components/Carousel/carousel.tsx +93 -42
- package/src/components/Checkbox/checkbox-group.tsx +26 -15
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
- package/src/components/Checkbox/checkbox.spec.md +12 -3
- package/src/components/Checkbox/checkbox.stories.tsx +4 -4
- package/src/components/Checkbox/checkbox.tsx +79 -19
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
- package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
- package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
- package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
- package/src/components/Combobox/combobox.spec.md +6 -2
- package/src/components/Combobox/combobox.stories.tsx +9 -36
- package/src/components/Combobox/combobox.tsx +42 -27
- package/src/components/Command/command.spec.md +3 -3
- package/src/components/Command/command.tsx +9 -2
- package/src/components/DataTable/cell-registry.tsx +75 -76
- package/src/components/DataTable/column-types.ts +4 -17
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
- package/src/components/DataTable/data-table-filter-panel.tsx +6 -6
- package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
- package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
- package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
- package/src/components/DataTable/data-table.css +2 -3
- package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
- package/src/components/DataTable/data-table.spec.md +8 -7
- package/src/components/DataTable/data-table.stories.tsx +39 -29
- package/src/components/DataTable/data-table.tsx +90 -67
- package/src/components/DataTable/filter-operators.spec.md +2 -0
- package/src/components/DateGrid/date-grid.spec.md +1 -1
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
- package/src/components/DatePicker/date-picker.spec.md +10 -9
- package/src/components/DatePicker/date-picker.stories.tsx +9 -9
- package/src/components/DatePicker/date-picker.tsx +13 -13
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
- package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
- package/src/components/DescriptionList/description-list.spec.md +12 -12
- package/src/components/DescriptionList/description-list.stories.tsx +3 -3
- package/src/components/DescriptionList/description-list.tsx +10 -10
- package/src/components/Dialog/dialog.tsx +4 -1
- package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
- package/src/components/Empty/empty.spec.md +0 -1
- package/src/components/Field/field-context.ts +17 -11
- package/src/components/Field/field-controls.spec.md +46 -37
- package/src/components/Field/field-types.ts +14 -12
- package/src/components/Field/field-wrapper.tsx +59 -43
- package/src/components/Field/field.anatomy.stories.tsx +6 -6
- package/src/components/Field/field.principles.stories.tsx +5 -28
- package/src/components/Field/field.spec.md +5 -4
- package/src/components/Field/field.stories.tsx +103 -72
- package/src/components/Field/field.tsx +36 -4
- package/src/components/Field/form-validation.spec.md +4 -0
- package/src/components/Field/use-form-validation.ts +1 -1
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
- package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
- package/src/components/FileItem/file-item.tsx +10 -8
- package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
- package/src/components/FileUpload/file-upload.spec.md +3 -2
- package/src/components/FileUpload/file-upload.tsx +5 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.spec.md +1 -1
- package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.tsx +3 -2
- package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
- package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
- package/src/components/HoverCard/hover-card.spec.md +2 -2
- package/src/components/HoverCard/hover-card.tsx +4 -2
- package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
- package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
- package/src/components/InlineEdit/inline-edit.spec.md +71 -46
- package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
- package/src/components/InlineEdit/inline-edit.tsx +211 -125
- package/src/components/Input/input.anatomy.stories.tsx +15 -15
- package/src/components/Input/input.principles.stories.tsx +3 -3
- package/src/components/Input/input.spec.md +4 -4
- package/src/components/Input/input.stories.tsx +3 -3
- package/src/components/Input/input.tsx +13 -13
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
- package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
- package/src/components/LinkInput/link-input.spec.md +6 -2
- package/src/components/LinkInput/link-input.stories.tsx +8 -8
- package/src/components/LinkInput/link-input.tsx +21 -19
- package/src/components/Notice/notice.principles.stories.tsx +1 -1
- package/src/components/Notice/notice.tsx +8 -2
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
- package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.spec.md +6 -6
- package/src/components/NumberInput/number-input.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.tsx +17 -5
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
- package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
- package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
- package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
- package/src/components/PeoplePicker/people-picker.tsx +39 -20
- package/src/components/PeoplePicker/person-display.tsx +3 -3
- package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
- package/src/components/Popover/popover.principles.stories.tsx +49 -28
- package/src/components/Popover/popover.spec.md +4 -2
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
- package/src/components/ProfileCard/profile-card.tsx +1 -1
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
- package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
- package/src/components/README.md +1 -0
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
- package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
- package/src/components/RadioGroup/radio-group.tsx +19 -14
- package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
- package/src/components/Rating/rating.principles.stories.tsx +3 -3
- package/src/components/Rating/rating.spec.md +2 -2
- package/src/components/Rating/rating.stories.tsx +4 -18
- package/src/components/Rating/rating.tsx +5 -1
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +1 -1
- package/src/components/ScrollArea/scroll-area.tsx +5 -2
- package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
- package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
- package/src/components/SegmentedControl/segmented-control.tsx +6 -3
- package/src/components/Select/select.anatomy.stories.tsx +13 -7
- package/src/components/Select/select.principles.stories.tsx +3 -3
- package/src/components/Select/select.spec.md +10 -1
- package/src/components/Select/select.stories.tsx +41 -27
- package/src/components/Select/select.tsx +44 -26
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
- package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
- package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
- package/src/components/SelectMenu/select-menu.tsx +38 -5
- package/src/components/SelectionControl/boolean-value.tsx +2 -2
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
- package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
- package/src/components/Separator/separator.principles.stories.tsx +1 -1
- package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
- package/src/components/Sheet/sheet.tsx +4 -1
- package/src/components/Sidebar/sidebar.tsx +1 -1
- package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
- package/src/components/Slider/slider.principles.stories.tsx +6 -6
- package/src/components/Slider/slider.spec.md +13 -1
- package/src/components/Slider/slider.stories.tsx +44 -32
- package/src/components/Slider/slider.tsx +13 -4
- package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
- package/src/components/Steps/steps.principles.stories.tsx +1 -1
- package/src/components/Steps/steps.spec.md +4 -2
- package/src/components/Steps/steps.stories.tsx +4 -56
- package/src/components/Steps/steps.tsx +31 -7
- package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
- package/src/components/Switch/switch.principles.stories.tsx +1 -1
- package/src/components/Switch/switch.spec.md +4 -4
- package/src/components/Switch/switch.stories.tsx +3 -3
- package/src/components/Switch/switch.tsx +16 -10
- package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
- package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
- package/src/components/Tabs/tabs.spec.md +5 -2
- package/src/components/Tabs/tabs.stories.tsx +36 -44
- package/src/components/Tabs/tabs.tsx +101 -36
- package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
- package/src/components/Tag/tag.principles.stories.tsx +4 -4
- package/src/components/Tag/tag.spec.md +4 -1
- package/src/components/Tag/tag.tsx +5 -3
- package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
- package/src/components/Textarea/textarea.spec.md +5 -5
- package/src/components/Textarea/textarea.tsx +24 -24
- package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
- package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
- package/src/components/TimePicker/time-picker.spec.md +6 -5
- package/src/components/TimePicker/time-picker.stories.tsx +3 -3
- package/src/components/TimePicker/time-picker.tsx +24 -14
- package/src/components/Toast/toast.principles.stories.tsx +1 -1
- package/src/components/Toast/toast.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
- package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
- package/src/components/Tooltip/tooltip.spec.md +9 -3
- package/src/components/Tooltip/tooltip.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.tsx +12 -2
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
- package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
- package/src/components/TreeView/tree-view.spec.md +8 -6
- package/src/components/TreeView/tree-view.stories.tsx +9 -43
- package/src/components/TreeView/tree-view.tsx +36 -0
- package/src/index.ts +13 -10
- package/src/lib/drag-visual.ts +2 -2
- package/src/lib/utils.ts +19 -0
- package/src/patterns/action-bar/action-bar.spec.md +1 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
- package/src/patterns/element-anatomy/item-anatomy.spec.md +4 -0
- package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
- package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
- package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
- package/src/tokens/categorical-color.ts +5 -5
- package/src/tokens/color/color.spec.md +4 -4
- package/src/tokens/color/primitives.css +9 -2
- package/src/tokens/motion/motion.spec.md +6 -7
- package/src/tokens/opacity/opacity.spec.md +1 -1
- package/src/tokens/orphan-tokens.spec.md +1 -1
- package/src/tokens/typography/typography.spec.md +2 -0
- package/src/tokens/uiSize/uiSize.css +5 -0
- package/src/tokens/uiSize/uiSize.spec.md +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @story-trait-rationale: AllSizes retired 2026-05-15(anatomy SizeMatrix own size matrix);
|
|
2
2
|
// AllStates retired 2026-05-17 per audit Dim 46(anatomy StateBehavior own state matrix,
|
|
3
3
|
// manual trait grid 違 story-rules.md 三層定位「展示層 = 典型使用情境,不是 trait grid」)。
|
|
4
|
-
// Disabled state 由 FocusRingCombinations 內部展示(disabled + ring combo 正交)。
|
|
5
4
|
import * as React from 'react'
|
|
6
5
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
7
6
|
import { Check } from 'lucide-react'
|
|
@@ -72,7 +71,7 @@ export const Default: Story = {
|
|
|
72
71
|
</p>
|
|
73
72
|
<div>
|
|
74
73
|
<Button variant="secondary" onClick={reset}>
|
|
75
|
-
|
|
74
|
+
再填一份申請
|
|
76
75
|
</Button>
|
|
77
76
|
</div>
|
|
78
77
|
</div>
|
|
@@ -146,60 +145,9 @@ export const Default: Story = {
|
|
|
146
145
|
// AllSizes retired 2026-05-15(anatomy SizeMatrix own);AllStates retired 2026-05-17
|
|
147
146
|
// per Dim 46 audit(anatomy StateBehavior 已 own state matrix,manual trait grid 違反
|
|
148
147
|
// story-rules.md 三層定位「展示層應為典型使用情境,不是 trait grid」)。
|
|
149
|
-
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
export const FocusRingCombinations: Story = {
|
|
154
|
-
name: '聚焦環正交示範',
|
|
155
|
-
render: () => {
|
|
156
|
-
const [value, setValue] = React.useState('step-2')
|
|
157
|
-
return (
|
|
158
|
-
<div className="flex flex-col gap-4 w-[420px]">
|
|
159
|
-
<p className="text-caption text-fg-secondary">
|
|
160
|
-
點任何 step 看看 ring 如何獨立於底色——ring 表達「使用者在這步」,底色
|
|
161
|
-
表達「這步的狀態」。兩者正交。
|
|
162
|
-
</p>
|
|
163
|
-
<div className="flex gap-2">
|
|
164
|
-
{['step-1', 'step-2', 'step-3', 'step-4'].map(v => (
|
|
165
|
-
<Button
|
|
166
|
-
key={v}
|
|
167
|
-
size="sm"
|
|
168
|
-
variant={value === v ? 'primary' : 'secondary'}
|
|
169
|
-
onClick={() => setValue(v)}
|
|
170
|
-
>
|
|
171
|
-
value={v}
|
|
172
|
-
</Button>
|
|
173
|
-
))}
|
|
174
|
-
</div>
|
|
175
|
-
<Steps
|
|
176
|
-
value={value}
|
|
177
|
-
onValueChange={setValue}
|
|
178
|
-
completedValues={['step-1', 'step-3']}
|
|
179
|
-
errorValues={['step-4']}
|
|
180
|
-
linear={false}
|
|
181
|
-
>
|
|
182
|
-
<StepItem value="step-1">
|
|
183
|
-
<StepLabel>Completed</StepLabel>
|
|
184
|
-
<StepDescription>藍底 ✓ + ring(若 focused)</StepDescription>
|
|
185
|
-
</StepItem>
|
|
186
|
-
<StepItem value="step-2">
|
|
187
|
-
<StepLabel>Current</StepLabel>
|
|
188
|
-
<StepDescription>中性底(bg-secondary)數字 + ring(若 focused)</StepDescription>
|
|
189
|
-
</StepItem>
|
|
190
|
-
<StepItem value="step-3">
|
|
191
|
-
<StepLabel>Completed</StepLabel>
|
|
192
|
-
<StepDescription>藍底 ✓ + ring(若 focused)</StepDescription>
|
|
193
|
-
</StepItem>
|
|
194
|
-
<StepItem value="step-4">
|
|
195
|
-
<StepLabel>Error</StepLabel>
|
|
196
|
-
<StepDescription>紅底 ✕ + 紅 ring(若 focused)</StepDescription>
|
|
197
|
-
</StepItem>
|
|
198
|
-
</Steps>
|
|
199
|
-
</div>
|
|
200
|
-
)
|
|
201
|
-
},
|
|
202
|
-
}
|
|
148
|
+
// FocusRingCombinations retired 2026-07-17 per Dim 24 audit — ring⊥state 正交規則已由
|
|
149
|
+
// principles「規則:環是聚焦標記,不是選取」live own(completed+ring / error+ring 兩例);
|
|
150
|
+
// 互動式聚焦移動於「預設」「非線性」既有 clickable steps 已可見,展示層不重複原則 grid。
|
|
203
151
|
|
|
204
152
|
// ── Non-linear ──────────────────────────────────────────────────────────
|
|
205
153
|
|
|
@@ -175,6 +175,11 @@ export interface StepsProps
|
|
|
175
175
|
orientation?: StepsOrientation
|
|
176
176
|
expansion?: StepsExpansion
|
|
177
177
|
defaultExpanded?: 'all' | 'none' | string[]
|
|
178
|
+
/** Controlled 展開集合(2026-07-18 user 拍板補完整雙向控制,對齊 TreeView expandedIds + Radix/MUI/Ant Accordion)。
|
|
179
|
+
* 傳入則由 consumer 掌控展開狀態(與 `defaultExpanded` 二選一);toggle 時經 `onExpandedChange` 回寫。 */
|
|
180
|
+
expanded?: string[]
|
|
181
|
+
/** Controlled 展開變更回呼(展開/收合 step 時觸發,回傳新的展開值陣列)。 */
|
|
182
|
+
onExpandedChange?: (expanded: string[]) => void
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding
|
|
@@ -191,6 +196,8 @@ const Steps = React.forwardRef<HTMLOListElement, StepsProps>(
|
|
|
191
196
|
orientation = 'vertical',
|
|
192
197
|
expansion = 'follow-active',
|
|
193
198
|
defaultExpanded,
|
|
199
|
+
expanded: expandedProp,
|
|
200
|
+
onExpandedChange,
|
|
194
201
|
className,
|
|
195
202
|
children,
|
|
196
203
|
...props
|
|
@@ -229,18 +236,30 @@ const Steps = React.forwardRef<HTMLOListElement, StepsProps>(
|
|
|
229
236
|
[childValues, completedValues],
|
|
230
237
|
)
|
|
231
238
|
|
|
232
|
-
|
|
239
|
+
// Controlled(expandedProp 傳入)/ uncontrolled(defaultExpanded 初值)dual-mode(2026-07-18)。
|
|
240
|
+
const isExpandedControlled = expandedProp !== undefined
|
|
241
|
+
const [expandedInternal, setExpandedInternal] = React.useState<Set<string>>(() =>
|
|
233
242
|
normalizeExpanded(defaultExpanded, childValues),
|
|
234
243
|
)
|
|
244
|
+
const expandedSet = isExpandedControlled ? new Set(expandedProp) : expandedInternal
|
|
235
245
|
|
|
236
246
|
const toggleExpanded = React.useCallback((itemValue: string) => {
|
|
237
|
-
|
|
247
|
+
const compute = (prev: Set<string>) => {
|
|
238
248
|
const next = new Set(prev)
|
|
239
249
|
if (next.has(itemValue)) next.delete(itemValue)
|
|
240
250
|
else next.add(itemValue)
|
|
241
251
|
return next
|
|
242
|
-
}
|
|
243
|
-
|
|
252
|
+
}
|
|
253
|
+
if (isExpandedControlled) {
|
|
254
|
+
onExpandedChange?.([...compute(new Set(expandedProp))])
|
|
255
|
+
} else {
|
|
256
|
+
setExpandedInternal(prev => {
|
|
257
|
+
const next = compute(prev)
|
|
258
|
+
onExpandedChange?.([...next])
|
|
259
|
+
return next
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
}, [isExpandedControlled, expandedProp, onExpandedChange])
|
|
244
263
|
|
|
245
264
|
const stepCount = React.Children.count(children)
|
|
246
265
|
|
|
@@ -304,13 +323,15 @@ Steps.displayName = 'Steps'
|
|
|
304
323
|
|
|
305
324
|
// ── StepItem ──────────────────────────────────────────────────────────────
|
|
306
325
|
|
|
326
|
+
// Steps 內部 cloneElement 注入用的私有 props — 刻意「不」併入公開 StepItemProps:
|
|
327
|
+
// dunder 內部欄位不進 root API(consumer 無合法理由手動控制末項 connector / 間距),
|
|
328
|
+
// 也就不會被 barrel 匯出成公開型別。StepItem render body 以 intersection cast 內部讀取。
|
|
307
329
|
interface StepItemInjectedProps {
|
|
308
330
|
__isLast?: boolean
|
|
309
331
|
}
|
|
310
332
|
|
|
311
333
|
export interface StepItemProps
|
|
312
|
-
extends Omit<React.HTMLAttributes<HTMLLIElement>, 'value'
|
|
313
|
-
StepItemInjectedProps {
|
|
334
|
+
extends Omit<React.HTMLAttributes<HTMLLIElement>, 'value'> {
|
|
314
335
|
value: string
|
|
315
336
|
state?: 'error'
|
|
316
337
|
disabled?: boolean
|
|
@@ -336,7 +357,10 @@ const stepItemVariants = cva('group/step-item outline-none', {
|
|
|
336
357
|
|
|
337
358
|
// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding
|
|
338
359
|
const StepItem = React.forwardRef<HTMLLIElement, StepItemProps>(
|
|
339
|
-
({ value, state: stateOverride, disabled = false, children, className,
|
|
360
|
+
({ value, state: stateOverride, disabled = false, children, className, ...restProps }, ref) => {
|
|
361
|
+
// __isLast 由 Steps root 經 cloneElement 私下注入(見 StepItemInjectedProps);以 intersection
|
|
362
|
+
// cast 從 rest 讀出後解構掉,確保 dunder 不落到 DOM li,也不必污染公開 StepItemProps。
|
|
363
|
+
const { __isLast = false, ...props } = restProps as typeof restProps & StepItemInjectedProps
|
|
340
364
|
const steps = useStepsContext()
|
|
341
365
|
const state = computeState(
|
|
342
366
|
value,
|
|
@@ -38,7 +38,7 @@ export const Overview: Story = {
|
|
|
38
38
|
<thead><tr><Th>Prop</Th><Th>Type</Th><Th>Default</Th><Th>說明</Th></tr></thead>
|
|
39
39
|
<tbody>
|
|
40
40
|
{[
|
|
41
|
-
['mode', "'edit' | '
|
|
41
|
+
['mode', "'edit' | 'view' | 'readonly' | 'disabled'", "'edit'", 'Field mode(默認 inherit Field context 或 edit);view 渲純展示 勾/叉 icon,語意由 context 提供'],
|
|
42
42
|
['size', "'sm' | 'md' | 'lg'", "'md'", '對齊 field size tier(sm 跟 md 視覺相同)'],
|
|
43
43
|
['checked / defaultChecked', 'boolean', '—', 'ON/OFF 狀態(受控 / 非受控)'],
|
|
44
44
|
['onCheckedChange', '(checked: boolean) => void', '—', '切換 callback'],
|
|
@@ -77,8 +77,8 @@ export const Inspector: InspectorStory = {
|
|
|
77
77
|
argTypes: {
|
|
78
78
|
mode: {
|
|
79
79
|
control: 'radio',
|
|
80
|
-
options: ['edit', '
|
|
81
|
-
description: 'Field mode;
|
|
80
|
+
options: ['edit', 'view', 'readonly', 'disabled'],
|
|
81
|
+
description: 'Field mode;view 渲純展示 勾/叉 icon(語意由 context 提供)',
|
|
82
82
|
},
|
|
83
83
|
size: {
|
|
84
84
|
control: 'radio',
|
|
@@ -116,7 +116,7 @@ export const UsageGuidance: Story = {
|
|
|
116
116
|
|
|
117
117
|
<Rule
|
|
118
118
|
title="使用場景對照"
|
|
119
|
-
note="Readonly(standalone settings list):值重要、視覺不能弱化。表單 readonly = Field 內灰框 + 勾/叉 icon(2026-06-12 拍板);DataTable cell 非編輯態 = mode
|
|
119
|
+
note="Readonly(standalone settings list):值重要、視覺不能弱化。表單 readonly = Field 內灰框 + 勾/叉 icon(2026-06-12 拍板);DataTable cell 非編輯態 = mode view。Disabled:外部條件造成暫時不可用(方案限制、權限不足)——傳達「現在用不到」"
|
|
120
120
|
>
|
|
121
121
|
<Label>兩者都不可切換、不在 tab order 內(standalone),機制不同:readonly 用 `pointer-events-none`(視覺正常);disabled 走 native `disabled` + `cursor-not-allowed`(降透明度)。Field 內 readonly 灰框則可聚焦(tabIndex=0)</Label>
|
|
122
122
|
</Rule>
|
|
@@ -104,7 +104,7 @@ sm 和 md 視覺相同(純粹命名 mapping,讓消費者可直接傳同一
|
|
|
104
104
|
| ON | `bg-primary` | 白色 + 2px primary border | primary check |
|
|
105
105
|
| Disabled | 套 `opacity-disabled`(整體透明度降級) | 同 ON/OFF | 同 ON/OFF |
|
|
106
106
|
| Readonly(standalone)| 視覺同一般態 | 但 `pointer-events-none` + click guard + `aria-readonly` | — |
|
|
107
|
-
| Readonly(Field 內,2026-06-12 user 拍板)| 不渲染 toggle — 改渲染 `fieldWrapperStyles` readonly 灰框(= Input readonly 同源)+ 勾/叉 icon(
|
|
107
|
+
| Readonly(Field 內,2026-06-12 user 拍板)| 不渲染 toggle — 改渲染 `fieldWrapperStyles` readonly 灰框(= Input readonly 同源)+ 勾/叉 icon(view 同款值語言) | role="switch" + aria-checked + aria-readonly + 可 focus | — |
|
|
108
108
|
|
|
109
109
|
### Disabled 用 `opacity`
|
|
110
110
|
|
|
@@ -129,13 +129,13 @@ sm 和 md 視覺相同(純粹命名 mapping,讓消費者可直接傳同一
|
|
|
129
129
|
| Tab 焦點 | 不在 tab order | 不在 tab order |
|
|
130
130
|
| 用途 | settings list 鎖定呈現 | 外部條件造成不可操作 |
|
|
131
131
|
|
|
132
|
-
表單 readonly 呈現 = Field 內灰框 + 勾/叉 icon(2026-06-12 拍板);DataTable cell 非編輯態 = `mode="
|
|
132
|
+
表單 readonly 呈現 = Field 內灰框 + 勾/叉 icon(2026-06-12 拍板);DataTable cell 非編輯態 = `mode="view"`(勾/叉 icon),皆非本表 standalone readonly。
|
|
133
133
|
|
|
134
134
|
### `mode` prop(Field mode,正交於 size)
|
|
135
135
|
|
|
136
|
-
`mode?: 'edit' | '
|
|
136
|
+
`mode?: 'edit' | 'view' | 'readonly' | 'disabled'`(默認 inherit Field context 或 `'edit'`),對齊 `field-types.ts` FieldMode:
|
|
137
137
|
- `edit`(預設)— 可切換的 Switch。
|
|
138
|
-
- `
|
|
138
|
+
- `view` — **純展示**:渲染 勾/叉 icon(非互動 Switch;true=Check / false=X,中性 foreground 色,SSOT = `../SelectionControl/boolean-value.tsx`),語意由 context(如 DataTable boolean cell 的行/列 header)提供,對齊 Carbon read-only / Input·Select·Textarea view mode 一致。<!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
|
|
139
139
|
- `readonly` — **Field 內** = 灰框 + 勾/叉 icon(消費 `fieldWrapperStyles` readonly,與 Input readonly 同一視覺語言;世界級:Salesforce output ✓ glyph / SAP 靜態文字 — readonly 下 boolean 是資料 value 非控件);**standalone** = 正常色鎖互動(settings list 場景)。
|
|
140
140
|
- `disabled` — 同上表「Readonly vs Disabled」(opacity 弱化);`mode='disabled'` 直傳與 `disabled` prop 等效(effectiveDisabled,2026-06-12)。
|
|
141
141
|
|
|
@@ -20,9 +20,9 @@ export const Modes: Story = {
|
|
|
20
20
|
<Switch defaultChecked aria-label="啟用通知(edit mode demo)" />
|
|
21
21
|
</div>
|
|
22
22
|
<div>
|
|
23
|
-
<h3 className="text-body font-bold text-foreground mb-2">
|
|
24
|
-
<Switch mode="
|
|
25
|
-
<p className="text-caption text-fg-muted mt-1">純視覺 勾/叉 icon;語意由 context(如 DataTable 表頭 + 行標籤)提供,
|
|
23
|
+
<h3 className="text-body font-bold text-foreground mb-2">view</h3>
|
|
24
|
+
<Switch mode="view" checked />
|
|
25
|
+
<p className="text-caption text-fg-muted mt-1">純視覺 勾/叉 icon;語意由 context(如 DataTable 表頭 + 行標籤)提供,view 不暴露獨立 aria-label。需螢幕報讀器可讀請用 edit / readonly。</p>
|
|
26
26
|
</div>
|
|
27
27
|
<div>
|
|
28
28
|
<h3 className="text-body font-bold text-foreground mb-2">readonly</h3>
|
|
@@ -96,7 +96,11 @@ const SPECS: Record<string, { thumb: number; check: number; checkStroke: number
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
export interface SwitchProps
|
|
99
|
-
|
|
99
|
+
// asChild / children 從公開型別 Omit(2026-07-18 決策2):Switch 固定 anatomy —
|
|
100
|
+
// 恆渲染 Thumb + BooleanValueIcon,非 Slot host;children 被固定 Thumb 靜默覆蓋,
|
|
101
|
+
// asChild(Radix Slot 單子節點)破壞 track/thumb 結構(CLAUDE.md 失敗記憶「asChild ? Slot」)。
|
|
102
|
+
// 對齊 Checkbox 同款收窄(sibling selection control)。
|
|
103
|
+
extends Omit<React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>, 'asChild' | 'children'>,
|
|
100
104
|
VariantProps<typeof switchVariants> {
|
|
101
105
|
/**
|
|
102
106
|
* Inline label。提供時 Switch 自動包一個 <label> 並連結 htmlFor,
|
|
@@ -113,15 +117,15 @@ export interface SwitchProps
|
|
|
113
117
|
/**
|
|
114
118
|
* readonly 模式:standalone = 鎖定互動但維持 ON/OFF 視覺;Field 內 = 灰框 + 勾/叉 icon。
|
|
115
119
|
* 與 disabled 的差異:readonly 不降色(可讀),disabled 降色(弱化)。
|
|
116
|
-
* DataTable cell 非編輯態用 mode="
|
|
120
|
+
* DataTable cell 非編輯態用 mode="view"(勾/叉 icon),非 readOnly。
|
|
117
121
|
*/
|
|
118
122
|
readOnly?: boolean
|
|
119
123
|
/**
|
|
120
124
|
* Field mode(2026-05-05 Phase B3 align):
|
|
121
125
|
* edit — 一般可互動 Switch(預設)
|
|
122
|
-
*
|
|
126
|
+
* view — **純展示**:渲染 勾/叉 icon(無互動 primitive、無 input chrome);
|
|
123
127
|
* 對齊 Carbon read-only / DataTable boolean cell。
|
|
124
|
-
* `
|
|
128
|
+
* `view` 完全無 toggle 形體;`readonly` 視場景(field-types.ts)。
|
|
125
129
|
* readonly — standalone 同 readOnly prop(保留視覺鎖互動);Field 內 = 灰框 + 勾/叉 icon
|
|
126
130
|
* disabled — 同 disabled prop
|
|
127
131
|
*/
|
|
@@ -158,7 +162,7 @@ const Switch = React.forwardRef<
|
|
|
158
162
|
|
|
159
163
|
// Field context 偵測:在 Field 內時忽略自己的 label/description,避免雙層
|
|
160
164
|
// 2026-05-31 #35:hooks(useFieldContext / useId)必在任何 conditional return 前呼叫(Rules of Hooks)。
|
|
161
|
-
// 原 mode='
|
|
165
|
+
// 原 mode='view' early return 寫在 hooks 之上 → runtime 切 mode 會 hook count 不一致 crash;已下移至 hooks 後。
|
|
162
166
|
const fieldCtx = useFieldContext()
|
|
163
167
|
// 2026-06-08 SSOT:<Field disabled>/<Field mode> cascade(原 disabled/mode 直傳 prop,漏 fieldCtx)
|
|
164
168
|
const disabled = useResolvedFieldDisabled(disabledProp)
|
|
@@ -184,7 +188,7 @@ const Switch = React.forwardRef<
|
|
|
184
188
|
const generatedId = React.useId()
|
|
185
189
|
const inputId = idProp ?? fieldCtx?.id ?? generatedId
|
|
186
190
|
|
|
187
|
-
// 2026-07-04 修:
|
|
191
|
+
// 2026-07-04 修:view / readonly-in-Field 分支的裸 span/div 原丟棄剩餘 props
|
|
188
192
|
// (id/data-*/aria-*)且不轉發 forwardRef ref → consumer 的 aria-label 等靜默失效。
|
|
189
193
|
// 抽出 Radix 專屬 non-DOM props,其餘 DOM props 於兩分支 spread 轉發(與 Checkbox/
|
|
190
194
|
// RadioGroup 同修);edit 主路徑不受影響(rootEl 仍 spread 完整 props)。
|
|
@@ -198,12 +202,14 @@ const Switch = React.forwardRef<
|
|
|
198
202
|
asChild: _asChild,
|
|
199
203
|
children: _children,
|
|
200
204
|
...restDomProps
|
|
201
|
-
|
|
205
|
+
// asChild/children 已從 SwitchProps 型別 Omit(見型別註解);此處 cast 保留 runtime strip
|
|
206
|
+
// (防 any-cast consumer 洩漏到 primitive),與 RadioGroup 同款防禦。
|
|
207
|
+
} = props as SwitchProps & { asChild?: boolean; children?: React.ReactNode }
|
|
202
208
|
|
|
203
|
-
// ── mode='
|
|
204
|
-
// 純展示模式:無互動 toggle、渲染 Check / X icon。與 Checkbox
|
|
209
|
+
// ── mode='view'(下移至所有 hooks 之後,per #35 Rules of Hooks)──────────
|
|
210
|
+
// 純展示模式:無互動 toggle、渲染 Check / X icon。與 Checkbox view 對齊(同 boolean primitive,
|
|
205
211
|
// 共用 SelectionControl/boolean-value.tsx SSOT — 勾/叉 icon + 中性 foreground 色)。
|
|
206
|
-
if (resolvedMode === '
|
|
212
|
+
if (resolvedMode === 'view') {
|
|
207
213
|
const isChecked = checkedProp === true
|
|
208
214
|
return (
|
|
209
215
|
<span {...restDomProps} ref={ref as React.Ref<HTMLSpanElement>} className="inline-flex">
|
|
@@ -54,6 +54,7 @@ export const Overview: Story = {
|
|
|
54
54
|
</TabsTrigger>
|
|
55
55
|
<TabsTrigger value="settings" startIcon={Settings}>設定</TabsTrigger>
|
|
56
56
|
</TabsList>
|
|
57
|
+
<TabsContent value="files" className="text-body text-fg-secondary">專案文件與附件清單</TabsContent>
|
|
57
58
|
</Tabs>
|
|
58
59
|
</div>
|
|
59
60
|
</div>
|
|
@@ -213,6 +214,7 @@ export const SizeMatrix: Story = {
|
|
|
213
214
|
<TabsTrigger value="b">成員</TabsTrigger>
|
|
214
215
|
<TabsTrigger value="c">設定</TabsTrigger>
|
|
215
216
|
</TabsList>
|
|
217
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">專案的總覽資訊(KPI、最近活動)</TabsContent>
|
|
216
218
|
</Tabs>
|
|
217
219
|
</div>
|
|
218
220
|
</div>
|
|
@@ -297,6 +299,7 @@ export const ColorMatrix: Story = {
|
|
|
297
299
|
</TabsTrigger>
|
|
298
300
|
<TabsTrigger value="settings" startIcon={Settings}>設定</TabsTrigger>
|
|
299
301
|
</TabsList>
|
|
302
|
+
<TabsContent value="members" className="text-body text-fg-secondary mt-2">成員名單(3 人待邀請)</TabsContent>
|
|
300
303
|
</Tabs>
|
|
301
304
|
</div>
|
|
302
305
|
</div>
|
|
@@ -319,6 +322,7 @@ export const StateBehavior: Story = {
|
|
|
319
322
|
<TabsTrigger value="notifications">通知</TabsTrigger>
|
|
320
323
|
<TabsTrigger value="settings" disabled>設定</TabsTrigger>
|
|
321
324
|
</TabsList>
|
|
325
|
+
<TabsContent value="overview" className="text-body text-fg-secondary mt-2">專案的總覽資訊(KPI、最近活動)</TabsContent>
|
|
322
326
|
</Tabs>
|
|
323
327
|
</div>
|
|
324
328
|
<p className="text-footnote text-fg-muted mt-3">
|
|
@@ -350,6 +354,7 @@ export const OverflowMatrix: Story = {
|
|
|
350
354
|
<TabsTrigger value="g">計費</TabsTrigger>
|
|
351
355
|
<TabsTrigger value="h">安全性</TabsTrigger>
|
|
352
356
|
</TabsList>
|
|
357
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">工作區總覽(成員、方案、近期活動)</TabsContent>
|
|
353
358
|
</Tabs>
|
|
354
359
|
</div>
|
|
355
360
|
</div>
|
|
@@ -371,6 +376,7 @@ export const OverflowMatrix: Story = {
|
|
|
371
376
|
<TabsTrigger value="g">計費</TabsTrigger>
|
|
372
377
|
<TabsTrigger value="h">安全性</TabsTrigger>
|
|
373
378
|
</TabsList>
|
|
379
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">工作區總覽(成員、方案、近期活動)</TabsContent>
|
|
374
380
|
</Tabs>
|
|
375
381
|
</div>
|
|
376
382
|
</div>
|
|
@@ -121,7 +121,10 @@ export const UsageGuidance: Story = {
|
|
|
121
121
|
<TabsTrigger value="products">產品</TabsTrigger>
|
|
122
122
|
<TabsTrigger value="settings">設定</TabsTrigger>
|
|
123
123
|
</TabsList>
|
|
124
|
-
<TabsContent value="orders" className="text-body text-fg-muted">
|
|
124
|
+
<TabsContent value="orders" className="text-body text-fg-muted">1,284 筆訂單 · 篩選「待出貨」· 批次列印出貨單</TabsContent>
|
|
125
|
+
<TabsContent value="customers" className="text-body text-fg-muted">顧客名單、分群標籤與生命週期價值</TabsContent>
|
|
126
|
+
<TabsContent value="products" className="text-body text-fg-muted">商品目錄、庫存與上下架狀態</TabsContent>
|
|
127
|
+
<TabsContent value="settings" className="text-body text-fg-muted">商店設定:金流、物流、稅率</TabsContent>
|
|
125
128
|
</Tabs>
|
|
126
129
|
</div>
|
|
127
130
|
<div>
|
|
@@ -191,6 +194,7 @@ export const SizeSelection: Story = {
|
|
|
191
194
|
<TabsTrigger value="a">一般</TabsTrigger>
|
|
192
195
|
<TabsTrigger value="b">進階</TabsTrigger>
|
|
193
196
|
</TabsList>
|
|
197
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">名稱、描述與可見範圍等一般設定</TabsContent>
|
|
194
198
|
</Tabs>
|
|
195
199
|
</Rule>
|
|
196
200
|
|
|
@@ -205,6 +209,7 @@ export const SizeSelection: Story = {
|
|
|
205
209
|
<TabsTrigger value="b">成員</TabsTrigger>
|
|
206
210
|
<TabsTrigger value="c" badge={<Badge count={3} />}>通知</TabsTrigger>
|
|
207
211
|
</TabsList>
|
|
212
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">專案的總覽資訊(KPI、最近活動)</TabsContent>
|
|
208
213
|
</Tabs>
|
|
209
214
|
</Rule>
|
|
210
215
|
|
|
@@ -217,6 +222,7 @@ export const SizeSelection: Story = {
|
|
|
217
222
|
<TabsTrigger value="a">產品</TabsTrigger>
|
|
218
223
|
<TabsTrigger value="b">服務</TabsTrigger>
|
|
219
224
|
</TabsList>
|
|
225
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">產品功能、方案與定價總覽</TabsContent>
|
|
220
226
|
</Tabs>
|
|
221
227
|
</Rule>
|
|
222
228
|
</div>
|
|
@@ -231,7 +237,7 @@ export const TriggerSlots: Story = {
|
|
|
231
237
|
<div>
|
|
232
238
|
<Rule
|
|
233
239
|
title="startIcon 描述 tab 的內容性質"
|
|
234
|
-
note="使用名詞性 icon(人像配「成員」、齒輪配「設定」、鈴鐺配「通知」)。不放動詞性 icon(Download、Trash2),tab
|
|
240
|
+
note="使用名詞性 icon(人像配「成員」、齒輪配「設定」、鈴鐺配「通知」)。不放動詞性 icon(Download、Trash2),tab 是視圖切換不是動作觸發。同一組 tabs 內 startIcon 全有或全無、不混用(spec 禁止事項),下方三個 trigger 皆帶 icon 即為「全有」的 uniform 示範"
|
|
235
241
|
>
|
|
236
242
|
<Tabs defaultValue="a">
|
|
237
243
|
<TabsList>
|
|
@@ -239,6 +245,7 @@ export const TriggerSlots: Story = {
|
|
|
239
245
|
<TabsTrigger value="b" startIcon={Settings}>設定</TabsTrigger>
|
|
240
246
|
<TabsTrigger value="c" startIcon={Bell}>通知</TabsTrigger>
|
|
241
247
|
</TabsList>
|
|
248
|
+
<TabsContent value="a" className="text-body text-fg-secondary mt-2">成員名單與角色權限管理</TabsContent>
|
|
242
249
|
</Tabs>
|
|
243
250
|
</Rule>
|
|
244
251
|
|
|
@@ -252,6 +259,7 @@ export const TriggerSlots: Story = {
|
|
|
252
259
|
<TabsTrigger value="unread" badge={<Badge count={12} />}>未讀</TabsTrigger>
|
|
253
260
|
<TabsTrigger value="starred" badge={<Badge count={3} />}>星標</TabsTrigger>
|
|
254
261
|
</TabsList>
|
|
262
|
+
<TabsContent value="inbox" className="text-body text-fg-secondary mt-2">收件匣的所有訊息(依時間排序)</TabsContent>
|
|
255
263
|
</Tabs>
|
|
256
264
|
</Rule>
|
|
257
265
|
</div>
|
|
@@ -86,7 +86,9 @@ TabsContent ← 對應被選中的 trigger
|
|
|
86
86
|
- `startIcon` 描述 tab 的內容性質(人像 icon 配「成員」、齒輪 icon 配「設定」)
|
|
87
87
|
- `badge` 傳達該 tab 底下的待處理計數(「通知 3」「成員 12」)
|
|
88
88
|
- `endIcon` **純視覺 indicator only**(方向 / 狀態 — ChevronDown 暗示「展開後看到子內容」、Pin / Star 狀態徽記)。**不拼 click 行為** — 點到 endIcon 跟點到 tab body 同效果(切 tab)
|
|
89
|
-
- `inlineAction`(2026-05-21 加)拆分 click target:點到 inlineAction 走它自己的 handler 不切 tab;典型如「『更多 ▾』tab 後綴點開 overflow dropdown 不切 tab」(split-click pattern,對齊 GitHub「Code ▾」/ Linear "Triage..." menu / Atlassian split-tab
|
|
89
|
+
- `inlineAction`(2026-05-21 加)拆分 click target:點到 inlineAction 走它自己的 handler 不切 tab;典型如「『更多 ▾』tab 後綴點開 overflow dropdown 不切 tab」(split-click pattern,對齊 GitHub「Code ▾」/ Linear "Triage..." menu / Atlassian split-tab 共識)。**DOM 結構(2026-07-18 決策1 axe 正規修)**:inlineAction **portal 到 `TabsList` 的 overlay 層(`role=tablist` 之外的 sibling div)**,以 trigger 的量測座標(viewport-relative,涵蓋 none/scroll/menu)定位在 trigger 右緣預留的 paddingRight 區。**為什麼不放 tablist 內**:`role=tablist` 只能擁有 `role=tab`(ARIA required-children);inlineAction(`button[aria-haspopup]`)DOM-在 tablist 內 = axe critical(2026-07-18 實測確認),故 portal 出去。trigger 本身仍在 tablist 內(Radix roving focus 要求 trigger 為 List React 子代)。**演進史**:2026-07-05 先修 button-巢-button(nested-interactive serious,改 sibling 佈局);2026-07-18 再修 button-在-tablist(required-children critical,改 portal overlay)。**代價(user 2026-07-18 拍板接受)**:鍵盤 Tab 序 = 全部 tab 之後才到 action(action 現為 overlay 內獨立 tab stop)。click 天然分流(action portal 出 trigger 子樹,不冒泡)。<!-- @benchmark-unverified: axe aria-required-children rule 實測(.claude/logs/a11y-audit.json);split-click pattern 對照未逐一 URL cite -->
|
|
90
|
+
|
|
91
|
+
**⚠️ ARIA required-children 鐵律(泛化,防同類 regression)**:任何 composite widget 容器(`role=tablist` / `listbox` / `menu` / `radiogroup` / `tree`)只能擁有其 required child role;要在容器「格子」旁塞獨立互動 element(action / dropdown trigger)時,**必 portal 出容器 DOM 子樹 + 量測定位**(aria-owns 不可行:axe required-children 計 DOM-owned 子代,不因 aria-owns 排除)。對齊 W3C ARIA APG composite-widget owned-elements 規範。
|
|
90
92
|
|
|
91
93
|
### 對標對象與故意的偏離
|
|
92
94
|
|
|
@@ -282,7 +284,8 @@ Tabs anatomy 採 DS 標準結構 + 元件特有矩陣:
|
|
|
282
284
|
|
|
283
285
|
**Focus**:Tabs 為內嵌導覽,不困住焦點(無 focus trap);Radix `tabs` primitive 以 roving tabindex 管理 tab 之間的鍵盤移動(整組 tabs 為單一 tab stop)。選中 tab 與 TabsContent 各有 focus-visible 焦點框(`ring-2 ring-ring` per design-system focus-visible canonical)。
|
|
284
286
|
|
|
285
|
-
**驗證**:
|
|
287
|
+
**驗證**:Tabs 元件**自身結構** axe 0 critical(nested-interactive + aria-required-children 皆已修,2026-07-18 實測 `.claude/logs/a11y-audit.json`);鍵盤完整可操作(無需滑鼠)。WCAG AA contrast ≥ 4.5:1(text)/ 3:1(UI)。
|
|
288
|
+
**已知非-Tabs-結構例外(誠實標註,非本元件缺陷)**:(a) `aria-controls` 指向未掛載的 inactive `TabsContent` = Radix 內建行為(inactive panel 預設 unmount → IDREF 懸空,axe `aria-valid-attr-value` flag);要消除需 `forceMount` 全 panel(有 perf 取捨,屬另案)。(b) story 內 demo 內容的 color-contrast / DataTable 巢狀(appshell story)非 Tabs 元件 own — 屬各自 owner。
|
|
286
289
|
|
|
287
290
|
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
288
291
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// @story-trait-rationale: hasSizes 由 anatomy.stories.tsx SizeMatrix
|
|
1
|
+
// @story-trait-rationale: hasSizes 由 anatomy.stories.tsx SizeMatrix owns size showcase;hasInteractiveStates 由 anatomy.stories.tsx StateBehavior owns(展示層 Disabled + AllWithStartIcon story 2026-07-17 Dim 24 retire — 分別與 anatomy StateBehavior disabled 列 / Overview startIcon slot + principles TriggerSlots 全 icon 示範重複)。
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
3
|
-
import {
|
|
3
|
+
import { ChevronDown, Archive, Pin, EyeOff } from 'lucide-react'
|
|
4
4
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from './tabs'
|
|
5
5
|
import { Badge } from '@/design-system/components/Badge/badge'
|
|
6
6
|
import { ItemInlineActionButton } from '@/design-system/patterns/element-anatomy/item-anatomy'
|
|
@@ -75,24 +75,29 @@ export const WithSuffix: Story = {
|
|
|
75
75
|
更多
|
|
76
76
|
</TabsTrigger>
|
|
77
77
|
</TabsList>
|
|
78
|
+
<TabsContent value="all" className="text-body text-fg-secondary">全部訊息(通知、提及、系統公告)</TabsContent>
|
|
79
|
+
<TabsContent value="notifications" className="text-body text-fg-secondary">12 則未讀通知(含 3 則需要你回覆)</TabsContent>
|
|
80
|
+
<TabsContent value="more" className="text-body text-fg-secondary">已封存與已釘選的通知</TabsContent>
|
|
78
81
|
</Tabs>
|
|
79
82
|
),
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
85
|
+
// AllWithStartIcon story 2026-07-17 Dim 24 retire — 「全 trigger 帶 startIcon」的 uniform visual
|
|
86
|
+
// 已由 anatomy Overview「Trigger 內部結構」slot(全帶 icon)+ principles TriggerSlots(startIcon 全有全無 rule)
|
|
87
|
+
// 完整覆蓋,單獨一則展示屬重複。#4 startIcon 全有全無 rule 語意保留在 TriggerSlots note。
|
|
88
|
+
|
|
89
|
+
// 工作區設定頁的 8 個分頁 — OverflowScroll / OverflowMenu 共用(narrow 320px 容器強制觸發溢出);
|
|
90
|
+
// 每個 trigger 都有對應 TabsContent,是完整可切換的真實設定頁(非只有 TabsList 的空殼)。
|
|
91
|
+
const workspaceSettingsTabs = [
|
|
92
|
+
{ value: 'overview', label: '總覽', content: '工作區總覽(成員、方案、近期活動)' },
|
|
93
|
+
{ value: 'members', label: '成員', content: '成員名單與角色權限管理' },
|
|
94
|
+
{ value: 'projects', label: '專案設定', content: '專案預設值與範本' },
|
|
95
|
+
{ value: 'notifications', label: '通知', content: '通知偏好與訂閱範圍' },
|
|
96
|
+
{ value: 'integrations', label: '整合', content: '已連接的第三方服務(Slack、Zoom、Google 日曆)' },
|
|
97
|
+
{ value: 'api', label: 'API', content: 'API 金鑰與 Webhook 設定' },
|
|
98
|
+
{ value: 'billing', label: '計費', content: '訂閱方案與付款方式' },
|
|
99
|
+
{ value: 'security', label: '安全性', content: '雙重驗證與登入裝置管理' },
|
|
100
|
+
] as const
|
|
96
101
|
|
|
97
102
|
export const OverflowScroll: Story = {
|
|
98
103
|
name: '溢出處理 — 水平捲動',
|
|
@@ -102,15 +107,13 @@ export const OverflowScroll: Story = {
|
|
|
102
107
|
<div className="w-[320px] border border-divider rounded-md p-2">
|
|
103
108
|
<Tabs defaultValue="overview">
|
|
104
109
|
<TabsList overflow="scroll">
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<TabsTrigger value="notifications">通知</TabsTrigger>
|
|
109
|
-
<TabsTrigger value="integrations">整合</TabsTrigger>
|
|
110
|
-
<TabsTrigger value="api">API</TabsTrigger>
|
|
111
|
-
<TabsTrigger value="billing">計費</TabsTrigger>
|
|
112
|
-
<TabsTrigger value="security">安全性</TabsTrigger>
|
|
110
|
+
{workspaceSettingsTabs.map((t) => (
|
|
111
|
+
<TabsTrigger key={t.value} value={t.value}>{t.label}</TabsTrigger>
|
|
112
|
+
))}
|
|
113
113
|
</TabsList>
|
|
114
|
+
{workspaceSettingsTabs.map((t) => (
|
|
115
|
+
<TabsContent key={t.value} value={t.value} className="text-body text-fg-secondary mt-2">{t.content}</TabsContent>
|
|
116
|
+
))}
|
|
114
117
|
</Tabs>
|
|
115
118
|
</div>
|
|
116
119
|
),
|
|
@@ -123,15 +126,13 @@ export const OverflowMenu: Story = {
|
|
|
123
126
|
<div className="w-[320px] border border-divider rounded-md p-2">
|
|
124
127
|
<Tabs defaultValue="overview">
|
|
125
128
|
<TabsList overflow="menu">
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
<TabsTrigger value="notifications">通知</TabsTrigger>
|
|
130
|
-
<TabsTrigger value="integrations">整合</TabsTrigger>
|
|
131
|
-
<TabsTrigger value="api">API</TabsTrigger>
|
|
132
|
-
<TabsTrigger value="billing">計費</TabsTrigger>
|
|
133
|
-
<TabsTrigger value="security">安全性</TabsTrigger>
|
|
129
|
+
{workspaceSettingsTabs.map((t) => (
|
|
130
|
+
<TabsTrigger key={t.value} value={t.value}>{t.label}</TabsTrigger>
|
|
131
|
+
))}
|
|
134
132
|
</TabsList>
|
|
133
|
+
{workspaceSettingsTabs.map((t) => (
|
|
134
|
+
<TabsContent key={t.value} value={t.value} className="text-body text-fg-secondary mt-2">{t.content}</TabsContent>
|
|
135
|
+
))}
|
|
135
136
|
</Tabs>
|
|
136
137
|
</div>
|
|
137
138
|
),
|
|
@@ -141,15 +142,6 @@ export const OverflowMenu: Story = {
|
|
|
141
142
|
// OverflowMatrix own;上方兩則「溢出處理」是 320px 窄容器的真實情境示範
|
|
142
143
|
// (2026-05-18 加,user 要求展示層要真的看得到溢出),兩層分工不重複。
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<Tabs defaultValue="a" className="w-[600px]">
|
|
148
|
-
<TabsList>
|
|
149
|
-
<TabsTrigger value="a">可用</TabsTrigger>
|
|
150
|
-
<TabsTrigger value="b" disabled>停用</TabsTrigger>
|
|
151
|
-
<TabsTrigger value="c">可用</TabsTrigger>
|
|
152
|
-
</TabsList>
|
|
153
|
-
</Tabs>
|
|
154
|
-
),
|
|
155
|
-
}
|
|
145
|
+
// Disabled story 2026-07-17 Dim 24 retire — 「可用 / 停用 / 可用」的 disabled 態
|
|
146
|
+
// 已由 anatomy StateBehavior 的 disabled 列(selected / hover / disabled 三態並列)完整覆蓋,
|
|
147
|
+
// 單獨一則展示屬重複。hasInteractiveStates trait 由 anatomy StateBehavior owns(見檔首 rationale)。
|