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

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 (548) hide show
  1. package/CLAUDE.md +1 -1
  2. package/dist/components/Alert/alert.d.ts +5 -0
  3. package/dist/components/Alert/alert.d.ts.map +1 -1
  4. package/dist/components/Alert/alert.js +4 -1
  5. package/dist/components/Alert/alert.js.map +1 -1
  6. package/dist/components/AppShell/app-shell.d.ts +1 -1
  7. package/dist/components/AppShell/app-shell.js.map +1 -1
  8. package/dist/components/AspectRatio/aspect-ratio.d.ts +2 -1
  9. package/dist/components/AspectRatio/aspect-ratio.d.ts.map +1 -1
  10. package/dist/components/AspectRatio/aspect-ratio.js +1 -1
  11. package/dist/components/AspectRatio/aspect-ratio.js.map +1 -1
  12. package/dist/components/Avatar/avatar.d.ts +3 -2
  13. package/dist/components/Avatar/avatar.d.ts.map +1 -1
  14. package/dist/components/Avatar/avatar.js +8 -3
  15. package/dist/components/Avatar/avatar.js.map +1 -1
  16. package/dist/components/Badge/badge.d.ts.map +1 -1
  17. package/dist/components/Badge/badge.js +2 -1
  18. package/dist/components/Badge/badge.js.map +1 -1
  19. package/dist/components/Breadcrumb/breadcrumb.d.ts +14 -1
  20. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -1
  21. package/dist/components/Breadcrumb/breadcrumb.js +9 -3
  22. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
  23. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +4 -1
  24. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
  25. package/dist/components/BulkActionBar/bulk-action-bar.js +2 -2
  26. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  27. package/dist/components/Button/button.d.ts +4 -4
  28. package/dist/components/Button/button.d.ts.map +1 -1
  29. package/dist/components/Button/button.js +73 -44
  30. package/dist/components/Button/button.js.map +1 -1
  31. package/dist/components/Button/index.d.ts +1 -0
  32. package/dist/components/Button/index.d.ts.map +1 -1
  33. package/dist/components/Button/index.js +3 -0
  34. package/dist/components/Button/index.js.map +1 -1
  35. package/dist/components/Calendar/calendar.d.ts +3 -1
  36. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  37. package/dist/components/Calendar/calendar.js +40 -17
  38. package/dist/components/Calendar/calendar.js.map +1 -1
  39. package/dist/components/Carousel/carousel.d.ts +1 -1
  40. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  41. package/dist/components/Carousel/carousel.js +3 -1
  42. package/dist/components/Carousel/carousel.js.map +1 -1
  43. package/dist/components/Chart/chart.d.ts.map +1 -1
  44. package/dist/components/Chart/chart.js +1 -1
  45. package/dist/components/Chart/chart.js.map +1 -1
  46. package/dist/components/Checkbox/checkbox.d.ts +6 -3
  47. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  48. package/dist/components/Checkbox/checkbox.js +26 -4
  49. package/dist/components/Checkbox/checkbox.js.map +1 -1
  50. package/dist/components/Checkbox/index.d.ts +1 -0
  51. package/dist/components/Checkbox/index.d.ts.map +1 -1
  52. package/dist/components/Checkbox/index.js +3 -0
  53. package/dist/components/Checkbox/index.js.map +1 -1
  54. package/dist/components/Chip/chip.d.ts +9 -3
  55. package/dist/components/Chip/chip.d.ts.map +1 -1
  56. package/dist/components/Chip/chip.js +46 -13
  57. package/dist/components/Chip/chip.js.map +1 -1
  58. package/dist/components/Coachmark/coachmark.d.ts +5 -3
  59. package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
  60. package/dist/components/Coachmark/coachmark.js +10 -7
  61. package/dist/components/Coachmark/coachmark.js.map +1 -1
  62. package/dist/components/Combobox/combobox.d.ts +3 -1
  63. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  64. package/dist/components/Combobox/combobox.js +11 -7
  65. package/dist/components/Combobox/combobox.js.map +1 -1
  66. package/dist/components/Command/command.d.ts +2 -2
  67. package/dist/components/Command/command.d.ts.map +1 -1
  68. package/dist/components/Command/command.js +4 -2
  69. package/dist/components/Command/command.js.map +1 -1
  70. package/dist/components/DataTable/active-editor-controller.d.ts +4 -3
  71. package/dist/components/DataTable/active-editor-controller.d.ts.map +1 -1
  72. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  73. package/dist/components/DataTable/cell-registry.js +3 -0
  74. package/dist/components/DataTable/cell-registry.js.map +1 -1
  75. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  76. package/dist/components/DataTable/data-table-interaction-layer.d.ts +4 -3
  77. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -1
  78. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  79. package/dist/components/DataTable/data-table.d.ts +38 -7
  80. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  81. package/dist/components/DataTable/data-table.js +213 -63
  82. package/dist/components/DataTable/data-table.js.map +1 -1
  83. package/dist/components/DataTable/filter-tree.d.ts +5 -0
  84. package/dist/components/DataTable/filter-tree.d.ts.map +1 -1
  85. package/dist/components/DateGrid/date-grid.d.ts +3 -3
  86. package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
  87. package/dist/components/DateGrid/date-grid.js +52 -6
  88. package/dist/components/DateGrid/date-grid.js.map +1 -1
  89. package/dist/components/DatePicker/date-picker.d.ts +2 -8
  90. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  91. package/dist/components/DatePicker/date-picker.js +139 -109
  92. package/dist/components/DatePicker/date-picker.js.map +1 -1
  93. package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
  94. package/dist/components/DescriptionList/description-list.js +1 -1
  95. package/dist/components/DescriptionList/description-list.js.map +1 -1
  96. package/dist/components/Dialog/dialog.d.ts +1 -1
  97. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  98. package/dist/components/Dialog/dialog.js +2 -1
  99. package/dist/components/Dialog/dialog.js.map +1 -1
  100. package/dist/components/DropdownMenu/dropdown-menu.d.ts +4 -4
  101. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  102. package/dist/components/DropdownMenu/dropdown-menu.js +25 -8
  103. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  104. package/dist/components/Empty/empty.d.ts.map +1 -1
  105. package/dist/components/Empty/empty.js +1 -1
  106. package/dist/components/Empty/empty.js.map +1 -1
  107. package/dist/components/Field/field-wrapper.d.ts +1 -0
  108. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  109. package/dist/components/Field/field-wrapper.js +27 -7
  110. package/dist/components/Field/field-wrapper.js.map +1 -1
  111. package/dist/components/Field/field.d.ts +1 -1
  112. package/dist/components/Field/field.d.ts.map +1 -1
  113. package/dist/components/Field/field.js +2 -1
  114. package/dist/components/Field/field.js.map +1 -1
  115. package/dist/components/Field/use-form-validation.d.ts +5 -1
  116. package/dist/components/Field/use-form-validation.d.ts.map +1 -1
  117. package/dist/components/Field/use-form-validation.js +31 -21
  118. package/dist/components/Field/use-form-validation.js.map +1 -1
  119. package/dist/components/FieldControlGroup/field-control-group.d.ts +3 -3
  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 +3 -2
  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.d.ts.map +1 -1
  126. package/dist/components/FileUpload/file-upload.js +22 -10
  127. package/dist/components/FileUpload/file-upload.js.map +1 -1
  128. package/dist/components/FileViewer/can-render-image.d.ts +6 -0
  129. package/dist/components/FileViewer/can-render-image.d.ts.map +1 -0
  130. package/dist/components/FileViewer/can-render-image.js +11 -0
  131. package/dist/components/FileViewer/can-render-image.js.map +1 -0
  132. package/dist/components/FileViewer/file-viewer.d.ts +2 -2
  133. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  134. package/dist/components/FileViewer/file-viewer.js +24 -16
  135. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  136. package/dist/components/FileViewer/image-renderer.d.ts +0 -5
  137. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -1
  138. package/dist/components/FileViewer/image-renderer.js +1 -9
  139. package/dist/components/FileViewer/image-renderer.js.map +1 -1
  140. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  141. package/dist/components/HoverCard/hover-card.js +3 -1
  142. package/dist/components/HoverCard/hover-card.js.map +1 -1
  143. package/dist/components/Input/input.d.ts +26 -3
  144. package/dist/components/Input/input.d.ts.map +1 -1
  145. package/dist/components/Input/input.js +12 -8
  146. package/dist/components/Input/input.js.map +1 -1
  147. package/dist/components/LinkInput/link-input.d.ts +3 -3
  148. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  149. package/dist/components/LinkInput/link-input.js +29 -28
  150. package/dist/components/LinkInput/link-input.js.map +1 -1
  151. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  152. package/dist/components/Menu/menu-item.js +5 -4
  153. package/dist/components/Menu/menu-item.js.map +1 -1
  154. package/dist/components/Notice/notice.d.ts +5 -0
  155. package/dist/components/Notice/notice.d.ts.map +1 -1
  156. package/dist/components/Notice/notice.js +11 -5
  157. package/dist/components/Notice/notice.js.map +1 -1
  158. package/dist/components/NumberInput/number-input.d.ts +1 -1
  159. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  160. package/dist/components/NumberInput/number-input.js +17 -8
  161. package/dist/components/NumberInput/number-input.js.map +1 -1
  162. package/dist/components/OverflowIndicator/overflow-indicator.d.ts +1 -1
  163. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
  164. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -1
  165. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  166. package/dist/components/Pagination/index.d.ts +2 -0
  167. package/dist/components/Pagination/index.d.ts.map +1 -0
  168. package/dist/components/Pagination/index.js +6 -0
  169. package/dist/components/Pagination/index.js.map +1 -0
  170. package/dist/components/Pagination/pagination.d.ts +49 -0
  171. package/dist/components/Pagination/pagination.d.ts.map +1 -0
  172. package/dist/components/Pagination/pagination.js +182 -0
  173. package/dist/components/Pagination/pagination.js.map +1 -0
  174. package/dist/components/PeoplePicker/people-picker.d.ts +3 -3
  175. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  176. package/dist/components/PeoplePicker/people-picker.js +38 -36
  177. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  178. package/dist/components/PeoplePicker/person-display.d.ts +4 -0
  179. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
  180. package/dist/components/PeoplePicker/person-display.js +3 -3
  181. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  182. package/dist/components/Popover/popover.d.ts.map +1 -1
  183. package/dist/components/Popover/popover.js +58 -32
  184. package/dist/components/Popover/popover.js.map +1 -1
  185. package/dist/components/ProfileCard/profile-card.d.ts +11 -3
  186. package/dist/components/ProfileCard/profile-card.d.ts.map +1 -1
  187. package/dist/components/ProfileCard/profile-card.js +14 -4
  188. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  189. package/dist/components/RadioGroup/radio-group.d.ts +1 -1
  190. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  191. package/dist/components/RadioGroup/radio-group.js +28 -3
  192. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  193. package/dist/components/Rating/rating.js +3 -3
  194. package/dist/components/Rating/rating.js.map +1 -1
  195. package/dist/components/ScrollArea/scroll-area.d.ts +1 -1
  196. package/dist/components/ScrollArea/scroll-area.js +2 -2
  197. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  198. package/dist/components/SegmentedControl/segmented-control.d.ts +2 -2
  199. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
  200. package/dist/components/SegmentedControl/segmented-control.js +23 -10
  201. package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
  202. package/dist/components/Select/select.d.ts +10 -4
  203. package/dist/components/Select/select.d.ts.map +1 -1
  204. package/dist/components/Select/select.js +57 -14
  205. package/dist/components/Select/select.js.map +1 -1
  206. package/dist/components/SelectMenu/index.js +4 -2
  207. package/dist/components/SelectMenu/select-menu.d.ts +31 -6
  208. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  209. package/dist/components/SelectMenu/select-menu.js +169 -85
  210. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  211. package/dist/components/Separator/separator.js +1 -1
  212. package/dist/components/Separator/separator.js.map +1 -1
  213. package/dist/components/Sheet/sheet.d.ts +1 -1
  214. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  215. package/dist/components/Sheet/sheet.js +3 -2
  216. package/dist/components/Sheet/sheet.js.map +1 -1
  217. package/dist/components/Sidebar/sidebar.d.ts +2 -2
  218. package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
  219. package/dist/components/Sidebar/sidebar.js +28 -10
  220. package/dist/components/Sidebar/sidebar.js.map +1 -1
  221. package/dist/components/Skeleton/skeleton.d.ts +1 -1
  222. package/dist/components/Skeleton/skeleton.js +2 -2
  223. package/dist/components/Skeleton/skeleton.js.map +1 -1
  224. package/dist/components/Slider/slider.d.ts +1 -1
  225. package/dist/components/Slider/slider.d.ts.map +1 -1
  226. package/dist/components/Slider/slider.js +7 -3
  227. package/dist/components/Slider/slider.js.map +1 -1
  228. package/dist/components/Steps/steps.d.ts.map +1 -1
  229. package/dist/components/Steps/steps.js +6 -3
  230. package/dist/components/Steps/steps.js.map +1 -1
  231. package/dist/components/Switch/switch.d.ts +2 -2
  232. package/dist/components/Switch/switch.d.ts.map +1 -1
  233. package/dist/components/Switch/switch.js +47 -9
  234. package/dist/components/Switch/switch.js.map +1 -1
  235. package/dist/components/Tabs/tabs.d.ts +8 -5
  236. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  237. package/dist/components/Tabs/tabs.js +45 -33
  238. package/dist/components/Tabs/tabs.js.map +1 -1
  239. package/dist/components/Tag/tag.d.ts.map +1 -1
  240. package/dist/components/Tag/tag.js +20 -4
  241. package/dist/components/Tag/tag.js.map +1 -1
  242. package/dist/components/Textarea/textarea.d.ts +2 -1
  243. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  244. package/dist/components/Textarea/textarea.js +24 -13
  245. package/dist/components/Textarea/textarea.js.map +1 -1
  246. package/dist/components/TimePicker/time-picker.d.ts +2 -2
  247. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  248. package/dist/components/TimePicker/time-picker.js +23 -12
  249. package/dist/components/TimePicker/time-picker.js.map +1 -1
  250. package/dist/components/Toast/toast.d.ts +1 -1
  251. package/dist/components/Toast/toast.d.ts.map +1 -1
  252. package/dist/components/Toast/toast.js +7 -3
  253. package/dist/components/Toast/toast.js.map +1 -1
  254. package/dist/components/Tooltip/tooltip.js +1 -1
  255. package/dist/components/Tooltip/tooltip.js.map +1 -1
  256. package/dist/components/TreeView/tree-view.d.ts +1 -1
  257. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  258. package/dist/components/TreeView/tree-view.js +11 -5
  259. package/dist/components/TreeView/tree-view.js.map +1 -1
  260. package/dist/hooks/use-controllable.d.ts.map +1 -1
  261. package/dist/hooks/use-controllable.js +4 -2
  262. package/dist/hooks/use-controllable.js.map +1 -1
  263. package/dist/hooks/use-is-touch-device.d.ts.map +1 -1
  264. package/dist/hooks/use-is-touch-device.js +3 -1
  265. package/dist/hooks/use-is-touch-device.js.map +1 -1
  266. package/dist/index.d.ts +2 -0
  267. package/dist/index.d.ts.map +1 -1
  268. package/dist/index.js +14 -0
  269. package/dist/index.js.map +1 -1
  270. package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -2
  271. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  272. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  273. package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
  274. package/dist/tokens/categorical-color.d.ts +1 -1
  275. package/dist/tokens/categorical-color.js.map +1 -1
  276. package/dist/tokens/uiSize/icon-size.d.ts +2 -2
  277. package/ds-canonical/fork/governance.lock +1 -1
  278. package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +10 -1
  279. package/ds-canonical/hooks/check_audit_post_report_validator.sh +13 -0
  280. package/ds-canonical/hooks/check_full_story_visual_interaction_sweep.sh +4 -3
  281. package/ds-canonical/hooks/check_opacity_token_usage.sh +10 -1
  282. package/ds-canonical/hooks/check_plugin_fork_health.sh +30 -22
  283. package/ds-canonical/hooks/check_story_invariants.sh +17 -5
  284. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +5 -2
  285. package/ds-canonical/references/principle-dim-map.json +100 -0
  286. package/ds-canonical/references/story-baseline-registry.json +4 -3
  287. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +1 -1
  288. package/ds-canonical/skills/design-system-audit/SKILL.md +2 -2
  289. package/ds-story-manifest.json +41 -18
  290. package/llms-full.txt +11 -1
  291. package/llms.txt +3 -1
  292. package/package.json +1 -1
  293. package/src/components/Alert/alert.anatomy.stories.tsx +9 -6
  294. package/src/components/Alert/alert.spec.md +3 -3
  295. package/src/components/Alert/alert.tsx +9 -1
  296. package/src/components/AppShell/app-shell.anatomy.stories.tsx +3 -0
  297. package/src/components/AppShell/app-shell.spec.md +3 -2
  298. package/src/components/AppShell/app-shell.tsx +1 -1
  299. package/src/components/AspectRatio/aspect-ratio.spec.md +1 -2
  300. package/src/components/AspectRatio/aspect-ratio.tsx +3 -2
  301. package/src/components/Avatar/avatar.principles.stories.tsx +1 -1
  302. package/src/components/Avatar/avatar.spec.md +10 -30
  303. package/src/components/Avatar/avatar.stories.tsx +1 -1
  304. package/src/components/Avatar/avatar.tsx +30 -16
  305. package/src/components/Badge/badge.anatomy.stories.tsx +2 -2
  306. package/src/components/Badge/badge.spec.md +5 -4
  307. package/src/components/Badge/badge.tsx +4 -1
  308. package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +2 -2
  309. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +15 -10
  310. package/src/components/Breadcrumb/breadcrumb.spec.md +5 -3
  311. package/src/components/Breadcrumb/breadcrumb.tsx +10 -4
  312. package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +3 -2
  313. package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -14
  314. package/src/components/BulkActionBar/bulk-action-bar.tsx +10 -4
  315. package/src/components/Button/button.anatomy.stories.tsx +6 -6
  316. package/src/components/Button/button.spec.md +3 -2
  317. package/src/components/Button/button.tsx +67 -27
  318. package/src/components/Button/index.ts +1 -0
  319. package/src/components/Calendar/calendar.anatomy.stories.tsx +5 -3
  320. package/src/components/Calendar/calendar.principles.stories.tsx +3 -1
  321. package/src/components/Calendar/calendar.spec.md +9 -2
  322. package/src/components/Calendar/calendar.stories.tsx +3 -1
  323. package/src/components/Calendar/calendar.tsx +53 -19
  324. package/src/components/Carousel/carousel.principles.stories.tsx +1 -1
  325. package/src/components/Carousel/carousel.tsx +4 -1
  326. package/src/components/Chart/chart.spec.md +1 -1
  327. package/src/components/Chart/chart.tsx +2 -1
  328. package/src/components/Checkbox/checkbox.principles.stories.tsx +1 -1
  329. package/src/components/Checkbox/checkbox.spec.md +1 -1
  330. package/src/components/Checkbox/checkbox.tsx +41 -7
  331. package/src/components/Checkbox/index.ts +1 -0
  332. package/src/components/Chip/chip.anatomy.stories.tsx +9 -9
  333. package/src/components/Chip/chip.principles.stories.tsx +3 -3
  334. package/src/components/Chip/chip.spec.md +7 -4
  335. package/src/components/Chip/chip.tsx +60 -15
  336. package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +1 -1
  337. package/src/components/CircularProgress/circular-progress.principles.stories.tsx +7 -5
  338. package/src/components/CircularProgress/circular-progress.spec.md +2 -0
  339. package/src/components/CircularProgress/circular-progress.stories.tsx +3 -11
  340. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +2 -2
  341. package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
  342. package/src/components/Coachmark/coachmark.spec.md +3 -3
  343. package/src/components/Coachmark/coachmark.tsx +23 -13
  344. package/src/components/Combobox/combobox.anatomy.stories.tsx +4 -4
  345. package/src/components/Combobox/combobox.spec.md +1 -1
  346. package/src/components/Combobox/combobox.tsx +30 -17
  347. package/src/components/Command/command.principles.stories.tsx +10 -12
  348. package/src/components/Command/command.spec.md +5 -5
  349. package/src/components/Command/command.stories.tsx +4 -4
  350. package/src/components/Command/command.tsx +3 -2
  351. package/src/components/DataTable/active-editor-controller.ts +4 -3
  352. package/src/components/DataTable/cell-registry.tsx +8 -0
  353. package/src/components/DataTable/data-table-filter-panel.tsx +8 -2
  354. package/src/components/DataTable/data-table-interaction-layer.tsx +8 -7
  355. package/src/components/DataTable/data-table.anatomy.stories.tsx +4 -4
  356. package/src/components/DataTable/data-table.css +2 -2
  357. package/src/components/DataTable/data-table.spec.md +72 -115
  358. package/src/components/DataTable/data-table.stories.tsx +51 -3
  359. package/src/components/DataTable/data-table.tsx +348 -63
  360. package/src/components/DataTable/filter-operators.spec.md +4 -4
  361. package/src/components/DataTable/filter-tree.ts +192 -42
  362. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +1 -1
  363. package/src/components/DateGrid/date-grid.spec.md +11 -8
  364. package/src/components/DateGrid/date-grid.tsx +63 -8
  365. package/src/components/DatePicker/date-picker.principles.stories.tsx +1 -1
  366. package/src/components/DatePicker/date-picker.spec.md +1 -0
  367. package/src/components/DatePicker/date-picker.stories.tsx +19 -0
  368. package/src/components/DatePicker/date-picker.tsx +52 -15
  369. package/src/components/DescriptionList/description-list.spec.md +1 -1
  370. package/src/components/DescriptionList/description-list.tsx +3 -1
  371. package/src/components/Dialog/dialog.spec.md +1 -1
  372. package/src/components/Dialog/dialog.tsx +2 -1
  373. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +3 -1
  374. package/src/components/DropdownMenu/dropdown-menu.spec.md +8 -5
  375. package/src/components/DropdownMenu/dropdown-menu.tsx +33 -7
  376. package/src/components/Empty/empty.anatomy.stories.tsx +1 -1
  377. package/src/components/Empty/empty.spec.md +2 -2
  378. package/src/components/Empty/empty.stories.tsx +4 -15
  379. package/src/components/Empty/empty.tsx +4 -1
  380. package/src/components/Field/field-controls.spec.md +2 -1
  381. package/src/components/Field/field-wrapper.tsx +28 -8
  382. package/src/components/Field/field.anatomy.stories.tsx +7 -7
  383. package/src/components/Field/field.principles.stories.tsx +1 -1
  384. package/src/components/Field/field.spec.md +9 -7
  385. package/src/components/Field/field.tsx +2 -1
  386. package/src/components/Field/form-validation.spec.md +6 -3
  387. package/src/components/Field/use-form-validation.ts +49 -21
  388. package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +11 -10
  389. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
  390. package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
  391. package/src/components/FieldControlGroup/field-control-group.tsx +3 -3
  392. package/src/components/FileItem/file-item.anatomy.stories.tsx +6 -4
  393. package/src/components/FileItem/file-item.tsx +3 -2
  394. package/src/components/FileUpload/file-upload.anatomy.stories.tsx +1 -1
  395. package/src/components/FileUpload/file-upload.spec.md +4 -1
  396. package/src/components/FileUpload/file-upload.tsx +36 -10
  397. package/src/components/FileViewer/can-render-image.ts +15 -0
  398. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +6 -4
  399. package/src/components/FileViewer/file-viewer.spec.md +2 -2
  400. package/src/components/FileViewer/file-viewer.tsx +47 -21
  401. package/src/components/FileViewer/image-renderer.tsx +3 -8
  402. package/src/components/HoverCard/hover-card.spec.md +1 -1
  403. package/src/components/HoverCard/hover-card.tsx +3 -1
  404. package/src/components/Input/input.anatomy.stories.tsx +4 -4
  405. package/src/components/Input/input.principles.stories.tsx +1 -1
  406. package/src/components/Input/input.spec.md +1 -1
  407. package/src/components/Input/input.stories.tsx +11 -5
  408. package/src/components/Input/input.tsx +11 -9
  409. package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -0
  410. package/src/components/LinkInput/link-input.tsx +49 -34
  411. package/src/components/Menu/menu-item.anatomy.stories.tsx +1 -1
  412. package/src/components/Menu/menu-item.spec.md +4 -3
  413. package/src/components/Menu/menu-item.tsx +15 -4
  414. package/src/components/Notice/notice.anatomy.stories.tsx +10 -5
  415. package/src/components/Notice/notice.spec.md +4 -3
  416. package/src/components/Notice/notice.tsx +22 -5
  417. package/src/components/NumberInput/number-input.anatomy.stories.tsx +5 -4
  418. package/src/components/NumberInput/number-input.principles.stories.tsx +2 -1
  419. package/src/components/NumberInput/number-input.spec.md +2 -1
  420. package/src/components/NumberInput/number-input.tsx +25 -9
  421. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +3 -3
  422. package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
  423. package/src/components/OverflowIndicator/overflow-indicator.tsx +2 -1
  424. package/src/components/Pagination/index.ts +5 -0
  425. package/src/components/Pagination/pagination.anatomy.stories.tsx +143 -0
  426. package/src/components/Pagination/pagination.principles.stories.tsx +81 -0
  427. package/src/components/Pagination/pagination.spec.md +150 -0
  428. package/src/components/Pagination/pagination.stories.tsx +98 -0
  429. package/src/components/Pagination/pagination.tsx +263 -0
  430. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +1 -1
  431. package/src/components/PeoplePicker/people-picker.spec.md +4 -4
  432. package/src/components/PeoplePicker/people-picker.stories.tsx +1 -1
  433. package/src/components/PeoplePicker/people-picker.tsx +65 -55
  434. package/src/components/PeoplePicker/person-display.tsx +10 -4
  435. package/src/components/Popover/popover.anatomy.stories.tsx +2 -2
  436. package/src/components/Popover/popover.spec.md +13 -14
  437. package/src/components/Popover/popover.tsx +88 -39
  438. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +4 -4
  439. package/src/components/ProfileCard/profile-card.principles.stories.tsx +2 -2
  440. package/src/components/ProfileCard/profile-card.spec.md +1 -2
  441. package/src/components/ProfileCard/profile-card.stories.tsx +1 -1
  442. package/src/components/ProfileCard/profile-card.tsx +29 -8
  443. package/src/components/RadioGroup/radio-group.principles.stories.tsx +1 -1
  444. package/src/components/RadioGroup/radio-group.spec.md +2 -2
  445. package/src/components/RadioGroup/radio-group.stories.tsx +3 -1
  446. package/src/components/RadioGroup/radio-group.tsx +37 -3
  447. package/src/components/Rating/rating.anatomy.stories.tsx +11 -8
  448. package/src/components/Rating/rating.principles.stories.tsx +1 -1
  449. package/src/components/Rating/rating.spec.md +2 -2
  450. package/src/components/Rating/rating.stories.tsx +1 -1
  451. package/src/components/Rating/rating.tsx +3 -3
  452. package/src/components/ScrollArea/scroll-area.spec.md +1 -0
  453. package/src/components/ScrollArea/scroll-area.tsx +1 -1
  454. package/src/components/SegmentedControl/segmented-control.anatomy.stories.tsx +3 -3
  455. package/src/components/SegmentedControl/segmented-control.spec.md +7 -3
  456. package/src/components/SegmentedControl/segmented-control.tsx +29 -11
  457. package/src/components/Select/select.anatomy.stories.tsx +2 -2
  458. package/src/components/Select/select.spec.md +3 -2
  459. package/src/components/Select/select.tsx +62 -19
  460. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +1 -1
  461. package/src/components/SelectMenu/select-menu.principles.stories.tsx +1 -1
  462. package/src/components/SelectMenu/select-menu.spec.md +12 -8
  463. package/src/components/SelectMenu/select-menu.tsx +176 -20
  464. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  465. package/src/components/SelectionControl/selection-item.principles.stories.tsx +2 -2
  466. package/src/components/SelectionControl/selection-item.spec.md +2 -1
  467. package/src/components/SelectionControl/selection-item.stories.tsx +1 -1
  468. package/src/components/Separator/separator.anatomy.stories.tsx +2 -2
  469. package/src/components/Separator/separator.tsx +1 -1
  470. package/src/components/Sheet/sheet.spec.md +2 -1
  471. package/src/components/Sheet/sheet.tsx +4 -2
  472. package/src/components/Sidebar/sidebar.anatomy.stories.tsx +1 -1
  473. package/src/components/Sidebar/sidebar.spec.md +2 -1
  474. package/src/components/Sidebar/sidebar.stories.tsx +6 -4
  475. package/src/components/Sidebar/sidebar.tsx +41 -13
  476. package/src/components/Skeleton/skeleton.principles.stories.tsx +1 -1
  477. package/src/components/Skeleton/skeleton.spec.md +1 -2
  478. package/src/components/Skeleton/skeleton.tsx +1 -1
  479. package/src/components/Slider/slider.anatomy.stories.tsx +4 -4
  480. package/src/components/Slider/slider.spec.md +19 -85
  481. package/src/components/Slider/slider.tsx +13 -5
  482. package/src/components/Steps/steps.anatomy.stories.tsx +1 -1
  483. package/src/components/Steps/steps.spec.md +6 -4
  484. package/src/components/Steps/steps.tsx +11 -3
  485. package/src/components/Switch/switch.spec.md +4 -3
  486. package/src/components/Switch/switch.tsx +59 -10
  487. package/src/components/Tabs/tabs.anatomy.stories.tsx +7 -6
  488. package/src/components/Tabs/tabs.principles.stories.tsx +5 -3
  489. package/src/components/Tabs/tabs.spec.md +15 -48
  490. package/src/components/Tabs/tabs.tsx +70 -34
  491. package/src/components/Tag/tag.principles.stories.tsx +2 -2
  492. package/src/components/Tag/tag.spec.md +11 -43
  493. package/src/components/Tag/tag.tsx +30 -4
  494. package/src/components/Textarea/textarea.principles.stories.tsx +2 -1
  495. package/src/components/Textarea/textarea.spec.md +2 -1
  496. package/src/components/Textarea/textarea.tsx +20 -10
  497. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +2 -1
  498. package/src/components/TimePicker/time-picker.spec.md +2 -2
  499. package/src/components/TimePicker/time-picker.tsx +35 -16
  500. package/src/components/Toast/toast.anatomy.stories.tsx +5 -6
  501. package/src/components/Toast/toast.principles.stories.tsx +10 -11
  502. package/src/components/Toast/toast.spec.md +5 -5
  503. package/src/components/Toast/toast.stories.tsx +5 -1
  504. package/src/components/Toast/toast.tsx +13 -7
  505. package/src/components/Tooltip/tooltip.spec.md +3 -3
  506. package/src/components/Tooltip/tooltip.tsx +1 -1
  507. package/src/components/TreeView/tree-view.anatomy.stories.tsx +6 -1
  508. package/src/components/TreeView/tree-view.principles.stories.tsx +2 -2
  509. package/src/components/TreeView/tree-view.spec.md +2 -2
  510. package/src/components/TreeView/tree-view.tsx +27 -5
  511. package/src/hooks/use-controllable.ts +7 -2
  512. package/src/hooks/use-is-touch-device.ts +8 -1
  513. package/src/index.ts +2 -1
  514. package/src/patterns/element-anatomy/element-anatomy.spec.md +3 -3
  515. package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
  516. package/src/patterns/element-anatomy/item-anatomy.spec.md +5 -14
  517. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +1 -0
  518. package/src/patterns/element-anatomy/item-anatomy.tsx +5 -6
  519. package/src/patterns/header-canonical/header-canonical.css +1 -2
  520. package/src/patterns/header-canonical/header-canonical.spec.md +5 -5
  521. package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +5 -4
  522. package/src/patterns/horizontal-overflow/horizontal-overflow.stories.tsx +137 -0
  523. package/src/patterns/overlay-surface/overlay-surface.spec.md +8 -7
  524. package/src/patterns/overlay-surface/overlay-surface.stories.tsx +116 -0
  525. package/src/patterns/overlay-surface/overlay-surface.tsx +5 -5
  526. package/src/patterns/resize-handle/resize-handle.spec.md +1 -1
  527. package/src/tokens/categorical-color.ts +1 -1
  528. package/src/tokens/color/color.spec.md +11 -13
  529. package/src/tokens/color/color.stories.tsx +1 -1
  530. package/src/tokens/color/primitives.css +7 -5
  531. package/src/tokens/color/semantic.css +8 -2
  532. package/src/tokens/density/density.spec.md +2 -0
  533. package/src/tokens/elevation/elevation.spec.md +1 -1
  534. package/src/tokens/layoutSpace/layoutSpace.spec.md +2 -1
  535. package/src/tokens/layoutSpace/layoutSpace.stories.tsx +3 -3
  536. package/src/tokens/motion/motion.spec.md +1 -1
  537. package/src/tokens/motion/motion.stories.tsx +142 -0
  538. package/src/tokens/opacity/opacity.spec.md +1 -1
  539. package/src/tokens/opacity/opacity.stories.tsx +7 -11
  540. package/src/tokens/radius/radius.spec.md +1 -1
  541. package/src/tokens/typography/typography.css +1 -1
  542. package/src/tokens/typography/typography.spec.md +1 -1
  543. package/src/tokens/uiSize/icon-size.ts +2 -2
  544. package/src/tokens/uiSize/uiSize.spec.md +12 -11
  545. package/src/tokens/uiSize/uiSize.stories.tsx +103 -0
  546. package/src/tokens/utility-registry.json +5 -4
  547. package/dist/node_modules/react-hook-form/dist/index.esm.js +0 -1950
  548. package/dist/node_modules/react-hook-form/dist/index.esm.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cell-registry.js","sources":["../../../src/components/DataTable/cell-registry.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\n// code-quality-allow: file-size — Cell Registry 含 10 cell-type components(string/number/date/time/select/multiSelect/person/multiPerson/boolean/url)+ shared helpers,split-into-files 會破壞 type-keyed registry SSOT canonical\n// DataTable Cell Registry — type-keyed SSOT for cell rendering(Phase C 2026-05-05)\n//\n// 對齊 M17 SSOT consolidation + audit recommendation:\n// 原 `renderTypedValue` switch + `EditableCellContent` switch 兩條平行 type-switch 已 collapse\n// 為**一張 type → cell component** registry。每個 cell component 同時處理 display / edit mode,\n// 靠底層 Field control 的 `mode` prop 切換。\n//\n// 設計原則:\n// - 每個 cell component 接同一組 props(`CellComponentProps`)\n// - 用 `variant=\"naked\"` — DataTable cell-as-input substrate(對齊 Field B1 chrome=bare)\n// - 消費 full Field 家族 primitive(無 stub)\n// - 不再用 `meta._editable` 私有 flag — `isEditable` 直接顯式入參(消除 M1 hack)\n//\n// World-class 對照(@benchmark-unverified):AG Grid cellRendererSelector / Material X-Grid\n// `valueGetter + renderCell` / Notion property type registry。\n\nimport * as React from 'react'\nimport type { ComponentType } from 'react'\nimport { Pencil } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { ColumnType } from './column-types'\nimport { Input } from '@/design-system/components/Input/input'\nimport { Textarea } from '@/design-system/components/Textarea/textarea'\nimport { NumberInput } from '@/design-system/components/NumberInput/number-input'\nimport { Select } from '@/design-system/components/Select/select'\nimport { Combobox } from '@/design-system/components/Combobox/combobox'\nimport { DatePicker } from '@/design-system/components/DatePicker/date-picker'\nimport { TimePicker } from '@/design-system/components/TimePicker/time-picker'\nimport { PeoplePicker } from '@/design-system/components/PeoplePicker/people-picker'\nimport { LinkInput } from '@/design-system/components/LinkInput/link-input'\nimport { Checkbox } from '@/design-system/components/Checkbox/checkbox'\nimport { Button } from '@/design-system/components/Button/button'\nimport type { PersonValue } from '@/design-system/components/PeoplePicker/person-display'\nimport { FieldSurfaceProvider, FieldSurfaceSizeProvider } from '@/design-system/components/Field/field-context'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type CellMode = 'display' | 'edit'\nexport type CellSize = 'sm' | 'md' | 'lg'\n\nexport interface CellComponentProps {\n // any-allow: free-form column value(consumer-defined,跨 type 共用 signature)\n value: any\n // any-allow: free-form consumer meta bag(prefix / options / formatOptions / locale / linkLabel 等)\n meta: Record<string, any>\n mode: CellMode\n size: CellSize\n autoRowHeight: boolean\n /** 該 cell 是否可編。replaces 舊 `meta._editable` 私有 flag(Phase C M1 hack 移除)。 */\n isEditable?: boolean\n /** 2026-05-13:cell 是否 disabled(state overlay,orthogonal to display/edit lifecycle)。\n * per codex Q3 verdict:不擴 CellMode='disabled',加 prop。各 Cell function 收 true 時\n * 傳 `mode='disabled'` 給 inner Field control,各 Field 內部走具體 disabled token(非 wrapper opacity)。 */\n isDisabled?: boolean\n /** Cell 進 edit mode → 提交新值(blur / Enter / option select 都觸發)— 提交後**自動 exit edit**。\n * 適用 single-shot commit:string / number / select(single)/ person(single)/ date / time / boolean / url。 */\n onCommit?: (next: unknown) => void\n /** Live commit — 提交新值但 **不 exit edit**(popover 持續開)。\n * 適用 multi-select 類:multiSelect / multiPerson — user 連續勾選,直到點外面才關。\n * 對齊 Notion / Linear / Airtable canonical:multi-pick popover 不在每次 toggle 後關閉。 */\n onCommitLive?: (next: unknown) => void\n /** Esc 取消編輯,不 commit。 */\n onCancel?: () => void\n /** URL cell 專用:hover 顯示的 Pencil 鈕 → 進 edit mode(read mode 保留 link click 語意)。 */\n onRequestEdit?: () => void\n /** Per-keystroke draft propagation(2026-05-10 Phase 7 D.3 portal Field virtualizer unmount preserve draft):\n * Edit mode 內部 input onChange/onValueChange 每 keystroke 呼叫 onDraft,讓 lifted draft state(in\n * data-table.tsx)持有 user 編輯中字。Cell DOM unmount(virtualizer scroll out)時 draft 在\n * parent state 不丟;mount-back 時 portal Field value 從 draft 取,user 字保留。\n * 非 portal mode(inline edit)不傳此 prop,各 Cell 走原 uncontrolled defaultValue 路徑。 */\n onDraft?: (next: unknown) => void\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** 鍵盤 commit / cancel — string / number cell edit mode 共用 */\nfunction makeKeyHandler(\n onCommit?: (v: unknown) => void,\n onCancel?: () => void,\n parseValue?: (raw: string) => unknown,\n) {\n return (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter') {\n e.preventDefault()\n const raw = (e.target as HTMLInputElement).value\n onCommit?.(parseValue ? parseValue(raw) : raw)\n }\n }\n}\n\nconst sizeForInput = (size: CellSize): CellSize => size\n\n/** 2026-05-13 Q3 helper(per codex Q3 verdict):cell display + isDisabled → Field mode='disabled'。\n * Cell display lifecycle 不擴 CellMode='disabled',而是各 Cell 在 display branch 翻譯 isDisabled\n * → Field mode='disabled' prop。inner Field 內部走具體 disabled token(text-fg-disabled / bg-disabled 等),\n * 非 wrapper blanket opacity-disabled 逃生艙(per color.spec.md:729)。 */\nconst displayOrDisabled = (isDisabled?: boolean): 'display' | 'disabled' =>\n isDisabled ? 'disabled' : 'display'\n\n// ── Cell Components ──────────────────────────────────────────────────────────\n\nfunction StringCell({ value, meta, mode, size, isDisabled, autoRowHeight, onCommit, onCancel, onDraft }: CellComponentProps) {\n // 2026-05-14 I9 fix(per codex+Layer A 共識):meta.maxLines opt-in line-clamp。\n // display autoRow 用 Tailwind arbitrary line-clamp 支援 N rows;edit textarea field-sizing\n // 已 auto-grow to content,natural match clamp。\n // 2026-05-16 Round 5 audit Dim 27 fix:narrow type 取代 `as any` cast。\n const maxLines: number | undefined = (meta as { maxLines?: number } | undefined)?.maxLines\n const clampClass = maxLines && autoRowHeight ? `line-clamp-[${maxLines}]` : undefined\n // string type canonical(2026-05-05 v2 user 校正:input space ≥ display space):\n // - autoRowHeight: Textarea(display + edit)— display wrap text 撐高 row,edit textarea\n // 多行輸入、`!h-full` 填 cell。對齊 Notion long-text cell canonical。\n // - fixed: Input(display + edit)— 單行 truncate display,單行 input edit;Field naked intrinsic\n // 高 = cell 高 = h-field-md,文字位置 display↔edit 完全一致。對齊 AG Grid / Material X-Grid。\n // - autoRowHeight 是 table 框架決定(consumer 不需 per-column 設 meta.wrap)。\n // - 互動(Textarea):Esc cancel / Cmd|Ctrl+Enter commit / blur commit;Enter 保留換行\n // - 互動(Input):Esc cancel / Enter commit / blur commit\n const v = value != null ? String(value) : ''\n if (mode === 'display') {\n // size 必傳:DataTable cell 字級隨 size 變(sm/md text-body / lg text-body-lg),\n // 對齊 Field family size→font SSOT(field-wrapper.tsx:60-64)。漏傳 → fallback md → lg 表格\n // 字卡 14px 跟 Select/Date 等有傳 size 的 cell 不一致(2026-06-08 user 抓 frozen string 欄字偏小)。\n return autoRowHeight\n ? <Textarea variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={v} size={size} className={clampClass} />\n : <Input variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={v} size={size} />\n }\n if (autoRowHeight) {\n // 2026-05-14 I8 fix(per codex verdict + user 抓「edit cell shrink」):\n // 原 `wrapRows = value.length / 40` 字元估算不準(對應實際 column width 不同\n // → cell 進 edit shrink)。改 CSS `field-sizing: content`(Chrome 123+ / FF 122+ /\n // Safari 17+)讓 textarea 自動 grow to content,匹配 display wrap 真實高度。\n // Fallback rows 仍保留給舊 browser(rows attr 在 field-sizing 支援時被覆蓋)。\n const newlineRows = (v.match(/\\n/g) || []).length + 1\n const wrapRows = Math.ceil(v.length / 40)\n const estimateRows = Math.min(10, Math.max(1, newlineRows, wrapRows))\n return (\n <Textarea\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n rows={estimateRows}\n defaultValue={v}\n // any-allow: CSS `field-sizing` 屬性 Chrome 123+/FF 122+/Safari 17+ 支援但 TypeScript lib.dom\n // 尚未加 type;narrow 到 CSSProperties 仍需 cast,保留 single-site any 較 type aug 簡潔。\n style={{ fieldSizing: 'content' } as React.CSSProperties}\n onChange={(e) => onDraft?.((e.target as HTMLTextAreaElement).value)}\n onBlur={(e) => onCommit?.((e.target as HTMLTextAreaElement).value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n onCommit?.((e.target as HTMLTextAreaElement).value)\n }\n }}\n />\n )\n }\n return (\n <Input\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n defaultValue={v}\n onChange={(e) => onDraft?.(e.target.value)}\n onBlur={(e) => onCommit?.(e.target.value)}\n onKeyDown={makeKeyHandler(onCommit, onCancel)}\n />\n )\n}\n\nfunction NumberCell({ value, meta, mode, size, isDisabled, onCommit, onCancel, onDraft }: CellComponentProps) {\n // currency 透過 columnType-aware prefix:type='currency' → 預設 '$'(可 override)\n const isCurrency = meta?.type === 'currency'\n const prefix = isCurrency ? (meta?.prefix ?? '$') : meta?.prefix\n // React #310 fix:useState 必在 display early-return 前無條件呼叫。同一 memo'd cell instance\n // 在 display↔edit 切換時被重用(render site 無 key={mode},data-table.tsx:1352),hook 數量不可變,\n // 否則 Rules of Hooks violation → React #310 crash。對齊 combobox/select hoist pattern。\n const initial = typeof value === 'number' ? value : null\n const [localValue, setLocalValue] = React.useState<number | null>(initial)\n if (mode === 'display') {\n return (\n <NumberInput\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as number | null}\n // size 必傳(同 StringCell)— currency/number cell 字級隨 DataTable size 變,對齊 Field SSOT。\n size={size}\n prefix={prefix}\n suffix={meta?.suffix}\n precision={meta?.precision}\n locale={meta?.locale}\n />\n )\n }\n // Edit mode value pre-fill canonical(2026-05-05):NumberInput edit 強制 controlled\n // (`value={value ?? ''}`)— 若 NumberCell 以 `defaultValue` 傳入,NumberInput value=undefined → ''\n // empty。對齊 cell-as-input「edit mode 自動帶入 display 值」(對齊 Notion / Airtable 共識),\n // 改用 local state controlled。User typing → setLocalValue;blur/Enter → onCommit(localValue)。\n // (initial + useState 已 hoist 到 display-return 前 — 見上方 React #310 fix。)\n return (\n <NumberInput\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n value={localValue}\n onChange={(v) => { setLocalValue(v); onDraft?.(v) }}\n prefix={prefix}\n suffix={meta?.suffix}\n precision={meta?.precision}\n onBlur={() => onCommit?.(localValue)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter') { e.preventDefault(); onCommit?.(localValue) }\n }}\n />\n )\n}\n\n// Cell-as-input dismiss canonical(2026-05-05):defaultOpen=true 開始 → user click 外 popover 關\n// → 元件 fire onOpenChange(false) → cell call onCancel exit edit。否則 cell 卡 edit mode 不可 re-trigger\n// (對齊 Airtable / Notion canonical:click 外即關)。\nconst dismissOnClose = (onCancel?: () => void) => (open: boolean) => { if (!open) onCancel?.() }\n\n// Mode-keyed remount canonical(2026-05-05):display↔edit 切換時,因 React reconciliation 同 type 同\n// position 會重用 instance,導致 `useState(defaultOpen)` 只在首次 mount 跑(那時 mode='display'\n// defaultOpen 沒給→預設 false)。後續 mode='edit' 即使傳 defaultOpen=true 也無效。\n// Fix:`key={mode}` 強制 React unmount + remount,每次切 mode 都重跑 useState init。\n// 對齊 Notion / Airtable cell-as-input「display 跟 edit 是不同 mount cycle」語義。\n\nfunction DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n return (\n <DatePicker\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n size={size}\n formatOptions={meta?.formatOptions}\n locale={meta?.locale}\n // Indicator(calendar icon)= editable affordance(2026-05-10 user 糾正)。\n // Non-editable cell 不該顯 picker indicator(誤導 read-only 為 editable)。\n // 對齊 UrlCell L394 / BooleanCell L368 既有 isEditable conditional pattern。\n showDisplayEndIcon={isEditable === true}\n />\n )\n }\n return (\n <DatePicker\n key=\"edit\"\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n value={typeof value === 'string' ? value : null}\n showTime={meta?.includeTime === true}\n onChange={(v) => onCommit?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n return (\n <TimePicker\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n size={size}\n formatOptions={meta?.formatOptions}\n locale={meta?.locale}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 indicator\n />\n )\n }\n return (\n <TimePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={typeof value === 'string' ? value : null}\n showSeconds={meta?.showSeconds === true}\n minuteStep={meta?.minuteStep}\n secondStep={meta?.secondStep}\n onChange={(v) => onCommit?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n // Display canonical(2026-05-05):cell IS variant,default plain text(no Tag pill 疊在 cell border 內)。\n // Consumer 可在 column meta.display='tag' opt-in 內容導向的 Tag 視覺(category 含色彩標籤等)。\n // 對齊 JTable / AG Grid「renderer/editor 視覺一致」canonical。\n const displayMode = (meta?.display as 'plain' | 'tag' | undefined) ?? 'plain'\n if (mode === 'display') {\n return (\n <Select\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n options={meta?.options ?? []}\n size={size}\n display={displayMode}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator\n />\n )\n }\n return (\n <Select\n key=\"edit\"\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n options={meta?.options ?? []}\n value={value as string | null | undefined}\n onChange={(v) => onCommit?.(v)}\n // B7(2026-05-05):cell 編輯時支援 inline search,沿用 Select.searchable 機制(對齊 cell-as-input\n // 「沿用既有輸入框互動」原則)。Default false,consumer 在 meta.searchable 開啟。\n searchable={meta?.searchable === true}\n display={displayMode}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, isEditable, onCommitLive, onCancel }: CellComponentProps) {\n const wrap = autoRowHeight && meta?.wrap === true\n if (mode === 'display') {\n return (\n <Combobox\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={(value as string[] | null) ?? []}\n options={meta?.options ?? []}\n wrap={wrap}\n size={size}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator\n />\n )\n }\n // Multi 用 onCommitLive(commit 但不 exit edit)— 每勾一項即時生效,popover 持續開\n // 直到點外面;onOpenChange(false) → onCancel exit edit。對齊 Notion / Linear / Airtable canonical。\n return (\n <Combobox\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n options={meta?.options ?? []}\n value={Array.isArray(value) ? (value as string[]) : []}\n onChange={(v) => onCommitLive?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction PersonCell({ value, mode, size, isDisabled, isEditable, onCommit, onCancel, meta }: CellComponentProps) {\n if (mode === 'display') {\n // 2026-05-10:non-editable 不顯 chevron indicator(對齊 UrlCell isEditable conditional pattern)\n return <PeoplePicker key=\"display\" variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={value as PersonValue | null} size={size} showDisplayEndIcon={isEditable === true} />\n }\n return (\n <PeoplePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={value as PersonValue | null}\n people={meta?.people ?? []}\n // PeoplePicker onChange 永遠 emit array(API contract);single mode commit 取首位\n onChange={(next) => onCommit?.(next[0] ?? null)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction MultiPersonCell({ value, mode, size, isDisabled, isEditable, onCommitLive, onCancel, meta }: CellComponentProps) {\n if (mode === 'display') {\n // 2026-05-10:non-editable 不顯 chevron indicator\n return <PeoplePicker key=\"display\" variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={(value as PersonValue[]) ?? []} size={size} showDisplayEndIcon={isEditable === true} />\n }\n // Multi 用 onCommitLive(commit 但不 exit edit)— 每勾一人即時生效,popover 持續開\n // 直到點外面;onOpenChange(false) → onCancel exit edit。對齊 multiSelect canonical。\n return (\n <PeoplePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={Array.isArray(value) ? (value as PersonValue[]) : []}\n people={meta?.people ?? []}\n onChange={(next) => onCommitLive?.(next)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction BooleanCell({ value, mode, meta, size, isEditable, isDisabled, onCommit }: CellComponentProps) {\n // boolean 不分 read/edit mode — display 渲 mode='display' 純展示;editable 時直接 toggle Checkbox\n // 2026-05-13 codex V1 fix:editable=true + disabled=true 之前 fall through to live Checkbox,\n // onCheckedChange 仍 fire(violate disabled contract)。Fix:`!isEditable || isDisabled` →\n // 走 display branch,Checkbox 拿 disabled mode + 不接 onCheckedChange。\n if (mode === 'display' && (!isEditable || isDisabled)) {\n return <Checkbox variant=\"naked\" mode={displayOrDisabled(isDisabled)} checked={value === true} />\n }\n return (\n <Checkbox\n size={size === 'lg' ? 'lg' : 'md'}\n checked={value === true}\n onCheckedChange={(checked) => onCommit?.(checked === true)}\n aria-label={meta?.ariaLabel ?? '切換'}\n />\n )\n}\n\n/**\n * UrlCell — Phase C drift fix:\n * 舊 EditableCellContent edit mode 對 url 走 plain `<Input>`(失去 URL 驗證 + auto-link)。\n * 現改用 `<LinkInput>` edit mode → 保留 URL parse / hostname 顯示一致性 + 鍵盤 commit / cancel。\n * read mode 仍 `<LinkInput mode={displayOrDisabled(isDisabled)}>` = 一致 SSOT。\n * editable 互動:hover 時右側出 Pencil 鈕 → 進 edit(保留 link click 語意,對齊原 spec)。\n */\nfunction UrlCell({ value, meta, mode, size, isDisabled, isEditable, onRequestEdit, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n // showDisplayEndIcon ← D path Phase 2(2026-05-08):Field naked wrapper 包 anchor,與 Input edit 同 chrome\n const display = (\n <LinkInput variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={value as string | null} label={meta?.linkLabel} size={size} showDisplayEndIcon />\n )\n // 2026-05-13 codex V1 fix:disabled URL 不顯 Pencil affordance(parent onRequestEdit 已被攔但 UI 仍誤導)\n if (!isEditable || isDisabled) return display\n // editable read mode:hover Pencil 鈕(對齊 spec 第十二段「url:read = 連結 + Pencil」)\n return (\n <span className=\"group/cell relative flex items-center w-full\"> {/* @naked-row-mode-allow: URL hover-Pencil 是 inline action 不是 value content,items-center 鎖 Pencil 對齊行高第一行(autoRow 跟 fixed 皆同視覺正確) */}\n <span className=\"flex-1 min-w-0\">{display}</span>\n <Button\n variant=\"tertiary\"\n size=\"xs\"\n iconOnly\n startIcon={Pencil}\n aria-label=\"編輯連結\"\n className={cn('ml-1 opacity-0 group-hover/cell:opacity-100 transition-opacity')}\n onClick={(e) => {\n e.stopPropagation()\n onRequestEdit?.()\n }}\n />\n </span>\n )\n }\n // edit mode value pre-fill canonical(2026-05-05):LinkInput edit `value` prop 強制 controlled\n // (line 113 `useState(value ?? '')`)+ `showLink = !editing && hasValidValue` 預設顯 link 不顯 input\n // → cell-as-input editing 場景需要 input 直接 focus 編輯。改用 plain `<Input>`(uncontrolled\n // `defaultValue` 正確 pre-fill,Input.tsx `value={value}` 是 undefined → uncontrolled 走 defaultValue)。\n // URL 驗證等 deferred 到 commit phase(consumer 可在 onCommit 時 validate)。\n return (\n <Input\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n defaultValue={value != null ? String(value) : ''}\n onBlur={(e) => onCommit?.(e.target.value)}\n onKeyDown={makeKeyHandler(onCommit, onCancel)}\n />\n )\n}\n\n// ── Registry ────────────────────────────────────────────────────────────────\n//\n// type → cell component。新增 columnType 必同步註冊一條(否則 fallback 到 string)。\n\nexport const cellRegistry: Record<ColumnType, ComponentType<CellComponentProps>> = {\n string: StringCell,\n number: NumberCell,\n currency: NumberCell, // 共用 NumberCell — currency-ness 走 meta.type 判 prefix='$'\n date: DateCell,\n time: TimeCell,\n select: SelectCell,\n multiSelect: MultiSelectCell,\n person: PersonCell,\n multiPerson: MultiPersonCell,\n boolean: BooleanCell,\n url: UrlCell,\n}\n\n/** Resolve cell component by type;default = StringCell(consumer 沒設 type 的 fallback)。\n * 2026-05-12 Stream C Cluster B fix:wrap with FieldSurfaceProvider `surface='table-cell'`\n * 讓所有 Cell 內的 Field family controls 透過 `useFieldSurface()` 取得「我在 cell 裡」context,\n * 取代散落的 `variant === 'naked'` cell-detection heuristic + per-prop hardcoded padding。\n *\n * **2026-05-13 (a) perf fix(user 拍板 + codex V1 verdict + Layer A grep root cause)**:\n * 原 factory pattern 每次 call 在 function body 內宣告新 `CellWithSurface` FC closure → 每 scroll\n * × 每 visible cell 都 return 新 FC reference → React 認 component type 變,**整 subtree mount/\n * unmount cascade**(Field + ItemPrefix/Suffix + Avatar / Tag / PersonDisplay)。\n * Fix:每 ColumnType **module-level 預建** wrapped FC + `React.memo`,resolve 走 cached map,\n * identity stable across scroll → memo 真生效 + subtree 不 mount/unmount。\n * Cite world-class:AG Grid「cell renderer per-type stable reference」/ MUI X DataGrid「memoized\n * subcomponents」/ Glide Data Grid「DOM virtualization 加解掛 = bottleneck」。 */\nconst cellWithSurfaceCache = new Map<ColumnType | '_default_', ComponentType<CellComponentProps>>()\n\nfunction buildCellWithSurface(Inner: ComponentType<CellComponentProps>, key: string): ComponentType<CellComponentProps> {\n const CellWithSurface = React.memo(function CellWithSurface(props: CellComponentProps) {\n return (\n <FieldSurfaceProvider surface=\"table-cell\">\n {/* 2026-06-08:把 table-density size 經獨立 surface-size context 注給 child Field controls,\n 漏傳 size 的 cell 也自動繼承(根治「新 cell 漏傳 size」class);size primitive 不破壞 memo identity。*/}\n <FieldSurfaceSizeProvider size={props.size}>\n <Inner {...props} />\n </FieldSurfaceSizeProvider>\n </FieldSurfaceProvider>\n )\n })\n ;(CellWithSurface as { displayName?: string }).displayName = `CellWithSurface(${key})`\n return CellWithSurface as ComponentType<CellComponentProps>\n}\n\n// Pre-build per-type cached wrapped components(module-level,one-time init)\nfor (const type of Object.keys(cellRegistry) as ColumnType[]) {\n cellWithSurfaceCache.set(type, buildCellWithSurface(cellRegistry[type], type))\n}\ncellWithSurfaceCache.set('_default_', buildCellWithSurface(StringCell, 'StringCell-fallback'))\n\nexport function resolveCellComponent(type?: ColumnType): ComponentType<CellComponentProps> {\n return cellWithSurfaceCache.get(type ?? '_default_') ?? cellWithSurfaceCache.get('_default_')!\n}\n"],"names":["DatePicker","CellWithSurface"],"mappings":"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"}
