@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
@@ -4,9 +4,9 @@
4
4
  import * as React from 'react'
5
5
  import { X, ChevronDown } from 'lucide-react'
6
6
  import { cn } from '@/lib/utils'
7
- import type { FieldMode, FieldVariant } from '@/design-system/components/Field/field-types'
8
- import { fieldWrapperStyles, EMPTY_DISPLAY, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'
9
- import { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid } from '@/design-system/components/Field/field-context'
7
+ import type { FieldMode, FieldVariant, FieldVariantInternal, FieldWidth } from '@/design-system/components/Field/field-types'
8
+ import { fieldWrapperStyles, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'
9
+ import { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid, useFieldEmptyDisplay, fieldEmptyColorClass } from '@/design-system/components/Field/field-context'
10
10
  import { Tag } from '@/design-system/components/Tag/tag'
11
11
  import { ItemInlineAction, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'
12
12
  import { OverflowIndicator } from '@/design-system/components/OverflowIndicator/overflow-indicator'
@@ -326,8 +326,9 @@ function ComboboxTagStack({
326
326
  value?: string[] | null; options?: ComboboxOption[]; tagSize?: 'sm' | 'md' | 'lg'
327
327
  wrap?: boolean; containerRef?: React.RefObject<HTMLDivElement | null>; disabled?: boolean
328
328
  }) {
329
+ const emptyDisplay = useFieldEmptyDisplay()
329
330
  const ownRef = React.useRef<HTMLDivElement>(null)
330
- if (!value || value.length === 0) return <span className="text-fg-muted">{EMPTY_DISPLAY}</span>
331
+ if (!value || value.length === 0) return <span className={fieldEmptyColorClass(disabled ? 'disabled' : 'display')}>{emptyDisplay}</span>
331
332
  const items = value.map(v => ({ value: v, label: options?.find(o => o.value === v)?.label ?? v }))
332
333
  const disabledClass = disabled ? 'bg-disabled text-fg-disabled' : undefined
333
334
 
@@ -366,6 +367,10 @@ export interface ComboboxProps {
366
367
  mode?: FieldMode
367
368
  /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */
368
369
  variant?: FieldVariant
370
+ /** 寬度軸 — `fill` 填滿容器(default)/ `hug` 依內容收縮:value 寬 + slot 元素寬 + gap +
371
+ * field 內 padding;chrome 與互動不變。場景 = detail pane inline metadata。
372
+ * SSOT → field-controls.spec.md「寬度軸(width: fill / hug)」。 */
373
+ width?: FieldWidth
369
374
  error?: boolean
370
375
  size?: 'sm' | 'md' | 'lg'
371
376
  options: ComboboxOption[]
@@ -485,9 +490,13 @@ const getIconSize = (size: string) => ICON_SIZE[size as 'sm' | 'md' | 'lg']
485
490
  // ── Shared readonly/disabled/display render ─────────────────────────────────
486
491
 
487
492
  function ReadonlyMultiSelect({
488
- mode, variant: variantProp, size, options, value, wrap, className, showDisplayEndIcon = false,
489
- }: Pick<ComboboxProps, 'mode' | 'variant' | 'size' | 'options' | 'value' | 'wrap' | 'className' | 'showDisplayEndIcon'>) {
493
+ mode, variant: variantProp, width, size, options, value, wrap, className, showDisplayEndIcon = false,
494
+ }: Pick<ComboboxProps, 'mode' | 'width' | 'size' | 'options' | 'value' | 'wrap' | 'className' | 'showDisplayEndIcon'> & {
495
+ /** @internal 2026-07-14 API 策展 E:內部 render helper 吃 FieldVariantInternal(naked 由 cell-registry 通道傳入)*/
496
+ variant?: FieldVariantInternal
497
+ }) {
490
498
  const resolvedMode = mode ?? 'readonly'
499
+ const emptyDisplay = useFieldEmptyDisplay()
491
500
  const variant = variantProp ?? 'default'
492
501
  const sz = size ?? 'md'
493
502
  const iconSize = sz === 'lg' ? 20 : 16
@@ -503,20 +512,20 @@ function ReadonlyMultiSelect({
503
512
  if (!showDisplayEndIcon) {
504
513
  // 2026-05-14 I2 fix(spec contract (e) display typography canonical):empty bare span 套
505
514
  // `fieldDisplayTextClass(sz)`(sm/md→text-body,lg→text-body-lg)— 對齊跨 Field family 統一。
506
- if (!hasTags) return <span className={cn(fieldDisplayTextClass(sz), 'text-fg-muted', className)}>{EMPTY_DISPLAY}</span>
515
+ if (!hasTags) return <span className={cn(fieldDisplayTextClass(sz), fieldEmptyColorClass(resolvedMode), className)}>{emptyDisplay}</span>
507
516
  return (
508
517
  <ComboboxTagStack value={value} options={options} tagSize={sz} wrap={wrap} />
509
518
  )
510
519
  }
511
520
  return (
512
521
  <div
513
- className={cn(fieldWrapperStyles({ mode: 'display', variant, size: sz }), hasTags && tagPadding[sz], className)}
522
+ className={cn(fieldWrapperStyles({ mode: 'display', variant, width, size: sz }), hasTags && tagPadding[sz], className)}
514
523
  data-field-mode="display"
515
524
  >
516
525
  {hasTags ? (
517
526
  <ComboboxTagStack value={value} options={options} tagSize={sz} wrap={wrap} />
518
527
  ) : (
519
- <span className={cn('flex-1 min-w-0', 'text-fg-muted')}>{EMPTY_DISPLAY}</span>
528
+ <span className={cn('flex-1 min-w-0', fieldEmptyColorClass(resolvedMode))}>{emptyDisplay}</span>
520
529
  )}
521
530
  <ItemSuffix className="pointer-events-none">
522
531
  <ChevronDown size={iconSize} className="shrink-0 text-fg-muted" aria-hidden />
@@ -527,7 +536,7 @@ function ReadonlyMultiSelect({
527
536
 
528
537
  return (
529
538
  <div ref={containerRef}
530
- className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), hasTags && tagPadding[sz],
539
+ className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, width, size: sz }), hasTags && tagPadding[sz],
531
540
  // 2026-05-18 #6A Round 1 Step 1/4(per user 拍板「決策6選a」+ codex M31 Step 5 verdict cite combobox.tsx:451):
532
541
  // readonly/disabled path 對齊 L293 display wrapper 已 ship 的 overflow-hidden fix。
533
542
  // M10 propagation:原 overflow-visible 讓 readonly tag 越界蓋 indicator,跟 display 不對稱。
@@ -540,7 +549,7 @@ function ReadonlyMultiSelect({
540
549
  <ComboboxTagStack value={value} options={options} tagSize={sz} wrap={wrap}
541
550
  containerRef={containerRef} disabled={resolvedMode === 'disabled'} />
542
551
  ) : (
543
- <span className="text-fg-muted">{EMPTY_DISPLAY}</span>
552
+ <span className={fieldEmptyColorClass(resolvedMode)}>{emptyDisplay}</span>
544
553
  )}
545
554
  {/* 2026-06-26 類型身份 indicator:edit 顯示 / readonly 不顯示(純值、不可開下拉) / disabled 保留(fg-disabled,對齊原生 <select disabled>);naked cell 依 showDisplayEndIcon */}
546
555
  {(variant === 'naked' ? !!showDisplayEndIcon : resolvedMode === 'disabled') && (
@@ -567,12 +576,16 @@ function ReadonlyMultiSelect({
567
576
  type ComboboxInternalProps = ComboboxProps & { __triggerRef?: React.Ref<HTMLDivElement> }
568
577
 
569
578
  function NativeCombobox({
570
- mode, variant: variantProp, error = false, size = 'md', options, value = [], onChange, placeholder,
579
+ mode, variant: variantProp, width, error = false, size = 'md', options, value = [], onChange, placeholder,
571
580
  className, disabled: disabledProp, wrap = false, clearable = false, showDisplayEndIcon = false,
572
581
  __triggerRef,
582
+ 'aria-label': ariaLabel,
573
583
  }: ComboboxInternalProps) {
584
+ // a11y(2026-07-14 dim10):touch/native 路徑同樣接 fieldCtx — id 讓 FieldLabel htmlFor
585
+ // 命名 native <select>;describedby/errormessage/required 對齊 desktop CustomCombobox trigger。
586
+ const fieldCtx = useFieldContext()
574
587
  const disabled = useResolvedFieldDisabled(disabledProp)
575
- const variant: FieldVariant = useResolvedFieldVariant(variantProp)
588
+ const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)
576
589
  // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="display"> 漏 cascade
577
590
  const resolvedMode = useResolvedFieldMode({ mode, disabled })
578
591
  const iconSize = getIconSize(size)
@@ -588,7 +601,7 @@ function NativeCombobox({
588
601
  const tagAreaRef = React.useRef<HTMLDivElement>(null)
589
602
 
590
603
  if (resolvedMode !== 'edit') {
591
- return <ReadonlyMultiSelect mode={resolvedMode} variant={variant} size={size} options={options} value={value} wrap={wrap} className={className} showDisplayEndIcon={showDisplayEndIcon} />
604
+ return <ReadonlyMultiSelect mode={resolvedMode} variant={variant} width={width} size={size} options={options} value={value} wrap={wrap} className={className} showDisplayEndIcon={showDisplayEndIcon} />
592
605
  }
593
606
 
594
607
  const items = value.map(v => ({ value: v, label: options.find(o => o.value === v)?.label ?? v }))
@@ -597,6 +610,15 @@ function NativeCombobox({
597
610
 
598
611
  const selectDropdown = unselected.length > 0 ? (
599
612
  <select ref={selectRef} value="" onChange={(e) => handleAdd(e.target.value)}
613
+ // a11y(2026-07-14 dim10):accessible name — FieldLabel htmlFor 經 id 命名 native select;
614
+ // consumer aria-label 優先,否則 fieldCtx.labelId fallback(對齊 select.tsx:240 accname 優先序)。
615
+ id={fieldCtx?.id}
616
+ aria-label={ariaLabel}
617
+ aria-labelledby={ariaLabel ? undefined : fieldCtx?.labelId}
618
+ aria-invalid={error || undefined}
619
+ aria-required={fieldCtx?.required || undefined}
620
+ aria-describedby={fieldCtx?.descriptionId}
621
+ aria-errormessage={error ? fieldCtx?.errorId : undefined}
600
622
  className={cn('bg-transparent outline-none border-none p-0 text-[inherit] font-[inherit] leading-[inherit] text-fg-muted cursor-pointer appearance-none',
601
623
  value.length > 0 ? 'absolute inset-0 w-full h-full opacity-0 z-0 cursor-pointer' : 'relative z-10 flex-1 min-w-20')}>
602
624
  <option value="" disabled>{placeholder ?? '選擇...'}</option>
@@ -605,7 +627,7 @@ function NativeCombobox({
605
627
  ) : null
606
628
 
607
629
  return (
608
- <div ref={__triggerRef} className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }), value.length > 0 && tagPadding[size], 'relative',
630
+ <div ref={__triggerRef} className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, width, size, error }), value.length > 0 && tagPadding[size], 'relative',
609
631
  wrap && 'items-start py-1', className)}
610
632
  style={{ paddingRight: 'var(--field-px)', ...(wrap ? { height: 'auto' } : undefined) }} data-field-mode="edit" data-error={error ? '' : undefined}
611
633
  onClick={(e) => { if (e.target === e.currentTarget) { selectRef.current?.showPicker?.(); selectRef.current?.focus() } }}>
@@ -642,7 +664,7 @@ function NativeCombobox({
642
664
  // ── Custom Combobox (desktop — consumes SelectMenu) ───────────────────
643
665
 
644
666
  function CustomCombobox({
645
- mode, variant: variantProp, error: errorProp = false, size = 'md', options, value = [], onChange, placeholder,
667
+ mode, variant: variantProp, width, error: errorProp = false, size = 'md', options, value = [], onChange, placeholder,
646
668
  className, disabled: disabledProp, wrap = false, clearable = false, searchable = false, loading, searchIn = 'menu',
647
669
  searchPlaceholder = '搜尋…', // i18n-allow: DS default
648
670
  searchAriaLabel = '搜尋選項', // i18n-allow: DS default
@@ -668,7 +690,7 @@ function CustomCombobox({
668
690
  const disabled = useResolvedFieldDisabled(disabledProp)
669
691
  // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="display"> 漏 cascade
670
692
  const resolvedMode = useResolvedFieldMode({ mode, disabled })
671
- const variant: FieldVariant = useResolvedFieldVariant(variantProp)
693
+ const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)
672
694
  const iconSize = getIconSize(size)
673
695
  const showClear = clearable && value.length > 0 && resolvedMode === 'edit'
674
696
  const [open, setOpen] = React.useState(defaultOpen)
@@ -723,7 +745,7 @@ function CustomCombobox({
723
745
  )
724
746
 
725
747
  if (resolvedMode !== 'edit') {
726
- return <ReadonlyMultiSelect mode={resolvedMode} variant={variant} size={size} options={options} value={value} wrap={wrap} className={className} showDisplayEndIcon={showDisplayEndIcon} />
748
+ return <ReadonlyMultiSelect mode={resolvedMode} variant={variant} width={width} size={size} options={options} value={value} wrap={wrap} className={className} showDisplayEndIcon={showDisplayEndIcon} />
727
749
  }
728
750
 
729
751
  const chevronEl = <ChevronDown size={iconSize} className={cn('shrink-0 text-fg-muted transition-transform', open && 'rotate-180')} aria-hidden />
@@ -734,11 +756,14 @@ function CustomCombobox({
734
756
  id={fieldCtx?.id}
735
757
  role="combobox" aria-expanded={open} aria-haspopup="listbox" aria-controls={listboxId} tabIndex={0}
736
758
  aria-label={ariaLabel}
759
+ // a11y(2026-07-14 dim-10):div-based role=combobox 的 <label for> 無效,接 FieldLabel labelId
760
+ // (field-context.ts labelId jsDoc);consumer aria-label 優先 — 與 sibling select.tsx:705 同款 guard。
761
+ aria-labelledby={ariaLabel ? undefined : fieldCtx?.labelId}
737
762
  aria-invalid={error || undefined}
738
763
  aria-required={fieldCtx?.required || undefined}
739
764
  aria-describedby={fieldCtx?.descriptionId}
740
765
  aria-errormessage={error ? fieldCtx?.errorId : undefined}
741
- className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }), value.length > 0 && tagPadding[size], 'relative cursor-pointer',
766
+ className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, width, size, error }), value.length > 0 && tagPadding[size], 'relative cursor-pointer',
742
767
  wrap && 'items-start py-1',
743
768
  // 2026-05-06 v13.3 SSOT retire:per-control `open && 'border-primary'` 移除。Field default
744
769
  // 統一處理 — open=灰深(data-state)/ focus=藍;2026-07-04 Q1:error 亦收進 error variant。
@@ -752,6 +777,15 @@ function CustomCombobox({
752
777
  // open 後不 preventDefault 讓方向鍵自由流向選單導覽)。
753
778
  // 純 additive:此 trigger 原無 onKeyDown,不覆寫既有 handler;open 邏輯仍走 setOpen SSOT。
754
779
  onKeyDown={(e) => {
780
+ // a11y(2026-07-14 dim-10):Enter/Space 來自 descendant 互動元素(Tag 移除 / clear 按鈕)
781
+ // 時直接放行 —— 否則下方 preventDefault 會取消 native button activation(鍵盤永遠按不動
782
+ // 按鈕)。guard 限 Enter/Space + button 類:search input 的 Enter 仍走 cmdk 選項選取
783
+ // (forwardKeyToListbox),Escape / 方向鍵仍走 combobox 導覽。
784
+ if (
785
+ (e.key === 'Enter' || e.key === ' ') &&
786
+ e.target !== e.currentTarget &&
787
+ (e.target as HTMLElement).closest?.('button, a, [role="button"]')
788
+ ) return
755
789
  // 2026-07-05 D4 P0:open 後 ArrowUp/Down/Enter 轉送 cmdk root(select-menu.tsx forwardKeyToListbox)
756
790
  if (open && forwardKeyToListbox(listboxId, e)) return
757
791
  if (e.key === 'Enter' || e.key === ' ') {
@@ -2,8 +2,8 @@
2
2
  // Inspector / ColorMatrix / SizeMatrix / StateBehavior N/A — Command 是
3
3
  // headless Internal primitive(cmdk passthrough),不被 App 直接消費,而是透過
4
4
  // SelectMenu 等外層元件呈現。色彩 / 尺寸 / 狀態都由消費方(SelectMenu / Combobox /
5
- // PeoplePicker)決定並在各自的 anatomy 詳述。本檔僅保留 Overview 教結構與
6
- // 消費路徑。
5
+ // PeoplePicker)決定並在各自的 anatomy 詳述。本檔保留 Overview(教結構與
6
+ // 消費路徑)+ Accessibility(6-canonical 中適用的 2 個;2026-05-17 per Dim 13 加)。
7
7
  import type { Meta, StoryObj } from '@storybook/react'
8
8
  import { Settings, User, LogOut, FileText } from 'lucide-react'
9
9
  import {
@@ -30,7 +30,7 @@ export const UsageGuidance: Story = {
30
30
  <LinkTo kind="Design System/Internal/Command/展示" name="行內搜尋清單"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">行內搜尋清單 — Gmail 式 sidebar 信件資料夾過濾</span></LinkTo>
31
31
  </li>
32
32
  <li>
33
- <LinkTo kind="Design System/Internal/Command/展示" name="外觀切換器"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">外觀切換器選中立即執行的純動作清單</span></LinkTo>
33
+ <LinkTo kind="Design System/Internal/Command/展示" name="純動作指令"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">純動作指令選中立即執行的快速動作清單</span></LinkTo>
34
34
  </li>
35
35
  <li>
36
36
  <LinkTo kind="Design System/Internal/Command/展示" name="無結果狀態"><span className="text-primary hover:text-primary-hover font-medium cursor-pointer">搜尋無結果時的空狀態文案(CommandEmpty)</span></LinkTo>
@@ -200,47 +200,79 @@ export const InlineCommand: Story = {
200
200
  }
201
201
 
202
202
  /* ═══════════════════════════════════════════════════════════════════════════
203
- Story 3:Theme switcher(純動作 command,無 form value 儲存)
203
+ Story 3:純動作指令(action command,無 form value 儲存)
204
+ 2026-07-14 dim-68 修:原「外觀切換器」只 2 項固定 action 配搜尋框 —— 正向示範了
205
+ command.spec.md:75 明文禁止的「< 6 項短選單用 Command」誤用(短選單該用 DropdownMenu /
206
+ SegmentedControl)。改為快速動作清單(7 項、2 群組),保留本 story 獨有教學點:
207
+ 「選中立即執行、不保留 form value」的純 action palette。
204
208
  ═══════════════════════════════════════════════════════════════════════════ */
205
209
 
206
- const ThemeSwitcherDemo = () => {
210
+ const ActionCommandDemo = () => {
207
211
  const [theme, setTheme] = useState<'light' | 'dark'>('light')
212
+ const [lastAction, setLastAction] = useState<string | null>(null)
208
213
 
209
214
  return (
210
215
  <div className="flex flex-col gap-3 max-w-md">
211
216
  <p className="text-caption text-fg-muted">
212
- 純 action palette — 選中立即執行(切 theme),不保留 form value。
217
+ 純 action palette — 選中立即執行(切 theme / 觸發動作),不保留 form value。
218
+ 動作多到需要搜尋才用 Command;&lt; 6 項的短選單用 DropdownMenu(spec「與 DropdownMenu 的分界」)。
213
219
  </p>
214
220
  <div
215
221
  className="rounded-lg border border-border bg-surface-raised overflow-hidden"
216
222
  style={{ boxShadow: 'var(--elevation-100)' }}
217
223
  >
218
224
  <Command>
219
- <CommandInput placeholder="切換外觀…" />
225
+ <CommandInput placeholder="輸入指令…" />
220
226
  <CommandList>
221
- <CommandEmpty>沒有符合的外觀</CommandEmpty>
227
+ <CommandEmpty>沒有符合的指令</CommandEmpty>
222
228
  <CommandGroup heading="外觀">
223
- <CommandItem onSelect={() => setTheme('light')}>
229
+ <CommandItem onSelect={() => { setTheme('light'); setLastAction('切換淺色模式') }}>
224
230
  <Sun />
225
231
  <span>淺色模式</span>
226
232
  {theme === 'light' && <CommandShortcut>當前</CommandShortcut>}
227
233
  </CommandItem>
228
- <CommandItem onSelect={() => setTheme('dark')}>
234
+ <CommandItem onSelect={() => { setTheme('dark'); setLastAction('切換深色模式') }}>
229
235
  <MoonStar />
230
236
  <span>深色模式</span>
231
237
  {theme === 'dark' && <CommandShortcut>當前</CommandShortcut>}
232
238
  </CommandItem>
233
239
  </CommandGroup>
240
+ <CommandSeparator />
241
+ <CommandGroup heading="快速動作">
242
+ <CommandItem onSelect={() => setLastAction('建立新文件')}>
243
+ <Plus />
244
+ <span>建立新文件</span>
245
+ <CommandShortcut>⌘N</CommandShortcut>
246
+ </CommandItem>
247
+ <CommandItem onSelect={() => setLastAction('開啟收件匣')}>
248
+ <Inbox />
249
+ <span>開啟收件匣</span>
250
+ </CommandItem>
251
+ <CommandItem onSelect={() => setLastAction('加入我的最愛')}>
252
+ <Star />
253
+ <span>加入我的最愛</span>
254
+ </CommandItem>
255
+ <CommandItem onSelect={() => setLastAction('封存目前頁面')}>
256
+ <Archive />
257
+ <span>封存目前頁面</span>
258
+ </CommandItem>
259
+ <CommandItem onSelect={() => setLastAction('開啟設定')}>
260
+ <Settings />
261
+ <span>開啟設定</span>
262
+ <CommandShortcut>⌘,</CommandShortcut>
263
+ </CommandItem>
264
+ </CommandGroup>
234
265
  </CommandList>
235
266
  </Command>
236
267
  </div>
268
+ {lastAction && <p className="text-caption text-fg-muted">已執行:{lastAction}</p>}
237
269
  </div>
238
270
  )
239
271
  }
240
272
 
241
- export const ThemeSwitcher: Story = {
242
- name: '外觀切換器',
243
- render: () => <ThemeSwitcherDemo />,
273
+ export const ActionCommand: Story = {
274
+ name: '純動作指令',
275
+ render: () => <ActionCommandDemo />,
244
276
  }
245
277
 
246
278
  /* ═══════════════════════════════════════════════════════════════════════════
@@ -9,7 +9,7 @@
9
9
  //
10
10
  // 設計原則:
11
11
  // - 每個 cell component 接同一組 props(`CellComponentProps`)
12
- // - 用 `variant="naked"` — DataTable cell-as-input substrate(對齊 Field B1 chrome=bare)
12
+ // - 用 `variant="naked"` — DataTable cell-as-input substrate(Field chrome variant;bare 2026-07-09 退役)
13
13
  // - 消費 full Field 家族 primitive(無 stub)
14
14
  // - 不再用 `meta._editable` 私有 flag — `isEditable` 直接顯式入參(消除 M1 hack)
15
15
  //
@@ -21,19 +21,37 @@ import type { ComponentType } from 'react'
21
21
  import { Pencil } from 'lucide-react'
22
22
  import { cn } from '@/lib/utils'
23
23
  import type { ColumnType } from './column-types'
24
- import { Input } from '@/design-system/components/Input/input'
25
- import { Textarea } from '@/design-system/components/Textarea/textarea'
26
- import { NumberInput } from '@/design-system/components/NumberInput/number-input'
27
- import { Select } from '@/design-system/components/Select/select'
28
- import { Combobox } from '@/design-system/components/Combobox/combobox'
29
- import { DatePicker } from '@/design-system/components/DatePicker/date-picker'
30
- import { TimePicker } from '@/design-system/components/TimePicker/time-picker'
31
- import { PeoplePicker } from '@/design-system/components/PeoplePicker/people-picker'
32
- import { LinkInput } from '@/design-system/components/LinkInput/link-input'
33
- import { Checkbox } from '@/design-system/components/Checkbox/checkbox'
24
+ import { Input as InputPublic } from '@/design-system/components/Input/input'
25
+ import { Textarea as TextareaPublic } from '@/design-system/components/Textarea/textarea'
26
+ import { NumberInput as NumberInputPublic } from '@/design-system/components/NumberInput/number-input'
27
+ import { Select as SelectPublic } from '@/design-system/components/Select/select'
28
+ import { Combobox as ComboboxPublic } from '@/design-system/components/Combobox/combobox'
29
+ import { DatePicker as DatePickerPublic } from '@/design-system/components/DatePicker/date-picker'
30
+ import { TimePicker as TimePickerPublic } from '@/design-system/components/TimePicker/time-picker'
31
+ import { PeoplePicker as PeoplePickerPublic } from '@/design-system/components/PeoplePicker/people-picker'
32
+ import { LinkInput as LinkInputPublic } from '@/design-system/components/LinkInput/link-input'
33
+ import { Checkbox as CheckboxPublic } from '@/design-system/components/Checkbox/checkbox'
34
34
  import { Button } from '@/design-system/components/Button/button'
35
35
  import type { PersonValue } from '@/design-system/components/PeoplePicker/person-display'
36
- import { FieldSurfaceProvider, FieldSurfaceSizeProvider } from '@/design-system/components/Field/field-context'
36
+ import { FieldSurfaceProvider, FieldSurfaceSizeProvider, FieldSurfaceEditableProvider } from '@/design-system/components/Field/field-context'
37
+ import { makeEditSettleKeyHandler } from '@/design-system/components/Field/field-edit-keys'
38
+ import type { WithFieldVariantInternal } from '@/design-system/components/Field/field-types'
39
+
40
+ // ── @internal naked variant 通道(2026-07-14 API 策展 E,user 拍板「全部收窄」)──────────────
41
+ // `naked` 已從公開 FieldVariant 拆出(field-types.ts `FieldVariantInternal`);本檔是唯一合法
42
+ // naked 消費者(field-controls.spec.md「軸二 variant」明文)。以 `WithFieldVariantInternal`
43
+ // 型別層 widen 各 Field control 的 `variant` prop — 純型別、零 runtime;元件內部 cva / resolver
44
+ // 分支本就吃 FieldVariantInternal,widen 不引入 unsound 行為。
45
+ const Input = InputPublic as WithFieldVariantInternal<typeof InputPublic>
46
+ const Textarea = TextareaPublic as WithFieldVariantInternal<typeof TextareaPublic>
47
+ const NumberInput = NumberInputPublic as WithFieldVariantInternal<typeof NumberInputPublic>
48
+ const Select = SelectPublic as WithFieldVariantInternal<typeof SelectPublic>
49
+ const Combobox = ComboboxPublic as WithFieldVariantInternal<typeof ComboboxPublic>
50
+ const DatePicker = DatePickerPublic as WithFieldVariantInternal<typeof DatePickerPublic>
51
+ const TimePicker = TimePickerPublic as WithFieldVariantInternal<typeof TimePickerPublic>
52
+ const PeoplePicker = PeoplePickerPublic as WithFieldVariantInternal<typeof PeoplePickerPublic>
53
+ const LinkInput = LinkInputPublic as WithFieldVariantInternal<typeof LinkInputPublic>
54
+ const Checkbox = CheckboxPublic as WithFieldVariantInternal<typeof CheckboxPublic>
37
55
 
38
56
  // ── Types ────────────────────────────────────────────────────────────────────
39
57
 
@@ -81,18 +99,15 @@ function makeKeyHandler(
81
99
  onCancel?: () => void,
82
100
  parseValue?: (raw: string) => unknown,
83
101
  ) {
84
- return (e: React.KeyboardEvent<HTMLInputElement>) => {
85
- // IME 組字 guard(2026-07-05 D4 fix):中文輸入法選字的 Enter 是組字確認、Esc 是取消組字,
86
- // 非 commit / cancel 意圖 — 無 guard 會把半截組字提交並退出 edit(Esc 則丟棄整個 draft)。
87
- // 同 data-table.tsx nav handler 既有寫法(isComposing + Safari/舊 Chrome keyCode 229)。
88
- if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return
89
- if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }
90
- if (e.key === 'Enter') {
91
- e.preventDefault()
102
+ // 消費 edit-in-place 鍵盤結算 SSOT(field-edit-keys.ts):IME guard + Enter/Esc dispatch 統一
103
+ // (2026-07-09 抽出;原本 InlineEdit 漏 IME guard = bug,現同源)。value 讀取為 input-specific,留本地。
104
+ return makeEditSettleKeyHandler({
105
+ onCommit: (e) => {
92
106
  const raw = (e.target as HTMLInputElement).value
93
107
  onCommit?.(parseValue ? parseValue(raw) : raw)
94
- }
95
- }
108
+ },
109
+ onCancel: () => onCancel?.(),
110
+ })
96
111
  }
97
112
 
98
113
  const sizeForInput = (size: CellSize): CellSize => size
@@ -151,15 +166,13 @@ function StringCell({ value, meta, mode, size, isDisabled, autoRowHeight, onComm
151
166
  style={{ fieldSizing: 'content' } as React.CSSProperties}
152
167
  onChange={(e) => onDraft?.((e.target as HTMLTextAreaElement).value)}
153
168
  onBlur={(e) => onCommit?.((e.target as HTMLTextAreaElement).value)}
154
- onKeyDown={(e) => {
155
- // IME 組字 guard(2026-07-05 D4 fix,同 makeKeyHandler)
156
- if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return
157
- if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }
158
- if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
159
- e.preventDefault()
160
- onCommit?.((e.target as HTMLTextAreaElement).value)
161
- }
162
- }}
169
+ // 多行:走 edit-in-place 鍵盤結算 SSOT(IME guard + Esc + Cmd/Ctrl+Enter commit;
170
+ // plain Enter=換行)。commitOnEnter:false Enter 不攔。
171
+ onKeyDown={makeEditSettleKeyHandler({
172
+ onCommit: (e) => onCommit?.((e.target as HTMLTextAreaElement).value),
173
+ onCancel: () => onCancel?.(),
174
+ commitOnEnter: false,
175
+ })}
163
176
  />
164
177
  )
165
178
  }
@@ -216,12 +229,12 @@ function NumberCell({ value, meta, mode, size, isDisabled, onCommit, onCancel, o
216
229
  suffix={meta?.suffix}
217
230
  precision={meta?.precision}
218
231
  onBlur={() => onCommit?.(localValue)}
219
- onKeyDown={(e) => {
220
- // IME 組字 guard(2026-07-05 D4 fix,同 makeKeyHandler;IME 可在 number 欄輸入全形數字)
221
- if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return
222
- if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }
223
- if (e.key === 'Enter') { e.preventDefault(); onCommit?.(localValue) }
224
- }}
232
+ // 單行:走 edit-in-place 鍵盤結算 SSOT(IME guard + Esc + Enter commit)。
233
+ // commit localValue(controlled state,非 e.target.value)
234
+ onKeyDown={makeEditSettleKeyHandler({
235
+ onCommit: () => onCommit?.(localValue),
236
+ onCancel: () => onCancel?.(),
237
+ })}
225
238
  />
226
239
  )
227
240
  }
@@ -237,7 +250,7 @@ const dismissOnClose = (onCancel?: () => void) => (open: boolean) => { if (!open
237
250
  // Fix:`key={mode}` 強制 React unmount + remount,每次切 mode 都重跑 useState init。
238
251
  // 對齊 Notion / Airtable cell-as-input「display 跟 edit 是不同 mount cycle」語義。
239
252
 
240
- function DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {
253
+ function DateCell({ value, meta, mode, size, isDisabled, onCommit, onCancel }: CellComponentProps) {
241
254
  if (mode === 'display') {
242
255
  return (
243
256
  <DatePicker
@@ -248,10 +261,10 @@ function DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, o
248
261
  size={size}
249
262
  formatOptions={meta?.formatOptions}
250
263
  locale={meta?.locale}
251
- // Indicator(calendar icon)= editable affordance(2026-05-10 user 糾正)。
252
- // Non-editable cell 不該顯 picker indicator(誤導 read-only 為 editable)。
253
- // 對齊 UrlCell L394 / BooleanCell L368 既有 isEditable conditional pattern。
254
- showDisplayEndIcon={isEditable === true}
264
+ // 2026-07-08 user 拍板 A 案(推翻 2026-05-10/06-26 兩次拍板,per 6 家 benchmark 6/6 共識
265
+ // Ant/MUI X/AG Grid/Atlaskit/Notion/Airtable:display 態零恆顯型別 icon;editable
266
+ // affordance 統一 = hover outline(field.spec.md L4)。showDisplayEndIcon 不再傳
267
+ //(prop 保留為 spreadsheet-flavored 消費端 opt-in 逃生門,見 field.spec.md L6)。
255
268
  />
256
269
  )
257
270
  }
@@ -270,7 +283,7 @@ function DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, o
270
283
  )
271
284
  }
272
285
 
273
- function TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {
286
+ function TimeCell({ value, meta, mode, size, isDisabled, onCommit, onCancel }: CellComponentProps) {
274
287
  if (mode === 'display') {
275
288
  return (
276
289
  <TimePicker
@@ -281,7 +294,7 @@ function TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, o
281
294
  size={size}
282
295
  formatOptions={meta?.formatOptions}
283
296
  locale={meta?.locale}
284
- showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 indicator
297
+ // showDisplayEndIcon 不傳 2026-07-08 A 案:display 態零恆顯 icon(同 DateCell 註)
285
298
  />
286
299
  )
287
300
  }
@@ -301,7 +314,7 @@ function TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, o
301
314
  )
302
315
  }
303
316
 
304
- function SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {
317
+ function SelectCell({ value, meta, mode, size, isDisabled, onCommit, onCancel }: CellComponentProps) {
305
318
  // Display canonical(2026-05-05):cell IS variant,default plain text(no Tag pill 疊在 cell border 內)。
306
319
  // Consumer 可在 column meta.display='tag' opt-in 內容導向的 Tag 視覺(category 含色彩標籤等)。
307
320
  // 對齊 JTable / AG Grid「renderer/editor 視覺一致」canonical。
@@ -316,7 +329,8 @@ function SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit,
316
329
  options={meta?.options ?? []}
317
330
  size={size}
318
331
  display={displayMode}
319
- showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator
332
+ // showDisplayEndIcon 不傳 2026-07-08 A 案:display 態零恆顯 icon(同 DateCell 註)
333
+ selectedItemRenderer={meta?.selectedItemRenderer} // 2026-07-08 WM 戰役:status 類彩色 cell 顯示通道
320
334
  />
321
335
  )
322
336
  }
@@ -326,6 +340,7 @@ function SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit,
326
340
  autoFocus
327
341
  variant="naked"
328
342
  size={sizeForInput(size)}
343
+ selectedItemRenderer={meta?.selectedItemRenderer}
329
344
  options={meta?.options ?? []}
330
345
  value={value as string | null | undefined}
331
346
  onChange={(v) => onCommit?.(v)}
@@ -339,7 +354,7 @@ function SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit,
339
354
  )
340
355
  }
341
356
 
342
- function MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, isEditable, onCommitLive, onCancel }: CellComponentProps) {
357
+ function MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, onCommitLive, onCancel }: CellComponentProps) {
343
358
  const wrap = autoRowHeight && meta?.wrap === true
344
359
  if (mode === 'display') {
345
360
  return (
@@ -351,7 +366,7 @@ function MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, i
351
366
  options={meta?.options ?? []}
352
367
  wrap={wrap}
353
368
  size={size}
354
- showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator
369
+ // showDisplayEndIcon 不傳 2026-07-08 A 案:display 態零恆顯 icon(同 DateCell 註)
355
370
  />
356
371
  )
357
372
  }
@@ -371,10 +386,10 @@ function MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, i
371
386
  )
372
387
  }
373
388
 
374
- function PersonCell({ value, mode, size, isDisabled, isEditable, onCommit, onCancel, meta }: CellComponentProps) {
389
+ function PersonCell({ value, mode, size, isDisabled, onCommit, onCancel, meta }: CellComponentProps) {
375
390
  if (mode === 'display') {
376
- // 2026-05-10:non-editable 不顯 chevron indicator(對齊 UrlCell isEditable conditional pattern)
377
- return <PeoplePicker key="display" variant="naked" mode={displayOrDisabled(isDisabled)} value={value as PersonValue | null} size={size} showDisplayEndIcon={isEditable === true} />
391
+ // 2026-07-08 A 案:display 態零恆顯 icon( DateCell )
392
+ return <PeoplePicker key="display" variant="naked" mode={displayOrDisabled(isDisabled)} value={value as PersonValue | null} size={size} />
378
393
  }
379
394
  return (
380
395
  <PeoplePicker
@@ -391,10 +406,10 @@ function PersonCell({ value, mode, size, isDisabled, isEditable, onCommit, onCan
391
406
  )
392
407
  }
393
408
 
394
- function MultiPersonCell({ value, mode, size, isDisabled, isEditable, onCommitLive, onCancel, meta }: CellComponentProps) {
409
+ function MultiPersonCell({ value, mode, size, isDisabled, onCommitLive, onCancel, meta }: CellComponentProps) {
395
410
  if (mode === 'display') {
396
- // 2026-05-10:non-editable 不顯 chevron indicator
397
- return <PeoplePicker key="display" variant="naked" mode={displayOrDisabled(isDisabled)} value={(value as PersonValue[]) ?? []} size={size} showDisplayEndIcon={isEditable === true} />
411
+ // 2026-07-08 A 案:display 態零恆顯 icon(同 DateCell 註)
412
+ return <PeoplePicker key="display" variant="naked" mode={displayOrDisabled(isDisabled)} value={(value as PersonValue[]) ?? []} size={size} />
398
413
  }
399
414
  // Multi 用 onCommitLive(commit 但不 exit edit)— 每勾一人即時生效,popover 持續開
400
415
  // 直到點外面;onOpenChange(false) → onCancel exit edit。對齊 multiSelect canonical。
@@ -418,7 +433,8 @@ function BooleanCell({ value, mode, meta, size, isEditable, isDisabled, onCommit
418
433
  // onCheckedChange 仍 fire(violate disabled contract)。Fix:`!isEditable || isDisabled` →
419
434
  // 走 display branch,Checkbox 拿 disabled mode + 不接 onCheckedChange。
420
435
  if (mode === 'display' && (!isEditable || isDisabled)) {
421
- return <Checkbox variant="naked" mode={displayOrDisabled(isDisabled)} checked={value === true} />
436
+ // size 傳入 → boolean 值 icon(Check/X)@lg 縮放對齊其他 cell(對齊 editable 分支同 size 邏輯)
437
+ return <Checkbox variant="naked" size={size === 'lg' ? 'lg' : 'md'} mode={displayOrDisabled(isDisabled)} checked={value === true} />
422
438
  }
423
439
  return (
424
440
  <Checkbox
@@ -431,17 +447,19 @@ function BooleanCell({ value, mode, meta, size, isEditable, isDisabled, onCommit
431
447
  }
432
448
 
433
449
  /**
434
- * UrlCell Phase C drift fix:
435
- * EditableCellContent edit mode 對 url 走 plain `<Input>`(失去 URL 驗證 + auto-link)。
436
- * 現改用 `<LinkInput>` edit mode 保留 URL parse / hostname 顯示一致性 + 鍵盤 commit / cancel
437
- * read mode `<LinkInput mode={displayOrDisabled(isDisabled)}>` = 一致 SSOT。
438
- * editable 互動:hover 時右側出 Pencil edit(保留 link click 語意,對齊原 spec)。
450
+ * UrlCell(2026-07-14 docblock 對齊實作):
451
+ * display branch = `<LinkInput mode={displayOrDisabled(isDisabled)}>`(URL parse / hostname
452
+ * 顯示一致性 SSOT);editable 互動:hover 時右側出 Pencil edit(保留 link click 語意)
453
+ * edit branch = plain `<Input variant="naked">`(LinkInput edit controlled value 衝突
454
+ * revert,詳下方 edit branch 註解);URL 驗證 deferred onCommit(consumer validate)。
439
455
  */
440
456
  function UrlCell({ value, meta, mode, size, isDisabled, isEditable, onRequestEdit, onCommit, onCancel }: CellComponentProps) {
441
457
  if (mode === 'display') {
442
- // showDisplayEndIcon ← D path Phase 2(2026-05-08):Field naked wrapper 包 anchor,與 Input edit 同 chrome
458
+ // showDisplayEndIcon ← D path Phase 2(2026-05-08):Field naked wrapper 包 anchor,與 Input edit 同 chrome
459
+ // LinkInput 此 prop = wrapper-only(無 icon,field.spec.md L6 例外)→ A 案(2026-07-08)不撤;
460
+ // 但修 I1:原無條件 true 違反「= isEditable」knob 等式(field-controls.spec.md cell 例外),改等式。
443
461
  const display = (
444
- <LinkInput variant="naked" mode={displayOrDisabled(isDisabled)} value={value as string | null} label={meta?.linkLabel} size={size} showDisplayEndIcon />
462
+ <LinkInput variant="naked" mode={displayOrDisabled(isDisabled)} value={value as string | null} label={meta?.linkLabel} size={size} showDisplayEndIcon={isEditable === true} />
445
463
  )
446
464
  // 2026-05-13 codex V1 fix:disabled URL 不顯 Pencil affordance(parent onRequestEdit 已被攔但 UI 仍誤導)
447
465
  if (!isEditable || isDisabled) return display
@@ -521,7 +539,12 @@ function buildCellWithSurface(Inner: ComponentType<CellComponentProps>, key: str
521
539
  {/* 2026-06-08:把 table-density size 經獨立 surface-size context 注給 child Field controls,
522
540
  漏傳 size 的 cell 也自動繼承(根治「新 cell 漏傳 size」class);size primitive 不破壞 memo identity。*/}
523
541
  <FieldSurfaceSizeProvider size={props.size}>
524
- <Inner {...props} />
542
+ {/* 2026-07-08 user 拍板:cell 可編輯訊號經獨立 boolean context 注給 child Field controls,
543
+ 讓 useFieldEmptyDisplay 分流「可編輯 cell 空 display → 空白」vs「不可編輯 cell → '-'」。
544
+ boolean primitive 不破壞 memo identity(同 size context)。 */}
545
+ <FieldSurfaceEditableProvider isEditable={props.isEditable ?? false}>
546
+ <Inner {...props} />
547
+ </FieldSurfaceEditableProvider>
525
548
  </FieldSurfaceSizeProvider>
526
549
  </FieldSurfaceProvider>
527
550
  )
@@ -122,7 +122,16 @@ declare module '@tanstack/react-table' {
122
122
  precision?: number
123
123
  locale?: string
124
124
  /** Select/multiSelect options — maps value to display label */
125
- options?: Array<{ value: string; label: string }>
125
+ /** select/multiSelect 選項:消費 Select SelectOption 完整 schema(M30 wrapper-extends-primitive;
126
+ * 2026-07-08 原 {value,label} 窄型別讓 icon/description/iconClassName 傳不進 = 假 SSOT)*/
127
+ options?: Array<import('../Select/select').SelectOption>
128
+ /** select cell 的 trigger/display 自訂渲染(轉發 Select.selectedItemRenderer;status 彩色 icon 場景)*/
129
+ selectedItemRenderer?: (opt: import('../Select/select').SelectOption) => React.ReactNode
130
+ /** select cell 顯示模式(轉發 Select.display;cell-registry SelectCell 消費 `meta?.display`)。
131
+ * default `'plain'` 純文字;`'tag'` opt-in 內容導向 Tag 視覺(status / category 彩色標籤,
132
+ * 搭配 options 的 `tagVariant`)。2026-07-14 deep-audit 補型別:runtime 一直消費此欄位
133
+ * (cell-registry.tsx SelectCell displayMode),但 ColumnMeta 漏宣告 → typed consumer 傳不進(假 SSOT)。 */
134
+ display?: 'plain' | 'tag'
126
135
  /** Date: Intl.DateTimeFormat options */
127
136
  formatOptions?: Intl.DateTimeFormatOptions
128
137
  /**