@qijenchen/design-system 0.1.0-beta.61 → 0.1.0-beta.63
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/CLAUDE.md +6 -6
- package/dist/components/Accordion/accordion.d.ts +1 -1
- package/dist/components/Accordion/accordion.js +1 -1
- package/dist/components/Accordion/accordion.js.map +1 -1
- package/dist/components/Alert/alert.d.ts +2 -2
- package/dist/components/Alert/alert.js +4 -3
- package/dist/components/Alert/alert.js.map +1 -1
- package/dist/components/AppShell/app-shell.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.js +4 -3
- package/dist/components/AppShell/app-shell.js.map +1 -1
- package/dist/components/Avatar/avatar.d.ts +1 -1
- package/dist/components/Avatar/avatar.js +2 -1
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/Badge/badge.d.ts +1 -1
- package/dist/components/Badge/badge.js +2 -1
- package/dist/components/Badge/badge.js.map +1 -1
- package/dist/components/Breadcrumb/breadcrumb.d.ts +1 -1
- package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
- package/dist/components/Button/button.d.ts +5 -5
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +4 -3
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Calendar/calendar.d.ts +1 -1
- package/dist/components/Calendar/calendar.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.js +80 -69
- package/dist/components/Calendar/calendar.js.map +1 -1
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +5 -3
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Checkbox/checkbox-group.d.ts +2 -1
- package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox-group.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +9 -3
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +8 -3
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Chip/chip.d.ts +2 -2
- package/dist/components/Chip/chip.js +3 -2
- package/dist/components/Chip/chip.js.map +1 -1
- package/dist/components/CircularProgress/circular-progress.d.ts +1 -1
- package/dist/components/CircularProgress/circular-progress.js +2 -1
- package/dist/components/CircularProgress/circular-progress.js.map +1 -1
- package/dist/components/Coachmark/coachmark.d.ts +4 -4
- package/dist/components/Coachmark/coachmark.js +2 -1
- package/dist/components/Coachmark/coachmark.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +17 -13
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Command/command.d.ts +4 -0
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DateGrid/date-grid.d.ts +8 -4
- package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
- package/dist/components/DateGrid/date-grid.js +2 -2
- package/dist/components/DateGrid/date-grid.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
- package/dist/components/DatePicker/date-picker.js +6 -4
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/DescriptionList/description-list.js +1 -1
- package/dist/components/DescriptionList/description-list.js.map +1 -1
- 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 +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +0 -1
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Empty/empty.d.ts +1 -1
- package/dist/components/Empty/empty.js.map +1 -1
- package/dist/components/Field/field-wrapper.js +1 -1
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +1 -0
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
- package/dist/components/FileUpload/file-upload.d.ts +8 -1
- package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
- package/dist/components/FileUpload/file-upload.js +7 -3
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +25 -14
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/HoverCard/hover-card.d.ts +5 -1
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +2 -1
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/Menu/menu-item.d.ts +6 -2
- package/dist/components/Menu/menu-item.d.ts.map +1 -1
- package/dist/components/Menu/menu-item.js.map +1 -1
- package/dist/components/Notice/notice.d.ts +5 -1
- package/dist/components/Notice/notice.d.ts.map +1 -1
- package/dist/components/Notice/notice.js +2 -1
- package/dist/components/Notice/notice.js.map +1 -1
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts +4 -0
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
- package/dist/components/OverflowIndicator/overflow-indicator.js +2 -2
- package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +6 -2
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/Popover/popover.d.ts +1 -1
- package/dist/components/Popover/popover.js +2 -1
- package/dist/components/Popover/popover.js.map +1 -1
- package/dist/components/ProfileCard/profile-card.d.ts +9 -4
- package/dist/components/ProfileCard/profile-card.d.ts.map +1 -1
- package/dist/components/ProfileCard/profile-card.js.map +1 -1
- package/dist/components/RadioGroup/radio-group.d.ts +6 -0
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +4 -0
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +14 -4
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +4 -0
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +6 -3
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/selection-item.d.ts +5 -1
- package/dist/components/SelectionControl/selection-item.d.ts.map +1 -1
- package/dist/components/SelectionControl/selection-item.js +3 -1
- package/dist/components/SelectionControl/selection-item.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +6 -5
- 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.d.ts.map +1 -1
- package/dist/components/Sidebar/sidebar.js +3 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Skeleton/skeleton.d.ts +1 -1
- package/dist/components/Skeleton/skeleton.js +2 -1
- package/dist/components/Skeleton/skeleton.js.map +1 -1
- package/dist/components/Slider/slider.d.ts +1 -1
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js +7 -3
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Steps/steps.d.ts +1 -1
- package/dist/components/Steps/steps.d.ts.map +1 -1
- package/dist/components/Steps/steps.js +9 -6
- package/dist/components/Steps/steps.js.map +1 -1
- package/dist/components/Switch/switch.d.ts +5 -5
- package/dist/components/Switch/switch.js +3 -3
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/tabs.js +1 -1
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Textarea/textarea.js +1 -1
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-columns.js +1 -1
- package/dist/components/TimePicker/time-columns.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +2 -1
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Toast/toast.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts +1 -1
- package/dist/components/Tooltip/tooltip.js +2 -1
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts +4 -4
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +3 -3
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +3 -3
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.d.ts +3 -2
- package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.d.ts +3 -2
- package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
- package/ds-canonical/hooks/_log-fire.sh +3 -1
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +21 -1
- package/ds-canonical/hooks/check_audit_sample_escape.sh +6 -3
- package/ds-canonical/hooks/check_chrome_header_avatar_canonical.sh +8 -0
- package/ds-canonical/hooks/check_consumer_app_invariants.sh +321 -0
- package/ds-canonical/hooks/check_datatable_invariants.sh +75 -12
- package/ds-canonical/hooks/check_escape_marker_abuse.sh +15 -1
- package/ds-canonical/hooks/check_field_family_invariants.sh +12 -2
- package/ds-canonical/hooks/check_plugin_fork_health.sh +137 -0
- package/ds-canonical/hooks/check_propose_discipline.sh +147 -0
- package/ds-canonical/hooks/check_solo_workflow.sh +11 -1
- package/ds-canonical/hooks/check_story_invariants.sh +63 -9
- package/ds-canonical/hooks/check_storybook_addon_packaging.sh +151 -0
- package/ds-canonical/hooks/check_tailwind_wildcard_in_docs.sh +8 -2
- package/ds-canonical/hooks/lib/_overlay_handcraft.sh +25 -4
- package/ds-canonical/hooks/lib/_token_hygiene.sh +9 -1
- package/ds-canonical/hooks/session_start_governance_check.sh +7 -2
- package/ds-canonical/hooks/stop_self_audit.sh +2 -2
- package/ds-canonical/hooks/tests/test_check_addon_subdir_ship.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_consumer_app_invariants.sh +12 -0
- package/ds-canonical/hooks/tests/test_check_consumer_app_story_title.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +6 -4
- package/ds-canonical/hooks/tests/test_check_consumer_no_ds_catalog.sh +7 -4
- package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +6 -4
- package/ds-canonical/hooks/tests/test_check_data_table_size_num_to_meta_width.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_fork_user_plugin_install.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_plugin_fork_health.sh +9 -0
- package/ds-canonical/hooks/tests/test_check_propose_cite_required.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_propose_discipline.sh +10 -0
- package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +3 -2
- package/ds-canonical/hooks/tests/test_check_storybook_addon_packaging.sh +10 -0
- package/ds-canonical/hooks/tests/test_check_storybook_addon_preset_cjs.sh +3 -2
- package/ds-canonical/references/build-ui-canonicals.md +2 -2
- package/ds-canonical/references/composition-fidelity.md +3 -3
- package/ds-canonical/references/naming-conventions.md +1 -0
- package/ds-canonical/references/ssot-consultation.md +1 -1
- package/ds-canonical/references/ssot-index.md +7 -7
- package/ds-canonical/rules/meta-patterns.md +5 -5
- package/ds-canonical/rules/self-verify.md +1 -1
- package/ds-canonical/rules/story-rules.md +2 -0
- package/ds-canonical/rules/ui-development.md +1 -1
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +11 -2
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +1 -1
- package/ds-canonical/skills/design-system-audit/SKILL.md +15 -15
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +4 -3
- package/ds-story-manifest.json +15 -21
- package/llms-full.txt +9 -5
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
- package/src/components/Accordion/accordion.spec.md +22 -5
- package/src/components/Accordion/accordion.tsx +1 -1
- package/src/components/Alert/alert.anatomy.stories.tsx +4 -4
- package/src/components/Alert/alert.principles.stories.tsx +5 -5
- package/src/components/Alert/alert.spec.md +16 -11
- package/src/components/Alert/alert.stories.tsx +5 -5
- package/src/components/Alert/alert.tsx +2 -2
- package/src/components/AppShell/app-shell.principles.stories.tsx +68 -21
- package/src/components/AppShell/app-shell.spec.md +17 -24
- package/src/components/AppShell/app-shell.tsx +4 -3
- package/src/components/AspectRatio/aspect-ratio.anatomy.stories.tsx +3 -3
- package/src/components/AspectRatio/aspect-ratio.spec.md +15 -1
- package/src/components/Avatar/avatar.anatomy.stories.tsx +1 -1
- package/src/components/Avatar/avatar.principles.stories.tsx +8 -8
- package/src/components/Avatar/avatar.spec.md +25 -54
- package/src/components/Avatar/avatar.tsx +2 -2
- package/src/components/Badge/badge.principles.stories.tsx +2 -2
- package/src/components/Badge/badge.spec.md +22 -13
- package/src/components/Badge/badge.tsx +1 -1
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +5 -2
- package/src/components/Breadcrumb/breadcrumb.spec.md +25 -25
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +7 -32
- package/src/components/Breadcrumb/breadcrumb.tsx +1 -1
- package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +2 -2
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +20 -6
- package/src/components/BulkActionBar/bulk-action-bar.tsx +2 -2
- package/src/components/Button/button.anatomy.stories.tsx +2 -2
- package/src/components/Button/button.spec.md +19 -17
- package/src/components/Button/button.stories.tsx +1 -1
- package/src/components/Button/button.tsx +10 -9
- package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
- package/src/components/Calendar/calendar.spec.md +37 -17
- package/src/components/Calendar/calendar.tsx +26 -22
- package/src/components/Carousel/carousel.anatomy.stories.tsx +6 -6
- package/src/components/Carousel/carousel.principles.stories.tsx +1 -1
- package/src/components/Carousel/carousel.spec.md +23 -3
- package/src/components/Carousel/carousel.tsx +19 -4
- package/src/components/Chart/chart.anatomy.stories.tsx +1 -1
- package/src/components/Chart/chart.spec.md +20 -1
- package/src/components/Checkbox/checkbox-group.tsx +2 -1
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +4 -4
- package/src/components/Checkbox/checkbox.principles.stories.tsx +2 -2
- package/src/components/Checkbox/checkbox.spec.md +35 -15
- package/src/components/Checkbox/checkbox.stories.tsx +1 -1
- package/src/components/Checkbox/checkbox.tsx +14 -3
- package/src/components/Chip/chip.anatomy.stories.tsx +5 -5
- package/src/components/Chip/chip.principles.stories.tsx +9 -3
- package/src/components/Chip/chip.spec.md +8 -9
- package/src/components/Chip/chip.tsx +2 -2
- package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +6 -6
- package/src/components/CircularProgress/circular-progress.spec.md +10 -11
- package/src/components/CircularProgress/circular-progress.stories.tsx +36 -43
- package/src/components/CircularProgress/circular-progress.tsx +1 -1
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +1 -1
- package/src/components/Coachmark/coachmark.principles.stories.tsx +14 -29
- package/src/components/Coachmark/coachmark.spec.md +21 -13
- package/src/components/Coachmark/coachmark.tsx +4 -4
- package/src/components/Combobox/combobox.anatomy.stories.tsx +28 -28
- package/src/components/Combobox/combobox.principles.stories.tsx +1 -1
- package/src/components/Combobox/combobox.spec.md +25 -7
- package/src/components/Combobox/combobox.tsx +12 -3
- package/src/components/Command/command.anatomy.stories.tsx +1 -1
- package/src/components/Command/command.principles.stories.tsx +8 -8
- package/src/components/Command/command.spec.md +18 -8
- package/src/components/Command/command.tsx +8 -3
- package/src/components/DataTable/data-table-sort-manager.tsx +1 -1
- package/src/components/DataTable/data-table.anatomy.stories.tsx +9 -7
- package/src/components/DataTable/data-table.principles.stories.tsx +3 -3
- package/src/components/DataTable/data-table.spec.md +15 -11
- package/src/components/DataTable/data-table.stories.tsx +58 -13
- package/src/components/DataTable/data-table.tsx +13 -0
- package/src/components/DataTable/filter-operators.spec.md +19 -27
- package/src/components/DateGrid/date-grid.anatomy.stories.tsx +8 -8
- package/src/components/DateGrid/date-grid.principles.stories.tsx +7 -7
- package/src/components/DateGrid/date-grid.spec.md +17 -14
- package/src/components/DateGrid/date-grid.tsx +8 -4
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +11 -15
- package/src/components/DatePicker/date-picker.principles.stories.tsx +8 -8
- package/src/components/DatePicker/date-picker.spec.md +40 -36
- package/src/components/DatePicker/date-picker.stories.tsx +23 -53
- package/src/components/DatePicker/date-picker.tsx +12 -6
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +2 -2
- package/src/components/DescriptionList/description-list.principles.stories.tsx +4 -18
- package/src/components/DescriptionList/description-list.spec.md +9 -3
- package/src/components/DescriptionList/description-list.stories.tsx +2 -18
- package/src/components/DescriptionList/description-list.tsx +1 -1
- package/src/components/Dialog/dialog.principles.stories.tsx +1 -1
- package/src/components/Dialog/dialog.spec.md +26 -11
- package/src/components/Dialog/dialog.stories.tsx +159 -184
- package/src/components/Dialog/dialog.tsx +2 -1
- package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +2 -2
- package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +16 -17
- package/src/components/DropdownMenu/dropdown-menu.spec.md +10 -15
- package/src/components/DropdownMenu/dropdown-menu.stories.tsx +13 -15
- package/src/components/DropdownMenu/dropdown-menu.tsx +12 -2
- package/src/components/Empty/empty.spec.md +19 -18
- package/src/components/Empty/empty.tsx +1 -1
- package/src/components/Field/field-controls.spec.md +52 -41
- package/src/components/Field/field-wrapper.tsx +2 -2
- package/src/components/Field/field.anatomy.stories.tsx +6 -5
- package/src/components/Field/field.principles.stories.tsx +8 -7
- package/src/components/Field/field.spec.md +42 -20
- package/src/components/Field/field.stories.tsx +9 -7
- package/src/components/Field/field.tsx +6 -3
- package/src/components/Field/form-validation.spec.md +20 -19
- package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +16 -15
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +5 -1
- package/src/components/FieldControlGroup/field-control-group.spec.md +17 -1
- package/src/components/FieldControlGroup/field-control-group.stories.tsx +9 -9
- package/src/components/FieldControlGroup/field-control-group.tsx +4 -3
- package/src/components/FileItem/file-item.anatomy.stories.tsx +7 -17
- package/src/components/FileItem/file-item.principles.stories.tsx +7 -7
- package/src/components/FileItem/file-item.spec.md +24 -24
- package/src/components/FileUpload/file-upload.anatomy.stories.tsx +4 -2
- package/src/components/FileUpload/file-upload.principles.stories.tsx +10 -12
- package/src/components/FileUpload/file-upload.spec.md +37 -8
- package/src/components/FileUpload/file-upload.tsx +5 -3
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +16 -11
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +4 -4
- package/src/components/FileViewer/file-viewer.spec.md +7 -19
- package/src/components/FileViewer/file-viewer.stories.tsx +3 -3
- package/src/components/FileViewer/file-viewer.tsx +42 -16
- package/src/components/HoverCard/hover-card.spec.md +20 -10
- package/src/components/HoverCard/hover-card.stories.tsx +1 -1
- package/src/components/HoverCard/hover-card.tsx +12 -1
- package/src/components/Input/input.anatomy.stories.tsx +4 -4
- package/src/components/Input/input.principles.stories.tsx +4 -31
- package/src/components/Input/input.spec.md +16 -4
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
- package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
- package/src/components/LinkInput/link-input.spec.md +14 -1
- package/src/components/Menu/menu-item.principles.stories.tsx +5 -5
- package/src/components/Menu/menu-item.spec.md +24 -12
- package/src/components/Menu/menu-item.tsx +7 -3
- package/src/components/Notice/notice.principles.stories.tsx +7 -7
- package/src/components/Notice/notice.spec.md +7 -5
- package/src/components/Notice/notice.tsx +5 -1
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +4 -4
- package/src/components/NumberInput/number-input.principles.stories.tsx +13 -35
- package/src/components/NumberInput/number-input.spec.md +19 -0
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +4 -3
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +2 -5
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +9 -1
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -42
- package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -3
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +11 -2
- package/src/components/PeoplePicker/people-picker.spec.md +26 -12
- package/src/components/PeoplePicker/people-picker.stories.tsx +14 -15
- package/src/components/PeoplePicker/people-picker.tsx +12 -4
- package/src/components/Popover/popover.spec.md +20 -11
- package/src/components/Popover/popover.tsx +2 -2
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
- package/src/components/ProfileCard/profile-card.principles.stories.tsx +29 -25
- package/src/components/ProfileCard/profile-card.spec.md +30 -10
- package/src/components/ProfileCard/profile-card.tsx +12 -7
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +1 -1
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +7 -5
- package/src/components/ProgressBar/progress-bar.spec.md +9 -1
- package/src/components/ProgressBar/progress-bar.stories.tsx +1 -1
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +6 -3
- package/src/components/RadioGroup/radio-group.principles.stories.tsx +6 -13
- package/src/components/RadioGroup/radio-group.spec.md +7 -1
- package/src/components/RadioGroup/radio-group.tsx +10 -0
- package/src/components/Rating/rating.anatomy.stories.tsx +1 -0
- package/src/components/Rating/rating.principles.stories.tsx +9 -6
- package/src/components/Rating/rating.spec.md +13 -7
- package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +44 -24
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +51 -57
- package/src/components/ScrollArea/scroll-area.spec.md +5 -7
- package/src/components/ScrollArea/scroll-area.stories.tsx +110 -60
- package/src/components/ScrollArea/scroll-area.tsx +1 -1
- package/src/components/SegmentedControl/segmented-control.anatomy.stories.tsx +1 -1
- package/src/components/SegmentedControl/segmented-control.spec.md +15 -14
- package/src/components/SegmentedControl/segmented-control.stories.tsx +1 -1
- package/src/components/Select/select.anatomy.stories.tsx +12 -11
- package/src/components/Select/select.principles.stories.tsx +3 -3
- package/src/components/Select/select.spec.md +34 -8
- package/src/components/Select/select.stories.tsx +2 -2
- package/src/components/Select/select.tsx +18 -3
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +2 -2
- package/src/components/SelectMenu/select-menu.principles.stories.tsx +5 -5
- package/src/components/SelectMenu/select-menu.spec.md +19 -12
- package/src/components/SelectMenu/select-menu.stories.tsx +34 -27
- package/src/components/SelectMenu/select-menu.tsx +14 -3
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
- package/src/components/SelectionControl/selection-item.spec.md +13 -2
- package/src/components/SelectionControl/selection-item.stories.tsx +1 -1
- package/src/components/SelectionControl/selection-item.tsx +8 -2
- package/src/components/Separator/separator.principles.stories.tsx +2 -2
- package/src/components/Separator/separator.spec.md +11 -5
- package/src/components/Sheet/sheet.anatomy.stories.tsx +7 -6
- package/src/components/Sheet/sheet.principles.stories.tsx +18 -38
- package/src/components/Sheet/sheet.spec.md +9 -11
- package/src/components/Sheet/sheet.stories.tsx +2 -2
- package/src/components/Sheet/sheet.tsx +6 -5
- package/src/components/Sidebar/sidebar.anatomy.stories.tsx +42 -33
- package/src/components/Sidebar/sidebar.principles.stories.tsx +4 -4
- package/src/components/Sidebar/sidebar.spec.md +22 -17
- package/src/components/Sidebar/sidebar.stories.tsx +16 -0
- package/src/components/Sidebar/sidebar.tsx +15 -7
- package/src/components/Skeleton/skeleton.anatomy.stories.tsx +2 -2
- package/src/components/Skeleton/skeleton.principles.stories.tsx +20 -7
- package/src/components/Skeleton/skeleton.spec.md +6 -4
- package/src/components/Skeleton/skeleton.stories.tsx +34 -26
- package/src/components/Skeleton/skeleton.tsx +1 -1
- package/src/components/Slider/slider.principles.stories.tsx +3 -3
- package/src/components/Slider/slider.spec.md +16 -12
- package/src/components/Slider/slider.stories.tsx +2 -18
- package/src/components/Slider/slider.tsx +6 -2
- package/src/components/Steps/steps.anatomy.stories.tsx +3 -3
- package/src/components/Steps/steps.principles.stories.tsx +9 -12
- package/src/components/Steps/steps.spec.md +31 -25
- package/src/components/Steps/steps.stories.tsx +5 -40
- package/src/components/Steps/steps.tsx +17 -12
- package/src/components/Switch/switch.principles.stories.tsx +1 -1
- package/src/components/Switch/switch.spec.md +13 -0
- package/src/components/Switch/switch.tsx +3 -3
- package/src/components/Tabs/tabs.anatomy.stories.tsx +4 -4
- package/src/components/Tabs/tabs.principles.stories.tsx +1 -1
- package/src/components/Tabs/tabs.spec.md +13 -6
- package/src/components/Tabs/tabs.stories.tsx +3 -3
- package/src/components/Tabs/tabs.tsx +2 -2
- package/src/components/Tag/tag.anatomy.stories.tsx +15 -15
- package/src/components/Tag/tag.principles.stories.tsx +1 -1
- package/src/components/Tag/tag.spec.md +25 -5
- package/src/components/Textarea/textarea.anatomy.stories.tsx +3 -3
- package/src/components/Textarea/textarea.principles.stories.tsx +7 -7
- package/src/components/Textarea/textarea.spec.md +15 -3
- package/src/components/Textarea/textarea.tsx +1 -1
- package/src/components/TimePicker/time-columns.tsx +1 -1
- package/src/components/TimePicker/time-picker.anatomy.stories.tsx +8 -2
- package/src/components/TimePicker/time-picker.spec.md +23 -3
- package/src/components/TimePicker/time-picker.tsx +5 -3
- package/src/components/Toast/toast.anatomy.stories.tsx +1 -1
- package/src/components/Toast/toast.spec.md +7 -4
- package/src/components/Toast/toast.stories.tsx +12 -6
- package/src/components/Toast/toast.tsx +1 -1
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +1 -1
- package/src/components/Tooltip/tooltip.spec.md +11 -8
- package/src/components/Tooltip/tooltip.tsx +1 -1
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +25 -9
- package/src/components/TreeView/tree-view.principles.stories.tsx +5 -5
- package/src/components/TreeView/tree-view.spec.md +11 -9
- package/src/components/TreeView/tree-view.stories.tsx +5 -3
- package/src/components/TreeView/tree-view.tsx +8 -5
- package/src/patterns/action-bar/action-bar.spec.md +11 -4
- package/src/patterns/element-anatomy/element-anatomy.spec.md +8 -6
- package/src/patterns/element-anatomy/inline-action.spec.md +18 -18
- package/src/patterns/element-anatomy/item-anatomy.spec.md +47 -42
- package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -6
- package/src/patterns/element-anatomy/item-anatomy.tsx +3 -3
- package/src/patterns/header-canonical/chrome-header.tsx +3 -2
- package/src/patterns/header-canonical/header-canonical.spec.md +24 -11
- package/src/patterns/header-canonical/header-canonical.stories.tsx +9 -9
- package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +22 -12
- package/src/patterns/overlay-surface/overlay-surface.spec.md +43 -39
- package/src/patterns/overlay-surface/overlay-surface.tsx +3 -2
- package/src/patterns/resize-handle/resize-handle.spec.md +10 -1
- package/src/patterns/resize-handle/resize-handle.stories.tsx +7 -7
- package/src/tokens/README.md +5 -2
- package/src/tokens/color/color.spec.md +17 -10
- package/src/tokens/color/semantic.css +2 -0
- package/src/tokens/density/density.spec.md +4 -14
- package/src/tokens/elevation/elevation.spec.md +7 -8
- package/src/tokens/layoutSpace/layoutSpace.spec.md +20 -27
- package/src/tokens/motion/motion.spec.md +15 -7
- package/src/tokens/opacity/opacity.spec.md +15 -26
- package/src/tokens/orphan-tokens.spec.md +14 -3
- package/src/tokens/radius/radius.spec.md +13 -15
- package/src/tokens/token-system.spec.md +10 -13
- package/src/tokens/typography/typography.spec.md +8 -12
- package/src/tokens/uiSize/uiSize.spec.md +28 -16
- /package/ds-canonical/hooks/{check_addon_subdir_ship.sh → retired/2026-06-11-prune-merge/check_addon_subdir_ship.sh} +0 -0
- /package/ds-canonical/hooks/{check_consumer_app_story_title.sh → retired/2026-06-11-prune-merge/check_consumer_app_story_title.sh} +0 -0
- /package/ds-canonical/hooks/{check_consumer_ds_primitive_misuse.sh → retired/2026-06-11-prune-merge/check_consumer_ds_primitive_misuse.sh} +0 -0
- /package/ds-canonical/hooks/{check_consumer_no_ds_catalog.sh → retired/2026-06-11-prune-merge/check_consumer_no_ds_catalog.sh} +0 -0
- /package/ds-canonical/hooks/{check_consumer_story_baseline.sh → retired/2026-06-11-prune-merge/check_consumer_story_baseline.sh} +0 -0
- /package/ds-canonical/hooks/{check_data_table_size_num_to_meta_width.sh → retired/2026-06-11-prune-merge/check_data_table_size_num_to_meta_width.sh} +0 -0
- /package/ds-canonical/hooks/{check_fork_user_plugin_install.sh → retired/2026-06-11-prune-merge/check_fork_user_plugin_install.sh} +0 -0
- /package/ds-canonical/hooks/{check_plugin_freshness.sh → retired/2026-06-11-prune-merge/check_plugin_freshness.sh} +0 -0
- /package/ds-canonical/hooks/{check_propose_cite_required.sh → retired/2026-06-11-prune-merge/check_propose_cite_required.sh} +0 -0
- /package/ds-canonical/hooks/{check_propose_plain_chinese.sh → retired/2026-06-11-prune-merge/check_propose_plain_chinese.sh} +0 -0
- /package/ds-canonical/hooks/{check_storybook_addon_preset_cjs.sh → retired/2026-06-11-prune-merge/check_storybook_addon_preset_cjs.sh} +0 -0
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.63。
|
|
4
4
|
|
|
5
5
|
# Components
|
|
6
6
|
|
|
@@ -36,7 +36,7 @@ Source(AI 讀此看官方範例): src/components/AspectRatio/
|
|
|
36
36
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
37
37
|
Source(AI 讀此看官方範例): src/components/Avatar/
|
|
38
38
|
|
|
39
|
-
## Badge(family
|
|
39
|
+
## Badge(family self-contained)
|
|
40
40
|
|
|
41
41
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
42
42
|
Source(AI 讀此看官方範例): src/components/Badge/
|
|
@@ -180,6 +180,10 @@ Source(AI 讀此看官方範例): src/components/FileItem/
|
|
|
180
180
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
181
181
|
Source(AI 讀此看官方範例): src/components/FileUpload/
|
|
182
182
|
|
|
183
|
+
### Variants
|
|
184
|
+
- **dropzone**: 預設 — 大型 dashed 拖放區;「拖放有價值」+ 主要上傳區(drag + click)
|
|
185
|
+
- **button**: form 內單欄 / 空間省 / 與其他 field 並列 — 緊湊 Button 觸發(click-only)
|
|
186
|
+
|
|
183
187
|
## FileViewer(family composite)
|
|
184
188
|
|
|
185
189
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
@@ -280,7 +284,7 @@ Source(AI 讀此看官方範例): src/components/Sidebar/
|
|
|
280
284
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
281
285
|
Source(AI 讀此看官方範例): src/components/Skeleton/
|
|
282
286
|
|
|
283
|
-
## Slider(family
|
|
287
|
+
## Slider(family self-contained)
|
|
284
288
|
|
|
285
289
|
Storybook: https://ajenchen-design-system.netlify.app
|
|
286
290
|
Source(AI 讀此看官方範例): src/components/Slider/
|
|
@@ -316,9 +320,9 @@ Storybook: https://ajenchen-design-system.netlify.app
|
|
|
316
320
|
Source(AI 讀此看官方範例): src/components/Tabs/
|
|
317
321
|
|
|
318
322
|
### Sizes
|
|
319
|
-
- **sm**: ★ cva default — 所有 header 內 tabs(overlay / chrome header / Dialog / Sidebar / dense toolbar)
|
|
323
|
+
- **sm**: ★ cva default — 所有 header 內 tabs(overlay / chrome header / Dialog / Sidebar / dense toolbar)
|
|
320
324
|
- **md**: future tier — 目前無 recommended use case,新 consumer 須先諮詢 DS owner
|
|
321
|
-
- **lg**: 獨立 tabs 直接取代 chrome header — page-level workspace 主導覽(tab
|
|
325
|
+
- **lg**: 獨立 tabs 直接取代 chrome header — page-level workspace 主導覽(tab 高度 = chrome-header-height)
|
|
322
326
|
|
|
323
327
|
## Tag(family 3)
|
|
324
328
|
|
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
|
-
> 54 components + 4 public patterns + design tokens。v0.1.0-beta.
|
|
4
|
+
> 54 components + 4 public patterns + design tokens。v0.1.0-beta.63。
|
|
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)。
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
- [FieldControlGroup](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/FieldControlGroup
|
|
36
36
|
- [FieldControls](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/Field
|
|
37
37
|
- [FileItem](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/FileItem
|
|
38
|
-
- [FileUpload](https://ajenchen-design-system.netlify.app):
|
|
38
|
+
- [FileUpload](https://ajenchen-design-system.netlify.app): variants:dropzone/button — src:components/FileUpload
|
|
39
39
|
- [FileViewer](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/FileViewer
|
|
40
40
|
- [Input](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/Input
|
|
41
41
|
- [LinkInput](https://ajenchen-design-system.netlify.app): 見 Storybook / spec — src:components/LinkInput
|
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.63",
|
|
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",
|
|
@@ -69,7 +69,7 @@ export const UsageGuidance: Story = {
|
|
|
69
69
|
>
|
|
70
70
|
<ul className="space-y-1">
|
|
71
71
|
<li>
|
|
72
|
-
<LinkTo kind="Design System/Components/Accordion/展示" name="FAQ"><span className="text-primary hover:underline font-medium cursor-pointer">FAQ
|
|
72
|
+
<LinkTo kind="Design System/Components/Accordion/展示" name="FAQ 常見問題"><span className="text-primary hover:underline font-medium cursor-pointer">FAQ 常見問題</span></LinkTo>
|
|
73
73
|
</li>
|
|
74
74
|
<li>
|
|
75
75
|
<LinkTo kind="Design System/Components/Accordion/展示" name="設定分組"><span className="text-primary hover:underline font-medium cursor-pointer">設定分組</span></LinkTo>
|
|
@@ -19,7 +19,7 @@ benchmark:
|
|
|
19
19
|
|
|
20
20
|
Accordion 是**垂直堆疊、可收合的多區塊容器**——每個 item 由 header(含 chevron)點擊切換展開 / 收合狀態。適合「多段內容,多數時間只想看其中一段」的情境。
|
|
21
21
|
|
|
22
|
-
**實作基礎**:shadcn/ui 結構 + Radix Accordion primitive。本 DS 保留 shadcn 的 `Accordion / AccordionItem / AccordionTrigger / AccordionContent` API,視覺全改本 DS token
|
|
22
|
+
**實作基礎**:shadcn/ui 結構 + Radix Accordion primitive。本 DS 保留 shadcn 的 `Accordion / AccordionItem / AccordionTrigger / AccordionContent` API,視覺全改本 DS token(與 shadcn 預設的差異見「視覺規則」)。
|
|
23
23
|
|
|
24
24
|
**Layout Family**:非上述 family — composite / multi-section(多個 AccordionItem 垂直堆疊,自 own layout)。
|
|
25
25
|
|
|
@@ -30,7 +30,8 @@ Accordion 是**垂直堆疊、可收合的多區塊容器**——每個 item 由
|
|
|
30
30
|
- **FAQ / 說明**:常見問題、使用教學(預設全收合,使用者展開有興趣的)
|
|
31
31
|
- **設定分組**:一般 / 通知 / 安全 / 付款等多節 settings 頁(長 form 拆段)
|
|
32
32
|
- **進階選項可隱藏**:預設展示主要欄位,「進階選項」收合起來避免壓力
|
|
33
|
-
- **單邊 sidebar
|
|
33
|
+
- **單邊 sidebar 多分類(淺層分組)**:notion-style 工作區 sidebar 的 section 收合;檔案樹 / 深度 tree 改用 `TreeView`(見「何時不用」)
|
|
34
|
+
- **多段獨立收合(非互斥切換)**:各段內容垂直堆疊、可各自展開收合——若是「同一塊空間互斥切換視圖」改用 Tabs(見「何時不用」)
|
|
34
35
|
|
|
35
36
|
## 何時不用
|
|
36
37
|
|
|
@@ -72,7 +73,10 @@ Accordion 是**垂直堆疊、可收合的多區塊容器**——每個 item 由
|
|
|
72
73
|
- **Content 文字**:次要閱讀色—— 主資訊在 trigger,展開內容是補充
|
|
73
74
|
- **焦點環**:鍵盤 focus 用 ring token(非自訂 outline)
|
|
74
75
|
|
|
75
|
-
**為什麼 hover 不用底線**:
|
|
76
|
+
**為什麼 hover 不用底線**:
|
|
77
|
+
- shadcn 預設 `hover:underline` 是 web 早期 link convention,現代 SaaS(Notion / Linear / Stripe / Vercel)皆不使用
|
|
78
|
+
- 改用文字色 tint 弱化,維持 DS 統一質感
|
|
79
|
+
- 仍保留可點擊提示——完全不變色會讓使用者不確定能否點擊;「失去可點擊提示」的風險大於「被誤以為是 link」
|
|
76
80
|
|
|
77
81
|
完整 class / token 對照見 anatomy story(`ColorMatrix` + `SizeMatrix`)。
|
|
78
82
|
|
|
@@ -84,7 +88,7 @@ Accordion 是**垂直堆疊、可收合的多區塊容器**——每個 item 由
|
|
|
84
88
|
- ❌ **不寫「全部展開 / 全部收合」按鈕**(違反 accordion 節省空間的設計意圖;若需要此功能,改用 TreeView 或 DescriptionList)
|
|
85
89
|
- ❌ **單一 item 不用 Accordion**(用 `<details>` 或自組 toggle;見「何時不用」)
|
|
86
90
|
- ❌ **不用 Accordion 做主要導航**(主導航用 Tabs / Sidebar,Accordion 是 content-level 收合)
|
|
87
|
-
- ❌ **AccordionContent
|
|
91
|
+
- ❌ **AccordionContent 不放重焦點互動元素**(例:complex form / Dialog trigger)——a11y 硬限制:item 被收合時(尤其 `single` 模式展開他段會自動收合本段)內部焦點隨 content 隱藏而消失,鍵盤使用者失去落點。少量輸入欄位可以(UX 建議層級:使用者通常完成填寫才切換)
|
|
88
92
|
|
|
89
93
|
---
|
|
90
94
|
|
|
@@ -99,9 +103,16 @@ Consumer 無需額外處理,保留 Radix `data-state` 屬性即可。
|
|
|
99
103
|
|
|
100
104
|
---
|
|
101
105
|
|
|
106
|
+
## 常見誤解
|
|
107
|
+
|
|
108
|
+
**誤解**:「Accordion 該提供全部展開 / 全部收合按鈕」。
|
|
109
|
+
**事實**:期待「全展開一次讀完 / 全收合做導航」代表內容是參照型結構——那是 TreeView / DescriptionList 的場景。Accordion 的設計意圖是節省空間、一次聚焦一段(見「禁止事項」)。
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
102
113
|
## 邊界狀態
|
|
103
114
|
|
|
104
|
-
Empty state 由 consumer 處理(無 items 則不渲染);loading 狀態由 consumer 用 `<Skeleton />` 包;disabled state 詳 `../Field/field-controls.spec.md`;本元件無 density 概念,padding 固定為 `py-4 / pb-4`(不隨 density token 變動)
|
|
115
|
+
Empty state 由 consumer 處理(無 items 則不渲染);loading 狀態由 consumer 用 `<Skeleton />` 包;disabled state 詳 `../Field/field-controls.spec.md`;本元件無 density 概念,padding 固定為 `py-4 / pb-4`(不隨 density token 變動);item 數量無內建上限與虛擬捲動(全數 render),極長清單的收納(拆頁 / 搜尋)由 consumer 內容層處理。
|
|
105
116
|
|
|
106
117
|
---
|
|
107
118
|
|
|
@@ -112,3 +123,9 @@ Empty state 由 consumer 處理(無 items 則不渲染);loading 狀態由 consum
|
|
|
112
123
|
- `../Sheet/sheet.spec.md` — 側邊抽屜
|
|
113
124
|
- `../TreeView/tree-view.spec.md` — 具層級結構的收合(Accordion 的巢狀延伸)
|
|
114
125
|
- Radix Accordion primitive — `@radix-ui/react-accordion`
|
|
126
|
+
|
|
127
|
+
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
128
|
+
|
|
129
|
+
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
130
|
+
|
|
131
|
+
- `tabs.spec.md`
|
|
@@ -96,7 +96,7 @@ export const accordionMeta = {
|
|
|
96
96
|
sizes: {
|
|
97
97
|
|
|
98
98
|
},
|
|
99
|
-
states: ['default', 'hover', '
|
|
99
|
+
states: ['default', 'hover', 'focus-visible', 'disabled'],
|
|
100
100
|
tokens: {
|
|
101
101
|
bg: [],
|
|
102
102
|
fg: ['text-fg-disabled', 'text-fg-muted', 'text-fg-secondary', 'text-foreground'],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @anatomy-exempt: anatomy specs / token 對照表格用 raw <table>,非業務資料表。業務資料表才用 <DataTable>。
|
|
2
2
|
// @anatomy-rationale:
|
|
3
3
|
// SizeMatrix N/A — Alert 固定 md tier(由消費的 Notice primitive 決定),
|
|
4
|
-
// 不隨 density
|
|
4
|
+
// 不隨 density 縮放(僅 placement="fixed" 的水平 px 走 --layout-space-loose,density-aware)。Placement(inline / fixed)取代 size 作為佈局決策,
|
|
5
5
|
// 已由 PlacementMatrix 涵蓋。
|
|
6
6
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
7
7
|
import { Alert, type AlertProps } from './alert'
|
|
@@ -127,7 +127,7 @@ export const ColorMatrix: Story = {
|
|
|
127
127
|
<table className="text-caption border-collapse">
|
|
128
128
|
<thead><tr><Th>Variant</Th><Th>Subtle</Th><Th>Solid</Th></tr></thead>
|
|
129
129
|
<tbody>
|
|
130
|
-
<tr><Td mono>neutral</Td><Td mono>bg-muted + border-border
|
|
130
|
+
<tr><Td mono>neutral</Td><Td mono>bg-muted + border-border;無 status icon(VARIANT_ICON.neutral = null)</Td><Td>bg-surface-raised + data-theme inverse(跟頁面反)</Td></tr>
|
|
131
131
|
<tr><Td mono>info</Td><Td mono>bg-info-subtle + border-info-hover + text-info-text</Td><Td mono>bg-info + data-theme="dark"(藍底白字)</Td></tr>
|
|
132
132
|
<tr><Td mono>success</Td><Td mono>bg-success-subtle + border-success-hover + text-success-text</Td><Td mono>bg-success + data-theme="dark"(綠底白字)</Td></tr>
|
|
133
133
|
<tr><Td mono>warning</Td><Td mono>bg-warning-subtle + border-warning-hover + text-warning-text</Td><Td mono>bg-warning + data-theme="light"(黃底深字)</Td></tr>
|
|
@@ -200,7 +200,7 @@ export const StateBehavior: Story = {
|
|
|
200
200
|
<div>
|
|
201
201
|
<H3>Close button 互動狀態</H3>
|
|
202
202
|
<Desc>
|
|
203
|
-
Chrome corner close 用 **Button iconOnly `dismiss` size="xs"**(notification banner family 設計準則,見 `overlay-surface.spec.md`「Chrome dismiss size canonical」)。現行 canonical 為兩分:notification banner family(Notice / Alert / Toast,px-4 py-3 固定)dismiss 用 `xs`;overlay surface(Dialog / Sheet / Popover)另走 `sm` + unbounded 負 margin trick。corner 屬 action group region,實務上可與 refresh / share 等 Button 並排(用
|
|
203
|
+
Chrome corner close 用 **Button iconOnly `dismiss` size="xs"**(notification banner family 設計準則,見 `overlay-surface.spec.md`「Chrome dismiss size canonical」)。現行 canonical 為兩分:notification banner family(Notice / Alert / Toast,px-4 py-3 固定)dismiss 用 `xs`;overlay surface(Dialog / Sheet / Popover)另走 `sm` + unbounded 負 margin trick。corner 屬 action group region,實務上可與 refresh / share 等 Button 並排(用 ButtonDivider 分群),必須統一 Button primitive + 同 family 全 xs。`dismiss` prop 自動套 `variant="text"` + icon `fg-muted` 弱化,hover 時恢復 foreground。
|
|
204
204
|
</Desc>
|
|
205
205
|
<div className="overflow-x-auto">
|
|
206
206
|
<table className="text-caption border-collapse">
|
|
@@ -209,7 +209,7 @@ export const StateBehavior: Story = {
|
|
|
209
209
|
<tr><Td>default</Td><Td>Button xs iconOnly(24×24),X icon 16,fg-muted</Td><Td mono>text-fg-muted(`dismiss` override)</Td></tr>
|
|
210
210
|
<tr><Td>hover</Td><Td>Button bg 套 neutral-hover,icon 升 foreground</Td><Td mono>bg-neutral-hover / text-foreground</Td></tr>
|
|
211
211
|
<tr><Td>focus</Td><Td>2px ring(鍵盤導航)</Td><Td mono>ring-ring ring-offset-1</Td></tr>
|
|
212
|
-
<tr><Td>solid appearance</Td><Td>icon 隨 variant 的 data-theme:info / success / error(dark theme)白字,warning(light theme)深字</Td><Td mono>text-foreground(隨 data-theme 翻轉)</Td></tr>
|
|
212
|
+
<tr><Td>solid appearance</Td><Td>icon 隨 variant 的 data-theme:info / success / error(dark theme)白字,warning(light theme)深字</Td><Td mono>text-fg-muted → hover text-foreground(隨 data-theme 翻轉)</Td></tr>
|
|
213
213
|
</tbody>
|
|
214
214
|
</table>
|
|
215
215
|
</div>
|
|
@@ -41,19 +41,19 @@ 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="低調單行"><span className="text-primary hover:underline font-medium cursor-pointer">低調單行</span></LinkTo>
|
|
45
45
|
</li>
|
|
46
46
|
<li>
|
|
47
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
47
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="實心單行"><span className="text-primary hover:underline font-medium cursor-pointer">實心單行</span></LinkTo>
|
|
48
48
|
</li>
|
|
49
49
|
<li>
|
|
50
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
50
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="低調含說明文字"><span className="text-primary hover:underline font-medium cursor-pointer">低調含說明文字</span></LinkTo>
|
|
51
51
|
</li>
|
|
52
52
|
<li>
|
|
53
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
53
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="實心含說明文字"><span className="text-primary hover:underline font-medium cursor-pointer">實心含說明文字</span></LinkTo>
|
|
54
54
|
</li>
|
|
55
55
|
<li>
|
|
56
|
-
<LinkTo kind="Design System/Components/Alert/展示" name="
|
|
56
|
+
<LinkTo kind="Design System/Components/Alert/展示" name="右上角操作群組"><span className="text-primary hover:underline font-medium cursor-pointer">右上角操作群組</span></LinkTo>
|
|
57
57
|
</li>
|
|
58
58
|
</ul>
|
|
59
59
|
<p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
|
|
@@ -38,7 +38,7 @@ Alert 是**持久性通知**,嵌入在頁面中。用於系統狀態提示、
|
|
|
38
38
|
|
|
39
39
|
**實作基礎**:消費 Notice primitive(共享 Toast 的 layout + icon + theme 策略)。
|
|
40
40
|
|
|
41
|
-
**Layout Family**:CLAUDE.md 4-Family Model **Family 2(List item layout
|
|
41
|
+
**Layout Family**:CLAUDE.md 4-Family Model **Family 2(List item layout)**——由 Notice primitive own(Notice 消費 `patterns/element-anatomy/item-anatomy.spec.md`「List item layout」reading-mode 規格),Alert 透過 Notice 間接繼承,不直接消費 item-anatomy。
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -73,6 +73,8 @@ Alert 是**持久性通知**,嵌入在頁面中。用於系統狀態提示、
|
|
|
73
73
|
- 是(方案到期、帳戶未驗證、系統維護中、錯誤需要處理)→ **Alert**
|
|
74
74
|
- 否(儲存成功、已複製、上傳完成)→ **Toast**
|
|
75
75
|
|
|
76
|
+
頂部全域警告同理走 Alert(`placement="fixed"`):fixed 是**頁面流內**的持久 bar(非 position fixed 浮層),與 Toast 浮層分屬不同層,不互相取代、不衝突。
|
|
77
|
+
|
|
76
78
|
---
|
|
77
79
|
|
|
78
80
|
## 禁止事項
|
|
@@ -81,15 +83,14 @@ Alert 是**持久性通知**,嵌入在頁面中。用於系統狀態提示、
|
|
|
81
83
|
- ❌ **不把 error form validation 做成 Alert**:欄位級錯誤必須貼近發生位置(FieldError),使用者才能快速定位;頁面級 Alert 只放非欄位的整體錯誤(如提交失敗、權限不足)
|
|
82
84
|
- ❌ **Alert 不疊 Alert**:同區出現多個 Alert 視覺雜訊重,整理成一組 messages 或合併為單一 Alert with list
|
|
83
85
|
- ❌ **destructive 操作確認不用 Alert**:刪除 / 離開等需要明確確認的動作用 Dialog,Alert 無法承載 confirm / cancel 雙按鈕的阻斷流程
|
|
84
|
-
- ❌
|
|
85
|
-
- ❌ **close X 不用 Inline Action 或自刻 `<button><X /></button>`**:corner 屬 action group region,必用 `<Button iconOnly dismiss size="xs" />`(見上方 Chrome corner close X canonical)
|
|
86
|
+
- ❌ **兩個 action 區域不混用**:chrome corner 只放 close X(必用 `<Button iconOnly dismiss size="xs" />`,不是 Inline Action、不是自刻 `<button><X /></button>`,見下方 Chrome corner close X canonical);body action row 只放 CTA(Button xs tertiary)。close X 混入 body action row 違反 same-row consistency(box size 與視覺分量不同,造成 gap / 對齊錯亂),完整規則見 `patterns/element-anatomy/inline-action.spec.md`「Same-row consistency rule(防混用)」節
|
|
86
87
|
|
|
87
88
|
---
|
|
88
89
|
|
|
89
90
|
## A11y 預設
|
|
90
91
|
|
|
91
92
|
- **一般提示(neutral / info / success)**:`role="status"` + `aria-live="polite"`——screen reader 在空閒時讀出 Alert 內容,不中斷使用者目前動作
|
|
92
|
-
- **緊急提示(warning / error)**:`role="alert"` + `aria-live="assertive"`——立即中斷 screen reader
|
|
93
|
+
- **緊急提示(warning / error)**:`role="alert"` + `aria-live="assertive"`——立即中斷 screen reader 目前朗讀讀出內容。「緊急與否」的界線即 variant 選擇本身:選 warning / error 即 assertive,依 variant 自動套用,無 per-instance 切換 API
|
|
93
94
|
- **Close X 按鈕**:必須有 `aria-label`(如「關閉通知」),實作見下方「Chrome corner close X canonical」
|
|
94
95
|
- **CTA 按鈕**:放在 Alert body action row 時 size 固定為 `xs` tertiary,文字描述動作(「前往設定」「立即更新」)
|
|
95
96
|
|
|
@@ -100,7 +101,7 @@ Alert 是**持久性通知**,嵌入在頁面中。用於系統狀態提示、
|
|
|
100
101
|
Alert 右上角的 close X **必須用 `<Button iconOnly dismiss size="xs" />`**,不是 Inline Action、不是自刻 button。
|
|
101
102
|
|
|
102
103
|
**為什麼是 Button(Cat 3 Action group region)而非 Inline Action**:
|
|
103
|
-
- Alert 的 chrome corner 屬 **action group region**(toolbar / chrome corner / standalone 類),實務上 close 左側可並排 refresh / share / minimize 等額外 action + `<
|
|
104
|
+
- Alert 的 chrome corner 屬 **action group region**(toolbar / chrome corner / standalone 類),實務上 close 左側可並排 refresh / share / minimize 等額外 action + `<ButtonDivider />`——一旦成為 action group,所有成員必同類(same-row consistency),統一 Button iconOnly
|
|
104
105
|
- Inline Action 是「embedded 在 host 內部的 tap target」(Cat 1,如 Input clear X / Tag dismiss X),不參與 action group 規則,兩者不可混用
|
|
105
106
|
- `dismiss` prop 自動套 `variant="text"` + `fg-muted → hover foreground` 弱化,視覺輕量不壓過內容
|
|
106
107
|
|
|
@@ -114,7 +115,7 @@ Alert chrome corner 可承載多個 action(close 左側並排):
|
|
|
114
115
|
|
|
115
116
|
```
|
|
116
117
|
┌─ Alert ────────────────── [⟲] │ [X] ┐ ← chrome corner action group(Button xs)
|
|
117
|
-
│ [icon] Title │ refresh / share / minimize 等 +
|
|
118
|
+
│ [icon] Title │ refresh / share / minimize 等 + ButtonDivider + close X
|
|
118
119
|
│ Description │
|
|
119
120
|
│ [CTA1] [CTA2] │ ← body action row(Button xs tertiary)
|
|
120
121
|
└──────────────────────────────────────┘
|
|
@@ -122,14 +123,14 @@ Alert chrome corner 可承載多個 action(close 左側並排):
|
|
|
122
123
|
|
|
123
124
|
**規則**:
|
|
124
125
|
- 同一 action group 所有 Button 同 `size="xs"`(跟 close X 對齊)
|
|
125
|
-
- 多 action 之間用 `<
|
|
126
|
-
- 若只有 close X 則不需要
|
|
126
|
+
- 多 action 之間用 `<ButtonDivider />` 分群(`refresh / share` 一群,`close` 一群)——Button 家族 action group 專用 divider(`button-group.tsx`,`role="separator"` 自帶 mx-1),canonical story 同此
|
|
127
|
+
- 若只有 close X 則不需要 ButtonDivider(單一 action 即 group)
|
|
127
128
|
|
|
128
129
|
**世界級對照**:
|
|
129
130
|
- **Material Banner**(`<Banner actions={[...]}/>` 右上 close + 可加 refresh)
|
|
130
131
|
- **Polaris Banner**(`onDismiss` 走 IconButton,右上 action group)
|
|
131
132
|
- **VS Code editor tab** window corner(close + pin + split,全部同 size IconButton)
|
|
132
|
-
- **Figma panel corner**(close + collapse 同 group,
|
|
133
|
+
- **Figma panel corner**(close + collapse 同 group,divider 分隔)
|
|
133
134
|
|
|
134
135
|
### Multi corner action 場景
|
|
135
136
|
|
|
@@ -161,7 +162,7 @@ Subtle vs Solid 的完整 variant × theme class 對照見 anatomy `ColorMatrix`
|
|
|
161
162
|
## 為何無 Inspector / SizeMatrix
|
|
162
163
|
|
|
163
164
|
- **無 Inspector**:Alert 的關鍵決策維度是 `variant`(5 色)× `appearance`(subtle / solid)× `placement`(inline / fixed),已在 `ColorMatrix` 完整呈現 variant × appearance 矩陣,再加 `PlacementMatrix` 呈現 placement——互動切換式 Inspector 不會比這兩張矩陣更能傳達 Alert 的設計規格。
|
|
164
|
-
- **無 SizeMatrix**:Alert 無 `size` prop,其視覺尺寸繼承自 Notice primitive(14px body / 16px icon /
|
|
165
|
+
- **無 SizeMatrix**:Alert 無 `size` prop,其視覺尺寸繼承自 Notice primitive(14px body / 16px icon / 固定 py),字級與垂直 padding 不隨 density 變動;僅 `placement="fixed"` 的水平 px 走 `--layout-space-loose`(density-aware,跟周圍 loose-padding 佈局對齊,見 alert.tsx)。尺寸規格由 `Notice` spec own。改 Notice 時 Alert 自動跟進,不需要 Alert 有獨立 SizeMatrix。
|
|
165
166
|
|
|
166
167
|
對應 anatomy story:保留 `Overview` + `ColorMatrix` + `StateBehavior` + 元件特有 `PlacementMatrix`。
|
|
167
168
|
|
|
@@ -179,9 +180,10 @@ Subtle vs Solid 的完整 variant × theme class 對照見 anatomy `ColorMatrix`
|
|
|
179
180
|
|
|
180
181
|
## 邊界案例
|
|
181
182
|
|
|
182
|
-
- **Disabled(dismiss button)**:Alert **不提供 dismiss 停用 API**——banner dismiss 恆可用(對齊 Polaris / Material Banner:通知關閉鈕應永遠可按)。Alert 本身亦無 `disabled` prop(持久通知不該被禁用)。若需防止 close action(API in-flight)被雙擊,consumer 在 `onDismiss` 內自行 debounce / 加上層鎖,不在 UI 層加 disable(
|
|
183
|
+
- **Disabled(dismiss button)**:Alert **不提供 dismiss 停用 API**——banner dismiss 恆可用(對齊 Polaris / Material Banner:通知關閉鈕應永遠可按)。Alert 本身亦無 `disabled` prop(持久通知不該被禁用)。若需防止 close action(API in-flight)被雙擊,consumer 在 `onDismiss` 內自行 debounce / 加上層鎖,不在 UI 層加 disable(Alert 不提供 dismiss 停用 API、也不把 disabled 轉傳給內部 dismiss Button;Button primitive 本身支援 disabled,但 Alert 刻意不開洞)。
|
|
183
184
|
- **Loading**:Alert 本身不需 loading state(非 async surface);若 Alert body action row 內 CTA 在 async 動作中,該 Button 自己處理 `loading` prop。
|
|
184
185
|
- **Empty / icon-only**:Alert 必有 `title`(API contract),無 empty 場景;若無 description 則僅顯示 title + icon,layout 自動收斂。
|
|
186
|
+
- **極長字串**:title 單行 truncate、description 自由換行不截斷(皆繼承 ItemContent 預設);description 超過 2–3 行屬誤用,改 Dialog(見禁止事項)。
|
|
185
187
|
|
|
186
188
|
## 相關
|
|
187
189
|
|
|
@@ -193,5 +195,8 @@ Subtle vs Solid 的完整 variant × theme class 對照見 anatomy `ColorMatrix`
|
|
|
193
195
|
|
|
194
196
|
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
195
197
|
|
|
198
|
+
- `dialog.spec.md`
|
|
196
199
|
- `empty.spec.md`
|
|
200
|
+
- `notice.spec.md`
|
|
197
201
|
- `skeleton.spec.md`
|
|
202
|
+
- `toast.spec.md`
|
|
@@ -35,7 +35,7 @@ const D: Record<string, string> = {
|
|
|
35
35
|
const actionBtn = <Button variant="tertiary" size="xs">查看詳情</Button>
|
|
36
36
|
|
|
37
37
|
export const SubtleSingleLine = {
|
|
38
|
-
name: '
|
|
38
|
+
name: '低調單行',
|
|
39
39
|
render: () => (
|
|
40
40
|
<div className="flex flex-col gap-3 max-w-lg">
|
|
41
41
|
{ALL.map((v) => <Alert key={v} variant={v} appearance="subtle" title={L[v]} endContent={actionBtn} />)}
|
|
@@ -44,7 +44,7 @@ export const SubtleSingleLine = {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export const SolidSingleLine = {
|
|
47
|
-
name: '
|
|
47
|
+
name: '實心單行',
|
|
48
48
|
render: () => (
|
|
49
49
|
<div className="flex flex-col gap-3 max-w-lg">
|
|
50
50
|
{ALL.map((v) => <Alert key={v} variant={v} appearance="solid" title={L[v]} endContent={actionBtn} />)}
|
|
@@ -53,7 +53,7 @@ export const SolidSingleLine = {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export const SubtleWithDescription = {
|
|
56
|
-
name: '
|
|
56
|
+
name: '低調含說明文字',
|
|
57
57
|
render: () => (
|
|
58
58
|
<div className="flex flex-col gap-3 max-w-lg">
|
|
59
59
|
{ALL.map((v) => <Alert key={v} variant={v} appearance="subtle" title={L[v]} description={D[v]} endContent={actionBtn} />)}
|
|
@@ -62,7 +62,7 @@ export const SubtleWithDescription = {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export const SolidWithDescription = {
|
|
65
|
-
name: '
|
|
65
|
+
name: '實心含說明文字',
|
|
66
66
|
render: () => (
|
|
67
67
|
<div className="flex flex-col gap-3 max-w-lg">
|
|
68
68
|
{ALL.map((v) => <Alert key={v} variant={v} appearance="solid" title={L[v]} description={D[v]} endContent={actionBtn} />)}
|
|
@@ -71,7 +71,7 @@ export const SolidWithDescription = {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
export const CornerActionGroup = {
|
|
74
|
-
name: '
|
|
74
|
+
name: '右上角操作群組',
|
|
75
75
|
render: () => (
|
|
76
76
|
<div className="flex flex-col gap-4 max-w-lg">
|
|
77
77
|
<span className="text-caption text-fg-muted">
|
|
@@ -167,7 +167,7 @@ Alert.displayName = 'Alert'
|
|
|
167
167
|
// Sizes = none(Alert 視覺尺寸繼承 Notice primitive,不隨 size 變;見 spec「為何無 SizeMatrix」)
|
|
168
168
|
export const alertMeta = {
|
|
169
169
|
component: 'Alert',
|
|
170
|
-
family:
|
|
170
|
+
family: 2, // List item(對齊 alert.spec.md frontmatter family: 2)
|
|
171
171
|
variants: {
|
|
172
172
|
neutral: { purpose: '中性提示(系統公告、非緊急說明);無情緒色' },
|
|
173
173
|
info: { purpose: '資訊性提示(版本更新、流程說明);藍色 hue' },
|
|
@@ -176,7 +176,7 @@ export const alertMeta = {
|
|
|
176
176
|
error: { purpose: '錯誤但非阻斷(系統錯誤可重試、API 失敗摘要);aria-live=assertive' },
|
|
177
177
|
},
|
|
178
178
|
sizes: {},
|
|
179
|
-
states: ['default',
|
|
179
|
+
states: ['default'], // 2026-06-11 R2:Alert 本體無互動 state(spec L183 明文無 disabled;dismiss 互動屬內部 Button),
|
|
180
180
|
tokens: {
|
|
181
181
|
bg: ['bg-error', 'bg-error-subtle', 'bg-info', 'bg-info-subtle', 'bg-muted', 'bg-success', 'bg-success-subtle', 'bg-surface-raised', 'bg-warning', 'bg-warning-subtle'],
|
|
182
182
|
fg: ['text-foreground'],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @benchmark-cited: Polaris / Material / Ant 共識 principles canonical(UsageGuidance integrated)
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
3
|
+
import LinkTo from '@storybook/addon-links/react'
|
|
3
4
|
|
|
4
5
|
const meta: Meta = {
|
|
5
6
|
title: 'Design System/Components/AppShell/設計原則',
|
|
@@ -14,25 +15,72 @@ export const UsageGuidance: Story = {
|
|
|
14
15
|
<div className="prose max-w-2xl space-y-6 px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]">
|
|
15
16
|
<section>
|
|
16
17
|
<h2 className="text-h4 mb-2">何時用 AppShell</h2>
|
|
17
|
-
<ul className="text-body space-y-
|
|
18
|
-
<li
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
<ul className="text-body space-y-2">
|
|
19
|
+
<li>
|
|
20
|
+
• 多頁 web service 的主結構——Linear / Notion / Slack / GitHub / Asana 這類「左側導覽 + 中央工作區」產品。完整組合見{' '}
|
|
21
|
+
<LinkTo kind="Design System/Components/AppShell/展示" name="主側欄佈局 — Linear 式議題追蹤"><span className="text-primary hover:underline font-medium cursor-pointer">展示 → 主側欄佈局 — Linear 式議題追蹤</span></LinkTo>
|
|
22
|
+
</li>
|
|
23
|
+
<li>
|
|
24
|
+
• 需要 sidebar + main 持續共存——在議題列表、看板、報表等頁面間切換時,左側導覽不重渲染、捲動位置不丟失。見{' '}
|
|
25
|
+
<LinkTo kind="Design System/Components/AppShell/展示" name="主側欄佈局 + 頁面分頁"><span className="text-primary hover:underline font-medium cursor-pointer">展示 → 主側欄佈局 + 頁面分頁</span></LinkTo>
|
|
26
|
+
</li>
|
|
27
|
+
<li>
|
|
28
|
+
• 需要右側詳情面板(議題詳情 / inspector / 成員資料)跟 main 並存——如 Linear 點選議題後右側展開詳情。開合行為見{' '}
|
|
29
|
+
<LinkTo kind="Design System/Components/AppShell/設計規格" name="右側面板開合行為(兩種模式)"><span className="text-primary hover:underline font-medium cursor-pointer">設計規格 → 右側面板開合行為</span></LinkTo>
|
|
30
|
+
</li>
|
|
21
31
|
</ul>
|
|
22
32
|
</section>
|
|
23
33
|
|
|
24
34
|
<section>
|
|
25
35
|
<h2 className="text-h4 mb-2">何時不用</h2>
|
|
26
36
|
<ul className="text-body space-y-1">
|
|
27
|
-
<li>• 單頁 landing / marketing site
|
|
28
|
-
<li>• Auth 頁(login / signup)→
|
|
29
|
-
<li>• Embedded widget / iframe
|
|
37
|
+
<li>• 單頁 landing / marketing site(產品官網、定價頁)→ `<main>` 直接展開,沒導覽不需要 shell</li>
|
|
38
|
+
<li>• Auth 頁(login / signup)→ 自寫置中 layout,不被 sidebar 佔位</li>
|
|
39
|
+
<li>• Embedded widget / iframe(嵌進別人頁面的客服小視窗類)→ 已被 host shell 包住</li>
|
|
30
40
|
<li>• 文件 reader(全螢幕閱讀)→ shell chrome 干擾閱讀</li>
|
|
31
41
|
</ul>
|
|
32
42
|
</section>
|
|
33
43
|
|
|
34
44
|
<section>
|
|
35
45
|
<h2 className="text-h4 mb-2">Layout mode 怎麼選</h2>
|
|
46
|
+
<p className="text-body">
|
|
47
|
+
兩種佈局模式(primary-sidebar / primary-header)的選型決策樹獨立成「佈局模式怎麼選」story(含
|
|
48
|
+
WorkspaceBrand 放置規則),見本頁側欄或{' '}
|
|
49
|
+
<LinkTo kind="Design System/Components/AppShell/設計原則" name="佈局模式怎麼選"><span className="text-primary hover:underline font-medium cursor-pointer">設計原則 → 佈局模式怎麼選</span></LinkTo>
|
|
50
|
+
</p>
|
|
51
|
+
</section>
|
|
52
|
+
|
|
53
|
+
<section>
|
|
54
|
+
<h2 className="text-h4 mb-2">vs Sidebar 規則</h2>
|
|
55
|
+
<p className="text-body">
|
|
56
|
+
AppShell 只負責整體組合、版面模式、以及右側面板的響應式開合。Sidebar 的外觀、行為、行動裝置上的
|
|
57
|
+
抽屜形式都由 Sidebar 元件自己定義,<strong>AppShell 不會去改 Sidebar 的樣式</strong>。
|
|
58
|
+
多個 sidebar 的情境要等 Sidebar 元件本身支援後才提供。
|
|
59
|
+
</p>
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
<section>
|
|
63
|
+
<h2 className="text-h4 mb-2">Consumer 紀律</h2>
|
|
64
|
+
<ul className="text-body space-y-1">
|
|
65
|
+
<li>❌ 禁:`<AppShell>` 內塞另一個 `<AppShell>`(整頁框架單例)</li>
|
|
66
|
+
<li>❌ 禁:`sidebar={'{'}<div>...</div>{'}'}` → 應傳 `<Sidebar>` primitive(型別收 ReactNode 不機械強制,2026-06-10 拍板)</li>
|
|
67
|
+
<li>❌ 禁:`header={'{'}<header>raw</header>{'}'}` → 應傳 `<ChromeHeader>` 或 header-canonical 派生(同上,不機械強制)</li>
|
|
68
|
+
<li>❌ 禁:`<AppShell.Main>` 強制 padding(違 layoutSpace 規則 1B)</li>
|
|
69
|
+
<li>✅ 必:Main 內容遵循既有 `layoutSpace.spec.md` 6 條規則(Page header / Card / DataTable / naked list 各按規則)</li>
|
|
70
|
+
</ul>
|
|
71
|
+
</section>
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 佈局模式選型 deep-dive — 內容錨定 app-shell.spec.md「兩 mode 差異」(L93-94 / L105 常見誤解)
|
|
77
|
+
// +「WorkspaceBrand 放置 SSOT」(L112-119);category-templates.md component-specific `{Topic}Rule` idiom
|
|
78
|
+
export const LayoutModeRule: Story = {
|
|
79
|
+
name: '佈局模式怎麼選',
|
|
80
|
+
render: () => (
|
|
81
|
+
<div className="prose max-w-2xl space-y-6 px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]">
|
|
82
|
+
<section>
|
|
83
|
+
<h2 className="text-h4 mb-2">唯一判準:Header scope</h2>
|
|
36
84
|
<p className="text-body mb-2">
|
|
37
85
|
唯一 distinguisher = <strong>Header scope 是 local 還是 global</strong>,
|
|
38
86
|
<em>不是</em> workspace 多寡(Notion / Gmail 都支援 multi-workspace,卻分屬不同派)。
|
|
@@ -48,32 +96,31 @@ export const UsageGuidance: Story = {
|
|
|
48
96
|
<strong>primary-header</strong>:多一條 <strong>global bar</strong> 橫跨頂部 —
|
|
49
97
|
服務整個 app(account / workspace switcher / 跨頁 search / notifications);local toolbar
|
|
50
98
|
<em>仍在</em> main col 頂,只是上面多了 global header。WorkspaceBrand 改放 globalHeader 左側。
|
|
51
|
-
參考 GitHub / Slack / Gmail
|
|
99
|
+
參考 GitHub / Slack / Gmail。完整組合見{' '}
|
|
100
|
+
<LinkTo kind="Design System/Components/AppShell/展示" name="主標頭佈局 — 全域+本地兩層(GitHub/Gmail/Slack 派)"><span className="text-primary hover:underline font-medium cursor-pointer">展示 → 主標頭佈局 — 全域+本地兩層</span></LinkTo>
|
|
52
101
|
</li>
|
|
53
102
|
</ul>
|
|
54
|
-
<p className="text-caption text-fg-
|
|
55
|
-
兩 mode 是 product
|
|
56
|
-
|
|
103
|
+
<p className="text-caption text-fg-secondary mt-2">
|
|
104
|
+
兩 mode 是 product 角色表態——啟動時固定,不該在 runtime 切換。視覺對照圖見{' '}
|
|
105
|
+
<LinkTo kind="Design System/Components/AppShell/設計規格" name="兩種布局模式對照圖"><span className="text-primary hover:underline font-medium cursor-pointer">設計規格 → 兩種布局模式對照圖</span></LinkTo>
|
|
57
106
|
</p>
|
|
58
107
|
</section>
|
|
59
108
|
|
|
60
109
|
<section>
|
|
61
|
-
<h2 className="text-h4 mb-2"
|
|
110
|
+
<h2 className="text-h4 mb-2">常見誤解:global header 取代 local toolbar</h2>
|
|
62
111
|
<p className="text-body">
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
112
|
+
錯。primary-header = primary-sidebar 的所有東西 + <strong>額外一條</strong> global header 在頂;
|
|
113
|
+
`header` slot(local toolbar)<strong>仍然存在</strong>。GitHub / Slack / Gmail 全部同時保有兩層,
|
|
114
|
+
不是二選一。
|
|
66
115
|
</p>
|
|
67
116
|
</section>
|
|
68
117
|
|
|
69
118
|
<section>
|
|
70
|
-
<h2 className="text-h4 mb-2">
|
|
119
|
+
<h2 className="text-h4 mb-2">WorkspaceBrand 跟著 mode 走(只能出現一次)</h2>
|
|
71
120
|
<ul className="text-body space-y-1">
|
|
72
|
-
<li
|
|
73
|
-
<li
|
|
74
|
-
<li>❌ 禁:`header
|
|
75
|
-
<li>❌ 禁:`<AppShell.Main>` 強制 padding(違 layoutSpace 規則 1B)</li>
|
|
76
|
-
<li>✅ 必:Main 內容遵循既有 `layoutSpace.spec.md` 6 條規則(Page header / Card / DataTable / naked list 各按規則)</li>
|
|
121
|
+
<li>• <strong>primary-sidebar</strong>:WorkspaceBrand 放 Sidebar 頂部(`<SidebarHeader>` 內)— Linear / Notion / Figma file panel</li>
|
|
122
|
+
<li>• <strong>primary-header</strong>:WorkspaceBrand 改放 globalHeader 左側(搭配 SidebarTrigger),SidebarHeader 留空 — GitHub / Gmail / Figma file editor</li>
|
|
123
|
+
<li>❌ 禁:`primary-header` mode 同時在 globalHeader + SidebarHeader 各放一份 = 視覺冗餘 + 跨產品識別混淆(WorkspaceBrand 視覺 SSOT,只能出現一次)</li>
|
|
77
124
|
</ul>
|
|
78
125
|
</section>
|
|
79
126
|
</div>
|