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

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 (622) hide show
  1. package/CLAUDE.md +8 -8
  2. package/README.md +3 -2
  3. package/dist/components/Alert/alert.js.map +1 -1
  4. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
  5. package/dist/components/AppShell/app-shell.d.ts +1 -1
  6. package/dist/components/AppShell/app-shell.d.ts.map +1 -1
  7. package/dist/components/AppShell/app-shell.js +22 -2
  8. package/dist/components/AppShell/app-shell.js.map +1 -1
  9. package/dist/components/Avatar/avatar.d.ts.map +1 -1
  10. package/dist/components/Avatar/avatar.js +4 -4
  11. package/dist/components/Avatar/avatar.js.map +1 -1
  12. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -1
  13. package/dist/components/Breadcrumb/breadcrumb.js +1 -1
  14. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
  15. package/dist/components/Button/button.d.ts +2 -2
  16. package/dist/components/Button/button.d.ts.map +1 -1
  17. package/dist/components/Button/button.js +12 -3
  18. package/dist/components/Button/button.js.map +1 -1
  19. package/dist/components/Calendar/calendar.d.ts +13 -5
  20. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  21. package/dist/components/Calendar/calendar.js +7 -1
  22. package/dist/components/Calendar/calendar.js.map +1 -1
  23. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  24. package/dist/components/Carousel/carousel.js +8 -3
  25. package/dist/components/Carousel/carousel.js.map +1 -1
  26. package/dist/components/Chart/chart.d.ts.map +1 -1
  27. package/dist/components/Chart/chart.js +1 -0
  28. package/dist/components/Chart/chart.js.map +1 -1
  29. package/dist/components/Checkbox/checkbox.d.ts +1 -1
  30. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  31. package/dist/components/Checkbox/checkbox.js +8 -4
  32. package/dist/components/Checkbox/checkbox.js.map +1 -1
  33. package/dist/components/Chip/chip.d.ts +1 -1
  34. package/dist/components/Chip/chip.d.ts.map +1 -1
  35. package/dist/components/Chip/chip.js.map +1 -1
  36. package/dist/components/Coachmark/coachmark.d.ts +10 -3
  37. package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
  38. package/dist/components/Coachmark/coachmark.js.map +1 -1
  39. package/dist/components/Combobox/combobox.d.ts +5 -1
  40. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  41. package/dist/components/Combobox/combobox.js +30 -13
  42. package/dist/components/Combobox/combobox.js.map +1 -1
  43. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  44. package/dist/components/DataTable/cell-registry.js +53 -62
  45. package/dist/components/DataTable/cell-registry.js.map +1 -1
  46. package/dist/components/DataTable/column-types.d.ts +10 -4
  47. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  48. package/dist/components/DataTable/column-types.js.map +1 -1
  49. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +1 -1
  50. package/dist/components/DataTable/data-table-column-visibility-panel.js +183 -0
  51. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -0
  52. package/dist/components/DataTable/data-table-filter-group.d.ts +47 -0
  53. package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -0
  54. package/dist/components/DataTable/data-table-filter-group.js +154 -0
  55. package/dist/components/DataTable/data-table-filter-group.js.map +1 -0
  56. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  57. package/dist/components/DataTable/data-table-filter-panel.js +285 -0
  58. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -0
  59. package/dist/components/DataTable/data-table-filter-value-picker.d.ts +29 -0
  60. package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -0
  61. package/dist/components/DataTable/data-table-filter-value-picker.js +187 -0
  62. package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -0
  63. package/dist/components/DataTable/data-table-interaction-layer.d.ts +11 -15
  64. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -1
  65. package/dist/components/DataTable/data-table-interaction-layer.js +1 -3
  66. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  67. package/dist/components/DataTable/data-table-sort-manager.js +140 -0
  68. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -0
  69. package/dist/components/DataTable/data-table.d.ts +5 -6
  70. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  71. package/dist/components/DataTable/data-table.js +36 -15
  72. package/dist/components/DataTable/data-table.js.map +1 -1
  73. package/dist/components/DataTable/filter-operators.js +140 -0
  74. package/dist/components/DataTable/filter-operators.js.map +1 -0
  75. package/dist/components/DataTable/filter-tree.js +312 -0
  76. package/dist/components/DataTable/filter-tree.js.map +1 -0
  77. package/dist/components/DataTable/index.d.ts +3 -0
  78. package/dist/components/DataTable/index.d.ts.map +1 -1
  79. package/dist/components/DataTable/index.js +12 -1
  80. package/dist/components/DataTable/index.js.map +1 -1
  81. package/dist/components/DataTable/lib/column-meta.js +25 -0
  82. package/dist/components/DataTable/lib/column-meta.js.map +1 -0
  83. package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
  84. package/dist/components/DateGrid/date-grid.js +3 -1
  85. package/dist/components/DateGrid/date-grid.js.map +1 -1
  86. package/dist/components/DatePicker/date-picker.d.ts +7 -1
  87. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  88. package/dist/components/DatePicker/date-picker.js +105 -74
  89. package/dist/components/DatePicker/date-picker.js.map +1 -1
  90. package/dist/components/Dialog/dialog.d.ts +20 -3
  91. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  92. package/dist/components/Dialog/dialog.js +38 -20
  93. package/dist/components/Dialog/dialog.js.map +1 -1
  94. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  95. package/dist/components/DropdownMenu/dropdown-menu.js +3 -1
  96. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  97. package/dist/components/Field/field-context.d.ts +45 -5
  98. package/dist/components/Field/field-context.d.ts.map +1 -1
  99. package/dist/components/Field/field-context.js +19 -0
  100. package/dist/components/Field/field-context.js.map +1 -1
  101. package/dist/components/Field/field-edit-keys.d.ts +21 -0
  102. package/dist/components/Field/field-edit-keys.d.ts.map +1 -0
  103. package/dist/components/Field/field-edit-keys.js +19 -0
  104. package/dist/components/Field/field-edit-keys.js.map +1 -0
  105. package/dist/components/Field/field-types.d.ts +20 -1
  106. package/dist/components/Field/field-types.d.ts.map +1 -1
  107. package/dist/components/Field/field-types.js.map +1 -1
  108. package/dist/components/Field/field-wrapper.d.ts +3 -2
  109. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  110. package/dist/components/Field/field-wrapper.js +38 -39
  111. package/dist/components/Field/field-wrapper.js.map +1 -1
  112. package/dist/components/Field/field.d.ts +2 -1
  113. package/dist/components/Field/field.d.ts.map +1 -1
  114. package/dist/components/Field/field.js.map +1 -1
  115. package/dist/components/Field/index.d.ts +1 -0
  116. package/dist/components/Field/index.d.ts.map +1 -1
  117. package/dist/components/Field/index.js +2 -0
  118. package/dist/components/Field/index.js.map +1 -1
  119. package/dist/components/FieldControlGroup/field-control-group.d.ts +1 -1
  120. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
  121. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  122. package/dist/components/FileItem/file-item.js +1 -1
  123. package/dist/components/FileItem/file-item.js.map +1 -1
  124. package/dist/components/FileUpload/file-upload.d.ts +1 -1
  125. package/dist/components/FileUpload/file-upload.js.map +1 -1
  126. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  127. package/dist/components/FileViewer/file-viewer.js +7 -2
  128. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  129. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -1
  130. package/dist/components/FileViewer/image-renderer.js +22 -1
  131. package/dist/components/FileViewer/image-renderer.js.map +1 -1
  132. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  133. package/dist/components/HoverCard/hover-card.js +5 -3
  134. package/dist/components/HoverCard/hover-card.js.map +1 -1
  135. package/dist/components/InlineEdit/index.d.ts +2 -0
  136. package/dist/components/InlineEdit/index.d.ts.map +1 -0
  137. package/dist/components/InlineEdit/index.js +5 -0
  138. package/dist/components/InlineEdit/index.js.map +1 -0
  139. package/dist/components/InlineEdit/inline-edit.d.ts +59 -0
  140. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -0
  141. package/dist/components/InlineEdit/inline-edit.js +164 -0
  142. package/dist/components/InlineEdit/inline-edit.js.map +1 -0
  143. package/dist/components/Input/input.d.ts +6 -11
  144. package/dist/components/Input/input.d.ts.map +1 -1
  145. package/dist/components/Input/input.js +43 -13
  146. package/dist/components/Input/input.js.map +1 -1
  147. package/dist/components/LinkInput/link-input.d.ts +2 -2
  148. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  149. package/dist/components/LinkInput/link-input.js +6 -5
  150. package/dist/components/LinkInput/link-input.js.map +1 -1
  151. package/dist/components/Menu/menu-item.d.ts +14 -2
  152. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  153. package/dist/components/Menu/menu-item.js +25 -3
  154. package/dist/components/Menu/menu-item.js.map +1 -1
  155. package/dist/components/NumberInput/number-input.d.ts +3 -3
  156. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  157. package/dist/components/NumberInput/number-input.js +6 -5
  158. package/dist/components/NumberInput/number-input.js.map +1 -1
  159. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
  160. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -6
  161. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  162. package/dist/components/Pagination/pagination.js +1 -1
  163. package/dist/components/Pagination/pagination.js.map +1 -1
  164. package/dist/components/PeoplePicker/index.js +7 -1
  165. package/dist/components/PeoplePicker/index.js.map +1 -1
  166. package/dist/components/PeoplePicker/people-picker.d.ts +9 -2
  167. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  168. package/dist/components/PeoplePicker/people-picker.js +23 -10
  169. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  170. package/dist/components/PeoplePicker/person-display.d.ts +6 -3
  171. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
  172. package/dist/components/PeoplePicker/person-display.js +19 -14
  173. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  174. package/dist/components/Popover/popover.d.ts.map +1 -1
  175. package/dist/components/Popover/popover.js +3 -1
  176. package/dist/components/Popover/popover.js.map +1 -1
  177. package/dist/components/ProfileCard/profile-card.d.ts +2 -2
  178. package/dist/components/ProfileCard/profile-card.js +3 -3
  179. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  180. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  181. package/dist/components/RadioGroup/radio-group.js +15 -9
  182. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  183. package/dist/components/ScrollArea/scroll-area.d.ts +11 -1
  184. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  185. package/dist/components/ScrollArea/scroll-area.js +6 -3
  186. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  187. package/dist/components/Select/select.d.ts +46 -5
  188. package/dist/components/Select/select.d.ts.map +1 -1
  189. package/dist/components/Select/select.js +109 -28
  190. package/dist/components/Select/select.js.map +1 -1
  191. package/dist/components/SelectMenu/select-menu.d.ts +3 -1
  192. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  193. package/dist/components/SelectMenu/select-menu.js +8 -1
  194. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  195. package/dist/components/SelectionControl/boolean-value.d.ts +11 -0
  196. package/dist/components/SelectionControl/boolean-value.d.ts.map +1 -0
  197. package/dist/components/SelectionControl/boolean-value.js +23 -0
  198. package/dist/components/SelectionControl/boolean-value.js.map +1 -0
  199. package/dist/components/SelectionControl/index.d.ts +1 -0
  200. package/dist/components/SelectionControl/index.d.ts.map +1 -1
  201. package/dist/components/SelectionControl/index.js +2 -0
  202. package/dist/components/SelectionControl/index.js.map +1 -1
  203. package/dist/components/Sheet/index.js +2 -1
  204. package/dist/components/Sheet/sheet.d.ts +7 -1
  205. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  206. package/dist/components/Sheet/sheet.js +5 -2
  207. package/dist/components/Sheet/sheet.js.map +1 -1
  208. package/dist/components/Sidebar/sidebar.d.ts +9 -4
  209. package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
  210. package/dist/components/Sidebar/sidebar.js +8 -10
  211. package/dist/components/Sidebar/sidebar.js.map +1 -1
  212. package/dist/components/Slider/slider.d.ts.map +1 -1
  213. package/dist/components/Slider/slider.js.map +1 -1
  214. package/dist/components/Switch/switch.d.ts +6 -6
  215. package/dist/components/Switch/switch.d.ts.map +1 -1
  216. package/dist/components/Switch/switch.js +3 -2
  217. package/dist/components/Switch/switch.js.map +1 -1
  218. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  219. package/dist/components/Tabs/tabs.js +15 -1
  220. package/dist/components/Tabs/tabs.js.map +1 -1
  221. package/dist/components/Textarea/textarea.d.ts +2 -2
  222. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  223. package/dist/components/Textarea/textarea.js +50 -42
  224. package/dist/components/Textarea/textarea.js.map +1 -1
  225. package/dist/components/TimePicker/time-columns.d.ts.map +1 -1
  226. package/dist/components/TimePicker/time-columns.js +42 -38
  227. package/dist/components/TimePicker/time-columns.js.map +1 -1
  228. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  229. package/dist/components/TimePicker/time-picker.js +8 -6
  230. package/dist/components/TimePicker/time-picker.js.map +1 -1
  231. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  232. package/dist/components/Tooltip/tooltip.js +7 -5
  233. package/dist/components/Tooltip/tooltip.js.map +1 -1
  234. package/dist/components/TreeView/tree-view.d.ts +56 -1
  235. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  236. package/dist/components/TreeView/tree-view.js +211 -12
  237. package/dist/components/TreeView/tree-view.js.map +1 -1
  238. package/dist/index.d.ts +115 -58
  239. package/dist/index.d.ts.map +1 -1
  240. package/dist/index.js +95 -108
  241. package/dist/index.js.map +1 -1
  242. package/dist/patterns/element-anatomy/item-anatomy.d.ts +7 -6
  243. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  244. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  245. package/dist/tokens/categorical-color.js +15 -0
  246. package/dist/tokens/categorical-color.js.map +1 -1
  247. package/dist/tokens/motion/motion.d.ts +7 -6
  248. package/dist/tokens/motion/motion.d.ts.map +1 -1
  249. package/dist/tokens/motion/motion.js +6 -6
  250. package/dist/tokens/motion/motion.js.map +1 -1
  251. package/dist/tokens/motion/overlay-motion.d.ts +19 -0
  252. package/dist/tokens/motion/overlay-motion.d.ts.map +1 -0
  253. package/dist/tokens/motion/overlay-motion.js +9 -0
  254. package/dist/tokens/motion/overlay-motion.js.map +1 -0
  255. package/dist/tokens/uiSize/icon-size.js +5 -0
  256. package/dist/tokens/uiSize/icon-size.js.map +1 -0
  257. package/ds-canonical/fork/governance.lock +31 -19
  258. package/ds-canonical/fork/hooks/_log-fire.sh +46 -0
  259. package/ds-canonical/fork/hooks/block_prototype_imports.py +15 -4
  260. package/ds-canonical/fork/hooks/check_consumer_app_invariants.sh +145 -13
  261. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +2 -1
  262. package/ds-canonical/fork/hooks/check_dynamic_tailwind_class.sh +47 -0
  263. package/ds-canonical/fork/hooks/check_escape_marker_abuse.sh +27 -0
  264. package/ds-canonical/fork/hooks/check_field_family_invariants.sh +61 -1
  265. package/ds-canonical/fork/hooks/check_layout_space_magic_numbers.sh +28 -4
  266. package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +28 -0
  267. package/ds-canonical/fork/hooks/check_story_determinism.sh +2 -0
  268. package/ds-canonical/fork/hooks/check_story_invariants.sh +119 -0
  269. package/ds-canonical/fork/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  270. package/ds-canonical/fork/manifest.json +15 -0
  271. package/ds-canonical/fork/preamble.md +20 -18
  272. package/ds-canonical/fork/skills/bug-fix-rhythm/SKILL.md +3 -3
  273. package/ds-canonical/fork/skills/code-quality-audit/SKILL.md +3 -3
  274. package/ds-canonical/fork/skills/delivery-handoff/SKILL.md +1 -1
  275. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +3 -3
  276. package/ds-canonical/fork/skills/propose-options/SKILL.md +3 -3
  277. package/ds-canonical/fork/skills/prototype/SKILL.md +1 -1
  278. package/ds-canonical/fork/skills/scan-similar-bugs/SKILL.md +2 -2
  279. package/ds-canonical/fork/skills/visual-audit/SKILL.md +2 -2
  280. package/ds-canonical/hooks/README.md +1 -1
  281. package/ds-canonical/hooks/block_prototype_imports.py +15 -4
  282. package/ds-canonical/hooks/check_audit_post_report_validator.sh +65 -7
  283. package/ds-canonical/hooks/check_codex_brief_invariants.sh +28 -1
  284. package/ds-canonical/hooks/check_consumer_app_invariants.sh +145 -13
  285. package/ds-canonical/hooks/check_datatable_invariants.sh +6 -3
  286. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +2 -1
  287. package/ds-canonical/hooks/check_dynamic_tailwind_class.sh +47 -0
  288. package/ds-canonical/hooks/check_escape_marker_abuse.sh +27 -0
  289. package/ds-canonical/hooks/check_field_family_invariants.sh +61 -1
  290. package/ds-canonical/hooks/check_layout_space_magic_numbers.sh +28 -4
  291. package/ds-canonical/hooks/check_naming_and_abstraction.sh +1 -1
  292. package/ds-canonical/hooks/check_opacity_token_usage.sh +28 -0
  293. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +3 -2
  294. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +6 -1
  295. package/ds-canonical/hooks/check_ssot_header_declaration.sh +3 -1
  296. package/ds-canonical/hooks/check_story_determinism.sh +2 -0
  297. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +8 -7
  298. package/ds-canonical/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  299. package/ds-canonical/hooks/lib/_story_compile_drift.sh +1 -1
  300. package/ds-canonical/hooks/lib/_token_hygiene.sh +10 -1
  301. package/ds-canonical/hooks/stop_self_audit.sh +31 -0
  302. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +24 -0
  303. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +44 -0
  304. package/ds-canonical/hooks/tests/test_check_codex_brief_invariants.sh +43 -2
  305. package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +112 -0
  306. package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +9 -2
  307. package/ds-canonical/hooks/tests/test_check_dynamic_tailwind_class.sh +76 -0
  308. package/ds-canonical/hooks/tests/test_check_escape_marker_abuse.sh +24 -0
  309. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +27 -2
  310. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +39 -0
  311. package/ds-canonical/hooks/tests/test_check_tabs_content_chrome_body_double_gap.sh +76 -0
  312. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
  313. package/ds-canonical/references/build-ui-canonicals.md +2 -1
  314. package/ds-canonical/references/failure-class-registry.json +145 -0
  315. package/ds-canonical/references/governance-audit-coverage.md +33 -0
  316. package/ds-canonical/references/item-anatomy-recipe.md +2 -2
  317. package/ds-canonical/references/scenario-definition.md +6 -9
  318. package/ds-canonical/references/ssot-consultation.md +2 -2
  319. package/ds-canonical/references/ssot-index.md +5 -4
  320. package/ds-canonical/references/story-baseline-registry.json +8 -2
  321. package/ds-canonical/references/structural-token-retention.md +6 -9
  322. package/ds-canonical/rules/meta-patterns.md +8 -8
  323. package/ds-canonical/rules/self-verify.md +4 -3
  324. package/ds-canonical/rules/story-rules.md +2 -2
  325. package/ds-canonical/rules/ui-development.md +2 -2
  326. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +3 -3
  327. package/ds-canonical/skills/code-quality-audit/SKILL.md +3 -3
  328. package/ds-canonical/skills/codex-collab/SKILL.md +9 -7
  329. package/ds-canonical/skills/codex-collab/references/brief-template.md +1 -1
  330. package/ds-canonical/skills/codify-principle/SKILL.md +2 -2
  331. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  332. package/ds-canonical/skills/component-quality-gate/references/checklist.md +2 -2
  333. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +51 -58
  334. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +29 -0
  335. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +29 -10
  336. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +21 -0
  337. package/ds-canonical/skills/delivery-handoff/SKILL.md +1 -1
  338. package/ds-canonical/skills/design-system-audit/SKILL.md +26 -25
  339. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +13 -1
  340. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +1 -1
  341. package/ds-canonical/skills/governance-health/SKILL.md +1 -1
  342. package/ds-canonical/skills/knowledge-prune/SKILL.md +3 -0
  343. package/ds-canonical/skills/knowledge-prune/references/prune-dimensions-d5-d10.md +1 -0
  344. package/ds-canonical/skills/new-component/SKILL.md +5 -5
  345. package/ds-canonical/skills/new-component/references/new-component-checklist.md +1 -1
  346. package/ds-canonical/skills/product-ui-audit/SKILL.md +3 -3
  347. package/ds-canonical/skills/propose-options/SKILL.md +3 -3
  348. package/ds-canonical/skills/prototype/SKILL.md +1 -1
  349. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +2 -2
  350. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +3 -3
  351. package/ds-canonical/skills/story-writing/SKILL.md +3 -3
  352. package/ds-canonical/skills/visual-audit/SKILL.md +2 -2
  353. package/ds-story-manifest.json +29 -20
  354. package/llms-full.txt +22 -1
  355. package/llms.txt +5 -4
  356. package/package.json +7 -3
  357. package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
  358. package/src/components/Accordion/accordion.stories.tsx +16 -1
  359. package/src/components/Alert/alert.principles.stories.tsx +1 -1
  360. package/src/components/Alert/alert.spec.md +8 -10
  361. package/src/components/Alert/alert.stories.tsx +28 -28
  362. package/src/components/Alert/alert.tsx +1 -1
  363. package/src/components/AppShell/_demo-helpers.tsx +6 -3
  364. package/src/components/AppShell/app-shell.spec.md +4 -4
  365. package/src/components/AppShell/app-shell.tsx +28 -2
  366. package/src/components/AspectRatio/aspect-ratio.spec.md +1 -1
  367. package/src/components/AspectRatio/aspect-ratio.stories.tsx +7 -89
  368. package/src/components/Avatar/avatar.anatomy.stories.tsx +7 -3
  369. package/src/components/Avatar/avatar.principles.stories.tsx +19 -15
  370. package/src/components/Avatar/avatar.spec.md +2 -2
  371. package/src/components/Avatar/avatar.stories.tsx +8 -6
  372. package/src/components/Avatar/avatar.tsx +13 -5
  373. package/src/components/Badge/badge.principles.stories.tsx +1 -1
  374. package/src/components/Badge/badge.spec.md +2 -0
  375. package/src/components/Badge/badge.stories.tsx +4 -2
  376. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +6 -4
  377. package/src/components/Breadcrumb/breadcrumb.stories.tsx +6 -5
  378. package/src/components/Breadcrumb/breadcrumb.tsx +3 -2
  379. package/src/components/BulkActionBar/bulk-action-bar.spec.md +4 -2
  380. package/src/components/Button/button.principles.stories.tsx +1 -1
  381. package/src/components/Button/button.spec.md +2 -2
  382. package/src/components/Button/button.tsx +18 -3
  383. package/src/components/Calendar/calendar.anatomy.stories.tsx +12 -10
  384. package/src/components/Calendar/calendar.principles.stories.tsx +14 -6
  385. package/src/components/Calendar/calendar.spec.md +5 -4
  386. package/src/components/Calendar/calendar.stories.tsx +7 -4
  387. package/src/components/Calendar/calendar.tsx +26 -7
  388. package/src/components/Carousel/carousel.anatomy.stories.tsx +5 -4
  389. package/src/components/Carousel/carousel.spec.md +2 -2
  390. package/src/components/Carousel/carousel.tsx +11 -3
  391. package/src/components/Chart/chart.anatomy.stories.tsx +7 -4
  392. package/src/components/Chart/chart.principles.stories.tsx +1 -1
  393. package/src/components/Chart/chart.stories.tsx +2 -8
  394. package/src/components/Chart/chart.tsx +3 -0
  395. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +28 -49
  396. package/src/components/Checkbox/checkbox.principles.stories.tsx +1 -1
  397. package/src/components/Checkbox/checkbox.spec.md +13 -26
  398. package/src/components/Checkbox/checkbox.stories.tsx +11 -8
  399. package/src/components/Checkbox/checkbox.tsx +18 -13
  400. package/src/components/Chip/chip.anatomy.stories.tsx +44 -24
  401. package/src/components/Chip/chip.principles.stories.tsx +1 -1
  402. package/src/components/Chip/chip.spec.md +5 -4
  403. package/src/components/Chip/chip.tsx +5 -1
  404. package/src/components/CircularProgress/circular-progress.principles.stories.tsx +7 -4
  405. package/src/components/CircularProgress/circular-progress.spec.md +3 -3
  406. package/src/components/CircularProgress/circular-progress.stories.tsx +2 -2
  407. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +2 -2
  408. package/src/components/Coachmark/coachmark.principles.stories.tsx +2 -1
  409. package/src/components/Coachmark/coachmark.spec.md +5 -5
  410. package/src/components/Coachmark/coachmark.stories.tsx +3 -1
  411. package/src/components/Coachmark/coachmark.tsx +10 -3
  412. package/src/components/Combobox/combobox.anatomy.stories.tsx +2 -2
  413. package/src/components/Combobox/combobox.tsx +53 -19
  414. package/src/components/Command/command.anatomy.stories.tsx +2 -2
  415. package/src/components/Command/command.principles.stories.tsx +1 -1
  416. package/src/components/Command/command.stories.tsx +42 -10
  417. package/src/components/DataTable/cell-registry.tsx +86 -63
  418. package/src/components/DataTable/column-types.ts +10 -1
  419. package/src/components/DataTable/data-table-column-visibility-panel.tsx +1 -1
  420. package/src/components/DataTable/data-table-filter-group.tsx +231 -0
  421. package/src/components/DataTable/data-table-filter-panel.tsx +16 -430
  422. package/src/components/DataTable/data-table-filter-value-picker.tsx +237 -0
  423. package/src/components/DataTable/data-table-interaction-layer.tsx +15 -19
  424. package/src/components/DataTable/data-table.anatomy.stories.tsx +15 -13
  425. package/src/components/DataTable/data-table.principles.stories.tsx +9 -9
  426. package/src/components/DataTable/data-table.spec.md +33 -13
  427. package/src/components/DataTable/data-table.stories.tsx +16 -17
  428. package/src/components/DataTable/data-table.tsx +107 -61
  429. package/src/components/DataTable/filter-operators.spec.md +3 -3
  430. package/src/components/DataTable/index.ts +3 -0
  431. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +4 -4
  432. package/src/components/DateGrid/date-grid.principles.stories.tsx +1 -1
  433. package/src/components/DateGrid/date-grid.spec.md +1 -1
  434. package/src/components/DateGrid/date-grid.tsx +3 -1
  435. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +8 -8
  436. package/src/components/DatePicker/date-picker.principles.stories.tsx +3 -3
  437. package/src/components/DatePicker/date-picker.spec.md +3 -3
  438. package/src/components/DatePicker/date-picker.stories.tsx +4 -5
  439. package/src/components/DatePicker/date-picker.tsx +99 -45
  440. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +12 -10
  441. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  442. package/src/components/DescriptionList/description-list.spec.md +3 -3
  443. package/src/components/DescriptionList/description-list.stories.tsx +7 -6
  444. package/src/components/Dialog/dialog.anatomy.stories.tsx +1 -0
  445. package/src/components/Dialog/dialog.spec.md +9 -0
  446. package/src/components/Dialog/dialog.stories.tsx +66 -5
  447. package/src/components/Dialog/dialog.tsx +60 -25
  448. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
  449. package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +8 -6
  450. package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -5
  451. package/src/components/DropdownMenu/dropdown-menu.tsx +18 -9
  452. package/src/components/Empty/empty.anatomy.stories.tsx +1 -1
  453. package/src/components/Empty/empty.spec.md +2 -2
  454. package/src/components/Field/field-context.ts +69 -5
  455. package/src/components/Field/field-controls.spec.md +62 -8
  456. package/src/components/Field/field-edit-keys.ts +66 -0
  457. package/src/components/Field/field-types.ts +58 -9
  458. package/src/components/Field/field-wrapper.tsx +50 -42
  459. package/src/components/Field/field.anatomy.stories.tsx +9 -6
  460. package/src/components/Field/field.spec.md +1 -1
  461. package/src/components/Field/field.stories.tsx +1 -1
  462. package/src/components/Field/field.tsx +2 -1
  463. package/src/components/Field/form-validation.spec.md +3 -3
  464. package/src/components/Field/index.ts +1 -0
  465. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +6 -6
  466. package/src/components/FieldControlGroup/field-control-group.spec.md +9 -4
  467. package/src/components/FieldControlGroup/field-control-group.tsx +1 -1
  468. package/src/components/FileItem/file-item.anatomy.stories.tsx +1 -1
  469. package/src/components/FileItem/file-item.spec.md +5 -8
  470. package/src/components/FileItem/file-item.stories.tsx +36 -25
  471. package/src/components/FileItem/file-item.tsx +8 -6
  472. package/src/components/FileUpload/file-upload.anatomy.stories.tsx +6 -6
  473. package/src/components/FileUpload/file-upload.principles.stories.tsx +5 -5
  474. package/src/components/FileUpload/file-upload.spec.md +1 -1
  475. package/src/components/FileUpload/file-upload.tsx +1 -1
  476. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +4 -3
  477. package/src/components/FileViewer/file-viewer.principles.stories.tsx +3 -3
  478. package/src/components/FileViewer/file-viewer.spec.md +30 -12
  479. package/src/components/FileViewer/file-viewer.stories.tsx +1 -2
  480. package/src/components/FileViewer/file-viewer.tsx +12 -4
  481. package/src/components/FileViewer/image-renderer.tsx +35 -7
  482. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -2
  483. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -3
  484. package/src/components/HoverCard/hover-card.spec.md +5 -5
  485. package/src/components/HoverCard/hover-card.stories.tsx +16 -16
  486. package/src/components/HoverCard/hover-card.tsx +5 -3
  487. package/src/components/InlineEdit/index.ts +5 -0
  488. package/src/components/InlineEdit/inline-edit.spec.md +149 -0
  489. package/src/components/InlineEdit/inline-edit.stories.tsx +246 -0
  490. package/src/components/InlineEdit/inline-edit.tsx +287 -0
  491. package/src/components/Input/input.anatomy.stories.tsx +8 -7
  492. package/src/components/Input/input.principles.stories.tsx +2 -12
  493. package/src/components/Input/input.spec.md +13 -18
  494. package/src/components/Input/input.tsx +69 -22
  495. package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
  496. package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
  497. package/src/components/LinkInput/link-input.tsx +11 -10
  498. package/src/components/Menu/menu-item.anatomy.stories.tsx +3 -3
  499. package/src/components/Menu/menu-item.principles.stories.tsx +1 -1
  500. package/src/components/Menu/menu-item.spec.md +22 -15
  501. package/src/components/Menu/menu-item.stories.tsx +39 -11
  502. package/src/components/Menu/menu-item.tsx +38 -4
  503. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  504. package/src/components/Notice/notice.spec.md +16 -3
  505. package/src/components/NumberInput/number-input.anatomy.stories.tsx +3 -3
  506. package/src/components/NumberInput/number-input.principles.stories.tsx +1 -1
  507. package/src/components/NumberInput/number-input.spec.md +4 -4
  508. package/src/components/NumberInput/number-input.tsx +19 -12
  509. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +10 -8
  510. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +3 -3
  511. package/src/components/OverflowIndicator/overflow-indicator.spec.md +4 -2
  512. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +71 -63
  513. package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -8
  514. package/src/components/Pagination/pagination.spec.md +1 -1
  515. package/src/components/Pagination/pagination.stories.tsx +2 -6
  516. package/src/components/Pagination/pagination.tsx +1 -1
  517. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +4 -4
  518. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +2 -2
  519. package/src/components/PeoplePicker/people-picker.spec.md +6 -6
  520. package/src/components/PeoplePicker/people-picker.tsx +56 -16
  521. package/src/components/PeoplePicker/person-display.tsx +32 -16
  522. package/src/components/Popover/popover.anatomy.stories.tsx +2 -2
  523. package/src/components/Popover/popover.tsx +3 -1
  524. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +12 -23
  525. package/src/components/ProfileCard/profile-card.spec.md +3 -3
  526. package/src/components/ProfileCard/profile-card.tsx +6 -6
  527. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +3 -1
  528. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +1 -1
  529. package/src/components/ProgressBar/progress-bar.stories.tsx +50 -42
  530. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +10 -28
  531. package/src/components/RadioGroup/radio-group.stories.tsx +29 -32
  532. package/src/components/RadioGroup/radio-group.tsx +41 -15
  533. package/src/components/Rating/rating.spec.md +11 -3
  534. package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
  535. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  536. package/src/components/ScrollArea/scroll-area.spec.md +7 -3
  537. package/src/components/ScrollArea/scroll-area.stories.tsx +1 -1
  538. package/src/components/ScrollArea/scroll-area.tsx +17 -4
  539. package/src/components/Select/select.anatomy.stories.tsx +3 -3
  540. package/src/components/Select/select.spec.md +29 -17
  541. package/src/components/Select/select.stories.tsx +33 -0
  542. package/src/components/Select/select.tsx +190 -36
  543. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +4 -4
  544. package/src/components/SelectMenu/select-menu.spec.md +15 -7
  545. package/src/components/SelectMenu/select-menu.tsx +16 -3
  546. package/src/components/SelectionControl/boolean-value.tsx +39 -0
  547. package/src/components/SelectionControl/index.ts +1 -0
  548. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +2 -2
  549. package/src/components/SelectionControl/selection-item.principles.stories.tsx +2 -2
  550. package/src/components/SelectionControl/selection-item.spec.md +3 -3
  551. package/src/components/SelectionControl/selection-item.stories.tsx +3 -3
  552. package/src/components/Separator/separator.spec.md +2 -2
  553. package/src/components/Separator/separator.stories.tsx +6 -27
  554. package/src/components/Sheet/sheet.anatomy.stories.tsx +1 -1
  555. package/src/components/Sheet/sheet.principles.stories.tsx +1 -1
  556. package/src/components/Sheet/sheet.spec.md +2 -2
  557. package/src/components/Sheet/sheet.tsx +9 -5
  558. package/src/components/Sidebar/sidebar.anatomy.stories.tsx +16 -12
  559. package/src/components/Sidebar/sidebar.principles.stories.tsx +10 -8
  560. package/src/components/Sidebar/sidebar.spec.md +13 -15
  561. package/src/components/Sidebar/sidebar.stories.tsx +8 -7
  562. package/src/components/Sidebar/sidebar.tsx +37 -25
  563. package/src/components/Skeleton/skeleton.stories.tsx +4 -11
  564. package/src/components/Slider/slider.anatomy.stories.tsx +3 -3
  565. package/src/components/Slider/slider.principles.stories.tsx +2 -2
  566. package/src/components/Slider/slider.spec.md +5 -5
  567. package/src/components/Slider/slider.tsx +3 -1
  568. package/src/components/Steps/steps.anatomy.stories.tsx +4 -4
  569. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  570. package/src/components/Steps/steps.spec.md +1 -1
  571. package/src/components/Switch/switch.anatomy.stories.tsx +7 -7
  572. package/src/components/Switch/switch.principles.stories.tsx +4 -4
  573. package/src/components/Switch/switch.spec.md +8 -8
  574. package/src/components/Switch/switch.stories.tsx +9 -24
  575. package/src/components/Switch/switch.tsx +17 -13
  576. package/src/components/Tabs/tabs.anatomy.stories.tsx +10 -7
  577. package/src/components/Tabs/tabs.spec.md +1 -1
  578. package/src/components/Tabs/tabs.tsx +21 -1
  579. package/src/components/Textarea/textarea.anatomy.stories.tsx +1 -1
  580. package/src/components/Textarea/textarea.principles.stories.tsx +1 -1
  581. package/src/components/Textarea/textarea.spec.md +4 -4
  582. package/src/components/Textarea/textarea.tsx +72 -46
  583. package/src/components/TimePicker/time-columns.tsx +6 -2
  584. package/src/components/TimePicker/time-picker.principles.stories.tsx +1 -1
  585. package/src/components/TimePicker/time-picker.spec.md +3 -3
  586. package/src/components/TimePicker/time-picker.tsx +16 -10
  587. package/src/components/Toast/toast.stories.tsx +7 -4
  588. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +4 -4
  589. package/src/components/Tooltip/tooltip.principles.stories.tsx +3 -3
  590. package/src/components/Tooltip/tooltip.spec.md +1 -1
  591. package/src/components/Tooltip/tooltip.stories.tsx +4 -39
  592. package/src/components/Tooltip/tooltip.tsx +8 -6
  593. package/src/components/TreeView/tree-view.anatomy.stories.tsx +6 -3
  594. package/src/components/TreeView/tree-view.spec.md +42 -11
  595. package/src/components/TreeView/tree-view.stories.tsx +1 -0
  596. package/src/components/TreeView/tree-view.tsx +322 -17
  597. package/src/index.ts +588 -60
  598. package/src/patterns/action-bar/action-bar.spec.md +9 -0
  599. package/src/patterns/action-bar/action-bar.stories.tsx +6 -3
  600. package/src/patterns/element-anatomy/inline-action.spec.md +2 -0
  601. package/src/patterns/element-anatomy/item-anatomy.spec.md +14 -5
  602. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -4
  603. package/src/patterns/element-anatomy/item-anatomy.tsx +7 -6
  604. package/src/patterns/header-canonical/header-canonical.spec.md +5 -4
  605. package/src/patterns/overlay-surface/overlay-surface.spec.md +22 -1
  606. package/src/styles/tokens.css +3 -0
  607. package/src/tokens/README.md +1 -1
  608. package/src/tokens/color/color.spec.md +4 -4
  609. package/src/tokens/color/color.stories.tsx +3 -3
  610. package/src/tokens/density/density.stories.tsx +16 -3
  611. package/src/tokens/layoutSpace/layoutSpace.spec.md +3 -1
  612. package/src/tokens/motion/motion.css +33 -21
  613. package/src/tokens/motion/motion.spec.md +32 -15
  614. package/src/tokens/motion/motion.stories.tsx +58 -5
  615. package/src/tokens/motion/motion.ts +7 -6
  616. package/src/tokens/motion/overlay-motion.ts +26 -0
  617. package/src/tokens/orphan-tokens.spec.md +4 -4
  618. package/src/tokens/token-system.spec.md +1 -0
  619. package/src/tokens/uiSize/uiSize.css +1 -1
  620. package/src/tokens/uiSize/uiSize.spec.md +1 -1
  621. package/src/tokens/uiSize/uiSize.stories.tsx +4 -2
  622. package/src/tokens/utility-registry.json +160 -23
