@qijenchen/design-system 0.1.0-beta.61 → 0.1.0-beta.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/CLAUDE.md +6 -6
  2. package/dist/components/Accordion/accordion.d.ts +1 -1
  3. package/dist/components/Accordion/accordion.js +1 -1
  4. package/dist/components/Accordion/accordion.js.map +1 -1
  5. package/dist/components/Alert/alert.d.ts +2 -2
  6. package/dist/components/Alert/alert.js +4 -3
  7. package/dist/components/Alert/alert.js.map +1 -1
  8. package/dist/components/AppShell/app-shell.d.ts.map +1 -1
  9. package/dist/components/AppShell/app-shell.js +4 -3
  10. package/dist/components/AppShell/app-shell.js.map +1 -1
  11. package/dist/components/Avatar/avatar.d.ts +1 -1
  12. package/dist/components/Avatar/avatar.js +2 -1
  13. package/dist/components/Avatar/avatar.js.map +1 -1
  14. package/dist/components/Badge/badge.d.ts +1 -1
  15. package/dist/components/Badge/badge.js +2 -1
  16. package/dist/components/Badge/badge.js.map +1 -1
  17. package/dist/components/Breadcrumb/breadcrumb.d.ts +1 -1
  18. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
  19. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  20. package/dist/components/Button/button.d.ts +5 -5
  21. package/dist/components/Button/button.d.ts.map +1 -1
  22. package/dist/components/Button/button.js +4 -3
  23. package/dist/components/Button/button.js.map +1 -1
  24. package/dist/components/Calendar/calendar.d.ts +1 -1
  25. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  26. package/dist/components/Calendar/calendar.js +80 -69
  27. package/dist/components/Calendar/calendar.js.map +1 -1
  28. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  29. package/dist/components/Carousel/carousel.js +5 -3
  30. package/dist/components/Carousel/carousel.js.map +1 -1
  31. package/dist/components/Checkbox/checkbox-group.d.ts +2 -1
  32. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
  33. package/dist/components/Checkbox/checkbox-group.js.map +1 -1
  34. package/dist/components/Checkbox/checkbox.d.ts +9 -3
  35. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  36. package/dist/components/Checkbox/checkbox.js +8 -3
  37. package/dist/components/Checkbox/checkbox.js.map +1 -1
  38. package/dist/components/Chip/chip.d.ts +2 -2
  39. package/dist/components/Chip/chip.js +3 -2
  40. package/dist/components/Chip/chip.js.map +1 -1
  41. package/dist/components/CircularProgress/circular-progress.d.ts +1 -1
  42. package/dist/components/CircularProgress/circular-progress.js +2 -1
  43. package/dist/components/CircularProgress/circular-progress.js.map +1 -1
  44. package/dist/components/Coachmark/coachmark.d.ts +4 -4
  45. package/dist/components/Coachmark/coachmark.js +2 -1
  46. package/dist/components/Coachmark/coachmark.js.map +1 -1
  47. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  48. package/dist/components/Combobox/combobox.js +17 -13
  49. package/dist/components/Combobox/combobox.js.map +1 -1
  50. package/dist/components/Command/command.d.ts +4 -0
  51. package/dist/components/Command/command.d.ts.map +1 -1
  52. package/dist/components/Command/command.js.map +1 -1
  53. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  54. package/dist/components/DataTable/data-table.js.map +1 -1
  55. package/dist/components/DateGrid/date-grid.d.ts +8 -4
  56. package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
  57. package/dist/components/DateGrid/date-grid.js +2 -2
  58. package/dist/components/DateGrid/date-grid.js.map +1 -1
  59. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  60. package/dist/components/DatePicker/date-picker.js +6 -4
  61. package/dist/components/DatePicker/date-picker.js.map +1 -1
  62. package/dist/components/DescriptionList/description-list.js +1 -1
  63. package/dist/components/DescriptionList/description-list.js.map +1 -1
  64. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  65. package/dist/components/Dialog/dialog.js.map +1 -1
  66. package/dist/components/DropdownMenu/dropdown-menu.d.ts +1 -1
  67. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  68. package/dist/components/DropdownMenu/dropdown-menu.js +0 -1
  69. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  70. package/dist/components/Empty/empty.d.ts +1 -1
  71. package/dist/components/Empty/empty.js.map +1 -1
  72. package/dist/components/Field/field-wrapper.js +1 -1
  73. package/dist/components/Field/field-wrapper.js.map +1 -1
  74. package/dist/components/Field/field.d.ts.map +1 -1
  75. package/dist/components/Field/field.js +1 -0
  76. package/dist/components/Field/field.js.map +1 -1
  77. package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
  78. package/dist/components/FieldControlGroup/field-control-group.js +1 -1
  79. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
  80. package/dist/components/FileUpload/file-upload.d.ts +8 -1
  81. package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
  82. package/dist/components/FileUpload/file-upload.js +7 -3
  83. package/dist/components/FileUpload/file-upload.js.map +1 -1
  84. package/dist/components/FileViewer/file-viewer.d.ts +1 -1
  85. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  86. package/dist/components/FileViewer/file-viewer.js +25 -14
  87. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  88. package/dist/components/HoverCard/hover-card.d.ts +5 -1
  89. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  90. package/dist/components/HoverCard/hover-card.js +2 -1
  91. package/dist/components/HoverCard/hover-card.js.map +1 -1
  92. package/dist/components/Menu/menu-item.d.ts +6 -2
  93. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  94. package/dist/components/Menu/menu-item.js.map +1 -1
  95. package/dist/components/Notice/notice.d.ts +5 -1
  96. package/dist/components/Notice/notice.d.ts.map +1 -1
  97. package/dist/components/Notice/notice.js +2 -1
  98. package/dist/components/Notice/notice.js.map +1 -1
  99. package/dist/components/OverflowIndicator/overflow-indicator.d.ts +4 -0
  100. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
  101. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -2
  102. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  103. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  104. package/dist/components/PeoplePicker/people-picker.js +6 -2
  105. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  106. package/dist/components/Popover/popover.d.ts +1 -1
  107. package/dist/components/Popover/popover.js +2 -1
  108. package/dist/components/Popover/popover.js.map +1 -1
  109. package/dist/components/ProfileCard/profile-card.d.ts +9 -4
  110. package/dist/components/ProfileCard/profile-card.d.ts.map +1 -1
  111. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  112. package/dist/components/RadioGroup/radio-group.d.ts +6 -0
  113. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  114. package/dist/components/RadioGroup/radio-group.js +4 -0
  115. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  116. package/dist/components/ScrollArea/scroll-area.js +1 -1
  117. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  118. package/dist/components/Select/select.d.ts.map +1 -1
  119. package/dist/components/Select/select.js +14 -4
  120. package/dist/components/Select/select.js.map +1 -1
  121. package/dist/components/SelectMenu/select-menu.d.ts +4 -0
  122. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  123. package/dist/components/SelectMenu/select-menu.js +6 -3
  124. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  125. package/dist/components/SelectionControl/selection-item.d.ts +5 -1
  126. package/dist/components/SelectionControl/selection-item.d.ts.map +1 -1
  127. package/dist/components/SelectionControl/selection-item.js +3 -1
  128. package/dist/components/SelectionControl/selection-item.js.map +1 -1
  129. package/dist/components/Sheet/sheet.d.ts +6 -5
  130. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  131. package/dist/components/Sheet/sheet.js.map +1 -1
  132. package/dist/components/Sidebar/sidebar.d.ts +1 -1
  133. package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
  134. package/dist/components/Sidebar/sidebar.js +3 -2
  135. package/dist/components/Sidebar/sidebar.js.map +1 -1
  136. package/dist/components/Skeleton/skeleton.d.ts +1 -1
  137. package/dist/components/Skeleton/skeleton.js +2 -1
  138. package/dist/components/Skeleton/skeleton.js.map +1 -1
  139. package/dist/components/Slider/slider.d.ts +1 -1
  140. package/dist/components/Slider/slider.d.ts.map +1 -1
  141. package/dist/components/Slider/slider.js +7 -3
  142. package/dist/components/Slider/slider.js.map +1 -1
  143. package/dist/components/Steps/steps.d.ts +1 -1
  144. package/dist/components/Steps/steps.d.ts.map +1 -1
  145. package/dist/components/Steps/steps.js +9 -6
  146. package/dist/components/Steps/steps.js.map +1 -1
  147. package/dist/components/Switch/switch.d.ts +5 -5
  148. package/dist/components/Switch/switch.js +3 -3
  149. package/dist/components/Switch/switch.js.map +1 -1
  150. package/dist/components/Tabs/tabs.js +1 -1
  151. package/dist/components/Tabs/tabs.js.map +1 -1
  152. package/dist/components/Textarea/textarea.js +1 -1
  153. package/dist/components/Textarea/textarea.js.map +1 -1
  154. package/dist/components/TimePicker/time-columns.js +1 -1
  155. package/dist/components/TimePicker/time-columns.js.map +1 -1
  156. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  157. package/dist/components/TimePicker/time-picker.js +2 -1
  158. package/dist/components/TimePicker/time-picker.js.map +1 -1
  159. package/dist/components/Toast/toast.js.map +1 -1
  160. package/dist/components/Tooltip/tooltip.d.ts +1 -1
  161. package/dist/components/Tooltip/tooltip.js +2 -1
  162. package/dist/components/Tooltip/tooltip.js.map +1 -1
  163. package/dist/components/TreeView/tree-view.d.ts +4 -4
  164. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  165. package/dist/components/TreeView/tree-view.js +3 -3
  166. package/dist/components/TreeView/tree-view.js.map +1 -1
  167. package/dist/patterns/element-anatomy/item-anatomy.d.ts +3 -3
  168. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  169. package/dist/patterns/header-canonical/chrome-header.d.ts +3 -2
  170. package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
  171. package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
  172. package/dist/patterns/overlay-surface/overlay-surface.d.ts +3 -2
  173. package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
  174. package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
  175. package/ds-canonical/hooks/_log-fire.sh +3 -1
  176. package/ds-canonical/hooks/check_audit_post_report_validator.sh +21 -1
  177. package/ds-canonical/hooks/check_audit_sample_escape.sh +6 -3
  178. package/ds-canonical/hooks/check_chrome_header_avatar_canonical.sh +8 -0
  179. package/ds-canonical/hooks/check_consumer_app_invariants.sh +321 -0
  180. package/ds-canonical/hooks/check_datatable_invariants.sh +75 -12
  181. package/ds-canonical/hooks/check_escape_marker_abuse.sh +15 -1
  182. package/ds-canonical/hooks/check_field_family_invariants.sh +12 -2
  183. package/ds-canonical/hooks/check_plugin_fork_health.sh +137 -0
  184. package/ds-canonical/hooks/check_propose_discipline.sh +147 -0
  185. package/ds-canonical/hooks/check_solo_workflow.sh +11 -1
  186. package/ds-canonical/hooks/check_story_invariants.sh +63 -9
  187. package/ds-canonical/hooks/check_storybook_addon_packaging.sh +151 -0
  188. package/ds-canonical/hooks/check_tailwind_wildcard_in_docs.sh +8 -2
  189. package/ds-canonical/hooks/lib/_overlay_handcraft.sh +25 -4
  190. package/ds-canonical/hooks/lib/_token_hygiene.sh +9 -1
  191. package/ds-canonical/hooks/session_start_governance_check.sh +7 -2
  192. package/ds-canonical/hooks/stop_self_audit.sh +2 -2
  193. package/ds-canonical/hooks/tests/test_check_addon_subdir_ship.sh +3 -2
  194. package/ds-canonical/hooks/tests/test_check_consumer_app_invariants.sh +12 -0
  195. package/ds-canonical/hooks/tests/test_check_consumer_app_story_title.sh +3 -2
  196. package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +6 -4
  197. package/ds-canonical/hooks/tests/test_check_consumer_no_ds_catalog.sh +7 -4
  198. package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +6 -4
  199. package/ds-canonical/hooks/tests/test_check_data_table_size_num_to_meta_width.sh +3 -2
  200. package/ds-canonical/hooks/tests/test_check_fork_user_plugin_install.sh +3 -2
  201. package/ds-canonical/hooks/tests/test_check_plugin_fork_health.sh +9 -0
  202. package/ds-canonical/hooks/tests/test_check_propose_cite_required.sh +3 -2
  203. package/ds-canonical/hooks/tests/test_check_propose_discipline.sh +10 -0
  204. package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +3 -2
  205. package/ds-canonical/hooks/tests/test_check_storybook_addon_packaging.sh +10 -0
  206. package/ds-canonical/hooks/tests/test_check_storybook_addon_preset_cjs.sh +3 -2
  207. package/ds-canonical/references/build-ui-canonicals.md +2 -2
  208. package/ds-canonical/references/composition-fidelity.md +3 -3
  209. package/ds-canonical/references/naming-conventions.md +1 -0
  210. package/ds-canonical/references/ssot-consultation.md +1 -1
  211. package/ds-canonical/references/ssot-index.md +7 -7
  212. package/ds-canonical/rules/meta-patterns.md +5 -5
  213. package/ds-canonical/rules/self-verify.md +1 -1
  214. package/ds-canonical/rules/story-rules.md +2 -0
  215. package/ds-canonical/rules/ui-development.md +1 -1
  216. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +11 -2
  217. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +1 -1
  218. package/ds-canonical/skills/design-system-audit/SKILL.md +15 -15
  219. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +4 -3
  220. package/ds-story-manifest.json +15 -21
  221. package/llms-full.txt +9 -5
  222. package/llms.txt +2 -2
  223. package/package.json +1 -1
  224. package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
  225. package/src/components/Accordion/accordion.spec.md +22 -5
  226. package/src/components/Accordion/accordion.tsx +1 -1
  227. package/src/components/Alert/alert.anatomy.stories.tsx +4 -4
  228. package/src/components/Alert/alert.principles.stories.tsx +5 -5
  229. package/src/components/Alert/alert.spec.md +16 -11
  230. package/src/components/Alert/alert.stories.tsx +5 -5
  231. package/src/components/Alert/alert.tsx +2 -2
  232. package/src/components/AppShell/app-shell.principles.stories.tsx +68 -21
  233. package/src/components/AppShell/app-shell.spec.md +17 -24
  234. package/src/components/AppShell/app-shell.tsx +4 -3
  235. package/src/components/AspectRatio/aspect-ratio.anatomy.stories.tsx +3 -3
  236. package/src/components/AspectRatio/aspect-ratio.spec.md +15 -1
  237. package/src/components/Avatar/avatar.anatomy.stories.tsx +1 -1
  238. package/src/components/Avatar/avatar.principles.stories.tsx +8 -8
  239. package/src/components/Avatar/avatar.spec.md +25 -54
  240. package/src/components/Avatar/avatar.tsx +2 -2
  241. package/src/components/Badge/badge.principles.stories.tsx +2 -2
  242. package/src/components/Badge/badge.spec.md +22 -13
  243. package/src/components/Badge/badge.tsx +1 -1
  244. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +5 -2
  245. package/src/components/Breadcrumb/breadcrumb.spec.md +25 -25
  246. package/src/components/Breadcrumb/breadcrumb.stories.tsx +7 -32
  247. package/src/components/Breadcrumb/breadcrumb.tsx +1 -1
  248. package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +2 -2
  249. package/src/components/BulkActionBar/bulk-action-bar.spec.md +20 -6
  250. package/src/components/BulkActionBar/bulk-action-bar.tsx +2 -2
  251. package/src/components/Button/button.anatomy.stories.tsx +2 -2
  252. package/src/components/Button/button.spec.md +19 -17
  253. package/src/components/Button/button.stories.tsx +1 -1
  254. package/src/components/Button/button.tsx +10 -9
  255. package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
  256. package/src/components/Calendar/calendar.spec.md +37 -17
  257. package/src/components/Calendar/calendar.tsx +26 -22
  258. package/src/components/Carousel/carousel.anatomy.stories.tsx +6 -6
  259. package/src/components/Carousel/carousel.principles.stories.tsx +1 -1
  260. package/src/components/Carousel/carousel.spec.md +23 -3
  261. package/src/components/Carousel/carousel.tsx +19 -4
  262. package/src/components/Chart/chart.anatomy.stories.tsx +1 -1
  263. package/src/components/Chart/chart.spec.md +20 -1
  264. package/src/components/Checkbox/checkbox-group.tsx +2 -1
  265. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +4 -4
  266. package/src/components/Checkbox/checkbox.principles.stories.tsx +2 -2
  267. package/src/components/Checkbox/checkbox.spec.md +35 -15
  268. package/src/components/Checkbox/checkbox.stories.tsx +1 -1
  269. package/src/components/Checkbox/checkbox.tsx +14 -3
  270. package/src/components/Chip/chip.anatomy.stories.tsx +5 -5
  271. package/src/components/Chip/chip.principles.stories.tsx +9 -3
  272. package/src/components/Chip/chip.spec.md +8 -9
  273. package/src/components/Chip/chip.tsx +2 -2
  274. package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +6 -6
  275. package/src/components/CircularProgress/circular-progress.spec.md +10 -11
  276. package/src/components/CircularProgress/circular-progress.stories.tsx +36 -43
  277. package/src/components/CircularProgress/circular-progress.tsx +1 -1
  278. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +1 -1
  279. package/src/components/Coachmark/coachmark.principles.stories.tsx +14 -29
  280. package/src/components/Coachmark/coachmark.spec.md +21 -13
  281. package/src/components/Coachmark/coachmark.tsx +4 -4
  282. package/src/components/Combobox/combobox.anatomy.stories.tsx +28 -28
  283. package/src/components/Combobox/combobox.principles.stories.tsx +1 -1
  284. package/src/components/Combobox/combobox.spec.md +25 -7
  285. package/src/components/Combobox/combobox.tsx +12 -3
  286. package/src/components/Command/command.anatomy.stories.tsx +1 -1
  287. package/src/components/Command/command.principles.stories.tsx +8 -8
  288. package/src/components/Command/command.spec.md +18 -8
  289. package/src/components/Command/command.tsx +8 -3
  290. package/src/components/DataTable/data-table-sort-manager.tsx +1 -1
  291. package/src/components/DataTable/data-table.anatomy.stories.tsx +9 -7
  292. package/src/components/DataTable/data-table.principles.stories.tsx +3 -3
  293. package/src/components/DataTable/data-table.spec.md +15 -11
  294. package/src/components/DataTable/data-table.stories.tsx +58 -13
  295. package/src/components/DataTable/data-table.tsx +13 -0
  296. package/src/components/DataTable/filter-operators.spec.md +19 -27
  297. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +8 -8
  298. package/src/components/DateGrid/date-grid.principles.stories.tsx +7 -7
  299. package/src/components/DateGrid/date-grid.spec.md +17 -14
  300. package/src/components/DateGrid/date-grid.tsx +8 -4
  301. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +11 -15
  302. package/src/components/DatePicker/date-picker.principles.stories.tsx +8 -8
  303. package/src/components/DatePicker/date-picker.spec.md +40 -36
  304. package/src/components/DatePicker/date-picker.stories.tsx +23 -53
  305. package/src/components/DatePicker/date-picker.tsx +12 -6
  306. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +2 -2
  307. package/src/components/DescriptionList/description-list.principles.stories.tsx +4 -18
  308. package/src/components/DescriptionList/description-list.spec.md +9 -3
  309. package/src/components/DescriptionList/description-list.stories.tsx +2 -18
  310. package/src/components/DescriptionList/description-list.tsx +1 -1
  311. package/src/components/Dialog/dialog.principles.stories.tsx +1 -1
  312. package/src/components/Dialog/dialog.spec.md +26 -11
  313. package/src/components/Dialog/dialog.stories.tsx +159 -184
  314. package/src/components/Dialog/dialog.tsx +2 -1
  315. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +2 -2
  316. package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +16 -17
  317. package/src/components/DropdownMenu/dropdown-menu.spec.md +10 -15
  318. package/src/components/DropdownMenu/dropdown-menu.stories.tsx +13 -15
  319. package/src/components/DropdownMenu/dropdown-menu.tsx +12 -2
  320. package/src/components/Empty/empty.spec.md +19 -18
  321. package/src/components/Empty/empty.tsx +1 -1
  322. package/src/components/Field/field-controls.spec.md +52 -41
  323. package/src/components/Field/field-wrapper.tsx +2 -2
  324. package/src/components/Field/field.anatomy.stories.tsx +6 -5
  325. package/src/components/Field/field.principles.stories.tsx +8 -7
  326. package/src/components/Field/field.spec.md +42 -20
  327. package/src/components/Field/field.stories.tsx +9 -7
  328. package/src/components/Field/field.tsx +6 -3
  329. package/src/components/Field/form-validation.spec.md +20 -19
  330. package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +16 -15
  331. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +5 -1
  332. package/src/components/FieldControlGroup/field-control-group.spec.md +17 -1
  333. package/src/components/FieldControlGroup/field-control-group.stories.tsx +9 -9
  334. package/src/components/FieldControlGroup/field-control-group.tsx +4 -3
  335. package/src/components/FileItem/file-item.anatomy.stories.tsx +7 -17
  336. package/src/components/FileItem/file-item.principles.stories.tsx +7 -7
  337. package/src/components/FileItem/file-item.spec.md +24 -24
  338. package/src/components/FileUpload/file-upload.anatomy.stories.tsx +4 -2
  339. package/src/components/FileUpload/file-upload.principles.stories.tsx +10 -12
  340. package/src/components/FileUpload/file-upload.spec.md +37 -8
  341. package/src/components/FileUpload/file-upload.tsx +5 -3
  342. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +16 -11
  343. package/src/components/FileViewer/file-viewer.principles.stories.tsx +4 -4
  344. package/src/components/FileViewer/file-viewer.spec.md +7 -19
  345. package/src/components/FileViewer/file-viewer.stories.tsx +3 -3
  346. package/src/components/FileViewer/file-viewer.tsx +42 -16
  347. package/src/components/HoverCard/hover-card.spec.md +20 -10
  348. package/src/components/HoverCard/hover-card.stories.tsx +1 -1
  349. package/src/components/HoverCard/hover-card.tsx +12 -1
  350. package/src/components/Input/input.anatomy.stories.tsx +4 -4
  351. package/src/components/Input/input.principles.stories.tsx +4 -31
  352. package/src/components/Input/input.spec.md +16 -4
  353. package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
  354. package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
  355. package/src/components/LinkInput/link-input.spec.md +14 -1
  356. package/src/components/Menu/menu-item.principles.stories.tsx +5 -5
  357. package/src/components/Menu/menu-item.spec.md +24 -12
  358. package/src/components/Menu/menu-item.tsx +7 -3
  359. package/src/components/Notice/notice.principles.stories.tsx +7 -7
  360. package/src/components/Notice/notice.spec.md +7 -5
  361. package/src/components/Notice/notice.tsx +5 -1
  362. package/src/components/NumberInput/number-input.anatomy.stories.tsx +4 -4
  363. package/src/components/NumberInput/number-input.principles.stories.tsx +13 -35
  364. package/src/components/NumberInput/number-input.spec.md +19 -0
  365. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +4 -3
  366. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +2 -5
  367. package/src/components/OverflowIndicator/overflow-indicator.spec.md +9 -1
  368. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -42
  369. package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -3
  370. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +11 -2
  371. package/src/components/PeoplePicker/people-picker.spec.md +26 -12
  372. package/src/components/PeoplePicker/people-picker.stories.tsx +14 -15
  373. package/src/components/PeoplePicker/people-picker.tsx +12 -4
  374. package/src/components/Popover/popover.spec.md +20 -11
  375. package/src/components/Popover/popover.tsx +2 -2
  376. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  377. package/src/components/ProfileCard/profile-card.principles.stories.tsx +29 -25
  378. package/src/components/ProfileCard/profile-card.spec.md +30 -10
  379. package/src/components/ProfileCard/profile-card.tsx +12 -7
  380. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +1 -1
  381. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +7 -5
  382. package/src/components/ProgressBar/progress-bar.spec.md +9 -1
  383. package/src/components/ProgressBar/progress-bar.stories.tsx +1 -1
  384. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +6 -3
  385. package/src/components/RadioGroup/radio-group.principles.stories.tsx +6 -13
  386. package/src/components/RadioGroup/radio-group.spec.md +7 -1
  387. package/src/components/RadioGroup/radio-group.tsx +10 -0
  388. package/src/components/Rating/rating.anatomy.stories.tsx +1 -0
  389. package/src/components/Rating/rating.principles.stories.tsx +9 -6
  390. package/src/components/Rating/rating.spec.md +13 -7
  391. package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +44 -24
  392. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +51 -57
  393. package/src/components/ScrollArea/scroll-area.spec.md +5 -7
  394. package/src/components/ScrollArea/scroll-area.stories.tsx +110 -60
  395. package/src/components/ScrollArea/scroll-area.tsx +1 -1
  396. package/src/components/SegmentedControl/segmented-control.anatomy.stories.tsx +1 -1
  397. package/src/components/SegmentedControl/segmented-control.spec.md +15 -14
  398. package/src/components/SegmentedControl/segmented-control.stories.tsx +1 -1
  399. package/src/components/Select/select.anatomy.stories.tsx +12 -11
  400. package/src/components/Select/select.principles.stories.tsx +3 -3
  401. package/src/components/Select/select.spec.md +34 -8
  402. package/src/components/Select/select.stories.tsx +2 -2
  403. package/src/components/Select/select.tsx +18 -3
  404. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +2 -2
  405. package/src/components/SelectMenu/select-menu.principles.stories.tsx +5 -5
  406. package/src/components/SelectMenu/select-menu.spec.md +19 -12
  407. package/src/components/SelectMenu/select-menu.stories.tsx +34 -27
  408. package/src/components/SelectMenu/select-menu.tsx +14 -3
  409. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  410. package/src/components/SelectionControl/selection-item.spec.md +13 -2
  411. package/src/components/SelectionControl/selection-item.stories.tsx +1 -1
  412. package/src/components/SelectionControl/selection-item.tsx +8 -2
  413. package/src/components/Separator/separator.principles.stories.tsx +2 -2
  414. package/src/components/Separator/separator.spec.md +11 -5
  415. package/src/components/Sheet/sheet.anatomy.stories.tsx +7 -6
  416. package/src/components/Sheet/sheet.principles.stories.tsx +18 -38
  417. package/src/components/Sheet/sheet.spec.md +9 -11
  418. package/src/components/Sheet/sheet.stories.tsx +2 -2
  419. package/src/components/Sheet/sheet.tsx +6 -5
  420. package/src/components/Sidebar/sidebar.anatomy.stories.tsx +42 -33
  421. package/src/components/Sidebar/sidebar.principles.stories.tsx +4 -4
  422. package/src/components/Sidebar/sidebar.spec.md +22 -17
  423. package/src/components/Sidebar/sidebar.stories.tsx +16 -0
  424. package/src/components/Sidebar/sidebar.tsx +15 -7
  425. package/src/components/Skeleton/skeleton.anatomy.stories.tsx +2 -2
  426. package/src/components/Skeleton/skeleton.principles.stories.tsx +20 -7
  427. package/src/components/Skeleton/skeleton.spec.md +6 -4
  428. package/src/components/Skeleton/skeleton.stories.tsx +34 -26
  429. package/src/components/Skeleton/skeleton.tsx +1 -1
  430. package/src/components/Slider/slider.principles.stories.tsx +3 -3
  431. package/src/components/Slider/slider.spec.md +16 -12
  432. package/src/components/Slider/slider.stories.tsx +2 -18
  433. package/src/components/Slider/slider.tsx +6 -2
  434. package/src/components/Steps/steps.anatomy.stories.tsx +3 -3
  435. package/src/components/Steps/steps.principles.stories.tsx +9 -12
  436. package/src/components/Steps/steps.spec.md +31 -25
  437. package/src/components/Steps/steps.stories.tsx +5 -40
  438. package/src/components/Steps/steps.tsx +17 -12
  439. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  440. package/src/components/Switch/switch.spec.md +13 -0
  441. package/src/components/Switch/switch.tsx +3 -3
  442. package/src/components/Tabs/tabs.anatomy.stories.tsx +4 -4
  443. package/src/components/Tabs/tabs.principles.stories.tsx +1 -1
  444. package/src/components/Tabs/tabs.spec.md +13 -6
  445. package/src/components/Tabs/tabs.stories.tsx +3 -3
  446. package/src/components/Tabs/tabs.tsx +2 -2
  447. package/src/components/Tag/tag.anatomy.stories.tsx +15 -15
  448. package/src/components/Tag/tag.principles.stories.tsx +1 -1
  449. package/src/components/Tag/tag.spec.md +25 -5
  450. package/src/components/Textarea/textarea.anatomy.stories.tsx +3 -3
  451. package/src/components/Textarea/textarea.principles.stories.tsx +7 -7
  452. package/src/components/Textarea/textarea.spec.md +15 -3
  453. package/src/components/Textarea/textarea.tsx +1 -1
  454. package/src/components/TimePicker/time-columns.tsx +1 -1
  455. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +8 -2
  456. package/src/components/TimePicker/time-picker.spec.md +23 -3
  457. package/src/components/TimePicker/time-picker.tsx +5 -3
  458. package/src/components/Toast/toast.anatomy.stories.tsx +1 -1
  459. package/src/components/Toast/toast.spec.md +7 -4
  460. package/src/components/Toast/toast.stories.tsx +12 -6
  461. package/src/components/Toast/toast.tsx +1 -1
  462. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +1 -1
  463. package/src/components/Tooltip/tooltip.spec.md +11 -8
  464. package/src/components/Tooltip/tooltip.tsx +1 -1
  465. package/src/components/TreeView/tree-view.anatomy.stories.tsx +25 -9
  466. package/src/components/TreeView/tree-view.principles.stories.tsx +5 -5
  467. package/src/components/TreeView/tree-view.spec.md +11 -9
  468. package/src/components/TreeView/tree-view.stories.tsx +5 -3
  469. package/src/components/TreeView/tree-view.tsx +8 -5
  470. package/src/patterns/action-bar/action-bar.spec.md +11 -4
  471. package/src/patterns/element-anatomy/element-anatomy.spec.md +8 -6
  472. package/src/patterns/element-anatomy/inline-action.spec.md +18 -18
  473. package/src/patterns/element-anatomy/item-anatomy.spec.md +47 -42
  474. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -6
  475. package/src/patterns/element-anatomy/item-anatomy.tsx +3 -3
  476. package/src/patterns/header-canonical/chrome-header.tsx +3 -2
  477. package/src/patterns/header-canonical/header-canonical.spec.md +24 -11
  478. package/src/patterns/header-canonical/header-canonical.stories.tsx +9 -9
  479. package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +22 -12
  480. package/src/patterns/overlay-surface/overlay-surface.spec.md +43 -39
  481. package/src/patterns/overlay-surface/overlay-surface.tsx +3 -2
  482. package/src/patterns/resize-handle/resize-handle.spec.md +10 -1
  483. package/src/patterns/resize-handle/resize-handle.stories.tsx +7 -7
  484. package/src/tokens/README.md +5 -2
  485. package/src/tokens/color/color.spec.md +17 -10
  486. package/src/tokens/color/semantic.css +2 -0
  487. package/src/tokens/density/density.spec.md +4 -14
  488. package/src/tokens/elevation/elevation.spec.md +7 -8
  489. package/src/tokens/layoutSpace/layoutSpace.spec.md +20 -27
  490. package/src/tokens/motion/motion.spec.md +15 -7
  491. package/src/tokens/opacity/opacity.spec.md +15 -26
  492. package/src/tokens/orphan-tokens.spec.md +14 -3
  493. package/src/tokens/radius/radius.spec.md +13 -15
  494. package/src/tokens/token-system.spec.md +10 -13
  495. package/src/tokens/typography/typography.spec.md +8 -12
  496. package/src/tokens/uiSize/uiSize.spec.md +28 -16
  497. /package/ds-canonical/hooks/{check_addon_subdir_ship.sh → retired/2026-06-11-prune-merge/check_addon_subdir_ship.sh} +0 -0
  498. /package/ds-canonical/hooks/{check_consumer_app_story_title.sh → retired/2026-06-11-prune-merge/check_consumer_app_story_title.sh} +0 -0
  499. /package/ds-canonical/hooks/{check_consumer_ds_primitive_misuse.sh → retired/2026-06-11-prune-merge/check_consumer_ds_primitive_misuse.sh} +0 -0
  500. /package/ds-canonical/hooks/{check_consumer_no_ds_catalog.sh → retired/2026-06-11-prune-merge/check_consumer_no_ds_catalog.sh} +0 -0
  501. /package/ds-canonical/hooks/{check_consumer_story_baseline.sh → retired/2026-06-11-prune-merge/check_consumer_story_baseline.sh} +0 -0
  502. /package/ds-canonical/hooks/{check_data_table_size_num_to_meta_width.sh → retired/2026-06-11-prune-merge/check_data_table_size_num_to_meta_width.sh} +0 -0
  503. /package/ds-canonical/hooks/{check_fork_user_plugin_install.sh → retired/2026-06-11-prune-merge/check_fork_user_plugin_install.sh} +0 -0
  504. /package/ds-canonical/hooks/{check_plugin_freshness.sh → retired/2026-06-11-prune-merge/check_plugin_freshness.sh} +0 -0
  505. /package/ds-canonical/hooks/{check_propose_cite_required.sh → retired/2026-06-11-prune-merge/check_propose_cite_required.sh} +0 -0
  506. /package/ds-canonical/hooks/{check_propose_plain_chinese.sh → retired/2026-06-11-prune-merge/check_propose_plain_chinese.sh} +0 -0
  507. /package/ds-canonical/hooks/{check_storybook_addon_preset_cjs.sh → retired/2026-06-11-prune-merge/check_storybook_addon_preset_cjs.sh} +0 -0
