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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/AGENTS.md +210 -0
  2. package/CLAUDE.md +17 -191
  3. package/cli-init.mjs +30 -2
  4. package/dist/components/Accordion/accordion.d.ts +2 -2
  5. package/dist/components/Accordion/accordion.d.ts.map +1 -1
  6. package/dist/components/Accordion/accordion.js.map +1 -1
  7. package/dist/components/Avatar/avatar.js +1 -1
  8. package/dist/components/Avatar/avatar.js.map +1 -1
  9. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
  10. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
  11. package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
  12. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  13. package/dist/components/Button/button-group.d.ts +2 -2
  14. package/dist/components/Button/button-group.d.ts.map +1 -1
  15. package/dist/components/Button/button-group.js +2 -2
  16. package/dist/components/Button/button-group.js.map +1 -1
  17. package/dist/components/Button/button.d.ts +2 -1
  18. package/dist/components/Button/button.d.ts.map +1 -1
  19. package/dist/components/Button/button.js +1 -1
  20. package/dist/components/Button/button.js.map +1 -1
  21. package/dist/components/Carousel/carousel.d.ts +14 -8
  22. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  23. package/dist/components/Carousel/carousel.js +64 -37
  24. package/dist/components/Carousel/carousel.js.map +1 -1
  25. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
  26. package/dist/components/Checkbox/checkbox-group.js +21 -14
  27. package/dist/components/Checkbox/checkbox-group.js.map +1 -1
  28. package/dist/components/Checkbox/checkbox.d.ts +2 -2
  29. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  30. package/dist/components/Checkbox/checkbox.js +49 -10
  31. package/dist/components/Checkbox/checkbox.js.map +1 -1
  32. package/dist/components/Combobox/combobox.d.ts +15 -6
  33. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  34. package/dist/components/Combobox/combobox.js +13 -7
  35. package/dist/components/Combobox/combobox.js.map +1 -1
  36. package/dist/components/Command/command.d.ts.map +1 -1
  37. package/dist/components/Command/command.js +11 -2
  38. package/dist/components/Command/command.js.map +1 -1
  39. package/dist/components/DataTable/cell-registry.d.ts +5 -5
  40. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  41. package/dist/components/DataTable/cell-registry.js +41 -38
  42. package/dist/components/DataTable/cell-registry.js.map +1 -1
  43. package/dist/components/DataTable/column-types.d.ts +1 -17
  44. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  45. package/dist/components/DataTable/column-types.js.map +1 -1
  46. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
  47. package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
  48. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
  49. package/dist/components/DataTable/data-table-filter-group.d.ts +47 -0
  50. package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -0
  51. package/dist/components/DataTable/data-table-filter-group.js +154 -0
  52. package/dist/components/DataTable/data-table-filter-group.js.map +1 -0
  53. package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
  54. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  55. package/dist/components/DataTable/data-table-filter-panel.js +5 -328
  56. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
  57. package/dist/components/DataTable/data-table-filter-value-picker.d.ts +29 -0
  58. package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -0
  59. package/dist/components/DataTable/data-table-filter-value-picker.js +187 -0
  60. package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -0
  61. package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
  62. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  63. package/dist/components/DataTable/data-table-sort-manager.js +2 -2
  64. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
  65. package/dist/components/DataTable/data-table.d.ts +1 -1
  66. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  67. package/dist/components/DataTable/data-table.js +44 -32
  68. package/dist/components/DataTable/data-table.js.map +1 -1
  69. package/dist/components/DatePicker/date-picker.d.ts +3 -3
  70. package/dist/components/DatePicker/date-picker.js +4 -4
  71. package/dist/components/DatePicker/date-picker.js.map +1 -1
  72. package/dist/components/DescriptionList/description-list.d.ts +3 -3
  73. package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
  74. package/dist/components/DescriptionList/description-list.js +6 -6
  75. package/dist/components/DescriptionList/description-list.js.map +1 -1
  76. package/dist/components/Dialog/dialog.d.ts +2 -2
  77. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  78. package/dist/components/Dialog/dialog.js.map +1 -1
  79. package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
  80. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  81. package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
  82. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  83. package/dist/components/Field/field-context.d.ts +16 -10
  84. package/dist/components/Field/field-context.d.ts.map +1 -1
  85. package/dist/components/Field/field-context.js.map +1 -1
  86. package/dist/components/Field/field-types.d.ts +2 -2
  87. package/dist/components/Field/field-types.d.ts.map +1 -1
  88. package/dist/components/Field/field-types.js.map +1 -1
  89. package/dist/components/Field/field-wrapper.d.ts +20 -4
  90. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  91. package/dist/components/Field/field-wrapper.js +30 -31
  92. package/dist/components/Field/field-wrapper.js.map +1 -1
  93. package/dist/components/Field/field.d.ts +1 -1
  94. package/dist/components/Field/field.d.ts.map +1 -1
  95. package/dist/components/Field/field.js +25 -3
  96. package/dist/components/Field/field.js.map +1 -1
  97. package/dist/components/Field/index.d.ts +1 -0
  98. package/dist/components/Field/index.d.ts.map +1 -1
  99. package/dist/components/Field/index.js +2 -0
  100. package/dist/components/Field/index.js.map +1 -1
  101. package/dist/components/Field/use-form-validation.d.ts +1 -1
  102. package/dist/components/Field/use-form-validation.js.map +1 -1
  103. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  104. package/dist/components/FileItem/file-item.js +2 -5
  105. package/dist/components/FileItem/file-item.js.map +1 -1
  106. package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
  107. package/dist/components/FileUpload/file-upload.js +5 -1
  108. package/dist/components/FileUpload/file-upload.js.map +1 -1
  109. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  110. package/dist/components/FileViewer/file-viewer.js +2 -1
  111. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  112. package/dist/components/HoverCard/hover-card.d.ts +2 -2
  113. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  114. package/dist/components/HoverCard/hover-card.js +4 -2
  115. package/dist/components/HoverCard/hover-card.js.map +1 -1
  116. package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
  117. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
  118. package/dist/components/InlineEdit/inline-edit.js +104 -62
  119. package/dist/components/InlineEdit/inline-edit.js.map +1 -1
  120. package/dist/components/Input/input.d.ts +1 -1
  121. package/dist/components/Input/input.d.ts.map +1 -1
  122. package/dist/components/Input/input.js +6 -6
  123. package/dist/components/Input/input.js.map +1 -1
  124. package/dist/components/LinkInput/link-input.d.ts +5 -5
  125. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  126. package/dist/components/LinkInput/link-input.js +3 -3
  127. package/dist/components/LinkInput/link-input.js.map +1 -1
  128. package/dist/components/Notice/notice.d.ts +17 -1
  129. package/dist/components/Notice/notice.d.ts.map +1 -1
  130. package/dist/components/Notice/notice.js +7 -1
  131. package/dist/components/Notice/notice.js.map +1 -1
  132. package/dist/components/NumberInput/number-input.d.ts +1 -1
  133. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  134. package/dist/components/NumberInput/number-input.js +12 -1
  135. package/dist/components/NumberInput/number-input.js.map +1 -1
  136. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
  137. package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
  138. package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
  139. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  140. package/dist/components/PeoplePicker/people-picker.js +7 -5
  141. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  142. package/dist/components/PeoplePicker/person-display.d.ts +1 -1
  143. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  144. package/dist/components/ProfileCard/profile-card.d.ts +1 -1
  145. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  146. package/dist/components/RadioGroup/radio-group.d.ts +3 -3
  147. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  148. package/dist/components/RadioGroup/radio-group.js +1 -1
  149. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  150. package/dist/components/Rating/rating.d.ts.map +1 -1
  151. package/dist/components/Rating/rating.js +4 -0
  152. package/dist/components/Rating/rating.js.map +1 -1
  153. package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
  154. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  155. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  156. package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
  157. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
  158. package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
  159. package/dist/components/Select/select.d.ts +16 -6
  160. package/dist/components/Select/select.d.ts.map +1 -1
  161. package/dist/components/Select/select.js +17 -5
  162. package/dist/components/Select/select.js.map +1 -1
  163. package/dist/components/SelectMenu/select-menu.d.ts +17 -1
  164. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  165. package/dist/components/SelectMenu/select-menu.js +17 -3
  166. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  167. package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
  168. package/dist/components/SelectionControl/boolean-value.js.map +1 -1
  169. package/dist/components/Sheet/sheet.d.ts +2 -2
  170. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  171. package/dist/components/Sheet/sheet.js.map +1 -1
  172. package/dist/components/Sidebar/sidebar.d.ts +1 -1
  173. package/dist/components/Sidebar/sidebar.js +2 -2
  174. package/dist/components/Sidebar/sidebar.js.map +1 -1
  175. package/dist/components/Slider/slider.d.ts.map +1 -1
  176. package/dist/components/Slider/slider.js +6 -3
  177. package/dist/components/Slider/slider.js.map +1 -1
  178. package/dist/components/Steps/steps.d.ts +6 -4
  179. package/dist/components/Steps/steps.d.ts.map +1 -1
  180. package/dist/components/Steps/steps.js +19 -5
  181. package/dist/components/Steps/steps.js.map +1 -1
  182. package/dist/components/Switch/switch.d.ts +4 -4
  183. package/dist/components/Switch/switch.d.ts.map +1 -1
  184. package/dist/components/Switch/switch.js +3 -1
  185. package/dist/components/Switch/switch.js.map +1 -1
  186. package/dist/components/Tabs/tabs.d.ts +1 -1
  187. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  188. package/dist/components/Tabs/tabs.js +73 -23
  189. package/dist/components/Tabs/tabs.js.map +1 -1
  190. package/dist/components/Tag/tag.d.ts +3 -1
  191. package/dist/components/Tag/tag.d.ts.map +1 -1
  192. package/dist/components/Tag/tag.js +2 -2
  193. package/dist/components/Tag/tag.js.map +1 -1
  194. package/dist/components/Textarea/textarea.d.ts +4 -4
  195. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  196. package/dist/components/Textarea/textarea.js +15 -15
  197. package/dist/components/Textarea/textarea.js.map +1 -1
  198. package/dist/components/TimePicker/time-picker.d.ts +4 -4
  199. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  200. package/dist/components/TimePicker/time-picker.js +8 -5
  201. package/dist/components/TimePicker/time-picker.js.map +1 -1
  202. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  203. package/dist/components/Tooltip/tooltip.js +27 -23
  204. package/dist/components/Tooltip/tooltip.js.map +1 -1
  205. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  206. package/dist/components/TreeView/tree-view.js +16 -0
  207. package/dist/components/TreeView/tree-view.js.map +1 -1
  208. package/dist/index.d.ts +7 -7
  209. package/dist/index.d.ts.map +1 -1
  210. package/dist/index.js +6 -11
  211. package/dist/lib/drag-visual.d.ts +2 -2
  212. package/dist/lib/drag-visual.js.map +1 -1
  213. package/dist/lib/utils.d.ts +1 -0
  214. package/dist/lib/utils.d.ts.map +1 -1
  215. package/dist/lib/utils.js +21 -1
  216. package/dist/lib/utils.js.map +1 -1
  217. package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
  218. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  219. package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
  220. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  221. package/dist/tokens/categorical-color.d.ts +3 -3
  222. package/dist/tokens/categorical-color.d.ts.map +1 -1
  223. package/dist/tokens/categorical-color.js +2 -2
  224. package/dist/tokens/categorical-color.js.map +1 -1
  225. package/ds-canonical/fork/AGENTS.md +213 -0
  226. package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
  227. package/ds-canonical/fork/codex/hooks.json +16 -0
  228. package/ds-canonical/fork/governance.lock +22 -7
  229. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
  230. package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
  231. package/ds-canonical/fork/manifest.json +10 -1
  232. package/ds-canonical/fork/preamble.md +3 -2
  233. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
  234. package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
  235. package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
  236. package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
  237. package/ds-canonical/hooks/check_datatable_invariants.sh +6 -3
  238. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
  239. package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +11 -2
  240. package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
  241. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
  242. package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
  243. package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
  244. package/ds-canonical/references/certified-surfaces.md +20 -0
  245. package/ds-canonical/references/preflight-gate-baseline.json +5 -0
  246. package/ds-canonical/references/principle-dim-map.json +20 -2
  247. package/ds-canonical/references/props-naming.md +2 -1
  248. package/ds-canonical/references/ssot-index.md +2 -2
  249. package/ds-canonical/references/story-baseline-registry.json +2 -2
  250. package/ds-canonical/rules/story-rules.md +1 -1
  251. package/ds-canonical/rules/ui-development.md +2 -1
  252. package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
  253. package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
  254. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  255. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
  256. package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
  257. package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
  258. package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
  259. package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
  260. package/ds-story-manifest.json +21 -21
  261. package/llms-full.txt +3 -3
  262. package/llms.txt +1 -1
  263. package/package.json +2 -1
  264. package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
  265. package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
  266. package/src/components/Accordion/accordion.spec.md +10 -1
  267. package/src/components/Accordion/accordion.stories.tsx +10 -5
  268. package/src/components/Accordion/accordion.tsx +7 -2
  269. package/src/components/Alert/alert.principles.stories.tsx +2 -8
  270. package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
  271. package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
  272. package/src/components/AppShell/app-shell.spec.md +4 -0
  273. package/src/components/AppShell/app-shell.stories.tsx +4 -5
  274. package/src/components/Avatar/avatar.tsx +1 -1
  275. package/src/components/Badge/badge.spec.md +2 -2
  276. package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
  277. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
  278. package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
  279. package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
  280. package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
  281. package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
  282. package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
  283. package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
  284. package/src/components/Button/button-group.tsx +4 -4
  285. package/src/components/Button/button.anatomy.stories.tsx +26 -7
  286. package/src/components/Button/button.principles.stories.tsx +1 -1
  287. package/src/components/Button/button.spec.md +2 -2
  288. package/src/components/Button/button.stories.tsx +22 -28
  289. package/src/components/Button/button.tsx +2 -1
  290. package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
  291. package/src/components/Calendar/calendar.spec.md +1 -1
  292. package/src/components/Carousel/carousel.spec.md +17 -1
  293. package/src/components/Carousel/carousel.tsx +93 -42
  294. package/src/components/Checkbox/checkbox-group.tsx +26 -15
  295. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
  296. package/src/components/Checkbox/checkbox.spec.md +14 -3
  297. package/src/components/Checkbox/checkbox.stories.tsx +4 -4
  298. package/src/components/Checkbox/checkbox.tsx +79 -19
  299. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
  300. package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
  301. package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
  302. package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
  303. package/src/components/Combobox/combobox.spec.md +6 -2
  304. package/src/components/Combobox/combobox.stories.tsx +9 -36
  305. package/src/components/Combobox/combobox.tsx +42 -27
  306. package/src/components/Command/command.spec.md +3 -3
  307. package/src/components/Command/command.tsx +9 -2
  308. package/src/components/DataTable/cell-registry.tsx +75 -76
  309. package/src/components/DataTable/column-types.ts +4 -17
  310. package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
  311. package/src/components/DataTable/data-table-filter-group.tsx +231 -0
  312. package/src/components/DataTable/data-table-filter-panel.tsx +19 -436
  313. package/src/components/DataTable/data-table-filter-value-picker.tsx +237 -0
  314. package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
  315. package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
  316. package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
  317. package/src/components/DataTable/data-table.css +2 -3
  318. package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
  319. package/src/components/DataTable/data-table.spec.md +8 -8
  320. package/src/components/DataTable/data-table.stories.tsx +39 -29
  321. package/src/components/DataTable/data-table.tsx +94 -68
  322. package/src/components/DataTable/filter-operators.spec.md +5 -3
  323. package/src/components/DateGrid/date-grid.spec.md +1 -1
  324. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
  325. package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
  326. package/src/components/DatePicker/date-picker.spec.md +9 -9
  327. package/src/components/DatePicker/date-picker.stories.tsx +9 -9
  328. package/src/components/DatePicker/date-picker.tsx +13 -13
  329. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
  330. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  331. package/src/components/DescriptionList/description-list.spec.md +12 -12
  332. package/src/components/DescriptionList/description-list.stories.tsx +3 -3
  333. package/src/components/DescriptionList/description-list.tsx +10 -10
  334. package/src/components/Dialog/dialog.tsx +4 -1
  335. package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
  336. package/src/components/Field/field-context.ts +17 -11
  337. package/src/components/Field/field-controls.spec.md +44 -37
  338. package/src/components/Field/field-types.ts +14 -12
  339. package/src/components/Field/field-wrapper.tsx +59 -43
  340. package/src/components/Field/field.anatomy.stories.tsx +6 -6
  341. package/src/components/Field/field.principles.stories.tsx +5 -28
  342. package/src/components/Field/field.spec.md +4 -4
  343. package/src/components/Field/field.stories.tsx +103 -72
  344. package/src/components/Field/field.tsx +36 -4
  345. package/src/components/Field/form-validation.spec.md +2 -0
  346. package/src/components/Field/index.ts +1 -0
  347. package/src/components/Field/use-form-validation.ts +1 -1
  348. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
  349. package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
  350. package/src/components/FileItem/file-item.tsx +10 -8
  351. package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
  352. package/src/components/FileUpload/file-upload.spec.md +3 -2
  353. package/src/components/FileUpload/file-upload.tsx +5 -1
  354. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
  355. package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
  356. package/src/components/FileViewer/file-viewer.spec.md +1 -1
  357. package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
  358. package/src/components/FileViewer/file-viewer.tsx +3 -2
  359. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
  360. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
  361. package/src/components/HoverCard/hover-card.spec.md +2 -2
  362. package/src/components/HoverCard/hover-card.tsx +4 -2
  363. package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
  364. package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
  365. package/src/components/InlineEdit/inline-edit.spec.md +71 -46
  366. package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
  367. package/src/components/InlineEdit/inline-edit.tsx +211 -125
  368. package/src/components/Input/input.anatomy.stories.tsx +15 -15
  369. package/src/components/Input/input.principles.stories.tsx +3 -3
  370. package/src/components/Input/input.spec.md +4 -4
  371. package/src/components/Input/input.stories.tsx +3 -3
  372. package/src/components/Input/input.tsx +13 -13
  373. package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
  374. package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
  375. package/src/components/LinkInput/link-input.spec.md +6 -2
  376. package/src/components/LinkInput/link-input.stories.tsx +8 -8
  377. package/src/components/LinkInput/link-input.tsx +21 -19
  378. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  379. package/src/components/Notice/notice.tsx +8 -2
  380. package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
  381. package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
  382. package/src/components/NumberInput/number-input.spec.md +6 -6
  383. package/src/components/NumberInput/number-input.stories.tsx +4 -4
  384. package/src/components/NumberInput/number-input.tsx +17 -5
  385. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
  386. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
  387. package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
  388. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
  389. package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
  390. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
  391. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
  392. package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
  393. package/src/components/PeoplePicker/people-picker.tsx +39 -20
  394. package/src/components/PeoplePicker/person-display.tsx +3 -3
  395. package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
  396. package/src/components/Popover/popover.principles.stories.tsx +49 -28
  397. package/src/components/Popover/popover.spec.md +4 -2
  398. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  399. package/src/components/ProfileCard/profile-card.tsx +1 -1
  400. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
  401. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
  402. package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
  403. package/src/components/README.md +1 -0
  404. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
  405. package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
  406. package/src/components/RadioGroup/radio-group.tsx +19 -14
  407. package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
  408. package/src/components/Rating/rating.principles.stories.tsx +3 -3
  409. package/src/components/Rating/rating.spec.md +2 -2
  410. package/src/components/Rating/rating.stories.tsx +4 -18
  411. package/src/components/Rating/rating.tsx +5 -1
  412. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  413. package/src/components/ScrollArea/scroll-area.spec.md +1 -1
  414. package/src/components/ScrollArea/scroll-area.tsx +5 -2
  415. package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
  416. package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
  417. package/src/components/SegmentedControl/segmented-control.tsx +6 -3
  418. package/src/components/Select/select.anatomy.stories.tsx +13 -7
  419. package/src/components/Select/select.principles.stories.tsx +3 -3
  420. package/src/components/Select/select.spec.md +11 -1
  421. package/src/components/Select/select.stories.tsx +41 -27
  422. package/src/components/Select/select.tsx +44 -26
  423. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
  424. package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
  425. package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
  426. package/src/components/SelectMenu/select-menu.tsx +38 -5
  427. package/src/components/SelectionControl/boolean-value.tsx +2 -2
  428. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  429. package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
  430. package/src/components/Separator/separator.principles.stories.tsx +1 -1
  431. package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
  432. package/src/components/Sheet/sheet.tsx +4 -1
  433. package/src/components/Sidebar/sidebar.tsx +1 -1
  434. package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
  435. package/src/components/Slider/slider.principles.stories.tsx +6 -6
  436. package/src/components/Slider/slider.spec.md +13 -1
  437. package/src/components/Slider/slider.stories.tsx +44 -32
  438. package/src/components/Slider/slider.tsx +13 -4
  439. package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
  440. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  441. package/src/components/Steps/steps.spec.md +4 -2
  442. package/src/components/Steps/steps.stories.tsx +4 -56
  443. package/src/components/Steps/steps.tsx +31 -7
  444. package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
  445. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  446. package/src/components/Switch/switch.spec.md +4 -4
  447. package/src/components/Switch/switch.stories.tsx +3 -3
  448. package/src/components/Switch/switch.tsx +16 -10
  449. package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
  450. package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
  451. package/src/components/Tabs/tabs.spec.md +5 -2
  452. package/src/components/Tabs/tabs.stories.tsx +36 -44
  453. package/src/components/Tabs/tabs.tsx +101 -36
  454. package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
  455. package/src/components/Tag/tag.principles.stories.tsx +4 -4
  456. package/src/components/Tag/tag.spec.md +3 -1
  457. package/src/components/Tag/tag.tsx +5 -3
  458. package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
  459. package/src/components/Textarea/textarea.spec.md +5 -5
  460. package/src/components/Textarea/textarea.tsx +24 -24
  461. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
  462. package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
  463. package/src/components/TimePicker/time-picker.spec.md +6 -5
  464. package/src/components/TimePicker/time-picker.stories.tsx +3 -3
  465. package/src/components/TimePicker/time-picker.tsx +24 -14
  466. package/src/components/Toast/toast.principles.stories.tsx +1 -1
  467. package/src/components/Toast/toast.stories.tsx +1 -1
  468. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
  469. package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
  470. package/src/components/Tooltip/tooltip.spec.md +9 -3
  471. package/src/components/Tooltip/tooltip.stories.tsx +1 -1
  472. package/src/components/Tooltip/tooltip.tsx +12 -2
  473. package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
  474. package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
  475. package/src/components/TreeView/tree-view.spec.md +8 -6
  476. package/src/components/TreeView/tree-view.stories.tsx +9 -43
  477. package/src/components/TreeView/tree-view.tsx +36 -0
  478. package/src/index.ts +16 -9
  479. package/src/lib/drag-visual.ts +2 -2
  480. package/src/lib/utils.ts +19 -0
  481. package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
  482. package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
  483. package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
  484. package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
  485. package/src/tokens/categorical-color.ts +5 -5
  486. package/src/tokens/color/color.spec.md +5 -5
  487. package/src/tokens/color/primitives.css +9 -2
  488. package/src/tokens/opacity/opacity.spec.md +1 -1
  489. package/src/tokens/orphan-tokens.spec.md +1 -1
  490. package/src/tokens/typography/typography.spec.md +2 -0
  491. package/src/tokens/uiSize/uiSize.css +6 -1
  492. package/src/tokens/uiSize/uiSize.spec.md +1 -1