@@ -0,0 +1,25 @@
1
+ function getColumnId(col) {
2
+ if ("id" in col && typeof col.id === "string" && col.id) return col.id;
3
+ if ("accessorKey" in col && (typeof col.accessorKey === "string" || typeof col.accessorKey === "number")) {
4
+ return String(col.accessorKey);
5
+ }
6
+ return void 0;
7
+ }
8
+ function getColumnHeader(col) {
9
+ return "header" in col ? col.header : void 0;
10
+ }
11
+ function getColumnMeta(col) {
12
+ return col.meta;
13
+ }
14
+ function getColumnLabel(col, fallbackId) {
15
+ const header = getColumnHeader(col);
16
+ if (typeof header === "string") return header;
17
+ return fallbackId ?? getColumnId(col) ?? "";
18
+ }
19
+ export {
20
+ getColumnHeader,
21
+ getColumnId,
22
+ getColumnLabel,
23
+ getColumnMeta
24
+ };
25
+ //# sourceMappingURL=column-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column-meta.js","sources":["../../../../src/components/DataTable/lib/column-meta.ts"],"sourcesContent":["/**\n * column-meta — TanStack ColumnDef typed accessor helpers.\n *\n * **Scope:Internal-only — DataTable 自用,非 public API**(本檔不 re-export 出\n * `data-table-filter-panel.tsx` / `data-table.tsx`,consumer 透過 panel / sort-manager\n * 間接使用)。M21 (a) classification:lib/ folder 慣例 = internal helper。\n *\n * 為什麼存在:`ColumnDef<T, V>` 是 discriminated union(AccessorKey / AccessorFn /\n * Display / Group),每個 variant 有不同欄位,直接 `col.id` 在型別上不安全。\n * 既有 consumer 用 `(col as any).id` cast,3+ 處 hard-code = M17 違反。\n * 抽成 typed helper 統一型別 narrowing,消除 `any` cast。\n *\n * Why not annotate each `as any`:DRY + single SSOT for column field access。\n * 任一 helper 行為變更(e.g. 加 fallback 邏輯)只需改一處。\n *\n * 對齊 mindset #2 「優先消費既有」+ M17「同 hard-code 在 3+ consumer 必抽」。\n */\n\nimport type { ColumnDef, ColumnMeta, RowData } from '@tanstack/react-table'\n\n/**\n * 取 column 的 stable identifier。\n *\n * 解析順序對齊 TanStack 內部行為:\n * 1. `col.id`(顯式設定優先)\n * 2. `col.accessorKey`(string version,fallback for accessor columns)\n *\n * 都無 → return undefined(display column 無 accessorKey 且未設 id)。\n */\nexport function getColumnId<T extends RowData>(\n col: ColumnDef<T, unknown>,\n): string | undefined {\n if ('id' in col && typeof col.id === 'string' && col.id) return col.id\n if (\n 'accessorKey' in col &&\n (typeof col.accessorKey === 'string' || typeof col.accessorKey === 'number')\n ) {\n return String(col.accessorKey)\n }\n return undefined\n}\n\n/**\n * 取 column 的 header 定義(可為 string / React node / function — TanStack 規約)。\n *\n * 注意:本 helper 不執行 header function。consumer 若需 rendered string,\n * 自行 narrow + call,或用 TanStack `flexRender` API。\n */\nexport function getColumnHeader<T extends RowData>(\n col: ColumnDef<T, unknown>,\n): ColumnDef<T, unknown>['header'] {\n return 'header' in col ? col.header : undefined\n}\n\n/**\n * 取 column 的 meta(本 DS 的 ColumnMeta 已 extend 加上 type / align / wrap 等)。\n */\nexport function getColumnMeta<T extends RowData>(\n col: ColumnDef<T, unknown>,\n): ColumnMeta<T, unknown> | undefined {\n return col.meta\n}\n\n/**\n * 從 header 定義抽 plain string label(filter / sort UI 顯示用)。\n *\n * 處理 3 種 header 形式:\n * - string → 直接 return\n * - function → 不執行(避過 React render context),fallback id\n * - undefined / 其他 → fallback id\n */\nexport function getColumnLabel<T extends RowData>(\n col: ColumnDef<T, unknown>,\n fallbackId?: string,\n): string {\n const header = getColumnHeader(col)\n if (typeof header === 'string') return header\n return fallbackId ?? getColumnId(col) ?? ''\n}\n"],"names":[],"mappings":"AA6BO,SAAS,YACd,KACoB;AACpB,MAAI,QAAQ,OAAO,OAAO,IAAI,OAAO,YAAY,IAAI,GAAI,QAAO,IAAI;AACpE,MACE,iBAAiB,QAChB,OAAO,IAAI,gBAAgB,YAAY,OAAO,IAAI,gBAAgB,WACnE;AACA,WAAO,OAAO,IAAI,WAAW;AAAA,EAC/B;AACA,SAAO;AACT;AAQO,SAAS,gBACd,KACiC;AACjC,SAAO,YAAY,MAAM,IAAI,SAAS;AACxC;AAKO,SAAS,cACd,KACoC;AACpC,SAAO,IAAI;AACb;AAUO,SAAS,eACd,KACA,YACQ;AACR,QAAM,SAAS,gBAAgB,GAAG;AAClC,MAAI,OAAO,WAAW,SAAU,QAAO;AACvC,SAAO,cAAc,YAAY,GAAG,KAAK;AAC3C;"}
@@ -1 +1 @@
1
- {"version":3,"file":"date-grid.d.ts","sourceRoot":"","sources":["../../../src/components/DateGrid/date-grid.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,4BAA4B,CAAA;AAKnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,CAAA;AAUlE,QAAA,MAAM,QAAQ,kHAgLZ,CAAA;AAKF,eAAO,MAAM,YAAY;;;;;;;;;;;CAiBf,CAAA;AAEV,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"date-grid.d.ts","sourceRoot":"","sources":["../../../src/components/DateGrid/date-grid.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,4BAA4B,CAAA;AAKnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,CAAA;AAUlE,QAAA,MAAM,QAAQ,kHAkLZ,CAAA;AAKF,eAAO,MAAM,YAAY;;;;;;;;;;;CAiBf,CAAA;AAEV,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -45,7 +45,9 @@ const DateGrid = React.forwardRef(function DateGrid2({
45
45
  // weekday 列標跟 caption「April 2026」同視覺權重(都屬 calendar header 區),
46
46
  // 不弱化(撤銷 v3 fg-secondary 的 mistake)。對齊 icon-only Button 預設 neutral-9 一致。
47
47
  "text-foreground text-body font-medium",
48
- "h-7 align-middle text-center"
48
+ // h-field-sm(md=28/lg=32 隨 density):對齊 day cell 同 token 同 row cadence
49
+ // (spec:127 既定 canonical;Ant 36/36、Carbon 40/40 header/day 同節奏;2026-07-14 修 h-7 固定 drift)
50
+ "h-[var(--field-height-sm)] align-middle text-center"
49
51
  ),
50
52
  week: "",
51
53
  // tr default
@@ -1 +1 @@
1
- {"version":3,"file":"date-grid.js","sources":["../../../src/components/DateGrid/date-grid.tsx"],"sourcesContent":["/**\n * @internal — DS-internal 單元(per `.claude/rules/ui-development.md` Public vs Internal canonical;spec frontmatter `isInternal`)。\n * 不進 root barrel front-door;由 DatePicker wrap 消費,end-user app 請用 wrapper 元件。\n */\n// @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.\n// M22 retrofit DONE 2026-05-03 v11(real source URLs added inline at lines 38 + 111)\nimport * as React from 'react'\nimport { DayPicker } from 'react-day-picker'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport 'react-day-picker/style.css'\n\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/design-system/components/Button/button'\n\n/**\n * DateGrid — DayPicker 包裝,用本 DS token 覆寫預設視覺。\n *\n * ── 視覺對照(ref/datepicker.png,2026-04-21 rewrite)──\n *\n * | 區塊 | 規格 |\n * |------|------|\n * | Outer padding | `p-3`(12px 四邊對稱) |\n * | Nav + Month caption row | h-field-xs(24px)單行,chevron(xs)分居左右 / 月份置中垂直對齊 |\n * | Nav → Weekday gap | 12px(month_caption mb-3) |\n * | Weekday | text-body(14px)text-foreground font-medium(neutral-9,同 caption 權重;撤銷 v3 fg-secondary) |\n * | Cell gap(水平 + 垂直)| 4px(table-native border-separate border-spacing-1;非 gap — grid 會 break,見下方 v7 註) |\n * | Day cell size | h-field-sm w-[var(--field-height-sm)](28×28 md / 32×32 lg) |\n * | Day button | rounded-full 填滿 cell |\n *\n * ── 五種 cell state canonical ──\n *\n * | State | 視覺 | Token |\n * |-------|------|-------|\n * | today | 數字下方藍色短桿 | `::after` pseudo bar(bg-primary,w-40% h-1.5px rounded-full,貼近數字底)|\n * | disabled | 灰底圓圈 + disabled 字色(跟 Button disabled 一致) | [&>button]:bg-disabled [&>button]:text-fg-disabled rounded-full |\n * | outside(非本月) | text-fg-muted(neutral-7) | [&>button]:text-fg-muted |\n * | selected / range 端點 | 藍底白字圓 | [&>button]:bg-primary [&>button]:text-on-emphasis rounded-full |\n * | range middle | 灰底矩形 track(bg-neutral-selected = neutral-2),**高度 = cell 高度**(28×28 @ md) | before pseudo: `inset-y-0 -inset-x-[2px]` |\n * | range start/end 半圓 track | 左/右半圓 + selected 圓疊在上,**圓半徑 = button 半徑** | before pseudo: `rounded-l/r-full` + start `left-0 -right-[2px]` / end `-left-[2px] right-0`(向 middle 外擴 2px bridge gap)|\n * | hover(未選中) | 藍圈 outline | hover:ring-[1.5px] hover:ring-primary-hover(2026-07-07 統一:瞬時 hover = hover 階)|\n *\n * ── Range track 高度 canonical(2026-05-03 v6,M8 4 家對照)──\n * Ant Design([picker source](https://github.com/ant-design/ant-design/blob/master/components/date-picker/style/panel.ts))/ Material X DateRangePicker([mui-x source](https://github.com/mui/mui-x/tree/master/packages/x-date-pickers-pro/src/DateRangeCalendar))/ Apple Calendar `@benchmark-unverified`(closed-source)/ Google Calendar `@benchmark-unverified`(closed-source)共識:\n * **range track 為連續 stadium**,跟 selected 圓緊貼成連續 pill。\n * 實作:bg 走 `before:` pseudo 用 `inset-y-0`(滿 cell 高度)+ `-inset-x-[2px]`\n * (左右各外擴 2px bridge 相鄰 cell gap)→ 相鄰 cell 的 pseudo 連續銜接 = 橫向連貫;\n * day cell 本身就是 button 容器(L102-105 day = h-field-sm cell),故滿 cell 高 = 滿 button 高。\n *\n * ── Range track 色用 bg-neutral-selected(= neutral-2)──\n * 對齊 TimePicker 選中項目樣式(semantic `--neutral-selected` = neutral-2,semantic.css L84/L340)。\n * 同 DS 內「持續選中」語意 token,不自開 neutral-3 tier。\n *\n * ── 為什麼 nav 放頂部 + 年月垂直置中(不 separate 兩行)──\n * ref/datepicker.png:chevron prev / 月份 / chevron next 同一行,24px 高(xs field height)。\n * 省垂直空間,使用者視線不需上下跳。世界級(Google Calendar / Apple / iOS 日期輸入)皆此佈局。\n */\n\nexport type DateGridProps = React.ComponentProps<typeof DayPicker>\n\n// ── SR label 中文 formatter(2026-07-05)──\n// 走 Intl.DateTimeFormat(對齊 TimePicker / Calendar 既有 canonical,不引第二套 date lib);\n// module-level 建一次 — label fn 每個 day cell 都會呼叫,避免 per-call new formatter。\nconst ZH_FULL_DATE = new Intl.DateTimeFormat('zh-TW', { dateStyle: 'full' })\nconst ZH_MONTH_YEAR = new Intl.DateTimeFormat('zh-TW', { year: 'numeric', month: 'long' })\nconst ZH_WEEKDAY = new Intl.DateTimeFormat('zh-TW', { weekday: 'long' })\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst DateGrid = React.forwardRef<HTMLDivElement, DateGridProps>(function DateGrid(\n {\n className,\n classNames,\n labels,\n showOutsideDays = true,\n ...props\n },\n _ref,\n) {\n // Note: react-day-picker v9 DayPicker 未對外 forward ref 到單一 DOM 節點(內部有多 div),\n // 故 ref 簽名保留但不附著(符合 DS 統一 forwardRef 慣例;真要取 DOM 用 wrapper 包)。\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n // navLayout=\"around\" = prev 渲染在首月(displayIndex===0)caption 左、next 渲染在末月(displayIndex===numberOfMonths-1)caption 右;單月時兩鍵同 caption 兩側\n // 取代先前 absolute 定位覆蓋整個 months 容器導致箭頭垂直置中於中段的 bug\n navLayout=\"around\"\n // p-3 = 12px 四邊對稱(canonical 不可動)\n className={cn('p-3', className)}\n classNames={{\n months: 'flex flex-col sm:flex-row gap-4',\n // Month:relative 讓 prev/next 按鈕 absolute 定位到 month 右上/左上(navLayout=\"around\")\n month: 'flex flex-col relative',\n // Month caption:單行置中 h-field-xs,prev/next 按鈕 absolute 從兩側貼齊\n month_caption: 'flex items-center justify-center h-field-xs mb-3',\n caption_label: 'text-body font-medium',\n // ── Prev/Next button(canonical 2026-05-03 v6,user audit fix)──\n // RDP 把這 className apply 到 <Button> 本身(不是 wrapper),所以用 className 直接套\n // 定位類(absolute top/left/right-0)。muted 色透過 Button override 內部加,不用 [&>button] 黑魔法。\n button_previous: 'absolute top-0 left-0 z-[1]',\n button_next: 'absolute top-0 right-0 z-[1]',\n // ── Grid layout(canonical 2026-05-03 v7,純 table-native)──\n // RDP v9 month_grid = <table>。v6 試 grid 在 tr 上但 break border-spacing(grid 蓋掉\n // table-row layout)。乾淨修:**純 table layout** + `border-spacing-1`(4px H+V,table-native)。\n // 所有 cells 自動同寬同高(td 的 w/h-field-sm),無 grid hack。\n month_grid: 'border-separate border-spacing-1',\n weekdays: '', // thead default\n weekday: cn(\n // text-foreground + font-medium 對齊 DS 一致設計語言(2026-05-03 user audit):\n // weekday 列標跟 caption「April 2026」同視覺權重(都屬 calendar header 區),\n // 不弱化(撤銷 v3 fg-secondary 的 mistake)。對齊 icon-only Button 預設 neutral-9 一致。\n 'text-foreground text-body font-medium',\n 'h-7 align-middle text-center',\n ),\n week: '', // tr default\n // Cell **就是** button 容器(28×28 @ md / 32×32 @ lg),`relative` 讓 before pseudo 定位\n // ── h-field-sm 對齊 user spec(28×28 @ md)— v3 用 h-field-md (32×32) 是錯的\n day: cn(\n 'h-field-sm w-[var(--field-height-sm)] p-0 text-center relative',\n ),\n day_button: cn(\n // absolute inset-0 = 完全填滿 cell(naked button,無 inset 4px 空隙)\n // z-[1] 讓 button 疊在 range track `before:` pseudo 之上\n 'absolute inset-0 z-[1] flex items-center justify-center',\n 'font-normal text-body rounded-full transition-colors',\n // Hover 藍圈 1.5px(對齊 Apple HIG / Ant `@benchmark-unverified` visual ring measurement)— ring 在 button 之上 + 透明 bg 不擋 range track\n // 2026-07-07 user 拍板統一:瞬時 hover 進 primary 家族 = hover 階(FileUpload dropzone /\n // Slider thumb hover 同族;base 專屬持續選中與 focus)——ring-primary → ring-primary-hover\n 'hover:ring-[1.5px] hover:ring-primary-hover hover:bg-transparent',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n ),\n // today:藍色 underline bar 貼近數字\n today: cn(\n \"[&>button]:after:content-['']\",\n '[&>button]:after:absolute',\n '[&>button]:after:bottom-[5px] [&>button]:after:left-1/2 [&>button]:after:-translate-x-1/2',\n '[&>button]:after:w-[40%] [&>button]:after:h-[1.5px] [&>button]:after:rounded-full',\n '[&>button]:after:bg-primary',\n // today + selected:bar 切 on-emphasis(白)— 只為「藍底白字圓」的選中日/端點設計;\n // range 中段(淺灰底)由 range_middle 的 !bg-primary 覆寫回藍(2026-07-07 user 拍板)。\n '[&[data-selected=true]>button]:after:bg-on-emphasis',\n ),\n outside: '[&>button]:text-fg-muted',\n // Selected(single 或 range 端點):button 藍底白字圓\n selected: cn(\n '[&>button]:bg-primary [&>button]:text-on-emphasis',\n '[&>button]:hover:bg-primary-hover [&>button]:hover:ring-0',\n ),\n disabled: cn(\n '[&>button]:bg-disabled [&>button]:text-fg-disabled [&>button]:cursor-not-allowed',\n '[&>button]:hover:ring-0 [&>button]:hover:bg-disabled',\n ),\n // ── Range track(canonical 2026-05-03 v6,Ant stadium pattern)──\n // v5 用 pseudo 矩形蓋全 cell 修「白色破圖」,但新副作用:button 圓比矩形小,4 個\n // corner triangle 區域 pseudo grey 凸出圓外(user 2026-05-03 抓到「凸出去」)。\n // 對齊 Ant 實證(`cell-range-start::before { border-radius: 9999px 0 0 9999px }`):\n // rangeStart pseudo 加 `rounded-l-full` → pseudo 變「左半圓 + 右矩形」stadium\n // 左半圓 EXACTLY OVERLAY button 圓的左半圓(同 center,同 radius 14)→ 邊界無縫\n // 右側矩形 bridge 2px to middle → 跟 middle pseudo 連續\n // Cell 的 top-left + bottom-left corner triangle:pseudo 不蓋 + button 不蓋 →\n // popover white 顯露(乾淨 breathing,跟 outside-of-range cells 一致視覺)\n range_start: cn(\n \"before:content-[''] before:absolute before:inset-y-0\",\n 'before:left-0 before:-right-[2px]',\n 'before:bg-neutral-selected before:pointer-events-none',\n 'before:rounded-l-full', // ← stadium 左半圓 matches button 圓的左半弧\n ),\n range_end: cn(\n \"before:content-[''] before:absolute before:inset-y-0\",\n 'before:-left-[2px] before:right-0',\n 'before:bg-neutral-selected before:pointer-events-none',\n 'before:rounded-r-full', // ← 鏡像\n ),\n range_middle: cn(\n \"before:content-[''] before:absolute before:inset-y-0 before:-inset-x-[2px]\",\n 'before:bg-neutral-selected before:pointer-events-none',\n // 2026-07-07 user 拍板:range 中段的 today bar 維持藍(切白只屬藍底選中日;白條在\n // neutral-selected 淺灰底上近乎隱形 = today 標記消失)。!important 確定性壓過 today 的\n // data-selected 切白規則(同權重靠 stylesheet 順序不可靠)。Ant 源碼實錘:cell-today\n // 指示 = colorPrimary,in-range 只換底色、無規則隱藏/改色 today 指示(panel.ts)。\n // 非 today 的中段日無 after content,本規則無作用 — 安全。\n '[&>button]:after:!bg-primary',\n // button 透明顯露 track。2026-07-05 對齊 RDP v9 真實行為(deep-audit A.1b):\n // range 中段日同樣掛 selected modifier(useRange rangeIncludesDate 不排除中段)→\n // 上方 selected 的 `[&>button]:hover:ring-0` 一併壓制 hover ring(與 selected 一致\n // 的 hover 抑制),非原註解宣稱的「hover ring 仍顯示」;today bar 亦被 data-selected\n // selector 切 on-emphasis(見 spec「組合狀態」段)。\n '[&>button]:!bg-transparent [&>button]:!text-foreground',\n ),\n hidden: 'invisible',\n ...classNames,\n }}\n // ── SR label 中文 defaults(2026-07-05,RDP labels API 正門)──\n // 對齊 MUI X localeText「預設可覆寫」idiom + 2026-07-04 全庫 SR label 中文\n // canonical(commit 241676c6):DS 給中文 default,consumer 傳 labels 逐鍵覆寫(i18n)。\n // 禁在 components override 內 spread 後 hardcode aria-label — 會蓋死此覆寫通道\n // (2026-07-05 修正 07-04 的錯誤修法:中文要走 labels 正門,不是蓋 RDP 算好的值)。\n labels={{\n labelPrevious: () => '上一個月',\n labelNext: () => '下一個月',\n // 鏡射 RDP default 結構(labels/labelDayButton.js:today 前綴 / selected 後綴),文案中文化\n labelDayButton: (date, modifiers) => {\n let label = ZH_FULL_DATE.format(date)\n if (modifiers.today) label = `今天,${label}`\n if (modifiers.selected) label = `${label},已選取`\n return label\n },\n // 未傳 mode 的非互動 grid(spec「mode 無預設值」段)day cell 走 labelGridcell\n labelGridcell: (date, modifiers) => {\n let label = ZH_FULL_DATE.format(date)\n if (modifiers?.today) label = `今天,${label}`\n return label\n },\n labelGrid: (date) => ZH_MONTH_YEAR.format(date),\n labelWeekday: (date) => ZH_WEEKDAY.format(date),\n // 以下非 default 渲染面(captionLayout dropdown / showWeekNumber 由 consumer 經\n // {...props} 開啟)— 一併補齊,避免開啟後 SR 中英夾雜\n labelMonthDropdown: () => '選擇月份',\n labelYearDropdown: () => '選擇年份',\n labelWeekNumber: (weekNumber) => `第 ${weekNumber} 週`,\n labelWeekNumberHeader: () => '週數',\n ...labels,\n }}\n components={{\n // ── Prev/Next nav(canonical 2026-05-03 v9,DS 一致設計語言)──\n // User 2026-05-03 audit:「icon-only Button icon 都用 neutral-9,只有 dismiss 用 45%」\n // → chevron 不是 dismiss,**走 Button 預設 text-foreground**(neutral-9 85%),\n // 不開新 tier 自打嘴(撤銷 v6-v8 用 fg-muted override 的 mistake)。\n // RDP v9 `PreviousMonthButton / NextMonthButton` override(node_modules/react-day-picker/dist/esm/components/Nav.js)\n // ⚠️ children: _ 必丟棄(RDP 把 <Chevron> 當 children 傳 → 跟 Button startIcon 重疊變 double chevron)\n // 2026-07-05 修:此處**不** hardcode aria-label — 中文走上方 labels API 正門,\n // RDP 算好 labelPrevious()/labelNext() 後經 {...props} 流入 Button;\n // spread 後 hardcode(07-04 舊修法)= 蓋死 consumer labels 覆寫通道。\n PreviousMonthButton: ({ className, children: _children, ...props }) => (\n <Button variant=\"text\" size=\"xs\" iconOnly startIcon={ChevronLeft}\n className={className} {...props} />\n ),\n NextMonthButton: ({ className, children: _children, ...props }) => (\n <Button variant=\"text\" size=\"xs\" iconOnly startIcon={ChevronRight}\n className={className} {...props} />\n ),\n }}\n {...props}\n />\n )\n})\nDateGrid.displayName = 'DateGrid'\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 dateGridMeta = {\n component: 'DateGrid',\n family: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n // 'selected' = 選中日期 / range 端點持續選中(藍底白字圓 bg-primary + range 帶 bg-neutral-selected);\n // 'active' 移除 — 全檔無 Tailwind 按壓 utility,無按壓專屬視覺態(2026-07-07 詞彙統一對抗稽核補修)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-disabled', 'bg-neutral-selected', 'bg-on-emphasis', 'bg-primary', 'bg-primary-hover', 'bg-transparent'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-foreground', 'text-on-emphasis'],\n ring: ['ring-primary', 'ring-ring'],\n },\n} as const\n\nexport { DateGrid }\n"],"names":["DateGrid","className","props"],"mappings":";;;;;;;AA8DA,MAAM,eAAe,IAAI,KAAK,eAAe,SAAS,EAAE,WAAW,QAAQ;AAC3E,MAAM,gBAAgB,IAAI,KAAK,eAAe,SAAS,EAAE,MAAM,WAAW,OAAO,QAAQ;AACzF,MAAM,aAAa,IAAI,KAAK,eAAe,SAAS,EAAE,SAAS,QAAQ;AAGvE,MAAM,WAAW,MAAM,WAA0C,SAASA,UACxE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,GAAG;AACL,GACA,MACA;AAGA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MAGA,WAAU;AAAA,MAEV,WAAW,GAAG,OAAO,SAAS;AAAA,MAC9B,YAAY;AAAA,QACV,QAAQ;AAAA;AAAA,QAER,OAAO;AAAA;AAAA,QAEP,eAAe;AAAA,QACf,eAAe;AAAA;AAAA;AAAA;AAAA,QAIf,iBAAiB;AAAA,QACjB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,QAKb,YAAY;AAAA,QACZ,UAAU;AAAA;AAAA,QACV,SAAS;AAAA;AAAA;AAAA;AAAA,UAIP;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,MAAM;AAAA;AAAA;AAAA;AAAA,QAGN,KAAK;AAAA,UACH;AAAA,QAAA;AAAA,QAEF,YAAY;AAAA;AAAA;AAAA,UAGV;AAAA,UACA;AAAA;AAAA;AAAA;AAAA,UAIA;AAAA,UACA;AAAA,QAAA;AAAA;AAAA,QAGF,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA;AAAA,UAGA;AAAA,QAAA;AAAA,QAEF,SAAS;AAAA;AAAA,QAET,UAAU;AAAA,UACR;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,UAAU;AAAA,UACR;AAAA,UACA;AAAA,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAWF,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAAA;AAAA,QAEF,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAAA;AAAA,QAEF,cAAc;AAAA,UACZ;AAAA,UACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMA;AAAA,QAAA;AAAA,QAEF,QAAQ;AAAA,QACR,GAAG;AAAA,MAAA;AAAA,MAOL,QAAQ;AAAA,QACN,eAAe,MAAM;AAAA,QACrB,WAAW,MAAM;AAAA;AAAA,QAEjB,gBAAgB,CAAC,MAAM,cAAc;AACnC,cAAI,QAAQ,aAAa,OAAO,IAAI;AACpC,cAAI,UAAU,MAAO,SAAQ,MAAM,KAAK;AACxC,cAAI,UAAU,SAAU,SAAQ,GAAG,KAAK;AACxC,iBAAO;AAAA,QACT;AAAA;AAAA,QAEA,eAAe,CAAC,MAAM,cAAc;AAClC,cAAI,QAAQ,aAAa,OAAO,IAAI;AACpC,cAAI,uCAAW,MAAO,SAAQ,MAAM,KAAK;AACzC,iBAAO;AAAA,QACT;AAAA,QACA,WAAW,CAAC,SAAS,cAAc,OAAO,IAAI;AAAA,QAC9C,cAAc,CAAC,SAAS,WAAW,OAAO,IAAI;AAAA;AAAA;AAAA,QAG9C,oBAAoB,MAAM;AAAA,QAC1B,mBAAmB,MAAM;AAAA,QACzB,iBAAiB,CAAC,eAAe,KAAK,UAAU;AAAA,QAChD,uBAAuB,MAAM;AAAA,QAC7B,GAAG;AAAA,MAAA;AAAA,MAEL,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUV,qBAAqB,CAAC,EAAE,WAAAC,YAAW,UAAU,WAAW,GAAGC,OAAAA,MACzD;AAAA,UAAC;AAAA,UAAA;AAAA,YAAO,SAAQ;AAAA,YAAO,MAAK;AAAA,YAAK,UAAQ;AAAA,YAAC,WAAW;AAAA,YACnD,WAAWD;AAAAA,YAAY,GAAGC;AAAAA,UAAA;AAAA,QAAA;AAAA,QAE9B,iBAAiB,CAAC,EAAE,WAAAD,YAAW,UAAU,WAAW,GAAGC,OAAAA,MACrD;AAAA,UAAC;AAAA,UAAA;AAAA,YAAO,SAAQ;AAAA,YAAO,MAAK;AAAA,YAAK,UAAQ;AAAA,YAAC,WAAW;AAAA,YACnD,WAAWD;AAAAA,YAAY,GAAGC;AAAAA,UAAA;AAAA,QAAA;AAAA,MAAO;AAAA,MAGtC,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACD,SAAS,cAAc;AAIhB,MAAM,eAAe;AAAA,EAC1B,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EACR,UAAU,CAAA;AAAA,EAGV,OAAO,CAAA;AAAA;AAAA;AAAA,EAKP,QAAQ,CAAC,WAAW,SAAS,YAAY,iBAAiB,UAAU;AAAA,EACpE,QAAQ;AAAA,IACN,IAAI,CAAC,eAAe,uBAAuB,kBAAkB,cAAc,oBAAoB,gBAAgB;AAAA,IAC/G,IAAI,CAAC,oBAAoB,iBAAiB,mBAAmB,kBAAkB;AAAA,IAC/E,MAAM,CAAC,gBAAgB,WAAW;AAAA,EAAA;AAEtC;"}
1
+ {"version":3,"file":"date-grid.js","sources":["../../../src/components/DateGrid/date-grid.tsx"],"sourcesContent":["/**\n * @internal — DS-internal 單元(per `.claude/rules/ui-development.md` Public vs Internal canonical;spec frontmatter `isInternal`)。\n * 不進 root barrel front-door;由 DatePicker wrap 消費,end-user app 請用 wrapper 元件。\n */\n// @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.\n// M22 retrofit DONE 2026-05-03 v11(real source URLs added inline at lines 38 + 111)\nimport * as React from 'react'\nimport { DayPicker } from 'react-day-picker'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport 'react-day-picker/style.css'\n\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/design-system/components/Button/button'\n\n/**\n * DateGrid — DayPicker 包裝,用本 DS token 覆寫預設視覺。\n *\n * ── 視覺對照(ref/datepicker.png,2026-04-21 rewrite)──\n *\n * | 區塊 | 規格 |\n * |------|------|\n * | Outer padding | `p-3`(12px 四邊對稱) |\n * | Nav + Month caption row | h-field-xs(24px)單行,chevron(xs)分居左右 / 月份置中垂直對齊 |\n * | Nav → Weekday gap | 12px(month_caption mb-3) |\n * | Weekday | text-body(14px)text-foreground font-medium(neutral-9,同 caption 權重;撤銷 v3 fg-secondary) |\n * | Cell gap(水平 + 垂直)| 4px(table-native border-separate border-spacing-1;非 gap — grid 會 break,見下方 v7 註) |\n * | Day cell size | h-field-sm w-[var(--field-height-sm)](28×28 md / 32×32 lg) |\n * | Day button | rounded-full 填滿 cell |\n *\n * ── 五種 cell state canonical ──\n *\n * | State | 視覺 | Token |\n * |-------|------|-------|\n * | today | 數字下方藍色短桿 | `::after` pseudo bar(bg-primary,w-40% h-1.5px rounded-full,貼近數字底)|\n * | disabled | 灰底圓圈 + disabled 字色(跟 Button disabled 一致) | [&>button]:bg-disabled [&>button]:text-fg-disabled rounded-full |\n * | outside(非本月) | text-fg-muted(neutral-7) | [&>button]:text-fg-muted |\n * | selected / range 端點 | 藍底白字圓 | [&>button]:bg-primary [&>button]:text-on-emphasis rounded-full |\n * | range middle | 灰底矩形 track(bg-neutral-selected = neutral-2),**高度 = cell 高度**(28×28 @ md) | before pseudo: `inset-y-0 -inset-x-[2px]` |\n * | range start/end 半圓 track | 左/右半圓 + selected 圓疊在上,**圓半徑 = button 半徑** | before pseudo: `rounded-l/r-full` + start `left-0 -right-[2px]` / end `-left-[2px] right-0`(向 middle 外擴 2px bridge gap)|\n * | hover(未選中) | 藍圈 outline | hover:ring-[1.5px] hover:ring-primary-hover(2026-07-07 統一:瞬時 hover = hover 階)|\n *\n * ── Range track 高度 canonical(2026-05-03 v6,M8 4 家對照)──\n * Ant Design([picker source](https://github.com/ant-design/ant-design/blob/master/components/date-picker/style/panel.ts))/ Material X DateRangePicker([mui-x source](https://github.com/mui/mui-x/tree/master/packages/x-date-pickers-pro/src/DateRangeCalendar))/ Apple Calendar `@benchmark-unverified`(closed-source)/ Google Calendar `@benchmark-unverified`(closed-source)共識:\n * **range track 為連續 stadium**,跟 selected 圓緊貼成連續 pill。\n * 實作:bg 走 `before:` pseudo 用 `inset-y-0`(滿 cell 高度)+ `-inset-x-[2px]`\n * (左右各外擴 2px bridge 相鄰 cell gap)→ 相鄰 cell 的 pseudo 連續銜接 = 橫向連貫;\n * day cell 本身就是 button 容器(L102-105 day = h-field-sm cell),故滿 cell 高 = 滿 button 高。\n *\n * ── Range track 色用 bg-neutral-selected(= neutral-2)──\n * 對齊 TimePicker 選中項目樣式(semantic `--neutral-selected` = neutral-2,semantic.css L84/L340)。\n * 同 DS 內「持續選中」語意 token,不自開 neutral-3 tier。\n *\n * ── 為什麼 nav 放頂部 + 年月垂直置中(不 separate 兩行)──\n * ref/datepicker.png:chevron prev / 月份 / chevron next 同一行,24px 高(xs field height)。\n * 省垂直空間,使用者視線不需上下跳。世界級(Google Calendar / Apple / iOS 日期輸入)皆此佈局。\n */\n\nexport type DateGridProps = React.ComponentProps<typeof DayPicker>\n\n// ── SR label 中文 formatter(2026-07-05)──\n// 走 Intl.DateTimeFormat(對齊 TimePicker / Calendar 既有 canonical,不引第二套 date lib);\n// module-level 建一次 — label fn 每個 day cell 都會呼叫,避免 per-call new formatter。\nconst ZH_FULL_DATE = new Intl.DateTimeFormat('zh-TW', { dateStyle: 'full' })\nconst ZH_MONTH_YEAR = new Intl.DateTimeFormat('zh-TW', { year: 'numeric', month: 'long' })\nconst ZH_WEEKDAY = new Intl.DateTimeFormat('zh-TW', { weekday: 'long' })\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst DateGrid = React.forwardRef<HTMLDivElement, DateGridProps>(function DateGrid(\n {\n className,\n classNames,\n labels,\n showOutsideDays = true,\n ...props\n },\n _ref,\n) {\n // Note: react-day-picker v9 DayPicker 未對外 forward ref 到單一 DOM 節點(內部有多 div),\n // 故 ref 簽名保留但不附著(符合 DS 統一 forwardRef 慣例;真要取 DOM 用 wrapper 包)。\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n // navLayout=\"around\" = prev 渲染在首月(displayIndex===0)caption 左、next 渲染在末月(displayIndex===numberOfMonths-1)caption 右;單月時兩鍵同 caption 兩側\n // 取代先前 absolute 定位覆蓋整個 months 容器導致箭頭垂直置中於中段的 bug\n navLayout=\"around\"\n // p-3 = 12px 四邊對稱(canonical 不可動)\n className={cn('p-3', className)}\n classNames={{\n months: 'flex flex-col sm:flex-row gap-4',\n // Month:relative 讓 prev/next 按鈕 absolute 定位到 month 右上/左上(navLayout=\"around\")\n month: 'flex flex-col relative',\n // Month caption:單行置中 h-field-xs,prev/next 按鈕 absolute 從兩側貼齊\n month_caption: 'flex items-center justify-center h-field-xs mb-3',\n caption_label: 'text-body font-medium',\n // ── Prev/Next button(canonical 2026-05-03 v6,user audit fix)──\n // RDP 把這 className apply 到 <Button> 本身(不是 wrapper),所以用 className 直接套\n // 定位類(absolute top/left/right-0)。muted 色透過 Button override 內部加,不用 [&>button] 黑魔法。\n button_previous: 'absolute top-0 left-0 z-[1]',\n button_next: 'absolute top-0 right-0 z-[1]',\n // ── Grid layout(canonical 2026-05-03 v7,純 table-native)──\n // RDP v9 month_grid = <table>。v6 試 grid 在 tr 上但 break border-spacing(grid 蓋掉\n // table-row layout)。乾淨修:**純 table layout** + `border-spacing-1`(4px H+V,table-native)。\n // 所有 cells 自動同寬同高(td 的 w/h-field-sm),無 grid hack。\n month_grid: 'border-separate border-spacing-1',\n weekdays: '', // thead default\n weekday: cn(\n // text-foreground + font-medium 對齊 DS 一致設計語言(2026-05-03 user audit):\n // weekday 列標跟 caption「April 2026」同視覺權重(都屬 calendar header 區),\n // 不弱化(撤銷 v3 fg-secondary 的 mistake)。對齊 icon-only Button 預設 neutral-9 一致。\n 'text-foreground text-body font-medium',\n // h-field-sm(md=28/lg=32 隨 density):對齊 day cell 同 token 同 row cadence\n // (spec:127 既定 canonical;Ant 36/36、Carbon 40/40 header/day 同節奏;2026-07-14 修 h-7 固定 drift)\n 'h-[var(--field-height-sm)] align-middle text-center',\n ),\n week: '', // tr default\n // Cell **就是** button 容器(28×28 @ md / 32×32 @ lg),`relative` 讓 before pseudo 定位\n // ── h-field-sm 對齊 user spec(28×28 @ md)— v3 用 h-field-md (32×32) 是錯的\n day: cn(\n 'h-field-sm w-[var(--field-height-sm)] p-0 text-center relative',\n ),\n day_button: cn(\n // absolute inset-0 = 完全填滿 cell(naked button,無 inset 4px 空隙)\n // z-[1] 讓 button 疊在 range track `before:` pseudo 之上\n 'absolute inset-0 z-[1] flex items-center justify-center',\n 'font-normal text-body rounded-full transition-colors',\n // Hover 藍圈 1.5px(對齊 Apple HIG / Ant `@benchmark-unverified` visual ring measurement)— ring 在 button 之上 + 透明 bg 不擋 range track\n // 2026-07-07 user 拍板統一:瞬時 hover 進 primary 家族 = hover 階(FileUpload dropzone /\n // Slider thumb hover 同族;base 專屬持續選中與 focus)——ring-primary → ring-primary-hover\n 'hover:ring-[1.5px] hover:ring-primary-hover hover:bg-transparent',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n ),\n // today:藍色 underline bar 貼近數字\n today: cn(\n \"[&>button]:after:content-['']\",\n '[&>button]:after:absolute',\n '[&>button]:after:bottom-[5px] [&>button]:after:left-1/2 [&>button]:after:-translate-x-1/2',\n '[&>button]:after:w-[40%] [&>button]:after:h-[1.5px] [&>button]:after:rounded-full',\n '[&>button]:after:bg-primary',\n // today + selected:bar 切 on-emphasis(白)— 只為「藍底白字圓」的選中日/端點設計;\n // range 中段(淺灰底)由 range_middle 的 !bg-primary 覆寫回藍(2026-07-07 user 拍板)。\n '[&[data-selected=true]>button]:after:bg-on-emphasis',\n ),\n outside: '[&>button]:text-fg-muted',\n // Selected(single 或 range 端點):button 藍底白字圓\n selected: cn(\n '[&>button]:bg-primary [&>button]:text-on-emphasis',\n '[&>button]:hover:bg-primary-hover [&>button]:hover:ring-0',\n ),\n disabled: cn(\n '[&>button]:bg-disabled [&>button]:text-fg-disabled [&>button]:cursor-not-allowed',\n '[&>button]:hover:ring-0 [&>button]:hover:bg-disabled',\n ),\n // ── Range track(canonical 2026-05-03 v6,Ant stadium pattern)──\n // v5 用 pseudo 矩形蓋全 cell 修「白色破圖」,但新副作用:button 圓比矩形小,4 個\n // corner triangle 區域 pseudo grey 凸出圓外(user 2026-05-03 抓到「凸出去」)。\n // 對齊 Ant 實證(`cell-range-start::before { border-radius: 9999px 0 0 9999px }`):\n // rangeStart pseudo 加 `rounded-l-full` → pseudo 變「左半圓 + 右矩形」stadium\n // 左半圓 EXACTLY OVERLAY button 圓的左半圓(同 center,同 radius 14)→ 邊界無縫\n // 右側矩形 bridge 2px to middle → 跟 middle pseudo 連續\n // Cell 的 top-left + bottom-left corner triangle:pseudo 不蓋 + button 不蓋 →\n // popover white 顯露(乾淨 breathing,跟 outside-of-range cells 一致視覺)\n range_start: cn(\n \"before:content-[''] before:absolute before:inset-y-0\",\n 'before:left-0 before:-right-[2px]',\n 'before:bg-neutral-selected before:pointer-events-none',\n 'before:rounded-l-full', // ← stadium 左半圓 matches button 圓的左半弧\n ),\n range_end: cn(\n \"before:content-[''] before:absolute before:inset-y-0\",\n 'before:-left-[2px] before:right-0',\n 'before:bg-neutral-selected before:pointer-events-none',\n 'before:rounded-r-full', // ← 鏡像\n ),\n range_middle: cn(\n \"before:content-[''] before:absolute before:inset-y-0 before:-inset-x-[2px]\",\n 'before:bg-neutral-selected before:pointer-events-none',\n // 2026-07-07 user 拍板:range 中段的 today bar 維持藍(切白只屬藍底選中日;白條在\n // neutral-selected 淺灰底上近乎隱形 = today 標記消失)。!important 確定性壓過 today 的\n // data-selected 切白規則(同權重靠 stylesheet 順序不可靠)。Ant 源碼實錘:cell-today\n // 指示 = colorPrimary,in-range 只換底色、無規則隱藏/改色 today 指示(panel.ts)。\n // 非 today 的中段日無 after content,本規則無作用 — 安全。\n '[&>button]:after:!bg-primary',\n // button 透明顯露 track。2026-07-05 對齊 RDP v9 真實行為(deep-audit A.1b):\n // range 中段日同樣掛 selected modifier(useRange rangeIncludesDate 不排除中段)→\n // 上方 selected 的 `[&>button]:hover:ring-0` 一併壓制 hover ring(與 selected 一致\n // 的 hover 抑制),非原註解宣稱的「hover ring 仍顯示」;today bar 亦被 data-selected\n // selector 切 on-emphasis(見 spec「組合狀態」段)。\n '[&>button]:!bg-transparent [&>button]:!text-foreground',\n ),\n hidden: 'invisible',\n ...classNames,\n }}\n // ── SR label 中文 defaults(2026-07-05,RDP labels API 正門)──\n // 對齊 MUI X localeText「預設可覆寫」idiom + 2026-07-04 全庫 SR label 中文\n // canonical(commit 241676c6):DS 給中文 default,consumer 傳 labels 逐鍵覆寫(i18n)。\n // 禁在 components override 內 spread 後 hardcode aria-label — 會蓋死此覆寫通道\n // (2026-07-05 修正 07-04 的錯誤修法:中文要走 labels 正門,不是蓋 RDP 算好的值)。\n labels={{\n labelPrevious: () => '上一個月',\n labelNext: () => '下一個月',\n // 鏡射 RDP default 結構(labels/labelDayButton.js:today 前綴 / selected 後綴),文案中文化\n labelDayButton: (date, modifiers) => {\n let label = ZH_FULL_DATE.format(date)\n if (modifiers.today) label = `今天,${label}`\n if (modifiers.selected) label = `${label},已選取`\n return label\n },\n // 未傳 mode 的非互動 grid(spec「mode 無預設值」段)day cell 走 labelGridcell\n labelGridcell: (date, modifiers) => {\n let label = ZH_FULL_DATE.format(date)\n if (modifiers?.today) label = `今天,${label}`\n return label\n },\n labelGrid: (date) => ZH_MONTH_YEAR.format(date),\n labelWeekday: (date) => ZH_WEEKDAY.format(date),\n // 以下非 default 渲染面(captionLayout dropdown / showWeekNumber 由 consumer 經\n // {...props} 開啟)— 一併補齊,避免開啟後 SR 中英夾雜\n labelMonthDropdown: () => '選擇月份',\n labelYearDropdown: () => '選擇年份',\n labelWeekNumber: (weekNumber) => `第 ${weekNumber} 週`,\n labelWeekNumberHeader: () => '週數',\n ...labels,\n }}\n components={{\n // ── Prev/Next nav(canonical 2026-05-03 v9,DS 一致設計語言)──\n // User 2026-05-03 audit:「icon-only Button icon 都用 neutral-9,只有 dismiss 用 45%」\n // → chevron 不是 dismiss,**走 Button 預設 text-foreground**(neutral-9 85%),\n // 不開新 tier 自打嘴(撤銷 v6-v8 用 fg-muted override 的 mistake)。\n // RDP v9 `PreviousMonthButton / NextMonthButton` override(node_modules/react-day-picker/dist/esm/components/Nav.js)\n // ⚠️ children: _ 必丟棄(RDP 把 <Chevron> 當 children 傳 → 跟 Button startIcon 重疊變 double chevron)\n // 2026-07-05 修:此處**不** hardcode aria-label — 中文走上方 labels API 正門,\n // RDP 算好 labelPrevious()/labelNext() 後經 {...props} 流入 Button;\n // spread 後 hardcode(07-04 舊修法)= 蓋死 consumer labels 覆寫通道。\n PreviousMonthButton: ({ className, children: _children, ...props }) => (\n <Button variant=\"text\" size=\"xs\" iconOnly startIcon={ChevronLeft}\n className={className} {...props} />\n ),\n NextMonthButton: ({ className, children: _children, ...props }) => (\n <Button variant=\"text\" size=\"xs\" iconOnly startIcon={ChevronRight}\n className={className} {...props} />\n ),\n }}\n {...props}\n />\n )\n})\nDateGrid.displayName = 'DateGrid'\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 dateGridMeta = {\n component: 'DateGrid',\n family: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n // 'selected' = 選中日期 / range 端點持續選中(藍底白字圓 bg-primary + range 帶 bg-neutral-selected);\n // 'active' 移除 — 全檔無 Tailwind 按壓 utility,無按壓專屬視覺態(2026-07-07 詞彙統一對抗稽核補修)。\n states: ['default', 'hover', 'selected', 'focus-visible', 'disabled'],\n tokens: {\n bg: ['bg-disabled', 'bg-neutral-selected', 'bg-on-emphasis', 'bg-primary', 'bg-primary-hover', 'bg-transparent'],\n fg: ['text-fg-disabled', 'text-fg-muted', 'text-foreground', 'text-on-emphasis'],\n ring: ['ring-primary', 'ring-ring'],\n },\n} as const\n\nexport { DateGrid }\n"],"names":["DateGrid","className","props"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { FieldMode, FieldVariant } from '../../components/Field/field-types';
2
+ import type { FieldMode, FieldVariant, FieldWidth } from '../../components/Field/field-types';
3
3
  import { type TimeStep } from '../../components/TimePicker/time-columns';
4
4
  export interface DateFormatOptions {
5
5
  /** Intl.DateTimeFormat options(預設 { year: 'numeric', month: '2-digit', day: '2-digit' }) */
@@ -12,6 +12,9 @@ export interface DatePickerProps extends DateFormatOptions, Omit<React.HTMLAttri
12
12
  mode?: FieldMode;
13
13
  /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */
14
14
  variant?: FieldVariant;
15
+ /** 寬度軸 — `fill` 填滿容器(default)/ `hug` 依內容收縮(value 寬 + slot 寬 + gap + 內 padding);
16
+ * chrome 與互動不變。SSOT → field-controls.spec.md「寬度軸(width: fill / hug)」。 */
17
+ width?: FieldWidth;
15
18
  error?: boolean;
16
19
  size?: 'sm' | 'md' | 'lg';
17
20
  /** ISO date(YYYY-MM-DD)或 ISO datetime(YYYY-MM-DDTHH:MM:SS,當 showTime=true) */
@@ -76,6 +79,9 @@ export interface DatePickerRangeProps extends DateFormatOptions, Omit<React.HTML
76
79
  mode?: FieldMode;
77
80
  /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */
78
81
  variant?: FieldVariant;
82
+ /** 寬度軸 — `fill` 填滿容器(default)/ `hug` 依內容收縮(value 寬 + slot 寬 + gap + 內 padding);
83
+ * chrome 與互動不變。SSOT → field-controls.spec.md「寬度軸(width: fill / hug)」。 */
84
+ width?: FieldWidth;
79
85
  error?: boolean;
80
86
  size?: 'sm' | 'md' | 'lg';
81
87
  /** 區間值:[start ISO, end ISO]。任一 null 代表尚未選。 */
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/DatePicker/date-picker.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/DatePicker/date-picker.tsx"],"names":[],"mappings":"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"}
@@ -2,13 +2,13 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { ArrowRight, Calendar, X } from "lucide-react";
4
4
  import { cn } from "../../lib/utils.js";
5
- import { EMPTY_DISPLAY, nakedCellRowModeAlign, fieldWrapperStyles, bareInputStyles, fieldDisplayTextClass } from "../Field/field-wrapper.js";
5
+ import { nakedCellRowModeAlign, fieldWrapperStyles, bareInputStyles, fieldDisplayTextClass } from "../Field/field-wrapper.js";
6
6
  import { ICON_SIZE, ItemSuffix, ItemInlineAction } from "../../patterns/element-anatomy/item-anatomy.js";
7
7
  import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../Popover/popover.js";
8
8
  import { DateGrid } from "../DateGrid/date-grid.js";
9
9
  import { Button } from "../Button/button.js";
10
10
  import { SurfaceFooter } from "../../patterns/overlay-surface/overlay-surface.js";
11
- import { useFieldContext, useResolvedFieldSize, useResolvedFieldInvalid, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant } from "../Field/field-context.js";
11
+ import { useFieldContext, useResolvedFieldSize, useResolvedFieldInvalid, useResolvedFieldDisabled, useResolvedFieldMode, useFieldEmptyDisplay, useResolvedFieldVariant, fieldEmptyColorClass } from "../Field/field-context.js";
12
12
  import { isoToTimeParts, timePartsToString, TimeColumns } from "../TimePicker/time-columns.js";
13
13
  const dtfCache = /* @__PURE__ */ new Map();
14
14
  function getDateTimeFormatter(locale, options) {
@@ -21,7 +21,7 @@ function getDateTimeFormatter(locale, options) {
21
21
  return fmt;
22
22
  }
23
23
  function formatDate(value, options = {}) {
24
- const date = value instanceof Date ? value : new Date(value);
24
+ const date = value instanceof Date ? value : typeof value === "string" ? isoToDate(value) ?? new Date(value) : new Date(value);
25
25
  if (Number.isNaN(date.getTime())) return String(value);
26
26
  if (options.formatOptions || options.locale) {
27
27
  return getDateTimeFormatter(options.locale ?? "en-US", options.formatOptions ?? { year: "numeric", month: "2-digit", day: "2-digit" }).format(date);
@@ -59,6 +59,7 @@ function parseDateInput(input, opts) {
59
59
  const [, y, m, d, hh, mm, ss] = isoDateMatch;
60
60
  const date = new Date(Number(y), Number(m) - 1, Number(d), Number(hh ?? 0), Number(mm ?? 0), Number(ss ?? 0));
61
61
  if (isNaN(date.getTime()) || date.getMonth() !== Number(m) - 1) return { iso: null, valid: false };
62
+ if (hh != null && (Number(hh) > 23 || Number(mm) > 59 || Number(ss ?? 0) > 59)) return { iso: null, valid: false };
62
63
  const datePart = dateToIso(date);
63
64
  if (hh != null && opts.allowTime) {
64
65
  const h2 = String(Number(hh)).padStart(2, "0");
@@ -146,6 +147,7 @@ const DatePicker = React.forwardRef(
146
147
  ({
147
148
  mode,
148
149
  variant: variantProp,
150
+ width,
149
151
  error: errorProp = false,
150
152
  size: sizeProp,
151
153
  value,
@@ -177,6 +179,7 @@ const DatePicker = React.forwardRef(
177
179
  const error = useResolvedFieldInvalid(errorProp);
178
180
  const disabled = useResolvedFieldDisabled(disabledProp);
179
181
  const resolvedMode = useResolvedFieldMode({ mode, disabled });
182
+ const emptyDisplay = useFieldEmptyDisplay();
180
183
  const variant = useResolvedFieldVariant(variantProp);
181
184
  const isEditable = resolvedMode === "edit";
182
185
  const iconSize = ICON_SIZE[size];
@@ -191,7 +194,7 @@ const DatePicker = React.forwardRef(
191
194
  const accessibleName = ariaLabelProp ?? (ariaLabelledByProp ? void 0 : (fieldCtx == null ? void 0 : fieldCtx.id) ? void 0 : resolvedPlaceholder);
192
195
  const lastOpenRef = React.useRef(open);
193
196
  React.useEffect(() => {
194
- if (!lastOpenRef.current && open) setDraft(value ?? null);
197
+ if (!open || !lastOpenRef.current) setDraft(value ?? null);
195
198
  lastOpenRef.current = open;
196
199
  }, [open, value]);
197
200
  const displayValue = needConfirm ? draft : value ?? null;
@@ -229,16 +232,16 @@ const DatePicker = React.forwardRef(
229
232
  }, [onChange, showTime]);
230
233
  if (resolvedMode === "display") {
231
234
  if (!showDisplayEndIcon) {
232
- if (!value) return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "text-fg-muted", className), children: EMPTY_DISPLAY });
235
+ if (!value) return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), fieldEmptyColorClass(resolvedMode), className), children: emptyDisplay });
233
236
  return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "truncate", className), children: displayCommitted });
234
237
  }
235
238
  return /* @__PURE__ */ jsxs(
236
239
  "div",
237
240
  {
238
- className: cn(fieldWrapperStyles({ mode: "display", variant, size }), className),
241
+ className: cn(fieldWrapperStyles({ mode: "display", variant, width, size }), className),
239
242
  "data-field-mode": "display",
240
243
  children: [
241
- /* @__PURE__ */ jsx("span", { className: cn(bareInputStyles, "flex-1 min-w-0 truncate", !value && "text-fg-muted"), children: value ? displayCommitted : EMPTY_DISPLAY }),
244
+ /* @__PURE__ */ jsx("span", { className: cn(bareInputStyles, "flex-1 min-w-0 truncate", !value && fieldEmptyColorClass(resolvedMode)), children: value ? displayCommitted : emptyDisplay }),
242
245
  /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: "text-fg-muted", "aria-hidden": true }) })
243
246
  ]
244
247
  }
@@ -248,12 +251,12 @@ const DatePicker = React.forwardRef(
248
251
  return /* @__PURE__ */ jsxs(
249
252
  "div",
250
253
  {
251
- className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size }), className),
254
+ className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, width, size }), className),
252
255
  "data-field-mode": resolvedMode,
253
256
  "aria-disabled": resolvedMode === "disabled" ? true : void 0,
254
257
  ...props,
255
258
  children: [
256
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", resolvedMode === "disabled" && "text-fg-disabled"), children: value ? displayCommitted : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: EMPTY_DISPLAY }) }),
259
+ /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", resolvedMode === "disabled" && "text-fg-disabled"), children: value ? displayCommitted : /* @__PURE__ */ jsx("span", { className: fieldEmptyColorClass(resolvedMode), children: emptyDisplay }) }),
257
260
  (variant === "naked" ? showDisplayEndIcon : resolvedMode === "disabled") && /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: resolvedMode === "disabled" ? "text-fg-disabled" : "text-fg-muted", "aria-hidden": true }) })
