@qijenchen/design-system 0.1.0-beta.82 → 0.1.0-beta.84

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 (612) hide show
  1. package/CLAUDE.md +8 -8
  2. package/README.md +3 -2
  3. package/dist/components/Alert/alert.js.map +1 -1
  4. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
  5. package/dist/components/AppShell/app-shell.d.ts +1 -1
  6. package/dist/components/AppShell/app-shell.d.ts.map +1 -1
  7. package/dist/components/AppShell/app-shell.js +22 -2
  8. package/dist/components/AppShell/app-shell.js.map +1 -1
  9. package/dist/components/Avatar/avatar.d.ts.map +1 -1
  10. package/dist/components/Avatar/avatar.js +4 -4
  11. package/dist/components/Avatar/avatar.js.map +1 -1
  12. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -1
  13. package/dist/components/Breadcrumb/breadcrumb.js +1 -1
  14. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
  15. package/dist/components/Button/button.d.ts +2 -2
  16. package/dist/components/Button/button.d.ts.map +1 -1
  17. package/dist/components/Button/button.js +12 -3
  18. package/dist/components/Button/button.js.map +1 -1
  19. package/dist/components/Calendar/calendar.d.ts +13 -5
  20. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  21. package/dist/components/Calendar/calendar.js +7 -1
  22. package/dist/components/Calendar/calendar.js.map +1 -1
  23. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  24. package/dist/components/Carousel/carousel.js +8 -3
  25. package/dist/components/Carousel/carousel.js.map +1 -1
  26. package/dist/components/Chart/chart.d.ts.map +1 -1
  27. package/dist/components/Chart/chart.js +1 -0
  28. package/dist/components/Chart/chart.js.map +1 -1
  29. package/dist/components/Checkbox/checkbox.d.ts +1 -1
  30. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  31. package/dist/components/Checkbox/checkbox.js +8 -4
  32. package/dist/components/Checkbox/checkbox.js.map +1 -1
  33. package/dist/components/Chip/chip.d.ts +1 -1
  34. package/dist/components/Chip/chip.d.ts.map +1 -1
  35. package/dist/components/Chip/chip.js.map +1 -1
  36. package/dist/components/Coachmark/coachmark.d.ts +10 -3
  37. package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
  38. package/dist/components/Coachmark/coachmark.js.map +1 -1
  39. package/dist/components/Combobox/combobox.d.ts +5 -1
  40. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  41. package/dist/components/Combobox/combobox.js +30 -13
  42. package/dist/components/Combobox/combobox.js.map +1 -1
  43. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  44. package/dist/components/DataTable/cell-registry.js +53 -62
  45. package/dist/components/DataTable/cell-registry.js.map +1 -1
  46. package/dist/components/DataTable/column-types.d.ts +10 -4
  47. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  48. package/dist/components/DataTable/column-types.js.map +1 -1
  49. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +1 -1
  50. package/dist/components/DataTable/data-table-column-visibility-panel.js +183 -0
  51. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -0
  52. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  53. package/dist/components/DataTable/data-table-filter-panel.js +607 -0
  54. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -0
  55. package/dist/components/DataTable/data-table-interaction-layer.d.ts +11 -15
  56. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -1
  57. package/dist/components/DataTable/data-table-interaction-layer.js +1 -3
  58. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  59. package/dist/components/DataTable/data-table-sort-manager.js +140 -0
  60. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -0
  61. package/dist/components/DataTable/data-table.d.ts +5 -6
  62. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  63. package/dist/components/DataTable/data-table.js +36 -15
  64. package/dist/components/DataTable/data-table.js.map +1 -1
  65. package/dist/components/DataTable/filter-operators.js +140 -0
  66. package/dist/components/DataTable/filter-operators.js.map +1 -0
  67. package/dist/components/DataTable/filter-tree.js +312 -0
  68. package/dist/components/DataTable/filter-tree.js.map +1 -0
  69. package/dist/components/DataTable/index.d.ts +3 -0
  70. package/dist/components/DataTable/index.d.ts.map +1 -1
  71. package/dist/components/DataTable/index.js +12 -1
  72. package/dist/components/DataTable/index.js.map +1 -1
  73. package/dist/components/DataTable/lib/column-meta.js +25 -0
  74. package/dist/components/DataTable/lib/column-meta.js.map +1 -0
  75. package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
  76. package/dist/components/DateGrid/date-grid.js +3 -1
  77. package/dist/components/DateGrid/date-grid.js.map +1 -1
  78. package/dist/components/DatePicker/date-picker.d.ts +7 -1
  79. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  80. package/dist/components/DatePicker/date-picker.js +105 -74
  81. package/dist/components/DatePicker/date-picker.js.map +1 -1
  82. package/dist/components/Dialog/dialog.d.ts +20 -3
  83. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  84. package/dist/components/Dialog/dialog.js +38 -20
  85. package/dist/components/Dialog/dialog.js.map +1 -1
  86. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  87. package/dist/components/DropdownMenu/dropdown-menu.js +3 -1
  88. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  89. package/dist/components/Field/field-context.d.ts +45 -5
  90. package/dist/components/Field/field-context.d.ts.map +1 -1
  91. package/dist/components/Field/field-context.js +19 -0
  92. package/dist/components/Field/field-context.js.map +1 -1
  93. package/dist/components/Field/field-edit-keys.d.ts +21 -0
  94. package/dist/components/Field/field-edit-keys.d.ts.map +1 -0
  95. package/dist/components/Field/field-edit-keys.js +19 -0
  96. package/dist/components/Field/field-edit-keys.js.map +1 -0
  97. package/dist/components/Field/field-types.d.ts +20 -1
  98. package/dist/components/Field/field-types.d.ts.map +1 -1
  99. package/dist/components/Field/field-types.js.map +1 -1
  100. package/dist/components/Field/field-wrapper.d.ts +3 -2
  101. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  102. package/dist/components/Field/field-wrapper.js +38 -39
  103. package/dist/components/Field/field-wrapper.js.map +1 -1
  104. package/dist/components/Field/field.d.ts +2 -1
  105. package/dist/components/Field/field.d.ts.map +1 -1
  106. package/dist/components/Field/field.js.map +1 -1
  107. package/dist/components/FieldControlGroup/field-control-group.d.ts +1 -1
  108. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
  109. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  110. package/dist/components/FileItem/file-item.js +1 -1
  111. package/dist/components/FileItem/file-item.js.map +1 -1
  112. package/dist/components/FileUpload/file-upload.d.ts +1 -1
  113. package/dist/components/FileUpload/file-upload.js.map +1 -1
  114. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  115. package/dist/components/FileViewer/file-viewer.js +7 -2
  116. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  117. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -1
  118. package/dist/components/FileViewer/image-renderer.js +22 -1
  119. package/dist/components/FileViewer/image-renderer.js.map +1 -1
  120. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  121. package/dist/components/HoverCard/hover-card.js +5 -3
  122. package/dist/components/HoverCard/hover-card.js.map +1 -1
  123. package/dist/components/InlineEdit/index.d.ts +2 -0
  124. package/dist/components/InlineEdit/index.d.ts.map +1 -0
  125. package/dist/components/InlineEdit/index.js +5 -0
  126. package/dist/components/InlineEdit/index.js.map +1 -0
  127. package/dist/components/InlineEdit/inline-edit.d.ts +59 -0
  128. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -0
  129. package/dist/components/InlineEdit/inline-edit.js +164 -0
  130. package/dist/components/InlineEdit/inline-edit.js.map +1 -0
  131. package/dist/components/Input/input.d.ts +6 -11
  132. package/dist/components/Input/input.d.ts.map +1 -1
  133. package/dist/components/Input/input.js +43 -13
  134. package/dist/components/Input/input.js.map +1 -1
  135. package/dist/components/LinkInput/link-input.d.ts +2 -2
  136. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  137. package/dist/components/LinkInput/link-input.js +6 -5
  138. package/dist/components/LinkInput/link-input.js.map +1 -1
  139. package/dist/components/Menu/menu-item.d.ts +14 -2
  140. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  141. package/dist/components/Menu/menu-item.js +25 -3
  142. package/dist/components/Menu/menu-item.js.map +1 -1
  143. package/dist/components/NumberInput/number-input.d.ts +3 -3
  144. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  145. package/dist/components/NumberInput/number-input.js +6 -5
  146. package/dist/components/NumberInput/number-input.js.map +1 -1
  147. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
  148. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -6
  149. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  150. package/dist/components/Pagination/pagination.js +1 -1
  151. package/dist/components/Pagination/pagination.js.map +1 -1
  152. package/dist/components/PeoplePicker/index.js +7 -1
  153. package/dist/components/PeoplePicker/index.js.map +1 -1
  154. package/dist/components/PeoplePicker/people-picker.d.ts +9 -2
  155. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  156. package/dist/components/PeoplePicker/people-picker.js +23 -10
  157. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  158. package/dist/components/PeoplePicker/person-display.d.ts +6 -3
  159. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
  160. package/dist/components/PeoplePicker/person-display.js +19 -14
  161. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  162. package/dist/components/Popover/popover.d.ts.map +1 -1
  163. package/dist/components/Popover/popover.js +3 -1
  164. package/dist/components/Popover/popover.js.map +1 -1
  165. package/dist/components/ProfileCard/profile-card.d.ts +2 -2
  166. package/dist/components/ProfileCard/profile-card.js +3 -3
  167. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  168. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  169. package/dist/components/RadioGroup/radio-group.js +15 -9
  170. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  171. package/dist/components/ScrollArea/scroll-area.d.ts +11 -1
  172. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  173. package/dist/components/ScrollArea/scroll-area.js +6 -3
  174. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  175. package/dist/components/Select/select.d.ts +46 -5
  176. package/dist/components/Select/select.d.ts.map +1 -1
  177. package/dist/components/Select/select.js +109 -28
  178. package/dist/components/Select/select.js.map +1 -1
  179. package/dist/components/SelectMenu/select-menu.d.ts +3 -1
  180. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  181. package/dist/components/SelectMenu/select-menu.js +8 -1
  182. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  183. package/dist/components/SelectionControl/boolean-value.d.ts +11 -0
  184. package/dist/components/SelectionControl/boolean-value.d.ts.map +1 -0
  185. package/dist/components/SelectionControl/boolean-value.js +23 -0
  186. package/dist/components/SelectionControl/boolean-value.js.map +1 -0
  187. package/dist/components/SelectionControl/index.d.ts +1 -0
  188. package/dist/components/SelectionControl/index.d.ts.map +1 -1
  189. package/dist/components/SelectionControl/index.js +2 -0
  190. package/dist/components/SelectionControl/index.js.map +1 -1
  191. package/dist/components/Sheet/index.js +2 -1
  192. package/dist/components/Sheet/sheet.d.ts +7 -1
  193. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  194. package/dist/components/Sheet/sheet.js +5 -2
  195. package/dist/components/Sheet/sheet.js.map +1 -1
  196. package/dist/components/Sidebar/sidebar.d.ts +9 -4
  197. package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
  198. package/dist/components/Sidebar/sidebar.js +8 -10
  199. package/dist/components/Sidebar/sidebar.js.map +1 -1
  200. package/dist/components/Slider/slider.d.ts.map +1 -1
  201. package/dist/components/Slider/slider.js.map +1 -1
  202. package/dist/components/Switch/switch.d.ts +6 -6
  203. package/dist/components/Switch/switch.d.ts.map +1 -1
  204. package/dist/components/Switch/switch.js +3 -2
  205. package/dist/components/Switch/switch.js.map +1 -1
  206. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  207. package/dist/components/Tabs/tabs.js +15 -1
  208. package/dist/components/Tabs/tabs.js.map +1 -1
  209. package/dist/components/Textarea/textarea.d.ts +2 -2
  210. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  211. package/dist/components/Textarea/textarea.js +50 -42
  212. package/dist/components/Textarea/textarea.js.map +1 -1
  213. package/dist/components/TimePicker/time-columns.d.ts.map +1 -1
  214. package/dist/components/TimePicker/time-columns.js +42 -38
  215. package/dist/components/TimePicker/time-columns.js.map +1 -1
  216. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  217. package/dist/components/TimePicker/time-picker.js +8 -6
  218. package/dist/components/TimePicker/time-picker.js.map +1 -1
  219. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  220. package/dist/components/Tooltip/tooltip.js +7 -5
  221. package/dist/components/Tooltip/tooltip.js.map +1 -1
  222. package/dist/components/TreeView/tree-view.d.ts +56 -1
  223. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  224. package/dist/components/TreeView/tree-view.js +211 -12
  225. package/dist/components/TreeView/tree-view.js.map +1 -1
  226. package/dist/index.d.ts +115 -58
  227. package/dist/index.d.ts.map +1 -1
  228. package/dist/index.js +93 -108
  229. package/dist/index.js.map +1 -1
  230. package/dist/patterns/element-anatomy/item-anatomy.d.ts +7 -6
  231. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  232. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  233. package/dist/tokens/categorical-color.js +15 -0
  234. package/dist/tokens/categorical-color.js.map +1 -1
  235. package/dist/tokens/motion/motion.d.ts +7 -6
  236. package/dist/tokens/motion/motion.d.ts.map +1 -1
  237. package/dist/tokens/motion/motion.js +6 -6
  238. package/dist/tokens/motion/motion.js.map +1 -1
  239. package/dist/tokens/motion/overlay-motion.d.ts +19 -0
  240. package/dist/tokens/motion/overlay-motion.d.ts.map +1 -0
  241. package/dist/tokens/motion/overlay-motion.js +9 -0
  242. package/dist/tokens/motion/overlay-motion.js.map +1 -0
  243. package/dist/tokens/uiSize/icon-size.js +5 -0
  244. package/dist/tokens/uiSize/icon-size.js.map +1 -0
  245. package/ds-canonical/fork/governance.lock +37 -19
  246. package/ds-canonical/fork/hooks/_log-fire.sh +46 -0
  247. package/ds-canonical/fork/hooks/block_prototype_imports.py +15 -4
  248. package/ds-canonical/fork/hooks/check_consumer_app_invariants.sh +145 -13
  249. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +17 -5
  250. package/ds-canonical/fork/hooks/check_dynamic_tailwind_class.sh +47 -0
  251. package/ds-canonical/fork/hooks/check_escape_marker_abuse.sh +27 -0
  252. package/ds-canonical/fork/hooks/check_field_family_invariants.sh +61 -1
  253. package/ds-canonical/fork/hooks/check_layout_space_magic_numbers.sh +28 -4
  254. package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +36 -0
  255. package/ds-canonical/fork/hooks/check_story_determinism.sh +39 -0
  256. package/ds-canonical/fork/hooks/check_story_invariants.sh +119 -0
  257. package/ds-canonical/fork/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  258. package/ds-canonical/fork/manifest.json +20 -0
  259. package/ds-canonical/fork/preamble.md +22 -18
  260. package/ds-canonical/fork/skills/bug-fix-rhythm/SKILL.md +9 -3
  261. package/ds-canonical/fork/skills/code-quality-audit/SKILL.md +3 -3
  262. package/ds-canonical/fork/skills/delivery-handoff/SKILL.md +7 -0
  263. package/ds-canonical/fork/skills/performance-audit/SKILL.md +4 -2
  264. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +3 -3
  265. package/ds-canonical/fork/skills/propose-options/SKILL.md +3 -3
  266. package/ds-canonical/fork/skills/prototype/SKILL.md +1 -1
  267. package/ds-canonical/fork/skills/scan-similar-bugs/SKILL.md +2 -2
  268. package/ds-canonical/fork/skills/visual-audit/SKILL.md +10 -2
  269. package/ds-canonical/hooks/README.md +1 -1
  270. package/ds-canonical/hooks/block_prototype_imports.py +15 -4
  271. package/ds-canonical/hooks/check_audit_post_report_validator.sh +65 -7
  272. package/ds-canonical/hooks/check_benchmark_citation.sh +5 -3
  273. package/ds-canonical/hooks/check_codex_brief_invariants.sh +28 -1
  274. package/ds-canonical/hooks/check_consumer_app_invariants.sh +145 -13
  275. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +17 -5
  276. package/ds-canonical/hooks/check_dynamic_tailwind_class.sh +47 -0
  277. package/ds-canonical/hooks/check_escape_marker_abuse.sh +27 -0
  278. package/ds-canonical/hooks/check_field_family_invariants.sh +61 -1
  279. package/ds-canonical/hooks/check_layout_space_magic_numbers.sh +28 -4
  280. package/ds-canonical/hooks/check_naming_and_abstraction.sh +1 -1
  281. package/ds-canonical/hooks/check_opacity_token_usage.sh +36 -0
  282. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +3 -2
  283. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +6 -1
  284. package/ds-canonical/hooks/check_propose_without_benchmark.sh +6 -2
  285. package/ds-canonical/hooks/check_ssot_header_declaration.sh +55 -0
  286. package/ds-canonical/hooks/check_story_determinism.sh +39 -0
  287. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +8 -7
  288. package/ds-canonical/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  289. package/ds-canonical/hooks/lib/_story_compile_drift.sh +1 -1
  290. package/ds-canonical/hooks/lib/_token_hygiene.sh +10 -1
  291. package/ds-canonical/hooks/stop_self_audit.sh +31 -0
  292. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +24 -0
  293. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +44 -0
  294. package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +3 -3
  295. package/ds-canonical/hooks/tests/test_check_codex_brief_invariants.sh +43 -2
  296. package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +112 -0
  297. package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +9 -2
  298. package/ds-canonical/hooks/tests/test_check_dynamic_tailwind_class.sh +76 -0
  299. package/ds-canonical/hooks/tests/test_check_escape_marker_abuse.sh +24 -0
  300. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +27 -2
  301. package/ds-canonical/hooks/tests/test_check_fork_user_plugin_install.sh +3 -1
  302. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +41 -2
  303. package/ds-canonical/hooks/tests/test_check_ssot_header_declaration.sh +72 -0
  304. package/ds-canonical/hooks/tests/test_check_tabs_content_chrome_body_double_gap.sh +76 -0
  305. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
  306. package/ds-canonical/references/build-ui-canonicals.md +2 -1
  307. package/ds-canonical/references/failure-class-registry.json +145 -0
  308. package/ds-canonical/references/governance-audit-coverage.md +33 -0
  309. package/ds-canonical/references/item-anatomy-recipe.md +2 -2
  310. package/ds-canonical/references/scenario-definition.md +6 -9
  311. package/ds-canonical/references/ssot-consultation.md +2 -2
  312. package/ds-canonical/references/ssot-index.md +5 -4
  313. package/ds-canonical/references/story-baseline-registry.json +8 -2
  314. package/ds-canonical/references/structural-token-retention.md +6 -9
  315. package/ds-canonical/rules/meta-patterns.md +8 -8
  316. package/ds-canonical/rules/self-verify.md +4 -3
  317. package/ds-canonical/rules/spec-rules.md +1 -1
  318. package/ds-canonical/rules/story-rules.md +2 -2
  319. package/ds-canonical/rules/ui-development.md +4 -2
  320. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +9 -3
  321. package/ds-canonical/skills/code-quality-audit/SKILL.md +3 -3
  322. package/ds-canonical/skills/codex-collab/SKILL.md +9 -7
  323. package/ds-canonical/skills/codex-collab/references/brief-template.md +1 -1
  324. package/ds-canonical/skills/codify-principle/SKILL.md +2 -2
  325. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  326. package/ds-canonical/skills/component-quality-gate/references/checklist.md +2 -2
  327. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +57 -68
  328. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +29 -0
  329. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +29 -10
  330. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +21 -0
  331. package/ds-canonical/skills/delivery-handoff/SKILL.md +5 -0
  332. package/ds-canonical/skills/design-system-audit/SKILL.md +27 -26
  333. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +13 -1
  334. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +1 -1
  335. package/ds-canonical/skills/governance-health/SKILL.md +2 -1
  336. package/ds-canonical/skills/knowledge-prune/SKILL.md +3 -0
  337. package/ds-canonical/skills/knowledge-prune/references/prune-dimensions-d5-d10.md +1 -0
  338. package/ds-canonical/skills/new-component/SKILL.md +7 -5
  339. package/ds-canonical/skills/new-component/references/new-component-checklist.md +1 -1
  340. package/ds-canonical/skills/performance-audit/SKILL.md +2 -2
  341. package/ds-canonical/skills/product-ui-audit/SKILL.md +3 -3
  342. package/ds-canonical/skills/propose-options/SKILL.md +3 -3
  343. package/ds-canonical/skills/prototype/SKILL.md +1 -1
  344. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +2 -2
  345. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +3 -3
  346. package/ds-canonical/skills/story-writing/SKILL.md +3 -3
  347. package/ds-canonical/skills/visual-audit/SKILL.md +10 -2
  348. package/ds-story-manifest.json +29 -20
  349. package/llms-full.txt +22 -1
  350. package/llms.txt +5 -4
  351. package/package.json +7 -3
  352. package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
  353. package/src/components/Accordion/accordion.stories.tsx +16 -1
  354. package/src/components/Alert/alert.principles.stories.tsx +1 -1
  355. package/src/components/Alert/alert.spec.md +8 -10
  356. package/src/components/Alert/alert.stories.tsx +28 -28
  357. package/src/components/Alert/alert.tsx +1 -1
  358. package/src/components/AppShell/_demo-helpers.tsx +6 -3
  359. package/src/components/AppShell/app-shell.spec.md +4 -4
  360. package/src/components/AppShell/app-shell.tsx +28 -2
  361. package/src/components/AspectRatio/aspect-ratio.spec.md +1 -1
  362. package/src/components/AspectRatio/aspect-ratio.stories.tsx +7 -89
  363. package/src/components/Avatar/avatar.anatomy.stories.tsx +7 -3
  364. package/src/components/Avatar/avatar.principles.stories.tsx +19 -15
  365. package/src/components/Avatar/avatar.spec.md +2 -2
  366. package/src/components/Avatar/avatar.stories.tsx +8 -6
  367. package/src/components/Avatar/avatar.tsx +13 -5
  368. package/src/components/Badge/badge.principles.stories.tsx +1 -1
  369. package/src/components/Badge/badge.spec.md +2 -0
  370. package/src/components/Badge/badge.stories.tsx +4 -2
  371. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +6 -4
  372. package/src/components/Breadcrumb/breadcrumb.stories.tsx +6 -5
  373. package/src/components/Breadcrumb/breadcrumb.tsx +3 -2
  374. package/src/components/BulkActionBar/bulk-action-bar.spec.md +4 -2
  375. package/src/components/Button/button.principles.stories.tsx +1 -1
  376. package/src/components/Button/button.spec.md +2 -2
  377. package/src/components/Button/button.tsx +18 -3
  378. package/src/components/Calendar/calendar.anatomy.stories.tsx +12 -10
  379. package/src/components/Calendar/calendar.principles.stories.tsx +14 -6
  380. package/src/components/Calendar/calendar.spec.md +5 -4
  381. package/src/components/Calendar/calendar.stories.tsx +7 -4
  382. package/src/components/Calendar/calendar.tsx +26 -7
  383. package/src/components/Carousel/carousel.anatomy.stories.tsx +5 -4
  384. package/src/components/Carousel/carousel.spec.md +2 -2
  385. package/src/components/Carousel/carousel.tsx +11 -3
  386. package/src/components/Chart/chart.anatomy.stories.tsx +7 -4
  387. package/src/components/Chart/chart.principles.stories.tsx +1 -1
  388. package/src/components/Chart/chart.stories.tsx +2 -8
  389. package/src/components/Chart/chart.tsx +3 -0
  390. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +28 -49
  391. package/src/components/Checkbox/checkbox.principles.stories.tsx +1 -1
  392. package/src/components/Checkbox/checkbox.spec.md +11 -26
  393. package/src/components/Checkbox/checkbox.stories.tsx +11 -8
  394. package/src/components/Checkbox/checkbox.tsx +18 -13
  395. package/src/components/Chip/chip.anatomy.stories.tsx +44 -24
  396. package/src/components/Chip/chip.principles.stories.tsx +1 -1
  397. package/src/components/Chip/chip.spec.md +5 -4
  398. package/src/components/Chip/chip.tsx +5 -1
  399. package/src/components/CircularProgress/circular-progress.principles.stories.tsx +7 -4
  400. package/src/components/CircularProgress/circular-progress.spec.md +3 -3
  401. package/src/components/CircularProgress/circular-progress.stories.tsx +2 -2
  402. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +2 -2
  403. package/src/components/Coachmark/coachmark.principles.stories.tsx +2 -1
  404. package/src/components/Coachmark/coachmark.spec.md +5 -5
  405. package/src/components/Coachmark/coachmark.stories.tsx +3 -1
  406. package/src/components/Coachmark/coachmark.tsx +10 -3
  407. package/src/components/Combobox/combobox.anatomy.stories.tsx +2 -2
  408. package/src/components/Combobox/combobox.tsx +53 -19
  409. package/src/components/Command/command.anatomy.stories.tsx +2 -2
  410. package/src/components/Command/command.principles.stories.tsx +1 -1
  411. package/src/components/Command/command.stories.tsx +42 -10
  412. package/src/components/DataTable/cell-registry.tsx +86 -63
  413. package/src/components/DataTable/column-types.ts +10 -1
  414. package/src/components/DataTable/data-table-column-visibility-panel.tsx +1 -1
  415. package/src/components/DataTable/data-table-filter-panel.tsx +4 -1
  416. package/src/components/DataTable/data-table-interaction-layer.tsx +15 -19
  417. package/src/components/DataTable/data-table.anatomy.stories.tsx +15 -13
  418. package/src/components/DataTable/data-table.principles.stories.tsx +9 -9
  419. package/src/components/DataTable/data-table.spec.md +32 -12
  420. package/src/components/DataTable/data-table.stories.tsx +16 -17
  421. package/src/components/DataTable/data-table.tsx +103 -60
  422. package/src/components/DataTable/index.ts +3 -0
  423. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +4 -4
  424. package/src/components/DateGrid/date-grid.principles.stories.tsx +1 -1
  425. package/src/components/DateGrid/date-grid.spec.md +1 -1
  426. package/src/components/DateGrid/date-grid.tsx +3 -1
  427. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +8 -8
  428. package/src/components/DatePicker/date-picker.principles.stories.tsx +3 -3
  429. package/src/components/DatePicker/date-picker.spec.md +3 -3
  430. package/src/components/DatePicker/date-picker.stories.tsx +4 -5
  431. package/src/components/DatePicker/date-picker.tsx +99 -45
  432. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +12 -10
  433. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  434. package/src/components/DescriptionList/description-list.spec.md +3 -3
  435. package/src/components/DescriptionList/description-list.stories.tsx +7 -6
  436. package/src/components/Dialog/dialog.anatomy.stories.tsx +1 -0
  437. package/src/components/Dialog/dialog.spec.md +9 -0
  438. package/src/components/Dialog/dialog.stories.tsx +66 -5
  439. package/src/components/Dialog/dialog.tsx +60 -25
  440. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
  441. package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +8 -6
  442. package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -5
  443. package/src/components/DropdownMenu/dropdown-menu.tsx +18 -9
  444. package/src/components/Empty/empty.anatomy.stories.tsx +1 -1
  445. package/src/components/Empty/empty.spec.md +2 -2
  446. package/src/components/Field/field-context.ts +69 -5
  447. package/src/components/Field/field-controls.spec.md +62 -8
  448. package/src/components/Field/field-edit-keys.ts +66 -0
  449. package/src/components/Field/field-types.ts +58 -9
  450. package/src/components/Field/field-wrapper.tsx +50 -42
  451. package/src/components/Field/field.anatomy.stories.tsx +9 -6
  452. package/src/components/Field/field.spec.md +1 -1
  453. package/src/components/Field/field.stories.tsx +1 -1
  454. package/src/components/Field/field.tsx +2 -1
  455. package/src/components/Field/form-validation.spec.md +3 -3
  456. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +6 -6
  457. package/src/components/FieldControlGroup/field-control-group.spec.md +9 -4
  458. package/src/components/FieldControlGroup/field-control-group.tsx +1 -1
  459. package/src/components/FileItem/file-item.anatomy.stories.tsx +1 -1
  460. package/src/components/FileItem/file-item.spec.md +14 -8
  461. package/src/components/FileItem/file-item.stories.tsx +36 -25
  462. package/src/components/FileItem/file-item.tsx +8 -6
  463. package/src/components/FileUpload/file-upload.anatomy.stories.tsx +6 -6
  464. package/src/components/FileUpload/file-upload.principles.stories.tsx +5 -5
  465. package/src/components/FileUpload/file-upload.spec.md +1 -1
  466. package/src/components/FileUpload/file-upload.tsx +1 -1
  467. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +4 -3
  468. package/src/components/FileViewer/file-viewer.principles.stories.tsx +3 -3
  469. package/src/components/FileViewer/file-viewer.spec.md +30 -12
  470. package/src/components/FileViewer/file-viewer.stories.tsx +1 -2
  471. package/src/components/FileViewer/file-viewer.tsx +12 -4
  472. package/src/components/FileViewer/image-renderer.tsx +35 -7
  473. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -2
  474. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -3
  475. package/src/components/HoverCard/hover-card.spec.md +5 -5
  476. package/src/components/HoverCard/hover-card.stories.tsx +16 -16
  477. package/src/components/HoverCard/hover-card.tsx +5 -3
  478. package/src/components/InlineEdit/index.ts +5 -0
  479. package/src/components/InlineEdit/inline-edit.spec.md +149 -0
  480. package/src/components/InlineEdit/inline-edit.stories.tsx +246 -0
  481. package/src/components/InlineEdit/inline-edit.tsx +287 -0
  482. package/src/components/Input/input.anatomy.stories.tsx +8 -7
  483. package/src/components/Input/input.principles.stories.tsx +2 -12
  484. package/src/components/Input/input.spec.md +13 -18
  485. package/src/components/Input/input.tsx +69 -22
  486. package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
  487. package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
  488. package/src/components/LinkInput/link-input.tsx +11 -10
  489. package/src/components/Menu/menu-item.anatomy.stories.tsx +3 -3
  490. package/src/components/Menu/menu-item.principles.stories.tsx +1 -1
  491. package/src/components/Menu/menu-item.spec.md +22 -15
  492. package/src/components/Menu/menu-item.stories.tsx +39 -11
  493. package/src/components/Menu/menu-item.tsx +38 -4
  494. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  495. package/src/components/Notice/notice.spec.md +16 -3
  496. package/src/components/NumberInput/number-input.anatomy.stories.tsx +3 -3
  497. package/src/components/NumberInput/number-input.principles.stories.tsx +1 -1
  498. package/src/components/NumberInput/number-input.spec.md +4 -4
  499. package/src/components/NumberInput/number-input.tsx +19 -12
  500. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +10 -8
  501. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +3 -3
  502. package/src/components/OverflowIndicator/overflow-indicator.spec.md +4 -2
  503. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +71 -63
  504. package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -8
  505. package/src/components/Pagination/pagination.spec.md +1 -1
  506. package/src/components/Pagination/pagination.stories.tsx +2 -6
  507. package/src/components/Pagination/pagination.tsx +1 -1
  508. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +4 -4
  509. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +2 -2
  510. package/src/components/PeoplePicker/people-picker.spec.md +6 -6
  511. package/src/components/PeoplePicker/people-picker.tsx +56 -16
  512. package/src/components/PeoplePicker/person-display.tsx +32 -16
  513. package/src/components/Popover/popover.anatomy.stories.tsx +2 -2
  514. package/src/components/Popover/popover.tsx +3 -1
  515. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +12 -23
  516. package/src/components/ProfileCard/profile-card.spec.md +3 -3
  517. package/src/components/ProfileCard/profile-card.tsx +6 -6
  518. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +3 -1
  519. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +1 -1
  520. package/src/components/ProgressBar/progress-bar.stories.tsx +50 -42
  521. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +10 -28
  522. package/src/components/RadioGroup/radio-group.stories.tsx +29 -32
  523. package/src/components/RadioGroup/radio-group.tsx +41 -15
  524. package/src/components/Rating/rating.spec.md +11 -3
  525. package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
  526. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  527. package/src/components/ScrollArea/scroll-area.spec.md +7 -3
  528. package/src/components/ScrollArea/scroll-area.stories.tsx +1 -1
  529. package/src/components/ScrollArea/scroll-area.tsx +17 -4
  530. package/src/components/Select/select.anatomy.stories.tsx +3 -3
  531. package/src/components/Select/select.spec.md +27 -17
  532. package/src/components/Select/select.stories.tsx +33 -0
  533. package/src/components/Select/select.tsx +190 -36
  534. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +4 -4
  535. package/src/components/SelectMenu/select-menu.spec.md +15 -7
  536. package/src/components/SelectMenu/select-menu.tsx +16 -3
  537. package/src/components/SelectionControl/boolean-value.tsx +39 -0
  538. package/src/components/SelectionControl/index.ts +1 -0
  539. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +2 -2
  540. package/src/components/SelectionControl/selection-item.principles.stories.tsx +2 -2
  541. package/src/components/SelectionControl/selection-item.spec.md +3 -3
  542. package/src/components/SelectionControl/selection-item.stories.tsx +3 -3
  543. package/src/components/Separator/separator.spec.md +2 -2
  544. package/src/components/Separator/separator.stories.tsx +6 -27
  545. package/src/components/Sheet/sheet.anatomy.stories.tsx +1 -1
  546. package/src/components/Sheet/sheet.principles.stories.tsx +1 -1
  547. package/src/components/Sheet/sheet.spec.md +2 -2
  548. package/src/components/Sheet/sheet.tsx +9 -5
  549. package/src/components/Sidebar/sidebar.anatomy.stories.tsx +16 -12
  550. package/src/components/Sidebar/sidebar.principles.stories.tsx +10 -8
  551. package/src/components/Sidebar/sidebar.spec.md +13 -15
  552. package/src/components/Sidebar/sidebar.stories.tsx +8 -7
  553. package/src/components/Sidebar/sidebar.tsx +37 -25
  554. package/src/components/Skeleton/skeleton.stories.tsx +4 -11
  555. package/src/components/Slider/slider.anatomy.stories.tsx +3 -3
  556. package/src/components/Slider/slider.principles.stories.tsx +2 -2
  557. package/src/components/Slider/slider.spec.md +5 -5
  558. package/src/components/Slider/slider.tsx +3 -1
  559. package/src/components/Steps/steps.anatomy.stories.tsx +4 -4
  560. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  561. package/src/components/Steps/steps.spec.md +1 -1
  562. package/src/components/Switch/switch.anatomy.stories.tsx +7 -7
  563. package/src/components/Switch/switch.principles.stories.tsx +4 -4
  564. package/src/components/Switch/switch.spec.md +8 -8
  565. package/src/components/Switch/switch.stories.tsx +9 -24
  566. package/src/components/Switch/switch.tsx +17 -13
  567. package/src/components/Tabs/tabs.anatomy.stories.tsx +10 -7
  568. package/src/components/Tabs/tabs.spec.md +1 -1
  569. package/src/components/Tabs/tabs.tsx +21 -1
  570. package/src/components/Textarea/textarea.anatomy.stories.tsx +1 -1
  571. package/src/components/Textarea/textarea.principles.stories.tsx +1 -1
  572. package/src/components/Textarea/textarea.spec.md +4 -4
  573. package/src/components/Textarea/textarea.tsx +72 -46
  574. package/src/components/TimePicker/time-columns.tsx +6 -2
  575. package/src/components/TimePicker/time-picker.principles.stories.tsx +1 -1
  576. package/src/components/TimePicker/time-picker.spec.md +3 -3
  577. package/src/components/TimePicker/time-picker.tsx +16 -10
  578. package/src/components/Toast/toast.stories.tsx +7 -4
  579. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +4 -4
  580. package/src/components/Tooltip/tooltip.principles.stories.tsx +3 -3
  581. package/src/components/Tooltip/tooltip.spec.md +1 -1
  582. package/src/components/Tooltip/tooltip.stories.tsx +4 -39
  583. package/src/components/Tooltip/tooltip.tsx +8 -6
  584. package/src/components/TreeView/tree-view.anatomy.stories.tsx +6 -3
  585. package/src/components/TreeView/tree-view.spec.md +42 -11
  586. package/src/components/TreeView/tree-view.stories.tsx +1 -0
  587. package/src/components/TreeView/tree-view.tsx +322 -17
  588. package/src/index.ts +584 -60
  589. package/src/patterns/action-bar/action-bar.spec.md +9 -0
  590. package/src/patterns/action-bar/action-bar.stories.tsx +6 -3
  591. package/src/patterns/element-anatomy/inline-action.spec.md +2 -0
  592. package/src/patterns/element-anatomy/item-anatomy.spec.md +14 -5
  593. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -4
  594. package/src/patterns/element-anatomy/item-anatomy.tsx +7 -6
  595. package/src/patterns/header-canonical/header-canonical.spec.md +5 -4
  596. package/src/patterns/overlay-surface/overlay-surface.spec.md +22 -1
  597. package/src/styles/tokens.css +3 -0
  598. package/src/tokens/README.md +1 -1
  599. package/src/tokens/color/color.spec.md +3 -3
  600. package/src/tokens/color/color.stories.tsx +3 -3
  601. package/src/tokens/density/density.stories.tsx +16 -3
  602. package/src/tokens/layoutSpace/layoutSpace.spec.md +3 -1
  603. package/src/tokens/motion/motion.css +33 -21
  604. package/src/tokens/motion/motion.spec.md +32 -15
  605. package/src/tokens/motion/motion.stories.tsx +58 -5
  606. package/src/tokens/motion/motion.ts +7 -6
  607. package/src/tokens/motion/overlay-motion.ts +26 -0
  608. package/src/tokens/orphan-tokens.spec.md +4 -4
  609. package/src/tokens/token-system.spec.md +1 -0
  610. package/src/tokens/uiSize/uiSize.spec.md +1 -1
  611. package/src/tokens/uiSize/uiSize.stories.tsx +4 -2
  612. package/src/tokens/utility-registry.json +160 -23
