@qijenchen/design-system 0.1.0-beta.85 → 0.1.0-beta.86

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 (477) hide show
  1. package/AGENTS.md +210 -0
  2. package/CLAUDE.md +17 -191
  3. package/cli-init.mjs +30 -2
  4. package/dist/components/Accordion/accordion.d.ts +2 -2
  5. package/dist/components/Accordion/accordion.d.ts.map +1 -1
  6. package/dist/components/Accordion/accordion.js.map +1 -1
  7. package/dist/components/Avatar/avatar.js +1 -1
  8. package/dist/components/Avatar/avatar.js.map +1 -1
  9. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
  10. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
  11. package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
  12. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  13. package/dist/components/Button/button-group.d.ts +2 -2
  14. package/dist/components/Button/button-group.d.ts.map +1 -1
  15. package/dist/components/Button/button-group.js +2 -2
  16. package/dist/components/Button/button-group.js.map +1 -1
  17. package/dist/components/Button/button.d.ts +2 -1
  18. package/dist/components/Button/button.d.ts.map +1 -1
  19. package/dist/components/Button/button.js +1 -1
  20. package/dist/components/Button/button.js.map +1 -1
  21. package/dist/components/Carousel/carousel.d.ts +14 -8
  22. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  23. package/dist/components/Carousel/carousel.js +64 -37
  24. package/dist/components/Carousel/carousel.js.map +1 -1
  25. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
  26. package/dist/components/Checkbox/checkbox-group.js +21 -14
  27. package/dist/components/Checkbox/checkbox-group.js.map +1 -1
  28. package/dist/components/Checkbox/checkbox.d.ts +2 -2
  29. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  30. package/dist/components/Checkbox/checkbox.js +49 -10
  31. package/dist/components/Checkbox/checkbox.js.map +1 -1
  32. package/dist/components/Combobox/combobox.d.ts +15 -6
  33. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  34. package/dist/components/Combobox/combobox.js +13 -7
  35. package/dist/components/Combobox/combobox.js.map +1 -1
  36. package/dist/components/Command/command.d.ts.map +1 -1
  37. package/dist/components/Command/command.js +11 -2
  38. package/dist/components/Command/command.js.map +1 -1
  39. package/dist/components/DataTable/cell-registry.d.ts +5 -5
  40. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  41. package/dist/components/DataTable/cell-registry.js +41 -38
  42. package/dist/components/DataTable/cell-registry.js.map +1 -1
  43. package/dist/components/DataTable/column-types.d.ts +1 -17
  44. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  45. package/dist/components/DataTable/column-types.js.map +1 -1
  46. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
  47. package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
  48. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
  49. package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
  50. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  51. package/dist/components/DataTable/data-table-filter-panel.js +3 -4
  52. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
  53. package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
  54. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  55. package/dist/components/DataTable/data-table-sort-manager.js +2 -2
  56. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
  57. package/dist/components/DataTable/data-table.d.ts +1 -1
  58. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  59. package/dist/components/DataTable/data-table.js +44 -32
  60. package/dist/components/DataTable/data-table.js.map +1 -1
  61. package/dist/components/DatePicker/date-picker.d.ts +3 -3
  62. package/dist/components/DatePicker/date-picker.js +4 -4
  63. package/dist/components/DatePicker/date-picker.js.map +1 -1
  64. package/dist/components/DescriptionList/description-list.d.ts +3 -3
  65. package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
  66. package/dist/components/DescriptionList/description-list.js +6 -6
  67. package/dist/components/DescriptionList/description-list.js.map +1 -1
  68. package/dist/components/Dialog/dialog.d.ts +2 -2
  69. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  70. package/dist/components/Dialog/dialog.js.map +1 -1
  71. package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
  72. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  73. package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
  74. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  75. package/dist/components/Field/field-context.d.ts +16 -10
  76. package/dist/components/Field/field-context.d.ts.map +1 -1
  77. package/dist/components/Field/field-context.js.map +1 -1
  78. package/dist/components/Field/field-types.d.ts +2 -2
  79. package/dist/components/Field/field-types.d.ts.map +1 -1
  80. package/dist/components/Field/field-types.js.map +1 -1
  81. package/dist/components/Field/field-wrapper.d.ts +20 -4
  82. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  83. package/dist/components/Field/field-wrapper.js +30 -31
  84. package/dist/components/Field/field-wrapper.js.map +1 -1
  85. package/dist/components/Field/field.d.ts +1 -1
  86. package/dist/components/Field/field.d.ts.map +1 -1
  87. package/dist/components/Field/field.js +25 -3
  88. package/dist/components/Field/field.js.map +1 -1
  89. package/dist/components/Field/use-form-validation.d.ts +1 -1
  90. package/dist/components/Field/use-form-validation.js.map +1 -1
  91. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  92. package/dist/components/FileItem/file-item.js +2 -5
  93. package/dist/components/FileItem/file-item.js.map +1 -1
  94. package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
  95. package/dist/components/FileUpload/file-upload.js +5 -1
  96. package/dist/components/FileUpload/file-upload.js.map +1 -1
  97. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  98. package/dist/components/FileViewer/file-viewer.js +2 -1
  99. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  100. package/dist/components/HoverCard/hover-card.d.ts +2 -2
  101. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  102. package/dist/components/HoverCard/hover-card.js +4 -2
  103. package/dist/components/HoverCard/hover-card.js.map +1 -1
  104. package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
  105. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
  106. package/dist/components/InlineEdit/inline-edit.js +104 -62
  107. package/dist/components/InlineEdit/inline-edit.js.map +1 -1
  108. package/dist/components/Input/input.d.ts +1 -1
  109. package/dist/components/Input/input.d.ts.map +1 -1
  110. package/dist/components/Input/input.js +6 -6
  111. package/dist/components/Input/input.js.map +1 -1
  112. package/dist/components/LinkInput/link-input.d.ts +5 -5
  113. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  114. package/dist/components/LinkInput/link-input.js +3 -3
  115. package/dist/components/LinkInput/link-input.js.map +1 -1
  116. package/dist/components/Notice/notice.d.ts +17 -1
  117. package/dist/components/Notice/notice.d.ts.map +1 -1
  118. package/dist/components/Notice/notice.js +7 -1
  119. package/dist/components/Notice/notice.js.map +1 -1
  120. package/dist/components/NumberInput/number-input.d.ts +1 -1
  121. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  122. package/dist/components/NumberInput/number-input.js +12 -1
  123. package/dist/components/NumberInput/number-input.js.map +1 -1
  124. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
  125. package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
  126. package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
  127. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  128. package/dist/components/PeoplePicker/people-picker.js +7 -5
  129. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  130. package/dist/components/PeoplePicker/person-display.d.ts +1 -1
  131. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  132. package/dist/components/ProfileCard/profile-card.d.ts +1 -1
  133. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  134. package/dist/components/RadioGroup/radio-group.d.ts +3 -3
  135. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  136. package/dist/components/RadioGroup/radio-group.js +1 -1
  137. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  138. package/dist/components/Rating/rating.d.ts.map +1 -1
  139. package/dist/components/Rating/rating.js +4 -0
  140. package/dist/components/Rating/rating.js.map +1 -1
  141. package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
  142. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  143. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  144. package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
  145. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
  146. package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
  147. package/dist/components/Select/select.d.ts +16 -6
  148. package/dist/components/Select/select.d.ts.map +1 -1
  149. package/dist/components/Select/select.js +17 -5
  150. package/dist/components/Select/select.js.map +1 -1
  151. package/dist/components/SelectMenu/select-menu.d.ts +17 -1
  152. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  153. package/dist/components/SelectMenu/select-menu.js +17 -3
  154. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  155. package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
  156. package/dist/components/SelectionControl/boolean-value.js.map +1 -1
  157. package/dist/components/Sheet/sheet.d.ts +2 -2
  158. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  159. package/dist/components/Sheet/sheet.js.map +1 -1
  160. package/dist/components/Sidebar/sidebar.d.ts +1 -1
  161. package/dist/components/Sidebar/sidebar.js +2 -2
  162. package/dist/components/Sidebar/sidebar.js.map +1 -1
  163. package/dist/components/Slider/slider.d.ts.map +1 -1
  164. package/dist/components/Slider/slider.js +6 -3
  165. package/dist/components/Slider/slider.js.map +1 -1
  166. package/dist/components/Steps/steps.d.ts +6 -4
  167. package/dist/components/Steps/steps.d.ts.map +1 -1
  168. package/dist/components/Steps/steps.js +19 -5
  169. package/dist/components/Steps/steps.js.map +1 -1
  170. package/dist/components/Switch/switch.d.ts +4 -4
  171. package/dist/components/Switch/switch.d.ts.map +1 -1
  172. package/dist/components/Switch/switch.js +3 -1
  173. package/dist/components/Switch/switch.js.map +1 -1
  174. package/dist/components/Tabs/tabs.d.ts +1 -1
  175. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  176. package/dist/components/Tabs/tabs.js +73 -23
  177. package/dist/components/Tabs/tabs.js.map +1 -1
  178. package/dist/components/Tag/tag.d.ts +3 -1
  179. package/dist/components/Tag/tag.d.ts.map +1 -1
  180. package/dist/components/Tag/tag.js +2 -2
  181. package/dist/components/Tag/tag.js.map +1 -1
  182. package/dist/components/Textarea/textarea.d.ts +4 -4
  183. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  184. package/dist/components/Textarea/textarea.js +15 -15
  185. package/dist/components/Textarea/textarea.js.map +1 -1
  186. package/dist/components/TimePicker/time-picker.d.ts +4 -4
  187. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  188. package/dist/components/TimePicker/time-picker.js +8 -5
  189. package/dist/components/TimePicker/time-picker.js.map +1 -1
  190. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  191. package/dist/components/Tooltip/tooltip.js +27 -23
  192. package/dist/components/Tooltip/tooltip.js.map +1 -1
  193. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  194. package/dist/components/TreeView/tree-view.js +16 -0
  195. package/dist/components/TreeView/tree-view.js.map +1 -1
  196. package/dist/index.d.ts +7 -7
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +6 -13
  199. package/dist/index.js.map +1 -1
  200. package/dist/lib/drag-visual.d.ts +2 -2
  201. package/dist/lib/drag-visual.js.map +1 -1
  202. package/dist/lib/utils.d.ts +1 -0
  203. package/dist/lib/utils.d.ts.map +1 -1
  204. package/dist/lib/utils.js +21 -1
  205. package/dist/lib/utils.js.map +1 -1
  206. package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
  207. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  208. package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
  209. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  210. package/dist/tokens/categorical-color.d.ts +3 -3
  211. package/dist/tokens/categorical-color.d.ts.map +1 -1
  212. package/dist/tokens/categorical-color.js +2 -2
  213. package/dist/tokens/categorical-color.js.map +1 -1
  214. package/ds-canonical/fork/AGENTS.md +213 -0
  215. package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
  216. package/ds-canonical/fork/codex/hooks.json +16 -0
  217. package/ds-canonical/fork/governance.lock +22 -7
  218. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
  219. package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
  220. package/ds-canonical/fork/manifest.json +10 -1
  221. package/ds-canonical/fork/preamble.md +3 -2
  222. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
  223. package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
  224. package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
  225. package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
  226. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
  227. package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +11 -2
  228. package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
  229. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
  230. package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
  231. package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
  232. package/ds-canonical/references/certified-surfaces.md +20 -0
  233. package/ds-canonical/references/preflight-gate-baseline.json +5 -0
  234. package/ds-canonical/references/principle-dim-map.json +20 -2
  235. package/ds-canonical/references/props-naming.md +2 -1
  236. package/ds-canonical/references/ssot-index.md +2 -2
  237. package/ds-canonical/references/story-baseline-registry.json +2 -2
  238. package/ds-canonical/rules/story-rules.md +1 -1
  239. package/ds-canonical/rules/ui-development.md +2 -1
  240. package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
  241. package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
  242. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  243. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
  244. package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
  245. package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
  246. package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
  247. package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
  248. package/ds-story-manifest.json +21 -21
  249. package/llms-full.txt +3 -3
  250. package/llms.txt +1 -1
  251. package/package.json +2 -1
  252. package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
  253. package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
  254. package/src/components/Accordion/accordion.spec.md +10 -1
  255. package/src/components/Accordion/accordion.stories.tsx +10 -5
  256. package/src/components/Accordion/accordion.tsx +7 -2
  257. package/src/components/Alert/alert.principles.stories.tsx +2 -8
  258. package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
  259. package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
  260. package/src/components/AppShell/app-shell.spec.md +4 -0
  261. package/src/components/AppShell/app-shell.stories.tsx +4 -5
  262. package/src/components/Avatar/avatar.tsx +1 -1
  263. package/src/components/Badge/badge.spec.md +2 -2
  264. package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
  265. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
  266. package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
  267. package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
  268. package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
  269. package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
  270. package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
  271. package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
  272. package/src/components/Button/button-group.tsx +4 -4
  273. package/src/components/Button/button.anatomy.stories.tsx +26 -7
  274. package/src/components/Button/button.principles.stories.tsx +1 -1
  275. package/src/components/Button/button.spec.md +2 -2
  276. package/src/components/Button/button.stories.tsx +22 -28
  277. package/src/components/Button/button.tsx +2 -1
  278. package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
  279. package/src/components/Calendar/calendar.spec.md +1 -1
  280. package/src/components/Carousel/carousel.spec.md +17 -1
  281. package/src/components/Carousel/carousel.tsx +93 -42
  282. package/src/components/Checkbox/checkbox-group.tsx +26 -15
  283. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
  284. package/src/components/Checkbox/checkbox.spec.md +12 -3
  285. package/src/components/Checkbox/checkbox.stories.tsx +4 -4
  286. package/src/components/Checkbox/checkbox.tsx +79 -19
  287. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
  288. package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
  289. package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
  290. package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
  291. package/src/components/Combobox/combobox.spec.md +6 -2
  292. package/src/components/Combobox/combobox.stories.tsx +9 -36
  293. package/src/components/Combobox/combobox.tsx +42 -27
  294. package/src/components/Command/command.spec.md +3 -3
  295. package/src/components/Command/command.tsx +9 -2
  296. package/src/components/DataTable/cell-registry.tsx +75 -76
  297. package/src/components/DataTable/column-types.ts +4 -17
  298. package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
  299. package/src/components/DataTable/data-table-filter-panel.tsx +6 -6
  300. package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
  301. package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
  302. package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
  303. package/src/components/DataTable/data-table.css +2 -3
  304. package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
  305. package/src/components/DataTable/data-table.spec.md +7 -7
  306. package/src/components/DataTable/data-table.stories.tsx +39 -29
  307. package/src/components/DataTable/data-table.tsx +90 -67
  308. package/src/components/DataTable/filter-operators.spec.md +2 -0
  309. package/src/components/DateGrid/date-grid.spec.md +1 -1
  310. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
  311. package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
  312. package/src/components/DatePicker/date-picker.spec.md +9 -9
  313. package/src/components/DatePicker/date-picker.stories.tsx +9 -9
  314. package/src/components/DatePicker/date-picker.tsx +13 -13
  315. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
  316. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  317. package/src/components/DescriptionList/description-list.spec.md +12 -12
  318. package/src/components/DescriptionList/description-list.stories.tsx +3 -3
  319. package/src/components/DescriptionList/description-list.tsx +10 -10
  320. package/src/components/Dialog/dialog.tsx +4 -1
  321. package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
  322. package/src/components/Field/field-context.ts +17 -11
  323. package/src/components/Field/field-controls.spec.md +44 -37
  324. package/src/components/Field/field-types.ts +14 -12
  325. package/src/components/Field/field-wrapper.tsx +59 -43
  326. package/src/components/Field/field.anatomy.stories.tsx +6 -6
  327. package/src/components/Field/field.principles.stories.tsx +5 -28
  328. package/src/components/Field/field.spec.md +4 -4
  329. package/src/components/Field/field.stories.tsx +103 -72
  330. package/src/components/Field/field.tsx +36 -4
  331. package/src/components/Field/form-validation.spec.md +2 -0
  332. package/src/components/Field/use-form-validation.ts +1 -1
  333. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
  334. package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
  335. package/src/components/FileItem/file-item.tsx +10 -8
  336. package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
  337. package/src/components/FileUpload/file-upload.spec.md +3 -2
  338. package/src/components/FileUpload/file-upload.tsx +5 -1
  339. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
  340. package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
  341. package/src/components/FileViewer/file-viewer.spec.md +1 -1
  342. package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
  343. package/src/components/FileViewer/file-viewer.tsx +3 -2
  344. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
  345. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
  346. package/src/components/HoverCard/hover-card.spec.md +2 -2
  347. package/src/components/HoverCard/hover-card.tsx +4 -2
  348. package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
  349. package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
  350. package/src/components/InlineEdit/inline-edit.spec.md +71 -46
  351. package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
  352. package/src/components/InlineEdit/inline-edit.tsx +211 -125
  353. package/src/components/Input/input.anatomy.stories.tsx +15 -15
  354. package/src/components/Input/input.principles.stories.tsx +3 -3
  355. package/src/components/Input/input.spec.md +4 -4
  356. package/src/components/Input/input.stories.tsx +3 -3
  357. package/src/components/Input/input.tsx +13 -13
  358. package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
  359. package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
  360. package/src/components/LinkInput/link-input.spec.md +6 -2
  361. package/src/components/LinkInput/link-input.stories.tsx +8 -8
  362. package/src/components/LinkInput/link-input.tsx +21 -19
  363. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  364. package/src/components/Notice/notice.tsx +8 -2
  365. package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
  366. package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
  367. package/src/components/NumberInput/number-input.spec.md +6 -6
  368. package/src/components/NumberInput/number-input.stories.tsx +4 -4
  369. package/src/components/NumberInput/number-input.tsx +17 -5
  370. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
  371. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
  372. package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
  373. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
  374. package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
  375. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
  376. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
  377. package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
  378. package/src/components/PeoplePicker/people-picker.tsx +39 -20
  379. package/src/components/PeoplePicker/person-display.tsx +3 -3
  380. package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
  381. package/src/components/Popover/popover.principles.stories.tsx +49 -28
  382. package/src/components/Popover/popover.spec.md +4 -2
  383. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  384. package/src/components/ProfileCard/profile-card.tsx +1 -1
  385. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
  386. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
  387. package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
  388. package/src/components/README.md +1 -0
  389. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
  390. package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
  391. package/src/components/RadioGroup/radio-group.tsx +19 -14
  392. package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
  393. package/src/components/Rating/rating.principles.stories.tsx +3 -3
  394. package/src/components/Rating/rating.spec.md +2 -2
  395. package/src/components/Rating/rating.stories.tsx +4 -18
  396. package/src/components/Rating/rating.tsx +5 -1
  397. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  398. package/src/components/ScrollArea/scroll-area.spec.md +1 -1
  399. package/src/components/ScrollArea/scroll-area.tsx +5 -2
  400. package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
  401. package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
  402. package/src/components/SegmentedControl/segmented-control.tsx +6 -3
  403. package/src/components/Select/select.anatomy.stories.tsx +13 -7
  404. package/src/components/Select/select.principles.stories.tsx +3 -3
  405. package/src/components/Select/select.spec.md +9 -1
  406. package/src/components/Select/select.stories.tsx +41 -27
  407. package/src/components/Select/select.tsx +44 -26
  408. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
  409. package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
  410. package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
  411. package/src/components/SelectMenu/select-menu.tsx +38 -5
  412. package/src/components/SelectionControl/boolean-value.tsx +2 -2
  413. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  414. package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
  415. package/src/components/Separator/separator.principles.stories.tsx +1 -1
  416. package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
  417. package/src/components/Sheet/sheet.tsx +4 -1
  418. package/src/components/Sidebar/sidebar.tsx +1 -1
  419. package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
  420. package/src/components/Slider/slider.principles.stories.tsx +6 -6
  421. package/src/components/Slider/slider.spec.md +13 -1
  422. package/src/components/Slider/slider.stories.tsx +44 -32
  423. package/src/components/Slider/slider.tsx +13 -4
  424. package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
  425. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  426. package/src/components/Steps/steps.spec.md +4 -2
  427. package/src/components/Steps/steps.stories.tsx +4 -56
  428. package/src/components/Steps/steps.tsx +31 -7
  429. package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
  430. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  431. package/src/components/Switch/switch.spec.md +4 -4
  432. package/src/components/Switch/switch.stories.tsx +3 -3
  433. package/src/components/Switch/switch.tsx +16 -10
  434. package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
  435. package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
  436. package/src/components/Tabs/tabs.spec.md +5 -2
  437. package/src/components/Tabs/tabs.stories.tsx +36 -44
  438. package/src/components/Tabs/tabs.tsx +101 -36
  439. package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
  440. package/src/components/Tag/tag.principles.stories.tsx +4 -4
  441. package/src/components/Tag/tag.spec.md +3 -1
  442. package/src/components/Tag/tag.tsx +5 -3
  443. package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
  444. package/src/components/Textarea/textarea.spec.md +5 -5
  445. package/src/components/Textarea/textarea.tsx +24 -24
  446. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
  447. package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
  448. package/src/components/TimePicker/time-picker.spec.md +6 -5
  449. package/src/components/TimePicker/time-picker.stories.tsx +3 -3
  450. package/src/components/TimePicker/time-picker.tsx +24 -14
  451. package/src/components/Toast/toast.principles.stories.tsx +1 -1
  452. package/src/components/Toast/toast.stories.tsx +1 -1
  453. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
  454. package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
  455. package/src/components/Tooltip/tooltip.spec.md +9 -3
  456. package/src/components/Tooltip/tooltip.stories.tsx +1 -1
  457. package/src/components/Tooltip/tooltip.tsx +12 -2
  458. package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
  459. package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
  460. package/src/components/TreeView/tree-view.spec.md +8 -6
  461. package/src/components/TreeView/tree-view.stories.tsx +9 -43
  462. package/src/components/TreeView/tree-view.tsx +36 -0
  463. package/src/index.ts +13 -10
  464. package/src/lib/drag-visual.ts +2 -2
  465. package/src/lib/utils.ts +19 -0
  466. package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
  467. package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
  468. package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
  469. package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
  470. package/src/tokens/categorical-color.ts +5 -5
  471. package/src/tokens/color/color.spec.md +4 -4
  472. package/src/tokens/color/primitives.css +9 -2
  473. package/src/tokens/opacity/opacity.spec.md +1 -1
  474. package/src/tokens/orphan-tokens.spec.md +1 -1
  475. package/src/tokens/typography/typography.spec.md +2 -0
  476. package/src/tokens/uiSize/uiSize.css +5 -0
  477. package/src/tokens/uiSize/uiSize.spec.md +1 -1
