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

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 (481) 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 +19 -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 +8 -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 +10 -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/Empty/empty.spec.md +0 -1
  323. package/src/components/Field/field-context.ts +17 -11
  324. package/src/components/Field/field-controls.spec.md +46 -37
  325. package/src/components/Field/field-types.ts +14 -12
  326. package/src/components/Field/field-wrapper.tsx +59 -43
  327. package/src/components/Field/field.anatomy.stories.tsx +6 -6
  328. package/src/components/Field/field.principles.stories.tsx +5 -28
  329. package/src/components/Field/field.spec.md +5 -4
  330. package/src/components/Field/field.stories.tsx +103 -72
  331. package/src/components/Field/field.tsx +36 -4
  332. package/src/components/Field/form-validation.spec.md +4 -0
  333. package/src/components/Field/use-form-validation.ts +1 -1
  334. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
  335. package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
  336. package/src/components/FileItem/file-item.tsx +10 -8
  337. package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
  338. package/src/components/FileUpload/file-upload.spec.md +3 -2
  339. package/src/components/FileUpload/file-upload.tsx +5 -1
  340. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
  341. package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
  342. package/src/components/FileViewer/file-viewer.spec.md +1 -1
  343. package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
  344. package/src/components/FileViewer/file-viewer.tsx +3 -2
  345. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
  346. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
  347. package/src/components/HoverCard/hover-card.spec.md +2 -2
  348. package/src/components/HoverCard/hover-card.tsx +4 -2
  349. package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
  350. package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
  351. package/src/components/InlineEdit/inline-edit.spec.md +71 -46
  352. package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
  353. package/src/components/InlineEdit/inline-edit.tsx +211 -125
  354. package/src/components/Input/input.anatomy.stories.tsx +15 -15
  355. package/src/components/Input/input.principles.stories.tsx +3 -3
  356. package/src/components/Input/input.spec.md +4 -4
  357. package/src/components/Input/input.stories.tsx +3 -3
  358. package/src/components/Input/input.tsx +13 -13
  359. package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
  360. package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
  361. package/src/components/LinkInput/link-input.spec.md +6 -2
  362. package/src/components/LinkInput/link-input.stories.tsx +8 -8
  363. package/src/components/LinkInput/link-input.tsx +21 -19
  364. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  365. package/src/components/Notice/notice.tsx +8 -2
  366. package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
  367. package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
  368. package/src/components/NumberInput/number-input.spec.md +6 -6
  369. package/src/components/NumberInput/number-input.stories.tsx +4 -4
  370. package/src/components/NumberInput/number-input.tsx +17 -5
  371. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
  372. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
  373. package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
  374. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
  375. package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
  376. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
  377. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
  378. package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
  379. package/src/components/PeoplePicker/people-picker.tsx +39 -20
  380. package/src/components/PeoplePicker/person-display.tsx +3 -3
  381. package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
  382. package/src/components/Popover/popover.principles.stories.tsx +49 -28
  383. package/src/components/Popover/popover.spec.md +4 -2
  384. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  385. package/src/components/ProfileCard/profile-card.tsx +1 -1
  386. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
  387. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
  388. package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
  389. package/src/components/README.md +1 -0
  390. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
  391. package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
  392. package/src/components/RadioGroup/radio-group.tsx +19 -14
  393. package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
  394. package/src/components/Rating/rating.principles.stories.tsx +3 -3
  395. package/src/components/Rating/rating.spec.md +2 -2
  396. package/src/components/Rating/rating.stories.tsx +4 -18
  397. package/src/components/Rating/rating.tsx +5 -1
  398. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  399. package/src/components/ScrollArea/scroll-area.spec.md +1 -1
  400. package/src/components/ScrollArea/scroll-area.tsx +5 -2
  401. package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
  402. package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
  403. package/src/components/SegmentedControl/segmented-control.tsx +6 -3
  404. package/src/components/Select/select.anatomy.stories.tsx +13 -7
  405. package/src/components/Select/select.principles.stories.tsx +3 -3
  406. package/src/components/Select/select.spec.md +10 -1
  407. package/src/components/Select/select.stories.tsx +41 -27
  408. package/src/components/Select/select.tsx +44 -26
  409. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
  410. package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
  411. package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
  412. package/src/components/SelectMenu/select-menu.tsx +38 -5
  413. package/src/components/SelectionControl/boolean-value.tsx +2 -2
  414. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  415. package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
  416. package/src/components/Separator/separator.principles.stories.tsx +1 -1
  417. package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
  418. package/src/components/Sheet/sheet.tsx +4 -1
  419. package/src/components/Sidebar/sidebar.tsx +1 -1
  420. package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
  421. package/src/components/Slider/slider.principles.stories.tsx +6 -6
  422. package/src/components/Slider/slider.spec.md +13 -1
  423. package/src/components/Slider/slider.stories.tsx +44 -32
  424. package/src/components/Slider/slider.tsx +13 -4
  425. package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
  426. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  427. package/src/components/Steps/steps.spec.md +4 -2
  428. package/src/components/Steps/steps.stories.tsx +4 -56
  429. package/src/components/Steps/steps.tsx +31 -7
  430. package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
  431. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  432. package/src/components/Switch/switch.spec.md +4 -4
  433. package/src/components/Switch/switch.stories.tsx +3 -3
  434. package/src/components/Switch/switch.tsx +16 -10
  435. package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
  436. package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
  437. package/src/components/Tabs/tabs.spec.md +5 -2
  438. package/src/components/Tabs/tabs.stories.tsx +36 -44
  439. package/src/components/Tabs/tabs.tsx +101 -36
  440. package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
  441. package/src/components/Tag/tag.principles.stories.tsx +4 -4
  442. package/src/components/Tag/tag.spec.md +4 -1
  443. package/src/components/Tag/tag.tsx +5 -3
  444. package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
  445. package/src/components/Textarea/textarea.spec.md +5 -5
  446. package/src/components/Textarea/textarea.tsx +24 -24
  447. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
  448. package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
  449. package/src/components/TimePicker/time-picker.spec.md +6 -5
  450. package/src/components/TimePicker/time-picker.stories.tsx +3 -3
  451. package/src/components/TimePicker/time-picker.tsx +24 -14
  452. package/src/components/Toast/toast.principles.stories.tsx +1 -1
  453. package/src/components/Toast/toast.stories.tsx +1 -1
  454. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
  455. package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
  456. package/src/components/Tooltip/tooltip.spec.md +9 -3
  457. package/src/components/Tooltip/tooltip.stories.tsx +1 -1
  458. package/src/components/Tooltip/tooltip.tsx +12 -2
  459. package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
  460. package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
  461. package/src/components/TreeView/tree-view.spec.md +8 -6
  462. package/src/components/TreeView/tree-view.stories.tsx +9 -43
  463. package/src/components/TreeView/tree-view.tsx +36 -0
  464. package/src/index.ts +13 -10
  465. package/src/lib/drag-visual.ts +2 -2
  466. package/src/lib/utils.ts +19 -0
  467. package/src/patterns/action-bar/action-bar.spec.md +1 -0
  468. package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
  469. package/src/patterns/element-anatomy/item-anatomy.spec.md +4 -0
  470. package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
  471. package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
  472. package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
  473. package/src/tokens/categorical-color.ts +5 -5
  474. package/src/tokens/color/color.spec.md +4 -4
  475. package/src/tokens/color/primitives.css +9 -2
  476. package/src/tokens/motion/motion.spec.md +6 -7
  477. package/src/tokens/opacity/opacity.spec.md +1 -1
  478. package/src/tokens/orphan-tokens.spec.md +1 -1
  479. package/src/tokens/typography/typography.spec.md +2 -0
  480. package/src/tokens/uiSize/uiSize.css +5 -0
  481. package/src/tokens/uiSize/uiSize.spec.md +1 -1
@@ -111,16 +111,18 @@ const TimePicker = React.forwardRef(
111
111
  commitDraft(next);
112
112
  setOpen(false);
113
113
  };
