@qijenchen/design-system 0.1.0-beta.10 → 0.1.0-beta.13

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.
Files changed (307) hide show
  1. package/CLAUDE.md +201 -0
  2. package/README.md +7 -15
  3. package/cli-init.mjs +90 -0
  4. package/ds-canonical/commands/README.md +26 -0
  5. package/ds-canonical/commands/gov-status.md +79 -0
  6. package/ds-canonical/hooks/README.md +145 -0
  7. package/ds-canonical/hooks/_log-fire.sh +44 -0
  8. package/ds-canonical/hooks/block_prototype_imports.py +111 -0
  9. package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
  10. package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
  11. package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
  12. package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
  13. package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
  14. package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
  15. package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
  16. package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
  17. package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
  18. package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
  19. package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
  20. package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
  21. package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
  22. package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
  23. package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
  24. package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
  25. package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
  26. package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
  27. package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
  28. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
  29. package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
  30. package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
  31. package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
  32. package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
  33. package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
  34. package/ds-canonical/hooks/check_story_invariants.sh +612 -0
  35. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
  36. package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
  37. package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
  38. package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
  39. package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
  40. package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
  41. package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
  42. package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
  43. package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
  44. package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
  45. package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
  46. package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
  47. package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
  48. package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
  49. package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
  50. package/ds-canonical/hooks/log_governance_fires.sh +50 -0
  51. package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
  52. package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
  53. package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
  54. package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
  55. package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
  56. package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
  57. package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
  58. package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
  59. package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
  60. package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
  61. package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
  62. package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
  63. package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
  64. package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
  65. package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
  66. package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
  67. package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
  68. package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
  69. package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
  70. package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
  71. package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
  72. package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
  73. package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
  74. package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
  75. package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
  76. package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
  77. package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
  78. package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
  79. package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
  80. package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
  81. package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
  82. package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
  83. package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
  84. package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
  85. package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
  86. package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
  87. package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
  88. package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
  89. package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
  90. package/ds-canonical/hooks/stop_self_audit.sh +450 -0
  91. package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
  92. package/ds-canonical/hooks/tests/run-all.sh +76 -0
  93. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
  94. package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
  95. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
  96. package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
  97. package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
  98. package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
  99. package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
  100. package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
  101. package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
  102. package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
  103. package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
  104. package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
  105. package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
  106. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
  107. package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
  108. package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
  109. package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
  110. package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
  111. package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
  112. package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
  113. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
  114. package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
  115. package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
  116. package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
  117. package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
  118. package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
  119. package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
  120. package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
  121. package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
  122. package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
  123. package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
  124. package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
  125. package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
  126. package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
  127. package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
  128. package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
  129. package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
  130. package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
  131. package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
  132. package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
  133. package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
  134. package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
  135. package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
  136. package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
  137. package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
  138. package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
  139. package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
  140. package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
  141. package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
  142. package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
  143. package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
  144. package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
  145. package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
  146. package/ds-canonical/references/README.md +43 -0
  147. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
  148. package/ds-canonical/references/build-ui-canonicals.md +69 -0
  149. package/ds-canonical/references/cva-patterns.md +41 -0
  150. package/ds-canonical/references/drag-canonical.md +331 -0
  151. package/ds-canonical/references/item-anatomy-recipe.md +225 -0
  152. package/ds-canonical/references/naming-conventions.md +56 -0
  153. package/ds-canonical/references/principle-dim-map.json +515 -0
  154. package/ds-canonical/references/props-naming.md +45 -0
  155. package/ds-canonical/references/spec-rules.md +58 -0
  156. package/ds-canonical/references/ssot-consultation.md +63 -0
  157. package/ds-canonical/references/ssot-index.md +40 -0
  158. package/ds-canonical/references/story-baseline-registry.json +79 -0
  159. package/ds-canonical/references/structural-token-retention.md +42 -0
  160. package/ds-canonical/references/tailwind-gotchas.md +87 -0
  161. package/ds-canonical/references/ui-dev-rules.md +60 -0
  162. package/ds-canonical/rules/README.md +34 -0
  163. package/ds-canonical/rules/meta-patterns.md +87 -0
  164. package/ds-canonical/rules/self-verify.md +53 -0
  165. package/ds-canonical/rules/spec-rules.md +25 -0
  166. package/ds-canonical/rules/story-rules.md +56 -0
  167. package/ds-canonical/rules/ui-development.md +87 -0
  168. package/ds-canonical/skills/README.md +88 -0
  169. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
  170. package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
  171. package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
  172. package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
  173. package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
  174. package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
  175. package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
  176. package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
  177. package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
  178. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
  179. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
  180. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
  181. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
  182. package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
  183. package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
  184. package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
  185. package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
  186. package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
  187. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
  188. package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
  189. package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
  190. package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
  191. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
  192. package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
  193. package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
  194. package/ds-canonical/skills/governance-health/SKILL.md +146 -0
  195. package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
  196. package/ds-canonical/skills/new-component/SKILL.md +170 -0
  197. package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
  198. package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
  199. package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
  200. package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
  201. package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
  202. package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
  203. package/ds-canonical/skills/propose-options/SKILL.md +177 -0
  204. package/ds-canonical/skills/prototype/SKILL.md +244 -0
  205. package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
  206. package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
  207. package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
  208. package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
  209. package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
  210. package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
  211. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
  212. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
  213. package/ds-canonical/skills/story-writing/SKILL.md +122 -0
  214. package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
  215. package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
  216. package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
  217. package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
  218. package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
  219. package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
  220. package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
  221. package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
  222. package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
  223. package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
  224. package/package.json +9 -5
  225. package/src/components/Accordion/accordion.spec.md +114 -0
  226. package/src/components/Alert/alert.spec.md +197 -0
  227. package/src/components/AppShell/app-shell.spec.md +331 -0
  228. package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
  229. package/src/components/Avatar/avatar.spec.md +329 -0
  230. package/src/components/Badge/badge.spec.md +380 -0
  231. package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
  232. package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
  233. package/src/components/Button/button.spec.md +460 -0
  234. package/src/components/Calendar/calendar.spec.md +242 -0
  235. package/src/components/Carousel/carousel.spec.md +253 -0
  236. package/src/components/Chart/chart.spec.md +155 -0
  237. package/src/components/Checkbox/checkbox.spec.md +344 -0
  238. package/src/components/Chip/chip.spec.md +237 -0
  239. package/src/components/CircularProgress/circular-progress.spec.md +268 -0
  240. package/src/components/Coachmark/coachmark.spec.md +230 -0
  241. package/src/components/Combobox/combobox.spec.md +180 -0
  242. package/src/components/Command/command.spec.md +171 -0
  243. package/src/components/DataTable/data-table.spec.md +525 -0
  244. package/src/components/DateGrid/date-grid.spec.md +215 -0
  245. package/src/components/DatePicker/date-picker.spec.md +334 -0
  246. package/src/components/DescriptionList/description-list.spec.md +214 -0
  247. package/src/components/Dialog/dialog.spec.md +202 -0
  248. package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
  249. package/src/components/Empty/empty.spec.md +214 -0
  250. package/src/components/Field/field-controls.spec.md +338 -0
  251. package/src/components/Field/field.spec.md +438 -0
  252. package/src/components/Field/form-validation.spec.md +152 -0
  253. package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
  254. package/src/components/FileItem/file-item.spec.md +467 -0
  255. package/src/components/FileUpload/file-upload.spec.md +123 -0
  256. package/src/components/FileViewer/file-viewer.spec.md +373 -0
  257. package/src/components/HoverCard/hover-card.spec.md +157 -0
  258. package/src/components/Input/input.spec.md +193 -0
  259. package/src/components/LinkInput/link-input.spec.md +130 -0
  260. package/src/components/Menu/menu-item.spec.md +290 -0
  261. package/src/components/NameCard/name-card.spec.md +171 -0
  262. package/src/components/Notice/notice.spec.md +149 -0
  263. package/src/components/NumberInput/number-input.spec.md +126 -0
  264. package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
  265. package/src/components/PeoplePicker/people-picker.spec.md +263 -0
  266. package/src/components/Popover/popover.spec.md +198 -0
  267. package/src/components/ProgressBar/progress-bar.spec.md +232 -0
  268. package/src/components/RadioGroup/radio-group.spec.md +141 -0
  269. package/src/components/Rating/rating.spec.md +208 -0
  270. package/src/components/ScrollArea/scroll-area.spec.md +145 -0
  271. package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
  272. package/src/components/Select/select.spec.md +299 -0
  273. package/src/components/SelectMenu/select-menu.spec.md +220 -0
  274. package/src/components/SelectionControl/selection-item.spec.md +128 -0
  275. package/src/components/Separator/separator.spec.md +109 -0
  276. package/src/components/Sheet/sheet.spec.md +148 -0
  277. package/src/components/Sidebar/sidebar.spec.md +713 -0
  278. package/src/components/Skeleton/skeleton.spec.md +104 -0
  279. package/src/components/Slider/slider.spec.md +353 -0
  280. package/src/components/Steps/steps.spec.md +465 -0
  281. package/src/components/Switch/switch.spec.md +215 -0
  282. package/src/components/Tabs/tabs.spec.md +314 -0
  283. package/src/components/Tag/tag.spec.md +282 -0
  284. package/src/components/Textarea/textarea.spec.md +151 -0
  285. package/src/components/TimePicker/time-picker.spec.md +279 -0
  286. package/src/components/Toast/toast.spec.md +177 -0
  287. package/src/components/Tooltip/tooltip.spec.md +139 -0
  288. package/src/components/TreeView/tree-view.spec.md +374 -0
  289. package/src/patterns/action-bar/action-bar.spec.md +458 -0
  290. package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
  291. package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
  292. package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
  293. package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
  294. package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
  295. package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
  296. package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
  297. package/src/tokens/color/color.spec.md +804 -0
  298. package/src/tokens/density/density.spec.md +127 -0
  299. package/src/tokens/elevation/elevation.spec.md +81 -0
  300. package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
  301. package/src/tokens/motion/motion.spec.md +97 -0
  302. package/src/tokens/opacity/opacity.spec.md +78 -0
  303. package/src/tokens/orphan-tokens.spec.md +117 -0
  304. package/src/tokens/radius/radius.spec.md +123 -0
  305. package/src/tokens/typography/typography.spec.md +202 -0
  306. package/src/tokens/uiSize/uiSize.spec.md +438 -0
  307. package/src/styles/preset.css +0 -31