258
261
  ]
259
262
  }
@@ -277,18 +280,18 @@ const DatePicker = React.forwardRef(
277
280
  "div",
278
281
  {
279
282
  ref,
280
- id: idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
281
- role: "combobox",
282
- tabIndex: disabled ? -1 : 0,
283
- "aria-disabled": disabled || void 0,
284
- "aria-label": accessibleName,
285
- "aria-labelledby": ariaLabelledByProp ?? (fieldCtx == null ? void 0 : fieldCtx.labelId),
286
- "aria-invalid": error || void 0,
287
- "aria-required": (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
288
- "aria-describedby": ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
289
- "aria-errormessage": ariaErrorMessageProp ?? (error ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
290
- "aria-haspopup": "dialog",
291
- "aria-expanded": open,
283
+ id: typeable ? void 0 : idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
284
+ role: typeable ? void 0 : "combobox",
285
+ tabIndex: typeable ? void 0 : disabled ? -1 : 0,
286
+ "aria-disabled": typeable ? void 0 : disabled || void 0,
287
+ "aria-label": typeable ? void 0 : accessibleName,
288
+ "aria-labelledby": typeable ? void 0 : ariaLabelledByProp ?? (fieldCtx == null ? void 0 : fieldCtx.labelId),
289
+ "aria-invalid": typeable ? void 0 : error || void 0,
290
+ "aria-required": typeable ? void 0 : (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
291
+ "aria-describedby": typeable ? void 0 : ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
292
+ "aria-errormessage": typeable ? void 0 : ariaErrorMessageProp ?? (error ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
293
+ "aria-haspopup": typeable ? void 0 : "dialog",
294
+ "aria-expanded": typeable ? void 0 : open,
292
295
  "data-field-mode": "edit",
293
296
  "data-error": error ? "" : void 0,
294
297
  onKeyDown: typeable ? void 0 : (e) => {
@@ -299,7 +302,7 @@ const DatePicker = React.forwardRef(
299
302
  if (e.key === "Escape") setOpen(false);
300
303
  },
301
304
  className: cn(
302
- fieldWrapperStyles({ mode: "edit", variant, size, error }),
305
+ fieldWrapperStyles({ mode: "edit", variant, width, size, error }),
303
306
  "text-left cursor-pointer",
304
307
  "focus-visible:outline-none",
305
308
  className
@@ -310,10 +313,23 @@ const DatePicker = React.forwardRef(
310
313
  // Issue 10 typed input(2026-05-10):real `<input>` 接 user 鍵盤打字。
311
314
  // Click 在 input 上不 propagate 給外層 popover trigger(避免每次打字都開 popover)。
312
315
  // Calendar icon `<ItemSuffix>` 點才開 popover(Material/Ant typed-date idiom)。
316
+ // a11y(2026-07-14 dim-10 修):input 持完整 combobox 語意(id/name/state,APG
317
+ // editable-combobox)— 外層 div 已讓位(見上方 role/tabIndex 註解);ArrowDown
318
+ // 開 popover 補鍵盤開啟路徑(原僅 icon click 可開,鍵盤 user 無入口)。
313
319
  /* @__PURE__ */ jsx(
314
320
  "input",
315
321
  {
316
322
  type: "text",
323
+ id: idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
324
+ role: "combobox",
325
+ "aria-haspopup": "dialog",
326
+ "aria-expanded": open,
327
+ "aria-label": accessibleName,
328
+ "aria-labelledby": ariaLabelledByProp ?? (fieldCtx == null ? void 0 : fieldCtx.labelId),
329
+ "aria-required": (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
330
+ "aria-describedby": ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
331
+ "aria-errormessage": ariaErrorMessageProp ?? (inputInvalid || error ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
332
+ disabled,
317
333
  className: cn(bareInputStyles, "truncate", !inputDraft && "placeholder:text-fg-muted"),
318
334
  value: inputDraft,
319
335
  placeholder: resolvedPlaceholder,
@@ -339,6 +355,10 @@ const DatePicker = React.forwardRef(
339
355
  setInputInvalid(false);
340
356
  e.preventDefault();
341
357
  }
358
+ if (e.key === "ArrowDown" && !open) {
359
+ e.preventDefault();
360
+ setOpen(true);
361
+ }
342
362
  },
343
363
  onBlur: () => {
344
364
  if (!composingRef.current) handleInputCommit(inputDraft);
@@ -371,56 +391,64 @@ const DatePicker = React.forwardRef(
371
391
  ]
372
392
  }
373
393
  ) }),
374
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsxs("div", { role: "dialog", className: "flex flex-col flex-1 min-h-0", children: [
375
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
376
- CalendarTimeContainer,
377
- {
378
- showTime,
379
- showSeconds,
380
- calendar: /* @__PURE__ */ jsx(
381
- DateGrid,
382
- {
383
- mode: "single",
384
- selected: displayDate,
385
- onSelect: (date) => {
386
- if (!date) return;
387
- if (showTime) {
388
- commitDraft(combineDateAndTime(date, draftTime));
389
- } else {
390
- commitDraft(dateToIso(date));
391
- if (!needConfirm) setOpen(false);
392
- }
393
- },
394
- defaultMonth: displayDate ?? void 0,
395
- autoFocus: true
396
- }
397
- ),
398
- timePanel: /* @__PURE__ */ jsx(
399
- TimePickerSidePanel,
394
+ /* @__PURE__ */ jsx(
395
+ PopoverContent,
396
+ {
397
+ className: "w-auto p-0",
398
+ align: "start",
399
+ "aria-label": "日期選擇",
400
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-h-0", children: [
401
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
402
+ CalendarTimeContainer,
400
403
  {
401
- value: draftTime,
402
- onChange: (time) => {
403
- const target = draftDate ?? /* @__PURE__ */ new Date();
404
- commitDraft(combineDateAndTime(target, time));
405
- },
404
+ showTime,
406
405
  showSeconds,
407
- minuteStep,
408
- secondStep
406
+ calendar: /* @__PURE__ */ jsx(
407
+ DateGrid,
408
+ {
409
+ mode: "single",
410
+ selected: displayDate,
411
+ onSelect: (date) => {
412
+ if (!date) return;
413
+ if (showTime) {
414
+ commitDraft(combineDateAndTime(date, draftTime));
415
+ } else {
416
+ commitDraft(dateToIso(date));
417
+ if (!needConfirm) setOpen(false);
418
+ }
419
+ },
420
+ defaultMonth: displayDate ?? void 0,
421
+ autoFocus: true
422
+ }
423
+ ),
424
+ timePanel: /* @__PURE__ */ jsx(
425
+ TimePickerSidePanel,
426
+ {
427
+ value: draftTime,
428
+ onChange: (time) => {
429
+ const target = draftDate ?? /* @__PURE__ */ new Date();
430
+ commitDraft(combineDateAndTime(target, time));
431
+ },
432
+ showSeconds,
433
+ minuteStep,
434
+ secondStep
435
+ }
436
+ )
409
437
  }
410
- )
411
- }
412
- ) }),
413
- (showTime || needConfirm) && // Footer:消費 SurfaceFooter SSOT(border-t + canonical px-loose py-tight padding,
414
- // 不再 hand-coded p-2 / Separator / ml-auto wrapper 三層垃圾)
415
- // 「此刻」加 mr-auto 把後面 button 推右(對齊 Ant `marginInlineStart: auto` on OK)。
416
- // 2026-07-05 D4:gate `showTime` `(showTime || needConfirm)` 對齊 Range(:1068)—
417
- // date-only `needConfirm` onSelect 只寫 draft 且不關 popover,footer「確定」是唯一
418
- // commit 路徑,原 gate 漏渲 footer = draft 永遠無法 commit 的死路。
419
- /* @__PURE__ */ jsxs(SurfaceFooter, { children: [
420
- /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleNow, className: "mr-auto", children: "此刻" }),
421
- needConfirm ? /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: handleConfirm, disabled: !draft, children: "確定" }) : /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: () => setOpen(false), children: "關閉" })
422
- ] })
423
- ] }) })
438
+ ) }),
439
+ (showTime || needConfirm) && // Footer:消費 SurfaceFooter SSOT(border-t + canonical px-loose py-tight padding,
440
+ // 不再 hand-coded p-2 / Separator / ml-auto wrapper 三層垃圾)
441
+ // 「此刻」加 mr-auto 把後面 button 推右(對齊 Ant `marginInlineStart: auto` on OK)。
442
+ // 2026-07-05 D4:gate `showTime` `(showTime || needConfirm)` 對齊 Range(:1068)—
443
+ // date-only `needConfirm` onSelect 只寫 draft 且不關 popover,footer「確定」是唯一
444
+ // commit 路徑,原 gate 漏渲 footer = draft 永遠無法 commit 的死路。
445
+ /* @__PURE__ */ jsxs(SurfaceFooter, { children: [
446
+ /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleNow, className: "mr-auto", children: "此刻" }),
447
+ needConfirm ? /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: handleConfirm, disabled: !draft, children: "確定" }) : /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: () => setOpen(false), children: "關閉" })
448
+ ] })
449
+ ] })
450
+ }
451
+ )
424
452
  ] });