114
- if (resolvedMode === "display") {
114
+ if (resolvedMode === "view") {
115
115
  if (!showDisplayEndIcon) {
116
- if (!value) return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className), children: emptyDisplay });
117
- return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "truncate", className), children: formatTime(value, { formatOptions, locale }) });
116
+ if (!value) return /* @__PURE__ */ jsx("span", { ...props, ref, className: cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className), children: emptyDisplay });
117
+ return /* @__PURE__ */ jsx("span", { ...props, ref, className: cn(fieldDisplayTextClass(size), "truncate", className), children: formatTime(value, { formatOptions, locale }) });
118
118
  }
119
119
  return /* @__PURE__ */ jsxs(
120
120
  "div",
121
121
  {
122
- className: cn(fieldWrapperStyles({ mode: "display", variant, size }), className),
123
- "data-field-mode": "display",
122
+ ref,
123
+ ...props,
124
+ className: cn(fieldWrapperStyles({ mode: "view", variant, size }), className),
125
+ "data-field-mode": "view",
124
126
  children: [
125
127
  /* @__PURE__ */ jsx("span", { className: cn(bareInputStyles, "flex-1 min-w-0 truncate", !value && fieldEmptyColorClass(resolvedMode)), children: value ? formatTime(value, { formatOptions, locale }) : emptyDisplay }),
126
128
  EndIconCmp && /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(EndIconCmp, { size: iconSize, className: "text-fg-muted", "aria-hidden": true }) })
@@ -132,6 +134,7 @@ const TimePicker = React.forwardRef(
132
134
  return /* @__PURE__ */ jsxs(
133
135
  "div",
134
136
  {
137
+ ref,
135
138
  className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size }), className),
136
139
  "data-field-mode": resolvedMode,
137
140
  "aria-disabled": resolvedMode === "disabled" ? true : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"time-picker.js","sources":["../../../src/components/TimePicker/time-picker.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\nimport * as React from 'react'\nimport { X, Clock } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant, FieldVariantInternal } from '@/design-system/components/Field/field-types'\nimport {\n fieldWrapperStyles,\n bareInputStyles,\n fieldDisplayTextClass,\n} from '@/design-system/components/Field/field-wrapper'\nimport { ItemInlineAction, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { Popover, PopoverTrigger, PopoverContent } from '@/design-system/components/Popover/popover'\nimport { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid, useFieldEmptyDisplay, fieldEmptyColorClass } from '@/design-system/components/Field/field-context'\nimport { Button } from '@/design-system/components/Button/button'\nimport { SurfaceFooter } from '@/design-system/patterns/overlay-surface/overlay-surface'\nimport {\n TimeColumns,\n isoToTimeParts,\n timePartsToString,\n type TimeParts,\n type TimeStep,\n type TimeColumnsDisabled,\n} from '@/design-system/components/TimePicker/time-columns'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n/**\n * TimePicker — 單一時間(時/分/秒)輸入與顯示元件\n *\n * ── 定位(同 DatePicker 家族)──\n * Value 以 ISO time string 儲存(\"HH:mm\" 或 \"HH:mm:ss\"),local-time 語義(不帶時區)。\n * Edit 用本 DS 自建 time column panel + Popover 呈現,視覺與 DatePicker 一致。\n * Display 用 Intl.DateTimeFormat 格式化(跨 locale / 12h-24h 統一經過此 API)。\n *\n * ── Layout Family ──\n * CLAUDE.md 4-Family Model Family 4(Field control layout)消費者。結構繼承\n * `fieldWrapperStyles + [<editable>] [endIcon=Clock]`,視覺對齊 DatePicker(同\n * 「點擊觸發浮層」role:indicator 在 suffix slot,對齊 Material `endAdornment` /\n * Ant DatePicker / Polaris Picker 共識)。\n *\n * ── 實作基礎 ──\n * Trigger:`<div role=\"combobox\">` + `fieldWrapperStyles`(視覺仍是 Input wrapper,改為可點擊觸發浮層;\n * 2026-04-25 由 `<button>` 改 div 避 nested-interactive,對齊 Select / Combobox,鍵盤靠顯式 onKeyDown)\n * Popup:`Popover`(消費 overlay-surface pattern)\n * Panel 主體:自建 column picker(三欄 scrollable list),不引入第三方 time library\n *\n * ── 共用規則 ──\n * Mode / size / disabled / error 等詳見 `../Field/field-controls.spec.md`。\n */\n\n// ── Time ISO <-> parts conversion ───────────────────────────────────────────\n// Value 用 ISO time string(HH:mm 或 HH:mm:ss),local-time 語義(不帶時區/日期)。\n// 跟 DatePicker 的 ISO date string 策略一致。\n// `isoToTimeParts` / `timePartsToString` 改 import from time-columns(M17 SSOT)。\n\n// ── Display formatting ──────────────────────────────────────────────────────\n\nexport interface TimeFormatOptions {\n /** Intl.DateTimeFormat options(預設 { hour: '2-digit', minute: '2-digit', hour12: false }) */\n formatOptions?: Intl.DateTimeFormatOptions\n /** locale(預設 'en-US') */\n locale?: string\n}\n\n// 2026-07-06 D3 perf:Intl.DateTimeFormat 是標準庫最貴 constructor 之一(locale data\n// resolution)。formatTime 無 cheap path,display/readonly/edit 每 render 必建;DataTable time 欄\n// 轉發 config 時每 cell × 每次表格 re-render 重建。module-level cache 重用實例(DateTimeFormat\n// 無狀態可安全重用),key = locale|JSON.stringify(options)。行為 Δ=0。\nconst dtfCache = new Map<string, Intl.DateTimeFormat>()\nfunction getDateTimeFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + '|' + JSON.stringify(options)\n let fmt = dtfCache.get(key)\n if (!fmt) {\n fmt = new Intl.DateTimeFormat(locale, options)\n dtfCache.set(key, fmt)\n }\n return fmt\n}\n\nfunction formatTime(\n iso: string,\n options: TimeFormatOptions = {},\n): string {\n const parts = isoToTimeParts(iso)\n if (!parts) return iso\n const {\n formatOptions = { hour: '2-digit', minute: '2-digit', hour12: false },\n locale = 'en-US',\n } = options\n // 借用 Date 讓 Intl.DateTimeFormat 處理 locale / 12h-24h\n const d = new Date()\n d.setHours(parts.hours, parts.minutes, parts.seconds, 0)\n return getDateTimeFormatter(locale, formatOptions).format(d)\n}\n\n// ── Disabled time callback ──────────────────────────────────────────────────\n// `Step` / `buildRange` / `TimeColumn`(內部欄位實作)拔掉,改 import `TimeColumns` primitive。\n\n// code-quality-allow: dead-export — public API surface — consumer-exposed for future use\nexport interface DisabledTimeResult {\n disabledHours?: number[]\n disabledMinutes?: number[]\n disabledSeconds?: number[]\n}\n\n// ── Component props ─────────────────────────────────────────────────────────\n\nexport interface TimePickerProps\n extends TimeFormatOptions,\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'placeholder'\n > {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n /** ISO time string(\"HH:mm\" 或 \"HH:mm:ss\") */\n value?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n className?: string\n disabled?: boolean\n /** 允許清空已選值 */\n clearable?: boolean\n /**\n * 是否顯示秒欄(三欄 picker)。預設 false(兩欄:時/分)。\n * format 自動對應:false → \"HH:mm\",true → \"HH:mm:ss\"。\n */\n showSeconds?: boolean\n /** 分鐘步進(會議常用 15)。預設 1 */\n minuteStep?: TimeStep\n /** 秒步進。預設 1。僅 showSeconds=true 有效 */\n secondStep?: TimeStep\n /** 動態 disabled 某些時/分/秒(基於已選其他欄位)。 */\n disabledTime?: (parts: TimeParts) => DisabledTimeResult\n /**\n * Suffix indicator(2026-05-05 v9 canonical fix):「點擊觸發浮層」indicator 一律 suffix\n * (對齊 DatePicker calendar / Material endAdornment)。預設 Clock,傳 null 可關閉。\n */\n endIcon?: LucideIcon | null\n /**\n * Display 是否渲 endIcon + Field naked wrapper(D-path opt-in,2026-05-08)\n * — DataTable cell display↔edit 像素級對齊用。預設 false(裸 span,backward compat)。\n * 設 true 時 display 也走 fieldWrapperStyles(naked variant)+ ItemSuffix Clock,\n * 與 edit 同 DOM 結構,消除 Layer-B padding mismatch。\n */\n showDisplayEndIcon?: boolean\n /** Initial open state(uncontrolled)— DataTable cell-as-input 1-step open canonical */\n defaultOpen?: boolean\n /** open state 變更 callback。DataTable cell-as-input 用:open=false → cell exit edit */\n onOpenChange?: (open: boolean) => void\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TimePicker = React.forwardRef<HTMLDivElement, TimePickerProps>(\n (\n {\n mode,\n variant: variantProp,\n error: errorProp = false,\n size: sizeProp,\n value,\n onChange,\n placeholder,\n className,\n disabled: disabledProp,\n clearable = false,\n showSeconds = false,\n minuteStep = 1,\n secondStep = 1,\n disabledTime,\n endIcon,\n showDisplayEndIcon = false,\n formatOptions,\n locale,\n defaultOpen = false,\n onOpenChange,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n 'aria-errormessage': ariaErrorMessageProp,\n ...props\n },\n ref,\n ) => {\n const fieldCtx = useFieldContext()\n const size = useResolvedFieldSize(sizeProp) // B 組 cascade fix\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const emptyDisplay = useFieldEmptyDisplay()\n const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)\n const isEditable = resolvedMode === 'edit'\n // 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反 7+ 重複 ternary)\n const iconSize = ICON_SIZE[size as 'sm' | 'md' | 'lg']\n const EndIconCmp: LucideIcon | null =\n endIcon === null ? null : (endIcon ?? Clock)\n const defaultPlaceholder = showSeconds ? 'HH:MM:SS' : 'HH:MM'\n const resolvedPlaceholder = placeholder ?? defaultPlaceholder\n const showClear = clearable && !!value && isEditable\n const [open, setOpenState] = React.useState(defaultOpen)\n const setOpen = React.useCallback((next: boolean) => { setOpenState(next); onOpenChange?.(next) }, [onOpenChange])\n\n const currentParts = React.useMemo(() => isoToTimeParts(value), [value])\n // draft = panel 開啟期間的暫存:供 eager commit(每次欄選 commitDraft 即 commit)+ disabledTime 重算;OK 按鈕只 setOpen(false) 關 Panel,不做 commit\n const [draft, setDraft] = React.useState<TimeParts>(\n () => currentParts ?? { hours: 0, minutes: 0, seconds: 0 },\n )\n\n // 每次 popover 開啟時以當前 value 初始化 draft\n React.useEffect(() => {\n if (open) {\n setDraft(currentParts ?? { hours: 0, minutes: 0, seconds: 0 })\n }\n }, [open, currentParts])\n\n const disabledForColumns: TimeColumnsDisabled | undefined = React.useMemo(() => {\n if (!disabledTime) return undefined\n const res = disabledTime(draft)\n return {\n hours: res.disabledHours,\n minutes: res.disabledMinutes,\n seconds: res.disabledSeconds,\n }\n }, [disabledTime, draft])\n\n const commitDraft = (next: TimeParts) => {\n setDraft(next)\n onChange?.(timePartsToString(next, showSeconds))\n }\n\n const handleNow = () => {\n const now = new Date()\n // 按照 minuteStep / secondStep 對齊。\n // 2026-07-05 邊界修正(deep-audit A.1b):Math.round 進位到 60 時,舊 `Math.min(round, 59)`\n // 會產生 59 這種「不對齊 step、也不在 column values 內」的值(如 53 分 @ step=15 → 59)\n // → panel 該欄失去 selected 高亮。改 clamp 到 ≤59 的最大 step 對齊值(= buildRange 產出的\n // 最後一格,如 45),不跨小時進位 — 保持「此刻 = commit 當前時間(step 對齊)」語意\n // (time-picker.spec.md「每次欄位選取當下即 commit」段)。\n const alignToStep = (raw: number, step: number) => {\n const rounded = Math.round(raw / step) * step\n return rounded > 59 ? Math.floor(59 / step) * step : rounded\n }\n const next: TimeParts = {\n hours: now.getHours(),\n minutes: alignToStep(now.getMinutes(), minuteStep),\n seconds: showSeconds ? alignToStep(now.getSeconds(), secondStep) : 0,\n }\n commitDraft(next)\n setOpen(false)\n }\n\n // mode='display'(Phase B2 2026-05-05):純內容輸出 — 對齊原 TimePickerDisplay sub-component(retired)。\n // Default(showDisplayEndIcon=false):無 Field wrapper / 無 Clock icon — backward compat 裸 span。\n // Opt-in(showDisplayEndIcon=true,2026-05-08 D-path):Field naked wrapper + ItemSuffix Clock,\n // 與 edit 同結構消除 cell display↔edit 像素偏移(Layer-B padding mismatch)。\n if (resolvedMode === 'display') {\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 套\n // `fieldDisplayTextClass(size)`(sm/md→text-body,lg→text-body-lg)— 對齊 Field family 統一。\n if (!value) return <span className={cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className)}>{emptyDisplay}</span>\n return <span className={cn(fieldDisplayTextClass(size), 'truncate', className)}>{formatTime(value, { formatOptions, locale })}</span>\n }\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: 'display', variant, size }), className)}\n data-field-mode=\"display\"\n >\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && fieldEmptyColorClass(resolvedMode))}>\n {value ? formatTime(value, { formatOptions, locale }) : emptyDisplay}\n </span>\n {EndIconCmp && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )}\n </div>\n )\n }\n\n // readonly / disabled\n if (!isEditable) {\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: resolvedMode, variant: variant, size }), className)}\n data-field-mode={resolvedMode}\n aria-disabled={resolvedMode === 'disabled' ? true : undefined}\n {...(props as React.HTMLAttributes<HTMLDivElement>)}\n >\n <span\n className={cn(\n 'flex-1 min-w-0',\n resolvedMode === 'disabled' && 'text-fg-disabled',\n )}\n >\n {value\n ? formatTime(value, { formatOptions, locale })\n : <span className={fieldEmptyColorClass(resolvedMode)}>{emptyDisplay}</span>\n }\n </span>\n {/* 2026-06-26 類型身份 indicator:edit 顯示 / readonly 不顯示 / disabled 保留(fg-disabled);naked cell 依 showDisplayEndIcon=isEditable(修 disabled cell 漏顯 bug)*/}\n {EndIconCmp && (variant === 'naked' ? showDisplayEndIcon : resolvedMode === 'disabled') && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp\n size={iconSize}\n className={resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'}\n aria-hidden\n />\n </ItemSuffix>\n )}\n </div>\n )\n }\n\n const displayText = value\n ? formatTime(value, { formatOptions, locale })\n : <span className=\"text-fg-muted\">{resolvedPlaceholder}</span>\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n {/* a11y(2026-04-25 nested-interactive fix):trigger 改 <div role='combobox'>\n (對齊 Select / Combobox 同 pattern),原 <button> 會與內層 ItemInlineAction\n 清除 button 構成 nested-interactive。\n 2026-06-01 鍵盤開啟修正:Radix PopoverTrigger 只 compose onClick\n (@radix-ui/react-popover index.js:145),不 inject 任何 onKeyDown。原生 <button>\n 靠瀏覽器在 Enter/Space 自動派發 click 才能開;但本 trigger 是 <div role=combobox>,\n div 不會自動派發 click → 鍵盤使用者打不開 panel。故顯式加 onKeyDown\n (對齊 select.tsx:609-619 既有 canonical + WAI-ARIA APG combobox required keys)。 */}\n <PopoverTrigger asChild>\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled || undefined}\n aria-labelledby={fieldCtx?.labelId}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onKeyDown={(e) => {\n if (disabled) return\n // 2026-07-14 dim-10 修:內層「清除時間」ItemInlineAction button 的 Enter/Space\n // 會 bubble 到本 handler 被 preventDefault 吞掉(按鈕 activation 被取消、panel 反而開)。\n // trigger 鍵盤邏輯只在事件源自 trigger div 本身時執行。\n if (e.target !== e.currentTarget) return\n // Enter / Space / ArrowDown / Alt+ArrowDown → 開 panel(APG combobox required + Select canonical)\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n e.preventDefault()\n setOpen(true)\n }\n // Escape → 關(Radix Content 已自帶,trigger 補位對齊 select.tsx:597)\n if (e.key === 'Escape') setOpen(false)\n }}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }),\n 'text-left cursor-pointer',\n 'focus-visible:outline-none',\n className,\n )}\n {...props}\n >\n <span className={cn(bareInputStyles, 'truncate', !value && 'text-fg-muted')}>\n {displayText}\n </span>\n {showClear && (\n <ItemInlineAction\n size={size ?? 'md'}\n action={{\n icon: X,\n label: '清除時間', // i18n-allow: DS default inline-action label\n onClick: (e) => {\n e?.stopPropagation()\n onChange?.('')\n },\n }}\n />\n )}\n {EndIconCmp && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )}\n </div>\n </PopoverTrigger>\n {/* a11y(2026-07-14 dim-10):Radix PopoverContent 輸出 role=\"dialog\",無 title 需\n accessible name(WAI-ARIA dialog required);對齊 date-picker.tsx:1040「日期區間選擇」同款 DS default。 */}\n <PopoverContent className=\"w-auto p-0\" align=\"start\" aria-label=\"選擇時間\" /* i18n-allow: DS default dialog label */>\n {/* Panel 對齊 ref/timepicker.png:2-3 個 SelectMenu 式欄位並排,分隔線分開。\n Width 依欄數由 TimeColumns 決定:2 欄 w-40 / 3 欄 w-60。\n Height 由 wrapper 控:216px 預設(扣 footer 後 list 約可見 5-6 items)。\n TimeColumns 本身 h-full,parent 控 height — 讓 DatePicker showTime / Range 可\n 用 flex-row items-stretch 自動同 calendar 高。 */}\n <div className=\"flex flex-col h-[216px]\">\n <TimeColumns\n value={draft}\n onChange={commitDraft}\n showSeconds={showSeconds}\n minuteStep={minuteStep}\n secondStep={secondStep}\n disabled={disabledForColumns}\n // 2026-05-06 v9.1 M25 chain fix:TimeColumns 自然高 = 24 buttons × ~28.7px = 688px\n // 會撐破 parent h-[216px]。flex-1 + min-h-0 讓 TimeColumns 取 parent 剩餘空間\n // (216 − footer ≈53px ≈ 163px)→ ScrollArea h-full 才能正確收斂 →\n // listbox scrollIntoView 找對 nearest scrollable ancestor(內部 viewport),\n // 不會走到 document body 把 popover 內容推出畫面(user 報「hours 欄空白」根因)。\n className=\"flex-1 min-h-0\"\n />\n {/* Footer:消費 SurfaceFooter SSOT(border-t + py-tight + gap-2 + shrink-0 + justify-end)。\n px override 回 layout-space-tight,因 TimePicker 滿欄 column 面板無 chrome-padded body\n 內縮邊可對齊(footer px = body 內縮 原則;column-selector 數字置中、零內距,\n 見 time-picker.spec.md)。此刻 mr-auto 把確定推右,視覺等同原 justify-between\n —— 純結構消費 overlay-surface canonical(overlay-surface.spec.md:17「不自寫 padding token」),零視覺變化。 */}\n <SurfaceFooter className=\"px-[var(--layout-space-tight)]\">\n <Button variant=\"text\" size=\"sm\" onClick={handleNow} className=\"mr-auto\">\n 此刻\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n 確定\n </Button>\n </SurfaceFooter>\n </div>\n </PopoverContent>\n </Popover>\n )\n },\n)\nTimePicker.displayName = 'TimePicker'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const timePickerMeta = {\n component: 'TimePicker',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n // states 對齊真實視覺態:trigger 與 panel item 皆無 'active'(按下)專屬視覺態(2026-07-04 audit 對齊);\n // 'selected' = panel item 持續選中(bg-neutral-selected,time-columns.tsx isSelected;2026-07-07 詞彙統一補列)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n // panel selected 走 bg-neutral-selected(time-columns.tsx isSelected;spec「欄內 item 狀態」),非 bg-primary。\n bg: ['bg-neutral-hover', 'bg-neutral-selected', 'bg-transparent'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-foreground'],\n ring: [],\n },\n} as const\n\nexport { TimePicker }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"time-picker.js","sources":["../../../src/components/TimePicker/time-picker.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\nimport * as React from 'react'\nimport { X, Clock } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant, FieldVariantInternal } from '@/design-system/components/Field/field-types'\nimport {\n fieldWrapperStyles,\n bareInputStyles,\n fieldDisplayTextClass,\n} from '@/design-system/components/Field/field-wrapper'\nimport { ItemInlineAction, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { Popover, PopoverTrigger, PopoverContent } from '@/design-system/components/Popover/popover'\nimport { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid, useFieldEmptyDisplay, fieldEmptyColorClass } from '@/design-system/components/Field/field-context'\nimport { Button } from '@/design-system/components/Button/button'\nimport { SurfaceFooter } from '@/design-system/patterns/overlay-surface/overlay-surface'\nimport {\n TimeColumns,\n isoToTimeParts,\n timePartsToString,\n type TimeParts,\n type TimeStep,\n type TimeColumnsDisabled,\n} from '@/design-system/components/TimePicker/time-columns'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n/**\n * TimePicker — 單一時間(時/分/秒)輸入與顯示元件\n *\n * ── 定位(同 DatePicker 家族)──\n * Value 以 ISO time string 儲存(\"HH:mm\" 或 \"HH:mm:ss\"),local-time 語義(不帶時區)。\n * Edit 用本 DS 自建 time column panel + Popover 呈現,視覺與 DatePicker 一致。\n * Display 用 Intl.DateTimeFormat 格式化(跨 locale / 12h-24h 統一經過此 API)。\n *\n * ── Layout Family ──\n * CLAUDE.md 4-Family Model Family 4(Field control layout)消費者。結構繼承\n * `fieldWrapperStyles + [<editable>] [endIcon=Clock]`,視覺對齊 DatePicker(同\n * 「點擊觸發浮層」role:indicator 在 suffix slot,對齊 Material `endAdornment` /\n * Ant DatePicker / Polaris Picker 共識)。\n *\n * ── 實作基礎 ──\n * Trigger:`<div role=\"combobox\">` + `fieldWrapperStyles`(視覺仍是 Input wrapper,改為可點擊觸發浮層;\n * 2026-04-25 由 `<button>` 改 div 避 nested-interactive,對齊 Select / Combobox,鍵盤靠顯式 onKeyDown)\n * Popup:`Popover`(消費 overlay-surface pattern)\n * Panel 主體:自建 column picker(三欄 scrollable list),不引入第三方 time library\n *\n * ── 共用規則 ──\n * Mode / size / disabled / error 等詳見 `../Field/field-controls.spec.md`。\n */\n\n// ── Time ISO <-> parts conversion ───────────────────────────────────────────\n// Value 用 ISO time string(HH:mm 或 HH:mm:ss),local-time 語義(不帶時區/日期)。\n// 跟 DatePicker 的 ISO date string 策略一致。\n// `isoToTimeParts` / `timePartsToString` 改 import from time-columns(M17 SSOT)。\n\n// ── Display formatting ──────────────────────────────────────────────────────\n\nexport interface TimeFormatOptions {\n /** Intl.DateTimeFormat options(預設 { hour: '2-digit', minute: '2-digit', hour12: false }) */\n formatOptions?: Intl.DateTimeFormatOptions\n /** locale(預設 'en-US') */\n locale?: string\n}\n\n// 2026-07-06 D3 perf:Intl.DateTimeFormat 是標準庫最貴 constructor 之一(locale data\n// resolution)。formatTime 無 cheap path,view/readonly/edit 每 render 必建;DataTable time 欄\n// 轉發 config 時每 cell × 每次表格 re-render 重建。module-level cache 重用實例(DateTimeFormat\n// 無狀態可安全重用),key = locale|JSON.stringify(options)。行為 Δ=0。\nconst dtfCache = new Map<string, Intl.DateTimeFormat>()\nfunction getDateTimeFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + '|' + JSON.stringify(options)\n let fmt = dtfCache.get(key)\n if (!fmt) {\n fmt = new Intl.DateTimeFormat(locale, options)\n dtfCache.set(key, fmt)\n }\n return fmt\n}\n\nfunction formatTime(\n iso: string,\n options: TimeFormatOptions = {},\n): string {\n const parts = isoToTimeParts(iso)\n if (!parts) return iso\n const {\n formatOptions = { hour: '2-digit', minute: '2-digit', hour12: false },\n locale = 'en-US',\n } = options\n // 借用 Date 讓 Intl.DateTimeFormat 處理 locale / 12h-24h\n const d = new Date()\n d.setHours(parts.hours, parts.minutes, parts.seconds, 0)\n return getDateTimeFormatter(locale, formatOptions).format(d)\n}\n\n// ── Disabled time callback ──────────────────────────────────────────────────\n// `Step` / `buildRange` / `TimeColumn`(內部欄位實作)拔掉,改 import `TimeColumns` primitive。\n\n// code-quality-allow: dead-export — public API surface — consumer-exposed for future use\nexport interface DisabledTimeResult {\n disabledHours?: number[]\n disabledMinutes?: number[]\n disabledSeconds?: number[]\n}\n\n// ── Component props ─────────────────────────────────────────────────────────\n\nexport interface TimePickerProps\n extends TimeFormatOptions,\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n // 'defaultValue' 明確排除:本元件 controlled-only(time-picker.spec.md「Controlled-only\n // rationale」),不支援 uncontrolled 初始值 — 若不 Omit,HTMLAttributes 會讓 defaultValue\n // 通過型別卻靜默無效(不初始化 draft),與 spec contract 矛盾。\n 'onChange' | 'placeholder' | 'defaultValue'\n > {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n /** ISO time string(\"HH:mm\" 或 \"HH:mm:ss\") */\n value?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n className?: string\n disabled?: boolean\n /** 允許清空已選值 */\n clearable?: boolean\n /**\n * 是否顯示秒欄(三欄 picker)。預設 false(兩欄:時/分)。\n * format 自動對應:false → \"HH:mm\",true → \"HH:mm:ss\"。\n */\n showSeconds?: boolean\n /** 分鐘步進(會議常用 15)。預設 1 */\n minuteStep?: TimeStep\n /** 秒步進。預設 1。僅 showSeconds=true 有效 */\n secondStep?: TimeStep\n /** 動態 disabled 某些時/分/秒(基於已選其他欄位)。 */\n disabledTime?: (parts: TimeParts) => DisabledTimeResult\n /**\n * Suffix indicator(2026-05-05 v9 canonical fix):「點擊觸發浮層」indicator 一律 suffix\n * (對齊 DatePicker calendar / Material endAdornment)。預設 Clock,傳 null 可關閉。\n */\n endIcon?: LucideIcon | null\n /**\n * View 態是否渲 endIcon + Field naked wrapper(D-path opt-in,2026-05-08)\n * — DataTable cell view↔edit 像素級對齊用。預設 false(裸 span,backward compat)。\n * 設 true 時 view 也走 fieldWrapperStyles(naked variant)+ ItemSuffix Clock,\n * 與 edit 同 DOM 結構,消除 Layer-B padding mismatch。\n */\n showDisplayEndIcon?: boolean\n /** Initial open state(uncontrolled)— DataTable cell-as-input 1-step open canonical */\n defaultOpen?: boolean\n /** open state 變更 callback。DataTable cell-as-input 用:open=false → cell exit edit */\n onOpenChange?: (open: boolean) => void\n}\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst TimePicker = React.forwardRef<HTMLDivElement, TimePickerProps>(\n (\n {\n mode,\n variant: variantProp,\n error: errorProp = false,\n size: sizeProp,\n value,\n onChange,\n placeholder,\n className,\n disabled: disabledProp,\n clearable = false,\n showSeconds = false,\n minuteStep = 1,\n secondStep = 1,\n disabledTime,\n endIcon,\n showDisplayEndIcon = false,\n formatOptions,\n locale,\n defaultOpen = false,\n onOpenChange,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n 'aria-errormessage': ariaErrorMessageProp,\n ...props\n },\n ref,\n ) => {\n const fieldCtx = useFieldContext()\n const size = useResolvedFieldSize(sizeProp) // B 組 cascade fix\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode;修 <Field mode=\"view\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const emptyDisplay = useFieldEmptyDisplay()\n const variant: FieldVariantInternal = useResolvedFieldVariant(variantProp)\n const isEditable = resolvedMode === 'edit'\n // 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反 7+ 重複 ternary)\n const iconSize = ICON_SIZE[size as 'sm' | 'md' | 'lg']\n const EndIconCmp: LucideIcon | null =\n endIcon === null ? null : (endIcon ?? Clock)\n const defaultPlaceholder = showSeconds ? 'HH:MM:SS' : 'HH:MM'\n const resolvedPlaceholder = placeholder ?? defaultPlaceholder\n const showClear = clearable && !!value && isEditable\n const [open, setOpenState] = React.useState(defaultOpen)\n const setOpen = React.useCallback((next: boolean) => { setOpenState(next); onOpenChange?.(next) }, [onOpenChange])\n\n const currentParts = React.useMemo(() => isoToTimeParts(value), [value])\n // draft = panel 開啟期間的暫存:供 eager commit(每次欄選 commitDraft 即 commit)+ disabledTime 重算;OK 按鈕只 setOpen(false) 關 Panel,不做 commit\n const [draft, setDraft] = React.useState<TimeParts>(\n () => currentParts ?? { hours: 0, minutes: 0, seconds: 0 },\n )\n\n // 每次 popover 開啟時以當前 value 初始化 draft\n React.useEffect(() => {\n if (open) {\n setDraft(currentParts ?? { hours: 0, minutes: 0, seconds: 0 })\n }\n }, [open, currentParts])\n\n const disabledForColumns: TimeColumnsDisabled | undefined = React.useMemo(() => {\n if (!disabledTime) return undefined\n const res = disabledTime(draft)\n return {\n hours: res.disabledHours,\n minutes: res.disabledMinutes,\n seconds: res.disabledSeconds,\n }\n }, [disabledTime, draft])\n\n const commitDraft = (next: TimeParts) => {\n setDraft(next)\n onChange?.(timePartsToString(next, showSeconds))\n }\n\n const handleNow = () => {\n const now = new Date()\n // 按照 minuteStep / secondStep 對齊。\n // 2026-07-05 邊界修正(deep-audit A.1b):Math.round 進位到 60 時,舊 `Math.min(round, 59)`\n // 會產生 59 這種「不對齊 step、也不在 column values 內」的值(如 53 分 @ step=15 → 59)\n // → panel 該欄失去 selected 高亮。改 clamp 到 ≤59 的最大 step 對齊值(= buildRange 產出的\n // 最後一格,如 45),不跨小時進位 — 保持「此刻 = commit 當前時間(step 對齊)」語意\n // (time-picker.spec.md「每次欄位選取當下即 commit」段)。\n const alignToStep = (raw: number, step: number) => {\n const rounded = Math.round(raw / step) * step\n return rounded > 59 ? Math.floor(59 / step) * step : rounded\n }\n const next: TimeParts = {\n hours: now.getHours(),\n minutes: alignToStep(now.getMinutes(), minuteStep),\n seconds: showSeconds ? alignToStep(now.getSeconds(), secondStep) : 0,\n }\n commitDraft(next)\n setOpen(false)\n }\n\n // mode='view'(Phase B2 2026-05-05):純內容輸出 — 對齊原 TimePickerDisplay sub-component(retired)。\n // Default(showDisplayEndIcon=false):無 Field wrapper / 無 Clock icon — backward compat 裸 span。\n // Opt-in(showDisplayEndIcon=true,2026-05-08 D-path):Field naked wrapper + ItemSuffix Clock,\n // 與 edit 同結構消除 cell view↔edit 像素偏移(Layer-B padding mismatch)。\n if (resolvedMode === 'view') {\n // 2026-07-16 DA3 fix:view 分支補 {...props} spread(aria-label 等 DOM attr 原本靜默丟失;\n // Switch 同型 2026-07-04 已修,本檔漏 — M10 同型)。\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) view typography canonical):bare span 套\n // `fieldDisplayTextClass(size)`(sm/md→text-body,lg→text-body-lg)— 對齊 Field family 統一。\n if (!value) return <span {...props} ref={ref as React.Ref<HTMLSpanElement>} className={cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className)}>{emptyDisplay}</span>\n return <span {...props} ref={ref as React.Ref<HTMLSpanElement>} className={cn(fieldDisplayTextClass(size), 'truncate', className)}>{formatTime(value, { formatOptions, locale })}</span>\n }\n return (\n <div\n ref={ref}\n {...props}\n className={cn(fieldWrapperStyles({ mode: 'view', variant, size }), className)}\n data-field-mode=\"view\"\n >\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && fieldEmptyColorClass(resolvedMode))}>\n {value ? formatTime(value, { formatOptions, locale }) : emptyDisplay}\n </span>\n {EndIconCmp && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )}\n </div>\n )\n }\n\n // readonly / disabled\n if (!isEditable) {\n return (\n <div\n // 2026-07-16 DA3 fix:非-edit 分支補 ref 轉發(forwardRef<HTMLDivElement> 原本只有 edit\n // 與 bare-span view 接 ref,readonly/disabled 及 endIcon-view div 靜默丟失 — 同 view props 漏接)。\n ref={ref}\n className={cn(fieldWrapperStyles({ mode: resolvedMode, variant: variant, size }), className)}\n data-field-mode={resolvedMode}\n aria-disabled={resolvedMode === 'disabled' ? true : undefined}\n {...(props as React.HTMLAttributes<HTMLDivElement>)}\n >\n <span\n className={cn(\n 'flex-1 min-w-0',\n resolvedMode === 'disabled' && 'text-fg-disabled',\n )}\n >\n {value\n ? formatTime(value, { formatOptions, locale })\n : <span className={fieldEmptyColorClass(resolvedMode)}>{emptyDisplay}</span>\n }\n </span>\n {/* 2026-06-26 類型身份 indicator:edit 顯示 / readonly 不顯示 / disabled 保留(fg-disabled);naked cell 依 showDisplayEndIcon=isEditable(修 disabled cell 漏顯 bug)*/}\n {EndIconCmp && (variant === 'naked' ? showDisplayEndIcon : resolvedMode === 'disabled') && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp\n size={iconSize}\n className={resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'}\n aria-hidden\n />\n </ItemSuffix>\n )}\n </div>\n )\n }\n\n const displayText = value\n ? formatTime(value, { formatOptions, locale })\n : <span className=\"text-fg-muted\">{resolvedPlaceholder}</span>\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n {/* a11y(2026-04-25 nested-interactive fix):trigger 改 <div role='combobox'>\n (對齊 Select / Combobox 同 pattern),原 <button> 會與內層 ItemInlineAction\n 清除 button 構成 nested-interactive。\n 2026-06-01 鍵盤開啟修正:Radix PopoverTrigger 只 compose onClick\n (@radix-ui/react-popover index.js:145),不 inject 任何 onKeyDown。原生 <button>\n 靠瀏覽器在 Enter/Space 自動派發 click 才能開;但本 trigger 是 <div role=combobox>,\n div 不會自動派發 click → 鍵盤使用者打不開 panel。故顯式加 onKeyDown\n (對齊 select.tsx:609-619 既有 canonical + WAI-ARIA APG combobox required keys)。 */}\n <PopoverTrigger asChild>\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled || undefined}\n aria-labelledby={fieldCtx?.labelId}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n onKeyDown={(e) => {\n if (disabled) return\n // 2026-07-14 dim-10 修:內層「清除時間」ItemInlineAction button 的 Enter/Space\n // 會 bubble 到本 handler 被 preventDefault 吞掉(按鈕 activation 被取消、panel 反而開)。\n // trigger 鍵盤邏輯只在事件源自 trigger div 本身時執行。\n if (e.target !== e.currentTarget) return\n // Enter / Space / ArrowDown / Alt+ArrowDown → 開 panel(APG combobox required + Select canonical)\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n e.preventDefault()\n setOpen(true)\n }\n // Escape → 關(Radix Content 已自帶,trigger 補位對齊 select.tsx:597)\n if (e.key === 'Escape') setOpen(false)\n }}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }),\n 'text-left cursor-pointer',\n 'focus-visible:outline-none',\n className,\n )}\n {...props}\n >\n <span className={cn(bareInputStyles, 'truncate', !value && 'text-fg-muted')}>\n {displayText}\n </span>\n {showClear && (\n <ItemInlineAction\n size={size ?? 'md'}\n action={{\n icon: X,\n label: '清除時間', // i18n-allow: DS default inline-action label\n onClick: (e) => {\n e?.stopPropagation()\n onChange?.('')\n },\n }}\n />\n )}\n {EndIconCmp && (\n <ItemSuffix className=\"pointer-events-none\">\n <EndIconCmp size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )}\n </div>\n </PopoverTrigger>\n {/* a11y(2026-07-14 dim-10):Radix PopoverContent 輸出 role=\"dialog\",無 title 需\n accessible name(WAI-ARIA dialog required);對齊 date-picker.tsx:1040「日期區間選擇」同款 DS default。 */}\n <PopoverContent className=\"w-auto p-0\" align=\"start\" aria-label=\"選擇時間\" /* i18n-allow: DS default dialog label */>\n {/* Panel 對齊 ref/timepicker.png:2-3 個 SelectMenu 式欄位並排,分隔線分開。\n Width 依欄數由 TimeColumns 決定:2 欄 w-40 / 3 欄 w-60。\n Height 由 wrapper 控:216px 預設(扣 footer 後 list 約可見 5-6 items)。\n TimeColumns 本身 h-full,parent 控 height — 讓 DatePicker showTime / Range 可\n 用 flex-row items-stretch 自動同 calendar 高。 */}\n <div className=\"flex flex-col h-[216px]\">\n <TimeColumns\n value={draft}\n onChange={commitDraft}\n showSeconds={showSeconds}\n minuteStep={minuteStep}\n secondStep={secondStep}\n disabled={disabledForColumns}\n // 2026-05-06 v9.1 M25 chain fix:TimeColumns 自然高 = 24 buttons × ~28.7px = 688px\n // 會撐破 parent h-[216px]。flex-1 + min-h-0 讓 TimeColumns 取 parent 剩餘空間\n // (216 − footer ≈53px ≈ 163px)→ ScrollArea h-full 才能正確收斂 →\n // listbox scrollIntoView 找對 nearest scrollable ancestor(內部 viewport),\n // 不會走到 document body 把 popover 內容推出畫面(user 報「hours 欄空白」根因)。\n className=\"flex-1 min-h-0\"\n />\n {/* Footer:消費 SurfaceFooter SSOT(border-t + py-tight + gap-2 + shrink-0 + justify-end)。\n px override 回 layout-space-tight,因 TimePicker 滿欄 column 面板無 chrome-padded body\n 內縮邊可對齊(footer px = body 內縮 原則;column-selector 數字置中、零內距,\n 見 time-picker.spec.md)。此刻 mr-auto 把確定推右,視覺等同原 justify-between\n —— 純結構消費 overlay-surface canonical(overlay-surface.spec.md:17「不自寫 padding token」),零視覺變化。 */}\n <SurfaceFooter className=\"px-[var(--layout-space-tight)]\">\n <Button variant=\"text\" size=\"sm\" onClick={handleNow} className=\"mr-auto\">\n 此刻\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n 確定\n </Button>\n </SurfaceFooter>\n </div>\n </PopoverContent>\n </Popover>\n )\n },\n)\nTimePicker.displayName = 'TimePicker'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const timePickerMeta = {\n component: 'TimePicker',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n // states 對齊真實視覺態:trigger 與 panel item 皆無 'active'(按下)專屬視覺態(2026-07-04 audit 對齊);\n // 'selected' = panel item 持續選中(bg-neutral-selected,time-columns.tsx isSelected;2026-07-07 詞彙統一補列)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n // panel selected 走 bg-neutral-selected(time-columns.tsx isSelected;spec「欄內 item 狀態」),非 bg-primary。\n bg: ['bg-neutral-hover', 'bg-neutral-selected', 'bg-transparent'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-foreground'],\n ring: [],\n },\n} as const\n\nexport { TimePicker }\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/Tooltip/tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAW3D,QAAA,MAAM,eAAe,GAAI,6BAAqD,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,4CAEnI,CAAA;AAED,QAAA,MAAM,OAAO,GAAI,6BAAqD,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,4CAEvH,CAAA;AAED,QAAA,MAAM,cAAc,gHAA2B,CAAA;AAE/C,QAAA,MAAM,cAAc,gKA4BlB,CAAA;AAKF,eAAO,MAAM,WAAW;;;;;;;;;;;CAed,CAAA;AAEV,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/Tooltip/tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAW3D,QAAA,MAAM,eAAe,GAAI,6BAAqD,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,4CAEnI,CAAA;AAED,QAAA,MAAM,OAAO,GAAI,6BAAqD,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,4CAEvH,CAAA;AAED,QAAA,MAAM,cAAc,gHAA2B,CAAA;AAE/C,QAAA,MAAM,cAAc,gKAsClB,CAAA;AAKF,eAAO,MAAM,WAAW;;;;;;;;;;;CAed,CAAA;AAEV,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
@@ -8,29 +8,33 @@ import { overlayMotion } from "../../tokens/motion/overlay-motion.js";
8
8
  const TooltipProvider = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }) => /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, ...props });
