@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
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
|
|
2
|
+
// @story-baseline: packages/design-system/src/components/DataTable/data-table.stories.tsx#NumberAlignment
|
|
2
3
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
4
|
+
import type { ColumnDef } from '@tanstack/react-table'
|
|
3
5
|
import { Skeleton } from './skeleton'
|
|
6
|
+
import { DataTable } from '@/design-system/components/DataTable/data-table'
|
|
7
|
+
import '@/design-system/components/DataTable/column-types' // ColumnMeta declaration merging
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Skeleton 展示——在資料載入完成前,用灰色色塊模擬真實內容的形狀與排版。
|
|
@@ -58,35 +62,39 @@ export const TaskListLoading: Story = {
|
|
|
58
62
|
),
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
/* ── 表格列載入 ──
|
|
66
|
+
消費真 <DataTable>(per data-table.spec.md「狀態處理職責邊界」:DataTable 禁內建 loading prop,
|
|
67
|
+
無資料載入由 consumer 渲 Skeleton placeholder rows;對齊 MUI X `noRowsVariant=skeleton` /
|
|
68
|
+
Carbon DataTableSkeleton「header 可見 + body cell skeleton」派)。
|
|
69
|
+
Columns 不設 meta.type → 走 consumer 自訂 cell 渲 Skeleton(meta.type 命中 registry 會繞過自訂 cell)。 */
|
|
70
|
+
interface LoadingRow {
|
|
71
|
+
id: string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const LOADING_ROWS: LoadingRow[] = Array.from({ length: 4 }, (_, i) => ({ id: `loading-${i + 1}` }))
|
|
75
|
+
|
|
76
|
+
const loadingColumns: ColumnDef<LoadingRow>[] = [
|
|
77
|
+
{ id: 'txn', header: '交易編號', meta: { width: 160 }, cell: () => <Skeleton className="h-4 w-28" /> },
|
|
78
|
+
{ id: 'amount', header: '金額', meta: { width: 110, align: 'right' }, cell: () => <Skeleton className="h-4 w-16" /> },
|
|
79
|
+
{
|
|
80
|
+
id: 'customer',
|
|
81
|
+
header: '客戶',
|
|
82
|
+
meta: { width: 200 },
|
|
83
|
+
cell: () => (
|
|
84
|
+
<div className="flex items-center gap-2">
|
|
85
|
+
<Skeleton className="h-6 w-6 rounded-full" />
|
|
86
|
+
<Skeleton className="h-4 w-24" />
|
|
87
|
+
</div>
|
|
88
|
+
),
|
|
89
|
+
},
|
|
90
|
+
{ id: 'date', header: '日期', meta: { width: 130 }, cell: () => <Skeleton className="h-4 w-20" /> },
|
|
91
|
+
]
|
|
92
|
+
|
|
61
93
|
export const TableRowLoading: Story = {
|
|
62
94
|
name: '表格列載入',
|
|
63
95
|
render: () => (
|
|
64
|
-
<div className="
|
|
65
|
-
<
|
|
66
|
-
<thead className="bg-muted">
|
|
67
|
-
<tr>
|
|
68
|
-
<th className="text-left text-caption text-fg-secondary px-4 py-2 font-medium">交易編號</th>
|
|
69
|
-
<th className="text-left text-caption text-fg-secondary px-4 py-2 font-medium">金額</th>
|
|
70
|
-
<th className="text-left text-caption text-fg-secondary px-4 py-2 font-medium">客戶</th>
|
|
71
|
-
<th className="text-left text-caption text-fg-secondary px-4 py-2 font-medium">日期</th>
|
|
72
|
-
</tr>
|
|
73
|
-
</thead>
|
|
74
|
-
<tbody className="divide-y divide-border">
|
|
75
|
-
{Array.from({ length: 4 }).map((_, i) => (
|
|
76
|
-
<tr key={i}>
|
|
77
|
-
<td className="px-4 py-3"><Skeleton className="h-4 w-28" /></td>
|
|
78
|
-
<td className="px-4 py-3"><Skeleton className="h-4 w-16" /></td>
|
|
79
|
-
<td className="px-4 py-3">
|
|
80
|
-
<div className="flex items-center gap-2">
|
|
81
|
-
<Skeleton className="h-6 w-6 rounded-full" />
|
|
82
|
-
<Skeleton className="h-4 w-24" />
|
|
83
|
-
</div>
|
|
84
|
-
</td>
|
|
85
|
-
<td className="px-4 py-3"><Skeleton className="h-4 w-20" /></td>
|
|
86
|
-
</tr>
|
|
87
|
-
))}
|
|
88
|
-
</tbody>
|
|
89
|
-
</table>
|
|
96
|
+
<div aria-busy="true" className="max-w-3xl">
|
|
97
|
+
<DataTable columns={loadingColumns} data={LOADING_ROWS} getRowId={(r) => r.id} height="auto" />
|
|
90
98
|
</div>
|
|
91
99
|
),
|
|
92
100
|
}
|
|
@@ -45,13 +45,13 @@ export const UsageGuidance: Story = {
|
|
|
45
45
|
<p>適合 Slider 的真實業務場景(點擊跳轉「展示」頁範例):</p>
|
|
46
46
|
<ul className="space-y-1">
|
|
47
47
|
<li>
|
|
48
|
-
<LinkTo kind="Design System/Components/Slider/展示" name="容器尺寸對齊"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
48
|
+
<LinkTo kind="Design System/Components/Slider/展示" name="容器尺寸對齊"><span className="text-primary hover:underline font-medium cursor-pointer">表單內與 Input / NumberInput 並排的數值調整(容器尺寸對齊)</span></LinkTo>
|
|
49
49
|
</li>
|
|
50
50
|
<li>
|
|
51
|
-
<LinkTo kind="Design System/Components/Slider/展示" name="最小 / 最大 / 步階"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
51
|
+
<LinkTo kind="Design System/Components/Slider/展示" name="最小 / 最大 / 步階"><span className="text-primary hover:underline font-medium cursor-pointer">價格 / 數量等有上下限與步階的調整(最小 / 最大 / 步階)</span></LinkTo>
|
|
52
52
|
</li>
|
|
53
53
|
<li>
|
|
54
|
-
<LinkTo kind="Design System/Components/Slider/展示" name="提交數值回呼"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
54
|
+
<LinkTo kind="Design System/Components/Slider/展示" name="提交數值回呼"><span className="text-primary hover:underline font-medium cursor-pointer">拖曳即時預覽、放開才送出查詢(提交數值回呼)</span></LinkTo>
|
|
55
55
|
</li>
|
|
56
56
|
</ul>
|
|
57
57
|
<p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: Slider
|
|
3
|
-
family:
|
|
3
|
+
family: self-contained
|
|
4
4
|
variants: {}
|
|
5
5
|
sizes:
|
|
6
6
|
sm:
|
|
@@ -85,7 +85,7 @@ Slider 接收 `size?: 'sm' | 'md' | 'lg'` prop(預設 `md`),**這個 prop 只決
|
|
|
85
85
|
|
|
86
86
|
### 為什麼不完全對齊 `--field-height-*`
|
|
87
87
|
|
|
88
|
-
- **現況**:容器高 = `--field-height-sm/md/lg`(對齊);track 厚度固定 4px / thumb 直徑固定 16px / thumb 邊框固定 2px
|
|
88
|
+
- **現況**:容器高 = `--field-height-sm/md/lg`(對齊);track 厚度固定 4px / thumb 直徑固定 16px / thumb 邊框固定 2px,**皆不隨 size 變化**(偏離 size-proportional scaling)。focus 不加 ring / halo,改用 border 加深(詳「視覺規格」表)
|
|
89
89
|
- **Rationale**:Slider 的 thumb 是「位置指示器」,必須足夠大好捕捉(Fitts's Law);縮小成比例(sm=12 / lg=20 之類)會讓 sm 幾乎無法精確拖曳。業界共識:track/thumb 是**單一視覺規格**,`size` 只控容器外高讓 Slider 並排對齊,內部透過 `flex items-center` 垂直置中
|
|
90
90
|
- **世界級對照**:Material 3 Slider(track 4dp thumb 20dp 固定)/ iOS UISlider(track 3pt thumb 28pt 固定)/ Ant Design Slider(track 4px thumb 14px 固定)/ Radix Slider(default 4px track)——全部 thumb / track 尺寸獨立於 form-size system <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
|
|
91
91
|
|
|
@@ -95,14 +95,14 @@ Slider 接收 `size?: 'sm' | 'md' | 'lg'` prop(預設 `md`),**這個 prop 只決
|
|
|
95
95
|
|
|
96
96
|
| 元素 | 值 | Token |
|
|
97
97
|
|---|---|---|
|
|
98
|
-
| **Track** 厚度 | 4px
|
|
98
|
+
| **Track** 厚度 | 4px | — |
|
|
99
99
|
| **Track** 底色 rest | `bg-secondary` | `--secondary`(neutral-3,跟 Tag neutral / Badge low 同級「微淡可辨」)|
|
|
100
100
|
| **Track** 底色 disabled | `bg-muted` | `--muted`(neutral-2,disabled-like 退化)|
|
|
101
101
|
| **Range** 填滿色 rest | `bg-primary` | `--primary` |
|
|
102
102
|
| **Range** 填滿色 disabled | `bg-border`(neutral-5)| `--border` |
|
|
103
|
-
| **Thumb** 直徑 | 16px
|
|
103
|
+
| **Thumb** 直徑 | 16px | — |
|
|
104
104
|
| **Thumb** 底色(rest + disabled 不變)| `bg-surface`(白) | `--surface` |
|
|
105
|
-
| **Thumb** 邊框 rest |
|
|
105
|
+
| **Thumb** 邊框 rest | 2px,色 = Range rest 同 token | `--primary` |
|
|
106
106
|
| **Thumb** 邊框 disabled | `border-border`(= Range disabled 同色)| `--border` |
|
|
107
107
|
| **Thumb** hover | border `primary-hover` + 陰影 `--elevation-100` | `--primary-hover` |
|
|
108
108
|
| **Thumb** active | 陰影 `--elevation-200` | — |
|
|
@@ -156,7 +156,7 @@ Slider 不是 button——它是「當前位置指示器」,底色不該動(動
|
|
|
156
156
|
step={number} // 預設 1
|
|
157
157
|
size="sm" | "md" | "lg" // 預設 md(只影響容器外高)
|
|
158
158
|
disabled={boolean}
|
|
159
|
-
orientation="horizontal" // 不支援 vertical(
|
|
159
|
+
orientation="horizontal" // 不支援 vertical(DS 尚無垂直變體;未來真有需求再擴充)
|
|
160
160
|
minStepsBetweenThumbs={number} // range mode 時兩個 thumb 的最小距離
|
|
161
161
|
/>
|
|
162
162
|
```
|
|
@@ -293,6 +293,14 @@ Slider 的 `readonly` 等同於 `disabled`——一個不能操作的 slider 本
|
|
|
293
293
|
|
|
294
294
|
---
|
|
295
295
|
|
|
296
|
+
## 常見誤解
|
|
297
|
+
|
|
298
|
+
- 「Slider 可以當計數器」——錯。Slider 傳達 position(在哪裡),計數(多少)用 NumberInput ±step(見「何時不用」)
|
|
299
|
+
- 「兩個選項可以用 Range mode」——錯。Range 是連續值區間(value = [start, end]),二元 / 布林選擇用 Switch / SegmentedControl
|
|
300
|
+
- 「focus 要加 ring」——本元件 documented 例外:focus 用 border 加深(同 hover 視覺),不加 ring / halo(見「視覺規格」表)
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
296
304
|
## Do / Don't
|
|
297
305
|
|
|
298
306
|
✅ **Do**
|
|
@@ -335,12 +343,7 @@ Slider 的可調維度是 `min` / `max` / `step` / `defaultValue`(值域與步
|
|
|
335
343
|
|
|
336
344
|
**ARIA / Pattern**:繼承 Radix `slider` primitive a11y 預設(role / aria-* / 鍵盤導覽)。詳 [Radix Accessibility docs](https://www.radix-ui.com/primitives/docs/components/slider#accessibility)。
|
|
337
345
|
|
|
338
|
-
**Keyboard
|
|
339
|
-
|
|
340
|
-
- Tab — focus thumb
|
|
341
|
-
- ←/→ — 微調
|
|
342
|
-
- Home/End — min/max
|
|
343
|
-
- PageUp/Down — 大步階
|
|
346
|
+
**Keyboard 行為**:完整鍵盤對照見上方「鍵盤操作(Radix 原生,免手工)」節,不重複列。
|
|
344
347
|
|
|
345
348
|
**Focus**:Radix primitive 自管 focus / restoration;thumb 鍵盤聚焦時 `outline-none focus-visible:border-primary-hover`(border 加深成 primary-hover,跟 hover 同視覺,不加 ring / halo)。
|
|
346
349
|
|
|
@@ -350,4 +353,5 @@ Slider 的可調維度是 `min` / `max` / `step` / `defaultValue`(值域與步
|
|
|
350
353
|
|
|
351
354
|
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
352
355
|
|
|
356
|
+
- `number-input.spec.md`
|
|
353
357
|
- `switch.spec.md`
|
|
@@ -66,24 +66,8 @@ export const MinMaxStep: Story = {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// @story-trait-rationale: Disabled retired 2026-05-17 per audit Dim 24 —
|
|
69
|
-
// anatomy.stories.tsx StateBehavior 已 cover disabled state。展示層保留 SizeAlignment + MinMaxStep。
|
|
70
|
-
//
|
|
71
|
-
export const Disabled_REMOVED: Story = {
|
|
72
|
-
name: '停用狀態(已移至設計規格頁示範)',
|
|
73
|
-
tags: ['!autodocs', '!dev'],
|
|
74
|
-
render: () => (
|
|
75
|
-
<div className="w-[360px] flex flex-col gap-6">
|
|
76
|
-
<div className="flex flex-col gap-2">
|
|
77
|
-
<div className="text-caption text-fg-muted">單值 disabled</div>
|
|
78
|
-
<Slider defaultValue={[60]} disabled />
|
|
79
|
-
</div>
|
|
80
|
-
<div className="flex flex-col gap-2">
|
|
81
|
-
<div className="text-caption text-fg-muted">範圍 disabled</div>
|
|
82
|
-
<Slider defaultValue={[20, 80]} disabled />
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
),
|
|
86
|
-
}
|
|
69
|
+
// anatomy.stories.tsx StateBehavior 已 cover disabled state(單值 + 範圍)。展示層保留 SizeAlignment + MinMaxStep + OnCommit。
|
|
70
|
+
// 2026-06-11:刪除 zombie export `Disabled_REMOVED`,對齊 DS-wide comment-only 退役慣例(deep-audit dim25)。
|
|
87
71
|
|
|
88
72
|
// ── With live value commit ──────────────────────────────────────────────
|
|
89
73
|
|
|
@@ -2,7 +2,7 @@ import * as React from 'react'
|
|
|
2
2
|
import * as SliderPrimitive from '@radix-ui/react-slider'
|
|
3
3
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
4
4
|
import { cn } from '@/lib/utils'
|
|
5
|
-
import { useResolvedFieldDisabled } from '@/design-system/components/Field/field-context'
|
|
5
|
+
import { useFieldContext, useResolvedFieldDisabled } from '@/design-system/components/Field/field-context'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Slider — 數值範圍選取器
|
|
@@ -62,6 +62,9 @@ const Slider = React.forwardRef<
|
|
|
62
62
|
// 家族整合時繼承其 canonical」)。Slider 已有完整 data-[disabled] 視覺,故只需把 fieldCtx disabled 接上。
|
|
63
63
|
// 2026-06-08 SSOT:讀 useResolvedFieldDisabled()(fieldCtx.disabled)→ <Field disabled> 與 <Field mode="disabled"> 都生效
|
|
64
64
|
const fieldDisabled = useResolvedFieldDisabled()
|
|
65
|
+
// 2026-06-10 a11y:Field 內 Slider thumb(role=slider)無 accessible name(deep-audit axe 抓 aria-input-field-name)
|
|
66
|
+
// → 預設接 FieldLabel(aria-labelledby),consumer ariaLabel 優先。對齊 rating/time-picker labelId 接線。
|
|
67
|
+
const fieldLabelId = useFieldContext()?.labelId
|
|
65
68
|
// 推導要渲染幾個 thumb:controlled 用 value,uncontrolled 用 defaultValue,
|
|
66
69
|
// 都沒有時 fallback 單 thumb(Radix 預設行為)
|
|
67
70
|
const thumbCount =
|
|
@@ -147,6 +150,7 @@ const Slider = React.forwardRef<
|
|
|
147
150
|
: ariaLabel
|
|
148
151
|
: undefined
|
|
149
152
|
}
|
|
153
|
+
aria-labelledby={!ariaLabel && fieldLabelId ? fieldLabelId : undefined}
|
|
150
154
|
/>
|
|
151
155
|
))}
|
|
152
156
|
</SliderPrimitive.Root>
|
|
@@ -158,7 +162,7 @@ Slider.displayName = 'Slider'
|
|
|
158
162
|
// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
|
|
159
163
|
export const sliderMeta = {
|
|
160
164
|
component: 'Slider',
|
|
161
|
-
family:
|
|
165
|
+
family: null, // self-contained(對齊 spec;同 rating.tsx 慣例),
|
|
162
166
|
variants: {},
|
|
163
167
|
// size 只控容器外高,對齊 Field family h-field-*(md density:28/32/36px,uiSize.css)。
|
|
164
168
|
// track 厚度 / thumb 直徑固定不隨 size 變,故無 iconSize / typography。
|
|
@@ -134,7 +134,7 @@ export const OrientationMatrix: Story = {
|
|
|
134
134
|
<H3>Horizontal</H3>
|
|
135
135
|
<Desc>步驟水平排列,常見於結帳流程 / wizard 頂部。Indicator 之間有橫向 connector。</Desc>
|
|
136
136
|
<div className="border border-border rounded-lg p-4 max-w-2xl">
|
|
137
|
-
<Steps value="payment" completedValues={['cart']}>
|
|
137
|
+
<Steps orientation="horizontal" value="payment" completedValues={['cart']}>
|
|
138
138
|
<StepItem value="cart"><StepLabel>購物車</StepLabel></StepItem>
|
|
139
139
|
<StepItem value="payment"><StepLabel>付款</StepLabel></StepItem>
|
|
140
140
|
<StepItem value="shipping"><StepLabel>配送</StepLabel></StepItem>
|
|
@@ -348,7 +348,7 @@ const ErrorInterrupt = () => {
|
|
|
348
348
|
))}
|
|
349
349
|
</Steps>
|
|
350
350
|
</div>
|
|
351
|
-
<div className="text-[11px] text-fg-muted">payment step 發生錯誤:indicator 切 `bg-error` + X icon,label 轉 `--error
|
|
351
|
+
<div className="text-[11px] text-fg-muted">payment step 發生錯誤:indicator 切 `bg-error` + X icon,label 轉 `--error-text`。focus ring 也從 info-hover 切到 error-hover。</div>
|
|
352
352
|
</div>
|
|
353
353
|
)
|
|
354
354
|
}
|
|
@@ -391,7 +391,7 @@ export const StateBehavior: Story = {
|
|
|
391
391
|
<div className="flex flex-col gap-3">
|
|
392
392
|
<span className="text-caption font-medium text-fg-secondary">行為 3:Error interrupt(中斷流程)</span>
|
|
393
393
|
<Desc>
|
|
394
|
-
任何 step 加入 `errorValues` 時,該 step 轉 error state(紅底 + X icon),label 色轉 `--error`。
|
|
394
|
+
任何 step 加入 `errorValues` 時,該 step 轉 error state(紅底 + X icon),label 色轉 `--error-text`。
|
|
395
395
|
consumer 若要繼續流程,必須先解除 errorValues 再推進 current——避免靜默跳過錯誤。
|
|
396
396
|
</Desc>
|
|
397
397
|
<ErrorInterrupt />
|
|
@@ -76,22 +76,19 @@ export const UsageGuidance: Story = {
|
|
|
76
76
|
<p>適合 Steps 的真實業務場景(點擊跳轉「展示」頁範例):</p>
|
|
77
77
|
<ul className="space-y-1">
|
|
78
78
|
<li>
|
|
79
|
-
<LinkTo kind="Design System/Components/Steps/展示" name="
|
|
79
|
+
<LinkTo kind="Design System/Components/Steps/展示" name="預設"><span className="text-primary hover:underline font-medium cursor-pointer">註冊申請精靈(預設)</span></LinkTo>
|
|
80
80
|
</li>
|
|
81
81
|
<li>
|
|
82
|
-
<LinkTo kind="Design System/Components/Steps/展示" name="非線性"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
82
|
+
<LinkTo kind="Design System/Components/Steps/展示" name="非線性"><span className="text-primary hover:underline font-medium cursor-pointer">工作區設定導覽(非線性)</span></LinkTo>
|
|
83
83
|
</li>
|
|
84
84
|
<li>
|
|
85
|
-
<LinkTo kind="Design System/Components/Steps/展示" name="水平"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
85
|
+
<LinkTo kind="Design System/Components/Steps/展示" name="水平"><span className="text-primary hover:underline font-medium cursor-pointer">結帳流程進度(水平)</span></LinkTo>
|
|
86
86
|
</li>
|
|
87
87
|
<li>
|
|
88
|
-
<LinkTo kind="Design System/Components/Steps/展示" name="多重展開模式"><span className="text-primary hover:underline font-medium cursor-pointer"
|
|
89
|
-
</li>
|
|
90
|
-
<li>
|
|
91
|
-
<LinkTo kind="Design System/Components/Steps/展示" name="欄 節奏 驗證"><span className="text-primary hover:underline font-medium cursor-pointer">欄 節奏 驗證</span></LinkTo>
|
|
88
|
+
<LinkTo kind="Design System/Components/Steps/展示" name="多重展開模式"><span className="text-primary hover:underline font-medium cursor-pointer">安裝指南逐步教學(多重展開模式)</span></LinkTo>
|
|
92
89
|
</li>
|
|
93
90
|
</ul>
|
|
94
|
-
<p className="text-fg-
|
|
91
|
+
<p className="text-fg-secondary mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用下方清單建議的近親元件。</p>
|
|
95
92
|
</div>
|
|
96
93
|
|
|
97
94
|
{/* 何時不用 / 替代元件 — 原 WhenNotToUse */}
|
|
@@ -146,7 +143,7 @@ export const ParentControlled: Story = {
|
|
|
146
143
|
// ── 規則 2:Ring 是 focus marker,不是 selection ──
|
|
147
144
|
|
|
148
145
|
export const RingIsFocusMarker: Story = {
|
|
149
|
-
name: '
|
|
146
|
+
name: '規則:環是聚焦標記,不是選取',
|
|
150
147
|
render: () => (
|
|
151
148
|
<Section
|
|
152
149
|
title="Ring 表達「你現在在這步」,跟 step 本身的狀態正交"
|
|
@@ -181,7 +178,7 @@ export const RingIsFocusMarker: Story = {
|
|
|
181
178
|
// ── 規則 3:Blue connector 只跟 completedValues 走 ──
|
|
182
179
|
|
|
183
180
|
export const BlueConnectorLogic: Story = {
|
|
184
|
-
name: '
|
|
181
|
+
name: '規則:藍色連線只跟已完成走',
|
|
185
182
|
render: () => (
|
|
186
183
|
<Section
|
|
187
184
|
title="藍色代表實際走過的路徑,不是 focus 指向"
|
|
@@ -220,7 +217,7 @@ export const BlueConnectorLogic: Story = {
|
|
|
220
217
|
// ── 規則 4:Column rhythm ──
|
|
221
218
|
|
|
222
219
|
export const ColumnRhythm: Story = {
|
|
223
|
-
name: '
|
|
220
|
+
name: '規則:指示欄節奏一致',
|
|
224
221
|
render: () => (
|
|
225
222
|
<Section
|
|
226
223
|
title="Indicator 永遠對齊 label 第一行——即使同一 Steps 內混用「有/無 description」"
|
|
@@ -259,7 +256,7 @@ export const ColumnRhythm: Story = {
|
|
|
259
256
|
// ── 規則 5:Linear 點 completed 不自動 unmark ──
|
|
260
257
|
|
|
261
258
|
export const LinearBackClickDoesNotMutate: Story = {
|
|
262
|
-
name: '規則:Linear
|
|
259
|
+
name: '規則:Linear 點回完成項不改狀態',
|
|
263
260
|
render: () => {
|
|
264
261
|
const [value, setValue] = React.useState('review')
|
|
265
262
|
const [completed] = React.useState(['info', 'account'])
|
|
@@ -72,7 +72,7 @@ Steps 是 `patterns/element-anatomy/item-anatomy.spec.md` 的 row primitive **co
|
|
|
72
72
|
| Prefix | `StepIndicator`(圓形 + 數字 / icon)|
|
|
73
73
|
| Label | `StepLabel` |
|
|
74
74
|
| Description | `StepDescription`(永遠可選)|
|
|
75
|
-
| Suffix |
|
|
75
|
+
| Suffix | 展開 chevron(僅 `expansion="multiple"` 且該 step 有 content 時渲染;消費 item-anatomy `<ItemSuffix>`)|
|
|
76
76
|
| Content | `StepContent`(垂直模式特有)|
|
|
77
77
|
|
|
78
78
|
### 從 item-layout **繼承**的規則(不重複定義)
|
|
@@ -131,6 +131,8 @@ indicator 圓形 flex items-center 居中
|
|
|
131
131
|
→ indicator 位置完全不受 description 有無影響
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
+
實作:indicator 容器(垂直 / 水平)與展開 chevron 一律消費 `patterns/element-anatomy` 的 `<ItemPrefix>` / `<ItemSuffix>` primitive(`h-[1lh] shrink-0 flex items-center` 的 SSOT),不手刻 wrapper(M17)。
|
|
135
|
+
|
|
134
136
|
---
|
|
135
137
|
|
|
136
138
|
## Size
|
|
@@ -173,6 +175,7 @@ indicator 圓形 flex items-center 居中
|
|
|
173
175
|
| `upcoming` | 灰底(`bg-muted`)+ 灰字(`text-fg-disabled`)| 未走到 |
|
|
174
176
|
| `current` | 藍底(`bg-info`)+ 白字數字 | step === `value` 且不在 completedValues / errorValues |
|
|
175
177
|
| `completed` | 藍底(`bg-info`)+ 白色 ✓ | step 在 `completedValues` 內 |
|
|
178
|
+
| `reachable` | 藍底(`bg-info`)+ 白字數字(僅 linear;sm 為空心環)| linear 下「下一個未完成」step(非 current / completed / error),可點 |
|
|
176
179
|
| `error` | 紅底(`bg-error`)+ 白色 ✕ | step 在 `errorValues` 內(或單項 `state="error"` override)|
|
|
177
180
|
|
|
178
181
|
### Sm size 的 state 視覺
|
|
@@ -183,28 +186,30 @@ sm 沒有 icon 空間,用色塊表達:
|
|
|
183
186
|
- `completed` → 藍實心點(`bg-info`)
|
|
184
187
|
- `error` → 紅實心點(`bg-error`)
|
|
185
188
|
|
|
186
|
-
### 自動推導(
|
|
189
|
+
### 自動推導(順序即優先級,對齊 `computeState`)
|
|
187
190
|
|
|
188
|
-
**Consumer 不手寫每個 step 的 state**。State 由 Steps root 的 props
|
|
191
|
+
**Consumer 不手寫每個 step 的 state**。State 由 Steps root 的 props 依下列順序推導(`steps.tsx` `computeState`):
|
|
189
192
|
|
|
190
193
|
```
|
|
191
|
-
|
|
192
|
-
step 在 errorValues
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
per-item state override(escape hatch) → 直接採用
|
|
195
|
+
step 在 errorValues → error(優先於 completed;交集一律 error)
|
|
196
|
+
step 在 completedValues → completed
|
|
197
|
+
step === value → current(linear / non-linear 都成立)
|
|
198
|
+
linear && step 在 reachable(completed ∪ 首個未完成)→ reachable
|
|
199
|
+
其他 → upcoming
|
|
195
200
|
```
|
|
196
201
|
|
|
197
|
-
**關鍵**:`
|
|
202
|
+
**關鍵**:`value` 命中的 step 在兩種模式下 content state 都是 `current`,但 **filled 藍的「正在做」視覺只屬於 linear**。非 linear 的 current 渲染中性 `bg-secondary` + `foreground` 數字(見「Non-linear 被選中 ≠ filled 藍」),focus 由 box-shadow 外環表達,**不會**出現 filled 藍。
|
|
198
203
|
|
|
199
|
-
### 為什麼非 linear
|
|
204
|
+
### 為什麼非 linear 的 current 不渲染 filled 藍
|
|
200
205
|
|
|
201
|
-
非 linear 模式讓使用者跳著點 step(例如設定頁、教學目錄),value
|
|
206
|
+
非 linear 模式讓使用者跳著點 step(例如設定頁、教學目錄),value 的語意是「使用者在看哪一步」,**不是**「使用者在做哪一步」。如果非 linear 也渲染 filled 藍,會造成:
|
|
202
207
|
|
|
203
208
|
- 使用者點 upcoming step 想預覽 → step 立刻變 filled 藍,像是「標記為正在做」
|
|
204
209
|
- 跟 mental model「我只是在看,這步還沒做」衝突
|
|
205
|
-
- completedValues 沒有變化,前一個
|
|
210
|
+
- completedValues 沒有變化,前一個 filled 藍 step 突然不見
|
|
206
211
|
|
|
207
|
-
正確做法:focus
|
|
212
|
+
正確做法:focus 視覺跟「進度視覺」完全解耦——focus 透過 box-shadow 外環表達,filled 藍由 linear / completedValues 決定。filled「正在做」視覺是 linear 的概念。
|
|
208
213
|
|
|
209
214
|
Per-item `state="error"` prop 存在但是 **escape hatch**,僅用在 inline JSX 想直接宣告錯誤的罕見場景;一般情況用 `errorValues` array 統一管理,不要混用。
|
|
210
215
|
|
|
@@ -251,14 +256,14 @@ sm 的 8px dot 用同一套 `getOuterRingShadow` box-shadow halo 在 dot 外圍
|
|
|
251
256
|
|
|
252
257
|
直接在 filled circle 外貼一圈同色 ring 會讀成「雙圈」很醜;先用 `var(--surface)` 拉一圈 2px gap 再疊 ring,讓環跟 indicator 之間有底色間隙,視覺乾淨且各 state 都清楚(對齊 shadcn `ring-offset` / Polaris focus indicator surface-gap canonical)。
|
|
253
258
|
|
|
254
|
-
### Non-linear 被選中 ≠
|
|
259
|
+
### Non-linear 被選中 ≠ filled 藍(關鍵規則)
|
|
255
260
|
|
|
256
|
-
非 linear 模式使用者點 upcoming step 瀏覽時,step 的
|
|
257
|
-
- 底色:`bg-secondary`(**刻意不同於 linear upcoming 的 `bg-muted`**——non-linear 所有 step
|
|
261
|
+
非 linear 模式使用者點 upcoming step 瀏覽時,step 的 content state 變為 `current`(`computeState` 對 value 命中者一律回 current),但渲染**刻意中性**。視覺上會是(md/lg):
|
|
262
|
+
- 底色:`bg-secondary`(**刻意不同於 linear upcoming 的 `bg-muted`**——non-linear 所有 step 都可點,不該像 linear upcoming 那樣呈現「鎖住/還到不了」的 muted 灰;secondary 傳達「可導覽但非當前」)
|
|
258
263
|
- 數字:`foreground`(可讀,非 disabled 弱字——呼應 step 可達)
|
|
259
|
-
- 外環:`--
|
|
264
|
+
- 外環:`--border-hover` box-shadow ring(focus marker,表達「你在看這一步」;`resolveRingColor` 對 non-linear current)
|
|
260
265
|
|
|
261
|
-
|
|
266
|
+
**不會**出現 linear current 的 filled 藍——這對齊使用者 mental model「我只是在看,這步還沒做」。non-linear current 與 upcoming 同為 `bg-secondary` 底,被選中(focused)的 step 以 `--border-hover` 外環標示。sm 尺寸的 dot 在 non-linear current 仍用 `fg-disabled` 灰點(8px dot 最小化呈現)。
|
|
262
267
|
|
|
263
268
|
**Ring 不是 selection marker**。Steps 不是 SelectMenu / DropdownMenu 這類 selection control;ring 是 focus marker 單一語意。`CLAUDE.md` 的「選擇 / 狀態視覺」規則 B 指出的 `bg-neutral-selected`、radio 圓圈等 selection 視覺**都不適用 Steps**——Steps 用 box-shadow 外環表達「you are here」,不是「你選中了這個」。
|
|
264
269
|
|
|
@@ -311,7 +316,7 @@ Description 在 error state 下維持 `text-fg-secondary`(跟其他 state 一樣
|
|
|
311
316
|
|
|
312
317
|
| Mode | 點擊規則 |
|
|
313
318
|
|---|---|
|
|
314
|
-
| `linear=true`(預設) | 可點:`completed` / `current` / `error
|
|
319
|
+
| `linear=true`(預設) | 可點:`completed` / `current` / `error` / `reachable`(下一個未完成)。**不可點**:`upcoming`(尚未解鎖)。 |
|
|
315
320
|
| `linear=false` | 所有非 `disabled` 的 step 都可點。適合 setting wizard、教學目錄等「步驟之間無強依賴」的場景。 |
|
|
316
321
|
|
|
317
322
|
### 點擊 completed step 的行為
|
|
@@ -322,7 +327,7 @@ Description 在 error state 下維持 `text-fg-secondary`(跟其他 state 一樣
|
|
|
322
327
|
2. **`completedValues` 維持不變**,不自動 mutate
|
|
323
328
|
3. 如果應用層驗證使用者改錯某欄位需要 block 後續步驟,應用層自己從 `completedValues` 移除該 step 及其後所有 step(這是 business logic,不是元件責任)
|
|
324
329
|
|
|
325
|
-
這條規則的核心是:**Steps
|
|
330
|
+
這條規則的核心是:**Steps 從不偷偷改 parent state**——進度狀態(`completedValues` / `errorValues`)全由 parent own;`value` 為 controlled / uncontrolled(`defaultValue`)雙模,uncontrolled 僅內部記住 focus,不碰進度。所有進度 mutation 都經過 parent 的 state setter,讓應用層完整掌控推進邏輯。
|
|
326
331
|
|
|
327
332
|
---
|
|
328
333
|
|
|
@@ -331,7 +336,7 @@ Description 在 error state 下維持 `text-fg-secondary`(跟其他 state 一樣
|
|
|
331
336
|
| 模式 | 行為 |
|
|
332
337
|
|---|---|
|
|
333
338
|
| `follow-active`(預設) | 只有 `value` 指向的 step 渲染 `<StepContent>`。value 切換時 content 跟著切。其他 step 即使寫了 `<StepContent>` 也不顯示。 |
|
|
334
|
-
| `multiple` | 每個 step 獨立管理展開狀態,**可同時展開多個**。點 step header
|
|
339
|
+
| `multiple` | 每個 step 獨立管理展開狀態,**可同時展開多個**。點 step header 永遠先更新 `value`(focus),並額外切換該 step 的展開。`defaultExpanded` 接 `"all" \| "none" \| string[]`,預設 `"none"`。 |
|
|
335
340
|
|
|
336
341
|
### 為什麼 `all` 隸屬於 `multiple`
|
|
337
342
|
|
|
@@ -384,7 +389,7 @@ Description 在 error state 下維持 `text-fg-secondary`(跟其他 state 一樣
|
|
|
384
389
|
|
|
385
390
|
1. **Single source of truth**:所有狀態集中在 parent,不可能發生「多個 step 同時是 current」「completedValues 跟 item state 互相矛盾」這類 bug。
|
|
386
391
|
2. **Derived state**:每個 step 的 state 由 parent props 推導,consumer 不手算,不會漂移。
|
|
387
|
-
3. **無 side effect**:Steps
|
|
392
|
+
3. **無 side effect**:Steps 不偷偷 mutate 進度狀態(completedValues / errorValues),進度變動都走 parent 的 state setter,讓應用層完整掌控推進邏輯(驗證 → 加入 completedValues → 推進 value)。
|
|
388
393
|
4. **對齊業界**:Ant Design Steps(`current` + `status`)、Material Stepper(`activeStep`)、Radix Tabs(`value`)全部用此模式。開發者從這些系統來的直覺可直接套用,學習曲線接近零。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
|
|
389
394
|
|
|
390
395
|
### Per-item `state` escape hatch
|
|
@@ -428,10 +433,10 @@ Item-level **內容狀態色彩**(completed / current / upcoming / error indicat
|
|
|
428
433
|
## 邊界案例
|
|
429
434
|
|
|
430
435
|
- **Disabled step**:`disabled` step 視覺繼承 SelectionItem disabled token(`text-fg-disabled`,M24),click 不觸發 navigate;`linear` mode 下 upcoming steps 預設 disabled 直到前面 completed。
|
|
431
|
-
- **Loading(async step state fetch)**:Steps primitive 為 sync render,async data fetch 應由 consumer 在外層 Skeleton 取代整個 Steps;Steps 內部不獨立 own loading prop
|
|
432
|
-
- **Empty(0 steps)
|
|
433
|
-
- **Single step /
|
|
434
|
-
- **Error state(`errorValues`)**:由元件層級 own — 對應 step indicator 切 error token
|
|
436
|
+
- **Loading(async step state fetch)**:Steps primitive 為 sync render,async data fetch 應由 consumer 在外層 Skeleton 取代整個 Steps;Steps 內部不獨立 own loading prop,**也無 per-step loading state**(content state 集合不含 loading)— 單一步驟 async 進行中即 current,進度細節由 consumer 在 `StepContent` 內呈現。
|
|
437
|
+
- **Empty(0 steps)**:無任何 `<StepItem>` children 時無進度可呈現;consumer 應條件性不渲 Steps 或渲 `<Empty>` 替代,不渲空 Steps container。
|
|
438
|
+
- **Single step / `value` 指向第一步**:合法初始狀態,第一個 step 渲染 current,後續依推導為 reachable / upcoming。
|
|
439
|
+
- **Error state(`errorValues`)**:由元件層級 own — 對應 step indicator 切 error token、label 切 `text-error-text`(見「Label 色彩」);connector **不**變色,仍按「Connector 路徑色」規則(前一步 completed 才藍,否則灰);後續 step 仍 upcoming。
|
|
435
440
|
- **Dark mode**:走 semantic token + Primary token 自動 adapt。
|
|
436
441
|
- **Density**:Step indicator 32px 對齊 `AVATAR_SIZE.block.sm/md`,connector 細線跨 density 不變(進度視覺對 density 不敏感)。
|
|
437
442
|
|
|
@@ -470,4 +475,5 @@ Item-level **內容狀態色彩**(completed / current / upcoming / error indicat
|
|
|
470
475
|
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
471
476
|
|
|
472
477
|
- `horizontal-overflow.spec.md`
|
|
478
|
+
- `item-anatomy.spec.md`
|
|
473
479
|
- `progress-bar.spec.md`
|
|
@@ -185,7 +185,7 @@ export const FocusRingCombinations: Story = {
|
|
|
185
185
|
</StepItem>
|
|
186
186
|
<StepItem value="step-2">
|
|
187
187
|
<StepLabel>Current</StepLabel>
|
|
188
|
-
<StepDescription
|
|
188
|
+
<StepDescription>中性底(bg-secondary)數字 + ring(若 focused)</StepDescription>
|
|
189
189
|
</StepItem>
|
|
190
190
|
<StepItem value="step-3">
|
|
191
191
|
<StepLabel>Completed</StepLabel>
|
|
@@ -283,7 +283,7 @@ export const MultipleExpansion: Story = {
|
|
|
283
283
|
render: () => (
|
|
284
284
|
<div className="w-[480px]">
|
|
285
285
|
<p className="text-caption text-fg-secondary mb-4">
|
|
286
|
-
點 step header
|
|
286
|
+
點 step header 切換展開(並更新 value)。本例顯式傳 `defaultExpanded="all"` 全部展開起手(預設 `"none"`)。
|
|
287
287
|
</p>
|
|
288
288
|
<Steps
|
|
289
289
|
defaultValue="b"
|
|
@@ -330,41 +330,6 @@ export const MultipleExpansion: Story = {
|
|
|
330
330
|
),
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
|
|
336
|
-
export const MixedDescription: Story = {
|
|
337
|
-
name: '欄 節奏 驗證',
|
|
338
|
-
render: () => (
|
|
339
|
-
<div className="flex gap-12">
|
|
340
|
-
{(['md', 'lg'] as const).map(size => (
|
|
341
|
-
<div key={size} className="w-[280px]">
|
|
342
|
-
<div className="text-caption text-fg-muted mb-4">size = {size}</div>
|
|
343
|
-
<Steps
|
|
344
|
-
defaultValue="step-3"
|
|
345
|
-
completedValues={['step-1', 'step-2']}
|
|
346
|
-
size={size}
|
|
347
|
-
>
|
|
348
|
-
<StepItem value="step-1">
|
|
349
|
-
<StepLabel>建立帳號</StepLabel>
|
|
350
|
-
</StepItem>
|
|
351
|
-
<StepItem value="step-2">
|
|
352
|
-
<StepLabel>驗證 Email</StepLabel>
|
|
353
|
-
<StepDescription>發送確認信至你的信箱</StepDescription>
|
|
354
|
-
</StepItem>
|
|
355
|
-
<StepItem value="step-3">
|
|
356
|
-
<StepLabel>設定團隊</StepLabel>
|
|
357
|
-
<StepDescription>
|
|
358
|
-
命名你的工作區、選擇方案、匯入現有專案;這個步驟結束後可隨時在設定頁
|
|
359
|
-
調整
|
|
360
|
-
</StepDescription>
|
|
361
|
-
</StepItem>
|
|
362
|
-
<StepItem value="step-4">
|
|
363
|
-
<StepLabel>邀請成員</StepLabel>
|
|
364
|
-
</StepItem>
|
|
365
|
-
</Steps>
|
|
366
|
-
</div>
|
|
367
|
-
))}
|
|
368
|
-
</div>
|
|
369
|
-
),
|
|
370
|
-
}
|
|
333
|
+
// @story-trait-rationale: MixedDescription(欄節奏驗證 grid)retired 2026-06-11 per audit
|
|
334
|
+
// EXAMPLE_REDUNDANT — indicator 對齊 label 第一行的 column rhythm 已由 anatomy「欄位節奏」+
|
|
335
|
+
// principles「規則:指示欄節奏一致」雙層 own;展示層不重複 trait 驗證 grid。
|