425
453
  }
426
454
  );
@@ -429,6 +457,7 @@ const DatePickerRange = React.forwardRef(
429
457
  ({
430
458
  mode,
431
459
  variant: variantProp,
460
+ width,
432
461
  error: errorProp = false,
433
462
  size: sizeProp,
434
463
  value,
@@ -454,6 +483,7 @@ const DatePickerRange = React.forwardRef(
454
483
  const error = useResolvedFieldInvalid(errorProp);
455
484
  const disabled = useResolvedFieldDisabled(disabledProp);
456
485
  const resolvedMode = useResolvedFieldMode({ mode, disabled });
486
+ const emptyDisplay = useFieldEmptyDisplay();
457
487
  const variant = useResolvedFieldVariant(variantProp);
458
488
  const isEditable = resolvedMode === "edit";
459
489
  const iconSize = ICON_SIZE[size];
@@ -467,7 +497,7 @@ const DatePickerRange = React.forwardRef(
467
497
  const hasInteractedOutsideRef = React.useRef(false);
468
498
  const lastOpenRef = React.useRef(open);
469
499
  React.useEffect(() => {
470
- if (!lastOpenRef.current && open) setDraft(value ?? [null, null]);
500
+ if (!open || !lastOpenRef.current) setDraft(value ?? [null, null]);
471
501
  lastOpenRef.current = open;
472
502
  }, [open, value]);
473
503
  const startIso = (needConfirm ? draft[0] : value == null ? void 0 : value[0]) ?? null;
@@ -540,7 +570,7 @@ const DatePickerRange = React.forwardRef(
540
570
  }, [activeEnd, startDate, endDate]);
541
571
  if (resolvedMode === "display") {
542
572
  const hasAny = !!(startIso || endIso);
543
- if (!hasAny) return /* @__PURE__ */ jsx("span", { className: cn("text-fg-muted", className), children: EMPTY_DISPLAY });
573
+ if (!hasAny) return /* @__PURE__ */ jsx("span", { className: cn(fieldEmptyColorClass(resolvedMode), className), children: emptyDisplay });
544
574
  return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center min-w-0", nakedCellRowModeAlign, className), children: [
545
575
  /* @__PURE__ */ jsx("span", { className: cn("truncate", !startIso && "text-fg-muted"), children: startIso ? formatDateOrDateTime(startIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[0] }),
546
576
  /* @__PURE__ */ jsx(ArrowRight, { size: iconSize, className: "shrink-0 text-fg-muted mx-2", "aria-hidden": true }),
@@ -552,7 +582,7 @@ const DatePickerRange = React.forwardRef(
552
582
  "div",
553
583
  {
554
584
  ref,
555
- className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size }), className),
585
+ className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, width, size }), className),
556
586
  "data-field-mode": resolvedMode,
557
587
  "aria-disabled": resolvedMode === "disabled" ? true : void 0,
558
588
  ...props,
@@ -579,7 +609,7 @@ const DatePickerRange = React.forwardRef(
579
609
  "data-error": error ? "" : void 0,
580
610
  "data-state": open ? "open" : "closed",
581
611
  className: cn(
582
- fieldWrapperStyles({ mode: "edit", size, error }),
612
+ fieldWrapperStyles({ mode: "edit", width, size, error }),
583
613
  "cursor-text",
584
614
  className
585
615
  ),
@@ -645,6 +675,7 @@ const DatePickerRange = React.forwardRef(
645
675
  {
646
676
  className: "w-auto p-0",
647
677
  align: "start",
678
+ "aria-label": "日期區間選擇",
648
679
  onInteractOutside: () => {
649
680
  hasInteractedOutsideRef.current = true;
650
681
  },
@@ -656,7 +687,7 @@ const DatePickerRange = React.forwardRef(
656
687
  }
657
688
  hasInteractedOutsideRef.current = false;
658
689
  },
659
- children: /* @__PURE__ */ jsxs("div", { role: "dialog", "aria-label": "日期區間選擇", className: "flex flex-col flex-1 min-h-0", children: [
690
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-h-0", children: [
660
691
  /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
661
692
  CalendarTimeContainer,
662
693
  {