@@ -76,8 +76,8 @@ export const Modes: Story = {
76
76
  </div>
77
77
  {/* @story-trait-rationale: pre-existing trait gaps tracked separately */}
78
78
  <div>
79
- <h3 className="text-body font-bold text-foreground mb-2">display</h3>
80
- <DatePicker mode="display" value="2026-04-02" />
79
+ <h3 className="text-body font-bold text-foreground mb-2">view</h3>
80
+ <DatePicker mode="view" value="2026-04-02" />
81
81
  </div>
82
82
  <div>
83
83
  <h3 className="text-body font-bold text-foreground mb-2">readonly</h3>
@@ -315,26 +315,26 @@ export const ShowTimeRange: Story = {
315
315
  },
316
316
  }
317
317
 
318
- /* ── Display(DataTable cell 用)── */
319
- export const Display: Story = {
320
- name: '展示樣式',
318
+ /* ── View(DataTable cell 用)── */
319
+ export const View: Story = {
320
+ name: '檢視樣式',
321
321
  render: () => (
322
322
  <div className="flex flex-col gap-3">
323
323
  <div className="flex items-center gap-3">
324
324
  <span className="text-caption text-fg-muted w-20">預設</span>
325
- <DatePicker mode="display" value="2026-04-02" />
325
+ <DatePicker mode="view" value="2026-04-02" />
326
326
  </div>
327
327
  <div className="flex items-center gap-3">
328
328
  <span className="text-caption text-fg-muted w-20">完整月份</span>
329
- <DatePicker mode="display" value="2026-04-02" formatOptions={{ year: 'numeric', month: 'long', day: 'numeric' }} />
329
+ <DatePicker mode="view" value="2026-04-02" formatOptions={{ year: 'numeric', month: 'long', day: 'numeric' }} />
330
330
  </div>
331
331
  <div className="flex items-center gap-3">
332
332
  <span className="text-caption text-fg-muted w-20">zh-TW</span>
333
- <DatePicker mode="display" value="2026-04-02" locale="zh-TW" formatOptions={{ year: 'numeric', month: 'long', day: 'numeric' }} />
333
+ <DatePicker mode="view" value="2026-04-02" locale="zh-TW" formatOptions={{ year: 'numeric', month: 'long', day: 'numeric' }} />
334
334
  </div>
335
335
  <div className="flex items-center gap-3">
336
336
  <span className="text-caption text-fg-muted w-20">null</span>
337
- <DatePicker mode="display" value={null} />
337
+ <DatePicker mode="view" value={null} />
338
338
  </div>
339
339
  </div>
340
340
  ),
@@ -328,9 +328,9 @@ export interface DatePickerProps
328
328
  */
329
329
  needConfirm?: boolean
330
330
  /**
331
- * Display 是否渲 Calendar icon + Field naked wrapper(D-path opt-in,2026-05-08)
332
- * — DataTable cell display↔edit 像素級對齊用。預設 false(裸 span,backward compat)。
333
- * 設 true 時 display 走 fieldWrapperStyles(naked variant)+ ItemSuffix CalendarIcon,
331
+ * View 態是否渲 Calendar icon + Field naked wrapper(D-path opt-in,2026-05-08)
332
+ * — DataTable cell view↔edit 像素級對齊用。預設 false(裸 span,backward compat)。
333
+ * 設 true 時 view 走 fieldWrapperStyles(naked variant)+ ItemSuffix CalendarIcon,
334
334
  * 與 edit 同 DOM 結構,消除 Layer-B padding mismatch。
335
335
  */
336
336
  showDisplayEndIcon?: boolean
@@ -409,7 +409,7 @@ const DatePicker = React.forwardRef<HTMLDivElement, DatePickerProps>(
409
409
  const size = useResolvedFieldSize(sizeProp) // B 組 cascade fix:<Field size>/cell surface-size 對 DatePicker 生效
410
410
  const error = useResolvedFieldInvalid(errorProp)
411
411
  const disabled = useResolvedFieldDisabled(disabledProp)
412
- // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="display"> 漏 cascade
412
+ // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="view"> 漏 cascade
413
413
  const resolvedMode = useResolvedFieldMode({ mode, disabled })
414
414
  const emptyDisplay = useFieldEmptyDisplay()
415
415
  const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)
@@ -475,21 +475,21 @@ const DatePicker = React.forwardRef<HTMLDivElement, DatePickerProps>(
475
475
  }
476
476
  }, [onChange, showTime])