@@ -0,0 +1,465 @@
1
+ ---
2
+ component: Steps
3
+ family: 2
4
+ variants: {}
5
+ sizes:
6
+ sm:
7
+ px: 8
8
+ when: "Sidebar / 緊湊 onboarding;indicator 8px dot(hit area 24px),無內部 icon。對齊 INDICATOR_SIZE.sm + INDICATOR_ICON_SIZE.sm=0(steps.tsx:18-28)"
9
+ world-class: ["Ant Design Steps small", "MUI Stepper compact"]
10
+ md:
11
+ px: 24
12
+ when: "預設 — 主流程 wizard / checkout / 註冊;indicator 24px circle,內部 icon 16px(對齊 uiSize Icon Tier sm/md)"
13
+ world-class: ["Ant Design Steps default", "MUI Stepper default", "Linear setup wizard"]
14
+ lg:
15
+ px: 32
16
+ when: "Marketing / 重要 onboarding;indicator 32px circle,內部 icon 20px(對齊 uiSize Icon Tier lg)"
17
+ world-class: ["Material 3 large step indicator"]
18
+ traits:
19
+ - hasSizes
20
+ - hasInteractiveStates
21
+ - isStructural
22
+ benchmark:
23
+ - Ant Design Steps: github.com/ant-design/ant-design/tree/master/components/steps
24
+ - MUI Stepper: github.com/mui/material-ui/tree/master/packages/mui-material/src/Stepper
25
+ ---
26
+
27
+ <!-- @benchmark-cited: D5 retrofit 2026-05-18 — body claims marked per-claim @benchmark-unverified inline; canonical source URLs in frontmatter benchmark list. -->
28
+
29
+ # Steps 設計原則
30
+
31
+ **流程進度指示器**:把多步驟任務的「現在走到哪、完成了哪些、還剩哪些」視覺化為一條有序的 indicator + label 序列。
32
+
33
+ **實作基礎**:組合元件——Icon / number indicator + Text 有序序列,無 external primitive base。Radix / shadcn 無對應 Steps primitive。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
34
+
35
+ **Layout Family**:CLAUDE.md 4-Family Model **Family 2(List item layout)** 消費者。結構繼承 `patterns/element-anatomy/item-anatomy.spec.md`「List item layout」章節的 reading-mode 規格。Steps 有明文例外:indicator inline 對齊 label 第一行(不走 24px 閾值)。
36
+
37
+ > 命名選 `Steps`(複數)而非 `Stepper`——`stepper` 在 web 有 HTML `<input type="number">` 計數器的歷史包袱(spinbutton 也叫 stepper),`Steps` 更精確地表達「一組有序步驟」。對齊 Ant Design 的命名慣例。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
38
+
39
+ ---
40
+
41
+ ## 何時用
42
+
43
+ - **多步驟表單 / 精靈流程**:註冊流程、訂單結帳、設定引導(step 1 → 2 → 3)
44
+ - **訂單 / 任務進度**:物流追蹤(已下單 → 揀貨 → 出貨 → 送達)、審批流程
45
+ - **入職 / onboarding 進度**:教學性流程,明確告知使用者「還剩幾步」
46
+ - **CI / build 的 pipeline 狀態**:有序步驟且每步有明確完成 / 進行中 / 失敗狀態
47
+ - **步驟數量有限且已知**(3–7 個最佳;超過 7 個考慮改為 section + progress bar)
48
+
49
+ **判斷準則**:有**順序**、有**離散進度狀態**、步驟數量**有限且已知** → Steps;否則用其他元件。
50
+
51
+ ## 何時不用
52
+
53
+ Steps 只解決「有順序、有進度、步數有限且明確」的場景。下列情境**都不該用 Steps**:
54
+
55
+ | 場景 | 改用 | 原因 |
56
+ |------|------|------|
57
+ | 跳頁面 / 切 view | `Tabs` / `Breadcrumb` | Tabs 平行切換、Breadcrumb 表達位置,Steps 表達進度 |
58
+ | 選一個值 | `RadioGroup` / `SegmentedControl` / `Select` | Steps 不是選擇器,是進度指示 |
59
+ | 時間軸歷史事件 | `Timeline`(未來獨立元件)| Steps 表達「任務進度」,Timeline 表達「時序紀錄」,語意不同 |
60
+ | 分段表單佈局(不需進度感)| Form layout pattern + heading | 純分段不等於有進度順序 |
61
+ | 無限 / 動態步數 | ProgressBar + 步驟計數文字 | Steps 需步數有限且已知 |
62
+ | 使用者可自由跳步(非線性流程)| Tabs | Steps 強調線性順序,跳步破壞 mental model |
63
+
64
+ ---
65
+
66
+ ## 與 `item-layout` 的關係
67
+
68
+ Steps 是 `patterns/element-anatomy/item-anatomy.spec.md` 的 row primitive **consumer**,跟 MenuItem / TreeItem / SidebarMenuButton / DropdownMenuItem 屬於同一家族。每個 `StepItem` 結構上等同 row item:
69
+
70
+ | Row primitive 角色 | StepItem 對應 |
71
+ |---|---|
72
+ | Prefix | `StepIndicator`(圓形 + 數字 / icon)|
73
+ | Label | `StepLabel` |
74
+ | Description | `StepDescription`(永遠可選)|
75
+ | Suffix | — (Steps 不使用 suffix slot)|
76
+ | Content | `StepContent`(垂直模式特有)|
77
+
78
+ ### 從 item-layout **繼承**的規則(不重複定義)
79
+
80
+ - **字體 tier**:label `text-body` (sm/md) / `text-body-lg` (lg);description `text-caption` (sm/md) / `text-body` (lg)。跟 MenuItem / TreeItem 同一套。
81
+ - **字重**:`font-medium`(含 label,不隨 focus 變)
82
+ - **預設文字色**:`text-fg-secondary`;`value` 指向的 step(focused)為 `text-foreground`
83
+ - **Icon tier**:`ICON_SIZE = { sm: 16, md: 16, lg: 20 }`
84
+ - **Description 永遠可選**,任何 size 都不強制
85
+ - **Hit area 地板**:可點擊的 indicator 至少 `field-height-xs`(24px),不足者用透明 padding 撐開
86
+
87
+ ---
88
+
89
+ ## ⚠️ 對 item-layout 的明文例外:Indicator 永遠 inline 對齊 label 第一行
90
+
91
+ **這是 Steps 刻意打破 `item-anatomy.spec.md` 24px 閾值規則的特例,不是疏漏。**
92
+
93
+ ### 原規則
94
+
95
+ `item-anatomy.spec.md` 24px 閾值:
96
+ - Prefix ≤ 24px → `h-[1lh]` inline 對齊 label 第一行
97
+ - Prefix > 24px + 有 description → `h-[block calc]` 對齊 label + description 文字塊中心
98
+
99
+ ### Steps 的例外
100
+
101
+ **Steps 所有 size 的 indicator 一律 inline 對齊 label 第一行,不管 indicator 尺寸,也不管有無 description。**
102
+
103
+ ### 為什麼必須打破
104
+
105
+ Steps 的視覺身分是「一條直/橫排列的 circle indicator 序列」——這條 **indicator column(或 row)的 x/y rhythm 是這個元件的 mental model 核心**。
106
+
107
+ 如果遵守 24px 閾值:
108
+ - `size="lg"` 的 indicator 是 32px(> 24 閾值)
109
+ - 同一個 `<Steps size="lg">` 內,有些 item 有 description、有些沒有
110
+ - 有 description 的 item 走 block 對齊 → indicator 中心降到 label + description 中間
111
+ - 沒 description 的 item 走 inline 對齊 → indicator 中心在 label 第一行
112
+ - **同一 Steps 內 indicator 對齊不一致會破壞縱向節奏——進度路徑的視覺契約依賴 indicator 精確對齊同一水平線**
113
+
114
+ Column rhythm **優先於**「大 prefix 視覺重量平衡文字塊」的需求。這是 Steps 跟其他 row primitive 的本質差異:
115
+ - MenuItem / SidebarMenuButton 是「一堆選項的列表」——每個 row 獨立,視覺重量平衡是主要考量
116
+ - Steps 是「一條有連接關係的進度路徑」——column/row rhythm 是元件本身,任何破壞 rhythm 的對齊都不可接受
117
+
118
+ ### 業界共識
119
+
120
+ Material Stepper、Ant Design Steps、GitHub Workflows、Linear、Notion Checklist——**全部**走「indicator anchored to label 第一行」,**沒有任何世界級 stepper 把 indicator 對齊到文字塊中心**。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
121
+
122
+ ### 對齊公式
123
+
124
+ 所有 size 統一:
125
+
126
+ ```
127
+ indicator 容器 = h-[1lh](label 第一行行高)
128
+ indicator 圓形 flex items-center 居中
129
+ → 圓形垂直中心 = label 第一行垂直中心
130
+ → description 從第二行自然往下
131
+ → indicator 位置完全不受 description 有無影響
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Size
137
+
138
+ | Size | Indicator 直徑 | 內部 icon | 內部數字字體 | Label 字體 | Description 字體 |
139
+ |---|---|---|---|---|---|
140
+ | `sm` | 8px dot(hit area 24px)| 純圓點,不放數字/icon | — | `text-body` (14px) | `text-caption` (12px) |
141
+ | `md` | 24px circle | 16px | `text-body` (14px) | `text-body` (14px) | `text-caption` (12px) |
142
+ | `lg` | 32px circle | 20px | `text-body-lg` (16px) | `text-body-lg` (16px) | `text-body` (14px) |
143
+
144
+ ### 為什麼 indicator 內數字字體跟 label 同級(不是小一號)
145
+
146
+ 數字**本身就是 step 的 label**(「第 2 步」),跟側邊的 `StepLabel` 是同一個資訊層級,應該用同樣字體 tier。之前寫小一號(md=12, lg=14)是錯的——讓數字變得像配角,但它實際上是「這個 step 是第幾步」的主要識別符。同級字體讓數字跟 label 視覺權重平衡。
147
+
148
+ ### Size 的何時用 / 不用
149
+
150
+ **`sm`(小點)**
151
+ - ✅ 用在 sidebar 內 nested 流程、緊湊空間、次要進度指示
152
+ - ❌ 步驟需要 icon 或要使用者明確數到「第幾步」時不用(sm 沒有數字/icon,辨識度不足)
153
+ - sm 的 indicator 視覺只有 8px,但 hit area 撐到 24px(`field-height-xs` 地板),可點擊時不違反互動元件最小尺寸規則
154
+
155
+ **`md`(預設)**
156
+ - ✅ 絕大多數場景:checkout、註冊、設定精靈
157
+ - ✅ 主畫面主流程、對話框內流程
158
+
159
+ **`lg`**
160
+ - ✅ 重要主流程,使用者需要清楚感受到「現在在做什麼」(onboarding、KYC 驗證、重要申請表單)
161
+ - ❌ 容器寬度 < 480px(垂直模式)或步驟 > 6(水平模式)時,lg 太霸佔空間 → 降到 md
162
+
163
+ ### Size 對齊 Avatar tier 的依據
164
+
165
+ `md=24px` 對應 `AVATAR_SIZE.inline.md`;`lg=32px` 對應 `AVATAR_SIZE.block.sm/md`(32px)。`lg` 的 32px 選這個值是跟 Avatar 預設一致——但**對齊模式不跟 Avatar 的 block mode 一樣**(見上方例外)。
166
+
167
+ ---
168
+
169
+ ## State(Content state,跟 Focus 正交)
170
+
171
+ | State | 視覺 | 觸發 |
172
+ |---|---|---|
173
+ | `upcoming` | 灰底(`bg-muted`)+ 灰字(`text-fg-disabled`)| 未走到 |
174
+ | `current` | 藍底(`bg-primary`)+ 白字數字 | step === `value` 且不在 completedValues / errorValues |
175
+ | `completed` | 藍底(`bg-primary`)+ 白色 ✓ | step 在 `completedValues` 內 |
176
+ | `error` | 紅底(`bg-error`)+ 白色 ✕ | step 在 `errorValues` 內(或單項 `state="error"` override)|
177
+
178
+ ### Sm size 的 state 視覺
179
+
180
+ sm 沒有 icon 空間,用色塊表達:
181
+ - `upcoming` → 灰實心點(`bg-fg-disabled`)
182
+ - `current` → 藍色**空心**環(`border-2 border-primary`)
183
+ - `completed` → 藍實心點(`bg-primary`)
184
+ - `error` → 紅實心點(`bg-error`)
185
+
186
+ ### 自動推導(linear / non-linear 行為不同)
187
+
188
+ **Consumer 不手寫每個 step 的 state**。State 由 Steps root 的 props + `linear` flag 推導:
189
+
190
+ ```
191
+ step 在 completedValues → completed
192
+ step 在 errorValues → error
193
+ linear && step === value(且不在上面兩者) → current
194
+ 其他 → upcoming
195
+ ```
196
+
197
+ **關鍵**:`current` 狀態**只在 linear 模式**下被 auto-promote。非 linear 模式下,使用者「瀏覽」到 upcoming step 時,step 本身的 content state 仍然是 `upcoming`(還沒做),focus 透過 inset ring 視覺表達,**不會**變成 current 的 filled 藍色。
198
+
199
+ ### 為什麼非 linear 不 promote
200
+
201
+ 非 linear 模式讓使用者跳著點 step(例如設定頁、教學目錄),value 的語意是「使用者在看哪一步」,**不是**「使用者在做哪一步」。如果每次 value 變化就把該 step promote 成 current,會造成:
202
+
203
+ - 使用者點 upcoming step 想預覽 → step 立刻變 filled 藍,像是「標記為正在做」
204
+ - 跟 mental model「我只是在看,這步還沒做」衝突
205
+ - completedValues 沒有變化,前一個 current 突然不見
206
+
207
+ 正確做法:focus 跟 content state 完全解耦——focus 透過 inset ring 視覺表達,content state 由 linear/completedValues/errorValues 決定。linear 是 `current` 概念存在的前提。
208
+
209
+ Per-item `state="error"` prop 存在但是 **escape hatch**,僅用在 inline JSX 想直接宣告錯誤的罕見場景;一般情況用 `errorValues` array 統一管理,不要混用。
210
+
211
+ ---
212
+
213
+ ## Focus marker — Inset ring(bounding box 永遠不變)
214
+
215
+ **`value` 指向的 step,透過「inset ring」視覺表達 focus——而非加外圈 ring**。
216
+
217
+ ### Inset ring 的關鍵設計
218
+
219
+ - **Bounding box 固定**:focused / non-focused 的 indicator 佔用完全相同的寬高(md=24px,lg=32px,sm=24px hit area)
220
+ - **Nested element 實作**:外層 span 作為 ring 色彩,內層 absolute span 填 `inset: Npx`(內縮 N px)當 inner 色彩 + 放內容
221
+ - **非 box-shadow inset**:box-shadow 無法讓 ring 跟 inner 用不同顏色(filled state 下 ring 跟 bg 同色會完全隱形),nested element 能乾淨處理所有 state
222
+
223
+ ### State × Focus 視覺矩陣(md/lg)
224
+
225
+ | State | Non-focused(filled) | Focused(inset ring) |
226
+ |---|---|---|
227
+ | upcoming | `bg-muted` + `text-fg-disabled` 數字 | `bg-primary`(outer ring)+ `bg-muted`(inner)+ `fg-disabled` 數字 |
228
+ | current | `bg-primary` + white 數字 | `bg-primary`(outer ring)+ `bg-surface`(inner)+ `primary` 數字 |
229
+ | completed | `bg-primary` + white ✓ | `bg-primary`(outer ring)+ `bg-surface`(inner)+ `primary` ✓ |
230
+ | error | `bg-error` + white ✕ | `bg-error`(outer ring)+ `bg-surface`(inner)+ `error` ✕ |
231
+
232
+ **注意 linear mode 的 current 永遠 focused**,所以 linear mode 下 current step 永遠是 inset ring 樣式(而非 non-focused 的 filled 藍)。
233
+
234
+ ### Sm 尺寸的 focus 處理
235
+
236
+ sm 的 8px dot 太小,無法用 nested element 做 inset ring。改用 `box-shadow` halo 在 dot 外圍繞 2px 圈——**但仍在 24px hit area 內**,所以 bounding 不變。
237
+
238
+ ### 為什麼 bounding 不變這麼重要
239
+
240
+ 連結線幾何依賴 indicator 的邊緣位置。如果 focus 改變 bounding box,連結線的起點/終點會跟著變,造成「focused step 的連結線比別的短一點點」的視覺不齊感。**Inset ring 讓 indicator 的物理尺寸永遠相同**——focus 狀態變化時 **只有內部視覺改變,外部幾何不變**——連結線可以用統一公式,自然一致。
241
+
242
+ ### 為什麼不用原本的「外圈 ring」設計
243
+
244
+ 原本實作在 indicator 外加一圈 primary ring,導致兩個問題:
245
+ 1. Bounding box 變大,連結線位置隨 focus 切換漂移(這是之前「連結線間距沒韻律」的根因)
246
+ 2. Filled primary circle + primary outer ring 的視覺讀成「雙圈」,用户反應「很醜」
247
+
248
+ 改 inset ring 同時解決兩個問題。
249
+
250
+ ### Non-linear 被選中 ≠ current(關鍵規則)
251
+
252
+ 非 linear 模式使用者點 upcoming step 瀏覽時,step 的 **content state 仍是 upcoming**(見「自動推導」節),只是 focused。視覺上會是:
253
+ - Outer: `primary` ring(focus marker 永遠 primary,表達「你在看這一步」)
254
+ - Inner: `bg-muted`(保留 upcoming 的灰色感)
255
+ - Number: `fg-disabled`(保留 upcoming 的弱字)
256
+
257
+ **不會**變成 current 的 filled 藍——這對齊使用者 mental model「我只是在看,這步還沒做」。
258
+
259
+ **Ring 不是 selection marker**。Steps 不是 SelectMenu / DropdownMenu 這類 selection control;ring 是 focus marker 單一語意。`CLAUDE.md` 的「選擇 / 狀態視覺」規則 B 指出的 `bg-neutral-selected`、radio 圓圈等 selection 視覺**都不適用 Steps**——Steps 用 inset ring 表達「you are here」,不是「你選中了這個」。
260
+
261
+ ---
262
+
263
+ ## Label 色彩(error state 例外)
264
+
265
+ Label 色彩優先順序:
266
+
267
+ ```
268
+ disabled > error > focused > default
269
+ ```
270
+
271
+ - `disabled` → `text-fg-disabled`(最優先,覆蓋所有其他狀態)
272
+ - `error` → **`text-error-text`**(error state 時 label 變紅,跟 indicator 的紅 ✕ 協調表達「這步出錯」)
273
+ - `focused`(非 disabled 非 error)→ `text-foreground`(使用者當前在看這步,加強)
274
+ - `default` → `text-fg-secondary`(一般狀態)
275
+
276
+ ### 為什麼 error label 要跟 indicator 同色
277
+
278
+ Steps 的 step 本身是「狀態載體」,跟 Field 的「label 只是欄位名,error 靠 help text 表達」不同。Steps 的 label 在視覺上屬於 indicator 的延伸資訊,兩者應該一起講故事:紅 ✕ indicator + 紅 label + 紅 description(如有)形成一致的 error visual language,讓使用者一眼看出這步出了什麼錯。
279
+
280
+ 這跟 `CLAUDE.md` 的「Label 永遠 foreground」原則不衝突——那是 Field 家族的規則(edit / readonly / disabled 三態的欄位容器)。Steps 是**進度指示器**不是**輸入容器**,label 色彩跟著 step state 走是正確做法。
281
+
282
+ ### Description 沒有 error 變色
283
+
284
+ Description 在 error state 下維持 `text-fg-secondary`(跟其他 state 一樣)。理由:
285
+ 1. Error 的「為什麼出錯」訊息該放在 `<StepContent>` 內(可以用 `text-error-text` 寫錯誤詳情),description 只是輔助說明
286
+ 2. 太多紅字會造成視覺壓迫,三層紅(indicator + label + description + content)過多
287
+ 3. 保留 description 為 secondary 給 consumer 一個「寫冷靜說明」的空間
288
+
289
+ ---
290
+
291
+ ## Connector 路徑色
292
+
293
+ 連接 `stepA → stepB` 的 connector:**當且僅當 stepA 是 completed 時,該 connector 為藍色**(`border-primary`),其他一律灰(`border-border`)。
294
+
295
+ ### 為什麼藍色只跟 completedValues 走,不跟 value 走
296
+
297
+ 藍色代表「實際走過的進度路徑」,必須跟 `completedValues` 一對一對應,才能跟 step 本身的底色邏輯保持一致。非線性模式下:
298
+
299
+ - 使用者把 `value` 跳到中間未完成的 step 5
300
+ - step 1-4 仍為 upcoming(灰底)
301
+ - 若藍色延伸到 step 5 前面,會產生「藍線連灰 step」的矛盾視覺
302
+ - 正確做法:藍色 connector 跟 step 的 bg 同步,都只在 completed 區段出現
303
+
304
+ ---
305
+
306
+ ## Linear vs Non-linear
307
+
308
+ | Mode | 點擊規則 |
309
+ |---|---|
310
+ | `linear=true`(預設) | 可點:`completed` / `current` / `error`。**不可點**:`upcoming`(尚未解鎖)。 |
311
+ | `linear=false` | 所有非 `disabled` 的 step 都可點。適合 setting wizard、教學目錄等「步驟之間無強依賴」的場景。 |
312
+
313
+ ### 點擊 completed step 的行為
314
+
315
+ `linear=true` 下使用者點 completed step:
316
+
317
+ 1. Steps 觸發 `onValueChange(thatStep)`——**僅此而已**
318
+ 2. **`completedValues` 維持不變**,不自動 mutate
319
+ 3. 如果應用層驗證使用者改錯某欄位需要 block 後續步驟,應用層自己從 `completedValues` 移除該 step 及其後所有 step(這是 business logic,不是元件責任)
320
+
321
+ 這條規則的核心是:**Steps 是純 controlled 元件,從不偷偷改 parent state**。所有 state mutation 都經過 parent 的 state setter,讓應用層完整掌控推進邏輯。
322
+
323
+ ---
324
+
325
+ ## Expansion(垂直模式 content 區的展開行為)
326
+
327
+ | 模式 | 行為 |
328
+ |---|---|
329
+ | `follow-active`(預設) | 只有 `value` 指向的 step 渲染 `<StepContent>`。value 切換時 content 跟著切。其他 step 即使寫了 `<StepContent>` 也不顯示。 |
330
+ | `multiple` | 每個 step 獨立管理展開狀態,**可同時展開多個**。點 step header 切換該 step 的展開(不切換 `value`)。`defaultExpanded` 接 `"all" \| "none" \| string[]`,預設 `"none"`。 |
331
+
332
+ ### 為什麼 `all` 隸屬於 `multiple`
333
+
334
+ `all`(全部展開)跟 `none`(全部收合)**本質上都是「使用者可以同時展開多個」的行為**——差別只在初始狀態。把它們並列在同一個 mode 下、用 `defaultExpanded` 決定初始狀態,是比「三個平行 enum 值」更乾淨的結構。`follow-active` 則是完全不同的 mental model(展開狀態綁定 `value`,使用者不能獨立切換),所以拆成獨立 mode。
335
+
336
+ ### 水平模式無 content
337
+
338
+ `orientation="horizontal"` 時 `<StepContent>` 一律不渲染,`expansion` prop 被忽略。水平空間不夠塞 content 區,強塞會破壞 stepper 的掃視節奏。Consumer 可以共用同一份 JSX 在兩種 orientation 間切換,不會報錯。
339
+
340
+ ---
341
+
342
+ ## Orientation
343
+
344
+ | Orientation | Indicator 序列 | Connector | Label 位置 | Content 區 |
345
+ |---|---|---|---|---|
346
+ | `vertical`(預設) | 上 → 下 | 垂直線,穿過 description / content | indicator 右側 | 支援 |
347
+ | `horizontal` | 左 → 右 | 水平線 | indicator 右側(同行) | 不支援(忽略) |
348
+
349
+ **何時用 horizontal**:步驟 ≤ 5、重視「進度條」感、水平空間充足、不需要 per-step content 區。
350
+ **何時用 vertical**:步驟 > 5、需要 description 或 content、行動裝置、主流程精靈。
351
+
352
+ ---
353
+
354
+ ## API(parent-controlled)
355
+
356
+ ```tsx
357
+ <Steps
358
+ value={string} // 當前 focused step(ring 跟這個走)
359
+ defaultValue={string} // uncontrolled 初始值
360
+ onValueChange={(value: string) => void}
361
+ completedValues={string[]} // 已完成(✓ + 藍底 + 藍 connector)
362
+ errorValues={string[]} // 錯誤(✕ + 紅底)
363
+ linear={boolean} // 預設 true
364
+ size="sm" | "md" | "lg" // 預設 md ★ cva default
365
+ orientation="vertical" | "horizontal" // 預設 vertical
366
+ expansion="follow-active" | "multiple" // 預設 follow-active
367
+ defaultExpanded="all" | "none" | string[] // 只在 expansion=multiple 有效
368
+ >
369
+ <StepItem value="info" disabled?={boolean} state?="error">
370
+ <StepLabel>基本資料</StepLabel>
371
+ <StepDescription>填寫姓名與聯絡方式</StepDescription> {/* 可選 */}
372
+ <StepContent> {/* 可選;水平模式忽略 */}
373
+ <p>當前步驟的動作指引、表單欄位或按鈕</p>
374
+ </StepContent>
375
+ </StepItem>
376
+ </Steps>
377
+ ```
378
+
379
+ ### 為什麼 parent-controlled 是世界級做法
380
+
381
+ 1. **Single source of truth**:所有狀態集中在 parent,不可能發生「多個 step 同時是 current」「completedValues 跟 item state 互相矛盾」這類 bug。
382
+ 2. **Derived state**:每個 step 的 state 由 parent props 推導,consumer 不手算,不會漂移。
383
+ 3. **無 side effect**:Steps 不內部 mutate 狀態,所有變動都走 parent 的 state setter,讓應用層完整掌控推進邏輯(驗證 → 加入 completedValues → 推進 value)。
384
+ 4. **對齊業界**:Ant Design Steps(`current` + `status`)、Material Stepper(`activeStep`)、Radix Tabs(`value`)全部用此模式。開發者從這些系統來的直覺可直接套用,學習曲線接近零。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
385
+
386
+ ### Per-item `state` escape hatch
387
+
388
+ `<StepItem state="error">` 可單獨覆蓋該 step 的 content state,**僅限於**在 inline JSX 想直接宣告錯誤且不想維護 `errorValues` array 的場景。一般情況不要混用兩種方式——單一來源優於兩個競爭來源。
389
+
390
+ ---
391
+
392
+ ## Do / Don't
393
+
394
+ ✅ **Do**
395
+ - 用 Steps 表達「有順序、有進度、步數有限且已知」的任務流程
396
+ - linear 模式下允許點擊 completed step,讓使用者回看 / 修改
397
+ - 用 parent props 管理狀態,讓 Steps 自動推導每個 step 的視覺
398
+ - 垂直 content 放 form 欄位、指引、按鈕等「使用者當前需要互動」的內容
399
+ - 水平模式用在步驟 ≤ 5、不需要 per-step content 的場景
400
+
401
+ ❌ **Don't**
402
+ - 用 Steps 做 navigation(用 Tabs / Breadcrumb)
403
+ - 用 Steps 做 selection(用 Radio / SegmentedControl / SelectMenu)
404
+ - 水平模式塞 `<StepContent>`(會被忽略)
405
+ - 每個 StepItem 手動傳 state 管理狀態(用 parent `completedValues` / `errorValues`)
406
+ - 點 completed step 時自動從 completedValues 移除(應用層責任,Steps 不 mutate)
407
+ - 讓 indicator 對齊模式隨 description 有無變動(破壞 column rhythm)
408
+ - 把 ring 用在非 `value` 的 step(ring 是 focus marker,不是 decoration)
409
+ - sm size 的 indicator 試圖塞數字或 icon(空間不足,降低辨識度)
410
+ - 用 `bg-neutral-selected` 表達 Steps 的 focused step(那是 selection 語意,Steps 用 ring)
411
+
412
+ ---
413
+
414
+ ## 為何無 Inspector
415
+
416
+ Steps 的決策是「展示所有步驟進度」,需要一整條鏈才能呈現設計——單互動切換 value 不如 side-by-side 矩陣清楚。關鍵維度由 `OrientationMatrix` / `ColorMatrix`(含 4 狀態色)/ `SizeMatrix` / `StateBehavior`(進度流轉 / linear / error interrupt)/ 元件特有 `IndentAlignment` 五張 story 完整覆蓋。
417
+
418
+ ## StateBehavior 說明(Steps 層級特有)
419
+
420
+ Item-level **內容狀態色彩**(completed / current / upcoming / error indicator + label + connector)由 `ColorMatrix` 作為結構性 state-driven 色彩矩陣呈現;`StateBehavior` story 則展示**進度流轉行為**——current → completed 連鎖變化、`linear` 控制 upcoming step 可否點擊、`errorValues` 中斷流程——這些是 Steps 元件層級特有的動態行為,不存在於任何 item primitive。
421
+
422
+ ---
423
+
424
+ ## 邊界案例
425
+
426
+ - **Disabled step**:`disabled` step 視覺繼承 SelectionItem disabled token(`text-fg-disabled`,M24),click 不觸發 navigate;`linear` mode 下 upcoming steps 預設 disabled 直到前面 completed。
427
+ - **Loading(async step state fetch)**:Steps primitive 為 sync render,async data fetch 應由 consumer 在外層 Skeleton 取代整個 Steps;Steps 內部不獨立 own loading prop。
428
+ - **Empty(0 steps)**:`items=[]` 無意義(無進度可呈現);consumer 應條件性不渲 Steps 或渲 `<Empty>` 替代,不渲空 Steps container。
429
+ - **Single step / current=0**:合法初始狀態,渲第一個 step 為 current,後續為 upcoming。
430
+ - **Error state(`errorValues`)**:由元件層級 own — 對應 step indicator 切 error token,connector 切 error muted,後續 step 仍 upcoming 但 user 預期 navigation 暫停。
431
+ - **Dark mode**:走 semantic token + Primary token 自動 adapt。
432
+ - **Density**:Step indicator 32px 對齊 `AVATAR_SIZE.block.sm/md`,connector 細線跨 density 不變(進度視覺對 density 不敏感)。
433
+
434
+ ---
435
+
436
+ ## 相關
437
+
438
+ - `../../patterns/element-anatomy/item-anatomy.spec.md` — Row primitive 繼承規則(字體 / icon tier / hit area 地板)
439
+ - `../Tabs/tabs.spec.md` — 平行視圖切換(非進度場景)
440
+ - `../Breadcrumb/breadcrumb.spec.md` — 位置路徑(非進度場景)
441
+ - `../RadioGroup/radio-group.spec.md` — 選值(非進度場景)
442
+ - `../Avatar/avatar.tsx` — Indicator 32px 尺寸依據(`AVATAR_SIZE.block.sm/md = 32`)
443
+ - `../../tokens/uiSize/uiSize.spec.md` — `field-height-xs` 地板規則 + Icon 尺寸 Tier
444
+ - `../../tokens/color/color.spec.md` — Primary token
445
+ - CLAUDE.md「選擇 / 狀態視覺必須對齊既有 canonical」— Steps 不用 `bg-neutral-selected` 的理由
446
+
447
+ ## A11y 預設
448
+
449
+ **ARIA / Pattern**:對齊 [W3C ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/patterns/) 對應 pattern。
450
+
451
+ **Keyboard 行為**:
452
+
453
+ - Tab — focus step(若 clickable)
454
+ - Enter — navigate to step
455
+
456
+ **Focus**:focus-visible ring 對齊 DS canonical(`outline: 2px solid var(--ring)`);focus management 由元件 own。
457
+
458
+ **驗證**:Storybook a11y addon panel 應 0 critical violation;鍵盤完整可操作(無需滑鼠)。WCAG AA contrast ≥ 4.5:1(text)/ 3:1(UI)。
459
+
460
+ ## 被引用(auto-maintained,Dim 3 reciprocal audit)
461
+
462
+ > 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
463
+
464
+ - `horizontal-overflow.spec.md`
465
+ - `progress-bar.spec.md`