@@ -108,8 +108,8 @@ export const Overview: Story = {
108
108
  <Td mono>cmdk</Td>
109
109
  </tr>
110
110
  <tr>
111
- <Td mono>CommandInput</Td>
112
- <Td>搜尋框(searchable 模式,高度對齊 field-height)</Td>
111
+ <Td mono>CommandPrimitive.Input</Td>
112
+ <Td>搜尋框(raw cmdk input + 自建 wrapper,searchable 模式,高度對齊 field-height)</Td>
113
113
  <Td mono>cmdk</Td>
114
114
  </tr>
115
115
  <tr>
@@ -28,11 +28,11 @@ export const UsageGuidance: Story = {
28
28
  <div className="prose prose-sm max-w-prose mb-8">
29
29
  <p>適合 SelectMenu 的真實業務場景(點擊跳轉「展示」頁範例):</p>
30
30
  <ul className="space-y-1">
31
- <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="單選"><span className="text-primary hover:underline font-medium cursor-pointer">單選</span></LinkTo></li>
32
- <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="搜尋"><span className="text-primary hover:underline font-medium cursor-pointer">搜尋</span></LinkTo></li>
33
- <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="多選"><span className="text-primary hover:underline font-medium cursor-pointer">多選</span></LinkTo></li>
34
- <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="多選 + 搜尋"><span className="text-primary hover:underline font-medium cursor-pointer">多選 + 搜尋</span></LinkTo></li>
35
- <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="可清除"><span className="text-primary hover:underline font-medium cursor-pointer">可清除</span></LinkTo></li>
31
+ <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="單選"><span className="text-primary hover:underline font-medium cursor-pointer">議題狀態欄位擇一指派(單選)</span></LinkTo></li>
32
+ <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="搜尋"><span className="text-primary hover:underline font-medium cursor-pointer">數百人組織選負責人,輸入過濾(搜尋)</span></LinkTo></li>
33
+ <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="多選"><span className="text-primary hover:underline font-medium cursor-pointer">工單同時貼多個標籤(多選)</span></LinkTo></li>
34
+ <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="多選 + 搜尋"><span className="text-primary hover:underline font-medium cursor-pointer">大量標籤庫中過濾並複選(多選 + 搜尋)</span></LinkTo></li>
35
+ <li><LinkTo kind="Design System/Internal/SelectMenu/展示" name="可清除"><span className="text-primary hover:underline font-medium cursor-pointer">篩選列一鍵清空已選條件(可清除)</span></LinkTo></li>
36
36
  </ul>
37
37
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見下方 vs 近親 段)。</p>
38
38
  </div>
@@ -29,7 +29,7 @@ SelectMenu 是 **Popover + Command 組成的完整下拉選單浮層**——提
29
29
 
30
30
  ## Controlled-only rationale(Dim 26)
31
31
 
32
- 本元件刻意採 **controlled-only** 模式:`value` + `onChange` 必傳,不支援 `defaultValue` uncontrolled fallback。
32
+ 本元件刻意採 **controlled-only** 模式:value 軸走 `value` + `onValueChange`(型別宣告 optional、無 runtime 強制,但 internal 消費者 Select / Combobox / PeoplePicker 一律傳入),不支援 `defaultValue` uncontrolled fallback。
33
33
 
34
34
  **為什麼**:
35
35
  - 內部狀態複雜(search filter / range / menu open state)跟 `value` 雙向 sync 會產生 race condition
@@ -54,9 +54,11 @@ SelectMenu 是 **Popover + Command 組成的完整下拉選單浮層**——提
54
54
 
55
55
  ### 消費者
56
56
 
57
- - `../PeoplePicker/people-picker.tsx` — 人員選擇(永遠 searchable
58
- - `../Select/select.tsx` — `searchable` 模式會切換到 SelectMenu 浮層
59
- - `../Combobox/combobox.tsx` — `searchable` 模式會切換到 SelectMenu 浮層
57
+ - `../Select/select.tsx` — `searchable` 模式會切換到 SelectMenu 浮層(直接 import
58
+ - `../Combobox/combobox.tsx` — `searchable` 模式會切換到 SelectMenu 浮層(直接 import)
59
+ - `../PeoplePicker/people-picker.tsx` — 人員選擇(永遠 searchable;**間接消費** wrap Select / Combobox,不直接 import SelectMenu,見 `people-picker.spec.md`「實作基礎」)
60
+
61
+ **常見誤解**:(1)「要下拉浮層就 import SelectMenu」— internal primitive,一律經 Select / Combobox / PeoplePicker 消費(見上表);(2)「SelectMenu = DropdownMenu」— SelectMenu 是**選值**(值留在 field),DropdownMenu 是**執行動作**(點完即關)— 分界 SSOT 見 `dropdown-menu.spec.md`「與 SelectMenu 的區別」。
60
62
 
61
63
  ---
62
64
 
@@ -65,7 +67,7 @@ SelectMenu 是 **Popover + Command 組成的完整下拉選單浮層**——提
65
67
  ```
66
68
  Popover(浮動容器,handle 展開 / 定位)
67
69
  └─ Command(cmdk — 搜尋 + 鍵盤導覽)
68
- ├─ CommandInput(搜尋框,searchable 模式時顯示;選項 > 5 時建議開啟)
70
+ ├─ 搜尋框(`CommandPrimitive.Input` raw cmdk + 自建 icon/min-h wrapper,非 DS `CommandInput`;searchable 模式時顯示;選項 > 5 時建議開啟)
69
71
  ├─ CommandList(捲動區)
70
72
  │ └─ CommandGroup(分組標題)
71
73
  │ └─ MenuItem(選項 row,消費 item-layout)
@@ -91,7 +93,7 @@ Popover(浮動容器,handle 展開 / 定位)
91
93
 
92
94
  ## Creatable(建立新選項)
93
95
 
94
- 透過 `onCreate` prop 啟用。搜尋無結果時顯示「建立 "xxx"」提示(`Plus` icon + 使用者輸入的字)。
96
+ 透過 `creatable` + `onCreate` 啟用。search 非空且**無 label 完全相同(忽略大小寫)的既有選項**時,顯示 create row(`Plus` icon + `createLabel(query)`,預設「直接使用「xxx」」;`select-menu.tsx:219-224`)——完全同名時自動隱藏,防重複建立。
95
97
 
96
98
  **何時啟用**:
97
99
  - Tag input 允許使用者建立新 tag
@@ -122,7 +124,7 @@ Popover(浮動容器,handle 展開 / 定位)
122
124
 
123
125
  搜尋無結果時顯示 `Empty` 元件,可透過 `emptyText` 自訂訊息(預設「沒有符合的選項」)。
124
126
 
125
- - **Creatable 時**:即使搜尋無結果,仍顯示「建立 "xxx"」讓使用者補建選項
127
+ - **Creatable 時**:即使搜尋無結果,仍顯示 create row 讓使用者補建選項(顯示條件見「Creatable」段)
126
128
  - **非 creatable**:顯示 emptyText 提示使用者修改搜尋詞
127
129
 
128
130
  ---
@@ -135,9 +137,9 @@ Popover(浮動容器,handle 展開 / 定位)
135
137
  - **Dropdown 開啟時**:options 替換為 panel-center `<Empty icon={<CircularProgress size={48}/>} className="py-6"/>` compose 視覺(純 spinner,無 description)
136
138
  - **CircularProgress 預設 24px**,但在 Empty wrapper 內 48px(取代 Empty 的 48px Avatar icon slot)
137
139
 
138
- 對齊 MUI Autocomplete loading dropdown-body + Ant Select loading idiom + DS `empty.spec.md:191`「全頁 loading = Empty + CircularProgress compose」SSOT(SelectMenu loading 用法 canonical row 見 `empty.spec.md:163`)。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
140
+ 對齊 MUI Autocomplete loading dropdown-body + Ant Select loading idiom + DS `empty.spec.md`「禁止事項」段「loading Empty + CircularProgress compose」SSOT(SelectMenu loading 用法 canonical row 見 `empty.spec.md`「現有消費者」表)。 <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
139
141
 
140
- **消費**:Select / Combobox / PeoplePicker forward `loading` prop 到 SelectMenu,本元件不需 consumer 直接知道 Empty + CircularProgress 組合(封裝在內)。
142
+ **消費**:Select / Combobox forward `loading` prop 到 SelectMenu(PeoplePicker 尚未暴露 / 轉發 `loading`,見 `people-picker.spec.md`「邊界案例」),本元件不需 consumer 直接知道 Empty + CircularProgress 組合(封裝在內)。
141
143
 
142
144
  ---
143
145
 
@@ -156,7 +158,8 @@ Popover(浮動容器,handle 展開 / 定位)
156
158
  - **Disabled option**:individual MenuItem 透過 `disabled?: boolean` 控制(SelectMenu primitive option contract)。視覺繼承 `MenuItem` SSOT:text → `text-fg-disabled`(M24)、無 hover bg、`aria-disabled="true"`、Enter / click 不觸發 onChange、鍵盤導覽自動 skip。
157
159
  - **Disabled trigger**:trigger 由 consumer(Select / Combobox / PeoplePicker)的 `disabled` prop own,本元件不獨立 disable trigger。
158
160
  - **Loading**:已 codify(見「Loading」段),`loading=true` 時 dropdown body 切 panel-center Empty + CircularProgress 48px。
159
- - **Empty**:已 codify(見「Empty state」段),搜尋無結果 + 非 creatable 時渲 emptyText;creatable 時保留「建立 "xxx"」row。
161
+ - **Empty**:已 codify(見「Empty state」段),搜尋無結果 + 非 creatable 時渲 emptyText;creatable 時保留 create row(可鍵盤選取)
162
+ - **Creatable + search 與既有選項完全同名**(忽略大小寫):create row 隱藏(防重複建立,`select-menu.tsx:219-224`);選取既有選項為唯一路徑。
160
163
  - **Dark mode**:走 Popover / MenuItem semantic token 自動 adapt。
161
164
  - **Density**:row height 由 `MenuItem` SSOT 控(sm/md/lg);SelectMenu 不獨立 own density。
162
165
 
@@ -174,11 +177,12 @@ SelectMenu 是**多區塊 composite primitive**,不擁有獨立色彩決策:
174
177
 
175
178
  ## shadcn passthrough 例外說明
176
179
 
177
- SelectMenu 是 **composite**(Popover trigger + Command search + 滾動 MenuItem list + 浮動 surface),純 declarative API。**不套 `forwardRef` / `...props` spread`**,同 PeoplePicker 理由:
180
+ SelectMenu 是 **composite**(Popover trigger + Command search + 滾動 MenuItem list + 浮動 surface),純 declarative API。**套 `forwardRef` 簽名但 ref 不附著、無 `...props` spread**(shadcn forwardRef + displayName 統一;`select-menu.tsx:122-126` rationale):
178
181
 
179
182
  - **沒有單一 DOM root 可 ref**:trigger / search input / list / content portal 各自 DOM tree 離散
180
183
  - **`...props` spread 目標不明**:composite 的 root wrapper 只是 control 容器,spread 到那裡 consumer 無從預期作用
181
- - **API 邊界明確**:SelectMenu 暴露「選值」語意(value / onChange / options / mode),不暴露 DOM 細節
184
+ - **API 邊界明確**:SelectMenu 暴露「選值」語意(value / onValueChange / options / mode),不暴露 DOM 細節
185
+ - **`className` 合併到 PopoverContent**(contextually 最接近 user-facing surface)
182
186
 
183
187
  `displayName = 'SelectMenu'` 保留。若 consumer 需要 DOM-level 控制(custom trigger / portal / search input ref),改用底層 Popover + Command 自組。
184
188
 
@@ -220,3 +224,6 @@ SelectMenu 是 **composite**(Popover trigger + Command search + 滾動 MenuItem
220
224
 
221
225
  - `command.spec.md`
222
226
  - `dropdown-menu.spec.md`
227
+ - `menu-item.spec.md`
228
+ - `popover.spec.md`
229
+ - `select.spec.md`
@@ -118,31 +118,38 @@ export const Clearable: StoryObj = {
118
118
  }
119
119
 
120
120
  // @story-trait-rationale: AllSizes retired per F migration 2026-05-15 — anatomy.stories.tsx SizeMatrix auto-compile owns size showcase。
121
- // ── 狀態 ──
122
-
123
- export const States: StoryObj = {
124
- name: '狀態',
125
- render: () => {
126
- const [value, setValue] = React.useState('in_stock')
127
- return (
128
- <div className="flex flex-col gap-6 max-w-xs">
129
- <div>
130
- <span className="text-caption text-fg-muted mb-1 block">edit</span>
131
- <Select options={statusOptions} value={value} onChange={setValue} />
132
- </div>
133
- <div>
134
- <span className="text-caption text-fg-muted mb-1 block">readonly</span>
135
- <Select mode="readonly" options={statusOptions} value={value} />
136
- </div>
137
- <div>
138
- <span className="text-caption text-fg-muted mb-1 block">disabled</span>
139
- <Select mode="disabled" options={statusOptions} value={value} />
140
- </div>
141
- <div>
142
- <span className="text-caption text-fg-muted mb-1 block">error</span>
143
- <Select options={statusOptions} value={value} onChange={setValue} error />
144
- </div>
145
- </div>
146
- )
147
- },
121
+ // @story-trait-rationale: States(edit/readonly/disabled/error 觸發器狀態)retired 2026-06-11 —
122
+ // trigger field state 由 Select.stories.tsx「四模式」owns(SelectMenu 是 internal popover surface,
123
+ // 不 own input state,見檔頭 rationale)。本層改示範浮層自己 own 的選項狀態。
124
+ // ── 選項狀態(浮層內)──
125
+
126
+ const assigneeOptions = [
127
+ { value: 'ada', label: 'Ada Chen', description: 'Design Engineer' },
128
+ { value: 'ben', label: 'Ben Liu', description: 'Frontend' },
129
+ { value: 'cindy', label: 'Cindy Wang', description: '休假中,暫不可指派', disabled: true },
130
+ { value: 'derek', label: 'Derek Kao', description: 'Backend' },
131
+ ]
132
+
133
+ const OptionStatesDemo = () => {
134
+ const [value, setValue] = React.useState<string>('ada')
135
+ return (
136
+ <div className="flex flex-col gap-4 max-w-xs">
137
+ <p className="text-caption text-fg-secondary">
138
+ 浮層內選項狀態 已選中(勾選標記)、disabled(休假成員不可選)、搜尋無結果(輸入不存在的名字)
139
+ </p>
140
+ <Select
141
+ options={assigneeOptions}
142
+ value={value}
143
+ onChange={setValue}
144
+ searchable
145
+ placeholder="指派負責人…"
146
+ aria-label="指派負責人(SelectMenu option-states demo)"
147
+ />
148
+ </div>
149
+ )
150
+ }
151
+
152
+ export const OptionStates: StoryObj = {
153
+ name: '選項狀態',
154
+ render: () => <OptionStatesDemo />,
148
155
  }
@@ -1,8 +1,13 @@
1
+ /**
2
+ * @internal — DS-internal 單元(per `.claude/rules/ui-development.md` Public vs Internal canonical;spec frontmatter `isInternal`)。
3
+ * 不進 root barrel front-door;由 Select / Combobox wrap 消費,end-user app 請用 wrapper 元件。
4
+ */
1
5
  // @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
2
6
  import * as React from 'react'
3
7
  import { Plus, Search } from 'lucide-react'
4
8
  import type { LucideIcon } from 'lucide-react'
5
9
  import { cn } from '@/lib/utils'
10
+ import { useControllable } from '@/design-system/hooks/use-controllable'
6
11
  import type { AvatarData } from '@/design-system/components/Avatar/avatar'
7
12
  import { Popover, PopoverContent, PopoverTrigger } from '@/design-system/components/Popover/popover'
8
13
  import { Command, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator } from '@/design-system/components/Command/command'
@@ -150,9 +155,15 @@ const SelectMenu = React.forwardRef<HTMLElement, SelectMenuProps>(function Selec
150
155
  className,
151
156
  }, _ref) {
152
157
  // ── State ──
153
- const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)
154
- const open = controlledOpen ?? internalOpen
155
- const setOpen = controlledOnOpenChange ?? setInternalOpen
158
+ // 2026-06-11 R2 bug fix:原手寫 `setOpen = controlledOnOpenChange ?? setInternalOpen` 在
159
+ // uncontrolled + onOpenChange listener 場景(傳 onOpenChange 不傳 open)會讓 listener 蓋掉
160
+ // internal setter menu 開不了。改消費 DS 既有 useControllable(select.tsx 同 canonical):
161
+ // uncontrolled 時 internal state 為準、onOpenChange 僅通知。
162
+ const [open, setOpen] = useControllable<boolean>({
163
+ value: controlledOpen,
164
+ defaultValue: defaultOpen ?? false,
165
+ onChange: controlledOnOpenChange,
166
+ })
156
167
  const [search, setSearch] = React.useState('')
157
168
 
158
169
  // ── Value helpers ──
@@ -132,7 +132,7 @@ export const Overview: Story = {
132
132
  <Td mono>content · description</Td>
133
133
  <Td>輔助文字(reading mode,最小 14px)</Td>
134
134
  <Td mono>text-fg-secondary · line-height 1.5</Td>
135
- <Td mono>mt-0.5</Td>
135
+ <Td mono>mt-[var(--item-gap-label-desc-reading)](lg → -reading-lg)</Td>
136
136
  </tr>
137
137
  </tbody>
138
138
  </table>
@@ -34,6 +34,8 @@ SelectionItem 是 **Checkbox 和 RadioGroup 共用的 item 佈局 primitive**—
34
34
 
35
35
  **SelectionControl 是 internal primitive**——不直接使用,透過 Checkbox / RadioGroup 消費。
36
36
 
37
+ **icon / avatar prefix 消費路徑(2026-06-12 M30 修)**:`<Checkbox icon={...}>` / `<RadioGroupItem avatar={...}>` 直接轉發本 primitive 的既有槽(本檔「3-slot 結構」+ selection-item.tsx jsDoc 為對齊規則 SSOT)——不需也不准裸用 `<SelectionItem>`。
38
+
37
39
  | 場景 | 正確做法 |
38
40
  |------|---------|
39
41
  | 建立一組 Checkbox 選項 | 用 `Checkbox`(內部消費 SelectionItem)|
@@ -71,6 +73,7 @@ Checkbox 和 Radio 視覺幾乎完全一致(差異只在形狀 `rounded-md` vs
71
73
  - 單行時總高度 = field-height(對齊同 size 的 Input)
72
74
  - 多行時 padding 不變,自然撐高
73
75
  - density 切換時 field-height 自動調整,padding 跟著算
76
+ - **size 對應**:sm / md → `text-body` + `--field-height-{sm,md}`;lg → `text-body-lg` + `--field-height-lg`——與同 size Input 消費同一 token,是「單行高度對齊 Input」的機械保證
74
77
 
75
78
  ### Clamp 政策
76
79
 
@@ -100,8 +103,8 @@ SelectionItem 是**純 layout primitive**,只處理 3-slot 結構 + padding 公
100
103
  ## 邊界案例
101
104
 
102
105
  - **Disabled**:`disabled` 把 label / description / prefix icon 統一切 `text-fg-disabled`(M24 disabled>muted);control(Checkbox 方框 / Radio 圓圈)的 disabled 視覺由 consumer control 自己 own。SelectionItem 不獨立 own control state。
103
- - **Loading**:SelectionItem 為 layout primitive 非 async surface;無 loading state。Group-level loading 由 consumer(CheckboxGroup / RadioGroup)在外層處理(Skeleton stack)。
104
- - **Empty**:label 必傳(internal API contract);無 label-empty 場景。若 `description` 缺,layout 自動收斂為單行。
106
+ - **Loading**:SelectionItem 為 layout primitive 非 async surface;無 loading state。傳入的 control(Checkbox / Radio)亦無 loading prop(tsx 驗證);group-level loading 由 consumer(CheckboxGroup / RadioGroup)在外層處理(Skeleton stack)。
107
+ - **Empty**:label 為 required prop(省略 = TS error);傳空字串不防呆——會渲染空 `<label>`(點擊目標退化),consumer(Checkbox / RadioGroup)契約上必傳有效 label。若 `description` 缺,layout 自動收斂為單行。
105
108
  - **Dark mode / density**:走 semantic token 自動 adapt;`py` padding 公式對齊 `--field-height-{sm/md/lg}` density token。
106
109
 
107
110
  ---
@@ -128,3 +131,11 @@ SelectionItem 是純佈局元件,本身**不接管**鍵盤、焦點與勾選狀
128
131
 
129
132
  **驗證**:Storybook a11y addon panel 應 0 critical violation;鍵盤完整可操作(無需滑鼠)。WCAG AA contrast ≥ 4.5:1(text)/ 3:1(UI)。
130
133
 
134
+ ## 被引用(auto-maintained,Dim 3 reciprocal audit)
135
+
136
+ > 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
137
+
138
+ - `checkbox.spec.md`
139
+ - `item-anatomy.spec.md`
140
+ - `menu-item.spec.md`
141
+ - `radio-group.spec.md`
@@ -14,7 +14,7 @@ const meta: Meta<typeof SelectionItem> = {
14
14
  docs: {
15
15
  description: {
16
16
  component:
17
- 'SelectionItem 是 Checkbox 與 RadioGroup 共用的 item 佈局 primitive——提供 control + optional prefix(icon/avatar) + content(label/description) 的 3-slot 結構,並處理 `py = (field-height - 1lh) / 2` 的 padding 公式讓單行高度對齊同 size 的 Input。App 層級應使用 Checkbox / RadioGroup,不直接使用 SelectionItem——以下情境展示 primitive 被兩個 consumer 包出的樣貌。',
17
+ 'SelectionItem 是 Checkbox 與 RadioGroup 共用的 item 佈局 primitive——提供 control + optional prefix(icon/avatar) + content(label/description) 的 3-slot 結構,並處理 `py = (field-height - 1lh) / 2` 的 padding 公式讓單行高度對齊同 size 的 Input。App 層級應使用 Checkbox / RadioGroup,不直接使用 SelectionItem——前兩個情境展示 primitive Checkbox / RadioGroup 包出的樣貌;後兩個(前綴圖示 / 前綴頭像)直接以 primitive 展示 prefix slot 結構(docs 結構展示用,非 App 層用法)。',
18
18
  },
19
19
  },
20
20
  },
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @internal — DS-internal 單元(per `.claude/rules/ui-development.md` Public vs Internal canonical;spec frontmatter `isInternal`)。
3
+ * 不進 root barrel front-door;由 Checkbox / RadioGroup wrap 消費,end-user app 請用 wrapper 元件。
4
+ */
1
5
  import * as React from 'react'
2
6
  import { cva, type VariantProps } from 'class-variance-authority'
3
7
  import type { LucideIcon } from 'lucide-react'
@@ -9,7 +13,7 @@ import { ICON_SIZE, AVATAR_SIZE } from '@/design-system/patterns/element-anatomy
9
13
  // Checkbox 和 RadioGroup 共用的 item 佈局。
10
14
  //
11
15
  // 結構(item-anatomy.spec.md 4-slot 模型):
12
- // [control] [optional prefix(icon|avatar)] [content(label/desc)] [optional suffix]
16
+ // [control] [optional prefix(icon|avatar)] [content(label/desc)](3-slot,見 spec「定位」)
13
17
  //
14
18
  // padding 公式:py = (field-height - 1lh) / 2
15
19
  // - 單行時 item 高度 = field-height(對齊同 size 的 Input)
@@ -169,6 +173,8 @@ function ContentSlot({ htmlFor, disabled, label, description, sizeKey, labelClam
169
173
  <div className="min-w-0 flex-1">
170
174
  <label
171
175
  htmlFor={htmlFor}
176
+ // 2026-06-10 a11y:styled-disabled label 明告 inactive(WCAG 1.4.3 豁免可機判;對齊 FieldLabel 同修;a11y 補強不動 SSOT = AUTO 分權,user verbatim「確保所有的任務你都有做到完美做到完整」)
177
+ aria-disabled={disabled || undefined}
172
178
  className={cn(
173
179
  'cursor-pointer block break-words',
174
180
  labelClampClass,
@@ -252,7 +258,7 @@ export const selectionItemMeta = {
252
258
  lg: {},
253
259
  },
254
260
  defaultSize: 'md',
255
- states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],
261
+ states: ['default', 'disabled'], // disabled 是唯一視覺狀態;selected / hover 屬傳入的 control(spec「為何無 ColorMatrix / StateBehavior」)
256
262
  tokens: {
257
263
  fg: ['text-foreground', 'text-fg-secondary', 'text-fg-disabled'],
258
264
  },
@@ -54,10 +54,10 @@ export const UsageGuidance: Story = {
54
54
  <p>適合 Separator 的真實業務場景(點擊跳轉「展示」頁範例):</p>
55
55
  <ul className="space-y-1">
56
56
  <li>
57
- <LinkTo kind="Design System/Components/Separator/展示" name="Horizontal"><span className="text-primary hover:underline font-medium cursor-pointer">Horizontal</span></LinkTo>
57
+ <LinkTo kind="Design System/Components/Separator/展示" name="水平"><span className="text-primary hover:underline font-medium cursor-pointer">水平分隔</span></LinkTo>
58
58
  </li>
59
59
  <li>
60
- <LinkTo kind="Design System/Components/Separator/展示" name="Vertical"><span className="text-primary hover:underline font-medium cursor-pointer">Vertical</span></LinkTo>
60
+ <LinkTo kind="Design System/Components/Separator/展示" name="垂直"><span className="text-primary hover:underline font-medium cursor-pointer">垂直分隔</span></LinkTo>
61
61
  </li>
62
62
  <li>
63
63
  <LinkTo kind="Design System/Components/Separator/展示" name="在 DropdownMenu 內"><span className="text-primary hover:underline font-medium cursor-pointer">在 DropdownMenu 內</span></LinkTo>
@@ -29,16 +29,16 @@ Separator 是語意分隔元件,用於標示內容群組之間的邊界。
29
29
  ### Consumer 手動放 → Separator 元件
30
30
 
31
31
  Consumer 在 JSX 裡明確放置分隔線的場景:
32
- - `<SidebarSeparator />` 在 sidebar 群組間
33
- - `<DropdownMenuSeparator />` 在操作選單項目間
34
- - `<ButtonDivider />` 在按鈕群組內
32
+ - `<SidebarSeparator />` 在 sidebar 群組間(消費 DS Separator)
33
+ - `<DropdownMenuSeparator />` 在操作選單項目間(Radix Menu 自有 separator primitive,非 DS Separator)
34
+ - `<ButtonDivider />` 在按鈕群組內(raw div + `role="separator"`,非 DS Separator)
35
35
 
36
- 為什麼:Consumer 控制的分隔點需要語意標記(`role="separator"`),讓輔助技術能辨識內容群組邊界。
36
+ 為什麼:Consumer 控制的分隔點由放置者宣告語意——DS Separator 預設 decorative(`role="none"`,SR 靜默),真實切分內容區段時 `decorative={false}` 才輸出 `role="separator"`(詳「A11y 預設」段)。
37
37
 
38
38
  ### 元件自動分隔相鄰群組 → CSS `[&+&]`
39
39
 
40
40
  元件內部自動在相鄰同類群組間產生分隔線:
41
- - `MenuGroup`:相鄰同類群組之間自動出現 `border-divider` 分隔(見 `menu.tsx`)
41
+ - `MenuGroup`:相鄰同類群組之間自動出現 `border-divider` 分隔(見 `menu-item.tsx`)
42
42
  - `SidebarGroup`:相鄰群組之間自動產生分隔線(見 `sidebar.tsx`)
43
43
 
44
44
  為什麼:Consumer 只需要思考「分組」,不需要記得放分隔線。CSS 相鄰選擇器無法用元件替代(無處插入 DOM node)。
@@ -76,6 +76,12 @@ Consumer 在 JSX 裡明確放置分隔線的場景:
76
76
  - ❌ 用 `--border` token 做分隔線(應該用 `--divider`)
77
77
  - ❌ 用 `bg-border` 做 ButtonDivider 等 consumer 放置的分隔線
78
78
 
79
+ ## 邊界案例
80
+
81
+ - **Vertical 方向**:`h-full` 取父容器高度——父容器無確定高度(auto)時 separator 高度為 0、不可見;需父容器有確定高度或 flex row 的 stretch 對齊
82
+ - **空容器 / 0 寬**:horizontal `w-full` 隨父寬,父寬為 0 時無可見線;Separator 不自帶 min-width / min-height
83
+ - **厚度固定 1px**(`h-px` / `w-px`)、非互動無 hover / focus——無 size / state 變體(見下「為何無 …」段)
84
+
79
85
  ## 為何無 Inspector / ColorMatrix / SizeMatrix / StateBehavior
80
86
 
81
87
  Separator 是**視覺分隔 primitive**(一條 1px 線),結構極薄:
@@ -7,6 +7,7 @@ import {
7
7
  SheetHeader,
8
8
  SheetTitle,
9
9
  SheetDescription,
10
+ SheetBody,
10
11
  SheetFooter,
11
12
  } from './sheet'
12
13
  import { Button } from '@/design-system/components/Button/button'
@@ -36,10 +37,10 @@ export const Overview: Story = {
36
37
  <SheetTitle>修復付款流程 bug</SheetTitle>
37
38
  <SheetDescription>#PROJ-1234 · 指派給陳大明</SheetDescription>
38
39
  </SheetHeader>
39
- <div className="flex-1 p-4 text-body">
40
+ <SheetBody className="text-body">
40
41
  <p className="mb-3 text-fg-secondary">使用者於結帳最後一步點選「完成付款」後,頁面卡在轉圈動畫超過 30 秒,最終回到購物車且訂單未成立。重現率約 1/5,僅出現在 Safari 17。</p>
41
42
  <p className="text-caption text-fg-muted">優先級 P1 · 影響 230 筆訂單 · 截止 2026-04-25</p>
42
- </div>
43
+ </SheetBody>
43
44
  <SheetFooter>
44
45
  <Button variant="tertiary">標記為已解決</Button>
45
46
  <Button variant="primary">儲存變更</Button>
@@ -118,10 +119,10 @@ export const Inspector: Story = {
118
119
  <SheetTitle>修復付款流程 bug</SheetTitle>
119
120
  <SheetDescription>#PROJ-1234 · 指派給陳大明</SheetDescription>
120
121
  </SheetHeader>
121
- <div className="flex-1 p-4 text-body">
122
+ <SheetBody className="text-body">
122
123
  <p className="mb-3 text-fg-secondary">使用者於結帳最後一步點選「完成付款」後,頁面卡在轉圈動畫超過 30 秒,最終回到購物車且訂單未成立。重現率約 1/5,僅出現在 Safari 17。</p>
123
124
  <p className="text-caption text-fg-muted">優先級 P1 · 影響 230 筆訂單 · 截止 2026-04-25</p>
124
- </div>
125
+ </SheetBody>
125
126
  {showFooter && (
126
127
  <SheetFooter>
127
128
  <Button variant="tertiary">標記為已解決</Button>
@@ -166,9 +167,9 @@ export const SideMatrix: Story = {
166
167
  <SheetTitle>Q1 財報</SheetTitle>
167
168
  <SheetDescription>最後編輯:2026-04-18 17:32</SheetDescription>
168
169
  </SheetHeader>
169
- <div className="flex-1 p-4">
170
+ <SheetBody>
170
171
  <p className="text-body text-fg-secondary">本季營收 NT$4,820 萬,較上季成長 12%;毛利率 38.5%。下方附完整損益表與部門別明細,可直接在此面板註記後送交財務複核。</p>
171
- </div>
172
+ </SheetBody>
172
173
  <SheetFooter>
173
174
  <Button variant="primary">儲存</Button>
174
175
  </SheetFooter>
@@ -10,6 +10,7 @@ import {
10
10
  SheetHeader,
11
11
  SheetTitle,
12
12
  SheetDescription,
13
+ SheetBody,
13
14
  SheetFooter,
14
15
  SheetClose,
15
16
  } from './sheet'
@@ -32,7 +33,6 @@ import { Button } from '@/design-system/components/Button/button'
32
33
  import { Field, FieldLabel } from '@/design-system/components/Field/field'
33
34
  import { Input } from '@/design-system/components/Input/input'
34
35
  import { Checkbox } from '@/design-system/components/Checkbox/checkbox'
35
- import { ScrollArea } from '@/design-system/components/ScrollArea/scroll-area'
36
36
 
37
37
  const meta: Meta = {
38
38
  title: 'Design System/Components/Sheet/設計原則',
@@ -75,10 +75,10 @@ export const UsageGuidance: Story = {
75
75
  <p>適合 Sheet 的真實業務場景(點擊跳轉「展示」頁範例):</p>
76
76
  <ul className="space-y-1">
77
77
  <li>
78
- <LinkTo kind="Design System/Components/Sheet/展示" name="右側建立 專案"><span className="text-primary hover:underline font-medium cursor-pointer">右側建立 專案</span></LinkTo>
78
+ <LinkTo kind="Design System/Components/Sheet/展示" name="建立新專案(右側滑入)"><span className="text-primary hover:underline font-medium cursor-pointer">建立新專案(右側滑入)</span></LinkTo>
79
79
  </li>
80
80
  <li>
81
- <LinkTo kind="Design System/Components/Sheet/展示" name="右側編輯 使用者 詳情"><span className="text-primary hover:underline font-medium cursor-pointer">右側編輯 使用者 詳情</span></LinkTo>
81
+ <LinkTo kind="Design System/Components/Sheet/展示" name="編輯成員詳情(右側滑入)"><span className="text-primary hover:underline font-medium cursor-pointer">編輯成員詳情(右側滑入)</span></LinkTo>
82
82
  </li>
83
83
  </ul>
84
84
  <p className="text-fg-muted mt-3">判斷不確定時:對照 spec.md「何時用 / 何時不用」段;若仍不符,改用近親元件(見 <code>Vs*Rule</code> stories)。</p>
@@ -99,10 +99,9 @@ export const UsageGuidance: Story = {
99
99
  <SheetTitle>專案設定</SheetTitle>
100
100
  <SheetDescription>修改此專案的基本資訊與通知偏好</SheetDescription>
101
101
  </SheetHeader>
102
- {/* Overlay body 長內容必用 ScrollArea 而非 native overflow-y-auto,對齊 DS
103
- OS 一致設計準則(避免 Windows/Linux 右側被吃 15-17px)。 */}
104
- <ScrollArea className="flex-1">
105
- <div className="py-4 flex flex-col gap-4">
102
+ {/* Body 必用 SheetBody(內建 ScrollArea + 浮層 padding SSOT px-loose/pt-tight/pb-bottom);
103
+ 自組 ScrollArea + py-4 = 水平 0 padding 歷史 bug,詳 sheet.tsx SheetBody comment。 */}
104
+ <SheetBody className="flex flex-col gap-4">
106
105
  <Field>
107
106
  <FieldLabel>名稱</FieldLabel>
108
107
  <Input defaultValue="產品路線圖" />
@@ -118,8 +117,7 @@ export const UsageGuidance: Story = {
118
117
  <Checkbox label="每日摘要" />
119
118
  </div>
120
119
  </Field>
121
- </div>
122
- </ScrollArea>
120
+ </SheetBody>
123
121
  <SheetFooter>
124
122
  <SheetClose asChild>
125
123
  <Button variant="tertiary">取消</Button>
@@ -163,28 +161,12 @@ export const UsageGuidance: Story = {
163
161
  <Label>Dialog:刪除確認、放棄變更、登入、付款確認</Label>
164
162
  </Rule>
165
163
 
166
- {/* 何時不用 / 替代元件 — 原 WhenNotSheetRule */}
164
+ {/* 何時不用 / 替代元件 — 原 WhenNotSheetRule
165
+ 短確認 → Dialog 的完整 live 對照已在上方「Dialog — 居中 modal」段示範,此處不重複(2026-06-11 精簡)。 */}
167
166
  <Rule
168
167
  title="何時不用 / 替代元件 — 短確認 / 不可逆動作 → Dialog"
169
- note="「刪除 / 登出 / 放棄變更」這類要使用者完全停下做決定的場景,用 Dialog 的居中 modal 強制聚焦。Sheet 側滑視覺不夠強,使用者可能點旁邊就跳過"
168
+ note="「刪除 / 登出 / 放棄變更」這類要使用者完全停下做決定的場景,用 Dialog 的居中 modal 強制聚焦。Sheet 側滑視覺不夠強,使用者可能點旁邊就跳過(live 對照見上方「Dialog — 居中 modal」段)"
170
169
  >
171
- <Dialog>
172
- <DialogTrigger asChild>
173
- <Button variant="primary" danger startIcon={Trash2}>刪除帳號</Button>
174
- </DialogTrigger>
175
- <DialogContent autoHeight maxWidth="420px">
176
- <DialogHeader>
177
- <DialogTitle>確定要刪除帳號?</DialogTitle>
178
- </DialogHeader>
179
- <DialogBody>
180
- <p className="text-body">所有資料將於 30 天後永久移除,此動作無法復原。</p>
181
- </DialogBody>
182
- <DialogFooter>
183
- <Button variant="tertiary">取消</Button>
184
- <Button variant="primary" danger>確認刪除</Button>
185
- </DialogFooter>
186
- </DialogContent>
187
- </Dialog>
188
170
  <Label>↑ 短決策應該用 Dialog(Sheet 太長太輕)</Label>
189
171
  </Rule>
190
172
 
@@ -243,9 +225,9 @@ export const SidePropRule: Story = {
243
225
  <SheetTitle>任務詳情</SheetTitle>
244
226
  <SheetDescription>#PROJ-234 · 指派給Ada Chen</SheetDescription>
245
227
  </SheetHeader>
246
- <div className="flex-1 py-4 text-body text-fg-secondary">
228
+ <SheetBody className="text-body text-fg-secondary">
247
229
  登入頁在連續輸入錯誤密碼 3 次後未顯示鎖定提示,使用者反覆嘗試仍無回饋。建議補上鎖定倒數與重設連結。
248
- </div>
230
+ </SheetBody>
249
231
  </SheetContent>
250
232
  </Sheet>
251
233
  <Label>↑ 列表點 row → 右側滑入編輯,左側列表仍可見</Label>
@@ -287,13 +269,13 @@ export const SidePropRule: Story = {
287
269
  <SheetHeader>
288
270
  <SheetTitle>分享</SheetTitle>
289
271
  </SheetHeader>
290
- <div className="flex-1 py-4 flex flex-col gap-2">
272
+ <SheetBody className="flex flex-col gap-2">
291
273
  {['複製連結', '傳送到 Email', '加入我的最愛', '匯出 PDF'].map(name => (
292
274
  <button key={name} type="button" className="px-3 py-2 text-body text-left hover:bg-neutral-hover rounded-md">
293
275
  {name}
294
276
  </button>
295
277
  ))}
296
- </div>
278
+ </SheetBody>
297
279
  </SheetContent>
298
280
  </Sheet>
299
281
  <Label>↑ 手機拇指操作區 → bottom Sheet</Label>
@@ -322,7 +304,7 @@ export const HeaderFooterStructureRule: Story = {
322
304
  <div>
323
305
  <Rule
324
306
  title="標準結構 — Header(標題 + 描述) + 主內容 + Footer(按鈕列)"
325
- note="與 Dialog 共用 overlay-surface 視覺語言(bg-surface-raised / elevation-200;容器邊框用較淡的 border-divider,Dialog 用 border-border)。Header 放 SheetTitle + SheetDescription,Footer 放按鈕列;主內容區 flex-1 + ScrollArea(跨 OS 一致捲軸,非 native overflow-y-auto)吃長內容"
307
+ note="與 Dialog 共用 overlay-surface 視覺語言(bg-surface-raised / elevation-200;容器邊框用較淡的 border-divider,Dialog 用 border-border)。Header 放 SheetTitle + SheetDescription,Footer 放按鈕列;主內容區用 SheetBody(內建 ScrollArea 跨 OS 一致捲軸 + 浮層 padding SSOT)吃長內容"
326
308
  >
327
309
  <Sheet>
328
310
  <SheetTrigger asChild>
@@ -333,9 +315,8 @@ export const HeaderFooterStructureRule: Story = {
333
315
  <SheetTitle>建立新客戶</SheetTitle>
334
316
  <SheetDescription>填寫基本資料後可進行付款設定</SheetDescription>
335
317
  </SheetHeader>
336
- {/* Overlay body 長內容必用 ScrollArea,對齊 DS OS 一致 canonical */}
337
- <ScrollArea className="flex-1">
338
- <div className="py-4 flex flex-col gap-4">
318
+ {/* Body 必用 SheetBody(內建 ScrollArea + 浮層 padding SSOT) */}
319
+ <SheetBody className="flex flex-col gap-4">
339
320
  <Field>
340
321
  <FieldLabel>公司名稱</FieldLabel>
341
322
  <Input placeholder="輸入公司名稱" />
@@ -344,8 +325,7 @@ export const HeaderFooterStructureRule: Story = {
344
325
  <FieldLabel>聯絡人 Email</FieldLabel>
345
326
  <Input placeholder="contact@example.com" />
346
327
  </Field>
347
- </div>
348
- </ScrollArea>
328
+ </SheetBody>
349
329
  <SheetFooter>
350
330
  <SheetClose asChild>
351
331
  <Button variant="tertiary">取消</Button>