477
477
 
478
- // mode='display'(Phase B2 2026-05-05):純內容輸出 — 對齊原 DatePickerDisplay sub-component(retired)。
478
+ // mode='view'(Phase B2 2026-05-05):純內容輸出 — 對齊原 DatePickerDisplay sub-component(retired)。
479
479
  // Default(showDisplayEndIcon=false):無 Field wrapper / 無 Calendar icon — backward compat 裸 span。
480
480
  // Opt-in(showDisplayEndIcon=true,2026-05-08 D-path):Field naked wrapper + ItemSuffix Calendar,
481
- // 與 edit 同結構消除 cell display↔edit 像素偏移(Layer-B padding mismatch)。
482
- if (resolvedMode === 'display') {
481
+ // 與 edit 同結構消除 cell view↔edit 像素偏移(Layer-B padding mismatch)。
482
+ if (resolvedMode === 'view') {
483
483
  if (!showDisplayEndIcon) {
484
- // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 套
484
+ // 2026-05-14 I2 fix(spec contract (e) view typography canonical):bare span 套
485
485
  // `fieldDisplayTextClass(size)`(sm/md→text-body,lg→text-body-lg)— 對齊 Field family 統一。
486
486
  if (!value) return <span className={cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className)}>{emptyDisplay}</span>
487
487
  return <span className={cn(fieldDisplayTextClass(size), 'truncate', className)}>{displayCommitted}</span>
488
488
  }
489
489
  return (
490
490
  <div
491
- className={cn(fieldWrapperStyles({ mode: 'display', variant, width, size }), className)}
492
- data-field-mode="display"
491
+ className={cn(fieldWrapperStyles({ mode: 'view', variant, width, size }), className)}
492
+ data-field-mode="view"
493
493
  >
494
494
  <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && fieldEmptyColorClass(resolvedMode))}>
