@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,713 @@
1
+ ---
2
+ component: Sidebar
3
+ family: 1
4
+ variants:
5
+ default:
6
+ when: "標準導覽 row — 參與 single-selection,fg-secondary → hover foreground / active neutral-selected"
7
+ world-class: ["Linear sidebar nav item", "Notion sidebar item", "VS Code Activity Bar primary item"]
8
+ meta:
9
+ when: "Section 底部命令 row(「Show more」「載入更多」「+ 新增專案」);font-normal + fg-muted,不參與 selection"
10
+ world-class: ["Linear 'Show N more'", "Notion 'Show N more'", "Slack 'Show more'", "Gmail Labels 'More'"]
11
+ sizes:
12
+ sm:
13
+ px: 28
14
+ when: "次導覽 / 設定頁分類 / 緊湊空間;對齊 field-height-sm"
15
+ world-class: ["VS Code Settings sidebar(28)", "Atlassian secondary nav compact"]
16
+ md:
17
+ px: 32
18
+ when: "預設 — 應用程式主導覽 row;對齊 TreeView / MenuItem 同 size 視覺無縫"
19
+ world-class: ["Linear sidebar default", "Notion sidebar default", "Figma left panel"]
20
+ lg:
21
+ px: 36
22
+ when: "重要主導覽(高 touch 區、horizontal headroom 大)、icon-prominent workspace switcher"
23
+ world-class: ["Slack workspace sidebar large", "Discord server list large"]
24
+ traits:
25
+ - hasVariants
26
+ - hasSizes
27
+ - hasInteractiveStates
28
+ - isStructural
29
+ benchmark:
30
+ - Ant Design Layout (Sider): github.com/ant-design/ant-design/tree/master/components/layout
31
+ - MUI Drawer: github.com/mui/material-ui/tree/master/packages/mui-material/src/Drawer
32
+ - Polaris Navigation: github.com/Shopify/polaris/tree/main/polaris-react/src/components/Navigation
33
+ ---
34
+
35
+ <!-- @benchmark-cited: D5 retrofit 2026-05-18 — body claims marked per-claim @benchmark-unverified inline; canonical source URLs in frontmatter benchmark list. -->
36
+
37
+ # Sidebar 設計原則
38
+
39
+ > **Foundational SSOT rationale**(2026-04-24 approved,cap 800):
40
+ > Sidebar 有獨立 `sidebarMenuButtonVariants` cva(對齊 MenuItem 但獨立實作,同步風險見 item-anatomy.spec「SidebarMenuButton 獨立實作風險」)+ 20+ Sidebar-specific features SSOT(Chrome header/footer 高度 / Collapsible / Icon 模式 / SidebarTrigger 位置 / Mobile 行為 / 持久化 / 快捷鍵 / Group 收合 / Single selection / Inline actions / Keyboard shortcuts),scope > 單一 MenuItem consumer。Long-term 考慮 refactor 消費 menuItemVariants base(詳 `.claude/planning/row-primitive-consolidation.md`)— 若 refactor 成功,本 spec 可縮到 ~300。
41
+
42
+ ## 定位
43
+
44
+ **應用程式的主導覽外殼**——頁面固定的側邊導覽容器,支援展開 / 收合、桌機與行動裝置的不同形態、扁平選單與階層樹兩種內容。
45
+
46
+ **實作基礎**:基於 Radix Collapsible + Radix Slot(shadcn Sidebar 模式改寫)+ 橋接 DS token。
47
+
48
+ **Layout Family**:CLAUDE.md 4-Family Model **Family 1(Menu item layout)** 消費者。結構繼承 `patterns/element-anatomy/item-anatomy.spec.md`「Menu item layout」章節的 scanning-mode 規格。
49
+
50
+ **不是**:NavigationMenu(水平導覽)、Tabs(同層切換)、Command Palette(跨頁搜尋)、Sheet / Drawer(暫時性面板)。Sidebar 是**持續存在**的主骨架。
51
+
52
+ ---
53
+
54
+ ## 何時用
55
+
56
+ - **多頁 app 的主導覽**:Slack、Linear、Notion、Figma 的左側 workspace + channel / project 清單
57
+ - **需要在所有頁面持續存在的次導覽**:settings 頁的分類、文件的章節跳轉
58
+ - **workspace 切換 + 功能分組並存**:頂部 workspace switcher + 下方常用功能 + 底部 settings
59
+ - **需要展開 / 收合但不消失**:小螢幕收合為 icon bar,大螢幕展開完整 label
60
+
61
+ ## 何時不用
62
+
63
+ | 場景 | 改用 | 原因 |
64
+ |------|------|------|
65
+ | 頁面頂部水平導覽(單頁品牌、行銷站、電商)| 自訂 Nav / NavigationMenu | Sidebar 專於垂直結構、持續存在 |
66
+ | 同層切換內容(總覽 / 成員 / 設定)| `Tabs` | Tabs 切換的是平行視圖,不是跨頁導覽 |
67
+ | 暫時性的側邊面板(filter、detail pane)| `Sheet` | Sheet 可以被關閉消失,Sidebar 持續存在 |
68
+ | 跨頁搜尋 / 快速跳轉 | `Command`(Cmd+K palette)| Sidebar 是持久清單,Command 是即時查詢 |
69
+ | 少於 3 個頂層項目的 app | 頂部 tab bar 或直接頁面 | Sidebar 的視覺成本對小 app 過高 |
70
+
71
+ ---
72
+
73
+ ## 結構
74
+
75
+ ```
76
+ SidebarProvider ← 全域 context(open 狀態、cookie、快捷鍵)
77
+ Sidebar ← 主容器(variant + collapsible + side)
78
+ SidebarHeader ← 頂部:logo、workspace switcher
79
+ SidebarContent ← 中間可捲動區
80
+ SidebarGroup ← 分組容器(可多個,純視覺分段)
81
+ SidebarGroupLabel ← 分組標題(icon 模式自動隱藏)
82
+ SidebarGroupContent ← 放以下其中一種:
83
+
84
+ ├─ SidebarMenu 扁平選單(1 層、有限可列舉)
85
+ │ SidebarMenuItem
86
+ │ SidebarMenuButton ← 必須有 icon
87
+ │ SidebarMenuBadge ← 右側 badge
88
+ │ SidebarMenuAction ← hover 浮出的 action
89
+
90
+ └─ TreeView 階層樹(user data、任意深度)
91
+ SidebarFooter ← 底部:user menu、settings 觸發器
92
+ SidebarRail ← 邊緣細條,點擊切換收合(可選)
93
+ SidebarTrigger ← 展開 / 收合按鈕(可放 sidebar 內或外)
94
+ ```
95
+
96
+ **不使用 shadcn 原版的 `SidebarMenuSub` / `SidebarMenuSubItem`**——見下方內容形態規則。
97
+
98
+ ---
99
+
100
+ ## Size(sm / md / lg)— 透過 SidebarProvider 一次設定
101
+
102
+ `SidebarProvider` 接受 `size` prop(預設 `"md"`),透過 context 傳給所有 row 元件(`SidebarMenuButton` / `SidebarGroupLabel` / `SidebarMenuSkeleton`)。這對齊 `DropdownMenu` 的 `SizeContext` 架構——**consumer 設一次,整個 sidebar 的 row 都跟著變**。
103
+
104
+ ```tsx
105
+ <SidebarProvider size="lg">
106
+ <Sidebar>
107
+ <SidebarContent>
108
+ <SidebarGroup>
109
+ <SidebarGroupContent>
110
+ <SidebarMenu>
111
+ {/* 這裡所有 button 自動繼承 size="lg",不用一個一個傳 */}
112
+ <SidebarMenuItem>
113
+ <SidebarMenuButton startIcon={Inbox}>Inbox</SidebarMenuButton>
114
+ </SidebarMenuItem>
115
+ </SidebarMenu>
116
+ </SidebarGroupContent>
117
+ </SidebarGroup>
118
+ </SidebarContent>
119
+ </Sidebar>
120
+ </SidebarProvider>
121
+ ```
122
+
123
+ **個別覆寫**(少見):若某個 button 特別需要不同 size,可在 `SidebarMenuButton` 傳 `size` prop 覆寫 context 值。
124
+
125
+ **Row geometry 對齊 item-layout**:sm/md/lg 三個 size 的 row height / text size / icon size 跟 `TreeView` / `MenuItem` 完全一致——跨元件視覺無縫。
126
+
127
+ **Row size 跟 density 的差別**:
128
+ - **Size variant**(sm/md/lg)是 **consumer 的風格選擇**,決定 sidebar 整體 row 大小
129
+ - **Density**(md/lg)是**全域 UI 設定**,影響所有 `--field-height-*` tokens 的實際值
130
+ - 兩者**獨立**:size="md" 在 density="md" 下是 32px row、在 density="lg" 下自動變 36px row
131
+
132
+ **Chrome header 不跟 size 變**:`SidebarHeader` / `SidebarFooter` 固定用 `var(--chrome-header-height)`,只跟 **density** 連動,不跟 `size` prop 變——因為 header 是結構槽位,不是 row。
133
+
134
+ ---
135
+
136
+ ## 內容形態選擇(核心設計決策)
137
+
138
+ Sidebar 有兩種正交的內容形態,consumer 嚴格擇一或混用:
139
+
140
+ | 形態 | 元件 | 深度 | 數量 | Icon 模式 |
141
+ |------|------|------|------|----------|
142
+ | **扁平導覽** | `SidebarMenu` | **嚴格 1 層** | **有限可列舉** | ✅ 顯示 icon + tooltip |
143
+ | **階層樹** | `TreeView` | 任意 | 任意 | ❌ 整區隱藏 |
144
+
145
+ ### 判斷規則
146
+
147
+ > **SidebarMenu 只接受「1 層 + designer 能在設計時列舉所有項目」**。
148
+ > 任何不符合的情況——深度 > 1、數量不可列舉、使用者可 runtime 新增——一律 TreeView。
149
+
150
+ ### 為什麼只有 1 層
151
+
152
+ Linear、Notion、Slack、VS Code、Figma、Gmail——**沒有任何頂級產品在 sidebar 主選單用語意階層**。凡有階層都是 TreeView(user data)或 SidebarGroup(純視覺分段)。shadcn 的 `SidebarMenuSub` 是 demo 便利 API,本 design system 完全不 export,避免誤用。
153
+
154
+ ### 「Projects > A / B」這類
155
+
156
+ User-generated data **一律 TreeView**,不論數量——即使現在只有 3 個 project,未來會長。唯一例外是 designer 在設計時就固定死的 5 個 module 後台,這種情境極少。
157
+
158
+ ### Settings 這類有子頁的頁面
159
+
160
+ 三條正確路徑,**全部不用 SidebarMenuSub**:
161
+
162
+ #### 路徑 A:In-page secondary nav(推薦,最世界級)
163
+
164
+ Sidebar 只放一顆 `Settings`,點進去後在 **Settings 頁面內部**用左側 rail 或 Tabs 呈現子頁。子頁屬於 Settings 頁面的內部狀態,不佔 sidebar 位置。
165
+
166
+ 代表:Linear(modal + 左 rail)、GitHub(repo settings 頁內 rail)、Notion(modal + tabs)。
167
+
168
+ #### 路徑 B:SidebarGroup 扁平化
169
+
170
+ 子頁等重要、都需一鍵直達時,用 SidebarGroupLabel 當純視覺分段標題,**子項全部是獨立頂層 SidebarMenuItem**(各自有 icon、各自在 icon 模式顯示)。
171
+
172
+ 僅在子項確實高頻使用時才用,少見。
173
+
174
+ #### 路徑 C:User menu modal
175
+
176
+ Settings 不在 sidebar,從 footer 的 avatar / user menu 觸發 modal 或快捷鍵(`Cmd+,`)。適合低頻操作。
177
+
178
+ 代表:Linear、Slack、Discord。
179
+
180
+ #### A 和 C 並用
181
+
182
+ 大型產品通常**同時有 A 和 C**,依設定性質分流(Linear 的實際做法):
183
+
184
+ - **路徑 A**:功能性設定(workspace settings、project settings、team members、integrations)—— sidebar 有入口,點進去是完整頁面 + 內部 secondary nav
185
+ - **路徑 C**:個人偏好(theme、language、keyboard shortcuts、personal notifications)—— 從 user menu 叫出 modal,不佔 sidebar
186
+
187
+ 判斷:**需要協作、會分享連結給別人看的設定 → A**;**只影響自己、低頻的偏好 → C**。
188
+
189
+ ### 混用
190
+
191
+ Gmail / Linear 的標準版型:上方 SidebarGroup 放扁平主導覽(SidebarMenu),下方 SidebarGroup 放 user data(TreeView)。icon 模式下,扁平區顯示 icon + tooltip,TreeView 整段隱藏。
192
+
193
+ ---
194
+
195
+ ## Variant(視覺形態)
196
+
197
+ 目前只有一種:**`sidebar`**(貼齊 viewport 邊緣、與主內容共用邊界)。
198
+
199
+ **已移除 / 未實作的 variant**:
200
+ - **`floating`**(脫離邊緣的浮動面板):**刻意不做**。沒有可靠的「收合後預覽」互動(hover flyout 是 NN/g 反模式),單純換個圓角陰影的 floating 跟 `sidebar` 在功能上無差,徒增維護成本。如果未來需要卡片感,改用 `inset`
201
+ - **`inset`**(主內容浮起卡片):規劃中,未實作
202
+
203
+ ---
204
+
205
+ ## Chrome header / footer 高度:density-responsive shared token
206
+
207
+ `SidebarHeader` 和 `SidebarFooter` 的高度 = `var(--chrome-header-height)`,**不是寫死**,也**不是完全 content-based**。這個 token:
208
+
209
+ > **跨家族 SSOT pointer**:本元件 SidebarHeader 屬 **Chrome header(Fixed-h)家族**;border / padding / dismiss size / withTabs(tabs 進 header 時 border auto-suppress + tabs size 對應 + flush stack)的跨家族視覺契約 SSOT 詳 `patterns/header-canonical/header-canonical.spec.md`。本節僅 codify Sidebar 特有的高度 + token rationale。
210
+
211
+ - md density: `3rem`(48px)
212
+ - lg density: `3.5rem`(56px)
213
+ - **跨元件共享**:sidebar header、sidebar footer、主內容 page header 都用同一個 token
214
+ - **隨 density 同步變**
215
+
216
+ ### 為什麼是這個設計(不是 h-12 寫死 或 py-3 純 padding)
217
+
218
+ | 方案 | 外部對齊 | 內部 padding 比例 | 世界級? |
219
+ |---|---|---|---|
220
+ | A. 寫死 `h-12`(48px) | ✅ 跨元件同高 | ❌ lg density 下 button 撐高,chrome 固定 → padding 被擠壓到不足,比例破壞 | ❌ 破功 |
221
+ | B. 純 padding `py-3` | ❌ 不同 header 因 content 高度不同,無法對齊 | ✅ 內部 padding 固定 | ❌ 對齊破功 |
222
+ | C. **Density-responsive token**(本方案) | ✅ 跨元件同高(共享 token) | ✅ token 隨 density 放大,padding 比例維持 | ✅ |
223
+
224
+ **關鍵洞察**:chrome 的 content(button、icon)本身就是 density-responsive 的(綁 `--field-height-*`),chrome 容器如果不跟著 density 變,必然會擠壓。所以 chrome **必須跟 density 連動**,但**透過專屬 token,不直接綁 item size**。
225
+
226
+ ### 比例驗證
227
+
228
+ | Density | Header | Button md | 上下 padding |
229
+ |---|---|---|---|
230
+ | md | 48px | 32px | 8px |
231
+ | lg | 56px | 36px | 10px |
232
+
233
+ 比例維持一致,跨 density 視覺一致。
234
+
235
+ ### 不隨 item size variant 變
236
+
237
+ `SidebarMenuButton` 的 `size="sm/md/lg"` 是 **row 層級的選擇**(consumer 決定內容列的尺寸),跟 chrome 無關。Header 只跟 **density**(全域設定)綁定。
238
+
239
+ ### Chrome 內容的約束
240
+
241
+ 放在 SidebarHeader / SidebarFooter 裡的元件必須能容納在這個高度內:
242
+
243
+ - Avatar: `size={24}` —— **chrome header avatar canonical(density-fixed / row-size-fixed)**。consumer 用 **raw `<Avatar size={24}>`**(chrome header 不是 row context → 不該用 `<ItemAvatar>`)。對應 CSS local token `--chrome-header-avatar-size: 1.5rem`(`header-canonical.css`),sidebar 收合對齊公式消費此 token。詳 `header-canonical.spec.md`「4.5 Chrome header avatar SSOT」段 + `item-anatomy.spec.md:535` scope 限定段。
244
+ - Button: `size="sm"` 或 `size="md"`
245
+ - 單排 title 文字 + icon button
246
+
247
+ **不要**放超出高度的內容(多行 title、大按鈕等)——如果需要,代表誤用 header,改用獨立的 `SidebarContent` 區塊。
248
+
249
+ ### 跟 Modal header 的差別
250
+
251
+ Modal header 用 **padding-based**(`py-3` + content),因為 modal 是 ephemeral(自成一體),不需要外部對齊。兩種規則都是世界級,各自適用:
252
+
253
+ - **Chrome**(sidebar / page header):共享固定高度 token,density-responsive → 保證跨元件對齊
254
+ - **Ephemeral**(modal / dialog):padding-based → 保證內容適應性
255
+
256
+ ### Chrome 內的 text element:統一 typography
257
+
258
+ 所有住在 chrome header / footer 裡的 text element(workspace brand、page title、user name)**一律使用 `text-body-lg font-medium`**。
259
+
260
+ **原則:chrome 元素是 sibling,不用 size/weight 製造假階層**
261
+ - 不同 size → 會造成假階層,好像「A 是 B 的副標題」;chrome elements 實際上是並排的結構槽位,沒有從屬關係
262
+ - 不同 weight → 會造成「哪個比較重要」的語意混淆
263
+ - **「當前位置」的訊號由 sidebar active item(`bg-neutral-selected`)負責**,不靠 page title 的字重搶戲
264
+
265
+ ### 對照 Linear / Slack / Discord / Figma <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
266
+
267
+ | 產品 | Chrome text size | 做法 |
268
+ |---|---|---|
269
+ | Linear | 14-15px medium | 同 size 同 weight |
270
+ | Slack | 15-18px bold | 同 weight,稍有 size 差異 |
271
+ | Discord | 16px semibold | 同 size 同 weight |
272
+ | Figma | 13px regular | 同 size 同 weight |
273
+
274
+ 我們選 **`text-body-lg font-medium` 統一**,是世界級 chrome typography 的中庸做法——比 Linear(14-15px medium)字級大 1px / weight 一致,比 Slack(15-18px bold)字級略小且 weight 較輕避免 navigation 過度搶 attention,對齊 Discord(16px semibold)。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
275
+
276
+ ---
277
+
278
+ ## Collapsible(收合模式)
279
+
280
+ | Mode | 說明 | 適合 |
281
+ |------|------|------|
282
+ | **`offcanvas`** | 整個 sidebar 滑出畫面 | 內容優先、低頻導覽(Notion、Figma) |
283
+ | **`icon`** | 收合為 icon-only 細列,頂層 icon 仍可見可點 | 扁平導覽、高頻跨頁切換(Gmail、Slack)。**前提:所有 SidebarMenuItem 必須有 icon + 可導覽** |
284
+ | **`none`** | 不可收合 | 超簡單應用或 sidebar 是頁面核心(file explorer) |
285
+
286
+ ---
287
+
288
+ ## Icon 模式的行為規則
289
+
290
+ ### 規則 1:icon rail 上的每顆 icon 必須可導覽
291
+
292
+ 絕對不可有「點了沒反應」或「點了只是展開選單」的 icon。icon 列是收合狀態下唯一的導覽介面。
293
+
294
+ ### 規則 2:純分組 header 不可用 SidebarMenuItem
295
+
296
+ 只是用來分組下方 children(沒有自己的頁面)的項目,**必須用 SidebarGroup + SidebarGroupLabel**。`SidebarGroupLabel` 在 icon 模式自動隱藏,子 items 照常顯示;`SidebarMenuItem` 則會變成死 icon。
297
+
298
+ ### 規則 3:TreeView 在 icon 模式整個隱藏
299
+
300
+ 不做 icon 化、不做 flyout、不做 popover。Tree 無法壓縮成單排 icon,Gmail / Linear / Notion 一致隱藏。
301
+
302
+ ### 規則 4:重新看階層資料的唯一路徑 = 展開 sidebar
303
+
304
+ 不提供「點 icon 順便展開」的副作用——行為不可預測,熟練使用者要收合兩次。逃生艙由應用層搭配 Command Palette(Cmd+K)提供,不是 Sidebar 的責任。
305
+
306
+ ---
307
+
308
+ ## SidebarTrigger 位置(兩種 canonical pattern)
309
+
310
+ **核心判準**(唯一):**trigger 必須在 sidebar 任何 state(offcanvas 收掉 / icon / expanded)下都保持可見**。違反這條 = dead state(offcanvas 收掉就再也打不開)。
311
+
312
+ 兩種 canonical pattern,都符合判準,選哪種看 app shell 的整體 layout:
313
+
314
+ ### Pattern A:Full-height sidebar + 主內容 header
315
+
316
+ - Sidebar 從畫面頂部一路延伸到底部
317
+ - 主內容區自帶 header(page title bar)
318
+ - **Trigger 位置**:主內容 header 的最左(在 page title 之前)
319
+ - **代表**:Linear / Notion / Figma / Cursor / VS Code / Slack
320
+
321
+ ### Pattern B:Global top app bar + sidebar drawer
322
+
323
+ - 頂部 bar 跨整個畫面寬度(包含 sidebar 跟 main content 的水平範圍)
324
+ - Sidebar 在 top bar **下方**,只佔頁面剩餘高度
325
+ - **Trigger 位置**:top bar 的最左(視覺位置在 sidebar 上方對齊,實際屬於 top bar 的一部分;top bar 永遠存在,所以 offcanvas 收掉 sidebar 後 trigger 仍然在)
326
+ - **代表**:**Gmail / Google Calendar / Google Drive / Material Design apps** / 多數企業 dashboard
327
+
328
+ ### 判斷:trigger 在哪 = top bar 在哪
329
+
330
+ ```
331
+ Pattern A(無 global top bar):
332
+ ┌────────┬─────────────────┐
333
+ │ │ ☰ Page Title │ ← trigger 在主內容 header 最左
334
+ │Sidebar │ │
335
+ │ │ (content) │
336
+ └────────┴─────────────────┘
337
+
338
+ Pattern B(有 global top bar):
339
+ ┌──────────────────────────┐
340
+ │ ☰ Logo Search Nav │ ← trigger 在 global top bar 最左
341
+ ├────────┬─────────────────┤
342
+ │ │ │
343
+ │Sidebar │ (content) │
344
+ │ │ │
345
+ └────────┴─────────────────┘
346
+ ```
347
+
348
+ **搭配鍵盤快捷**:`⌘B` / `Ctrl+B` 是 industry-standard,已內建,不該改。
349
+
350
+ **禁止**:
351
+
352
+ - ❌ Trigger 放在 sidebar **內部** sidebar 元件之內(SidebarHeader 內)——offcanvas 收掉就消失,dead state
353
+ - ❌ 放在 header **最右**——違反 F-pattern 閱讀動線
354
+ - ❌ 使用浮動按鈕 / FAB——mobile app pattern,跟桌面 sidebar 語意不合
355
+ - ❌ 同一 app 內混用兩種 pattern——使用者肌肉記憶失效
356
+
357
+ **判斷你的 app 該用哪個**:
358
+
359
+ - 有 global top bar(logo / search / 全域 nav 在頂部)→ **Pattern B**,trigger 在 top bar 最左
360
+ - 沒有 global top bar(每個頁面自己 header)→ **Pattern A**,trigger 在主內容 header 最左
361
+ - 介於兩者之間 → 看主導需求,但 **不要混用**
362
+
363
+ ---
364
+
365
+ ## Sidebar 全域 prefix 對齊(`uniformPrefix`,預設關閉)
366
+
367
+ `<SidebarProvider>` 預設 `uniformPrefix={false}`——大宗情境(全 icon 主導覽 / 全 avatar user 列表 / 純 TreeView)各自獨立節奏即可,**不需要這個 prop**。
368
+
369
+ ### 什麼時候 opt-in `uniformPrefix={true}`
370
+
371
+ **唯一明確的場景:sidebar 內有大量 brand logo 和一般 icon 混用,使用者期待 label 齊左**。
372
+
373
+ 具體 use case:
374
+
375
+ - **Linear / Raycast / Notion 風格的 integrations 清單**:主導覽是 lucide icon(Home / Inbox / Team,16px),底下接著一串 integrations(GitHub / Slack / Figma / Jira,24px brand logo)。兩種 prefix 都是「導覽目的地」,語意等價,只是 visual hint 不同——使用者期待 label 齊左掃視
376
+ - **App launcher / workspace switcher**:每個 workspace 有自己的 brand logo,夾雜系統性的 icon-based 項目
377
+ - **CMS / connected apps**:每個來源(Notion / Google Docs / Confluence)有自己的 logo,跟 icon-based 的「我的草稿」「最近開啟」等並列
378
+
379
+ **不是這個 use case 就不要開**:
380
+
381
+ - ❌ 全 icon 主導覽 + 全 avatar 的 user footer → 語意不同層級,應該分 SidebarGroup,不該強迫對齊
382
+ - ❌ 純美感「我覺得對齊比較整齊」沒有真實混用情境 → 預設行為已經對(全 icon 自然就齊左)
383
+ - ❌ 偶爾一兩個 avatar 混在 icon 群裡 → 通常代表設計分組沒做好,先檢查語意,別用 `uniformPrefix` 補
384
+
385
+ ### API
386
+
387
+ ```tsx
388
+ // 預設:大宗情境,不需要這個 prop
389
+ <SidebarProvider>
390
+ <Sidebar>...</Sidebar>
391
+ </SidebarProvider>
392
+
393
+ // Opt-in:有 brand logo + icon 混用的 integration sidebar
394
+ <SidebarProvider uniformPrefix>
395
+ <Sidebar>
396
+ <SidebarContent>
397
+ <SidebarGroup>
398
+ <SidebarMenu>
399
+ {/* 主導覽:icon prefix */}
400
+ <SidebarMenuButton id="home" startIcon={Home}>Home</SidebarMenuButton>
401
+ <SidebarMenuButton id="inbox" startIcon={Inbox}>Inbox</SidebarMenuButton>
402
+
403
+ {/* Integrations:brand logo prefix(同 menu,語意等價)*/}
404
+ <SidebarMenuButton id="github" asChild>
405
+ <button>
406
+ <ItemAvatar shape="square" alt="GitHub" src="/logos/github.svg" />
407
+ <ItemLabel>GitHub</ItemLabel>
408
+ </button>
409
+ </SidebarMenuButton>
410
+ <SidebarMenuButton id="slack" asChild>
411
+ <button>
412
+ <ItemAvatar shape="square" alt="Slack" src="/logos/slack.svg" />
413
+ <ItemLabel>Slack</ItemLabel>
414
+ </button>
415
+ </SidebarMenuButton>
416
+ </SidebarMenu>
417
+ </SidebarGroup>
418
+ </SidebarContent>
419
+ </Sidebar>
420
+ </SidebarProvider>
421
+ ```
422
+
423
+ `uniformPrefix` 開啟後:`Home` / `Inbox` 的 16px icon 在 24px 槽內 `justify-center`,`GitHub` / `Slack` 的 24px logo 填滿槽——四個 label x 完全對齊。
424
+
425
+ ### 機制細節
426
+
427
+ - 啟用後,`SidebarProvider` wrapper 的 CSS `:has()` selector 偵測整個子樹同時存在 `data-prefix-type="icon"` 和 `"avatar"` 的後代(由 `<ItemIcon>` / `<ItemAvatar>` 自動標記)
428
+ - **混用偵測命中** → 套用固定 24px 槽
429
+ - **沒混用** → 偵測失敗,完全 no-op,行為跟預設一樣(零 runtime 成本)
430
+
431
+ 所以即使你預設開啟 `uniformPrefix`,只有真正混用時才會動到排版。但**我們仍然預設關閉**,因為:explicit > implicit——consumer 沒主動要求,系統不該在背後做事,源碼讀起來才透明。
432
+
433
+ ### 為什麼預設關閉(不是 always-on auto)
434
+
435
+ CSS `:has()` 不混用時零成本,理論上 always-on 也沒事。我們刻意預設關閉的理由是 **API 立場**:
436
+
437
+ 1. **Explicit > implicit**:CSS auto-detect 是「藏在背後的魔法」。預設關閉表示「sidebar 的排版行為從你寫的 prop 一眼看出」,沒有隱含規則
438
+ 2. **強迫 consumer 想清楚 use case**:打 `uniformPrefix` 一個字代表「我有意要做混用對齊」,reviewer / 未來維護者讀到這個 prop 就知道為什麼
439
+
440
+ ### 沒有 per-menu override
441
+
442
+ `SidebarMenu` 不接 `uniformPrefix`。曾經設計過(三層級組合),但零真實 caller。如果未來需要「全域對齊但這個 menu 不對齊」這種精細控制,那時候會有具體 use case 推導出正確 API,而不是現在猜想。
443
+
444
+ 詳細實作機制(`<ItemIcon>` / `<ItemAvatar>` 自動標記 `data-prefix-type`、`getUniformPrefixSlotStyle()` 算槽寬、CSS variable cascade)見 `item-anatomy.spec.md` 的「Uniform prefix slot」節。
445
+
446
+ ---
447
+
448
+ ## SidebarMenuButton variant
449
+
450
+ | Variant | 視覺 | 語意 | Single selection | 典型用法 |
451
+ |---|---|---|---|---|
452
+ | **`default`**(預設) | `text-fg-secondary`, `font-medium`, active → `bg-neutral-selected` | 導覽目的地(nav item) | ✅ 參與,接 `id` prop | Dashboard / Inbox / Settings / user data item |
453
+ | **`meta`** | `text-fg-muted`, `font-normal`, **永不 active** | 命令 row(非導覽) | ❌ 不參與,不傳 `id`(傳了也會被忽略) | 「查看更多」/「載入更多」/「+ 新增專案」/「Show all」 |
454
+
455
+ **為什麼需要 meta variant**:section 底部的「查看更多」如果用 default variant,會有三個問題:
456
+
457
+ 1. 視覺重量跟真正的 nav item 相同 → 使用者誤以為是另一個資料項
458
+ 2. 會被選中變 active → 搶走真正 nav item 的 selection 焦點
459
+ 3. consumer 得手動覆寫 `className="text-fg-muted"`、手動不傳 id → 每個 consumer 都有可能漏
460
+
461
+ variant=meta 把這三件事做成結構性保證:樣式自動退、selection 自動跳過、型別層不需要特判。
462
+
463
+ **API**:
464
+
465
+ ```tsx
466
+ <SidebarMenuButton
467
+ variant="meta"
468
+ startIcon={ChevronDown}
469
+ onClick={loadMore}
470
+ >
471
+ 查看更多 (12)
472
+ </SidebarMenuButton>
473
+ ```
474
+
475
+ **世界級對照**:Linear「Show N more」、Notion「Show N more」、Slack「Show more」、Gmail Labels「More」——全部是「section 底部的 muted 命令 row」,行為與視覺一致。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
476
+
477
+ **禁止**:
478
+
479
+ - ❌ meta variant 傳 `id`——語意矛盾,meta 不該參與 selection
480
+ - ❌ default variant 手動 `className="text-fg-muted"` 模擬 meta 效果——改用 `variant="meta"`,結構對齊
481
+ - ❌ meta variant 放在 section 中間——meta 只屬於 section **底部**,位置本身是「這是尾巴」的訊號
482
+
483
+ ---
484
+
485
+ ## Single selection(整個 sidebar 同時只有一個 active item)
486
+
487
+ **規則**:不論 MainNav / TreeView / Favorites / 任何 group,**同一時間只有一個 item 被選中**。選任何 item 都會自動 deselect 其他。沒有例外——sidebar 的核心語意是「當下在哪頁」,多個 active 就失去意義。
488
+
489
+ **結構性保證**:`SidebarProvider` 內建 single-selection state,`SidebarMenuButton` 接 `id` prop 自動從 context 讀 `isActive`、自動在 `onClick` 呼叫 `setActiveId`。
490
+
491
+ ```tsx
492
+ // Controlled(router-driven,typical production 用法)
493
+ <SidebarProvider activeId={currentPath} onActiveChange={router.push}>
494
+ <SidebarMenuButton id="/dashboard" startIcon={LayoutDashboard}>Dashboard</SidebarMenuButton>
495
+ <SidebarMenuButton id="/inbox" startIcon={Inbox}>Inbox</SidebarMenuButton>
496
+ </SidebarProvider>
497
+
498
+ // Uncontrolled(demo / simple app)
499
+ <SidebarProvider defaultActiveId="dashboard">
500
+ <SidebarMenuButton id="dashboard" ...>Dashboard</SidebarMenuButton>
501
+ </SidebarProvider>
502
+ ```
503
+
504
+ **為什麼結構性強制**:過去曾寫出「忘記接 isActive / onClick 的啞 item」(stories 展示 inline action 時發生)— 外觀提供可點擊 affordance 但事件未連 state,產生誤導性互動(click 後永遠不進 active)。把 selection state 內建到 Provider、讓 button 接 `id` 就自動 wire,consumer **無法**寫出啞 item——沒傳 id 就失去 selection 能力,一眼看得出來。
505
+
506
+ **禁止**:
507
+
508
+ - ❌ SidebarMenuButton 不傳 `id`(除非確定這個 item 不參與 selection——極罕見,例如純按鈕 action)
509
+ - ❌ 手動維護每個 group 獨立的 activeId(違反 single-selection,會出現兩個 active)
510
+ - ❌ 同時用 `id`(自動)和 `isActive`(手動覆寫),除非 consumer 有明確的 override 理由(例如 router 尚未更新的 optimistic highlight)
511
+
512
+ **Router integration**:production 用法通常是 controlled mode——從 URL 算 `activeId`,`onActiveChange` 呼叫 router.push。uncontrolled mode 主要是 demo / Storybook 用。
513
+
514
+ ---
515
+
516
+ ## SidebarGroup 收合(`collapsible` prop)
517
+
518
+ `<SidebarGroup collapsible>` 把整個 group 升級成可點擊收合。內部用 Radix Collapsible 實作,**三件事自動發生**:
519
+
520
+ 1. `SidebarGroupLabel` 從純裝飾 header 變成 trigger(button),加 hover 狀態、`cursor-pointer`
521
+ 2. Label 尾端自動渲染 `ChevronRight` icon,open 時旋轉 90°
522
+ 3. `SidebarGroupContent` 被 `Collapsible.Content` 包起來,data-state 可驅動動畫
523
+
524
+ Consumer 不需要任何額外 code——只要加一個 prop:
525
+
526
+ ```tsx
527
+ <SidebarGroup collapsible defaultOpen={false}>
528
+ <SidebarGroupLabel>Projects</SidebarGroupLabel>
529
+ <SidebarGroupContent><TreeView>...</TreeView></SidebarGroupContent>
530
+ </SidebarGroup>
531
+ ```
532
+
533
+ **何時用**:
534
+ - ✅ 長清單需要讓使用者暫時收起(Projects / Favorites 等次要 section)
535
+ - ✅ Group 內容可選(使用者可能根本沒加任何 project)
536
+ - ❌ 主導覽 group(永遠要看見)
537
+ - ❌ 只有 1-2 個 item 的 group(收合徒增互動成本)
538
+
539
+ **為什麼 prop 放在 `SidebarGroup` 而非 `SidebarGroupLabel`**:「是否可收合」是結構層決定,影響 label(是否 trigger)+ content(是否 animated container)兩個 primitive。放在 label 上會讓 content 不知道該不該被 `Collapsible.Content` 包,形成 prop drilling。group 層用 React context 傳遞是標準做法。
540
+
541
+ ---
542
+
543
+ ## Inline actions(SidebarMenuButton suffix slot)
544
+
545
+ `<SidebarMenuButton inlineActions={[...]}>` 支援 suffix 放置 inline action button,搭配 `actionsReveal="hover"` 做 TreeView 風格的 hover-reveal。
546
+
547
+ **宣告式 API**,完全對齊 `uiSize.spec.md`「Inline Action」節:
548
+
549
+ ```tsx
550
+ <SidebarMenuButton
551
+ startIcon={Folder}
552
+ actionsReveal="hover"
553
+ inlineActions={[
554
+ { icon: MoreVertical, label: '更多', onClick: handleMore },
555
+ { icon: Plus, label: '新增', onClick: handleAdd },
556
+ ]}
557
+ >
558
+ 專案 Alpha
559
+ </SidebarMenuButton>
560
+ ```
561
+
562
+ **Consumer 不需要**:
563
+
564
+ - 指定 icon 尺寸(host 從 row size 查 `ICON_SIZE`)
565
+ - 寫 hover background span 的絕對定位 JSX(`ItemInlineAction` 內部封裝)
566
+ - 處理 Tooltip / `aria-label` / `cursor-pointer`(宣告式 config 自動帶)
567
+ - 計算 button 的 `paddingRight`(host 用 `N×icon + (N-1)×gap + loose + gap` 公式自動算)
568
+
569
+ **規格**(完全繼承 uiSize.spec.md):
570
+
571
+ | 項目 | 值 |
572
+ |---|---|
573
+ | Icon 尺寸 | `ICON_SIZE[size]`(16/16/20) |
574
+ | Hover bg 尺寸 | icon + 2(18/18/22) |
575
+ | Hover bg 圓角 | `rounded-md` (sm/md) / `rounded-md` (lg) |
576
+ | Icon 顏色 | `fg-muted` → `foreground` on hover/active |
577
+ | 多個 action 間距 | `gap-2`(8px) |
578
+ | 出現時機 | 預設永遠顯示;`actionsReveal="hover"` → row hover/focus 才淡入 |
579
+ | Icon 模式 | 整個 suffix 隱藏 |
580
+ | Host disabled 時 | 不渲染(遵守宿主 disabled 規則) |
581
+
582
+ **Canonical 實作**:`ItemInlineAction` + `ItemSuffix`(`item-layout.tsx`)。未來 DropdownMenuItem / TreeItem / Field / Tag 都應逐步遷移到這個共用元件,消除「每個 host 各自複製 18 行 JSX」的技術債——見 `item-anatomy.spec.md` 底部「Inline action 共用元件」節。
583
+
584
+ **何時用**:
585
+ - ✅ Favorites / Bookmarks 類 user data item 的 hover-reveal 「⋯」/「×」
586
+ - ✅ Project item 的 quick action(rename / delete)
587
+ - ❌ 主導覽 item(應該聚焦導覽意圖,不放行為按鈕)
588
+ - ❌ 收合選單的觸發器(用 `<SidebarGroup collapsible>` label trigger,不要塞在 suffix)
589
+
590
+ ---
591
+
592
+ ## Mobile 行為
593
+
594
+ `md` breakpoint(768px)以下自動切 **Sheet 抽屜**——從側邊滑入、覆蓋主內容、點外部或 Esc 關閉。Sheet 寬度用 `--sidebar-width-mobile`,**mobile 沒有 icon 模式**(細列在手機上既占空間又難點)。
595
+
596
+ Sheet 開啟狀態**不持久化**。
597
+
598
+ ---
599
+
600
+ ## 持久化與快捷鍵
601
+
602
+ - **Cookie**:`sidebar_state`, 7 天。SSR 環境下 `SidebarProvider` 必須接 `defaultOpen` 從 server cookie 傳入以避免 hydration flash
603
+ - **快捷鍵**:`Cmd+B` / `Ctrl+B` 切換收合(VS Code、Linear、shadcn 一致,不要發明新鍵)
604
+
605
+ ---
606
+
607
+ ## 尺寸規範
608
+
609
+ 元件 scope 的 design token,consumer 可覆寫:
610
+
611
+ | Token | 預設值 | 用途 |
612
+ |-------|--------|------|
613
+ | `--sidebar-width` | `17rem` | 展開寬度 |
614
+ | `--sidebar-width-icon` | `calc(2 * var(--layout-space-loose) + var(--sidebar-menu-icon-size))` | icon 模式寬度(2026-05-21 v3 撤回 `3rem` hardcode,改 geometry formula 保證 icon center x = loose + icon/2 在展開/收合一致;md=48 / lg=64,跟 chrome-header-height 解耦)|
615
+ | `--sidebar-menu-icon-size` | `1rem` (16px) | sidebar menu icon 大小(per ICON_SIZE.sm/md=16);size=lg 罕見 case override `1.25rem` |
616
+ | `--sidebar-width-mobile` | `18rem` | Mobile sheet 寬度 |
617
+
618
+ **用 rem**:跟隨 root font-size,支援 accessibility 等比例縮放。**不用 layoutSpace / uiSize 推導**:sidebar width 是容器維度,不是間距或元件內高度,語意不同;耦合會讓寬度跟間距連動。**16rem / 3rem / 18rem** 是 shadcn + 多數 SaaS 的事實標準,不要為獨特而改。
619
+
620
+ ---
621
+
622
+ ## 禁止事項
623
+
624
+ - ❌ **使用 SidebarMenuSub / 讓 SidebarMenu 超過 1 層**——用 TreeView 或 in-page secondary nav
625
+ - ❌ **Hover flyout / popover 顯示 tree 或 sub-items**——2000 年代 cascading menu 反模式,NN/g 多年反對
626
+ - ❌ **純分組 header 用 SidebarMenuItem**——icon 模式變死 icon,用 SidebarGroup
627
+ - ❌ **點 icon 順便展開 sidebar**(expandOnClick 副作用)——行為不可預測
628
+ - ❌ **把 user data 塞 SidebarMenu**——即使只有 3 項,只要使用者可新增就是 tree
629
+ - ❌ **在 Sidebar 內放路由邏輯**——路由是 consumer 的事,用 `asChild` 包自家 Link / router
630
+ - ❌ **硬寫寬度到子元件**——子元件應完全自適應 Sidebar 寬度
631
+ - ❌ **Mobile 保留 icon 模式**——只有全寬 sheet / 關閉兩種狀態
632
+
633
+ ---
634
+
635
+ ## 與其他元件的關係
636
+
637
+ - **TreeView**:放在 SidebarContent 內;icon 模式由 Sidebar 透過 CSS 自動隱藏;`context="sidebar"` 讓 TreeView 用 sidebar 的 padding token
638
+ - **Command(Cmd+K)**:icon 模式下深層頁面跳轉的逃生艙
639
+ - **Tabs**:Settings 等頁面的 in-page secondary nav
640
+ - **DropdownMenu**:SidebarHeader 的 workspace switcher、SidebarFooter 的 user menu
641
+ - **Avatar**:SidebarFooter 顯示當前使用者
642
+
643
+ ---
644
+
645
+ ## 判斷決策樹
646
+
647
+ ```
648
+ Variant:傳統工具型 → sidebar;現代 SaaS 卡片化 → inset;浮動面板 → floating
649
+
650
+ Collapsible:內容優先低頻導覽 → offcanvas;扁平高頻切換 → icon;超簡單 → none
651
+
652
+ 內容:
653
+ ├─ designer 1 層固定導覽 → SidebarMenu
654
+ ├─ user data / 階層 / 可新增 → TreeView
655
+ ├─ 兩者都有 → SidebarMenu + TreeView 分區
656
+ └─ Settings 等有子頁的頁面 → in-page secondary nav(不塞 sidebar)
657
+ ```
658
+
659
+ ---
660
+
661
+ ## 為何無 Inspector
662
+
663
+ Sidebar 的決策維度是「結構配置」(variant / collapsible / uniformPrefix / density)不是單一 prop——已由 `Overview`(結構樹)+ `SizeMatrix` + `ColorMatrix` + `StateBehavior` + `ChromeTokens` 五 story 完整覆蓋。互動 Inspector 切單一 prop 不如結構對照,且 Sidebar 外觀需要足夠的 nav 量才能展示——真實展示是 `Overview` 的 SidebarPreview 完整結構。
664
+
665
+ ## StateBehavior(Sidebar 層級特有)
666
+
667
+ Item-level default / hover / active / selected / disabled **色彩**完全共用 item-anatomy row primitive(`patterns/element-anatomy/item-anatomy.spec.md`),由 `ColorMatrix` 用 5 個 state 的完整 token 對照表承載(state-driven 色彩表)。Sidebar 的 `StateBehavior` story 則展示 **container 層級的結構狀態切換**:三種 `collapsible` 模式(offcanvas / icon / none)、Cmd+B / SidebarTrigger toggle、icon mode 下 label 隱藏 + Tooltip 代償、跨 session cookie 還原——這些是 shell 層級特有的行為,不存在於 row item primitive。
668
+
669
+ ---
670
+
671
+ ## A11y 預設
672
+
673
+ - **Landmark**:`<Sidebar>` 渲染 `<nav aria-label="Main">`(或 consumer 傳入更精確的 label,例「Workspace navigation」),作為 page-level navigation landmark,讓 SR user 直接跳轉。
674
+ - **Active item**:`SidebarMenuButton` 帶 `id` + 命中 `activeId` 時自動加 `aria-current="page"`,SR 朗讀「current page」。`variant="meta"` 不參與 selection 不加此 attribute。
675
+ - **快捷鍵不衝突**:`Cmd+B` / `Ctrl+B` 是 industry-standard(VS Code / Linear / shadcn),DS 內建並 `preventDefault` 避免穿透到 browser bookmark bar(`Cmd+B` 在 Safari 是 favorites);若 consumer 已有同鍵其他語意需 opt-out 透過 `SidebarProvider` `disableShortcut` prop。
676
+ - **Mobile sheet focus trap**:`md` breakpoint 以下切 Sheet 模式時,Radix Dialog 自帶 focus trap + Esc dismiss + restore focus to trigger(詳 sheet.spec.md)。
677
+ - **Collapsible group**:`<SidebarGroup collapsible>` 的 label trigger 帶 `aria-expanded` + `aria-controls` 指向 GroupContent id,SR 可朗讀展開狀態。
678
+ - **Sticky header / footer focus order**:Tab 順序按 DOM 順序 — Header → Content → Footer,SidebarTrigger 在 Pattern A/B 都位於 page top-left,Tab 第一站即可達。
679
+ - **不使用 `SidebarMenuSub`**:避免 nested menu aria-tree 複雜度,階層交給 TreeView(`role="tree"` + `aria-level`)。
680
+
681
+ ---
682
+
683
+ ## 邊界案例
684
+
685
+ - **Disabled item**:SidebarMenuButton 走 MenuItem primitive SSOT(`disabled` prop → `text-fg-disabled` + `aria-disabled=true` + 不觸發 onClick + 鍵盤導覽自動 skip)。
686
+ - **Loading(nav data-fetch)**:async nav tree fetch 時 consumer 應在對應 group 內渲 `<Skeleton>` line-stack(常見 3-5 條 sidebar nav skeleton 行)而非 Empty + spinner — Sidebar 是 chrome 不是 panel,loading 用 skeleton 更符合 chrome 持續存在的 affordance。對齊 Atlassian Sidebar / VS Code activity-bar idiom。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
687
+ - **Empty(no nav items)**:罕見場景(用戶無權限 / 全空 workspace)。若整個 group 無 item,consumer 應 conditional 不渲該 group(不渲空 group label);若整個 sidebar 無 item,可能該 hide sidebar(走 layout context 不渲)。不渲空白 sidebar。
688
+ - **Dark mode / density**:Sidebar 為 chrome surface,走 chrome-header token 自動 adapt;density 預設 lock 跟隨 app density chrome token,不獨立 own。
689
+ - **Collapsed mode(icon-only)**:已 codify(見 Sidebar collapsed mode 段);此時 label / endAction 隱藏,只留 icon + tooltip。
690
+
691
+ ---
692
+
693
+ ## 相關
694
+
695
+ - `../TreeView/tree-view.spec.md` — 階層樹元件(user data、任意深度)
696
+ - `../DropdownMenu/dropdown-menu.spec.md` — Header / Footer 常用的下拉選單
697
+ - `../Tabs/tabs.spec.md` — in-page secondary nav(不塞 sidebar 的子頁切換)
698
+ - `../Menu/menu-item.spec.md` — SidebarMenuButton 的 item-layout 共用規則
699
+ - Command palette(`components/Command/`,shadcn passthrough 無 spec)— icon 模式下的跳轉逃生艙
700
+ - Sheet(`components/Sheet/`,shadcn passthrough 無 spec)— 暫時性側邊面板的替代
701
+
702
+ ## 被引用(auto-maintained,Dim 3 reciprocal audit)
703
+
704
+ > 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
705
+
706
+ - `scroll-area.spec.md`
707
+ - `sheet.spec.md`
708
+
709
+ ## 被引用(auto-maintained,Dim 3 reciprocal audit)
710
+
711
+ > 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
712
+
713
+ - `app-shell.spec.md`