9
9
  const Tooltip = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }) => /* @__PURE__ */ jsx(TooltipPrimitive.Root, { delayDuration, ...props });
10
10
  const TooltipTrigger = TooltipPrimitive.Trigger;
11
- const TooltipContent = React.forwardRef(({ className, sideOffset = OVERLAY_SIDE_OFFSET, collisionPadding = OVERLAY_COLLISION_PADDING, style, children, ...props }, ref) => (
12
- // collisionPadding default 8px:避免 tooltip viewport 邊(Radix avoidCollisions 預設 true padding 0 會貼邊)
13
- // 消費 OVERLAY_COLLISION_PADDING overlay 家族 canonical(與 Popover 一致;HoverCard 特例 12 補 rounding)避免 viewport edge clipping
14
- /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
15
- TooltipPrimitive.Content,
16
- {
17
- ref,
18
- sideOffset,
19
- collisionPadding,
20
- className: cn(
21
- "z-50 overflow-hidden rounded-md px-3 py-2 text-body font-normal text-on-emphasis bg-tooltip max-w-[280px] break-words",
22
- overlayMotion,
23
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
24
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
25
- "origin-[var(--radix-tooltip-content-transform-origin)]",
26
- className
27
- ),
28
- style: { boxShadow: "var(--elevation-200)", ...style },
29
- ...props,
30
- children: /* @__PURE__ */ jsx("div", { "data-theme": "dark", className: "contents", children })
31
- }
32
- ) })
33
- ));
11
+ const TooltipContent = React.forwardRef(({ className, sideOffset = OVERLAY_SIDE_OFFSET, collisionPadding = OVERLAY_COLLISION_PADDING, style, children, ...props }, ref) => {
12
+ const isEmptyContent = children == null || children === false || typeof children === "string" && children.trim() === "";
13
+ if (isEmptyContent) return null;
14
+ return (
15
+ // collisionPadding default 8px:避免 tooltip 貼 viewport 邊(Radix avoidCollisions 預設 true 但 padding 0 會貼邊)
16
+ // 消費 OVERLAY_COLLISION_PADDING overlay 家族 canonical(與 Popover 一致;HoverCard 特例 12 補 rounding)避免 viewport edge clipping
17
+ /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
18
+ TooltipPrimitive.Content,
19
+ {
20
+ ref,
21
+ sideOffset,
22
+ collisionPadding,
23
+ className: cn(
24
+ "z-50 overflow-hidden rounded-md px-3 py-2 text-body font-normal text-on-emphasis bg-tooltip max-w-[280px] break-words",
25
+ overlayMotion,
26
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
27
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
28
+ "origin-[var(--radix-tooltip-content-transform-origin)]",
29
+ className
30
+ ),
31
+ style: { boxShadow: "var(--elevation-200)", ...style },
32
+ ...props,
33
+ children: /* @__PURE__ */ jsx("div", { "data-theme": "dark", className: "contents", children })
34
+ }
35
+ ) })
36
+ );
37
+ });
34
38
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
35
39
  const tooltipMeta = {
36
40
  component: "Tooltip",
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","sources":["../../../src/components/Tooltip/tooltip.tsx"],"sourcesContent":["import * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"@/lib/utils\"\nimport { OVERLAY_SIDE_OFFSET, OVERLAY_COLLISION_PADDING } from \"@/design-system/tokens/elevation/overlay-geometry\"\nimport { MOTION_DELAY_PLAIN_MS } from \"@/design-system/tokens/motion/motion\"\nimport { overlayMotion } from \"@/design-system/tokens/motion/overlay-motion\"\n\n// 2026-05-18 ship per user 拍板 #3A:Tooltip Provider 預設 delayDuration 對齊 motion token SSOT。\n// Radix 預設 700ms 過保守(被 Material 150-200 / MUI 100 / Atlassian 300 集體驗證),DS 統一用\n// `--motion-delay-plain` (500ms,JS mirror `MOTION_DELAY_PLAIN_MS`)。Consumer 仍可 per-instance override。\n// 2026-05-21 D5 Phase B codex 抓 comment 200 vs token 500 drift → 註解 500ms 對齊 motion.css:27 SSOT。\nconst TooltipProvider = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) => (\n <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />\n)\n\nconst Tooltip = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) => (\n <TooltipPrimitive.Root delayDuration={delayDuration} {...props} />\n)\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = OVERLAY_SIDE_OFFSET, collisionPadding = OVERLAY_COLLISION_PADDING, style, children, ...props }, ref) => (\n // collisionPadding default 8px:避免 tooltip 貼 viewport 邊(Radix avoidCollisions 預設 true 但 padding 0 會貼邊)\n // 消費 OVERLAY_COLLISION_PADDING overlay 家族 canonical(與 Popover 一致;HoverCard 特例 12 補 rounding)避免 viewport edge clipping\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n // Density:繼承 page density(2026-06-15 canonical)。Tooltip padding 寫死 px-3 py-2、內容 text-body,\n // 不消費任何 density / layout-space token → 鎖 density 對它是 inert(原 data-density=\"md\" 是 409b91da\n // a11y 批次「對齊 Popover」順手加,非設計決策)→ 移除,讓全浮層行為一致(全繼承 page)。\n className={cn(\n \"z-50 overflow-hidden rounded-md px-3 py-2 text-body font-normal text-on-emphasis bg-tooltip max-w-[280px] break-words\",\n overlayMotion,\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"origin-[var(--radix-tooltip-content-transform-origin)]\",\n className\n )}\n style={{ boxShadow: 'var(--elevation-200)', ...style }}\n {...props}\n >\n <div data-theme=\"dark\" className=\"contents\">{children}</div>\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const tooltipMeta = {\n component: 'Tooltip',\n family: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default'], // 2026-06-11 R2:Tooltip 浮層本身無互動 state(anatomy rationale L9-12),\n tokens: {\n bg: [],\n fg: [],\n ring: [],\n },\n} as const\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"],"names":[],"mappings":";;;;;;;AAYA,MAAM,kBAAkB,CAAC,EAAE,gBAAgB,uBAAuB,GAAG,MAAA,MACnE,oBAAC,iBAAiB,UAAjB,EAA0B,eAA+B,GAAG,MAAA,CAAO;AAGtE,MAAM,UAAU,CAAC,EAAE,gBAAgB,uBAAuB,GAAG,MAAA,MAC3D,oBAAC,iBAAiB,MAAjB,EAAsB,eAA+B,GAAG,MAAA,CAAO;AAGlE,MAAM,iBAAiB,iBAAiB;AAExC,MAAM,iBAAiB,MAAM,WAG3B,CAAC,EAAE,WAAW,aAAa,qBAAqB,mBAAmB,2BAA2B,OAAO,UAAU,GAAG,SAAS;AAAA;AAAA;AAAA,EAG3H,oBAAC,iBAAiB,QAAjB,EACC,UAAA;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MAIA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,OAAO,EAAE,WAAW,wBAAwB,GAAG,MAAA;AAAA,MAC9C,GAAG;AAAA,MAEJ,8BAAC,OAAA,EAAI,cAAW,QAAO,WAAU,YAAY,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA,EACxD,CACF;AAAA,CACD;AACD,eAAe,cAAc,iBAAiB,QAAQ;AAI/C,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EACR,UAAU,CAAA;AAAA,EAGV,OAAO,CAAA;AAAA,EAGP,QAAQ,CAAC,SAAS;AAAA;AAAA,EAClB,QAAQ;AAAA,IACN,IAAI,CAAA;AAAA,IACJ,IAAI,CAAA;AAAA,IACJ,MAAM,CAAA;AAAA,EAAC;AAEX;"}
1
+ {"version":3,"file":"tooltip.js","sources":["../../../src/components/Tooltip/tooltip.tsx"],"sourcesContent":["import * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"@/lib/utils\"\nimport { OVERLAY_SIDE_OFFSET, OVERLAY_COLLISION_PADDING } from \"@/design-system/tokens/elevation/overlay-geometry\"\nimport { MOTION_DELAY_PLAIN_MS } from \"@/design-system/tokens/motion/motion\"\nimport { overlayMotion } from \"@/design-system/tokens/motion/overlay-motion\"\n\n// 2026-05-18 ship per user 拍板 #3A:Tooltip Provider 預設 delayDuration 對齊 motion token SSOT。\n// Radix 預設 700ms 過保守(被 Material 150-200 / MUI 100 / Atlassian 300 集體驗證),DS 統一用\n// `--motion-delay-plain` (500ms,JS mirror `MOTION_DELAY_PLAIN_MS`)。Consumer 仍可 per-instance override。\n// 2026-05-21 D5 Phase B codex 抓 comment 200 vs token 500 drift → 註解 500ms 對齊 motion.css:27 SSOT。\nconst TooltipProvider = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) => (\n <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />\n)\n\nconst Tooltip = ({ delayDuration = MOTION_DELAY_PLAIN_MS, ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) => (\n <TooltipPrimitive.Root delayDuration={delayDuration} {...props} />\n)\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = OVERLAY_SIDE_OFFSET, collisionPadding = OVERLAY_COLLISION_PADDING, style, children, ...props }, ref) => {\n // 空內容不掛浮層:children 為 null / undefined / false / 空字串時不渲染帶 padding 的空\n // role=\"tooltip\" 殼(見 spec「邊界狀態」)。Tooltip 是資訊補救機制,無補充內容即不出現,\n // trigger 由 TooltipTrigger 原樣保留。\n const isEmptyContent =\n children == null ||\n children === false ||\n (typeof children === 'string' && children.trim() === '')\n if (isEmptyContent) return null\n return (\n // collisionPadding default 8px:避免 tooltip 貼 viewport 邊(Radix avoidCollisions 預設 true 但 padding 0 會貼邊)\n // 消費 OVERLAY_COLLISION_PADDING overlay 家族 canonical(與 Popover 一致;HoverCard 特例 12 補 rounding)避免 viewport edge clipping\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n // Density:繼承 page density(2026-06-15 canonical)。Tooltip padding 寫死 px-3 py-2、內容 text-body,\n // 不消費任何 density / layout-space token → 鎖 density 對它是 inert(原 data-density=\"md\" 是 409b91da\n // a11y 批次「對齊 Popover」順手加,非設計決策)→ 移除,讓全浮層行為一致(全繼承 page)。\n className={cn(\n \"z-50 overflow-hidden rounded-md px-3 py-2 text-body font-normal text-on-emphasis bg-tooltip max-w-[280px] break-words\",\n overlayMotion,\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"origin-[var(--radix-tooltip-content-transform-origin)]\",\n className\n )}\n style={{ boxShadow: 'var(--elevation-200)', ...style }}\n {...props}\n >\n <div data-theme=\"dark\" className=\"contents\">{children}</div>\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n})\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const tooltipMeta = {\n component: 'Tooltip',\n family: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default'], // 2026-06-11 R2:Tooltip 浮層本身無互動 state(anatomy rationale L9-12),\n tokens: {\n bg: [],\n fg: [],\n ring: [],\n },\n} as const\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"],"names":[],"mappings":";;;;;;;AAYA,MAAM,kBAAkB,CAAC,EAAE,gBAAgB,uBAAuB,GAAG,MAAA,MACnE,oBAAC,iBAAiB,UAAjB,EAA0B,eAA+B,GAAG,MAAA,CAAO;AAGtE,MAAM,UAAU,CAAC,EAAE,gBAAgB,uBAAuB,GAAG,MAAA,MAC3D,oBAAC,iBAAiB,MAAjB,EAAsB,eAA+B,GAAG,MAAA,CAAO;AAGlE,MAAM,iBAAiB,iBAAiB;AAExC,MAAM,iBAAiB,MAAM,WAG3B,CAAC,EAAE,WAAW,aAAa,qBAAqB,mBAAmB,2BAA2B,OAAO,UAAU,GAAG,MAAA,GAAS,QAAQ;AAInI,QAAM,iBACJ,YAAY,QACZ,aAAa,SACZ,OAAO,aAAa,YAAY,SAAS,KAAA,MAAW;AACvD,MAAI,eAAgB,QAAO;AAC3B;AAAA;AAAA;AAAA,IAGA,oBAAC,iBAAiB,QAAjB,EACC,UAAA;AAAA,MAAC,iBAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QAIA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO,EAAE,WAAW,wBAAwB,GAAG,MAAA;AAAA,QAC9C,GAAG;AAAA,QAEJ,8BAAC,OAAA,EAAI,cAAW,QAAO,WAAU,YAAY,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA,EACxD,CACF;AAAA;AAEF,CAAC;AACD,eAAe,cAAc,iBAAiB,QAAQ;AAI/C,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EACR,UAAU,CAAA;AAAA,EAGV,OAAO,CAAA;AAAA,EAGP,QAAQ,CAAC,SAAS;AAAA;AAAA,EAClB,QAAQ;AAAA,IACN,IAAI,CAAA;AAAA,IACJ,IAAI,CAAA;AAAA,IACJ,MAAM,CAAA;AAAA,EAAC;AAEX;"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree-view.d.ts","sourceRoot":"","sources":["../../../src/components/TreeView/tree-view.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree-view.d.ts","sourceRoot":"","sources":["../../../src/components/TreeView/tree-view.tsx"],"names":[],"mappings":"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"}
@@ -74,6 +74,15 @@ const TreeView = React.forwardRef(
74
74
  children,
75
75
  ...props
76
76
  }, ref) => {
77
+ const ariaLabel = props["aria-label"];
78
+ const ariaLabelledby = props["aria-labelledby"];
79
+ React.useEffect(() => {
80
+ if (process.env.NODE_ENV !== "production" && ariaLabel == null && ariaLabelledby == null) {
81
+ console.warn(
82
+ '[DS] TreeView:role="tree" 缺 accessible name — 請傳 aria-label(直接字串)或 aria-labelledby(指向可見標題 id)其一。兩者皆缺時螢幕閱讀器只讀出「tree」無法辨識用途(WAI-ARIA APG 要求 role="tree" 具 accessible name)。'
83
+ );
84
+ }
85
+ }, [ariaLabel, ariaLabelledby]);
77
86
  const [internalExpanded, setInternalExpanded] = React.useState(
78
87
  () => new Set(defaultExpandedIds)
79
88
  );
@@ -461,6 +470,13 @@ const TreeView = React.forwardRef(
461
470
  (e) => {
462
471
  isKeyboardRef.current = true;
463
472
  if (!treeRef.current) return;
473
+ const keyTarget = e.target;
474
+ if (keyTarget && keyTarget !== e.currentTarget) {
475
+ const interactive = keyTarget.closest(
476
+ 'a[href], button, input, select, textarea, [contenteditable="true"], [tabindex]:not([tabindex="-1"])'
477
+ );
478
+ if (interactive && interactive !== e.currentTarget) return;
479
+ }
464
480
  if ((e.metaKey || e.ctrlKey) && e.shiftKey && REORDER_ARROW_KEYS.includes(e.key)) {
465
481
  if (!draggable) return;
466
482
  e.preventDefault();