@@ -1,11 +1,10 @@
1
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { RotateCcw, X, Search, Lock, GripVertical, Eye, EyeOff } from "lucide-react";
4
4
  import { Button } from "../Button/button.js";
5
5
  import { ButtonDivider } from "../Button/button-group.js";
6
6
  import { Input } from "../Input/input.js";
7
- import { ScrollArea } from "../ScrollArea/scroll-area.js";
8
- import { PopoverHeader, PopoverTitle, PopoverClose, PopoverFooter } from "../Popover/popover.js";
7
+ import { PopoverHeader, PopoverTitle, PopoverClose, PopoverBody, PopoverFooter } from "../Popover/popover.js";
9
8
  import { ItemPrefix, ItemInlineActionButton, ItemLabel, ROW_PADDING_BY_SIZE } from "../../patterns/element-anatomy/item-anatomy.js";
10
9
  import { cn } from "../../lib/utils.js";
11
10
  import { DndContext, closestCenter } from "@dnd-kit/core";
@@ -67,67 +66,75 @@ function DataTableColumnVisibilityPanel({
67
66
  next.splice(newIdx, 0, m);
68
67
  onColumnOrderChange(next);
69
68
  };
70
- return /* @__PURE__ */ jsxs(Fragment, { children: [
71
- /* @__PURE__ */ jsx(PopoverHeader, { hideClose: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 w-full min-w-0", children: [
72
- /* @__PURE__ */ jsx(PopoverTitle, { className: "flex-1", children: "欄位顯示" }),
73
- resettable && anyHidden && /* @__PURE__ */ jsxs(Fragment, { children: [
74
- /* @__PURE__ */ jsx(
75
- Button,
76
- {
77
- variant: "text",
78
- size: "sm",
79
- iconOnly: true,
80
- startIcon: RotateCcw,
81
- "aria-label": "恢復預設",
82
- onClick: handleReset
83
- }
84
- ),
85
- /* @__PURE__ */ jsx(ButtonDivider, {})
86
- ] }),
87
- /* @__PURE__ */ jsx(PopoverClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { "data-dismiss": true, iconOnly: true, dismiss: true, size: "sm", startIcon: X, "aria-label": "關閉" }) })
88
- ] }) }),
89
- searchable && /* @__PURE__ */ jsx("div", { className: "px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]", children: /* @__PURE__ */ jsx(
90
- Input,
91
- {
92
- size: "md",
93
- placeholder: "搜尋欄位…",
94
- value: search,
95
- onChange: (e) => setSearch(e.target.value),
96
- startIcon: Search
97
- }
98
- ) }),
99
- /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-72", children: /* @__PURE__ */ jsx("div", { className: "py-2 flex flex-col", style: { "--item-prefix-slot": "16px" }, children: dndEnabled ? /* @__PURE__ */ jsx(DndContext, { collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(
100
- SortableContext,
101
- {
102
- items: filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id)),
103
- strategy: verticalListSortingStrategy,
104
- children: filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
105
- VisibilityRow,
106
- {
107
- id,
108
- label,
109
- visible: visibility[id] !== false,
110
- locked: lockedSet.has(id),
111
- draggable: true,
112
- onToggle: () => handleToggle(id)
113
- },
114
- id
115
- ))
116
- }
117
- ) }) : filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
118
- VisibilityRow,
119
- {
120
- id,
121
- label,
122
- visible: visibility[id] !== false,
123
- locked: lockedSet.has(id),
124
- draggable: false,
125
- onToggle: () => handleToggle(id)
126
- },
127
- id
128
- )) }) }),
129
- /* @__PURE__ */ jsx(PopoverFooter, { className: "justify-start", children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleBulkToggle, children: allVisible ? "全部隱藏" : "顯示全部" }) })
130
- ] });
69
+ return (
70
+ // 決策16 定案(2026-07-18,SSOT consistency 稽核後):對齊 sibling FilterPanel/SortManager
71
+ // overlay-surface canonical shape —— root `<div flex flex-col h-full min-h-0>`(M25 viewport-aware
72
+ // scroll chain)+ viewport-adaptive `PopoverBody`(取代原 fixed `ScrollArea max-h-72`)。三個
73
+ // DataTable state-panel 收斂成同一形狀,body 隨視窗高度自適應(高螢幕多欄不再硬卡 288px)。
74
+ // 寬度仍由 consumer 的 `<PopoverContent w-72>` 提供(panel root w-full 撐滿)。
75
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full min-h-0 w-full", children: [
76
+ /* @__PURE__ */ jsx(PopoverHeader, { hideClose: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 w-full min-w-0", children: [
77
+ /* @__PURE__ */ jsx(PopoverTitle, { className: "flex-1", children: "欄位顯示" }),
78
+ resettable && anyHidden && /* @__PURE__ */ jsxs(Fragment, { children: [
79
+ /* @__PURE__ */ jsx(
80
+ Button,
81
+ {
82
+ variant: "text",
83
+ size: "sm",
84
+ iconOnly: true,
85
+ startIcon: RotateCcw,
86
+ "aria-label": "恢復預設",
87
+ onClick: handleReset
88
+ }
89
+ ),
90
+ /* @__PURE__ */ jsx(ButtonDivider, {})
91
+ ] }),
92
+ /* @__PURE__ */ jsx(PopoverClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { "data-dismiss": true, iconOnly: true, dismiss: true, size: "sm", startIcon: X, "aria-label": "關閉" }) })
93
+ ] }) }),
94
+ searchable && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]", children: /* @__PURE__ */ jsx(
95
+ Input,
96
+ {
97
+ size: "md",
98
+ placeholder: "搜尋欄位…",
99
+ "aria-label": "搜尋欄位",
100
+ value: search,
101
+ onChange: (e) => setSearch(e.target.value),
102
+ startIcon: Search
103
+ }
104
+ ) }),
105
+ /* @__PURE__ */ jsx(PopoverBody, { className: "!px-0 !py-0", children: /* @__PURE__ */ jsx("div", { className: "py-2 flex flex-col", style: { "--item-prefix-slot": "16px" }, children: dndEnabled ? /* @__PURE__ */ jsx(DndContext, { collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(
106
+ SortableContext,
107
+ {
108
+ items: filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id)),
109
+ strategy: verticalListSortingStrategy,
110
+ children: filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
111
+ VisibilityRow,
112
+ {
113
+ id,
114
+ label,
115
+ visible: visibility[id] !== false,
116
+ locked: lockedSet.has(id),
117
+ draggable: true,
118
+ onToggle: () => handleToggle(id)
119
+ },
120
+ id
121
+ ))
122
+ }
123
+ ) }) : filteredEntries.map(({ id, label }) => /* @__PURE__ */ jsx(
124
+ VisibilityRow,
125
+ {
126
+ id,
127
+ label,
128
+ visible: visibility[id] !== false,
129
+ locked: lockedSet.has(id),
130
+ draggable: false,
131
+ onToggle: () => handleToggle(id)
132
+ },
133
+ id
134
+ )) }) }),
135
+ /* @__PURE__ */ jsx(PopoverFooter, { className: "justify-start", children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleBulkToggle, children: allVisible ? "全部隱藏" : "顯示全部" }) })
136
+ ] })
137
+ );
131
138
  }