1
+ {"version":3,"file":"cell-registry.js","sources":["../../../src/components/DataTable/cell-registry.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\n// code-quality-allow: file-size — Cell Registry 含 10 cell-type components(string/number/date/time/select/multiSelect/person/multiPerson/boolean/url)+ shared helpers,split-into-files 會破壞 type-keyed registry SSOT canonical\n// DataTable Cell Registry — type-keyed SSOT for cell rendering(Phase C 2026-05-05)\n//\n// 對齊 M17 SSOT consolidation + audit recommendation:\n// 原 `renderTypedValue` switch + `EditableCellContent` switch 兩條平行 type-switch 已 collapse\n// 為**一張 type → cell component** registry。每個 cell component 同時處理 display / edit mode,\n// 靠底層 Field control 的 `mode` prop 切換。\n//\n// 設計原則:\n// - 每個 cell component 接同一組 props(`CellComponentProps`)\n// - 用 `variant=\"naked\"` — DataTable cell-as-input substrate(對齊 Field B1 chrome=bare)\n// - 消費 full Field 家族 primitive(無 stub)\n// - 不再用 `meta._editable` 私有 flag — `isEditable` 直接顯式入參(消除 M1 hack)\n//\n// World-class 對照(@benchmark-unverified):AG Grid cellRendererSelector / Material X-Grid\n// `valueGetter + renderCell` / Notion property type registry。\n\nimport * as React from 'react'\nimport type { ComponentType } from 'react'\nimport { Pencil } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { ColumnType } from './column-types'\nimport { Input } from '@/design-system/components/Input/input'\nimport { Textarea } from '@/design-system/components/Textarea/textarea'\nimport { NumberInput } from '@/design-system/components/NumberInput/number-input'\nimport { Select } from '@/design-system/components/Select/select'\nimport { Combobox } from '@/design-system/components/Combobox/combobox'\nimport { DatePicker } from '@/design-system/components/DatePicker/date-picker'\nimport { TimePicker } from '@/design-system/components/TimePicker/time-picker'\nimport { PeoplePicker } from '@/design-system/components/PeoplePicker/people-picker'\nimport { LinkInput } from '@/design-system/components/LinkInput/link-input'\nimport { Checkbox } from '@/design-system/components/Checkbox/checkbox'\nimport { Button } from '@/design-system/components/Button/button'\nimport type { PersonValue } from '@/design-system/components/PeoplePicker/person-display'\nimport { FieldSurfaceProvider, FieldSurfaceSizeProvider } from '@/design-system/components/Field/field-context'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type CellMode = 'display' | 'edit'\nexport type CellSize = 'sm' | 'md' | 'lg'\n\nexport interface CellComponentProps {\n // any-allow: free-form column value(consumer-defined,跨 type 共用 signature)\n value: any\n // any-allow: free-form consumer meta bag(prefix / options / formatOptions / locale / linkLabel 等)\n meta: Record<string, any>\n mode: CellMode\n size: CellSize\n autoRowHeight: boolean\n /** 該 cell 是否可編。replaces 舊 `meta._editable` 私有 flag(Phase C M1 hack 移除)。 */\n isEditable?: boolean\n /** 2026-05-13:cell 是否 disabled(state overlay,orthogonal to display/edit lifecycle)。\n * per codex Q3 verdict:不擴 CellMode='disabled',加 prop。各 Cell function 收 true 時\n * 傳 `mode='disabled'` 給 inner Field control,各 Field 內部走具體 disabled token(非 wrapper opacity)。 */\n isDisabled?: boolean\n /** Cell 進 edit mode → 提交新值(blur / Enter / option select 都觸發)— 提交後**自動 exit edit**。\n * 適用 single-shot commit:string / number / select(single)/ person(single)/ date / time / boolean / url。 */\n onCommit?: (next: unknown) => void\n /** Live commit — 提交新值但 **不 exit edit**(popover 持續開)。\n * 適用 multi-select 類:multiSelect / multiPerson — user 連續勾選,直到點外面才關。\n * 對齊 Notion / Linear / Airtable canonical:multi-pick popover 不在每次 toggle 後關閉。 */\n onCommitLive?: (next: unknown) => void\n /** Esc 取消編輯,不 commit。 */\n onCancel?: () => void\n /** URL cell 專用:hover 顯示的 Pencil 鈕 → 進 edit mode(read mode 保留 link click 語意)。 */\n onRequestEdit?: () => void\n /** Per-keystroke draft propagation(2026-05-10 Phase 7 D.3 portal Field virtualizer unmount preserve draft):\n * Edit mode 內部 input onChange/onValueChange 每 keystroke 呼叫 onDraft,讓 lifted draft state(in\n * data-table.tsx)持有 user 編輯中字。Cell DOM unmount(virtualizer scroll out)時 draft 在\n * parent state 不丟;mount-back 時 portal Field value 從 draft 取,user 字保留。\n * 非 portal mode(inline edit)不傳此 prop,各 Cell 走原 uncontrolled defaultValue 路徑。 */\n onDraft?: (next: unknown) => void\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** 鍵盤 commit / cancel — string / number cell edit mode 共用 */\nfunction makeKeyHandler(\n onCommit?: (v: unknown) => void,\n onCancel?: () => void,\n parseValue?: (raw: string) => unknown,\n) {\n return (e: React.KeyboardEvent<HTMLInputElement>) => {\n // IME 組字 guard(2026-07-05 D4 fix):中文輸入法選字的 Enter 是組字確認、Esc 是取消組字,\n // 非 commit / cancel 意圖 — 無 guard 會把半截組字提交並退出 edit(Esc 則丟棄整個 draft)。\n // 同 data-table.tsx nav handler 既有寫法(isComposing + Safari/舊 Chrome keyCode 229)。\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter') {\n e.preventDefault()\n const raw = (e.target as HTMLInputElement).value\n onCommit?.(parseValue ? parseValue(raw) : raw)\n }\n }\n}\n\nconst sizeForInput = (size: CellSize): CellSize => size\n\n/** 2026-05-13 Q3 helper(per codex Q3 verdict):cell display + isDisabled → Field mode='disabled'。\n * Cell display lifecycle 不擴 CellMode='disabled',而是各 Cell 在 display branch 翻譯 isDisabled\n * → Field mode='disabled' prop。inner Field 內部走具體 disabled token(text-fg-disabled / bg-disabled 等),\n * 非 wrapper blanket opacity-disabled 逃生艙(per color.spec.md:729)。 */\nconst displayOrDisabled = (isDisabled?: boolean): 'display' | 'disabled' =>\n isDisabled ? 'disabled' : 'display'\n\n// ── Cell Components ──────────────────────────────────────────────────────────\n\nfunction StringCell({ value, meta, mode, size, isDisabled, autoRowHeight, onCommit, onCancel, onDraft }: CellComponentProps) {\n // 2026-05-14 I9 fix(per codex+Layer A 共識):meta.maxLines opt-in line-clamp。\n // display autoRow 用 Tailwind arbitrary line-clamp 支援 N rows;edit textarea field-sizing\n // 已 auto-grow to content,natural match clamp。\n // 2026-05-16 Round 5 audit Dim 27 fix:narrow type 取代 `as any` cast。\n const maxLines: number | undefined = (meta as { maxLines?: number } | undefined)?.maxLines\n const clampClass = maxLines && autoRowHeight ? `line-clamp-[${maxLines}]` : undefined\n // string type canonical(2026-05-05 v2 user 校正:input space ≥ display space):\n // - autoRowHeight: Textarea(display + edit)— display wrap text 撐高 row,edit textarea\n // 多行輸入、`!h-full` 填 cell。對齊 Notion long-text cell canonical。\n // - fixed: Input(display + edit)— 單行 truncate display,單行 input edit;Field naked intrinsic\n // 高 = cell 高 = h-field-md,文字位置 display↔edit 完全一致。對齊 AG Grid / Material X-Grid。\n // - autoRowHeight 是 table 框架決定(consumer 不需 per-column 設 meta.wrap)。\n // - 互動(Textarea):Esc cancel / Cmd|Ctrl+Enter commit / blur commit;Enter 保留換行\n // - 互動(Input):Esc cancel / Enter commit / blur commit\n const v = value != null ? String(value) : ''\n if (mode === 'display') {\n // size 必傳:DataTable cell 字級隨 size 變(sm/md text-body / lg text-body-lg),\n // 對齊 Field family size→font SSOT(field-wrapper.tsx:60-64)。漏傳 → fallback md → lg 表格\n // 字卡 14px 跟 Select/Date 等有傳 size 的 cell 不一致(2026-06-08 user 抓 frozen string 欄字偏小)。\n return autoRowHeight\n ? <Textarea variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={v} size={size} className={clampClass} />\n : <Input variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={v} size={size} />\n }\n if (autoRowHeight) {\n // 2026-05-14 I8 fix(per codex verdict + user 抓「edit cell shrink」):\n // 原 `wrapRows = value.length / 40` 字元估算不準(對應實際 column width 不同\n // → cell 進 edit shrink)。改 CSS `field-sizing: content`(Chrome 123+ / FF 122+ /\n // Safari 17+)讓 textarea 自動 grow to content,匹配 display wrap 真實高度。\n // Fallback rows 仍保留給舊 browser(rows attr 在 field-sizing 支援時被覆蓋)。\n const newlineRows = (v.match(/\\n/g) || []).length + 1\n const wrapRows = Math.ceil(v.length / 40)\n const estimateRows = Math.min(10, Math.max(1, newlineRows, wrapRows))\n return (\n <Textarea\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n rows={estimateRows}\n defaultValue={v}\n // any-allow: CSS `field-sizing` 屬性 Chrome 123+/FF 122+/Safari 17+ 支援但 TypeScript lib.dom\n // 尚未加 type;narrow 到 CSSProperties 仍需 cast,保留 single-site any 較 type aug 簡潔。\n style={{ fieldSizing: 'content' } as React.CSSProperties}\n onChange={(e) => onDraft?.((e.target as HTMLTextAreaElement).value)}\n onBlur={(e) => onCommit?.((e.target as HTMLTextAreaElement).value)}\n onKeyDown={(e) => {\n // IME 組字 guard(2026-07-05 D4 fix,同 makeKeyHandler)\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n onCommit?.((e.target as HTMLTextAreaElement).value)\n }\n }}\n />\n )\n }\n return (\n <Input\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n defaultValue={v}\n onChange={(e) => onDraft?.(e.target.value)}\n onBlur={(e) => onCommit?.(e.target.value)}\n onKeyDown={makeKeyHandler(onCommit, onCancel)}\n />\n )\n}\n\nfunction NumberCell({ value, meta, mode, size, isDisabled, onCommit, onCancel, onDraft }: CellComponentProps) {\n // currency 透過 columnType-aware prefix:type='currency' → 預設 '$'(可 override)\n const isCurrency = meta?.type === 'currency'\n const prefix = isCurrency ? (meta?.prefix ?? '$') : meta?.prefix\n // React #310 fix:useState 必在 display early-return 前無條件呼叫。同一 memo'd cell instance\n // 在 display↔edit 切換時被重用(render site 無 key={mode},data-table.tsx:1352),hook 數量不可變,\n // 否則 Rules of Hooks violation → React #310 crash。對齊 combobox/select hoist pattern。\n const initial = typeof value === 'number' ? value : null\n const [localValue, setLocalValue] = React.useState<number | null>(initial)\n if (mode === 'display') {\n return (\n <NumberInput\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as number | null}\n // size 必傳(同 StringCell)— currency/number cell 字級隨 DataTable size 變,對齊 Field SSOT。\n size={size}\n prefix={prefix}\n suffix={meta?.suffix}\n precision={meta?.precision}\n locale={meta?.locale}\n />\n )\n }\n // Edit mode value pre-fill canonical(2026-05-05):NumberInput edit 強制 controlled\n // (`value={value ?? ''}`)— 若 NumberCell 以 `defaultValue` 傳入,NumberInput value=undefined → ''\n // empty。對齊 cell-as-input「edit mode 自動帶入 display 值」(對齊 Notion / Airtable 共識),\n // 改用 local state controlled。User typing → setLocalValue;blur/Enter → onCommit(localValue)。\n // (initial + useState 已 hoist 到 display-return 前 — 見上方 React #310 fix。)\n return (\n <NumberInput\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n value={localValue}\n onChange={(v) => { setLocalValue(v); onDraft?.(v) }}\n prefix={prefix}\n suffix={meta?.suffix}\n precision={meta?.precision}\n onBlur={() => onCommit?.(localValue)}\n onKeyDown={(e) => {\n // IME 組字 guard(2026-07-05 D4 fix,同 makeKeyHandler;IME 可在 number 欄輸入全形數字)\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return\n if (e.key === 'Escape') { e.preventDefault(); onCancel?.() }\n if (e.key === 'Enter') { e.preventDefault(); onCommit?.(localValue) }\n }}\n />\n )\n}\n\n// Cell-as-input dismiss canonical(2026-05-05):defaultOpen=true 開始 → user click 外 popover 關\n// → 元件 fire onOpenChange(false) → cell call onCancel exit edit。否則 cell 卡 edit mode 不可 re-trigger\n// (對齊 Airtable / Notion canonical:click 外即關)。\nconst dismissOnClose = (onCancel?: () => void) => (open: boolean) => { if (!open) onCancel?.() }\n\n// Mode-keyed remount canonical(2026-05-05):display↔edit 切換時,因 React reconciliation 同 type 同\n// position 會重用 instance,導致 `useState(defaultOpen)` 只在首次 mount 跑(那時 mode='display'\n// defaultOpen 沒給→預設 false)。後續 mode='edit' 即使傳 defaultOpen=true 也無效。\n// Fix:`key={mode}` 強制 React unmount + remount,每次切 mode 都重跑 useState init。\n// 對齊 Notion / Airtable cell-as-input「display 跟 edit 是不同 mount cycle」語義。\n\nfunction DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n return (\n <DatePicker\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n size={size}\n formatOptions={meta?.formatOptions}\n locale={meta?.locale}\n // Indicator(calendar icon)= editable affordance(2026-05-10 user 糾正)。\n // Non-editable cell 不該顯 picker indicator(誤導 read-only 為 editable)。\n // 對齊 UrlCell L394 / BooleanCell L368 既有 isEditable conditional pattern。\n showDisplayEndIcon={isEditable === true}\n />\n )\n }\n return (\n <DatePicker\n key=\"edit\"\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n value={typeof value === 'string' ? value : null}\n showTime={meta?.includeTime === true}\n onChange={(v) => onCommit?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n return (\n <TimePicker\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n size={size}\n formatOptions={meta?.formatOptions}\n locale={meta?.locale}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 indicator\n />\n )\n }\n return (\n <TimePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={typeof value === 'string' ? value : null}\n showSeconds={meta?.showSeconds === true}\n minuteStep={meta?.minuteStep}\n secondStep={meta?.secondStep}\n onChange={(v) => onCommit?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }: CellComponentProps) {\n // Display canonical(2026-05-05):cell IS variant,default plain text(no Tag pill 疊在 cell border 內)。\n // Consumer 可在 column meta.display='tag' opt-in 內容導向的 Tag 視覺(category 含色彩標籤等)。\n // 對齊 JTable / AG Grid「renderer/editor 視覺一致」canonical。\n const displayMode = (meta?.display as 'plain' | 'tag' | undefined) ?? 'plain'\n if (mode === 'display') {\n return (\n <Select\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={value as string | null}\n options={meta?.options ?? []}\n size={size}\n display={displayMode}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator\n />\n )\n }\n return (\n <Select\n key=\"edit\"\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n options={meta?.options ?? []}\n value={value as string | null | undefined}\n onChange={(v) => onCommit?.(v)}\n // B7(2026-05-05):cell 編輯時支援 inline search,沿用 Select.searchable 機制(對齊 cell-as-input\n // 「沿用既有輸入框互動」原則)。Default false,consumer 在 meta.searchable 開啟。\n searchable={meta?.searchable === true}\n display={displayMode}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, isEditable, onCommitLive, onCancel }: CellComponentProps) {\n const wrap = autoRowHeight && meta?.wrap === true\n if (mode === 'display') {\n return (\n <Combobox\n key=\"display\"\n variant=\"naked\"\n mode={displayOrDisabled(isDisabled)}\n value={(value as string[] | null) ?? []}\n options={meta?.options ?? []}\n wrap={wrap}\n size={size}\n showDisplayEndIcon={isEditable === true} // 2026-05-10:non-editable 不顯 chevron indicator\n />\n )\n }\n // Multi 用 onCommitLive(commit 但不 exit edit)— 每勾一項即時生效,popover 持續開\n // 直到點外面;onOpenChange(false) → onCancel exit edit。對齊 Notion / Linear / Airtable canonical。\n return (\n <Combobox\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n options={meta?.options ?? []}\n value={Array.isArray(value) ? (value as string[]) : []}\n onChange={(v) => onCommitLive?.(v)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction PersonCell({ value, mode, size, isDisabled, isEditable, onCommit, onCancel, meta }: CellComponentProps) {\n if (mode === 'display') {\n // 2026-05-10:non-editable 不顯 chevron indicator(對齊 UrlCell isEditable conditional pattern)\n return <PeoplePicker key=\"display\" variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={value as PersonValue | null} size={size} showDisplayEndIcon={isEditable === true} />\n }\n return (\n <PeoplePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={value as PersonValue | null}\n people={meta?.people ?? []}\n // PeoplePicker onChange 永遠 emit array(API contract);single mode commit 取首位\n onChange={(next) => onCommit?.(next[0] ?? null)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction MultiPersonCell({ value, mode, size, isDisabled, isEditable, onCommitLive, onCancel, meta }: CellComponentProps) {\n if (mode === 'display') {\n // 2026-05-10:non-editable 不顯 chevron indicator\n return <PeoplePicker key=\"display\" variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={(value as PersonValue[]) ?? []} size={size} showDisplayEndIcon={isEditable === true} />\n }\n // Multi 用 onCommitLive(commit 但不 exit edit)— 每勾一人即時生效,popover 持續開\n // 直到點外面;onOpenChange(false) → onCancel exit edit。對齊 multiSelect canonical。\n return (\n <PeoplePicker\n key=\"edit\"\n variant=\"naked\"\n size={sizeForInput(size)}\n value={Array.isArray(value) ? (value as PersonValue[]) : []}\n people={meta?.people ?? []}\n onChange={(next) => onCommitLive?.(next)}\n defaultOpen\n onOpenChange={dismissOnClose(onCancel)}\n />\n )\n}\n\nfunction BooleanCell({ value, mode, meta, size, isEditable, isDisabled, onCommit }: CellComponentProps) {\n // boolean 不分 read/edit mode — display 渲 mode='display' 純展示;editable 時直接 toggle Checkbox\n // 2026-05-13 codex V1 fix:editable=true + disabled=true 之前 fall through to live Checkbox,\n // onCheckedChange 仍 fire(violate disabled contract)。Fix:`!isEditable || isDisabled` →\n // 走 display branch,Checkbox 拿 disabled mode + 不接 onCheckedChange。\n if (mode === 'display' && (!isEditable || isDisabled)) {\n return <Checkbox variant=\"naked\" mode={displayOrDisabled(isDisabled)} checked={value === true} />\n }\n return (\n <Checkbox\n size={size === 'lg' ? 'lg' : 'md'}\n checked={value === true}\n onCheckedChange={(checked) => onCommit?.(checked === true)}\n aria-label={meta?.ariaLabel ?? '切換'}\n />\n )\n}\n\n/**\n * UrlCell — Phase C drift fix:\n * 舊 EditableCellContent edit mode 對 url 走 plain `<Input>`(失去 URL 驗證 + auto-link)。\n * 現改用 `<LinkInput>` edit mode → 保留 URL parse / hostname 顯示一致性 + 鍵盤 commit / cancel。\n * read mode 仍 `<LinkInput mode={displayOrDisabled(isDisabled)}>` = 一致 SSOT。\n * editable 互動:hover 時右側出 Pencil 鈕 → 進 edit(保留 link click 語意,對齊原 spec)。\n */\nfunction UrlCell({ value, meta, mode, size, isDisabled, isEditable, onRequestEdit, onCommit, onCancel }: CellComponentProps) {\n if (mode === 'display') {\n // showDisplayEndIcon ← D path Phase 2(2026-05-08):Field naked wrapper 包 anchor,與 Input edit 同 chrome\n const display = (\n <LinkInput variant=\"naked\" mode={displayOrDisabled(isDisabled)} value={value as string | null} label={meta?.linkLabel} size={size} showDisplayEndIcon />\n )\n // 2026-05-13 codex V1 fix:disabled URL 不顯 Pencil affordance(parent onRequestEdit 已被攔但 UI 仍誤導)\n if (!isEditable || isDisabled) return display\n // editable read mode:hover Pencil 鈕(對齊 spec 第十二段「url:read = 連結 + Pencil」)\n return (\n <span className=\"group/cell relative flex items-center w-full\"> {/* @naked-row-mode-allow: URL hover-Pencil 是 inline action 不是 value content,items-center 鎖 Pencil 對齊行高第一行(autoRow 跟 fixed 皆同視覺正確) */}\n <span className=\"flex-1 min-w-0\">{display}</span>\n <Button\n variant=\"tertiary\"\n size=\"xs\"\n iconOnly\n startIcon={Pencil}\n aria-label=\"編輯連結\"\n className={cn('ml-1 opacity-0 group-hover/cell:opacity-100 transition-opacity')}\n onClick={(e) => {\n e.stopPropagation()\n onRequestEdit?.()\n }}\n />\n </span>\n )\n }\n // edit mode value pre-fill canonical(2026-05-05):LinkInput edit `value` prop 強制 controlled\n // (line 113 `useState(value ?? '')`)+ `showLink = !editing && hasValidValue` 預設顯 link 不顯 input\n // → cell-as-input editing 場景需要 input 直接 focus 編輯。改用 plain `<Input>`(uncontrolled\n // `defaultValue` 正確 pre-fill,Input.tsx `value={value}` 是 undefined → uncontrolled 走 defaultValue)。\n // URL 驗證等 deferred 到 commit phase(consumer 可在 onCommit 時 validate)。\n return (\n <Input\n autoFocus\n variant=\"naked\"\n size={sizeForInput(size)}\n defaultValue={value != null ? String(value) : ''}\n onBlur={(e) => onCommit?.(e.target.value)}\n onKeyDown={makeKeyHandler(onCommit, onCancel)}\n />\n )\n}\n\n// ── Registry ────────────────────────────────────────────────────────────────\n//\n// type → cell component。新增 columnType 必同步註冊一條(否則 fallback 到 string)。\n\nexport const cellRegistry: Record<ColumnType, ComponentType<CellComponentProps>> = {\n string: StringCell,\n number: NumberCell,\n currency: NumberCell, // 共用 NumberCell — currency-ness 走 meta.type 判 prefix='$'\n date: DateCell,\n time: TimeCell,\n select: SelectCell,\n multiSelect: MultiSelectCell,\n person: PersonCell,\n multiPerson: MultiPersonCell,\n boolean: BooleanCell,\n url: UrlCell,\n}\n\n/** Resolve cell component by type;default = StringCell(consumer 沒設 type 的 fallback)。\n * 2026-05-12 Stream C Cluster B fix:wrap with FieldSurfaceProvider `surface='table-cell'`\n * 讓所有 Cell 內的 Field family controls 透過 `useFieldSurface()` 取得「我在 cell 裡」context,\n * 取代散落的 `variant === 'naked'` cell-detection heuristic + per-prop hardcoded padding。\n *\n * **2026-05-13 (a) perf fix(user 拍板 + codex V1 verdict + Layer A grep root cause)**:\n * 原 factory pattern 每次 call 在 function body 內宣告新 `CellWithSurface` FC closure → 每 scroll\n * × 每 visible cell 都 return 新 FC reference → React 認 component type 變,**整 subtree mount/\n * unmount cascade**(Field + ItemPrefix/Suffix + Avatar / Tag / PersonDisplay)。\n * Fix:每 ColumnType **module-level 預建** wrapped FC + `React.memo`,resolve 走 cached map,\n * identity stable across scroll → memo 真生效 + subtree 不 mount/unmount。\n * Cite world-class:AG Grid「cell renderer per-type stable reference」/ MUI X DataGrid「memoized\n * subcomponents」/ Glide Data Grid「DOM virtualization 加解掛 = bottleneck」。 */\nconst cellWithSurfaceCache = new Map<ColumnType | '_default_', ComponentType<CellComponentProps>>()\n\nfunction buildCellWithSurface(Inner: ComponentType<CellComponentProps>, key: string): ComponentType<CellComponentProps> {\n const CellWithSurface = React.memo(function CellWithSurface(props: CellComponentProps) {\n return (\n <FieldSurfaceProvider surface=\"table-cell\">\n {/* 2026-06-08:把 table-density size 經獨立 surface-size context 注給 child Field controls,\n 漏傳 size 的 cell 也自動繼承(根治「新 cell 漏傳 size」class);size primitive 不破壞 memo identity。*/}\n <FieldSurfaceSizeProvider size={props.size}>\n <Inner {...props} />\n </FieldSurfaceSizeProvider>\n </FieldSurfaceProvider>\n )\n })\n ;(CellWithSurface as { displayName?: string }).displayName = `CellWithSurface(${key})`\n return CellWithSurface as ComponentType<CellComponentProps>\n}\n\n// Pre-build per-type cached wrapped components(module-level,one-time init)\nfor (const type of Object.keys(cellRegistry) as ColumnType[]) {\n cellWithSurfaceCache.set(type, buildCellWithSurface(cellRegistry[type], type))\n}\ncellWithSurfaceCache.set('_default_', buildCellWithSurface(StringCell, 'StringCell-fallback'))\n\nexport function resolveCellComponent(type?: ColumnType): ComponentType<CellComponentProps> {\n return cellWithSurfaceCache.get(type ?? '_default_') ?? cellWithSurfaceCache.get('_default_')!\n}\n"],"names":["DatePicker","CellWithSurface"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-filter-panel.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAyBtD,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAElB,YAAY,EACZ,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,GACrB,CAAA;AACD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AAuTvG,MAAM,WAAW,yBAAyB,CAAC,KAAK;IAC9C,yDAAyD;IACzD,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;IACvB,0BAA0B;IAC1B,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAA;IAChC,gCAAgC;IAChC,KAAK,EAAE,UAAU,CAAA;IACjB,wBAAwB;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAA;IACzB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2PD,eAAO,MAAM,oBAAoB,EAAkD,CAAC,KAAK,EACvF,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;CAAE,KACnF,KAAK,CAAC,YAAY,CACtB"}
1
+ {"version":3,"file":"data-table-filter-panel.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAyBtD,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAElB,YAAY,EACZ,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,GACrB,CAAA;AACD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AA6TvG,MAAM,WAAW,yBAAyB,CAAC,KAAK;IAC9C,yDAAyD;IACzD,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;IACvB,0BAA0B;IAC1B,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAA;IAChC,gCAAgC;IAChC,KAAK,EAAE,UAAU,CAAA;IACjB,wBAAwB;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAA;IACzB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2PD,eAAO,MAAM,oBAAoB,EAAkD,CAAC,KAAK,EACvF,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;CAAE,KACnF,KAAK,CAAC,YAAY,CACtB"}
@@ -2,11 +2,12 @@
2
2
  * DataTableInteractionLayer — Slice D Step 1A scaffold(per `.claude/planning/datatable-spreadsheet-rfc.md`)
3
3
  *
4
4
  * Singleton overlay root inside DataTable(M21 private,不抽 global pattern)。
5
- * 5 sub-layer children(per RFC §Overlay Geometry):
5
+ * Sub-layer children(2026-07-04 對齊實作;原 RFC 5-layer 清單含未實作元件):
6
6
  * - HoverCellRect(z 1):hover 邊框,「one geometry owner, two paint owners」(Contract 8)
7
- * - SelectionRect / RangeRect(z 1.5):spreadsheet mode 才顯示(Contract 5,defer)
7
+ * - SelectionRing(z 2):spreadsheet mode selected cell 1px ring(CELL_RING_STYLES.selected)
8
8
  * - ActiveEditorHost(z 3):portal active edit Field(Slice C wire-up)
9
- * - NestedPortalRegistry(z 4):date/select popup 註冊為 inside editor(Contract 7)
9
+ * -(range 視覺 = CSS [data-range-cell] cell-bg,非 layer 元件;nested popup Radix idiom
10
+ * 見 active-editor-controller.ts — RangeRect / NestedPortalRegistry 元件不存在)
10
11
  *
11
12
  * Slice D Step 1A scope:
12
13
  * - getCellRect(cellId)geometry source(per Contract 8)
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-interaction-layer.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-interaction-layer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,KAAK,MAAM,GAAG,MAAM,CAAA;AAEpB,UAAU,QAAQ;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,8BAA8B;IACtC,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,+DAA+D;IAC/D,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IACpD,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;IACjD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,KAAK,CAAC,SAAS,CAAA;CACzE;AAsJD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,mBAA2B,EAC3B,kBAAkB,EAClB,cAAqB,EAErB,YAAY,EAAE,aAAa,GAC5B,EAAE,8BAA8B,kDAqFhC"}
1
+ {"version":3,"file":"data-table-interaction-layer.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-interaction-layer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,KAAK,MAAM,GAAG,MAAM,CAAA;AAEpB,UAAU,QAAQ;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,8BAA8B;IACtC,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,+DAA+D;IAC/D,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IACpD,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;IACjD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,KAAK,CAAC,SAAS,CAAA;CACzE;AAsJD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,mBAA2B,EAC3B,kBAAkB,EAClB,cAAqB,EAErB,YAAY,EAAE,aAAa,GAC5B,EAAE,8BAA8B,kDAqFhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-interaction-layer.js","sources":["../../../src/components/DataTable/data-table-interaction-layer.tsx"],"sourcesContent":["/**\n * DataTableInteractionLayer — Slice D Step 1A scaffold(per `.claude/planning/datatable-spreadsheet-rfc.md`)\n *\n * Singleton overlay root inside DataTable(M21 private,不抽 global pattern)。\n * 5 sub-layer children(per RFC §Overlay Geometry):\n * - HoverCellRect(z 1):hover 邊框,「one geometry owner, two paint owners」(Contract 8)\n * - SelectionRect / RangeRect(z 1.5):spreadsheet mode 才顯示(Contract 5,defer)\n * - ActiveEditorHost(z 3):portal active edit Field(Slice C wire-up)\n * - NestedPortalRegistry(z 4):date/select popup 註冊為 inside editor(Contract 7)\n *\n * Slice D Step 1A scope:\n * - getCellRect(cellId)geometry source(per Contract 8)\n * - HoverCellRect 1 layer 先做(Contract 8 / Contract 15 cellClickEntersEdit predicate)\n * - 默認 disabled via `experimentalSpreadsheetOverlay` flag,不破現有 outline\n * - 後續 Step 1B/C/D 漸進切換 + 拆 outline\n */\n\nimport * as React from 'react'\n\ntype CellId = string\n\ninterface CellRect {\n x: number\n y: number\n width: number\n height: number\n}\n\ninterface DataTableInteractionLayerProps {\n /** Flag default false:不破現有 outline。enable 後 hover/editor 走 overlay。 */\n enabled: boolean\n /** Container ref;layer absolute position 對 container origin */\n containerRef: React.RefObject<HTMLDivElement | null>\n /** Per Contract 15:`cellClickEntersEdit` predicate;hover overlay 顯示與否 */\n cellClickEntersEdit?: (cellId: CellId) => boolean\n /**\n * Slice D Step 3 scaffold(2026-05-10):active editor cell id。null = 無 active editor。\n * 當前只 render rect placeholder layer(z-index 3,higher than hover ring z-index 1)。\n * Future:ActiveEditorHost portal active edit Field per Contract 8 「two paint owners」。\n * Wire-up 走 codex Q-7 string-first canary(text cell first,picker types 漸進)。\n */\n activeEditorCellId?: CellId | null\n /**\n * Slice D Step 3.x flag:啟用 ActiveEditorHost dashed scaffold rect rendering。\n * 2026-05-10 bug fix(user 圖1 雙 ring 同時顯示):dashed scaffold 之前綁\n * `enabled`(= experimentalSpreadsheetOverlay)→ 任何 cell 進 edit mode 就 leak\n * 出 dashed rect。改 gate 給 `experimentalActiveEditorController`(Step 3.3 真\n * portal Field 工作),hover overlay scope 不會看到 dashed scaffold。\n */\n activeEditorEnabled?: boolean\n /**\n * Slice D Step 4(spreadsheet semantics,2026-05-10 user 圖1 ask + RFC Contract 5):\n * Excel-like 選取 cell ID。Click 1 select / Click 2 enter edit。\n * Layer renders solid border SelectionRect(per user「不要 dash 直接實的就好」)。\n */\n selectedCellId?: CellId | null\n /**\n * Slice D Step 4 range support(per user「應該支援 range」+ codex Q2.1 Airtable/AG Grid\n * cite):range cell IDs from anchor↔focus rectangle。Layer renders bg-fill RangeRect\n * (z 1,bg `--primary-subtle`)+ selection border on focus cell。\n */\n rangeCellIds?: CellId[]\n /**\n * Slice D Step 5(D.3 portal Field,2026-05-10 user 拍板「在乎完美乾淨」+ codex Q6.1\n * 撤回 defer):active editor render callback。當 activeEditorEnabled + activeEditorCellId\n * truthy → layer call this 拿 React node(已 bind value/onCommit/onCancel from controller),\n * 在 ActiveEditorHost portal(z 3,float rect)render 之。\n *\n * Per codex Q6.2 outline:cell 永遠 mode=\"display\"(SSOT preserved);portal host 渲\n * mode=\"edit\" 同 registry component;float pass-through + z-index 3 cover display below。\n */\n activeEditorRender?: (cellId: CellId, rect: CellRect) => React.ReactNode\n}\n\n/**\n * `getCellRect(cellId)` geometry source(per Contract 8)。\n *\n * 從 DOM 量(per-call `getBoundingClientRect()`)而非 layoutCache,因為:\n * 1. cell DOM 是 React-rendered,getBoundingClientRect 永遠是 source of truth\n * 2. layoutCache 需另寫 invalidation logic,added complexity\n * 3. Hover overlay re-render 頻率低(per cell hover,不是 per frame)\n *\n * 0.5px sub-pixel snap per RFC §Overlay Geometry。\n */\nfunction getCellRect(containerEl: HTMLElement | null, cellId: CellId): CellRect | null {\n if (!containerEl) return null\n const cellEl = containerEl.querySelector<HTMLElement>(`[data-cell-id=\"${cellId}\"]`)\n if (!cellEl) return null\n // Page-absolute coords for viewport-fixed layer(per Step 1C bug fix:layer\n // 用 position:fixed,讓 paint owner 跟 reference frame 解耦 outer container 的 positioning)。\n // 2026-05-10 v3 fix(user 圖5 SSOT consistency):**float coords no rounding**。\n // Cell 自身 layout 用 sub-pixel float position(CSS 不 snap to integer)— 跨 cell 累積\n // 常見 144.328 / 244.0 / 524.172 等 fractional。任何 Math.round / floor / ceil 都引入\n // varying rounding error(visual audit verified:dx=0.17/0.5/0.83 不一致)。\n // Float pass-through + outline + outline-offset:-1px(下方 paint)→ overlay 永遠跟\n // cell exact pixel-perfect overlap,user verbatim「在內容起始位置不變的前提下讓\n // overlay 的邊框直接剛好壓住 cell 邊框」達成。\n const rect = cellEl.getBoundingClientRect()\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n }\n}\n\n/**\n * Issue 6 viewport clip(2026-05-10):cell 跟 panel(left/center/right)bounding rect 一起取,\n * layer 用 panel rect 當 clip viewport intersect cell rect → overlay 永不畫到 panel 外。\n *\n * Per codex 13-issues verdict:「getCellRect 找最近 scroll viewport;intersect(cellRect, viewportRect),\n * 空 → 不 render,部分 → clipped rect render。」\n *\n * 對齊 AG Grid `cellsForRangeSet` viewport-aware paint / Glide DataGrid clip helpers /\n * Notion sticky-cell virtualizer mask。\n */\ninterface CellGeometry {\n /** Cell exact viewport rect(no rounding,float pass-through per Bug 5 SSOT) */\n rect: CellRect\n /** Nearest panel container rect(left/center/right body)— clip viewport for overlays */\n clipRect: CellRect\n /** Panel identifier(`left` / `center` / `right`)— grouped range outer ring 分段用 */\n panel: 'left' | 'center' | 'right'\n}\n\nfunction getCellGeometry(containerEl: HTMLElement | null, cellId: CellId): CellGeometry | null {\n if (!containerEl) return null\n const cellEl = containerEl.querySelector<HTMLElement>(`[data-cell-id=\"${cellId}\"]`)\n if (!cellEl) return null\n const panelEl = cellEl.closest<HTMLElement>('[data-datatable-panel]')\n if (!panelEl) return null\n const panel = panelEl.dataset.datatablePanel as 'left' | 'center' | 'right'\n const cellR = cellEl.getBoundingClientRect()\n const panelR = panelEl.getBoundingClientRect()\n return {\n rect: { x: cellR.x, y: cellR.y, width: cellR.width, height: cellR.height },\n clipRect: { x: panelR.x, y: panelR.y, width: panelR.width, height: panelR.height },\n panel,\n }\n}\n\n\n/**\n * Reactive rect sync hook — 確保 overlay rect 跨 RWD / scroll / resize 永遠對齊 cell(2026-05-10\n * user 拍板「所有 overlay 在各種 RWD 和捲動時都能處在正確位置上」)。\n *\n * 監聽 3 source(rAF coalesce 避 frame storm):\n * 1. window scroll(capture mode 抓 nested table body scroll + page scroll)\n * 2. window resize(viewport size change → cell width 變)\n * 3. ResizeObserver on container(column resize / table dimension 變)\n *\n * 每次事件 fire → setVersion(v+1) → 觸發 layer re-render → rect 用最新 getBoundingClientRect\n * 重算。getBoundingClientRect 本身永遠 return 當下 viewport-relative coords,沒 stale cache。\n *\n * Per codex(brief: codex-brief-rwd-future-2026-05-10):rAF coalesce 不需要 debounce,scroll\n * 跟到不延遲才對(Glide / AG Grid 同 idiom)。\n */\nfunction useReactiveRect(containerRef: React.RefObject<HTMLElement | null>, enabled: boolean) {\n const [, setVersion] = React.useState(0)\n React.useEffect(() => {\n if (!enabled) return\n let rafId: number | null = null\n const force = () => {\n if (rafId !== null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n setVersion((v) => v + 1)\n })\n }\n window.addEventListener('scroll', force, { capture: true, passive: true })\n window.addEventListener('resize', force, { passive: true })\n const container = containerRef.current\n let ro: ResizeObserver | null = null\n if (container && typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(force)\n ro.observe(container)\n }\n return () => {\n window.removeEventListener('scroll', force, { capture: true } as EventListenerOptions)\n window.removeEventListener('resize', force)\n if (ro) ro.disconnect()\n if (rafId !== null) cancelAnimationFrame(rafId)\n }\n }, [enabled, containerRef])\n}\n\n/**\n * Hover state hook — 監聽 container hover events,track hovered cell id。\n *\n * Implementation:event delegation on container(不 per-cell mount listeners),\n * 利用 `data-cell-id` attribute + closest()。\n */\nfunction useHoveredCell(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled: boolean,\n): CellId | null {\n const [hoveredCellId, setHoveredCellId] = React.useState<CellId | null>(null)\n\n React.useEffect(() => {\n if (!enabled) { setHoveredCellId(null); return }\n const container = containerRef.current\n if (!container) return\n\n const handleMouseOver = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null\n const cellEl = target?.closest<HTMLElement>('[data-cell-id]')\n const id = cellEl?.dataset.cellId ?? null\n setHoveredCellId(id)\n }\n const handleMouseLeave = () => setHoveredCellId(null)\n\n container.addEventListener('mouseover', handleMouseOver)\n container.addEventListener('mouseleave', handleMouseLeave)\n return () => {\n container.removeEventListener('mouseover', handleMouseOver)\n container.removeEventListener('mouseleave', handleMouseLeave)\n }\n }, [enabled, containerRef])\n\n return hoveredCellId\n}\n\n/**\n * Singleton interaction layer。\n *\n * Slice D Step 1A:HoverCellRect only。\n * Slice D Step 2/3/4:SelectionRect / ActiveEditorHost / RangeRect 漸進加入。\n */\nexport function DataTableInteractionLayer({\n enabled,\n containerRef,\n cellClickEntersEdit,\n activeEditorCellId,\n activeEditorEnabled = false,\n activeEditorRender,\n selectedCellId = null,\n // rangeCellIds retired 2026-05-10(outer ring 已 retire,range visual 靠 cell-bg `[data-range-cell]`)\n rangeCellIds: _rangeCellIds,\n}: DataTableInteractionLayerProps) {\n const hoveredCellId = useHoveredCell(containerRef, enabled)\n // 2026-05-10 RWD/scroll sync(per user mandate「所有 overlay 在各種 RWD 和捲動時都處在正確位置」):\n // window scroll(capture)+ resize + ResizeObserver(container)→ rAF coalesced re-render → rect 重算\n useReactiveRect(containerRef, enabled)\n\n // Contract 14 state precedence:editing > selected > hover(per RFC §State Precedence Matrix)\n const isEditingHovered = activeEditorCellId != null && activeEditorCellId === hoveredCellId\n const isSelectedHovered = selectedCellId != null && selectedCellId === hoveredCellId\n const shouldShowHover = enabled && hoveredCellId != null && !isEditingHovered && !isSelectedHovered\n && (cellClickEntersEdit ? cellClickEntersEdit(hoveredCellId) : true)\n\n // Issue 6 viewport clip(2026-05-10):每個 overlay rect 都跟最近 panel(left/center/right body)\n // intersect。Cell scroll 出 panel viewport(H scroll / pinned 範圍)→ rect null → 不 render;\n // 部分 → 用 ClipMask wrap 在 panel viewport 內裁切,outline 永遠在 cell 真邊但被 mask 限制視覺。\n const hoverGeo = shouldShowHover\n ? getCellGeometry(containerRef.current, hoveredCellId!)\n : null\n\n // Slice D Step 3 scaffold:ActiveEditorHost rect placeholder(per Contract 8 active editor paint owner)。\n // 2026-05-10 bug fix:gate by `activeEditorEnabled` flag(Step 3.3 portal Field work)。\n // Issue 6:active editor host **不**做 viewport clip(per codex「editor 必可見」),\n // 仍走原 path 從 getCellRect 取 viewport coords。User 應將 active editor cell 滾到 viewport 內。\n const activeEditorRect = activeEditorEnabled && activeEditorCellId != null\n ? getCellRect(containerRef.current, activeEditorCellId)\n : null\n\n // Slice D Step 4(spreadsheet semantics):SelectionRect + RangeRect with viewport clip。\n const selectedGeo = enabled && selectedCellId != null\n ? getCellGeometry(containerRef.current, selectedCellId)\n : null\n\n // 2026-05-10 retire `rangeOuterRingsByPanel` calc + render(per user 抓 range 2px outer\n // ring 不需要 — cell-bg `--primary-subtle` 已給「這些 cell 在範圍內」訊號,outer ring 是\n // redundant visual)。`CellRangeOuterRing` primitive 已 retire(下方刪),getCellGeometry 仍\n // 給 hover / selected overlay 使用,保留。Future 若需 outer ring 復用,從 git history 取\n // commit `763b3ac`(Issue 6 viewport clip)的 implementation。\n\n if (!enabled) return null\n\n // Layer absolute fixed-position relative to viewport(避 outer container 缺 position:relative\n // 找錯 reference frame)。getCellRect 已 return container-relative,但這裡 set top/left 用\n // page coords 一致 — 改用 viewport-fixed 簡化。\n return (\n <div\n aria-hidden\n style={{ position: 'fixed', inset: 0, pointerEvents: 'none', zIndex: 1 }}\n >\n {/* HoverRing — kind=hover(1px var(--border-hover)) z 1。Wrap 在 ClipMask(panel viewport)\n 內 → cell scroll 出 panel 時 outline 自動被 mask 裁切,不會 leak 到 panel 外。 */}\n {hoverGeo && (\n <ClipMask clipRect={hoverGeo.clipRect}>\n <CellRingOverlay rect={toRelRect(hoverGeo.rect, hoverGeo.clipRect)} kind=\"hover\" />\n </ClipMask>\n )}\n {/* SelectionRing — kind=selected(1px var(--primary)) z 2,SSOT 同 hover wide */}\n {selectedGeo && (\n <ClipMask clipRect={selectedGeo.clipRect}>\n <CellRingOverlay\n rect={toRelRect(selectedGeo.rect, selectedGeo.clipRect)}\n kind=\"selected\"\n cellId={selectedCellId!}\n />\n </ClipMask>\n )}\n {/* 2026-05-10 retire RangeOuterRing(per user 抓 image 4 + verbatim「range 的 cell 本來就有顏色變化,\n 那樣就夠了,不需要再有 2px 藍色的框」)。Range visual now relies purely on cell-bg\n (`--primary-subtle` via `[data-range-cell]` CSS in `data-table.css`)+ focus cell 2px selected\n border。Outer 2px primary ring 從 Issue 6 ship 但 visual 太重 — bg-fill 已給「這些 cell 在範圍內」\n 訊號,outer ring 是 redundant。`rangeOuterRingsByPanel` 計算保留但不 render(future 若需 reinstate\n 只需打開 .map)。 */}\n {/* {rangeOuterRingsByPanel.map((group) => (\n <ClipMask key={group.panel} clipRect={group.clipRect}>\n <CellRangeOuterRing rect={toRelRect(group.bbox, group.clipRect)} />\n </ClipMask>\n ))} */}\n {/* ActiveEditorHost — z 3,float rect,pointerEvents:auto opaque host(NOT a ring)。\n Issue 6:active editor 不 clip(editor 必可見) — user 滾出 viewport 自負責。 */}\n {activeEditorRect && (\n <ActiveEditorHost rect={activeEditorRect}>\n {activeEditorRender ? activeEditorRender(activeEditorCellId!, activeEditorRect) : null}\n </ActiveEditorHost>\n )}\n </div>\n )\n}\n\n/**\n * `toRelRect(cellRect, clipRect)` — Issue 6 helper(2026-05-10):\n * 把 viewport coords cell rect 轉成 ClipMask containing-block 內 relative coords。\n * ClipMask 用 panel rect 做 absolute container + overflow:hidden,內部 child absolute 定位\n * 以 mask 為 reference frame,所以 cellRect.x - clipRect.x 才對齊 cell 真實位置。\n */\nfunction toRelRect(cellRect: CellRect, clipRect: CellRect): CellRect {\n return {\n x: cellRect.x - clipRect.x,\n y: cellRect.y - clipRect.y,\n width: cellRect.width,\n height: cellRect.height,\n }\n}\n\n// ── Private primitives(per codex unified-ring-overlay-2026-05-10 Final A')──────\n//\n// 三個 private primitive 各自 own 一個 paint concern:\n// 1. CellRingOverlay — outline ring(hover / selected / future focus / error)\n// 2. CellRangeFill — bg fill(range cells in spreadsheet mode)\n// 3. ActiveEditorHost — opaque host(portal Field edit)\n//\n// SSOT pattern(共 3 primitives):rect float pass-through + boxSizing:border-box +\n// pointerEvents 視 kind / position:absolute on viewport-fixed layer。\n//\n// Token mapping 集中 `CELL_RING_STYLES`(per codex Q3 verdict 不開 global `--cell-ring-*` token,\n// 在 primitive 內 kind → semantic token mapping)。\n\nconst CELL_RING_STYLES = {\n hover: { width: 1, color: 'var(--border-hover)', zIndex: 1 },\n selected: { width: 1, color: 'var(--primary)', zIndex: 2 },\n // future kinds(per codex Q6 outline,加 entry 即可擴展):\n // focus: { width: 2, color: 'var(--primary)', zIndex: 2 },\n // error: { width: 1, color: 'var(--error)', zIndex: 2 },\n} as const\n\ntype CellRingKind = keyof typeof CELL_RING_STYLES\n\nfunction rectStyle(rect: CellRect): React.CSSProperties {\n return {\n position: 'absolute',\n left: rect.x,\n top: rect.y,\n width: rect.width,\n height: rect.height,\n }\n}\n\n/**\n * CellRingOverlay — paint owner for hover / selected / future focus / error rings。\n *\n * 共用 SSOT(per Bug 5 fix + codex Q2 unified primitive):\n * - Float pass-through rect(getCellRect 不 round)\n * - outline + outline-offset:`-${width}px` paint 在 cell 既有 border 上 in-place\n * - boxSizing:border-box(避免 outline 影響 layout)\n * - pointerEvents:none(透視點擊穿透)\n * - transition:none(避 fade flash)\n */\nfunction CellRingOverlay({ rect, kind, cellId }: {\n rect: CellRect\n kind: CellRingKind\n cellId?: CellId\n}) {\n const ring = CELL_RING_STYLES[kind]\n const dataAttr = kind === 'selected' && cellId ? { 'data-selected-cell-id': cellId } : {}\n return (\n <div\n aria-hidden\n style={{\n ...rectStyle(rect),\n outline: `${ring.width}px solid ${ring.color}`,\n outlineOffset: `-${ring.width}px`,\n boxSizing: 'border-box',\n pointerEvents: 'none',\n transition: 'none',\n zIndex: ring.zIndex,\n }}\n {...dataAttr}\n />\n )\n}\n\n// `CellRangeOuterRing` primitive retired 2026-05-10(per user 「range cell 本來就有顏色變化\n// 那樣就夠了,不需要再有 2px 藍色的框」)。Source 留 git history commit `763b3ac`(Issue 6\n// viewport clip ship)若需 reinstate。\n\n/**\n * ClipMask — Issue 6 primitive(2026-05-10):panel viewport 裁切容器。\n *\n * 用在 hover / selected / range outer ring overlay,避免 cell 滾出 panel viewport(H scroll /\n * pinned 範圍)時 overlay 仍漂浮在 panel 外。Layer 是 `position: fixed` viewport-anchor,\n * ClipMask 用 panel rect 當 absolute container + `overflow: hidden` mask;child overlay 用\n * `toRelRect(cellRect, clipRect)` 算出 mask-relative 座標,在 mask 內精準定位但被 mask 邊緣裁切。\n *\n * 對齊 AG Grid `cellsForRangeSet` viewport-aware paint / Glide DataGrid clip helpers /\n * Notion sticky-cell virtualizer mask。\n */\nfunction ClipMask({ clipRect, children }: { clipRect: CellRect; children: React.ReactNode }) {\n return (\n <div\n aria-hidden\n style={{\n position: 'absolute',\n left: clipRect.x,\n top: clipRect.y,\n width: clipRect.width,\n height: clipRect.height,\n overflow: 'hidden',\n pointerEvents: 'none',\n }}\n >\n {children}\n </div>\n )\n}\n\n/**\n * ActiveEditorHost — opaque host for portal Field edit(D.3,Slice D Step 5)。\n *\n * Per codex Q2 verdict:不該進 CellRingOverlay primitive — 它是 host 不是 ring。\n * - pointerEvents:auto(child Field 接收 click / keyboard)\n * - background:var(--canvas)(opaque cover display Field below;Cell SSOT 保留)\n * - z-index 3(above hover / selected / range)\n * - children = activeEditorRender 的回傳 React node\n *\n * Empty children fallback = dashed debug indicator(no portal Field provided)。\n */\nfunction ActiveEditorHost({ rect, children }: { rect: CellRect; children: React.ReactNode }) {\n if (!children) {\n return (\n <div\n aria-hidden\n style={{\n ...rectStyle(rect),\n pointerEvents: 'none',\n zIndex: 3,\n border: '1px dashed var(--primary)',\n boxSizing: 'border-box',\n }}\n data-active-editor-host-scaffold\n />\n )\n }\n return (\n <div\n style={{\n ...rectStyle(rect),\n pointerEvents: 'auto',\n zIndex: 3,\n boxSizing: 'border-box',\n background: 'var(--canvas)',\n }}\n data-active-editor-host\n >\n {children}\n </div>\n )\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-table-interaction-layer.js","sources":["../../../src/components/DataTable/data-table-interaction-layer.tsx"],"sourcesContent":["/**\n * DataTableInteractionLayer — Slice D Step 1A scaffold(per `.claude/planning/datatable-spreadsheet-rfc.md`)\n *\n * Singleton overlay root inside DataTable(M21 private,不抽 global pattern)。\n * Sub-layer children(2026-07-04 對齊實作;原 RFC 5-layer 清單含未實作元件):\n * - HoverCellRect(z 1):hover 邊框,「one geometry owner, two paint owners」(Contract 8)\n * - SelectionRing(z 2):spreadsheet mode selected cell 1px ring(CELL_RING_STYLES.selected)\n * - ActiveEditorHost(z 3):portal active edit Field(Slice C wire-up)\n * -(range 視覺 = CSS [data-range-cell] cell-bg,非 layer 元件;nested popup 走 Radix idiom\n * 見 active-editor-controller.ts — RangeRect / NestedPortalRegistry 元件不存在)\n *\n * Slice D Step 1A scope:\n * - getCellRect(cellId)geometry source(per Contract 8)\n * - HoverCellRect 1 layer 先做(Contract 8 / Contract 15 cellClickEntersEdit predicate)\n * - 默認 disabled via `experimentalSpreadsheetOverlay` flag,不破現有 outline\n * - 後續 Step 1B/C/D 漸進切換 + 拆 outline\n */\n\nimport * as React from 'react'\n\ntype CellId = string\n\ninterface CellRect {\n x: number\n y: number\n width: number\n height: number\n}\n\ninterface DataTableInteractionLayerProps {\n /** Flag default false:不破現有 outline。enable 後 hover/editor 走 overlay。 */\n enabled: boolean\n /** Container ref;layer absolute position 對 container origin */\n containerRef: React.RefObject<HTMLDivElement | null>\n /** Per Contract 15:`cellClickEntersEdit` predicate;hover overlay 顯示與否 */\n cellClickEntersEdit?: (cellId: CellId) => boolean\n /**\n * Slice D Step 3 scaffold(2026-05-10):active editor cell id。null = 無 active editor。\n * 當前只 render rect placeholder layer(z-index 3,higher than hover ring z-index 1)。\n * Future:ActiveEditorHost portal active edit Field per Contract 8 「two paint owners」。\n * Wire-up 走 codex Q-7 string-first canary(text cell first,picker types 漸進)。\n */\n activeEditorCellId?: CellId | null\n /**\n * Slice D Step 3.x flag:啟用 ActiveEditorHost dashed scaffold rect rendering。\n * 2026-05-10 bug fix(user 圖1 雙 ring 同時顯示):dashed scaffold 之前綁\n * `enabled`(= experimentalSpreadsheetOverlay)→ 任何 cell 進 edit mode 就 leak\n * 出 dashed rect。改 gate 給 `experimentalActiveEditorController`(Step 3.3 真\n * portal Field 工作),hover overlay scope 不會看到 dashed scaffold。\n */\n activeEditorEnabled?: boolean\n /**\n * Slice D Step 4(spreadsheet semantics,2026-05-10 user 圖1 ask + RFC Contract 5):\n * Excel-like 選取 cell ID。Click 1 select / Click 2 enter edit。\n * Layer renders solid border SelectionRect(per user「不要 dash 直接實的就好」)。\n */\n selectedCellId?: CellId | null\n /**\n * Slice D Step 4 range support(per user「應該支援 range」+ codex Q2.1 Airtable/AG Grid\n * cite):range cell IDs from anchor↔focus rectangle。Layer renders bg-fill RangeRect\n * (z 1,bg `--primary-subtle`)+ selection border on focus cell。\n */\n rangeCellIds?: CellId[]\n /**\n * Slice D Step 5(D.3 portal Field,2026-05-10 user 拍板「在乎完美乾淨」+ codex Q6.1\n * 撤回 defer):active editor render callback。當 activeEditorEnabled + activeEditorCellId\n * truthy → layer call this 拿 React node(已 bind value/onCommit/onCancel from controller),\n * 在 ActiveEditorHost portal(z 3,float rect)render 之。\n *\n * Per codex Q6.2 outline:cell 永遠 mode=\"display\"(SSOT preserved);portal host 渲\n * mode=\"edit\" 同 registry component;float pass-through + z-index 3 cover display below。\n */\n activeEditorRender?: (cellId: CellId, rect: CellRect) => React.ReactNode\n}\n\n/**\n * `getCellRect(cellId)` geometry source(per Contract 8)。\n *\n * 從 DOM 量(per-call `getBoundingClientRect()`)而非 layoutCache,因為:\n * 1. cell DOM 是 React-rendered,getBoundingClientRect 永遠是 source of truth\n * 2. layoutCache 需另寫 invalidation logic,added complexity\n * 3. Hover overlay re-render 頻率低(per cell hover,不是 per frame)\n *\n * Float coords pass-through — no rounding / no snap(v3 fix,見下方 v3 註解;原 RFC 0.5px snap 已撤)。\n */\nfunction getCellRect(containerEl: HTMLElement | null, cellId: CellId): CellRect | null {\n if (!containerEl) return null\n const cellEl = containerEl.querySelector<HTMLElement>(`[data-cell-id=\"${cellId}\"]`)\n if (!cellEl) return null\n // Page-absolute coords for viewport-fixed layer(per Step 1C bug fix:layer\n // 用 position:fixed,讓 paint owner 跟 reference frame 解耦 outer container 的 positioning)。\n // 2026-05-10 v3 fix(user 圖5 SSOT consistency):**float coords no rounding**。\n // Cell 自身 layout 用 sub-pixel float position(CSS 不 snap to integer)— 跨 cell 累積\n // 常見 144.328 / 244.0 / 524.172 等 fractional。任何 Math.round / floor / ceil 都引入\n // varying rounding error(visual audit verified:dx=0.17/0.5/0.83 不一致)。\n // Float pass-through + outline + outline-offset:-1px(下方 paint)→ overlay 永遠跟\n // cell exact pixel-perfect overlap,user verbatim「在內容起始位置不變的前提下讓\n // overlay 的邊框直接剛好壓住 cell 邊框」達成。\n const rect = cellEl.getBoundingClientRect()\n return {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n }\n}\n\n/**\n * Issue 6 viewport clip(2026-05-10):cell 跟 panel(left/center/right)bounding rect 一起取,\n * layer 用 panel rect 當 clip viewport intersect cell rect → overlay 永不畫到 panel 外。\n *\n * Per codex 13-issues verdict:「getCellRect 找最近 scroll viewport;intersect(cellRect, viewportRect),\n * 空 → 不 render,部分 → clipped rect render。」\n *\n * 對齊 AG Grid `cellsForRangeSet` viewport-aware paint / Glide DataGrid clip helpers /\n * Notion sticky-cell virtualizer mask。\n */\ninterface CellGeometry {\n /** Cell exact viewport rect(no rounding,float pass-through per Bug 5 SSOT) */\n rect: CellRect\n /** Nearest panel container rect(left/center/right body)— clip viewport for overlays */\n clipRect: CellRect\n /** Panel identifier(`left` / `center` / `right`)— grouped range outer ring 分段用 */\n panel: 'left' | 'center' | 'right'\n}\n\nfunction getCellGeometry(containerEl: HTMLElement | null, cellId: CellId): CellGeometry | null {\n if (!containerEl) return null\n const cellEl = containerEl.querySelector<HTMLElement>(`[data-cell-id=\"${cellId}\"]`)\n if (!cellEl) return null\n const panelEl = cellEl.closest<HTMLElement>('[data-datatable-panel]')\n if (!panelEl) return null\n const panel = panelEl.dataset.datatablePanel as 'left' | 'center' | 'right'\n const cellR = cellEl.getBoundingClientRect()\n const panelR = panelEl.getBoundingClientRect()\n return {\n rect: { x: cellR.x, y: cellR.y, width: cellR.width, height: cellR.height },\n clipRect: { x: panelR.x, y: panelR.y, width: panelR.width, height: panelR.height },\n panel,\n }\n}\n\n\n/**\n * Reactive rect sync hook — 確保 overlay rect 跨 RWD / scroll / resize 永遠對齊 cell(2026-05-10\n * user 拍板「所有 overlay 在各種 RWD 和捲動時都能處在正確位置上」)。\n *\n * 監聽 3 source(rAF coalesce 避 frame storm):\n * 1. window scroll(capture mode 抓 nested table body scroll + page scroll)\n * 2. window resize(viewport size change → cell width 變)\n * 3. ResizeObserver on container(column resize / table dimension 變)\n *\n * 每次事件 fire → setVersion(v+1) → 觸發 layer re-render → rect 用最新 getBoundingClientRect\n * 重算。getBoundingClientRect 本身永遠 return 當下 viewport-relative coords,沒 stale cache。\n *\n * Per codex(brief: codex-brief-rwd-future-2026-05-10):rAF coalesce 不需要 debounce,scroll\n * 跟到不延遲才對(Glide / AG Grid 同 idiom)。\n */\nfunction useReactiveRect(containerRef: React.RefObject<HTMLElement | null>, enabled: boolean) {\n const [, setVersion] = React.useState(0)\n React.useEffect(() => {\n if (!enabled) return\n let rafId: number | null = null\n const force = () => {\n if (rafId !== null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n setVersion((v) => v + 1)\n })\n }\n window.addEventListener('scroll', force, { capture: true, passive: true })\n window.addEventListener('resize', force, { passive: true })\n const container = containerRef.current\n let ro: ResizeObserver | null = null\n if (container && typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(force)\n ro.observe(container)\n }\n return () => {\n window.removeEventListener('scroll', force, { capture: true } as EventListenerOptions)\n window.removeEventListener('resize', force)\n if (ro) ro.disconnect()\n if (rafId !== null) cancelAnimationFrame(rafId)\n }\n }, [enabled, containerRef])\n}\n\n/**\n * Hover state hook — 監聽 container hover events,track hovered cell id。\n *\n * Implementation:event delegation on container(不 per-cell mount listeners),\n * 利用 `data-cell-id` attribute + closest()。\n */\nfunction useHoveredCell(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled: boolean,\n): CellId | null {\n const [hoveredCellId, setHoveredCellId] = React.useState<CellId | null>(null)\n\n React.useEffect(() => {\n if (!enabled) { setHoveredCellId(null); return }\n const container = containerRef.current\n if (!container) return\n\n const handleMouseOver = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null\n const cellEl = target?.closest<HTMLElement>('[data-cell-id]')\n const id = cellEl?.dataset.cellId ?? null\n setHoveredCellId(id)\n }\n const handleMouseLeave = () => setHoveredCellId(null)\n\n container.addEventListener('mouseover', handleMouseOver)\n container.addEventListener('mouseleave', handleMouseLeave)\n return () => {\n container.removeEventListener('mouseover', handleMouseOver)\n container.removeEventListener('mouseleave', handleMouseLeave)\n }\n }, [enabled, containerRef])\n\n return hoveredCellId\n}\n\n/**\n * Singleton interaction layer。\n *\n * Slice D Step 1A:HoverCellRect only。\n * Slice D Step 2/3/4:SelectionRect / ActiveEditorHost / RangeRect 漸進加入。\n */\nexport function DataTableInteractionLayer({\n enabled,\n containerRef,\n cellClickEntersEdit,\n activeEditorCellId,\n activeEditorEnabled = false,\n activeEditorRender,\n selectedCellId = null,\n // rangeCellIds retired 2026-05-10(outer ring 已 retire,range visual 靠 cell-bg `[data-range-cell]`)\n rangeCellIds: _rangeCellIds,\n}: DataTableInteractionLayerProps) {\n const hoveredCellId = useHoveredCell(containerRef, enabled)\n // 2026-05-10 RWD/scroll sync(per user mandate「所有 overlay 在各種 RWD 和捲動時都處在正確位置」):\n // window scroll(capture)+ resize + ResizeObserver(container)→ rAF coalesced re-render → rect 重算\n useReactiveRect(containerRef, enabled)\n\n // Contract 14 state precedence:editing > selected > hover(per RFC §State Precedence Matrix)\n const isEditingHovered = activeEditorCellId != null && activeEditorCellId === hoveredCellId\n const isSelectedHovered = selectedCellId != null && selectedCellId === hoveredCellId\n const shouldShowHover = enabled && hoveredCellId != null && !isEditingHovered && !isSelectedHovered\n && (cellClickEntersEdit ? cellClickEntersEdit(hoveredCellId) : true)\n\n // Issue 6 viewport clip(2026-05-10):每個 overlay rect 都跟最近 panel(left/center/right body)\n // intersect。Cell scroll 出 panel viewport(H scroll / pinned 範圍)→ rect null → 不 render;\n // 部分 → 用 ClipMask wrap 在 panel viewport 內裁切,outline 永遠在 cell 真邊但被 mask 限制視覺。\n const hoverGeo = shouldShowHover\n ? getCellGeometry(containerRef.current, hoveredCellId!)\n : null\n\n // Slice D Step 3 scaffold:ActiveEditorHost rect placeholder(per Contract 8 active editor paint owner)。\n // 2026-05-10 bug fix:gate by `activeEditorEnabled` flag(Step 3.3 portal Field work)。\n // Issue 6:active editor host **不**做 viewport clip(per codex「editor 必可見」),\n // 仍走原 path 從 getCellRect 取 viewport coords。User 應將 active editor cell 滾到 viewport 內。\n const activeEditorRect = activeEditorEnabled && activeEditorCellId != null\n ? getCellRect(containerRef.current, activeEditorCellId)\n : null\n\n // Slice D Step 4(spreadsheet semantics):SelectionRect + RangeRect with viewport clip。\n const selectedGeo = enabled && selectedCellId != null\n ? getCellGeometry(containerRef.current, selectedCellId)\n : null\n\n // 2026-05-10 retire `rangeOuterRingsByPanel` calc + render(per user 抓 range 2px outer\n // ring 不需要 — cell-bg `--primary-subtle` 已給「這些 cell 在範圍內」訊號,outer ring 是\n // redundant visual)。`CellRangeOuterRing` primitive 已 retire(下方刪),getCellGeometry 仍\n // 給 hover / selected overlay 使用,保留。Future 若需 outer ring 復用,從 git history 取\n // commit `763b3ac`(Issue 6 viewport clip)的 implementation。\n\n if (!enabled) return null\n\n // Layer absolute fixed-position relative to viewport(避 outer container 缺 position:relative\n // 找錯 reference frame)。getCellRect 已 return container-relative,但這裡 set top/left 用\n // page coords 一致 — 改用 viewport-fixed 簡化。\n return (\n <div\n aria-hidden\n style={{ position: 'fixed', inset: 0, pointerEvents: 'none', zIndex: 1 }}\n >\n {/* HoverRing — kind=hover(1px var(--border-hover)) z 1。Wrap 在 ClipMask(panel viewport)\n 內 → cell scroll 出 panel 時 outline 自動被 mask 裁切,不會 leak 到 panel 外。 */}\n {hoverGeo && (\n <ClipMask clipRect={hoverGeo.clipRect}>\n <CellRingOverlay rect={toRelRect(hoverGeo.rect, hoverGeo.clipRect)} kind=\"hover\" />\n </ClipMask>\n )}\n {/* SelectionRing — kind=selected(1px var(--primary)) z 2,SSOT 同 hover wide */}\n {selectedGeo && (\n <ClipMask clipRect={selectedGeo.clipRect}>\n <CellRingOverlay\n rect={toRelRect(selectedGeo.rect, selectedGeo.clipRect)}\n kind=\"selected\"\n cellId={selectedCellId!}\n />\n </ClipMask>\n )}\n {/* 2026-05-10 retire RangeOuterRing(per user 抓 image 4 + verbatim「range 的 cell 本來就有顏色變化,\n 那樣就夠了,不需要再有 2px 藍色的框」)。Range visual now relies purely on cell-bg\n (`--primary-subtle` via `[data-range-cell]` CSS in `data-table.css`)+ focus cell 1px selected\n border。Outer 2px primary ring 從 Issue 6 ship 但 visual 太重 — bg-fill 已給「這些 cell 在範圍內」\n 訊號,outer ring 是 redundant。calc + render 皆已 retire(變數已移除;future 若需 reinstate\n 參考 git history 2026-05-10)。 */}\n {/* {rangeOuterRingsByPanel.map((group) => (\n <ClipMask key={group.panel} clipRect={group.clipRect}>\n <CellRangeOuterRing rect={toRelRect(group.bbox, group.clipRect)} />\n </ClipMask>\n ))} */}\n {/* ActiveEditorHost — z 3,float rect,pointerEvents:auto opaque host(NOT a ring)。\n Issue 6:active editor 不 clip(editor 必可見) — user 滾出 viewport 自負責。 */}\n {activeEditorRect && (\n <ActiveEditorHost rect={activeEditorRect}>\n {activeEditorRender ? activeEditorRender(activeEditorCellId!, activeEditorRect) : null}\n </ActiveEditorHost>\n )}\n </div>\n )\n}\n\n/**\n * `toRelRect(cellRect, clipRect)` — Issue 6 helper(2026-05-10):\n * 把 viewport coords cell rect 轉成 ClipMask containing-block 內 relative coords。\n * ClipMask 用 panel rect 做 absolute container + overflow:hidden,內部 child absolute 定位\n * 以 mask 為 reference frame,所以 cellRect.x - clipRect.x 才對齊 cell 真實位置。\n */\nfunction toRelRect(cellRect: CellRect, clipRect: CellRect): CellRect {\n return {\n x: cellRect.x - clipRect.x,\n y: cellRect.y - clipRect.y,\n width: cellRect.width,\n height: cellRect.height,\n }\n}\n\n// ── Private primitives(per codex unified-ring-overlay-2026-05-10 Final A')──────\n//\n// 三個 private primitive 各自 own 一個 paint concern:\n// 1. CellRingOverlay — outline ring(hover / selected / future focus / error)\n// 2. CellRangeFill — bg fill(range cells in spreadsheet mode)\n// 3. ActiveEditorHost — opaque host(portal Field edit)\n//\n// SSOT pattern(共 3 primitives):rect float pass-through + boxSizing:border-box +\n// pointerEvents 視 kind / position:absolute on viewport-fixed layer。\n//\n// Token mapping 集中 `CELL_RING_STYLES`(per codex Q3 verdict 不開 global `--cell-ring-*` token,\n// 在 primitive 內 kind → semantic token mapping)。\n\nconst CELL_RING_STYLES = {\n hover: { width: 1, color: 'var(--border-hover)', zIndex: 1 },\n selected: { width: 1, color: 'var(--primary)', zIndex: 2 },\n // future kinds(per codex Q6 outline,加 entry 即可擴展):\n // focus: { width: 2, color: 'var(--primary)', zIndex: 2 },\n // error: { width: 1, color: 'var(--error)', zIndex: 2 },\n} as const\n\ntype CellRingKind = keyof typeof CELL_RING_STYLES\n\nfunction rectStyle(rect: CellRect): React.CSSProperties {\n return {\n position: 'absolute',\n left: rect.x,\n top: rect.y,\n width: rect.width,\n height: rect.height,\n }\n}\n\n/**\n * CellRingOverlay — paint owner for hover / selected / future focus / error rings。\n *\n * 共用 SSOT(per Bug 5 fix + codex Q2 unified primitive):\n * - Float pass-through rect(getCellRect 不 round)\n * - outline + outline-offset:`-${width}px` paint 在 cell 既有 border 上 in-place\n * - boxSizing:border-box(避免 outline 影響 layout)\n * - pointerEvents:none(透視點擊穿透)\n * - transition:none(避 fade flash)\n */\nfunction CellRingOverlay({ rect, kind, cellId }: {\n rect: CellRect\n kind: CellRingKind\n cellId?: CellId\n}) {\n const ring = CELL_RING_STYLES[kind]\n const dataAttr = kind === 'selected' && cellId ? { 'data-selected-cell-id': cellId } : {}\n return (\n <div\n aria-hidden\n style={{\n ...rectStyle(rect),\n outline: `${ring.width}px solid ${ring.color}`,\n outlineOffset: `-${ring.width}px`,\n boxSizing: 'border-box',\n pointerEvents: 'none',\n transition: 'none',\n zIndex: ring.zIndex,\n }}\n {...dataAttr}\n />\n )\n}\n\n// `CellRangeOuterRing` primitive retired 2026-05-10(per user 「range cell 本來就有顏色變化\n// 那樣就夠了,不需要再有 2px 藍色的框」)。Source 留 git history commit `763b3ac`(Issue 6\n// viewport clip ship)若需 reinstate。\n\n/**\n * ClipMask — Issue 6 primitive(2026-05-10):panel viewport 裁切容器。\n *\n * 用在 hover / selected / range outer ring overlay,避免 cell 滾出 panel viewport(H scroll /\n * pinned 範圍)時 overlay 仍漂浮在 panel 外。Layer 是 `position: fixed` viewport-anchor,\n * ClipMask 用 panel rect 當 absolute container + `overflow: hidden` mask;child overlay 用\n * `toRelRect(cellRect, clipRect)` 算出 mask-relative 座標,在 mask 內精準定位但被 mask 邊緣裁切。\n *\n * 對齊 AG Grid `cellsForRangeSet` viewport-aware paint / Glide DataGrid clip helpers /\n * Notion sticky-cell virtualizer mask。\n */\nfunction ClipMask({ clipRect, children }: { clipRect: CellRect; children: React.ReactNode }) {\n return (\n <div\n aria-hidden\n style={{\n position: 'absolute',\n left: clipRect.x,\n top: clipRect.y,\n width: clipRect.width,\n height: clipRect.height,\n overflow: 'hidden',\n pointerEvents: 'none',\n }}\n >\n {children}\n </div>\n )\n}\n\n/**\n * ActiveEditorHost — opaque host for portal Field edit(D.3,Slice D Step 5)。\n *\n * Per codex Q2 verdict:不該進 CellRingOverlay primitive — 它是 host 不是 ring。\n * - pointerEvents:auto(child Field 接收 click / keyboard)\n * - background:var(--canvas)(opaque cover display Field below;Cell SSOT 保留)\n * - z-index 3(above hover / selected / range)\n * - children = activeEditorRender 的回傳 React node\n *\n * Empty children fallback = dashed debug indicator(no portal Field provided)。\n */\nfunction ActiveEditorHost({ rect, children }: { rect: CellRect; children: React.ReactNode }) {\n if (!children) {\n return (\n <div\n aria-hidden\n style={{\n ...rectStyle(rect),\n pointerEvents: 'none',\n zIndex: 3,\n border: '1px dashed var(--primary)',\n boxSizing: 'border-box',\n }}\n data-active-editor-host-scaffold\n />\n )\n }\n return (\n <div\n style={{\n ...rectStyle(rect),\n pointerEvents: 'auto',\n zIndex: 3,\n boxSizing: 'border-box',\n background: 'var(--canvas)',\n }}\n data-active-editor-host\n >\n {children}\n </div>\n )\n}\n"],"names":[],"mappings":"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"}
@@ -10,6 +10,12 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
10
10
  data: TData[];
11
11
  size?: TableSize;
12
12
  autoRowHeight?: boolean;
13
+ /**
14
+ * 容器高度。預設 '400px'(body 內捲動);'auto' = 自然高度(hug rows);'100%' = fill parent。
15
+ * L5 分頁(2026-07-06):啟用 `pagination` 且未顯式傳 height 時預設改 'auto' —— 分頁的
16
+ * 導覽通道是頁碼,再疊 body 內捲動 = 雙重導覽(一頁 20 筆只露 10 筆);對齊 Ant Table
17
+ * 無預設高度罩、`scroll.y` 顯式選配的慣例。顯式傳 height 照舊尊重(分頁 + 頁內捲動可並用)。
18
+ */
13
19
  height?: string;
14
20
  overscan?: number;
15
21
  emptyState?: React.ReactNode;
@@ -42,7 +48,8 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
42
48
  * Slice D Step 1B(2026-05-10):啟用 spreadsheet-grade interaction overlay。
43
49
  * Default false(backward-compat)。Enable 後 hover/editor/selected/range 由
44
50
  * `DataTableInteractionLayer` overlay 統一畫,per `.claude/planning/datatable-spreadsheet-rfc.md`。
45
- * 漸進切換階段,當前 v1 minimal:hover overlay 1 layer
51
+ * 現況:hover ring + selection ring + active editor host 三個 sub-layer
52
+ * (詳 `data-table-interaction-layer.tsx` 檔頭)。
46
53
  */
47
54
  experimentalSpreadsheetOverlay?: boolean;
48
55
  /**
@@ -58,15 +65,16 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
58
65
  * Slice D Step 4(spreadsheet semantics,2026-05-10 user 拍板 + codex Layer B Q2.1 confirm):
59
66
  * Excel-like cell selection:click 1=select / click 2=edit / Shift+click=range。
60
67
  * Default false opt-in(per codex「DataTable is not a spreadsheet」既有原則 +
61
- * data-table.principles.stories.tsx L283-292)。
68
+ * data-table.principles.stories.tsx「不是試算表」principle story)。
62
69
  * Enable 後 inlineEdit cell click 行為:
63
70
  * - Plain click → setSelectedCellId,**不**進 edit mode
64
71
  * - Click on already-selected → enter edit
65
72
  * - Shift+click → extend range from anchor
66
73
  * - Double-click / Enter / F2 / printable(deferred) → enter edit on selected
67
74
  * - Click empty area → clear selection
68
- * 視覺:Layer SelectionRect(solid `--primary` 2px border)+ RangeRect
69
- * (`--primary-subtle` bg fill) per user「不要 dash 直接實的就好」+ codex Q2.2 token。
75
+ * 視覺:selection ring 1px `--primary`(layer `CELL_RING_STYLES.selected`);range 視覺
76
+ * = cell-bg `--primary-subtle`(`[data-range-cell]` CSS),outer ring 2026-05-10 retire
77
+ * — per user「不要 dash 直接實的就好」+ codex Q2.2 token。
70
78
  */
71
79
  spreadsheetMode?: boolean;
72
80
  /** 已選列(controlled)。傳 string[] = include shorthand;傳 DataTableSelection 支援反向選取(all + excluded) */
@@ -75,7 +83,8 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
75
83
  defaultSelection?: string[] | DataTableSelection;
76
84
  /** Selection 變更 callback(emit DataTableSelection union;include / all 兩模型) */
77
85
  onSelectionChange?: (next: DataTableSelection) => void;
78
- /** 全資料集筆數 M(server-side / filter 後);all 模式 count = totalCount − excluded.length(consumer 計算) */
86
+ /** 全資料集筆數 M(server-side / filter 後);all 模式 count = totalCount − excluded.length
87
+ * **DS 內部零消費(no-op prop)**:僅型別文件 + destructure 防 spread 到 DOM;count 全由 consumer 計算 */
79
88
  totalCount?: number;
80
89
  /** 是否啟用 selection / 模式;true 等同 'multi' */
81
90
  selectable?: boolean | 'single' | 'multi';
@@ -83,7 +92,7 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
83
92
  isRowSelectable?: (row: TData) => boolean;
84
93
  /** 取 row 唯一 ID(selection 用);default `(row, index) => String(index)` */
85
94
  getRowId?: (row: TData, index: number) => string;
86
- /** Checkbox aria-label fallback;default `'Select row'` */
95
+ /** Checkbox aria-label fallback;default `'選取此列'` */
87
96
  getRowAriaLabel?: (row: TData) => string;
88
97
  /** Filter 後 hidden selected rows 是否保留(default false,對齊 Material/AG Grid 共識) */
89
98
  preserveSelectionOnFilter?: boolean;
@@ -162,6 +171,28 @@ export interface DataTableProps<TData> extends Omit<React.HTMLAttributes<HTMLDiv
162
171
  * @param position 'before' | 'after'
163
172
  */
164
173
  onColumnReorder?: (sourceId: string, targetId: string, position: 'before' | 'after') => void;
174
+ /**
175
+ * L5 分頁(2026-07-06):`true` 或 config 物件啟用——內部接 TanStack `getPaginationRowModel`,
176
+ * 表格下方渲染分頁列(消費 `<Pagination>` 獨立元件,間距 tight、頁碼靠右)。
177
+ * 啟用時虛擬滾動自動關閉(TanStack 官方:互斥替代策略)。v1 = client-side only。
178
+ * 詳 data-table.spec.md「L5:分頁」段。
179
+ */
180
+ pagination?: boolean | DataTablePaginationOptions;
181
+ }
182
+ /** L5 分頁 config(頁碼 1-based 對外,對齊 Pagination / Ant;詳 data-table.spec.md「L5:分頁」段) */
183
+ export interface DataTablePaginationOptions {
184
+ /** 每頁筆數(預設 20) */
185
+ pageSize?: number;
186
+ /** 每頁筆數選項;傳了才渲染「每頁 N 筆」Select(消費既有 Select size="sm") */
187
+ pageSizeOptions?: number[];
188
+ /** 左側「共 N 筆」文字(opt-in,= Ant showTotal 邏輯;數源 = filter 後全集 getPrePaginationRowModel,非 selection all-mode 的 totalCount) */
189
+ showTotal?: boolean;
190
+ /** 當前頁(1-based,controlled;不傳 = uncontrolled) */
191
+ page?: number;
192
+ /** uncontrolled 初始頁(1-based,預設 1) */
193
+ defaultPage?: number;
194
+ onPageChange?: (page: number) => void;
195
+ onPageSizeChange?: (pageSize: number) => void;
165
196
  }
166
197
  /**
167
198
  * L2 選取模型(discriminated union,2026-06-22 對齊 MUI X DataGrid v8
@@ -191,7 +222,7 @@ export declare const dataTableMeta: {
191
222
  readonly family: null;
192
223
  readonly variants: {};
193
224
  readonly sizes: {};
194
- readonly states: readonly ["default", "hover", "active", "focus-visible", "disabled"];
225
+ readonly states: readonly ["default", "hover", "focus-visible", "disabled"];
195
226
  readonly tokens: {
196
227
  readonly bg: readonly ["bg-muted", "bg-neutral-hover", "bg-surface"];
197
228
  readonly fg: readonly ["text-fg-muted", "text-fg-secondary", "text-foreground"];
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table.tsx"],"names":[],"mappings":"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"}