@qijenchen/design-system 0.1.0-beta.85 → 0.1.0-beta.86
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 +11 -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 +7 -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 +9 -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/Field/field-context.ts +17 -11
- package/src/components/Field/field-controls.spec.md +44 -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 +4 -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 +2 -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 +9 -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 +3 -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/element-anatomy/inline-action.spec.md +1 -1
- 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/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
|
@@ -71,7 +71,7 @@ description: UX behavior audit for design-system components and product UI. Chec
|
|
|
71
71
|
1. **Animation duration**:< 200ms(micro)或 200-400ms(macro);超過 400ms 主畫面 → 可能 block 輸入
|
|
72
72
|
2. **Reduce-motion respect**:`@media (prefers-reduced-motion: reduce)` 下動畫減到 0 或極短
|
|
73
73
|
3. **Wheel zoom step 細緻**:> 10% 離散 = 非世界級(對齊 Figma / Preview.app ~3-5%)
|
|
74
|
-
4. **Hover delay**:tooltip / hover-card 的 open delay(
|
|
74
|
+
4. **Hover delay**:tooltip / hover-card 的 open delay(500ms for tooltip, 700ms for hover-card,per `tokens/motion/motion.spec.md` 三層 tier SSOT)
|
|
75
75
|
5. **Drag / pan**:pointer capture 正確;release on blur
|
|
76
76
|
|
|
77
77
|
### Phase 5 — Data / state coverage 五態(2026-04-24 擴充,補 24-checklist #23 edge case gap)
|
|
@@ -250,4 +250,3 @@ FAIL 項摘要:
|
|
|
250
250
|
- `.claude/skills/component-quality-gate/SKILL.md` — 元件合入 DS 前的 35 項 checklist;Ship phase 可 chain 本 skill
|
|
251
251
|
- .claude/references/ui-dev-rules.md `# 同 flex 列的互動 slot 幾何鐵律` — 本 skill checklist #3 的主要 canonical 來源
|
|
252
252
|
- `.claude/rules/ui-development.md`「建立 UI 前必讀」 → layout primitive / token spec 清單 — 本 skill「合格標準」的對照錨
|
|
253
|
-
- `memory/project_pending_tasks`「視覺 regression 基建」條目 — 長期 tech debt(Chromatic / screenshot-diff)
|
package/ds-story-manifest.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"scripts/composition-fidelity-visual-diff.mjs",
|
|
8
8
|
"product-workspace apps/template/src/AllDsComponents.stories.tsx (ImportSmoke portal → DS Storybook link)"
|
|
9
9
|
],
|
|
10
|
-
"generatedAt": "2026-07-
|
|
10
|
+
"generatedAt": "2026-07-18T09:25:13.585Z"
|
|
11
11
|
},
|
|
12
12
|
"components": {
|
|
13
13
|
"accordion": {
|
|
@@ -190,7 +190,6 @@
|
|
|
190
190
|
"tiers": {
|
|
191
191
|
"展示": [
|
|
192
192
|
"design-system-components-bulkactionbar-展示--default",
|
|
193
|
-
"design-system-components-bulkactionbar-展示--with-filter-hidden",
|
|
194
193
|
"design-system-components-bulkactionbar-展示--with-extend-dataset-hint",
|
|
195
194
|
"design-system-components-bulkactionbar-展示--empty-selection-hidden"
|
|
196
195
|
],
|
|
@@ -419,7 +418,6 @@
|
|
|
419
418
|
"展示": [
|
|
420
419
|
"design-system-components-combobox-展示--modes",
|
|
421
420
|
"design-system-components-combobox-展示--size-alignment",
|
|
422
|
-
"design-system-components-combobox-展示--wrap-modes",
|
|
423
421
|
"design-system-components-combobox-展示--searchable",
|
|
424
422
|
"design-system-components-combobox-展示--in-data-table"
|
|
425
423
|
],
|
|
@@ -561,7 +559,7 @@
|
|
|
561
559
|
"design-system-components-datepicker-展示--show-time-range-popover-open",
|
|
562
560
|
"design-system-components-datepicker-展示--range-middle-hover-state",
|
|
563
561
|
"design-system-components-datepicker-展示--show-time-range",
|
|
564
|
-
"design-system-components-datepicker-展示--
|
|
562
|
+
"design-system-components-datepicker-展示--view"
|
|
565
563
|
],
|
|
566
564
|
"設計規格": [
|
|
567
565
|
"design-system-components-datepicker-設計規格--overview",
|
|
@@ -731,7 +729,6 @@
|
|
|
731
729
|
],
|
|
732
730
|
"設計原則": [
|
|
733
731
|
"design-system-components-field-設計原則--usage-guidance",
|
|
734
|
-
"design-system-components-field-設計原則--responsibility-rule",
|
|
735
732
|
"design-system-components-field-設計原則--orientation-rule",
|
|
736
733
|
"design-system-components-field-設計原則--not-for-form-actions-rule"
|
|
737
734
|
]
|
|
@@ -885,8 +882,19 @@
|
|
|
885
882
|
"design-system-components-inlineedit-展示--multiline-description",
|
|
886
883
|
"design-system-components-inlineedit-展示--vertical-field-form"
|
|
887
884
|
],
|
|
888
|
-
"設計規格": [
|
|
889
|
-
|
|
885
|
+
"設計規格": [
|
|
886
|
+
"design-system-components-inlineedit-設計規格--overview",
|
|
887
|
+
"design-system-components-inlineedit-設計規格--inspector",
|
|
888
|
+
"design-system-components-inlineedit-設計規格--state-behavior",
|
|
889
|
+
"design-system-components-inlineedit-設計規格--in-field-cascade",
|
|
890
|
+
"design-system-components-inlineedit-設計規格--accessibility"
|
|
891
|
+
],
|
|
892
|
+
"設計原則": [
|
|
893
|
+
"design-system-components-inlineedit-設計原則--when-to-use",
|
|
894
|
+
"design-system-components-inlineedit-設計原則--when-not-to-use",
|
|
895
|
+
"design-system-components-inlineedit-設計原則--vs-control-view",
|
|
896
|
+
"design-system-components-inlineedit-設計原則--content-guidelines"
|
|
897
|
+
]
|
|
890
898
|
},
|
|
891
899
|
"openSnapshotIds": [],
|
|
892
900
|
"exception": null
|
|
@@ -926,7 +934,7 @@
|
|
|
926
934
|
"design-system-components-linkinput-展示--validation",
|
|
927
935
|
"design-system-components-linkinput-展示--size-alignment",
|
|
928
936
|
"design-system-components-linkinput-展示--modes",
|
|
929
|
-
"design-system-components-linkinput-展示--
|
|
937
|
+
"design-system-components-linkinput-展示--view"
|
|
930
938
|
],
|
|
931
939
|
"設計規格": [
|
|
932
940
|
"design-system-components-linkinput-設計規格--overview",
|
|
@@ -1028,7 +1036,6 @@
|
|
|
1028
1036
|
"展示": [
|
|
1029
1037
|
"design-system-internal-overflowindicator-展示--combobox-tag-overflow",
|
|
1030
1038
|
"design-system-internal-overflowindicator-展示--avatar-stack-overflow",
|
|
1031
|
-
"design-system-internal-overflowindicator-展示--breadcrumb-collapse",
|
|
1032
1039
|
"design-system-internal-overflowindicator-展示--table-row-assignees"
|
|
1033
1040
|
],
|
|
1034
1041
|
"設計規格": [
|
|
@@ -1196,8 +1203,7 @@
|
|
|
1196
1203
|
"展示": [
|
|
1197
1204
|
"design-system-components-rating-展示--read-only-product-rating",
|
|
1198
1205
|
"design-system-components-rating-展示--interactive-review",
|
|
1199
|
-
"design-system-components-rating-展示--in-field"
|
|
1200
|
-
"design-system-components-rating-展示--disabled"
|
|
1206
|
+
"design-system-components-rating-展示--in-field"
|
|
1201
1207
|
],
|
|
1202
1208
|
"設計規格": [
|
|
1203
1209
|
"design-system-components-rating-設計規格--overview",
|
|
@@ -1271,10 +1277,10 @@
|
|
|
1271
1277
|
"展示": [
|
|
1272
1278
|
"design-system-components-select-展示--modes",
|
|
1273
1279
|
"design-system-components-select-展示--hug-width",
|
|
1274
|
-
"design-system-components-select-展示--display-mode",
|
|
1275
1280
|
"design-system-components-select-展示--size-alignment",
|
|
1276
1281
|
"design-system-components-select-展示--clearable",
|
|
1277
1282
|
"design-system-components-select-展示--searchable",
|
|
1283
|
+
"design-system-components-select-展示--creatable",
|
|
1278
1284
|
"design-system-components-select-展示--in-data-table"
|
|
1279
1285
|
],
|
|
1280
1286
|
"設計規格": [
|
|
@@ -1302,7 +1308,6 @@
|
|
|
1302
1308
|
"design-system-internal-selectmenu-展示--searchable",
|
|
1303
1309
|
"design-system-internal-selectmenu-展示--multi-select",
|
|
1304
1310
|
"design-system-internal-selectmenu-展示--multi-searchable",
|
|
1305
|
-
"design-system-internal-selectmenu-展示--clearable",
|
|
1306
1311
|
"design-system-internal-selectmenu-展示--option-states"
|
|
1307
1312
|
],
|
|
1308
1313
|
"設計規格": [
|
|
@@ -1476,7 +1481,6 @@
|
|
|
1476
1481
|
"tiers": {
|
|
1477
1482
|
"展示": [
|
|
1478
1483
|
"design-system-components-steps-展示--default",
|
|
1479
|
-
"design-system-components-steps-展示--focus-ring-combinations",
|
|
1480
1484
|
"design-system-components-steps-展示--non-linear",
|
|
1481
1485
|
"design-system-components-steps-展示--horizontal",
|
|
1482
1486
|
"design-system-components-steps-展示--multiple-expansion"
|
|
@@ -1531,10 +1535,8 @@
|
|
|
1531
1535
|
"展示": [
|
|
1532
1536
|
"design-system-components-tabs-展示--default",
|
|
1533
1537
|
"design-system-components-tabs-展示--with-suffix",
|
|
1534
|
-
"design-system-components-tabs-展示--all-with-start-icon",
|
|
1535
1538
|
"design-system-components-tabs-展示--overflow-scroll",
|
|
1536
|
-
"design-system-components-tabs-展示--overflow-menu"
|
|
1537
|
-
"design-system-components-tabs-展示--disabled"
|
|
1539
|
+
"design-system-components-tabs-展示--overflow-menu"
|
|
1538
1540
|
],
|
|
1539
1541
|
"設計規格": [
|
|
1540
1542
|
"design-system-components-tabs-設計規格--overview",
|
|
@@ -1629,7 +1631,6 @@
|
|
|
1629
1631
|
"設計原則": [
|
|
1630
1632
|
"design-system-components-timepicker-設計原則--usage-guidance",
|
|
1631
1633
|
"design-system-components-timepicker-設計原則--rule-minute-step-for-meetings",
|
|
1632
|
-
"design-system-components-timepicker-設計原則--rule-range-composition",
|
|
1633
1634
|
"design-system-components-timepicker-設計原則--rule-clear-no-label-button"
|
|
1634
1635
|
]
|
|
1635
1636
|
},
|
|
@@ -1688,8 +1689,7 @@
|
|
|
1688
1689
|
"design-system-components-treeview-展示--stepper",
|
|
1689
1690
|
"design-system-components-treeview-展示--with-checkbox",
|
|
1690
1691
|
"design-system-components-treeview-展示--long-label",
|
|
1691
|
-
"design-system-components-treeview-展示--drag-and-drop"
|
|
1692
|
-
"design-system-components-treeview-展示--indent-alignment"
|
|
1692
|
+
"design-system-components-treeview-展示--drag-and-drop"
|
|
1693
1693
|
],
|
|
1694
1694
|
"設計規格": [
|
|
1695
1695
|
"design-system-components-treeview-設計規格--overview",
|
|
@@ -1712,5 +1712,5 @@
|
|
|
1712
1712
|
}
|
|
1713
1713
|
},
|
|
1714
1714
|
"totalComponents": 64,
|
|
1715
|
-
"totalStories":
|
|
1715
|
+
"totalStories": 917
|
|
1716
1716
|
}
|
package/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @qijenchen/design-system — 完整設計參考(llms-full)
|
|
2
2
|
|
|
3
|
-
> 全 component / pattern 的 variants / sizes / 禁止事項。build-time 從 spec.md frontmatter 生成,禁手改。v0.1.0-beta.
|
|
3
|
+
> 全 component / pattern 的 variants / sizes / 禁止事項。build-time 從 spec.md frontmatter 生成,禁手改。v0.1.0-beta.86。
|
|
4
4
|
|
|
5
5
|
# Components
|
|
6
6
|
|
|
@@ -418,9 +418,9 @@ Storybook: https://ajenchen-design-system.netlify.app
|
|
|
418
418
|
Source(AI 讀此看官方範例): src/components/TreeView/
|
|
419
419
|
|
|
420
420
|
### Sizes
|
|
421
|
-
- **sm**: 緊湊清單(與 md
|
|
421
|
+
- **sm**: 緊湊清單(與 md 同視覺,保留供密度語意)
|
|
422
422
|
- **md**: default 一般導覽樹
|
|
423
|
-
- **lg**: touch / 大字級
|
|
423
|
+
- **lg**: touch / 大字級
|
|
424
424
|
|
|
425
425
|
# Patterns
|
|
426
426
|
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @qijenchen/design-system
|
|
2
2
|
|
|
3
3
|
> World-class React design system(Radix/shadcn + Tailwind v4 + 自訂 design token)。
|
|
4
|
-
> 57 components + 4 public patterns + design tokens。v0.1.0-beta.
|
|
4
|
+
> 57 components + 4 public patterns + design tokens。v0.1.0-beta.86。
|
|
5
5
|
|
|
6
6
|
本檔由 source(spec.md frontmatter + Storybook index)build-time 自動生成,**禁手改**(CI --check drift gate 守)。
|
|
7
7
|
每元件 / pattern 的完整 variants / sizes / 禁止事項 全文見 [llms-full.txt](./llms-full.txt)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qijenchen/design-system",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.86",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "World-class design system — components, patterns, tokens, hooks (single source of truth for team distribution).",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"!src/**/*.test.ts",
|
|
15
15
|
"README.md",
|
|
16
16
|
"CLAUDE.md",
|
|
17
|
+
"AGENTS.md",
|
|
17
18
|
"ds-canonical",
|
|
18
19
|
"!ds-canonical/.claude",
|
|
19
20
|
"!**/__pycache__",
|
|
@@ -33,19 +33,19 @@ export const Overview: Story = {
|
|
|
33
33
|
<div className="border border-border rounded-lg p-4 max-w-[640px]">
|
|
34
34
|
<Accordion type="single" collapsible defaultValue="anatomy">
|
|
35
35
|
<AccordionItem value="anatomy">
|
|
36
|
-
<AccordionTrigger
|
|
36
|
+
<AccordionTrigger>退款要多久才會入帳?</AccordionTrigger>
|
|
37
37
|
<AccordionContent>
|
|
38
|
-
|
|
38
|
+
信用卡退款於 5–10 個工作天內退回原付款帳戶,實際入帳時間依發卡銀行作業而定。
|
|
39
39
|
</AccordionContent>
|
|
40
40
|
</AccordionItem>
|
|
41
41
|
<AccordionItem value="item-2">
|
|
42
|
-
<AccordionTrigger
|
|
43
|
-
<AccordionContent
|
|
42
|
+
<AccordionTrigger>退款會扣手續費嗎?</AccordionTrigger>
|
|
43
|
+
<AccordionContent>標準訂單退款不收手續費;跨境訂單的匯率價差由發卡機構認列,本平台不另收費。</AccordionContent>
|
|
44
44
|
</AccordionItem>
|
|
45
45
|
</Accordion>
|
|
46
46
|
</div>
|
|
47
47
|
<p className="text-footnote text-fg-muted mt-3">
|
|
48
|
-
結構:<span className="font-mono">[trigger: label + chevron(16px, rotate 180deg when open)] / [content: pb-4 + text-fg-secondary]</span>
|
|
48
|
+
結構:<span className="font-mono">[trigger: label + chevron(16px, rotate 180deg when open)] / [content: pb-4 + text-fg-secondary]</span>。每個 AccordionItem(含最後一個)底緣皆有 <span className="font-mono">border-b border-divider</span>——divider 在 item 底緣而非僅 item 之間(shadcn 同款)。
|
|
49
49
|
</p>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
@@ -440,16 +440,16 @@ export const StateBehavior: Story = {
|
|
|
440
440
|
<div className="border border-border rounded-lg p-4 max-w-[640px]">
|
|
441
441
|
<Accordion type="single" collapsible>
|
|
442
442
|
<AccordionItem value="a">
|
|
443
|
-
<AccordionTrigger
|
|
444
|
-
<AccordionContent
|
|
443
|
+
<AccordionTrigger>個人資料</AccordionTrigger>
|
|
444
|
+
<AccordionContent>姓名、聯絡方式與頭像設定。</AccordionContent>
|
|
445
445
|
</AccordionItem>
|
|
446
446
|
<AccordionItem value="b" disabled>
|
|
447
|
-
<AccordionTrigger
|
|
448
|
-
<AccordionContent
|
|
447
|
+
<AccordionTrigger>進階分析(升級 Pro 解鎖)</AccordionTrigger>
|
|
448
|
+
<AccordionContent>此區塊需 Pro 方案才可使用。</AccordionContent>
|
|
449
449
|
</AccordionItem>
|
|
450
450
|
<AccordionItem value="c">
|
|
451
|
-
<AccordionTrigger
|
|
452
|
-
<AccordionContent
|
|
451
|
+
<AccordionTrigger>通知偏好</AccordionTrigger>
|
|
452
|
+
<AccordionContent>Email 每日摘要、@提及立即通知。</AccordionContent>
|
|
453
453
|
</AccordionItem>
|
|
454
454
|
</Accordion>
|
|
455
455
|
</div>
|
|
@@ -269,23 +269,25 @@ export const ContentRule: Story = {
|
|
|
269
269
|
<div>
|
|
270
270
|
<Rule
|
|
271
271
|
title='✅ 可放 — 文字說明、簡單表單欄位'
|
|
272
|
-
note='Accordion 適合承載閱讀性內容或輕量輸入(e.g. 進階選項的文字欄位)。'
|
|
272
|
+
note='Accordion 適合承載閱讀性內容或輕量輸入(e.g. 進階選項的文字欄位)。多段獨立設定各自收合(type="multiple"),不是單一 item——單一區塊該用 details(見「單一項目不用 Accordion」)。'
|
|
273
273
|
>
|
|
274
|
-
<Accordion type='
|
|
275
|
-
<AccordionItem value='
|
|
276
|
-
<AccordionTrigger
|
|
274
|
+
<Accordion type='multiple'>
|
|
275
|
+
<AccordionItem value='deploy'>
|
|
276
|
+
<AccordionTrigger>進階部署設定</AccordionTrigger>
|
|
277
277
|
<AccordionContent>
|
|
278
278
|
<div className='flex flex-col gap-3'>
|
|
279
279
|
<div className='flex flex-col gap-1'>
|
|
280
|
-
<label className='text-body text-foreground'>專案識別碼</label>
|
|
280
|
+
<label htmlFor='adv-project-id' className='text-body text-foreground'>專案識別碼</label>
|
|
281
281
|
<input
|
|
282
|
+
id='adv-project-id'
|
|
282
283
|
className='h-field-md border border-border rounded-md px-3 text-body'
|
|
283
284
|
placeholder='例:Q2-RELEASE'
|
|
284
285
|
/>
|
|
285
286
|
</div>
|
|
286
287
|
<div className='flex flex-col gap-1'>
|
|
287
|
-
<label className='text-body text-foreground'>自訂網域</label>
|
|
288
|
+
<label htmlFor='adv-custom-domain' className='text-body text-foreground'>自訂網域</label>
|
|
288
289
|
<input
|
|
290
|
+
id='adv-custom-domain'
|
|
289
291
|
className='h-field-md border border-border rounded-md px-3 text-body'
|
|
290
292
|
placeholder='your-team.example.com'
|
|
291
293
|
/>
|
|
@@ -293,6 +295,19 @@ export const ContentRule: Story = {
|
|
|
293
295
|
</div>
|
|
294
296
|
</AccordionContent>
|
|
295
297
|
</AccordionItem>
|
|
298
|
+
<AccordionItem value='seo'>
|
|
299
|
+
<AccordionTrigger>SEO 與中繼資料</AccordionTrigger>
|
|
300
|
+
<AccordionContent>
|
|
301
|
+
<div className='flex flex-col gap-1'>
|
|
302
|
+
<label htmlFor='adv-page-title' className='text-body text-foreground'>頁面標題</label>
|
|
303
|
+
<input
|
|
304
|
+
id='adv-page-title'
|
|
305
|
+
className='h-field-md border border-border rounded-md px-3 text-body'
|
|
306
|
+
placeholder='顯示於瀏覽器分頁與搜尋結果'
|
|
307
|
+
/>
|
|
308
|
+
</div>
|
|
309
|
+
</AccordionContent>
|
|
310
|
+
</AccordionItem>
|
|
296
311
|
</Accordion>
|
|
297
312
|
</Rule>
|
|
298
313
|
|
|
@@ -112,7 +112,16 @@ Consumer 無需額外處理,保留 Radix `data-state` 屬性即可。
|
|
|
112
112
|
|
|
113
113
|
## 邊界狀態
|
|
114
114
|
|
|
115
|
-
Empty state 由 consumer 處理(無 items 則不渲染);loading 狀態由 consumer 用 `<Skeleton />`
|
|
115
|
+
Empty state 由 consumer 處理(無 items 則不渲染);loading 狀態由 consumer 用 `<Skeleton />` 包;本元件無 density 概念,padding 固定為 `py-4 / pb-4`(不隨 density token 變動)。
|
|
116
|
+
|
|
117
|
+
**Disabled**(Accordion 是 composite 家族,**非 Field 家族**——disabled 行為由 Radix Accordion 提供,不走 field-controls SSOT):
|
|
118
|
+
|
|
119
|
+
- **Root `disabled`**:停用整個 accordion,所有 trigger 皆不可展開 / 聚焦。
|
|
120
|
+
- **AccordionItem `disabled`**:停用單一 item——Radix 將 `disabled` 設在原生 `<button>` trigger 上,故該 trigger 鍵盤 Tab / ArrowUp/Down 會**略過**(原生 disabled 不可聚焦),點擊亦無反應;視覺上 trigger 文字 + chevron 切語義 `text-fg-disabled`(非降透明度,對齊 Button variant=text)。live 展示見 anatomy `StateBehavior` 的「disabled item」段。
|
|
121
|
+
|
|
122
|
+
**固定 anatomy(不支援 `asChild`)**:`AccordionTrigger` 恆渲染 `children + ChevronDown` 兩個子節點,`AccordionContent` 恆以內層 `<div className="pb-4">` 包住 children——兩者的型別皆已 `Omit<..., 'asChild'>`,**不對外開放 `asChild`**。理由:傳入會讓 Radix Slot 觸發 `React.Children.only` runtime 錯(Trigger 多子節點),或 consumer 元素無法成為 Content host(只 clone 內層 div)。需替換 host 結構時改自組 Radix Accordion。
|
|
123
|
+
|
|
124
|
+
**垂直留白世界級對照(2026-06-12 source-verified)**:shadcn trigger `py-4`=16px(本 DS 基底,一字不差;[ui.shadcn.com/docs/components/accordion](https://ui.shadcn.com/docs/components/accordion))/ Ant Collapse header 垂直 = paddingSM 12px([github.com/ant-design/ant-design](https://github.com/ant-design/ant-design/tree/master/components/collapse))/ MUI Accordion = minHeight 48 + content margin 12px(expanded 64/20 漸進式;[github.com/mui/material-ui](https://github.com/mui/material-ui/tree/master/packages/mui-material/src/Accordion))/ Carbon = min-height token 模型([github.com/carbon-design-system/carbon](https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/Accordion))——業界垂直節奏值域 12-16px,16px 為舒適端上緣;item 數量無內建上限與虛擬捲動(全數 render),極長清單的收納(拆頁 / 搜尋)由 consumer 內容層處理。
|
|
116
125
|
|
|
117
126
|
---
|
|
118
127
|
|
|
@@ -149,15 +149,17 @@ export const AdvancedOptions: Story = {
|
|
|
149
149
|
render: () => (
|
|
150
150
|
<div className="max-w-[640px] flex flex-col gap-4">
|
|
151
151
|
<div className="flex flex-col gap-1">
|
|
152
|
-
<label className="text-body font-medium text-foreground">專案名稱</label>
|
|
152
|
+
<label htmlFor="adv-project-name" className="text-body font-medium text-foreground">專案名稱</label>
|
|
153
153
|
<input
|
|
154
|
+
id="adv-project-name"
|
|
154
155
|
className="h-field-md border border-border rounded-md px-3 text-body"
|
|
155
156
|
defaultValue="Q2 發布計畫"
|
|
156
157
|
/>
|
|
157
158
|
</div>
|
|
158
159
|
<div className="flex flex-col gap-1">
|
|
159
|
-
<label className="text-body font-medium text-foreground">專案描述</label>
|
|
160
|
+
<label htmlFor="adv-project-desc" className="text-body font-medium text-foreground">專案描述</label>
|
|
160
161
|
<input
|
|
162
|
+
id="adv-project-desc"
|
|
161
163
|
className="h-field-md border border-border rounded-md px-3 text-body"
|
|
162
164
|
placeholder="一句話描述此專案"
|
|
163
165
|
/>
|
|
@@ -171,15 +173,17 @@ export const AdvancedOptions: Story = {
|
|
|
171
173
|
<AccordionContent>
|
|
172
174
|
<div className="flex flex-col gap-3">
|
|
173
175
|
<div className="flex flex-col gap-1">
|
|
174
|
-
<label className="text-body text-foreground">專案識別碼(選填)</label>
|
|
176
|
+
<label htmlFor="adv-opt-project-id" className="text-body text-foreground">專案識別碼(選填)</label>
|
|
175
177
|
<input
|
|
178
|
+
id="adv-opt-project-id"
|
|
176
179
|
className="h-field-md border border-border rounded-md px-3 text-body font-mono"
|
|
177
180
|
placeholder="例:Q2-RELEASE"
|
|
178
181
|
/>
|
|
179
182
|
</div>
|
|
180
183
|
<div className="flex flex-col gap-1">
|
|
181
|
-
<label className="text-body text-foreground">預設檢視模式</label>
|
|
184
|
+
<label htmlFor="adv-view-mode" className="text-body text-foreground">預設檢視模式</label>
|
|
182
185
|
<input
|
|
186
|
+
id="adv-view-mode"
|
|
183
187
|
className="h-field-md border border-border rounded-md px-3 text-body"
|
|
184
188
|
defaultValue="看板"
|
|
185
189
|
/>
|
|
@@ -191,8 +195,9 @@ export const AdvancedOptions: Story = {
|
|
|
191
195
|
<AccordionTrigger>通知設定</AccordionTrigger>
|
|
192
196
|
<AccordionContent>
|
|
193
197
|
<div className="flex flex-col gap-1">
|
|
194
|
-
<label className="text-body text-foreground">狀態變更通知對象</label>
|
|
198
|
+
<label htmlFor="adv-notify-target" className="text-body text-foreground">狀態變更通知對象</label>
|
|
195
199
|
<input
|
|
200
|
+
id="adv-notify-target"
|
|
196
201
|
className="h-field-md border border-border rounded-md px-3 text-body"
|
|
197
202
|
placeholder="例:專案成員 + 關注者"
|
|
198
203
|
/>
|
|
@@ -37,7 +37,10 @@ AccordionItem.displayName = 'AccordionItem'
|
|
|
37
37
|
|
|
38
38
|
const AccordionTrigger = React.forwardRef<
|
|
39
39
|
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
|
40
|
-
|
|
40
|
+
// asChild 不對外開放:Trigger 固定渲染 children + ChevronDown 兩個子節點,傳 asChild
|
|
41
|
+
// 會讓 Radix Slot 觸發 React.Children.only runtime 錯(見 CLAUDE.md 失敗記憶索引
|
|
42
|
+
// 「asChild 分支內部仍渲染多 children」)。固定 anatomy 見 accordion.spec.md「邊界狀態」。
|
|
43
|
+
Omit<React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>, 'asChild'>
|
|
41
44
|
>(({ className, children, ...props }, ref) => (
|
|
42
45
|
<AccordionPrimitive.Header className="flex">
|
|
43
46
|
<AccordionPrimitive.Trigger
|
|
@@ -70,7 +73,9 @@ AccordionTrigger.displayName = 'AccordionTrigger'
|
|
|
70
73
|
|
|
71
74
|
const AccordionContent = React.forwardRef<
|
|
72
75
|
React.ElementRef<typeof AccordionPrimitive.Content>,
|
|
73
|
-
|
|
76
|
+
// asChild 不對外開放:Content 固定以內層 <div className="pb-4"> 包住 children,傳 asChild
|
|
77
|
+
// 只會讓 Slot clone 該內層 div,consumer 元素無法成為 Content host(等同無效 API)。
|
|
78
|
+
Omit<React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>, 'asChild'>
|
|
74
79
|
>(({ className, children, ...props }, ref) => (
|
|
75
80
|
<AccordionPrimitive.Content
|
|
76
81
|
ref={ref}
|
|
@@ -41,16 +41,10 @@ export const UsageGuidance: Story = {
|
|
|
41
41
|
<p>適合 Alert 的真實業務場景(點擊跳轉「展示」頁範例):</p>
|
|
42
42
|
<ul className="space-y-1">
|
|
43
43
|
<li>
|
|
44
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
44
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="單行(低調 vs 實心對照)"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">單行(低調 vs 實心對照)</span></LinkTo>
|
|
45
45
|
</li>
|
|
46
46
|
<li>
|
|
47
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
48
|
-
</li>
|
|
49
|
-
<li>
|
|
50
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="低調含說明文字"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">低調含說明文字</span></LinkTo>
|
|
51
|
-
</li>
|
|
52
|
-
<li>
|
|
53
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="實心含說明文字"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">實心含說明文字</span></LinkTo>
|
|
47
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="含說明文字(低調 vs 實心對照)"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">含說明文字(低調 vs 實心對照)</span></LinkTo>
|
|
54
48
|
</li>
|
|
55
49
|
<li>
|
|
56
50
|
<LinkTo kind="Design System/Components/Alert/展示" name="右上角操作群組"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">右上角操作群組</span></LinkTo>
|
|
@@ -34,9 +34,13 @@ export const Overview: Story = {
|
|
|
34
34
|
sidebar={<AcmeSidebar />}
|
|
35
35
|
header={<PageHeader title="Dashboard" />}
|
|
36
36
|
aside={
|
|
37
|
-
<AppShellAside title="
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
<AppShellAside title="訂單詳情" width={320}>
|
|
38
|
+
{/* 面板內容自帶留白(px/py),示範 aside slot 不強制內距、由內容自管 */}
|
|
39
|
+
<div className="px-[var(--layout-space-loose)] py-[var(--layout-space-tight)] space-y-3 text-body">
|
|
40
|
+
<div className="flex justify-between"><span className="text-fg-muted">訂單編號</span><span className="font-medium">#SO-20481</span></div>
|
|
41
|
+
<div className="flex justify-between"><span className="text-fg-muted">客戶</span><span className="font-medium">陳怡君</span></div>
|
|
42
|
+
<div className="flex justify-between"><span className="text-fg-muted">付款狀態</span><span className="font-medium">已付款</span></div>
|
|
43
|
+
<div className="flex justify-between"><span className="text-fg-muted">金額</span><span className="font-medium">NT$ 12,800</span></div>
|
|
40
44
|
</div>
|
|
41
45
|
</AppShellAside>
|
|
42
46
|
}
|
|
@@ -107,26 +111,28 @@ export const StateBehavior: Story = {
|
|
|
107
111
|
header={
|
|
108
112
|
<ChromeHeader className="bg-surface">
|
|
109
113
|
<SidebarTrigger />
|
|
110
|
-
<h1 className="text-body-lg font-medium flex-1 truncate"
|
|
114
|
+
<h1 className="text-body-lg font-medium flex-1 truncate">訂單 #SO-20481</h1>
|
|
111
115
|
<Button size="sm" variant="primary" onClick={() => setOpen(!open)}>
|
|
112
|
-
{open ? '
|
|
116
|
+
{open ? '隱藏訂單詳情' : '顯示訂單詳情'}
|
|
113
117
|
</Button>
|
|
114
118
|
</ChromeHeader>
|
|
115
119
|
}
|
|
116
120
|
aside={
|
|
117
|
-
<AppShellAside title="
|
|
118
|
-
<div className="px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]">
|
|
119
|
-
<
|
|
121
|
+
<AppShellAside title="訂單詳情" width={320}>
|
|
122
|
+
<div className="px-[var(--layout-space-loose)] py-[var(--layout-space-tight)] space-y-3 text-body">
|
|
123
|
+
<div className="flex justify-between"><span className="text-fg-muted">訂單編號</span><span className="font-medium">#SO-20481</span></div>
|
|
124
|
+
<div className="flex justify-between"><span className="text-fg-muted">客戶</span><span className="font-medium">陳怡君</span></div>
|
|
125
|
+
<div className="flex justify-between"><span className="text-fg-muted">付款狀態</span><span className="font-medium">已付款</span></div>
|
|
120
126
|
</div>
|
|
121
127
|
</AppShellAside>
|
|
122
128
|
}
|
|
123
129
|
asideOpen={open}
|
|
124
130
|
onAsideOpenChange={setOpen}
|
|
125
131
|
>
|
|
126
|
-
<div className="px-[var(--layout-space-loose)] py-[var(--layout-space-tight)] text-body">
|
|
127
|
-
<p
|
|
128
|
-
<p
|
|
129
|
-
<p
|
|
132
|
+
<div className="px-[var(--layout-space-loose)] py-[var(--layout-space-tight)] text-body space-y-1">
|
|
133
|
+
<p>訂單詳情面板目前:{open ? '已展開' : '已收合'}(⌘. / Ctrl+. 可切換)</p>
|
|
134
|
+
<p className="text-fg-secondary">桌面 ≥ 768px:面板從右側並排展開,不蓋遮罩</p>
|
|
135
|
+
<p className="text-fg-secondary">行動裝置 < 768px:面板以 Sheet 從右側滑出,蓋半透明遮罩</p>
|
|
130
136
|
</div>
|
|
131
137
|
</AppShell>
|
|
132
138
|
</SidebarProvider>
|
|
@@ -154,7 +160,7 @@ export const Accessibility: Story = {
|
|
|
154
160
|
<li><strong>Skip to main</strong>:`Tab` 第一站 focus skip-link → jump 到 `#app-shell-main`(WCAG 2.4.1)</li>
|
|
155
161
|
<li><strong>Keyboard shortcuts</strong>:`⌘B` / `Ctrl+B` toggle sidebar(消費 Sidebar SSOT)/ `⌘.` / `Ctrl+.` toggle aside</li>
|
|
156
162
|
<li><strong>Modal Aside title</strong>:title 是必填 prop → 行動裝置上以 Sheet 形式開啟時,自動連結 `aria-labelledby`,讓螢幕報讀器讀得到面板名稱</li>
|
|
157
|
-
<li><strong>Focus trap</strong>:Sheet open 時 focus 在 Aside
|
|
163
|
+
<li><strong>Focus trap</strong>:Sheet open 時 focus 在 Aside 內;Esc 關閉後回焦 opener——controlled Sheet 無 SheetTrigger,Radix 內建回焦失效,由 AppShellAside 自建 opener snapshot + onCloseAutoFocus 手動還原(app-shell.tsx,2026-07-14)</li>
|
|
158
164
|
</ul>
|
|
159
165
|
</div>
|
|
160
166
|
),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @benchmark-
|
|
1
|
+
// @benchmark-unverified-blanket: file-level retraction per M22 (d) — 產品架構參照(Linear / Notion / Figma / GitHub / Slack / Gmail 等)為 usage 觀察,非逐句 URL-cited;視為 unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
3
3
|
import LinkTo from '@storybook/addon-links/react'
|
|
4
4
|
|
|
@@ -62,11 +62,11 @@ export const UsageGuidance: Story = {
|
|
|
62
62
|
<section>
|
|
63
63
|
<h2 className="text-h4 mb-2">Consumer 紀律</h2>
|
|
64
64
|
<ul className="text-body space-y-1">
|
|
65
|
-
<li>❌ 禁:`<AppShell>` 內塞另一個 `<AppShell>`(
|
|
66
|
-
<li>❌ 禁:`sidebar
|
|
67
|
-
<li>❌ 禁:`header
|
|
68
|
-
<li>❌
|
|
69
|
-
<li>✅ 必:Main
|
|
65
|
+
<li>❌ 禁:`<AppShell>` 內塞另一個 `<AppShell>`(整頁框架只能有一個)</li>
|
|
66
|
+
<li>❌ 禁:`sidebar` 傳裸 `<div>` → 必傳 `<Sidebar>`,才能維持一致的展開/收合、行動裝置抽屜、鍵盤操作與視覺;傳其他容器雖然型別過得了,卻會失去這些導覽行為</li>
|
|
67
|
+
<li>❌ 禁:`header` 傳裸 `<header>` → 應傳 `<ChromeHeader>`(或沿用同一套標準標頭結構自訂),才能得到一致的標頭高度、內距與對齊</li>
|
|
68
|
+
<li>❌ 禁:硬性撐開 Main 區域的內距 → Main 本身不加留白,由內容自己決定(自帶邊框的卡片、資料表各自帶內距)</li>
|
|
69
|
+
<li>✅ 必:Main 內容的間距沿用既有版面間距原則——頁面標頭、卡片、資料表、純列表各按對應規則處理</li>
|
|
70
70
|
</ul>
|
|
71
71
|
</section>
|
|
72
72
|
</div>
|
|
@@ -81,37 +81,37 @@ export const LayoutModeRule: Story = {
|
|
|
81
81
|
render: () => (
|
|
82
82
|
<div className="prose max-w-2xl space-y-6 px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]">
|
|
83
83
|
<section>
|
|
84
|
-
<h2 className="text-h4 mb-2"
|
|
84
|
+
<h2 className="text-h4 mb-2">唯一判準:頂部標頭服務的範圍</h2>
|
|
85
85
|
<p className="text-body mb-2">
|
|
86
|
-
|
|
87
|
-
<em>不是</em
|
|
88
|
-
|
|
86
|
+
唯一的區分標準 = <strong>頂部標頭服務的是「目前這一頁」還是「整個產品」</strong>,
|
|
87
|
+
<em>不是</em>工作區(workspace)的數量多寡(Notion / Gmail 都支援多工作區,卻分屬不同派)。
|
|
88
|
+
問自己:頂部那條標頭列服務的是當前頁面,還是整個產品?
|
|
89
89
|
</p>
|
|
90
90
|
<ul className="text-body space-y-1">
|
|
91
91
|
<li>
|
|
92
|
-
<strong>primary-sidebar</strong
|
|
93
|
-
|
|
92
|
+
<strong>primary-sidebar</strong>:頂部是<strong>服務當前頁的工具列</strong> —
|
|
93
|
+
放麵包屑、頁面層級操作、篩選。Sidebar 頂天立地,工作區品牌(`WorkspaceBrand`)放在 sidebar 頂。
|
|
94
94
|
參考 Linear / Notion / Figma。
|
|
95
95
|
</li>
|
|
96
96
|
<li>
|
|
97
|
-
<strong>primary-header</strong
|
|
98
|
-
|
|
99
|
-
<em>仍在</em
|
|
97
|
+
<strong>primary-header</strong>:多一條<strong>橫跨頂部、服務整個產品的全域標頭</strong> —
|
|
98
|
+
放帳號、工作區切換、跨頁搜尋、通知;服務當前頁的工具列
|
|
99
|
+
<em>仍在</em>主欄頂部,只是上面多了這條全域標頭。工作區品牌改放全域標頭(`globalHeader`)左側。
|
|
100
100
|
參考 GitHub / Slack / Gmail。完整組合見{' '}
|
|
101
101
|
<LinkTo kind="Design System/Components/AppShell/展示" name="主標頭佈局 — 全域+本地兩層(GitHub/Gmail/Slack 派)"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">展示 → 主標頭佈局 — 全域+本地兩層</span></LinkTo>
|
|
102
102
|
</li>
|
|
103
103
|
</ul>
|
|
104
104
|
<p className="text-caption text-fg-secondary mt-2">
|
|
105
|
-
|
|
105
|
+
兩種模式是產品的角色定位——啟動時就固定,不該在執行期切換。視覺對照圖見{' '}
|
|
106
106
|
<LinkTo kind="Design System/Components/AppShell/設計規格" name="兩種布局模式對照圖"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">設計規格 → 兩種布局模式對照圖</span></LinkTo>
|
|
107
107
|
</p>
|
|
108
108
|
</section>
|
|
109
109
|
|
|
110
110
|
<section>
|
|
111
|
-
<h2 className="text-h4 mb-2"
|
|
111
|
+
<h2 className="text-h4 mb-2">常見誤解:全域標頭會取代當前頁工具列</h2>
|
|
112
112
|
<p className="text-body">
|
|
113
|
-
錯。primary-header = primary-sidebar 的所有東西 + <strong>額外一條</strong
|
|
114
|
-
`header` slot
|
|
113
|
+
錯。primary-header = primary-sidebar 的所有東西 + <strong>額外一條</strong>全域標頭在頂;
|
|
114
|
+
當前頁工具列(`header` slot)<strong>仍然存在</strong>。GitHub / Slack / Gmail 全部同時保有兩層,
|
|
115
115
|
不是二選一。
|
|
116
116
|
</p>
|
|
117
117
|
</section>
|
|
@@ -129,9 +129,9 @@ export const LayoutModeRule: Story = {
|
|
|
129
129
|
<h2 className="text-h4 mb-2">帳號入口(個人設定)跟著 mode 走(只能出現一次)</h2>
|
|
130
130
|
<ul className="text-body space-y-1">
|
|
131
131
|
<li>• <strong>primary-sidebar</strong>:帳號 / 個人設定放 Sidebar 底部(`<SidebarFooter>`)— Linear / Notion / Figma</li>
|
|
132
|
-
<li>• <strong>primary-header</strong>:帳號入口改放 globalHeader 右側 avatar(品牌左、帳號右,左右對稱),sidebar
|
|
132
|
+
<li>• <strong>primary-header</strong>:帳號入口改放 globalHeader 右側 avatar(品牌左、帳號右,左右對稱),sidebar 不放帳號頁尾 — GitHub / Gmail / Slack 帳號一律在全域標頭右上</li>
|
|
133
133
|
<li>• 開「個人資料 / 設定 / 登出」帳號選單(`<DropdownMenu>`),<strong>不用 ProfileCard</strong>(ProfileCard 是看別人的人員卡,預設動作 Chat/通話用在自己身上不對)</li>
|
|
134
|
-
<li>• 帳號 avatar = 24px,跟左側品牌 avatar 同尺寸(
|
|
134
|
+
<li>• 帳號 avatar = 24px,跟左側品牌 avatar 同尺寸(沿用標準標頭的頭像尺寸規範);右側邊距與品牌距分割線對稱</li>
|
|
135
135
|
<li>❌ 禁:`primary-header` mode 同時在 globalHeader + sidebar footer 各放一份 = 入口混淆(帳號入口視覺 SSOT,只能出現一次)</li>
|
|
136
136
|
</ul>
|
|
137
137
|
</section>
|
|
@@ -67,6 +67,10 @@ benchmark:
|
|
|
67
67
|
|
|
68
68
|
Sub-component:`<AppShellAside title={...} width={400}>`(width consumer 自決 — `number` 或 `{ md, xl }` breakpoint-keyed,clamp `min-width: 240` / `max-width: 640`;**title prop required**,modal mode 走 Sheet → `aria-labelledby` 強制,per `sheet.spec.md`「禁止事項」(無 title → aria-labelledby 強制))。
|
|
69
69
|
|
|
70
|
+
**Aside body padding(內容自帶,刻意 Pattern B)**:`<AppShellAside>` 的 body(ScrollArea 內)**不自帶 px/py**,由 consumer 塞入的 children 自行負責留白(對齊 `layoutSpace.spec.md` 規則 1B「父層/內容管 padding」的裸結構路線,同 Table / DataTable)。**理由**:aside 內容異質(清單需 hover 貼邊滿版、表格需 flush、表單才需 padding),框架統一加 padding 反而破壞清單/表格。與 Dialog / Sheet body 自帶 `px-loose py-tight` 的差異是**刻意**的(那兩者內容較單一)。consumer 放需留白的內容時,自帶 `px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]`(範例 `app-shell.stories.tsx` 即如此)。
|
|
71
|
+
|
|
72
|
+
**Aside 開關控制(刻意單向,2026-07-17 user 拍板)**:`asideOpen` / `onAsideOpenChange` 提供完整 **controlled** 路徑;uncontrolled fallback 初值**刻意固定關閉**(`useState(false)`),**不提供 `defaultAsideOpen`**。理由:側邊詳情面板實務上幾乎一定由 app 的 route / 選取狀態驅動(modal mode 更明文要求 controlled),初值固定關閉是合理預設,額外加 `defaultAsideOpen` 偏 YAGNI。對齊 Dim 26 dual-mode canonical 的「刻意單一模式 → 補 rationale」例外機制。未來真有 uncontrolled 初值需求再加(additive,不破壞)。
|
|
73
|
+
|
|
70
74
|
### Hook export:`useAppShell()`(2026-05-21 D2 codify per Phase B codex catch)
|
|
71
75
|
|
|
72
76
|
Public compound API hook,讓 consumer 自拼 custom aside / 自管 modal layout(對齊 Radix `useDialogContext` / MUI `useFormControl` / Mantine `useAppShellContext` 慣例)。
|