132
139
  function VisibilityRow({
133
140
  id,
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-column-visibility-panel.js","sources":["../../../src/components/DataTable/data-table-column-visibility-panel.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/**\n * DataTableColumnVisibilityPanel — Issue 3 primitive(2026-05-10)。\n *\n * 從 WithBulkActions story L868+(149 lines)+ RoadmapAllInOne(L1796+,53 lines)抽出 SSOT\n * primitive。Roadmap demo 跟 WithBulkActions 都用此 panel 開啟「欄位顯示」popover。\n *\n * **Feature SSOT**(對齊 Linear / Airtable / Notion / Material X-DataGrid 的 columnVisibility panel idiom):\n * - 列出所有 togglable 欄位 + Eye / EyeOff 切換\n * - Locked 欄位(`lockedIds`)— 顯 Lock icon,不可 toggle / 不可 drag\n * - 可選 search filter(`searchable`,跨欄位 label match)\n * - 可選 column drag reorder(`onColumnOrderChange` 傳 → 啟 DnD)\n * - 可選 reset 按鈕(`resettable: boolean` opt-in,header 區 RotateCcw;點擊 `onVisibilityChange({})` 還原全顯示,無獨立 onReset prop)\n * - Bidirectional bulk toggle(footer button:全可見 → 全部隱藏 / 任一隱藏 → 顯示全部)\n *\n * **Why 抽 primitive**(per Issue 3 Rule-of-3):RoadmapAllInOne + WithBulkActions + 未來 product\n * UI 至少 3 處消費同 panel。重複 hand-craft → 設計語言 drift(已抓到:Roadmap 版無 search /\n * 無 drag / 無 reset,WithBulkActions 版有,語意不一致)。Primitive 把所有 feature 集中,\n * consumer opt-in via props 確保 SSOT。\n *\n * **對齊**:Linear column-visibility-panel pattern / Material X-DataGrid `<GridColumnsPanel>`\n * / Airtable Field-config drawer。\n */\n\nimport * as React from 'react'\nimport { Eye, EyeOff, Lock, GripVertical, Search, RotateCcw, X as XIcon } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { ButtonDivider } from '@/design-system/components/Button/button-group'\nimport { Input } from '@/design-system/components/Input/input'\nimport { ScrollArea } from '@/design-system/components/ScrollArea/scroll-area'\nimport { PopoverHeader, PopoverFooter, PopoverTitle, PopoverClose } from '@/design-system/components/Popover/popover'\nimport { ItemPrefix, ItemLabel, ItemInlineActionButton, ROW_PADDING_BY_SIZE } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { cn } from '@/lib/utils'\nimport { DndContext, closestCenter, type DragEndEvent } from '@dnd-kit/core'\nimport { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { dragSourceStyle } from '@/design-system/lib/drag-visual'\n\ninterface ColumnVisibilityPanelColumn {\n /** Column id(stable identifier;對齊 DataTable column.id / accessorKey)*/\n id: string\n /** Column header label(human-readable)*/\n label: string\n}\n\nexport interface DataTableColumnVisibilityPanelProps {\n /** 全部可 toggle 欄位(consumer 已過濾掉 system cols 如 __select__)*/\n columns: ColumnVisibilityPanelColumn[]\n /** 受控 visibility map(`true` / undefined = visible / `false` = hidden)*/\n visibility: Record<string, boolean>\n /** Visibility 變更 callback */\n onVisibilityChange: (next: Record<string, boolean>) => void\n /** 受控 column order(若提供啟 DnD reorder) */\n columnOrder?: string[]\n /** Order 變更 callback;若提供 → 啟用 drag handle / DnD reorder */\n onColumnOrderChange?: (next: string[]) => void\n /** Locked column ids(顯 Lock icon,不可 toggle / 不可 drag)*/\n lockedIds?: string[]\n /** 是否啟搜尋 input(預設 false)*/\n searchable?: boolean\n /** 是否顯 reset button(任一欄隱藏才顯,onClick 清空 visibility map)*/\n resettable?: boolean\n // Issue 3 post-codex audit(2026-05-10):`onClose` prop retired — Radix `PopoverClose asChild`\n // 已自帶 popover dismiss,沒 concrete consumer 需 callback。Future 若需要再加。\n}\n\nexport function DataTableColumnVisibilityPanel({\n columns,\n visibility,\n onVisibilityChange,\n columnOrder,\n onColumnOrderChange,\n lockedIds = [],\n searchable = false,\n resettable = false,\n}: DataTableColumnVisibilityPanelProps) {\n const [search, setSearch] = React.useState('')\n const lockedSet = React.useMemo(() => new Set(lockedIds), [lockedIds])\n const dndEnabled = !!(columnOrder && onColumnOrderChange)\n\n // 計算 visible order:用 columnOrder 排,fallback columns 順序。\n const orderedIds = React.useMemo(() => {\n if (columnOrder && columnOrder.length > 0) {\n const colSet = new Set(columns.map((c) => c.id))\n return columnOrder.filter((id) => colSet.has(id))\n }\n return columns.map((c) => c.id)\n }, [columnOrder, columns])\n\n const filteredEntries = React.useMemo(() => {\n return orderedIds\n .map((id) => columns.find((c) => c.id === id))\n .filter((c): c is ColumnVisibilityPanelColumn => c != null)\n .filter((c) => (search ? c.label.toLowerCase().includes(search.toLowerCase()) : true))\n }, [orderedIds, columns, search])\n\n const togglableIds = columns.map((c) => c.id).filter((id) => !lockedSet.has(id))\n const allVisible = togglableIds.every((id) => visibility[id] !== false)\n const anyHidden = togglableIds.some((id) => visibility[id] === false)\n\n const handleToggle = (id: string) => {\n const visible = visibility[id] !== false\n onVisibilityChange({ ...visibility, [id]: !visible })\n }\n\n const handleReset = () => onVisibilityChange({})\n\n const handleBulkToggle = () => {\n if (allVisible) {\n const next: Record<string, boolean> = {}\n togglableIds.forEach((id) => { next[id] = false })\n onVisibilityChange(next)\n } else {\n onVisibilityChange({})\n }\n }\n\n const handleDragEnd = (e: DragEndEvent) => {\n if (!dndEnabled) return\n const { active, over } = e\n if (!over || active.id === over.id) return\n const oldIdx = columnOrder!.indexOf(active.id as string)\n const newIdx = columnOrder!.indexOf(over.id as string)\n if (oldIdx < 0 || newIdx < 0) return\n // Locked id 不可被 reorder 動到\n if (lockedSet.has(columnOrder![oldIdx]) || lockedSet.has(columnOrder![newIdx])) return\n const next = [...columnOrder!]\n const [m] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, m)\n onColumnOrderChange!(next)\n }\n\n return (\n <>\n <PopoverHeader hideClose>\n <div className=\"flex items-center gap-1 w-full min-w-0\">\n <PopoverTitle className=\"flex-1\">欄位顯示</PopoverTitle>\n {resettable && anyHidden && (\n <>\n <Button\n variant=\"text\" size=\"sm\" iconOnly startIcon={RotateCcw}\n aria-label=\"恢復預設\"\n onClick={handleReset}\n />\n <ButtonDivider />\n </>\n )}\n <PopoverClose asChild>\n <Button data-dismiss iconOnly dismiss size=\"sm\" startIcon={XIcon} aria-label=\"關閉\" />\n </PopoverClose>\n </div>\n </PopoverHeader>\n {searchable && (\n <div className=\"px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]\">\n <Input\n size=\"md\"\n placeholder=\"搜尋欄位…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n startIcon={Search}\n />\n </div>\n )}\n <ScrollArea className=\"max-h-72\">\n <div className=\"py-2 flex flex-col\" style={{ '--item-prefix-slot': '16px' } as React.CSSProperties}>\n {dndEnabled ? (\n <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <SortableContext\n items={filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id))}\n strategy={verticalListSortingStrategy}\n >\n {filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable\n onToggle={() => handleToggle(id)}\n />\n ))}\n </SortableContext>\n </DndContext>\n ) : (\n filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable={false}\n onToggle={() => handleToggle(id)}\n />\n ))\n )}\n </div>\n </ScrollArea>\n <PopoverFooter className=\"justify-start\">\n <Button variant=\"tertiary\" size=\"sm\" onClick={handleBulkToggle}>\n {allVisible ? '全部隱藏' : '顯示全部'}\n </Button>\n </PopoverFooter>\n </>\n )\n}\n\n// VisibilityRow:single column row。Draggable mode → GripVertical handle / static mode → 無 handle。\nfunction VisibilityRow({\n id, label, visible, locked, draggable, onToggle,\n}: {\n id: string\n label: string\n visible: boolean\n locked: boolean\n draggable: boolean\n onToggle: () => void\n}) {\n // Conditional hooks 不行 — 永遠呼 useSortable,只是 disabled 時 listeners no-op\n const sortable = useSortable({ id, disabled: locked || !draggable })\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable\n const style: React.CSSProperties = draggable\n ? { transform: CSS.Transform.toString(transform), transition, ...dragSourceStyle(isDragging) }\n : {}\n return (\n <div\n ref={draggable ? setNodeRef : undefined}\n style={style}\n className={cn(\n 'flex items-start gap-2 w-full px-[var(--layout-space-loose)]',\n ROW_PADDING_BY_SIZE.md,\n )}\n >\n <ItemPrefix>\n {/* 2026-05-18 改 per user「做完」approval:14 → 16 對齊 uiSize.spec.md Icon Tier */}\n {locked ? (\n <Lock size={16} className=\"text-fg-muted\" aria-hidden />\n ) : draggable ? (\n <ItemInlineActionButton\n icon={GripVertical}\n size=\"md\"\n aria-label=\"拖曳重排\"\n className=\"cursor-grab active:cursor-grabbing\"\n {...attributes}\n {...listeners}\n />\n ) : null}\n </ItemPrefix>\n <ItemLabel className={locked ? 'text-fg-disabled' : undefined}>{label}</ItemLabel>\n <ItemInlineActionButton\n icon={visible ? Eye : EyeOff}\n size=\"md\"\n aria-label={visible ? '隱藏此欄' : '顯示此欄'}\n disabled={locked}\n onClick={onToggle}\n className={locked ? 'cursor-not-allowed text-fg-disabled' : ''}\n />\n </div>\n )\n}\n"],"names":["XIcon"],"mappings":";;;;;;;;;;;;;;AAkEO,SAAS,+BAA+B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,CAAA;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AACf,GAAwC;AACtC,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,EAAE;AAC7C,QAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,IAAI,SAAS,GAAG,CAAC,SAAS,CAAC;AACrE,QAAM,aAAa,CAAC,EAAE,eAAe;AAGrC,QAAM,aAAa,MAAM,QAAQ,MAAM;AACrC,QAAI,eAAe,YAAY,SAAS,GAAG;AACzC,YAAM,SAAS,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/C,aAAO,YAAY,OAAO,CAAC,OAAO,OAAO,IAAI,EAAE,CAAC;AAAA,IAClD;AACA,WAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAChC,GAAG,CAAC,aAAa,OAAO,CAAC;AAEzB,QAAM,kBAAkB,MAAM,QAAQ,MAAM;AAC1C,WAAO,WACJ,IAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAC5C,OAAO,CAAC,MAAwC,KAAK,IAAI,EACzD,OAAO,CAAC,MAAO,SAAS,EAAE,MAAM,YAAA,EAAc,SAAS,OAAO,YAAA,CAAa,IAAI,IAAK;AAAA,EACzF,GAAG,CAAC,YAAY,SAAS,MAAM,CAAC;AAEhC,QAAM,eAAe,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;AAC/E,QAAM,aAAa,aAAa,MAAM,CAAC,OAAO,WAAW,EAAE,MAAM,KAAK;AACtE,QAAM,YAAY,aAAa,KAAK,CAAC,OAAO,WAAW,EAAE,MAAM,KAAK;AAEpE,QAAM,eAAe,CAAC,OAAe;AACnC,UAAM,UAAU,WAAW,EAAE,MAAM;AACnC,uBAAmB,EAAE,GAAG,YAAY,CAAC,EAAE,GAAG,CAAC,SAAS;AAAA,EACtD;AAEA,QAAM,cAAc,MAAM,mBAAmB,EAAE;AAE/C,QAAM,mBAAmB,MAAM;AAC7B,QAAI,YAAY;AACd,YAAM,OAAgC,CAAA;AACtC,mBAAa,QAAQ,CAAC,OAAO;AAAE,aAAK,EAAE,IAAI;AAAA,MAAM,CAAC;AACjD,yBAAmB,IAAI;AAAA,IACzB,OAAO;AACL,yBAAmB,CAAA,CAAE;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAAoB;AACzC,QAAI,CAAC,WAAY;AACjB,UAAM,EAAE,QAAQ,KAAA,IAAS;AACzB,QAAI,CAAC,QAAQ,OAAO,OAAO,KAAK,GAAI;AACpC,UAAM,SAAS,YAAa,QAAQ,OAAO,EAAY;AACvD,UAAM,SAAS,YAAa,QAAQ,KAAK,EAAY;AACrD,QAAI,SAAS,KAAK,SAAS,EAAG;AAE9B,QAAI,UAAU,IAAI,YAAa,MAAM,CAAC,KAAK,UAAU,IAAI,YAAa,MAAM,CAAC,EAAG;AAChF,UAAM,OAAO,CAAC,GAAG,WAAY;AAC7B,UAAM,CAAC,CAAC,IAAI,KAAK,OAAO,QAAQ,CAAC;AACjC,SAAK,OAAO,QAAQ,GAAG,CAAC;AACxB,wBAAqB,IAAI;AAAA,EAC3B;AAEA,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,iBAAc,WAAS,MACtB,UAAA,qBAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAA,oBAAC,cAAA,EAAa,WAAU,UAAS,UAAA,QAAI;AAAA,MACpC,cAAc,aACb,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YAAO,MAAK;AAAA,YAAK,UAAQ;AAAA,YAAC,WAAW;AAAA,YAC7C,cAAW;AAAA,YACX,SAAS;AAAA,UAAA;AAAA,QAAA;AAAA,4BAEV,eAAA,CAAA,CAAc;AAAA,MAAA,GACjB;AAAA,0BAED,cAAA,EAAa,SAAO,MACnB,UAAA,oBAAC,QAAA,EAAO,gBAAY,MAAC,UAAQ,MAAC,SAAO,MAAC,MAAK,MAAK,WAAWA,GAAO,cAAW,MAAK,EAAA,CACpF;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IACC,cACC,oBAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,aAAY;AAAA,QACZ,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,KAAK;AAAA,QACzC,WAAW;AAAA,MAAA;AAAA,IAAA,GAEf;AAAA,wBAED,YAAA,EAAW,WAAU,YACpB,UAAA,oBAAC,OAAA,EAAI,WAAU,sBAAqB,OAAO,EAAE,sBAAsB,UAChE,UAAA,aACC,oBAAC,cAAW,oBAAoB,eAAe,WAAW,eACxD,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO,gBAAgB,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;AAAA,QACzE,UAAU;AAAA,QAET,0BAAgB,IAAI,CAAC,EAAE,IAAI,YAC1B;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC;AAAA,YACA;AAAA,YACA,SAAS,WAAW,EAAE,MAAM;AAAA,YAC5B,QAAQ,UAAU,IAAI,EAAE;AAAA,YACxB,WAAS;AAAA,YACT,UAAU,MAAM,aAAa,EAAE;AAAA,UAAA;AAAA,UAN1B;AAAA,QAAA,CAQR;AAAA,MAAA;AAAA,IAAA,EACH,CACF,IAEA,gBAAgB,IAAI,CAAC,EAAE,IAAI,YACzB;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA,SAAS,WAAW,EAAE,MAAM;AAAA,QAC5B,QAAQ,UAAU,IAAI,EAAE;AAAA,QACxB,WAAW;AAAA,QACX,UAAU,MAAM,aAAa,EAAE;AAAA,MAAA;AAAA,MAN1B;AAAA,IAAA,CAQR,GAEL,EAAA,CACF;AAAA,IACA,oBAAC,eAAA,EAAc,WAAU,iBACvB,8BAAC,QAAA,EAAO,SAAQ,YAAW,MAAK,MAAK,SAAS,kBAC3C,UAAA,aAAa,SAAS,QACzB,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAGA,SAAS,cAAc;AAAA,EACrB;AAAA,EAAI;AAAA,EAAO;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAW;AACzC,GAOG;AAED,QAAM,WAAW,YAAY,EAAE,IAAI,UAAU,UAAU,CAAC,WAAW;AACnE,QAAM,EAAE,YAAY,WAAW,YAAY,WAAW,YAAY,eAAe;AACjF,QAAM,QAA6B,YAC/B,EAAE,WAAW,IAAI,UAAU,SAAS,SAAS,GAAG,YAAY,GAAG,gBAAgB,UAAU,EAAA,IACzF,CAAA;AACJ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK,YAAY,aAAa;AAAA,MAC9B;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,MAGtB,UAAA;AAAA,QAAA,oBAAC,YAAA,EAEE,UAAA,SACC,oBAAC,MAAA,EAAK,MAAM,IAAI,WAAU,iBAAgB,eAAW,KAAA,CAAC,IACpD,YACF;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,MAAK;AAAA,YACL,cAAW;AAAA,YACX,WAAU;AAAA,YACT,GAAG;AAAA,YACH,GAAG;AAAA,UAAA;AAAA,QAAA,IAEJ,KAAA,CACN;AAAA,4BACC,WAAA,EAAU,WAAW,SAAS,qBAAqB,QAAY,UAAA,OAAM;AAAA,QACtE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM,UAAU,MAAM;AAAA,YACtB,MAAK;AAAA,YACL,cAAY,UAAU,SAAS;AAAA,YAC/B,UAAU;AAAA,YACV,SAAS;AAAA,YACT,WAAW,SAAS,wCAAwC;AAAA,UAAA;AAAA,QAAA;AAAA,MAC9D;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"data-table-column-visibility-panel.js","sources":["../../../src/components/DataTable/data-table-column-visibility-panel.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/**\n * DataTableColumnVisibilityPanel — Issue 3 primitive(2026-05-10)。\n *\n * 從 WithBulkActions story L868+(149 lines)+ RoadmapAllInOne(L1796+,53 lines)抽出 SSOT\n * primitive。Roadmap demo 跟 WithBulkActions 都用此 panel 開啟「欄位顯示」popover。\n *\n * **Feature SSOT**(對齊 Linear / Airtable / Notion / Material X-DataGrid 的 columnVisibility panel idiom):\n * - 列出所有 togglable 欄位 + Eye / EyeOff 切換\n * - Locked 欄位(`lockedIds`)— 顯 Lock icon,不可 toggle / 不可 drag\n * - 可選 search filter(`searchable`,跨欄位 label match)\n * - 可選 column drag reorder(`onColumnOrderChange` 傳 → 啟 DnD)\n * - 可選 reset 按鈕(`resettable: boolean` opt-in,header 區 RotateCcw;點擊 `onVisibilityChange({})` 還原全顯示,無獨立 onReset prop)\n * - Bidirectional bulk toggle(footer button:全可見 → 全部隱藏 / 任一隱藏 → 顯示全部)\n *\n * **Why 抽 primitive**(per Issue 3 Rule-of-3):RoadmapAllInOne + WithBulkActions + 未來 product\n * UI 至少 3 處消費同 panel。重複 hand-craft → 設計語言 drift(已抓到:Roadmap 版無 search /\n * 無 drag / 無 reset,WithBulkActions 版有,語意不一致)。Primitive 把所有 feature 集中,\n * consumer opt-in via props 確保 SSOT。\n *\n * **對齊**:Linear column-visibility-panel pattern / Material X-DataGrid `<GridColumnsPanel>`\n * / Airtable Field-config drawer。\n */\n\nimport * as React from 'react'\nimport { Eye, EyeOff, Lock, GripVertical, Search, RotateCcw, X as XIcon } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { ButtonDivider } from '@/design-system/components/Button/button-group'\nimport { Input } from '@/design-system/components/Input/input'\nimport { PopoverHeader, PopoverBody, PopoverFooter, PopoverTitle, PopoverClose } from '@/design-system/components/Popover/popover'\nimport { ItemPrefix, ItemLabel, ItemInlineActionButton, ROW_PADDING_BY_SIZE } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { cn } from '@/lib/utils'\nimport { DndContext, closestCenter, type DragEndEvent } from '@dnd-kit/core'\nimport { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { dragSourceStyle } from '@/design-system/lib/drag-visual'\n\ninterface ColumnVisibilityPanelColumn {\n /** Column id(stable identifier;對齊 DataTable column.id / accessorKey)*/\n id: string\n /** Column header label(human-readable)*/\n label: string\n}\n\nexport interface DataTableColumnVisibilityPanelProps {\n /** 全部可 toggle 欄位(consumer 已過濾掉 system cols 如 __select__)*/\n columns: ColumnVisibilityPanelColumn[]\n /** 受控 visibility map(`true` / undefined = visible / `false` = hidden)*/\n visibility: Record<string, boolean>\n /** Visibility 變更 callback */\n onVisibilityChange: (next: Record<string, boolean>) => void\n /** 受控 column order(若提供啟 DnD reorder) */\n columnOrder?: string[]\n /** Order 變更 callback;若提供 → 啟用 drag handle / DnD reorder */\n onColumnOrderChange?: (next: string[]) => void\n /** Locked column ids(顯 Lock icon,不可 toggle / 不可 drag)*/\n lockedIds?: string[]\n /** 是否啟搜尋 input(預設 false)*/\n searchable?: boolean\n /** 是否顯 reset button(任一欄隱藏才顯,onClick 清空 visibility map)*/\n resettable?: boolean\n // Issue 3 post-codex audit(2026-05-10):`onClose` prop retired — Radix `PopoverClose asChild`\n // 已自帶 popover dismiss,沒 concrete consumer 需 callback。Future 若需要再加。\n}\n\nexport function DataTableColumnVisibilityPanel({\n columns,\n visibility,\n onVisibilityChange,\n columnOrder,\n onColumnOrderChange,\n lockedIds = [],\n searchable = false,\n resettable = false,\n}: DataTableColumnVisibilityPanelProps) {\n const [search, setSearch] = React.useState('')\n const lockedSet = React.useMemo(() => new Set(lockedIds), [lockedIds])\n const dndEnabled = !!(columnOrder && onColumnOrderChange)\n\n // 計算 visible order:用 columnOrder 排,fallback columns 順序。\n const orderedIds = React.useMemo(() => {\n if (columnOrder && columnOrder.length > 0) {\n const colSet = new Set(columns.map((c) => c.id))\n return columnOrder.filter((id) => colSet.has(id))\n }\n return columns.map((c) => c.id)\n }, [columnOrder, columns])\n\n const filteredEntries = React.useMemo(() => {\n return orderedIds\n .map((id) => columns.find((c) => c.id === id))\n .filter((c): c is ColumnVisibilityPanelColumn => c != null)\n .filter((c) => (search ? c.label.toLowerCase().includes(search.toLowerCase()) : true))\n }, [orderedIds, columns, search])\n\n const togglableIds = columns.map((c) => c.id).filter((id) => !lockedSet.has(id))\n const allVisible = togglableIds.every((id) => visibility[id] !== false)\n const anyHidden = togglableIds.some((id) => visibility[id] === false)\n\n const handleToggle = (id: string) => {\n const visible = visibility[id] !== false\n onVisibilityChange({ ...visibility, [id]: !visible })\n }\n\n const handleReset = () => onVisibilityChange({})\n\n const handleBulkToggle = () => {\n if (allVisible) {\n const next: Record<string, boolean> = {}\n togglableIds.forEach((id) => { next[id] = false })\n onVisibilityChange(next)\n } else {\n onVisibilityChange({})\n }\n }\n\n const handleDragEnd = (e: DragEndEvent) => {\n if (!dndEnabled) return\n const { active, over } = e\n if (!over || active.id === over.id) return\n const oldIdx = columnOrder!.indexOf(active.id as string)\n const newIdx = columnOrder!.indexOf(over.id as string)\n if (oldIdx < 0 || newIdx < 0) return\n // Locked id 不可被 reorder 動到\n if (lockedSet.has(columnOrder![oldIdx]) || lockedSet.has(columnOrder![newIdx])) return\n const next = [...columnOrder!]\n const [m] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, m)\n onColumnOrderChange!(next)\n }\n\n // 2026-07-18 決策16 錯誤史(明記以免再犯):原本這個 panel 是 Fragment + fixed `ScrollArea max-h-72`,\n // 與 sibling FilterPanel/SortManager(root-div + viewport-aware SurfaceBody)不一致。我給過**兩個都錯**\n // 的辯護理由 —— (1)「PopoverHeader 用 -mx 負邊距、包 root 會破壞」= 錯(SurfaceHeader 用正 px-loose+border-b,\n // 無 -mx);(2)「sibling 自刻 header 不用 primitive」= 錯(三 panel 皆消費 SurfaceHeader/PopoverHeader primitive)。\n // 真正差異只是 body/scroll 策略。multi-agent SSOT consistency 稽核定案:**是 drift,該統一**(fixed 288px cap\n // 在高螢幕多欄下劣於 sibling 的 viewport-adaptive;且是唯一不能當 template 複製的 panel)。故下方已改成 canonical shape。\n return (\n // 決策16 定案(2026-07-18,SSOT consistency 稽核後):對齊 sibling FilterPanel/SortManager 的\n // overlay-surface canonical shape —— root `<div flex flex-col h-full min-h-0>`(M25 viewport-aware\n // scroll chain)+ viewport-adaptive `PopoverBody`(取代原 fixed `ScrollArea max-h-72`)。三個\n // DataTable state-panel 收斂成同一形狀,body 隨視窗高度自適應(高螢幕多欄不再硬卡 288px)。\n // 寬度仍由 consumer 的 `<PopoverContent w-72>` 提供(panel root w-full 撐滿)。\n <div className=\"flex flex-col h-full min-h-0 w-full\">\n <PopoverHeader hideClose>\n <div className=\"flex items-center gap-1 w-full min-w-0\">\n <PopoverTitle className=\"flex-1\">欄位顯示</PopoverTitle>\n {resettable && anyHidden && (\n <>\n <Button\n variant=\"text\" size=\"sm\" iconOnly startIcon={RotateCcw}\n aria-label=\"恢復預設\"\n onClick={handleReset}\n />\n <ButtonDivider />\n </>\n )}\n <PopoverClose asChild>\n <Button data-dismiss iconOnly dismiss size=\"sm\" startIcon={XIcon} aria-label=\"關閉\" />\n </PopoverClose>\n </div>\n </PopoverHeader>\n {searchable && (\n <div className=\"shrink-0 px-[var(--layout-space-loose)] pt-[var(--layout-space-tight)]\">\n <Input\n size=\"md\"\n placeholder=\"搜尋欄位…\"\n aria-label=\"搜尋欄位\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n startIcon={Search}\n />\n </div>\n )}\n {/* viewport-adaptive body(List-as-region idiom:PopoverBody !px-0 !py-0 撤 chrome padding,\n 內層 py-2 給垂直呼吸、row 自帶 px-loose 水平 padding)。取代原 fixed ScrollArea max-h-72。 */}\n <PopoverBody className=\"!px-0 !py-0\">\n <div className=\"py-2 flex flex-col\" style={{ '--item-prefix-slot': '16px' } as React.CSSProperties}>\n {dndEnabled ? (\n <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <SortableContext\n items={filteredEntries.map((e) => e.id).filter((id) => !lockedSet.has(id))}\n strategy={verticalListSortingStrategy}\n >\n {filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable\n onToggle={() => handleToggle(id)}\n />\n ))}\n </SortableContext>\n </DndContext>\n ) : (\n filteredEntries.map(({ id, label }) => (\n <VisibilityRow\n key={id}\n id={id}\n label={label}\n visible={visibility[id] !== false}\n locked={lockedSet.has(id)}\n draggable={false}\n onToggle={() => handleToggle(id)}\n />\n ))\n )}\n </div>\n </PopoverBody>\n <PopoverFooter className=\"justify-start\">\n <Button variant=\"tertiary\" size=\"sm\" onClick={handleBulkToggle}>\n {allVisible ? '全部隱藏' : '顯示全部'}\n </Button>\n </PopoverFooter>\n </div>\n )\n}\n\n// VisibilityRow:single column row。Draggable mode → GripVertical handle / static mode → 無 handle。\nfunction VisibilityRow({\n id, label, visible, locked, draggable, onToggle,\n}: {\n id: string\n label: string\n visible: boolean\n locked: boolean\n draggable: boolean\n onToggle: () => void\n}) {\n // Conditional hooks 不行 — 永遠呼 useSortable,只是 disabled 時 listeners no-op\n const sortable = useSortable({ id, disabled: locked || !draggable })\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable\n const style: React.CSSProperties = draggable\n ? { transform: CSS.Transform.toString(transform), transition, ...dragSourceStyle(isDragging) }\n : {}\n return (\n <div\n ref={draggable ? setNodeRef : undefined}\n style={style}\n className={cn(\n 'flex items-start gap-2 w-full px-[var(--layout-space-loose)]',\n ROW_PADDING_BY_SIZE.md,\n )}\n >\n <ItemPrefix>\n {/* 2026-05-18 改 per user「做完」approval:14 → 16 對齊 uiSize.spec.md Icon Tier */}\n {locked ? (\n <Lock size={16} className=\"text-fg-muted\" aria-hidden />\n ) : draggable ? (\n <ItemInlineActionButton\n icon={GripVertical}\n size=\"md\"\n aria-label=\"拖曳重排\"\n className=\"cursor-grab active:cursor-grabbing\"\n {...attributes}\n {...listeners}\n />\n ) : null}\n </ItemPrefix>\n <ItemLabel className={locked ? 'text-fg-disabled' : undefined}>{label}</ItemLabel>\n <ItemInlineActionButton\n icon={visible ? Eye : EyeOff}\n size=\"md\"\n aria-label={visible ? '隱藏此欄' : '顯示此欄'}\n disabled={locked}\n onClick={onToggle}\n className={locked ? 'cursor-not-allowed text-fg-disabled' : ''}\n />\n </div>\n )\n}\n"],"names":["XIcon"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type SelectOption } from '../../components/Select/select';
2
+ import type { ColumnType } from './column-types';
3
+ import type { Conjunction, FilterCondition, FilterGroup } from './filter-tree';
4
+ export interface FilterColumn {
5
+ id: string;
6
+ label: string;
7
+ type: ColumnType;
8
+ options?: Array<{
9
+ value: string;
10
+ label: string;
11
+ }>;
12
+ /** People pool for person/multiPerson filter picker(對齊 cell-registry meta.people SSOT)*/
13
+ people?: Array<{
14
+ name: string;
15
+ avatarUrl?: string;
16
+ description?: string;
17
+ }>;
18
+ includeTime?: boolean;
19
+ }
20
+ export declare function getDefaultOperator(type?: ColumnType): string;
21
+ export declare const datePrecisionOf: (col: FilterColumn | undefined) => "day" | "ms" | undefined;
22
+ export declare function FilterRow({ index, condition, conjunction, filterableColumns, fieldOptions, onChangeConjunction, onChangeField, onChangeOp, onChangeValue, onRemove, }: {
23
+ index: number;
24
+ condition: FilterCondition;
25
+ conjunction: Conjunction;
26
+ filterableColumns: FilterColumn[];
27
+ fieldOptions: SelectOption[];
28
+ onChangeConjunction: (c: Conjunction) => void;
29
+ onChangeField: (v: string) => void;
30
+ onChangeOp: (v: string) => void;
31
+ onChangeValue: (v: unknown) => void;
32
+ onRemove: () => void;
33
+ }): import("react/jsx-runtime").JSX.Element;
34
+ export declare function GroupBlock({ index, group, rootConjunction, filterableColumns, fieldOptions, onChangeRootConjunction, onChangeGroupConjunction, onChangeCondition, onRemoveCondition, onAddCondition, onRemoveGroup, }: {
35
+ index: number;
36
+ group: FilterGroup;
37
+ rootConjunction: Conjunction;
38
+ filterableColumns: FilterColumn[];
39
+ fieldOptions: SelectOption[];
40
+ onChangeRootConjunction: (c: Conjunction) => void;
41
+ onChangeGroupConjunction: (c: Conjunction) => void;
42
+ onChangeCondition: (condId: string, patch: Partial<FilterCondition>) => void;
43
+ onRemoveCondition: (condId: string) => void;
44
+ onAddCondition: () => void;
45
+ onRemoveGroup: () => void;
46
+ }): import("react/jsx-runtime").JSX.Element;
47
+ //# sourceMappingURL=data-table-filter-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-filter-group.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/data-table-filter-group.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAEpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAQhD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAK9E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,yFAAyF;IACzF,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAE5D;AAID,eAAO,MAAM,eAAe,GAAI,KAAK,YAAY,GAAG,SAAS,KAAG,KAAK,GAAG,IAAI,GAAG,SACV,CAAA;AA0CrE,wBAAgB,SAAS,CAAC,EACxB,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAC9D,mBAAmB,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,GACxE,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,eAAe,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,iBAAiB,EAAE,YAAY,EAAE,CAAA;IACjC,YAAY,EAAE,YAAY,EAAE,CAAA;IAC5B,mBAAmB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IAC7C,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,2CAgEA;AAID,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAC9D,uBAAuB,EAAE,wBAAwB,EACjD,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,GACpE,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,WAAW,CAAA;IAClB,eAAe,EAAE,WAAW,CAAA;IAC5B,iBAAiB,EAAE,YAAY,EAAE,CAAA;IACjC,YAAY,EAAE,YAAY,EAAE,CAAA;IAC5B,uBAAuB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACjD,wBAAwB,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IAClD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IAC5E,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,IAAI,CAAA;CAC1B,2CAoCA"}
@@ -0,0 +1,154 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Trash2, Plus } from "lucide-react";
3
+ import { Button } from "../Button/button.js";
4
+ import { Select } from "../Select/select.js";
5
+ import { FieldControlGroup } from "../FieldControlGroup/field-control-group.js";
6
+ import { DEFAULT_OPERATOR, getOperatorSpec, getValueShape, OPERATOR_REGISTRY } from "./filter-operators.js";
7
+ import { FilterValuePicker } from "./data-table-filter-value-picker.js";
8
+ function getOperatorOptions(type) {
9
+ const registry = type && OPERATOR_REGISTRY[type] ? OPERATOR_REGISTRY[type] : OPERATOR_REGISTRY.string;
10
+ return registry.map((op) => ({ value: op.op, label: op.label }));
11
+ }
12
+ function getDefaultOperator(type) {
13
+ return type && DEFAULT_OPERATOR[type] || DEFAULT_OPERATOR.string;
14
+ }
15
+ const datePrecisionOf = (col) => (col == null ? void 0 : col.type) === "date" ? col.includeTime ? "ms" : "day" : void 0;
16
+ const CONJ_OPTIONS = [
17
+ { value: "and", label: "And" },
18
+ { value: "or", label: "Or" }
19
+ ];
20
+ function ConjunctionLabel({
21
+ index,
22
+ conjunction,
23
+ onChange
24
+ }) {
25
+ if (index === 0) {
26
+ return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center", children: "Where" });
27
+ }
28
+ if (index >= 2) {
29
+ const label = conjunction === "and" ? "And" : "Or";
30
+ return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center", children: label });
31
+ }
32
+ return /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsx(
33
+ Select,
34
+ {
35
+ size: "sm",
36
+ options: CONJ_OPTIONS,
37
+ value: conjunction,
38
+ onChange: (v) => onChange(v),
39
+ minRows: 2,
40
+ "aria-label": "連接詞 — 同 group 共用"
41
+ }
42
+ ) });
43
+ }
44
+ function FilterRow({
45
+ index,
46
+ condition,
47
+ conjunction,
48
+ filterableColumns,
49
+ fieldOptions,
50
+ onChangeConjunction,
51
+ onChangeField,
52
+ onChangeOp,
53
+ onChangeValue,
54
+ onRemove
55
+ }) {
56
+ const colInfo = filterableColumns.find((c) => c.id === condition.field);
57
+ const operatorOptions = getOperatorOptions(colInfo == null ? void 0 : colInfo.type);
58
+ const hasField = !!condition.field;
59
+ const opSpec = colInfo ? getOperatorSpec(colInfo.type, condition.op) : null;
60
+ const valueShape = colInfo && opSpec ? getValueShape(opSpec, colInfo.type, colInfo.includeTime) : null;
61
+ const hasValueCell = valueShape !== "none";
62
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
63
+ /* @__PURE__ */ jsx(ConjunctionLabel, { index, conjunction, onChange: onChangeConjunction }),
64
+ /* @__PURE__ */ jsxs(FieldControlGroup, { block: true, className: "flex-1 min-w-0", children: [
65
+ /* @__PURE__ */ jsx(
66
+ Select,
67
+ {
68
+ className: "!w-[var(--data-table-filter-field-width)] flex-shrink-0",
69
+ size: "sm",
70
+ options: fieldOptions,
71
+ value: condition.field,
72
+ onChange: onChangeField,
73
+ placeholder: "選擇欄位",
74
+ "aria-label": "篩選欄位"
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx(
78
+ Select,
79
+ {
80
+ className: hasValueCell ? "!w-[var(--data-table-filter-op-width)] flex-shrink-0" : "!flex-1 !min-w-0",
81
+ size: "sm",
82
+ options: operatorOptions,
83
+ value: condition.op,
84
+ onChange: onChangeOp,
85
+ disabled: !hasField,
86
+ placeholder: "運算子",
87
+ "aria-label": "篩選運算子"
88
+ }
89
+ ),
90
+ hasValueCell && /* @__PURE__ */ jsx(
91
+ FilterValuePicker,
92
+ {
93
+ shape: valueShape,
94
+ value: condition.value,
95
+ onChange: onChangeValue,
96
+ colInfo,
97
+ disabled: !hasField,
98
+ ariaLabel: colInfo ? `${colInfo.label} 篩選值` : "篩選值",
99
+ className: "!flex-1 !min-w-0"
100
+ }
101
+ )
102
+ ] }),
103
+ /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", iconOnly: true, startIcon: Trash2, "aria-label": "刪除", onClick: onRemove })
104
+ ] });
105
+ }
106
+ function GroupBlock({
107
+ index,
108
+ group,
109
+ rootConjunction,
110
+ filterableColumns,
111
+ fieldOptions,
112
+ onChangeRootConjunction,
113
+ onChangeGroupConjunction,
114
+ onChangeCondition,
115
+ onRemoveCondition,
116
+ onAddCondition,
117
+ onRemoveGroup
118
+ }) {
119
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
120
+ /* @__PURE__ */ jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsx(ConjunctionLabel, { index, conjunction: rootConjunction, onChange: onChangeRootConjunction }) }),
121
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 rounded-md bg-muted p-2 flex flex-col gap-2", children: [
122
+ group.children.map((cond, cIdx) => /* @__PURE__ */ jsx(
123
+ FilterRow,
124
+ {
125
+ index: cIdx,
126
+ condition: cond,
127
+ conjunction: group.conjunction,
128
+ filterableColumns,
129
+ fieldOptions,
130
+ onChangeConjunction: onChangeGroupConjunction,
131
+ onChangeField: (v) => {
132
+ const newCol = filterableColumns.find((c) => c.id === v);
133
+ onChangeCondition(cond.id, { field: v, op: getDefaultOperator(newCol == null ? void 0 : newCol.type), value: "", datePrecision: datePrecisionOf(newCol) });
134
+ },
135
+ onChangeOp: (v) => onChangeCondition(cond.id, { op: v, value: "" }),
136
+ onChangeValue: (v) => onChangeCondition(cond.id, { value: v }),
137
+ onRemove: () => onRemoveCondition(cond.id)
138
+ },
139
+ cond.id
140
+ )),
141
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
142
+ /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", startIcon: Plus, onClick: onAddCondition, children: "加入巢狀篩選" }),
143
+ group.children.length === 0 && /* @__PURE__ */ jsx(Button, { variant: "text", size: "sm", startIcon: Trash2, danger: true, onClick: onRemoveGroup, children: "移除空群組" })
144
+ ] })
145
+ ] })
146
+ ] });
147
+ }
148
+ export {
149
+ FilterRow,
150
+ GroupBlock,
151
+ datePrecisionOf,
152
+ getDefaultOperator
153
+ };
154
+ //# sourceMappingURL=data-table-filter-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-filter-group.js","sources":["../../../src/components/DataTable/data-table-filter-group.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(2026-07-14 自 data-table-filter-panel.tsx 拆檔搬移,原檔級 escape 隨段落帶入)。\n// @internal — DS-internal 單元(filter row / nested-group renderer + 共用 column/operator\n// helpers;GroupBlock 為 nested-group renderer,FilterRow / ConjunctionLabel 為其 row 構件、\n// flat mode 共用。只被 data-table-filter-panel.tsx 消費);不隨 index.ts re-export 進 npm public surface。\n// ────────────────────────────── 消費的 SSOT ──────────────────────────────\n// - FieldControlGroup:field + op + value border-collapse 接合(field-control-group.spec.md;\n// FilterValuePicker 為 direct child,className forward 不開 wrapper div — 2026-05-04 #2 fix)\n// - Button(variant=\"text\" iconOnly)row meta trash / Select(size=\"sm\")conjunction・field・op\n// (data-table.spec.md「四、UI canonical」:trash = form-control row text Button;A6 conjunction)\n// - Width tokens:--data-table-filter-field-width / --data-table-filter-op-width(uiSize.css SSOT,\n// 2026-05-23 Phase A.4 Decision 2)\n// - Operator SSOT:./filter-operators.ts OPERATOR_REGISTRY(禁 hardcode op 字串)\n// - Group container 灰底 bg-muted:color.spec.md L651-654 靜態低重要 surface semantic(2026-05-09 Q3 A)\n// 設計規則:./filter-operators.spec.md + ./data-table.spec.md「進階篩選」段\n\nimport { Plus, Trash2 } from 'lucide-react'\nimport { Button } from '@/design-system/components/Button/button'\nimport { Select, type SelectOption } from '@/design-system/components/Select/select'\nimport { FieldControlGroup } from '@/design-system/components/FieldControlGroup/field-control-group'\nimport type { ColumnType } from './column-types'\nimport {\n OPERATOR_REGISTRY,\n DEFAULT_OPERATOR,\n getOperatorSpec,\n getValueShape,\n type ValueShape,\n} from './filter-operators'\nimport type { Conjunction, FilterCondition, FilterGroup } from './filter-tree'\nimport { FilterValuePicker } from './data-table-filter-value-picker'\n\n// ── Shared internal types + operator helpers(panel orchestration 也消費)────\n\nexport interface FilterColumn {\n id: string\n label: string\n type: ColumnType\n options?: Array<{ value: string; label: string }>\n /** People pool for person/multiPerson filter picker(對齊 cell-registry meta.people SSOT)*/\n people?: Array<{ name: string; avatarUrl?: string; description?: string }>\n includeTime?: boolean\n}\n\nfunction getOperatorOptions(type?: ColumnType): SelectOption[] {\n const registry = type && OPERATOR_REGISTRY[type] ? OPERATOR_REGISTRY[type] : OPERATOR_REGISTRY.string\n return registry.map((op) => ({ value: op.op, label: op.label }))\n}\n\nexport function getDefaultOperator(type?: ColumnType): string {\n return (type && DEFAULT_OPERATOR[type]) || DEFAULT_OPERATOR.string\n}\n\n// Q6(2026-07-04):date 欄位把比對精度寫進 condition(includeTime=true → ms,否則 day)。\n// 'time' 欄暫不寫(值非完整日期,truncate 語意不成立;見 filter-operators.spec v3 time 註)。\nexport const datePrecisionOf = (col: FilterColumn | undefined): 'day' | 'ms' | undefined =>\n col?.type === 'date' ? (col.includeTime ? 'ms' : 'day') : undefined\n\n// ── ConjunctionLabel ───────────────────────────────────────────────────\n\nconst CONJ_OPTIONS: SelectOption[] = [\n { value: 'and', label: 'And' },\n { value: 'or', label: 'Or' },\n]\n\nfunction ConjunctionLabel({\n index, conjunction, onChange,\n}: { index: number; conjunction: Conjunction; onChange: (c: Conjunction) => void }) {\n // index === 0:首 row 顯示靜態「Where」label\n // index === 1:**唯一可改**的 AND/OR Select(連動整 group conjunction)\n // index ≥ 2:被連動的 row,read-only 顯示當前 conjunction 文字(同 Where 視覺,A6 canonical)\n // 對齊 Airtable / Notion / Linear 共識 @benchmark-unverified(non-OSS)\n // px-[var(--field-px)] 對齊 Field 內部 padding 12px(Q13)\n if (index === 0) {\n return <div className=\"w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center\">Where</div>\n }\n if (index >= 2) {\n const label = conjunction === 'and' ? 'And' : 'Or'\n return <div className=\"w-20 shrink-0 text-body text-fg-muted px-[var(--field-px)] self-center\">{label}</div>\n }\n // index === 1:可切換的 AND/OR Select\n // minRows={2} — And/Or 2 選項,顯式縮 menu 高度避免 reserve 3 row 空白(Q5)\n return (\n <div className=\"w-20 shrink-0\">\n <Select\n size=\"sm\"\n options={CONJ_OPTIONS}\n value={conjunction}\n onChange={(v) => onChange(v as Conjunction)}\n minRows={2}\n aria-label=\"連接詞 — 同 group 共用\"\n />\n </div>\n )\n}\n\n// ── FilterRow(flat 用 + group 內共用) ──────────────────────────────\n\nexport function FilterRow({\n index, condition, conjunction, filterableColumns, fieldOptions,\n onChangeConjunction, onChangeField, onChangeOp, onChangeValue, onRemove,\n}: {\n index: number\n condition: FilterCondition\n conjunction: Conjunction\n filterableColumns: FilterColumn[]\n fieldOptions: SelectOption[]\n onChangeConjunction: (c: Conjunction) => void\n onChangeField: (v: string) => void\n onChangeOp: (v: string) => void\n onChangeValue: (v: unknown) => void\n onRemove: () => void\n}) {\n const colInfo = filterableColumns.find((c) => c.id === condition.field)\n const operatorOptions = getOperatorOptions(colInfo?.type)\n const hasField = !!condition.field\n const opSpec = colInfo ? getOperatorSpec(colInfo.type, condition.op) : null\n const valueShape: ValueShape | null = colInfo && opSpec\n ? getValueShape(opSpec, colInfo.type, colInfo.includeTime)\n : null\n // op 'is_set' / 'is_not_set' 等 shape='none' → 無 value cell,op 自動 expand 填剩餘寬\n // 對齊 Notion / Airtable / Linear filter row 行為\n // 注意:valueShape=null(初始無 field 選)時仍 render value cell(disabled placeholder)— 只 'none' 才 fold\n const hasValueCell = valueShape !== 'none'\n\n // FieldControlGroup 接合 field + op + value 視覺(2026-05-04 E refactor + 多輪 fix):\n // - border collapse 取代 3 顆獨立 Select 並排,對齊 Airtable / Linear / Notion filter row idiom\n // - ConjunctionLabel + Trash 在 group 外層(meta actions,不屬 control 一體)\n // - **#5 fix**:row 內水平 gap = `gap-2` (8px),layoutSpace 規則 5 緊密相關\n // - **#9 fix**:cell 用 `min-w-[]`(field 160 / op 120),value flex-1 min-w-0,讓 long label 可撐寬\n // - **#2 fix**:FilterValuePicker 直接是 FieldControlGroup direct child(無 wrapper div),CSS variants 命中正確\n return (\n <div className=\"flex items-center gap-2\">\n <ConjunctionLabel index={index} conjunction={conjunction} onChange={onChangeConjunction} />\n {/* **#9 fix(2026-05-04 v4)**:Field controls trigger `w-full` override 外 className,改用 Tailwind `!`\n important 強制 override(`!w-[160px]` / `!w-[120px]`),value 用 `!flex-1 !min-w-0`。\n Select 元件本身沒 destructure `style` prop 所以 inline style flex-basis 行不通,只能用 className。 */}\n <FieldControlGroup block className=\"flex-1 min-w-0\">\n {/* 2026-05-23 Phase A.4 Decision 2:`!w-[160px]` / `!w-[120px]` → tokens\n `--data-table-filter-field-width` / `--data-table-filter-op-width`(SSOT in uiSize.css)\n Behavior preserved 完好如初:flat + nested 同 width(token 是 design constant) */}\n <Select\n className=\"!w-[var(--data-table-filter-field-width)] flex-shrink-0\"\n size=\"sm\"\n options={fieldOptions}\n value={condition.field}\n onChange={onChangeField}\n placeholder=\"選擇欄位\"\n aria-label=\"篩選欄位\"\n />\n <Select\n className={hasValueCell ? '!w-[var(--data-table-filter-op-width)] flex-shrink-0' : '!flex-1 !min-w-0'}\n size=\"sm\"\n options={operatorOptions}\n value={condition.op}\n onChange={onChangeOp}\n disabled={!hasField}\n placeholder=\"運算子\"\n aria-label=\"篩選運算子\"\n />\n {hasValueCell && (\n <FilterValuePicker\n shape={valueShape}\n value={condition.value}\n onChange={onChangeValue}\n colInfo={colInfo}\n disabled={!hasField}\n ariaLabel={colInfo ? `${colInfo.label} 篩選值` : '篩選值'}\n className=\"!flex-1 !min-w-0\"\n />\n )}\n </FieldControlGroup>\n {/* Trash 用 text Button — filter row 是 form-control row,Field 同高對齊(28 md) */}\n <Button variant=\"text\" size=\"sm\" iconOnly startIcon={Trash2} aria-label=\"刪除\" onClick={onRemove} />\n </div>\n )\n}\n\n// ── GroupBlock(nested 用) ────────────────────────────────────────────\n\nexport function GroupBlock({\n index, group, rootConjunction, filterableColumns, fieldOptions,\n onChangeRootConjunction, onChangeGroupConjunction,\n onChangeCondition, onRemoveCondition, onAddCondition, onRemoveGroup,\n}: {\n index: number\n group: FilterGroup\n rootConjunction: Conjunction\n filterableColumns: FilterColumn[]\n fieldOptions: SelectOption[]\n onChangeRootConjunction: (c: Conjunction) => void\n onChangeGroupConjunction: (c: Conjunction) => void\n onChangeCondition: (condId: string, patch: Partial<FilterCondition>) => void\n onRemoveCondition: (condId: string) => void\n onAddCondition: () => void\n onRemoveGroup: () => void\n}) {\n return (\n <div className=\"flex items-start gap-2\">\n <div className=\"pt-2\">\n <ConjunctionLabel index={index} conjunction={rootConjunction} onChange={onChangeRootConjunction} />\n </div>\n {/* Group container 灰底 — `bg-muted`(`--muted` neutral-2,user 2026-05-09 拍板 Q3 A)。對齊 color.spec.md L651-654 「table header / tab / code block / skeleton」靜態低重要 surface semantic */}\n <div className=\"flex-1 min-w-0 rounded-md bg-muted p-2 flex flex-col gap-2\">\n {group.children.map((cond, cIdx) => (\n <FilterRow\n key={cond.id}\n index={cIdx}\n condition={cond}\n conjunction={group.conjunction}\n filterableColumns={filterableColumns}\n fieldOptions={fieldOptions}\n onChangeConjunction={onChangeGroupConjunction}\n onChangeField={(v) => {\n const newCol = filterableColumns.find((c) => c.id === v)\n onChangeCondition(cond.id, { field: v, op: getDefaultOperator(newCol?.type), value: '', datePrecision: datePrecisionOf(newCol) })\n }}\n onChangeOp={(v) => onChangeCondition(cond.id, { op: v, value: '' })}\n onChangeValue={(v) => onChangeCondition(cond.id, { value: v })}\n onRemove={() => onRemoveCondition(cond.id)}\n />\n ))}\n {/* Q9 — text variant 對齊 inline 派 + 視覺輕量 */}\n <div className=\"flex items-center justify-between\">\n <Button variant=\"text\" size=\"sm\" startIcon={Plus} onClick={onAddCondition}>加入巢狀篩選</Button>\n {group.children.length === 0 && (\n <Button variant=\"text\" size=\"sm\" startIcon={Trash2} danger onClick={onRemoveGroup}>移除空群組</Button>\n )}\n </div>\n </div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;AA0CA,SAAS,mBAAmB,MAAmC;AAC7D,QAAM,WAAW,QAAQ,kBAAkB,IAAI,IAAI,kBAAkB,IAAI,IAAI,kBAAkB;AAC/F,SAAO,SAAS,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,OAAO,GAAG,MAAA,EAAQ;AACjE;AAEO,SAAS,mBAAmB,MAA2B;AAC5D,SAAQ,QAAQ,iBAAiB,IAAI,KAAM,iBAAiB;AAC9D;AAIO,MAAM,kBAAkB,CAAC,SAC9B,2BAAK,UAAS,SAAU,IAAI,cAAc,OAAO,QAAS;AAI5D,MAAM,eAA+B;AAAA,EACnC,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,EACvB,EAAE,OAAO,MAAM,OAAO,KAAA;AACxB;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EAAO;AAAA,EAAa;AACtB,GAAoF;AAMlF,MAAI,UAAU,GAAG;AACf,WAAO,oBAAC,OAAA,EAAI,WAAU,0EAAyE,UAAA,SAAK;AAAA,EACtG;AACA,MAAI,SAAS,GAAG;AACd,UAAM,QAAQ,gBAAgB,QAAQ,QAAQ;AAC9C,WAAO,oBAAC,OAAA,EAAI,WAAU,0EAA0E,UAAA,OAAM;AAAA,EACxG;AAGA,SACE,oBAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU,CAAC,MAAM,SAAS,CAAgB;AAAA,MAC1C,SAAS;AAAA,MACT,cAAW;AAAA,IAAA;AAAA,EAAA,GAEf;AAEJ;AAIO,SAAS,UAAU;AAAA,EACxB;AAAA,EAAO;AAAA,EAAW;AAAA,EAAa;AAAA,EAAmB;AAAA,EAClD;AAAA,EAAqB;AAAA,EAAe;AAAA,EAAY;AAAA,EAAe;AACjE,GAWG;AACD,QAAM,UAAU,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,KAAK;AACtE,QAAM,kBAAkB,mBAAmB,mCAAS,IAAI;AACxD,QAAM,WAAW,CAAC,CAAC,UAAU;AAC7B,QAAM,SAAS,UAAU,gBAAgB,QAAQ,MAAM,UAAU,EAAE,IAAI;AACvE,QAAM,aAAgC,WAAW,SAC7C,cAAc,QAAQ,QAAQ,MAAM,QAAQ,WAAW,IACvD;AAIJ,QAAM,eAAe,eAAe;AAQpC,SACE,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,IAAA,oBAAC,kBAAA,EAAiB,OAAc,aAA0B,UAAU,qBAAqB;AAAA,IAIzF,qBAAC,mBAAA,EAAkB,OAAK,MAAC,WAAU,kBAIjC,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV,aAAY;AAAA,UACZ,cAAW;AAAA,QAAA;AAAA,MAAA;AAAA,MAEb;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,eAAe,yDAAyD;AAAA,UACnF,MAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV,UAAU,CAAC;AAAA,UACX,aAAY;AAAA,UACZ,cAAW;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBACC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,UACV;AAAA,UACA,UAAU,CAAC;AAAA,UACX,WAAW,UAAU,GAAG,QAAQ,KAAK,SAAS;AAAA,UAC9C,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACZ,GAEJ;AAAA,IAEA,oBAAC,QAAA,EAAO,SAAQ,QAAO,MAAK,MAAK,UAAQ,MAAC,WAAW,QAAQ,cAAW,MAAK,SAAS,SAAA,CAAU;AAAA,EAAA,GAClG;AAEJ;AAIO,SAAS,WAAW;AAAA,EACzB;AAAA,EAAO;AAAA,EAAO;AAAA,EAAiB;AAAA,EAAmB;AAAA,EAClD;AAAA,EAAyB;AAAA,EACzB;AAAA,EAAmB;AAAA,EAAmB;AAAA,EAAgB;AACxD,GAYG;AACD,SACE,qBAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,QACb,UAAA,oBAAC,kBAAA,EAAiB,OAAc,aAAa,iBAAiB,UAAU,wBAAA,CAAyB,EAAA,CACnG;AAAA,IAEA,qBAAC,OAAA,EAAI,WAAU,8DACZ,UAAA;AAAA,MAAA,MAAM,SAAS,IAAI,CAAC,MAAM,SACzB;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,OAAO;AAAA,UACP,WAAW;AAAA,UACX,aAAa,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA,qBAAqB;AAAA,UACrB,eAAe,CAAC,MAAM;AACpB,kBAAM,SAAS,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;AACvD,8BAAkB,KAAK,IAAI,EAAE,OAAO,GAAG,IAAI,mBAAmB,iCAAQ,IAAI,GAAG,OAAO,IAAI,eAAe,gBAAgB,MAAM,GAAG;AAAA,UAClI;AAAA,UACA,YAAY,CAAC,MAAM,kBAAkB,KAAK,IAAI,EAAE,IAAI,GAAG,OAAO,IAAI;AAAA,UAClE,eAAe,CAAC,MAAM,kBAAkB,KAAK,IAAI,EAAE,OAAO,GAAG;AAAA,UAC7D,UAAU,MAAM,kBAAkB,KAAK,EAAE;AAAA,QAAA;AAAA,QAbpC,KAAK;AAAA,MAAA,CAeb;AAAA,MAED,qBAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAO,SAAQ,QAAO,MAAK,MAAK,WAAW,MAAM,SAAS,gBAAgB,UAAA,SAAA,CAAM;AAAA,QAChF,MAAM,SAAS,WAAW,KACzB,oBAAC,UAAO,SAAQ,QAAO,MAAK,MAAK,WAAW,QAAQ,QAAM,MAAC,SAAS,eAAe,UAAA,QAAA,CAAK;AAAA,MAAA,EAAA,CAE5F;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
@@ -4,8 +4,6 @@ import { createEmptyFilterTree, isFilterTreeActive, evaluateTree, dataTableFilte
4
4
  export { createEmptyFilterTree, isFilterTreeActive, evaluateTree, dataTableFilterMatch, };
5
5
  export type { Conjunction, FilterCondition, FilterGroup, FilterTree, FilterTreeFlat, FilterTreeNested };
6
6
  export interface DataTableFilterPanelProps<TData> {
7
- /** flat(無 group)or nested(1-level group)— consumer 拍板 */
8
- mode: 'flat' | 'nested';
9
7
  /** 可被 filter 的 columns */
10
8
  columns: ColumnDef<TData, any>[];
11
9
  /** 當前 FilterTree(controlled) */
@@ -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;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;AA8PD,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":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAgBtD,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;AAsFvG,MAAM,WAAW,yBAAyB,CAAC,KAAK;IAI9C,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;AA6PD,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"}