@@ -1,6 +1,7 @@
1
1
  // @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
2
2
  import { useState } from 'react'
3
3
  import type { Meta } from '@storybook/react'
4
+ import { ChevronUp, ChevronDown, MoreVertical } from 'lucide-react'
4
5
  import {
5
6
  Dialog, DialogTrigger, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogClose,
6
7
  } from './dialog'
@@ -47,7 +48,7 @@ function NotificationSettings() {
47
48
  <DialogHeader>
48
49
  <DialogTitle>通知設定</DialogTitle>
49
50
  </DialogHeader>
50
- <DialogBody className="!px-0 !pt-0 !pb-0">
51
+ <DialogBody className="!px-0 !pt-0 !pb-0">{/* @tabs-content-gap-ok: list-as-region canonical(body 撤 chrome padding、list wrapper py-2 own;非 tabs !pt-0 hack)*/}
51
52
  <div className="flex flex-col py-2">
52
53
  {items.map((n) => (
53
54
  // item-anatomy Family 2:[content: title + desc(--item-gap-label-desc-scanning gap)] [ItemSuffix: Switch]
@@ -239,7 +240,7 @@ export const LongContent = {
239
240
  {/* Body 放 list canonical(2026-05-01):body 撤 chrome padding(`!px-0 !pt-0 !pb-0`)+ list outer
240
241
  wrapper 自帶 `py-2`(menu group 8px breathing)+ item 自帶 `px-loose rounded-md`
241
242
  (hover bg flush 到 chrome 邊)。30 筆超出 viewport → 驗證預設高度(填滿)+ body 區捲動。 */}
242
- <DialogBody className="!px-0 !pt-0 !pb-0">
243
+ <DialogBody className="!px-0 !pt-0 !pb-0">{/* @tabs-content-gap-ok: list-as-region canonical(body 撤 chrome padding、list wrapper py-2 own;非 tabs !pt-0 hack)*/}
243
244
  <div role="list" className="flex flex-col py-2">
244
245
  {MEMBERS.map((m, i) => (
245
246
  <MemberRow key={m.empNum} member={m} index={i} />
@@ -284,7 +285,7 @@ export const Destructive = {
284
285
  /**
285
286
  * ListBody — body 放 list 的 canonical pattern(Material / Polaris / Atlassian / Linear /
286
287
  * GitHub Primer 共識:overlay body 裝 list 時 body 不加 vertical padding,節奏源 = item 自己的 py)。
287
- * 我方 canonical(2026-05-01):`<DialogBody className="!px-0 !pt-0 !pb-0">` + list wrapper `py-2`
288
+ * 我方 canonical(2026-05-01):`<DialogBody className="!px-0 !pt-0 !pb-0">`(@tabs-content-gap-ok: list-as-region 文件範例,非 tabs !pt-0 hack)+ list wrapper `py-2`
288
289
  * + item 自帶 `px-loose rounded-md`。不加 `flush` variant — 加 1 row(search / banner)就破功,
289
290
  * 保留 chrome padding 較穩。以下三個範例對應不同 list-item tier(item-anatomy Family 2 / MenuItem)。
290
291
  */
@@ -301,7 +302,7 @@ export const ListBody = {
301
302
  <DialogHeader>
302
303
  <DialogTitle>成員列表</DialogTitle>
303
304
  </DialogHeader>
304
- <DialogBody className="!px-0 !pt-0 !pb-0">
305
+ <DialogBody className="!px-0 !pt-0 !pb-0">{/* @tabs-content-gap-ok: list-as-region canonical(body 撤 chrome padding、list wrapper py-2 own;非 tabs !pt-0 hack)*/}
305
306
  <div role="list" className="flex flex-col py-2">
306
307
  {MEMBERS.slice(0, 6).map((m, i) => (
307
308
  <MemberRow key={m.empNum} member={m} index={i} />
@@ -330,7 +331,7 @@ export const ListBody = {
330
331
  <DialogHeader>
331
332
  <DialogTitle>選擇標籤</DialogTitle>
332
333
  </DialogHeader>
333
- <DialogBody className="!px-0 !pt-0 !pb-0">
334
+ <DialogBody className="!px-0 !pt-0 !pb-0">{/* @tabs-content-gap-ok: list-as-region canonical(body 撤 chrome padding、list wrapper py-2 own;非 tabs !pt-0 hack)*/}
334
335
  <div role="list" className="flex flex-col py-2">
335
336
  {['Bug', 'Feature', 'Improvement', 'Research', 'Documentation', 'Refactor', 'Test'].map((t) => (
336
337
  // 小 item 純文字 label → 用 **MenuItem** primitive(世界級 Linear Cmd+K / Polaris OptionList
@@ -355,6 +356,66 @@ export const ListBody = {
355
356
  ),
356
357
  }
357
358
 
359
+ /**
360
+ * 標頭操作(actions slot,2026-07-08 WM 戰役 codify — 關閉鈕分隔線 SSOT 化)
361
+ *
362
+ * 真實場景:任務詳情 modal(Jira / Linear / Asana 任務檢視)— header 級 prev / next 導覽
363
+ * + ⋮ 溢出選單,操作對象是「dialog 承載的這筆任務」本身(非欄位級、非 confirm/cancel)。
364
+ *
365
+ * - `<DialogHeader actions={…}>`:DS 自動在 actions 與內建 Close X 之間放 `<ButtonDivider>`
366
+ * (action-bar.spec.md:281「最右側為關閉/解除按鈕 → 分隔線必須(誤觸保護)」;
367
+ * 幾何 = mx-1 於 gap-2 cluster → 12px 對稱)。**Consumer 禁自刻 cluster + divider**。
368
+ * - 按鈕 = `variant="text" iconOnly`(text 自動 data-unbounded,不撐高 48px chrome header;
369
+ * 對齊 action-bar「溢出按鈕一律最低視覺重量」)。
370
+ */
371
+ export const HeaderActions = {
372
+ name: '標頭操作',
373
+ render: () => (
374
+ <Dialog defaultOpen>
375
+ <DialogTrigger asChild>
376
+ <Button variant="tertiary">開啟任務詳情</Button>
377
+ </DialogTrigger>
378
+ <DialogContent autoHeight maxWidth={520}>
379
+ <DialogHeader
380
+ actions={
381
+ <>
382
+ <Button variant="text" iconOnly size="sm" startIcon={ChevronUp} aria-label="上一筆任務" />
383
+ <Button variant="text" iconOnly size="sm" startIcon={ChevronDown} aria-label="下一筆任務" />
384
+ <Button variant="text" iconOnly size="sm" startIcon={MoreVertical} aria-label="更多操作" />
385
+ </>
386
+ }
387
+ >
388
+ <DialogTitle>WM-142 結帳流程改版</DialogTitle>
389
+ </DialogHeader>
390
+ <DialogBody>
391
+ <div className="flex flex-col gap-[var(--layout-space-loose)]">
392
+ <p className="text-body">
393
+ 重新設計結帳步驟,將付款方式與發票資訊合併為單一步驟,預期提升行動端轉換率。
394
+ </p>
395
+ <div className="flex flex-col gap-2">
396
+ {[
397
+ ['指派人', 'Alan Chen'],
398
+ ['狀態', '進行中'],
399
+ ['截止日', '2026-07-18'],
400
+ ].map(([label, value]) => (
401
+ <div key={label} className="flex items-center gap-3">
402
+ <span className="w-16 shrink-0 text-caption text-fg-secondary">{label}</span>
403
+ <span className="text-body">{value}</span>
404
+ </div>
405
+ ))}
406
+ </div>
407
+ </div>
408
+ </DialogBody>
409
+ <DialogFooter>
410
+ <DialogClose asChild>
411
+ <Button variant="tertiary">關閉</Button>
412
+ </DialogClose>
413
+ </DialogFooter>
414
+ </DialogContent>
415
+ </Dialog>
416
+ ),
417
+ }
418
+
358
419
  /**
359
420
  * 標頭內含分頁(2026-05-18 從 patterns/header-canonical/header-canonical.stories.tsx 整合過來
360
421
  * per user「應該整合進去 dialog 吧?目前應該不需要獨立的 header canonical 資料夾來說明這些東西」)
@@ -5,8 +5,10 @@ import { X as XIcon } from "lucide-react"
5
5
 
6
6
  import { cn } from "@/lib/utils"
7
7
  import { Button } from "@/design-system/components/Button/button"
8
+ import { ButtonDivider } from "@/design-system/components/Button/button-group"
8
9
  import { SurfaceHeader, SurfaceFooter, type SurfaceHeaderProps } from "@/design-system/patterns/overlay-surface/overlay-surface"
9
10
  import { ScrollArea } from "@/design-system/components/ScrollArea/scroll-area"
11
+ import { surfaceMotion } from "@/design-system/tokens/motion/overlay-motion"
10
12
 
11
13
  /**
12
14
  * Dialog (Modal) — Radix Dialog + 設計系統 token
@@ -22,7 +24,7 @@ import { ScrollArea } from "@/design-system/components/ScrollArea/scroll-area"
22
24
  *
23
25
  * ── 高度行為 ──
24
26
  * 預設:height 填滿 viewport(扣除 inset),body 捲動。防止動態內容跳動。
25
- * height="auto":高度隨內容,超過 viewport 時 max-height 安全帽。
27
+ * autoHeight(boolean):高度隨內容,超過 viewport 時 max-height 安全帽。
26
28
  */
27
29
 
28
30
  const Dialog = DialogPrimitive.Root
@@ -106,7 +108,8 @@ const DialogContent = React.forwardRef<
106
108
  className={cn(
107
109
  "fixed left-1/2 top-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2",
108
110
  "flex flex-col bg-surface-raised rounded-lg border border-border",
109
- "data-[state=open]:animate-in data-[state=closed]:animate-out motion-reduce:animate-none",
111
+ surfaceMotion,
112
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
110
113
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
111
114
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
112
115
  "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
@@ -129,35 +132,67 @@ const DialogContent = React.forwardRef<
129
132
  DialogContent.displayName = DialogPrimitive.Content.displayName
130
133
 
131
134
  // DialogHeader: SurfaceHeader + Close 按鈕(Dialog 特有)
132
- // justify-between children Close 分左右;Close 用 Radix DialogPrimitive.Close 包裝。
135
+ // Close 靠右由「第一 child flex-1 grow」達成(justify-between 已移除,見 return 註解);Close 用 Radix DialogPrimitive.Close 包裝。
133
136
  // 2026-05-18 audit gap fix:type 用 SurfaceHeaderProps 對齊 — DialogHeader 是 SurfaceHeader
134
- // 薄包裝,withTabs / lockDensity props 透過 spread 已 forward,但 TS type 沒 expose
137
+ // 薄包裝,withTabs / tabsSlot props 透過 spread 已 forward,但 TS type 沒 expose
135
138
  // 導致 consumer 不能用 `<DialogHeader withTabs>` 而只能寫 `as any` 繞。Type lift 修
136
139
  // per header-canonical.spec.md W1 跨 6 consumer 同契約。
140
+ export interface DialogHeaderProps extends SurfaceHeaderProps {
141
+ /**
142
+ * Header 級操作 cluster(2026-07-08 WM 戰役 codify — 關閉鈕分隔線 SSOT 化)。
143
+ *
144
+ * 提供時 render 在 Close X 左側,DS 自動在 actions 與 Close 之間放 `<ButtonDivider>`
145
+ * (action-bar.spec.md:281「最右側為關閉/解除按鈕 → 分隔線必須(誤觸保護)」;
146
+ * 幾何 = ButtonDivider mx-1 於 gap-2 cluster → 12px 對稱,同 spec「分隔線幾何」段)。
147
+ *
148
+ * 用例:任務詳情 prev/next 導覽、header 級溢出選單(⋮)。
149
+ * Consumer 傳 `<Button variant="text" iconOnly …>`(text variant 自動 data-unbounded,
150
+ * 不撐高 chrome header)。**禁**在 children 內自刻 cluster + divider(分隔線落點歸 DS)。
151
+ */
152
+ actions?: React.ReactNode
153
+ }
154
+
137
155
  const DialogHeader = React.forwardRef<
138
156
  HTMLDivElement,
139
- SurfaceHeaderProps
140
- >(({ className, children, ...props }, ref) => (
141
- // 2026-05-18:className 不再硬加 justify-between(冗餘:row 1 flex items-center gap-2,
142
- // 第一 child flex-1 grow 自然 push close X 靠右,跟 justify-between 同視覺)。
143
- // 並且 column mode(tabsSlot 提供)justify-between 會把 row 1 / row 2 上下推開 = 破裂。
144
- // tabsSlot via `...props` spread 自動 forward(type 來自 SurfaceHeaderProps)。
145
- <SurfaceHeader
146
- ref={ref}
147
- className={className}
148
- {...props}
149
- >
150
- <div className="flex-1 min-w-0">{children}</div>
151
- {/* Dismiss X(chrome-slot canonical,v5):Button 本身 native sm(28 md / 32 lg,touch target 亦同),
152
- 但 `dismiss` prop 自動標 `data-unbounded`,SurfaceHeader CSS rule 對其套負 my 讓
153
- layout 佔位 = 24(`data-dismiss` 僅作 openAutoFocus 排除 marker,與縮位無關),
154
- header = 24 + 2×tight = 48 / 56 chrome-header-height ✓。
155
- 詳 overlay-surface.spec.md「Chrome dismiss size canonical」*/}
157
+ DialogHeaderProps
158
+ >(({ className, children, actions, ...props }, ref) => {
159
+ // Dismiss X(chrome-slot canonical,v5):Button 本身 native sm(28 md / 32 lg,touch target 亦同),
160
+ // `dismiss` prop 自動標 `data-unbounded`,SurfaceHeader CSS rule 對其套負 my
161
+ // layout 佔位 = 24(`data-dismiss` 僅作 openAutoFocus 排除 marker,與縮位無關),
162
+ // header = 24 + 2×tight = 48 / 56 chrome-header-height ✓。
163
+ // 詳 overlay-surface.spec.md「Chrome dismiss size canonical」
164
+ const closeButton = (
156
165
  <DialogPrimitive.Close asChild>
157
166
  <Button data-dismiss iconOnly dismiss size="sm" startIcon={XIcon} aria-label="關閉" />
158
167
  </DialogPrimitive.Close>
159
- </SurfaceHeader>
160
- ))
168
+ )
169
+ return (
170
+ // 2026-05-18:className 不再硬加 justify-between(冗餘:row 1 是 flex items-center gap-2,
171
+ // 第一 child flex-1 grow 自然 push close X 靠右,跟 justify-between 同視覺)。
172
+ // 並且 column mode(tabsSlot 提供)justify-between 會把 row 1 / row 2 上下推開 = 破裂。
173
+ // tabsSlot via `...props` spread 自動 forward(type 來自 SurfaceHeaderProps)。
174
+ <SurfaceHeader
175
+ ref={ref}
176
+ className={className}
177
+ {...props}
178
+ >
179
+ <div className="flex-1 min-w-0">{children}</div>
180
+ {actions != null ? (
181
+ // actions 提供 → 右側一體 cluster:{actions} + ButtonDivider + Close。
182
+ // 分隔線 = 關閉保護 canonical(action-bar.spec.md:281),由 DS 放,consumer 零自刻。
183
+ // gap-2 + ButtonDivider mx-1 = 兩側 12px 對稱(action-bar.spec.md「分隔線幾何」)。
184
+ <div className="flex items-center gap-2 shrink-0">
185
+ {actions}
186
+ <ButtonDivider />
187
+ {closeButton}
188
+ </div>
189
+ ) : (
190
+ // 無 actions → 原結構(Close 直接是 SurfaceHeader child),行為零回歸
191
+ closeButton
192
+ )}
193
+ </SurfaceHeader>
194
+ )
195
+ })
161
196
  DialogHeader.displayName = "DialogHeader"
162
197
 
163
198
  // DialogBody: flex-1 ScrollArea + chrome padding(對齊 overlay-surface SSOT + ScrollArea canonical)
@@ -169,7 +204,7 @@ DialogHeader.displayName = "DialogHeader"
169
204
  // 不再提供 `flush` variant(2026-05-01 移除,先前曾叫 `variant="list"`)。
170
205
  // **canonical pattern** = consumer 自管 list outer wrapper + 用 `className` override 撤掉 chrome padding:
171
206
  // ```tsx
172
- // <DialogBody className="!px-0 !pt-0 !pb-0">
207
+ // <DialogBody className="!px-0 !pt-0 !pb-0"> ← @tabs-content-gap-ok: JSDoc 文件範例(list-as-region canonical,非 tabs !pt-0 hack)
173
208
  // <div className="py-2"> {/* list outer wrapper 自帶 py-2(menu group canonical)*/}
174
209
  // {items.map(item => <MenuItem className="px-[var(--layout-space-loose)] rounded-md" />)}
175
210
  // </div>
@@ -187,7 +222,7 @@ const DialogBody = React.forwardRef<
187
222
  HTMLDivElement,
188
223
  React.ComponentPropsWithoutRef<typeof ScrollArea>
189
224
  >(({ className, children, ...props }, ref) => (
190
- <ScrollArea ref={ref} data-dialog-body className="flex-1 min-h-0" {...props}>
225
+ <ScrollArea fillX ref={ref} data-dialog-body className="flex-1 min-h-0" {...props}>
191
226
  <div
192
227
  className={cn(
193
228
  "px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)] pb-[var(--layout-space-bottom)]",
@@ -941,7 +941,7 @@ const StateBehaviorInner = () => {
941
941
  <span className="text-caption font-medium text-fg-secondary">行為規則</span>
942
942
  <ul className="text-caption text-fg-secondary space-y-1.5 ml-4 list-disc">
943
943
  <li>`DropdownMenuItem` 點擊即 close——這是「action 觸發即完成」語意。</li>
944
- <li>`DropdownMenuCheckboxItem` 點擊**不 close**——多選語意,等使用者關 menu 才 commit。</li>
944
+ <li>`DropdownMenuCheckboxItem` 點擊**不 close**——每次勾選即時生效(onCheckedChange 即時 fire),menu 保持開啟只為讓使用者連續多選。</li>
945
945
  <li>`DropdownMenuSub` 永遠右側滑入,parent menu 保持展開——提供 breadcrumb 式認知流,使用者知道自己在哪層。</li>
946
946
  <li>Escape close 整個選單(含所有展開子層;Radix root close)。ArrowLeft 才逐層收合(焦點回 SubTrigger)。</li>
947
947
  <li>Portal render 到 body,`z-50` 確保不被 parent overflow 截斷。</li>
@@ -1,4 +1,7 @@
1
1
  // @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.
2
+ // @story-trait-allow: missing-opensnapshot — 原則頁多個 inline dropdown demo 只為承載規則說明(rule note),
3
+ // forced defaultOpen 會讓 ~10 個浮層互疊;overlay open-state 快照由 dropdown-menu.anatomy.stories.tsx
4
+ // StateBehavior(defaultOpen)canonical 涵蓋(對齊 hover-card.principles.stories.tsx 同 rationale)。
2
5
  import React from 'react'
3
6
  import LinkTo from '@storybook/addon-links/react'
4
7
  import type { Meta, StoryObj } from '@storybook/react'
@@ -17,7 +20,6 @@ import {
17
20
  DropdownMenuSeparator,
18
21
  DropdownMenuGroup,
19
22
  DropdownMenuLabel,
20
- DropdownMenuShortcut,
21
23
  } from './dropdown-menu'
22
24
  import { Button } from '@/design-system/components/Button/button'
23
25
 
@@ -313,17 +315,17 @@ export const SuffixRule: Story = {
313
315
  render: () => (
314
316
  <div>
315
317
  <Rule
316
- title="DropdownMenuShortcut鍵盤快捷鍵(ml-auto 靠右)"
317
- note="使用者熟悉快捷鍵後可跳過選單直接按快捷鍵。shortcut 用 fg-muted 作為輔助資訊色,不搶 label 注意力"
318
+ title="鍵盤快捷鍵canonical shortcut prop(靠右對齊列尾)"
319
+ note="使用者熟悉快捷鍵後可跳過選單直接按快捷鍵。shortcut 用 fg-muted 作為輔助資訊色,不搶 label 注意力。標準場景用 `shortcut` prop(走 MenuItem endContent flex slot,真正靠右對齊列尾);`<DropdownMenuShortcut>` child 僅為相容 shadcn 的 escape-hatch,會 inline 附加在 label 尾、不會靠右。"
318
320
  >
319
321
  <DropdownMenu>
320
322
  <DropdownMenuTrigger asChild>
321
323
  <Button variant="tertiary">檔案</Button>
322
324
  </DropdownMenuTrigger>
323
325
  <DropdownMenuContent>
324
- <DropdownMenuItem>新增<DropdownMenuShortcut>⌘N</DropdownMenuShortcut></DropdownMenuItem>
325
- <DropdownMenuItem>開啟<DropdownMenuShortcut>⌘O</DropdownMenuShortcut></DropdownMenuItem>
326
- <DropdownMenuItem>儲存<DropdownMenuShortcut>⌘S</DropdownMenuShortcut></DropdownMenuItem>
326
+ <DropdownMenuItem shortcut="⌘N">新增</DropdownMenuItem>
327
+ <DropdownMenuItem shortcut="⌘O">開啟</DropdownMenuItem>
328
+ <DropdownMenuItem shortcut="⌘S">儲存</DropdownMenuItem>
327
329
  </DropdownMenuContent>
328
330
  </DropdownMenu>
329
331
  </Rule>
@@ -69,8 +69,8 @@ DropdownMenu ← Radix Root,管理開關狀態
69
69
 
70
70
  **快捷鍵提示 API(兩條,擇一不混用)**:
71
71
  - **Canonical:`<DropdownMenuItem shortcut="⌘C">`** prop —— 渲染進 MenuItem `endContent` 正規後綴 slot(跟 badge / endIcon 同槽,gap / 對齊一致)。**標準場景一律用 prop。**
72
- - **Escape-hatch:`<DropdownMenuShortcut>` child** —— 對齊 shadcn DropdownMenuShortcut idiom,供需手動 compose children 的少數場景( `ml-auto` children,繞過 endContent slot)
73
- - 兩者**視覺統一**(`text-caption` + `tracking-shortcut` + `fg-muted`,與 CommandShortcut 一致);**同一 item 只用一種**(見「禁止事項」)。
72
+ - **Escape-hatch:`<DropdownMenuShortcut>` child** —— 保留以相容 shadcn DropdownMenuShortcut idiom(source:https://ui.shadcn.com/docs/components/dropdown-menu `DropdownMenuShortcut` = `ml-auto` span,npm published API)。⚠️ 本 DS 的 MenuItem 把 children 塞進 ItemContent 的 label `<span>`( flex row),故 child 上的 `ml-auto` **不會靠右**——⌘N 只會 inline 附加在 label 文字尾端。要真正靠右對齊列尾的後綴,一律用上方 canonical `shortcut` prop
73
+ - 兩者**字體樣式統一**(`text-caption` + `tracking-shortcut` + `fg-muted`,與 CommandShortcut 一致),但**位置不等價**(prop 靠右對齊列尾;child inline 附加在 label 尾);**同一 item 只用一種**(見「禁止事項」)。
74
74
  - 為何不砍 child 只留 prop:`DropdownMenuShortcut` 是 npm published API(對齊 shadcn,fork repo 可能用),硬砍 = breaking;故保留為 escape-hatch,prop 為 canonical preferred。
75
75
 
76
76
  ### DropdownMenuGroup 的自動分隔
@@ -90,7 +90,7 @@ DropdownMenu ← Radix Root,管理開關狀態
90
90
  | 邊界 padding 來源 | 每個 Group 自己的 py-2(Command.List 無 py) | Content 的 py-2(Group 不套 py-2 避免 double) |
91
91
  | Group 間 gap | 8 + 8 = 16 + border | 0 + 8 + 8 = 16 + border |
92
92
 
93
- **為什麼不直接套 `py-2`**:`DropdownMenuContent` 已有 `py-2` 提供 Content 邊界 paddingRadix 預期行為,移除會影響 trigger focus offset)。若 Group 再套 `py-2` 會 double padding。改用 `mt-2 pt-2` 只加在第二個 Group 起,視覺等價但不 double。
93
+ **為什麼不直接套 `py-2`**:`DropdownMenuContent` 已有 `py-2` 提供 Content 邊界 padding(純視覺呼吸空間;Radix roving focus 依 collection refs + `element.focus()`,不讀 CSS padding,移除 py-2 不影響鍵盤導覽 / focus offset)。若 Group 再套 `py-2` 會 double padding。改用 `mt-2 pt-2` 只加在第二個 Group 起,視覺等價但不 double。
94
94
 
95
95
  兩種分隔機制的選擇:
96
96
  - **用 `DropdownMenuGroup` 包裝同類 items** → 自動分隔(零手動,跟 MenuGroup 理念一致)
@@ -123,7 +123,7 @@ CheckboxItem 和 RadioItem 雖然涉及「選擇」,但它們控制的是**即
123
123
 
124
124
  - prefix:由 `DropdownMenuItem` 的 `startIcon` prop 傳入,經 MenuItem 內部的 prefix 對齊容器(消費 item-anatomy 的 `itemPrefixAlignVariants`,`h-[1lh]` 對齊第一行 label)渲染。icon 跟 label 同色(foreground)
125
125
  - label:文字內容,`flex-1`
126
- - suffix:canonical 走 item prop(`shortcut` / `badge` / `endIcon` → MenuItem `endContent` 正規 slot);`DropdownMenuShortcut` child escape-hatch(`ml-auto` 靠右,見「快捷鍵提示 API」段)。指示型 icon 用 `fg-muted`
126
+ - suffix:canonical 走 item prop(`shortcut` / `badge` / `endIcon` → MenuItem `endContent` 正規 slot,真正靠右對齊列尾);`DropdownMenuShortcut` child 僅相容用 escape-hatch(inline 附加在 label 尾、**不靠右**,見「快捷鍵提示 API」段)。指示型 icon 用 `fg-muted`
127
127
 
128
128
  padding 公式:`py = (field-height - 1lh) / 2`,單行時總高度等於同 size 的 Button / Input。
129
129
 
@@ -209,7 +209,7 @@ DropdownMenu 是掃描模式——使用者快速瀏覽選項,所有尺寸使
209
209
 
210
210
  ## StateBehavior(DropdownMenu 層級特有)
211
211
 
212
- Item-level default / hover / focused / selected / disabled **色彩**由 MenuItem primitive SSOT 擁有(`patterns/element-anatomy/item-anatomy.spec.md`「選擇 / 狀態視覺規則」),在本元件 `ColorMatrix` story 承載並直接引用 MenuItem token。**selected × highlighted 疊加(2026-07-04 Q2 拍板)**:selected bg 勝 Radix `data-[highlighted]`(hover + keyboard cursor)— 對齊 MenuItem「selected 勝 hover」canonical(menu-item.spec.md 狀態表),`selected && 'data-[highlighted]:bg-neutral-selected'` override;CheckboxItem/RadioItem checked 同規則。DropdownMenu 的 `StateBehavior` story 展示**浮層層級特有的動態行為**:open / close 動畫(Radix `data-state` 驅動)、Submenu 展開 / 收起、CheckboxItem toggle(多選不 close)——這些是 item primitive 沒有的維度。
212
+ Item-level default / hover / focused / selected / disabled **色彩**由 MenuItem primitive SSOT 擁有(`patterns/element-anatomy/item-anatomy.spec.md`「選擇 / 狀態視覺規則」),在本元件 `ColorMatrix` story 承載並直接引用 MenuItem token。**selected × highlighted 疊加(2026-07-04 Q2 拍板)**:selected bg 勝 Radix `data-[highlighted]`(hover + keyboard cursor)— 對齊 MenuItem「selected 勝 hover」canonical(menu-item.spec.md 狀態表),`selected && 'bg-neutral-selected data-[highlighted]:bg-neutral-selected-active'` override(selected×highlighted 加深一階 `bg-neutral-selected-active`);**僅 RadioItem checked 走此 selected-bg 規則**(checked 底色套外層 Radix RadioItem)。CheckboxItem checked **不套 row bg**——checked 由內層 checkbox 控件表達,highlighted 時仍為 neutral-hover。DropdownMenu 的 `StateBehavior` story 展示**浮層層級特有的動態行為**:open / close 動畫(Radix `data-state` 驅動)、Submenu 展開 / 收起、CheckboxItem toggle(多選不 close)——這些是 item primitive 沒有的維度。
213
213
 
214
214
  ---
215
215
 
@@ -13,6 +13,7 @@ import {
13
13
  ICON_SIZE as ROW_ICON_SIZE,
14
14
  type RowSize,
15
15
  } from "@/design-system/patterns/element-anatomy/item-anatomy"
16
+ import { overlayMotion } from "@/design-system/tokens/motion/overlay-motion"
16
17
 
17
18
  /**
18
19
  * DropdownMenu — Radix DropdownMenu + MenuItem visual layer
@@ -41,7 +42,8 @@ import {
41
42
  // ── Floating layer 共用樣式 ──
42
43
  const floatingLayerClass = [
43
44
  'z-50 overflow-hidden rounded-lg border border-border bg-surface-raised',
44
- 'data-[state=open]:animate-in data-[state=closed]:animate-out motion-reduce:animate-none',
45
+ overlayMotion,
46
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
45
47
  'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
46
48
  'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
47
49
  'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
@@ -97,8 +99,10 @@ DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName
97
99
  // 的 8px,只需在第二個起的 group 加 8+8 = 16px gap + border)
98
100
  //
99
101
  // **視覺結果等同**:兩種實作的 visual output 一致,只是「padding 住在哪層」
100
- // 不同。不強制統一 CSS 表達式——DropdownMenuContent 的 py-2 是既有 Radix
101
- // 期望的行為,移除會影響 trigger 鍵盤導覽的 focus offset。
102
+ // 不同。不強制統一 CSS 表達式——DropdownMenuContent 的 py-2 是純視覺 Content
103
+ // 邊界 padding(Radix roving focus 依 collection refs + element.focus(),不讀
104
+ // CSS padding;對齊 spec.md「為什麼不直接套 py-2」段)。Group 若再套 py-2 會
105
+ // double padding,故 Group 用 mt-2/pt-2 只加在第二個起。
102
106
  const DropdownMenuGroup = React.forwardRef<
103
107
  React.ElementRef<typeof DropdownMenuPrimitive.Group>,
104
108
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Group>
@@ -423,7 +427,8 @@ const DropdownMenuSeparator = React.forwardRef<
423
427
  DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
424
428
 
425
429
  // ── RadioItem(單選,排序方式等)──
426
- // Radix handles checked state; visual用 MenuItem selected highlight。
430
+ // Radix handles checked state;checked 底色套在外層 Radix RadioItem 本身(parent-bg
431
+ // pattern,詳下方 2026-05-31 #10 註解),內層 MenuItem 恆 !bg-transparent 讓它透出。
427
432
  interface DropdownMenuRadioItemProps
428
433
  extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> {
429
434
  /** Prefix icon(LucideIcon) */
@@ -467,12 +472,16 @@ const DropdownMenuRadioItem = React.forwardRef<
467
472
  })
468
473
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
469
474
 
470
- // ── Shortcut(鍵盤快捷鍵提示,ml-auto 靠右)──
475
+ // ── Shortcut(鍵盤快捷鍵提示 child;escape-hatch,不靠右)──
471
476
  // **Canonical 是 `<DropdownMenuItem shortcut="⌘C">`** prop —— 走 MenuItem `endContent` 正規後綴 slot
472
- // (跟 badge / endIcon 同槽、gap/對齊一致)。本 child 是 **composition escape-hatch**(對齊 shadcn
473
- // DropdownMenuShortcut idiom),供需手動 compose children 的少數場景;它用 `ml-auto` 塞在 children
474
- // 內(繞過 endContent slot)。**同一 item 只用一種,勿混用**(見 spec.md 禁止事項)。
475
- // 視覺統一:text-caption + tracking-shortcut + fg-muted(對齊 prop 後綴 + CommandShortcut)。
477
+ // (跟 badge / endIcon 同槽、gap/對齊一致,真正靠右對齊列尾)。本 child 是 **composition
478
+ // escape-hatch**(相容 shadcn DropdownMenuShortcut idiom = `ml-auto` span,source:
479
+ // https://ui.shadcn.com/docs/components/dropdown-menu;npm published API 不砍)。⚠️
480
+ // DropdownMenuItem children 會進 MenuItem ItemContent label `<span>`(inline context,
481
+ // 非 flex row),故 `ml-auto` **不生效、不會靠右**——只會 inline 附加在 label 文字尾;`ml-auto`
482
+ // 僅在 consumer 自組 flex row 時生效。要靠右一律用 canonical `shortcut` prop。**同一 item
483
+ // 只用一種,勿混用**(見 spec.md「快捷鍵提示 API」+ 禁止事項)。
484
+ // 字體樣式統一:text-caption + tracking-shortcut + fg-muted(對齊 prop 後綴 + CommandShortcut);位置不等價。
476
485
  const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (
477
486
  <span
478
487
  className={cn('ml-auto text-caption text-fg-muted tracking-shortcut', className)}
@@ -146,7 +146,7 @@ export const ScenarioMatrix: Story = {
146
146
  <div>
147
147
  <H3>Table 空資料</H3>
148
148
  <div className="border border-border rounded-lg p-8">
149
- <Empty description="無資料" className="py-12" />
149
+ <Empty description="還沒有訂單" className="py-12" />
150
150
  </div>
151
151
  </div>
152
152
 
@@ -132,8 +132,8 @@ Empty 是 **non-interactive layout primitive**——本身無 ARIA role(讓 cons
132
132
  ## 消費範例
133
133
 
134
134
  ```tsx
135
- // Table 空狀態(最簡)
136
- <Empty description="沒有資料" />
135
+ // Table 空狀態(最簡)——文案仍點出「缺什麼資料」,避免抽象的「無資料」(見「禁止事項」)
136
+ <Empty description="還沒有訂單" />
137
137
 
138
138
  // SelectMenu 無結果
139
139
  <Empty icon={SearchX} description="找不到符合的結果" />
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react'
2
- import type { FieldMode, FieldVariant } from './field-types'
2
+ import type { FieldMode, FieldVariant, FieldVariantInternal, FieldWidth } from './field-types'
3
+ import { EMPTY_DISPLAY } from './field-wrapper'
3
4
 
4
5
  // ── Types ──
5
- export type { FieldMode, FieldVariant }
6
+ export type { FieldMode, FieldVariant, FieldVariantInternal, FieldWidth }
6
7
  export type FieldOrientation = 'vertical' | 'horizontal'
7
8
  export type FieldSize = 'sm' | 'md' | 'lg'
8
9
  export type FieldControlLayout = 'inline' | 'block'
@@ -29,7 +30,8 @@ export interface FieldContextValue {
29
30
  descriptionId: string
30
31
  errorId: string
31
32
  mode: FieldMode
32
- /** 視覺外殼透傳(2026-05-05)。default = 含 border+bg;bare = 透明 variant,hover/focus reveal。
33
+ /** 視覺外殼透傳(2026-05-05)。default = 含 border+bg;naked = cell-as-input(edit×naked 自畫 border-based state machine;display/readonly/disabled×naked 用 transparent border 由 host cell 供邊框);`bare` 2026-07-09 退役;naked 2026-07-14 型別收窄至
34
+ * FieldVariantInternal(@internal)— 公開 `<Field variant>` 只收 default,故本欄位維持 FieldVariant。
33
35
  * child Field control 自動繼承,per-control prop override 可覆寫。詳 field-types.ts。 */
34
36
  variant: FieldVariant
35
37
  disabled: boolean
@@ -202,10 +204,12 @@ export function useResolvedFieldMode({
202
204
  }
203
205
 
204
206
  /**
205
- * Resolve Field control 的 **variant**(default / bare / naked 視覺外殼)— 2026-06-08 SSOT。
207
+ * Resolve Field control 的 **variant**(default / naked 視覺外殼;`bare` 2026-07-09 退役)— 2026-06-08 SSOT。
206
208
  * 優先序:顯式 prop > FieldContext.variant > 'default'。與既有各控件公式一字不差(Δ=0),統一以利 gate 強制。
209
+ * 2026-07-14 API 策展 E:入參 / 回傳 widen 為 FieldVariantInternal — naked 僅 DataTable cell-registry
210
+ * 經 @internal 通道傳入(公開 prop 型別 = FieldVariant,不含 naked)。
207
211
  */
208
- export function useResolvedFieldVariant(variantProp?: FieldVariant | null): FieldVariant {
212
+ export function useResolvedFieldVariant(variantProp?: FieldVariantInternal | null): FieldVariantInternal {
209
213
  const fieldCtx = React.useContext(FieldContext)
210
214
  return variantProp ?? fieldCtx?.variant ?? 'default'
211
215
  }
@@ -232,3 +236,63 @@ export function FieldSurfaceSizeProvider({
232
236
  }): React.ReactElement {
233
237
  return React.createElement(FieldSurfaceSizeContext.Provider, { value: size }, children)
234
238
  }
239
+
240
+ /**
241
+ * Table-cell 可編輯訊號(2026-07-08 user 拍板)— 獨立於 FieldSurfaceContext / FieldSurfaceSizeContext
242
+ * 的純 boolean context,由 host(DataTable cell registry)注入該 cell 是否可編輯,讓 useFieldEmptyDisplay
243
+ * 分流「可編輯 cell 空 display → 空白」vs「不可編輯 cell 空 display → '-'」。
244
+ * value = boolean primitive(stable when unchanged),不破壞 cell memo identity(同 TableScrollContext /
245
+ * FieldSurfaceSizeContext L119-121 canonical);絕不污染 FieldContext(useFieldContext() 在 cell 內仍 null)。
246
+ */
247
+ const FieldSurfaceEditableContext = React.createContext<boolean>(false)
248
+
249
+ export function FieldSurfaceEditableProvider({
250
+ isEditable,
251
+ children,
252
+ }: {
253
+ isEditable: boolean
254
+ children: React.ReactNode
255
+ }): React.ReactElement {
256
+ return React.createElement(FieldSurfaceEditableContext.Provider, { value: isEditable }, children)
257
+ }
258
+
259
+ /**
260
+ * 空值顯示分流(2026-07-08 user 拍板,verbatim「...都用"-"...我從頭到尾哪裡有說要用全形的」):
261
+ *
262
+ * | 情境 | 空值顯示 |
263
+ * |------------------------------------------------|----------|
264
+ * | table-cell **可編輯** 的 display 靜止態 | **空白 `''`**(不佔位,affordance = hover outline)|
265
+ * | table-cell **不可編輯**(readonly cell) | **半形 `-`** |
266
+ * | standalone display / readonly / form / toolbar | **半形 `-`** |
267
+ *
268
+ * 收斂式:`surface==='table-cell' && isEditable ? '' : EMPTY_DISPLAY`。
269
+ * 可編輯 form / edit 輸入框走 native placeholder(不經此 hook)。boolean → unchecked / disabled →
270
+ * 同上文字 + text-fg-disabled(M24),各控件自理。
271
+ * 世界級對照:table-cell blank = MUI X / AG Grid / Ant core / Notion / Airtable grid 域共識;
272
+ * 非 table `-` = Ant ProTable `columnEmptyText`(見 field-wrapper.tsx EMPTY_DISPLAY 註)。
273
+ * SSOT 條文 → field-controls.spec.md「null / undefined 值」;全 Field family display/readonly/disabled
274
+ * 空值渲染必經此 hook,禁直接引 EMPTY_DISPLAY 常數(genre 分流會漏)。
275
+ */
276
+ export function useFieldEmptyDisplay(): string {
277
+ const surface = useFieldSurface()
278
+ const isEditable = React.useContext(FieldSurfaceEditableContext)
279
+ return surface === 'table-cell' && isEditable ? '' : EMPTY_DISPLAY
280
+ }
281
+
282
+ /**
283
+ * 空值符號「-」顏色分流(2026-07-09 user 拍板 verbatim「「-」代表的是不可編輯只拿來供檢視的值
284
+ * 所以應該跟readonly 的value同樣顏色吧」):
285
+ *
286
+ * 「-」是「不可編輯、供檢視的值」→ 同 readonly value 色 = `text-foreground`
287
+ * (field-wrapper.tsx base `text-foreground`),**非** `text-fg-muted`(muted 是「可編輯 placeholder
288
+ * 提示」的裝飾語意;空值符號不是提示、是被檢視的值狀態)。
289
+ * disabled 態維持 `text-fg-disabled`(M24 disabled 顯著性 > foreground/muted,不可被蓋)。
290
+ *
291
+ * SSOT:全 Field family display/readonly/disabled 空值 span 消費此 helper,傳入已 resolve 的
292
+ * resolvedMode。純函式(非 hook)—— resolvedMode 已由 useResolvedFieldMode 解析(含控件自身
293
+ * disabled prop,context hook 讀不到);故以 resolvedMode 為入參,可條件呼叫、不受 Rules of Hooks 限制。
294
+ * 世界級對照:Ant read-only / Carbon read-only value = 正常前景色;placeholder 才 muted。
295
+ */
296
+ export function fieldEmptyColorClass(resolvedMode: FieldMode): string {
297
+ return resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-foreground'
298
+ }