495
495
  {value ? displayCommitted : emptyDisplay}
@@ -801,7 +801,7 @@ const DatePickerRange = React.forwardRef<HTMLDivElement, DatePickerRangeProps>(
801
801
  const size = useResolvedFieldSize(sizeProp) // B 組 cascade fix:<Field size>/cell surface-size 對 DatePicker 生效
802
802
  const error = useResolvedFieldInvalid(errorProp)
803
803
  const disabled = useResolvedFieldDisabled(disabledProp)
804
- // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="display"> 漏 cascade
804
+ // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode="view"> 漏 cascade
805
805
  const resolvedMode = useResolvedFieldMode({ mode, disabled })
806
806
  const emptyDisplay = useFieldEmptyDisplay()
807
807
  const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)
@@ -936,8 +936,8 @@ const DatePickerRange = React.forwardRef<HTMLDivElement, DatePickerRangeProps>(
936
936
  return false
937
937
  }, [activeEnd, startDate, endDate])
938
938
 
939
- // mode='display'(Phase B2 2026-05-05):純內容輸出 — 無 Field wrapper / 無 Calendar icon。
940
- if (resolvedMode === 'display') {
939
+ // mode='view'(Phase B2 2026-05-05):純內容輸出 — 無 Field wrapper / 無 Calendar icon。
940
+ if (resolvedMode === 'view') {
941
941
  const hasAny = !!(startIso || endIso)
942
942
  if (!hasAny) return <span className={cn(fieldEmptyColorClass(resolvedMode), className)}>{emptyDisplay}</span>
943
943
  return (
@@ -5,7 +5,7 @@
5
5
  // foreground(value),無 variant × state 色彩矩陣。色彩 token 已於
6
6
  // Overview「Typography(閱讀模式)」段列出。
7
7
  // SizeMatrix N/A — 不提供 size prop;大小固定 text-body(14px reading mode),
8
- // 由 layout(cols / direction / divided)而非 size 決定差異。ColsMatrix 已
8
+ // 由 layout(cols / orientation / divided)而非 size 決定差異。ColsMatrix 已
9
9
  // 涵蓋 layout 變化。
10
10
  import type { Meta, StoryObj } from '@storybook/react'
11
11
  import { DescriptionList, DescriptionItem } from './description-list'
@@ -54,7 +54,7 @@ export const Overview: Story = {
54
54
  <Desc>items 之間垂直間距走 `--layout-space-tight` token(density-aware)——切 density 自動適配,避免硬寫 px / py-N 脫鉤 token;label → value(同 item 內)走 `--item-gap-label-desc-reading`(2px,見下表 row 1)。</Desc>
55
55
  <div className="overflow-x-auto">
56
56
  <table className="text-caption border-collapse">
57
- <thead><tr><Th>Direction</Th><Th>位置</Th><Th>Value</Th><Th>Rationale</Th></tr></thead>
57
+ <thead><tr><Th>Orientation</Th><Th>位置</Th><Th>Value</Th><Th>Rationale</Th></tr></thead>
58
58
  <tbody>
59
59
  <tr><Td mono>vertical</Td><Td>label → value(同 item 內)</Td><Td mono>--item-gap-label-desc-reading(2px)</Td><Td>極小間距,視覺上 label 與 value 緊密配對(dt body + dd body → reading token)</Td></tr>
60
60
  <tr><Td mono>vertical</Td><Td>items 之間垂直 gap</Td><Td mono>gap-y-[var(--layout-space-tight)]</Td><Td>density-aware;Gestalt proximity 群組</Td></tr>
@@ -73,16 +73,16 @@ export const Overview: Story = {
73
73
  export const Inspector: Story = {
74
74
  name: '元件檢閱器',
75
75
  parameters: {
76
- docs: { description: { story: '右側 Controls 切 props 即時 render,取代 Figma inspect。調整 `cols` / `direction` / `divided` 看 CSS grid 配置變化。' } },
76
+ docs: { description: { story: '右側 Controls 切 props 即時 render,取代 Figma inspect。調整 `cols` / `orientation` / `divided` 看 CSS grid 配置變化。' } },
77
77
  },
78
78
  args: {
79
79
  cols: 2,
80
- direction: 'vertical',
80
+ orientation: 'vertical',
81
81
  divided: false,
82
82
  },
83
83
  argTypes: {
84
84
  cols: { control: 'radio', options: [1, 2, 3] },
85
- direction: { control: 'radio', options: ['vertical', 'horizontal'] },
85
+ orientation: { control: 'radio', options: ['vertical', 'horizontal'] },
86
86
  divided: { control: 'boolean', description: 'horizontal 模式下,每個 item 下加 border-b 對齊 rows(長列表建議開)' },
87
87
  },
88
88
  render: (args) => (
@@ -197,7 +197,7 @@ export const LabelAlignmentRule: Story = {
197
197
  <div>
198
198
  <Rule
199
199
  title="本系統採 stacked(label 在上、value 在下)— label 左對齊"
200
- note="對齊 Atlassian / Shopify Polaris / Stripe 慣例——label 與 value 垂直堆疊,兩者都左對齊。閱讀節奏由上往下、由左往右,不需視線左右跳動。這是 vertical(預設)模式的結構;label 左 / value 右的 metadata 列改用既有 `direction=&quot;horizontal&quot;` prop(見 spec「Direction」段)"
200
+ note="對齊 Atlassian / Shopify Polaris / Stripe 慣例——label 與 value 垂直堆疊,兩者都左對齊。閱讀節奏由上往下、由左往右,不需視線左右跳動。這是 vertical(預設)模式的結構;label 左 / value 右的 metadata 列改用既有 `orientation=&quot;horizontal&quot;` prop(見 spec「Orientation」段)"
201
201
  >
202
202
  <Frame className="max-w-md">
203
203
  <DescriptionList cols={2}>
@@ -225,7 +225,7 @@ export const LabelAlignmentRule: Story = {
225
225
 
226
226
  <Rule
227
227
  title="❌ 不要自己用 flex 改 horizontal layout"
228
- note="手刻 flex 模擬 label 左 / value 右 → 失去 dl/dt/dd 語意,且多欄配置下 grid 對齊錯亂。有此需求 → 用既有 `direction=&quot;horizontal&quot;` prop(dl/dt/dd 語意完整保留,見 showcase「水平佈局」story),不要自組 layout"
228
+ note="手刻 flex 模擬 label 左 / value 右 → 失去 dl/dt/dd 語意,且多欄配置下 grid 對齊錯亂。有此需求 → 用既有 `orientation=&quot;horizontal&quot;` prop(dl/dt/dd 語意完整保留,見 showcase「水平佈局」story),不要自組 layout"
229
229
  >
230
230
  <Frame className="max-w-md">
231
231
  <div className="flex justify-between py-1">
@@ -44,11 +44,11 @@ benchmark:
44
44
  ## 結構
45
45
 
46
46
  - `DescriptionList`:外層 `dl`,vertical 模式為 CSS grid、horizontal 模式為 flex column
47
- - `DescriptionItem`:一組 `dt`(label)+ `dd`(value),透過 context 知道當前 direction 自動切 layout
47
+ - `DescriptionItem`:一組 `dt`(label)+ `dd`(value),透過 context 知道當前 orientation 自動切 layout
48
48
 
49
- ## Direction(2026-04-20 新增)
49
+ ## Orientation(2026-04-20 新增)
50
50
 
51
- | direction | Layout | 典型情境 | 世界級對照 |
51
+ | orientation | Layout | 典型情境 | 世界級對照 |
52
52
  |-----------|--------|---------|-----------|
53
53
  | `vertical`(預設)| label 在上 / value 在下 | ProfileCard detail、sidebar 長 value(地址、bio) | Atlassian DescriptionList、Polaris DescriptionList |
54
54
  | `horizontal` | label 左 / value 右對齊 | **file info panel / 訂單詳情 / settings summary**(短 value 的 metadata 列) | Google Drive file info、Notion file panel、iOS Settings | <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
@@ -63,13 +63,13 @@ benchmark:
63
63
 
64
64
  ```tsx
65
65
  // 短 metadata 列,無需 divider
66
- <DescriptionList direction="horizontal">
66
+ <DescriptionList orientation="horizontal">
67
67
  <DescriptionItem label="建立">2026-04-20</DescriptionItem>
68
68
  <DescriptionItem label="修改">2026-04-20</DescriptionItem>
69
69
  </DescriptionList>
70
70
 
71
71
  // 檔案資訊 — 多 row + key 長度不一 → divided 對齊格線
72
- <DescriptionList direction="horizontal" divided>
72
+ <DescriptionList orientation="horizontal" divided>
73
73
  <DescriptionItem label="檔名">Q1 財報分析.xlsx</DescriptionItem>
74
74
  <DescriptionItem label="類型">application/vnd.xlsx</DescriptionItem>
75
75
  <DescriptionItem label="大小">1.2 MB</DescriptionItem>
@@ -86,18 +86,18 @@ benchmark:
86
86
 
87
87
  ## 間距
88
88
 
89
- ### Vertical direction
89
+ ### Vertical orientation
90
90
 
91
91
  - **label → value**(同 item 內):`--item-gap-label-desc-reading` token(2px)——極小間距,視覺上 label 與 value 緊密配對
92
92
  - **items 之間垂直 gap**:`gap-y-[var(--layout-space-tight)]`——density-aware,跟隨系統密度設定
93
93
  - **columns 之間水平 gap**:`gap-x-4`(16px)
94
94
 
95
- ### Horizontal direction(divided=false)
95
+ ### Horizontal orientation(divided=false)
96
96
 
97
97
  - **items 之間垂直 gap**:`mb-[var(--layout-space-tight)]` per item(last:mb-0)——density-aware,等同 vertical 的 items gap
98
98
  - label ↔ value 水平距離:`justify-between` + `gap-4`(最小 16px,content 之間拉開)
99
99
 
100
- ### Horizontal direction(divided=true)
100
+ ### Horizontal orientation(divided=true)
101
101
 
102
102
  - 每個 item `py-[var(--layout-space-tight)]`(density-aware,形成 cell-like row 高度)
103
103
  - 每個 item 底部 `border-b border-divider`,`last:border-b-0`——row 之間視覺格線,key 長度不一時易於對齊掃描
@@ -106,9 +106,9 @@ benchmark:
106
106
 
107
107
  ## Props
108
108
 
109
- ### `direction`:vertical / horizontal
109
+ ### `orientation`:vertical / horizontal
110
110
 
111
- 見上「Direction」段。
111
+ 見上「Orientation」段。
112
112
 
113
113
  ### `divided`:horizontal 專用 row divider
114
114
 
@@ -184,11 +184,11 @@ consumer 要在 DL 上方加 section heading(「基本資料」/「團隊資訊
184
184
 
185
185
  DescriptionList 是**唯讀 label / value 資料呈現**(非互動 / 非 variant 驅動):
186
186
 
187
- - **有 Inspector**:DL 雖唯讀,但有 layout prop 可即時切換——`Inspector` story 暴露 `cols`(1 / 2 / 3)/ `direction`(vertical / horizontal)/ `divided` 三個 prop 的 Controls,取代 Figma inspect。`direction` 與 `divided` 是 `ColsMatrix`(只示範 cols)沒涵蓋的維度。
187
+ - **有 Inspector**:DL 雖唯讀,但有 layout prop 可即時切換——`Inspector` story 暴露 `cols`(1 / 2 / 3)/ `orientation`(vertical / horizontal)/ `divided` 三個 prop 的 Controls,取代 Figma inspect。`orientation` 與 `divided` 是 `ColsMatrix`(只示範 cols)沒涵蓋的維度。
188
188
  - **無 ColorMatrix**:DL 固定 semantic token(label `text-fg-secondary` / value `text-foreground`),無自己的色彩變體,dark mode 由 semantic token 自動切換。加 color variant 不符語意(DL 是資訊展示,非狀態載體)。
189
189
  - **無 SizeMatrix**:DL 無 size prop——垂直間距隨 `layout-space` token 感知 density(見「間距」段),但 label / value typography 走 reading mode 固定 tier,不提供 sm / md / lg 變體。不同 density 由 token 自動處理,非 prop 切換。
190
190
 
191
- 對應 anatomy story(實際 5 個,對齊 6-canonical 結構;ColorMatrix / SizeMatrix N/A):`Overview`(anatomy + typography + 間距) + `Inspector`(Controls 即時切 `cols` / `direction` / `divided`) + `ColsMatrix`(元件特有 1 / 2 / 3 欄對照) + `StateBehavior`(空值 `-` / 長值 / 多行 / ReactNode value) + `Accessibility`(`dl/dt/dd` 語意 + 無互動說明)。
191
+ 對應 anatomy story(實際 5 個,對齊 6-canonical 結構;ColorMatrix / SizeMatrix N/A):`Overview`(anatomy + typography + 間距) + `Inspector`(Controls 即時切 `cols` / `orientation` / `divided`) + `ColsMatrix`(元件特有 1 / 2 / 3 欄對照) + `StateBehavior`(空值 `-` / 長值 / 多行 / ReactNode value) + `Accessibility`(`dl/dt/dd` 語意 + 無互動說明)。
192
192
 
193
193
  ---
194
194
 
@@ -89,14 +89,14 @@ export const DetailPanel: Story = {
89
89
  ),
90
90
  }
91
91
 
92
- /* ── Horizontal direction(label 左 / value 右,divided=false)──────── */
92
+ /* ── Horizontal orientation(label 左 / value 右,divided=false)──────── */
93
93
  export const Horizontal: Story = {
94
94
  name: '水平佈局',
95
95
  render: () => (
96
96
  <div className="border border-border rounded-lg p-[var(--layout-space-loose)] max-w-md">
97
97
  {/* title 到第一個 item 的間距 = item 之間間距(Gestalt proximity canonical,見 spec) */}
98
98
  <div className="text-body font-medium mb-[var(--layout-space-tight)]">檔案資訊</div>
99
- <DescriptionList direction="horizontal">
99
+ <DescriptionList orientation="horizontal">
100
100
  <DescriptionItem label="檔名">Q1-roadmap.pdf</DescriptionItem>
101
101
  <DescriptionItem label="類型">application/pdf</DescriptionItem>
102
102
  <DescriptionItem label="大小">2.4 MB</DescriptionItem>
@@ -107,7 +107,7 @@ export const Horizontal: Story = {
107
107
  }
108
108
 
109
109
  // @story-trait-rationale: HorizontalDivided retired 2026-05-17 per audit Dim 24/25 strict re-run —
110
- // 違 story-rules.md L42「同 affordance 內 prop variations 用 Controls 不另開」。Horizontal direction
110
+ // 違 story-rules.md L42「同 affordance 內 prop variations 用 Controls 不另開」。Horizontal orientation
111
111
  // 已展示;divided 是單一 prop toggle,anatomy Inspector 已 expose Controls (L85-86)。
112
112
  // 原本內容 archive 於 git history(若要看 divided 視覺,進 anatomy Inspector 開 divided=true)。
113
113
  // 2026-06-12:刪除 zombie export _RETIRED_HorizontalDivided,對齊 DS-wide comment-only 退役慣例(deep-audit dim25)。
@@ -12,7 +12,7 @@ import { cn } from '@/lib/utils'
12
12
  * value (dd): text-body (14px) text-foreground (neutral-9)
13
13
  * 兩者都是 14px × 1.5 行高——層級靠色彩區分,不靠字體大小。
14
14
  *
15
- * ── direction(2026-04-20 新增)──
15
+ * ── orientation(2026-04-20 新增)──
16
16
  * vertical(預設):label 在上 / value 在下,適合長 value(地址、bio、說明段落)、
17
17
  * form-like 資訊展示
18
18
  * horizontal :label 左 / value 右對齊,適合短 value 的 metadata 列
@@ -30,15 +30,15 @@ import { cn } from '@/lib/utils'
30
30
  * divided horizontal 模式:每 item py-[var(--layout-space-tight)](cell-like row 高度)
31
31
  */
32
32
 
33
- export type DescriptionDirection = 'vertical' | 'horizontal'
33
+ export type DescriptionListOrientation = 'vertical' | 'horizontal'
34
34
 
35
35
  interface DescriptionContextValue {
36
- direction: DescriptionDirection
36
+ orientation: DescriptionListOrientation
37
37
  divided: boolean
38
38
  }
39
39
 
40
40
  const DescriptionContext = React.createContext<DescriptionContextValue>({
41
- direction: 'vertical',
41
+ orientation: 'vertical',
42
42
  divided: false,
43
43
  })
44
44
 
@@ -46,7 +46,7 @@ export interface DescriptionListProps extends React.HTMLAttributes<HTMLDListElem
46
46
  /** grid 欄數(vertical 才生效;horizontal 永遠單欄),預設 1 */
47
47
  cols?: 1 | 2 | 3
48
48
  /** 項目排列方向,預設 vertical(label 在上 / value 在下) */
49
- direction?: DescriptionDirection
49
+ orientation?: DescriptionListOrientation
50
50
  /**
51
51
  * horizontal 模式下每個 item 下方加分隔線以對齊 rows。預設 false。
52
52
  * 短列表(< 4 rows)不需要;檔案 metadata 等長列表、key 長度不一時建議開。
@@ -61,10 +61,10 @@ const colsClass: Record<number, string> = {
61
61
  }
62
62
 
63
63
  const DescriptionList = React.forwardRef<HTMLDListElement, DescriptionListProps>(
64
- ({ cols = 1, direction = 'vertical', divided = false, className, ...props }, ref) => {
65
- const isHorizontal = direction === 'horizontal'
64
+ ({ cols = 1, orientation = 'vertical', divided = false, className, ...props }, ref) => {
65
+ const isHorizontal = orientation === 'horizontal'
66
66
  // Memoize provider value(2026-04-22 D3 perf audit):避免每 render 重建 2-field object
67
- const ctxValue = React.useMemo(() => ({ direction, divided }), [direction, divided])
67
+ const ctxValue = React.useMemo(() => ({ orientation, divided }), [orientation, divided])
68
68
  return (
69
69
  <DescriptionContext.Provider value={ctxValue}>
70
70
  <dl
@@ -90,8 +90,8 @@ export interface DescriptionItemProps extends React.HTMLAttributes<HTMLDivElemen
90
90
 
91
91
  const DescriptionItem = React.forwardRef<HTMLDivElement, DescriptionItemProps>(
92
92
  ({ label, children, className, ...props }, ref) => {
93
- const { direction, divided } = React.useContext(DescriptionContext)
94
- if (direction === 'horizontal') {
93
+ const { orientation, divided } = React.useContext(DescriptionContext)
94
+ if (orientation === 'horizontal') {
95
95
  return (
96
96
  <div
97
97
  ref={ref}
@@ -52,7 +52,10 @@ const DialogOverlay = React.forwardRef<
52
52
  ))
53
53
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
54
54
 
55
- interface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
55
+ // asChild Omit(2026-07-18 決策2):DialogContent 是固定 surface chrome(overlay + 定位 +
56
+ // bg/rounded/shadow + onOpenAutoFocus),恆渲染 {children}(consumer body,通常 Header+Body+Footer
57
+ // 多節點)→ <Content asChild> Radix Slot React.Children.only crash。children 保留(consumer body)。
58
+ interface DialogContentProps extends Omit<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, 'asChild'> {
56
59
  /** 最大寬度。預設 512px。傳 number 視為 px。 */
57
60
  maxWidth?: string | number
58
61
  /**
@@ -40,6 +40,7 @@ import { overlayMotion } from "@/design-system/tokens/motion/overlay-motion"
40
40
  */
41
41
 
42
42
  // ── Floating layer 共用樣式 ──
43
+ /** @internal — menu 形浮層共用 class(DropdownMenu/SelectMenu/Command 內部);consumer 不 hand-craft menu surface,用元件本身。root barrel 排除(subpath 仍可 wrap 後用)。 */
43
44
  const floatingLayerClass = [
44
45
  'z-50 overflow-hidden rounded-lg border border-border bg-surface-raised',
45
46
  overlayMotion,
@@ -121,11 +122,17 @@ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
121
122
 
122
123
  // ── Content ──
123
124
  interface DropdownMenuContentProps
124
- extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> {
125
+ // asChild Omit(2026-07-18 決策2):Content 恆注入固定 <RowSizeProvider> + <ScrollArea>
126
+ // wrapper 於 Portal 內 → <Content asChild> 會把 Content props slot-merge 到非-DOM Provider 上而壞。
127
+ // children 保留(合法渲染於固定 wrapper 內)。
128
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>, 'asChild'> {
125
129
  size?: SizeKey
126
130
  /** 最小寬度(px),預設 `max(180px, 觸發元件寬度)`——窄 trigger 時吃 180px 地板 */
127
131
  minWidth?: number
128
- /** 最大高度(px),超過時捲動 */
132
+ /**
133
+ * 最大高度(px)——**可選更低上限**。預設已 viewport-adaptive(夾到 trigger→視窗碰撞邊界的剩餘高度、
134
+ * 離窗 ≥8px、超過即捲動);傳 `maxHeight` 只在「想比視窗剩餘更矮」時用(取 `min(視窗剩餘, maxHeight)`)。
135
+ */
129
136
  maxHeight?: number
130
137
  }
131
138
 
@@ -154,24 +161,26 @@ const DropdownMenuContent = React.forwardRef<
154
161
  // close 後 programmatic refocus 在 Chromium 仍可 match `:focus-visible`(UA heuristic),
155
162
  // 但與 shadcn 官方 live demo 同流程 DOM 比對 IDENTICAL — Radix 生態一致接受此
156
163
  // tradeoff:APG keyboard focus-return 優先於 cosmetic ring。
157
- className={cn(floatingLayerClass, !maxHeight && 'py-2', className)}
164
+ className={cn(floatingLayerClass, 'flex flex-col min-h-0', className)}
158
165
  style={{
159
166
  boxShadow: 'var(--elevation-200)',
160
167
  minWidth: minWidth ?? 'max(180px, var(--radix-dropdown-menu-trigger-width))',
161
- maxHeight,
168
+ // 2026-07-18 viewport-adaptive max-h(對齊 HoverCard/Popover 既有 canonical):夾到「trigger 到
169
+ // 碰撞邊界(已內縮 collisionPadding=8px)的剩餘高度」→ 高選單不溢出視窗、離視窗邊 ≥8px、
170
+ // 短選單仍貼內容;consumer `maxHeight` 為**可選更低上限**(min 取小者)。inline style 非 class,
171
+ // 故動態 maxHeight 不觸 Tailwind 掃描陷阱。
172
+ maxHeight: maxHeight
173
+ ? `min(var(--radix-dropdown-menu-content-available-height, 100vh), ${maxHeight}px)`
174
+ : 'var(--radix-dropdown-menu-content-available-height, 100vh)',
162
175
  }}
163
176
  {...props}
164
177
  >
165
178
  <RowSizeProvider value={size}>
166
- {maxHeight ? (
167
- // 長選單用 ScrollArea OS 一致捲動(不吃寬度,macOS/Windows 視覺一致)
168
- // py-2 移到內層,ScrollArea Viewport 才能 scroll 整個 padded 區
169
- <ScrollArea className="max-h-[inherit]">
170
- <div className="py-2">{children}</div>
171
- </ScrollArea>
172
- ) : (
173
- children
174
- )}
179
+ {/* body 恆在 flex-1 ScrollArea 內:超過 clamped 高度即跨-OS 一致捲動(不吃寬度);
180
+ 短選單 flex-1 貼內容不塌(同 HoverCard/Popover/DataTable panel 已驗)。py-2 在內層,整 padded 區可捲。 */}
181
+ <ScrollArea className="flex-1 min-h-0">
182
+ <div className="py-2">{children}</div>
183
+ </ScrollArea>
175
184
  </RowSizeProvider>
176
185
  </DropdownMenuPrimitive.Content>
177
186
  </DropdownMenuPrimitive.Portal>
@@ -430,7 +439,11 @@ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
430
439
  // Radix handles checked state;checked 底色套在外層 Radix RadioItem 本身(parent-bg
431
440
  // pattern,詳下方 2026-05-31 #10 註解),內層 MenuItem 恆 !bg-transparent 讓它透出。
432
441
  interface DropdownMenuRadioItemProps
433
- extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> {
442
+ // children Omit + redeclare required(2026-07-18 決策2 一致性):對齊 sibling Item/SubTrigger/
443
+ // CheckboxItem — menu item 必有 label,children 為 required 非 Radix optional。RadioItem 恆渲染
444
+ // 固定 <MenuItem>{children}</MenuItem>,children 是合法 label(非 lie),此為 required 化一致性修。
445
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>, 'children'> {
446
+ children: React.ReactNode
434
447
  /** Prefix icon(LucideIcon) */
435
448
  startIcon?: LucideIcon
436
449
  /** 次要說明文字 */
@@ -17,8 +17,14 @@ export type FieldControlLayout = 'inline' | 'block'
17
17
  * - `'toolbar'`— Toolbar / Action bar inline Field(future,目前無 consumer)
18
18
  * - `'table-cell'`— DataTable cell-as-input substrate(取代 variant='naked' cell-detection
19
19
  * heuristic;canonical metrics 由 surface 推導,不再 hardcode in Field consumer)
20
+ * - `'inline-edit'`(2026-07-17)— InlineEdit view 委派 surface。**唯一語義 = 委派控件 view 態
21
+ * 左 px 統一 `--field-px`(不繼承 tagPadding / avatar inset / bare-span 0px)**,讓 InlineEdit
22
+ * 固定 `-mx-[--field-px]` 對齊盒精準抵銷 → 值/tag/avatar 左緣落 label 左緣(x=0)。edit 態**不套**
23
+ * 本 surface(edit 完全繼承原 field,含 tagPadding — Jira 式)。對齊 Atlassian inline-edit
24
+ * read-view「fixed negative margin + read=edit geometry by construction」。只 InlineEdit display
25
+ * box 注入;DataTable cell(table-cell)/ 純表單(form)的 tagPadding + bare-span 完全不受影響。
20
26
  */
21
- type FieldSurface = 'form' | 'toolbar' | 'table-cell'
27
+ type FieldSurface = 'form' | 'toolbar' | 'table-cell' | 'inline-edit'
22
28
 
23
29
  // ── Context ──
24
30
  export interface FieldContextValue {
@@ -30,7 +36,7 @@ export interface FieldContextValue {
30
36
  descriptionId: string
31
37
  errorId: string
32
38
  mode: FieldMode
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 型別收窄至
39
+ /** 視覺外殼透傳(2026-05-05)。default = 含 border+bg;naked = cell-as-input(edit×naked 自畫 border-based state machine;view×naked 用 transparent border 由 host cell 供邊框);`bare` 2026-07-09 退役;naked 2026-07-14 型別收窄至
34
40
  * FieldVariantInternal(@internal)— 公開 `<Field variant>` 只收 default,故本欄位維持 FieldVariant。
35
41
  * child Field control 自動繼承,per-control prop override 可覆寫。詳 field-types.ts。 */
36
42
  variant: FieldVariant
@@ -175,13 +181,13 @@ export function useResolvedFieldDisabled(disabledProp?: boolean | null): boolean
175
181
  }
176
182
 
177
183
  /**
178
- * Resolve Field control 的 **mode**(display / readonly / disabled / edit)— 2026-06-08 SSOT,統一兩派散落:
184
+ * Resolve Field control 的 **mode**(view / readonly / disabled / edit)— 2026-06-08 SSOT,統一兩派散落:
179
185
  * 舊 Input 派 `modeProp ?? fieldCtx?.mode ?? (...)` → `<Field disabled>` 時 ctx.mode 仍 'edit',漏 disabled chrome。
180
- * 舊 picker 派 `disabled ? 'disabled' : mode`(mode 預設 'edit')→ 完全不讀 fieldCtx.mode,`<Field mode="display">` 失效。
186
+ * 舊 picker 派 `disabled ? 'disabled' : mode`(mode 預設 'edit')→ 完全不讀 fieldCtx.mode,`<Field mode="view">` 失效。
181
187
  * 統一優先序(world-class:MUI FormControl disabled 完整 cascade + 顯式 prop 永遠最優先):
182
- * 1. 顯式 mode prop(caller / DataTable cell displayOrDisabled)→ **永遠最優先**,故表格等顯式場景 inert
188
+ * 1. 顯式 mode prop(caller / DataTable cell mode="view")→ **永遠最優先**,故表格等顯式場景 inert
183
189
  * 2. 有效 disabled(prop 或 `<Field disabled>`)→ 'disabled'(完整 disabled chrome)
184
- * 3. FieldContext.mode(`<Field mode="display"/"readonly">`)→ 讓 mode cascade 真正生效
190
+ * 3. FieldContext.mode(`<Field mode="view"/"readonly">`)→ 讓 mode cascade 真正生效
185
191
  * 4. 本地 readOnly → 'readonly'
186
192
  * 5. 'edit'
187
193
  * cell:mode prop 必有 → step 1 命中、fieldCtx=null → 完全 inert(Δ=0)。`disabled` 傳已 resolve 的 boolean 或未預設 prop。
@@ -240,7 +246,7 @@ export function FieldSurfaceSizeProvider({
240
246
  /**
241
247
  * Table-cell 可編輯訊號(2026-07-08 user 拍板)— 獨立於 FieldSurfaceContext / FieldSurfaceSizeContext
242
248
  * 的純 boolean context,由 host(DataTable cell registry)注入該 cell 是否可編輯,讓 useFieldEmptyDisplay
243
- * 分流「可編輯 cell 空 display → 空白」vs「不可編輯 cell 空 display → '-'」。
249
+ * 分流「可編輯 cell 空 view → 空白」vs「不可編輯 cell 空 view → '-'」。
244
250
  * value = boolean primitive(stable when unchanged),不破壞 cell memo identity(同 TableScrollContext /
245
251
  * FieldSurfaceSizeContext L119-121 canonical);絕不污染 FieldContext(useFieldContext() 在 cell 內仍 null)。
246
252
  */
@@ -261,16 +267,16 @@ export function FieldSurfaceEditableProvider({
261
267
  *
262
268
  * | 情境 | 空值顯示 |
263
269
  * |------------------------------------------------|----------|
264
- * | table-cell **可編輯** 的 display 靜止態 | **空白 `''`**(不佔位,affordance = hover outline)|
270
+ * | table-cell **可編輯** 的 view 靜止態 | **空白 `''`**(不佔位,affordance = hover outline)|
265
271
  * | table-cell **不可編輯**(readonly cell) | **半形 `-`** |
266
- * | standalone display / readonly / form / toolbar | **半形 `-`** |
272
+ * | standalone view / readonly / form / toolbar | **半形 `-`** |
267
273
  *
268
274
  * 收斂式:`surface==='table-cell' && isEditable ? '' : EMPTY_DISPLAY`。
269
275
  * 可編輯 form / edit 輸入框走 native placeholder(不經此 hook)。boolean → unchecked / disabled →
270
276
  * 同上文字 + text-fg-disabled(M24),各控件自理。
271
277
  * 世界級對照:table-cell blank = MUI X / AG Grid / Ant core / Notion / Airtable grid 域共識;
272
278
  * 非 table `-` = Ant ProTable `columnEmptyText`(見 field-wrapper.tsx EMPTY_DISPLAY 註)。
273
- * SSOT 條文 → field-controls.spec.md「null / undefined 值」;全 Field family display/readonly/disabled
279
+ * SSOT 條文 → field-controls.spec.md「null / undefined 值」;全 Field family view/readonly/disabled
274
280
  * 空值渲染必經此 hook,禁直接引 EMPTY_DISPLAY 常數(genre 分流會漏)。
275
281
  */
276
282
  export function useFieldEmptyDisplay(): string {
@@ -288,7 +294,7 @@ export function useFieldEmptyDisplay(): string {
288
294
  * 提示」的裝飾語意;空值符號不是提示、是被檢視的值狀態)。
289
295
  * disabled 態維持 `text-fg-disabled`(M24 disabled 顯著性 > foreground/muted,不可被蓋)。
290
296
  *
291
- * SSOT:全 Field family display/readonly/disabled 空值 span 消費此 helper,傳入已 resolve 的
297
+ * SSOT:全 Field family view/readonly/disabled 空值 span 消費此 helper,傳入已 resolve 的
292
298
  * resolvedMode。純函式(非 hook)—— resolvedMode 已由 useResolvedFieldMode 解析(含控件自身
293
299
  * disabled prop,context hook 讀不到);故以 resolvedMode 為入參,可條件呼叫、不受 Rules of Hooks 限制。
294
300
  * 世界級對照:Ant read-only / Carbon read-only value = 正常前景色;placeholder 才 muted。