@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":"select.js","sources":["../../../src/components/Select/select.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 — Select 含 3 子元件(NativeSelect/CustomSelect/ReadonlyDisplay)+ helpers + 4-mode renderer + Field SSOT consumption,split-into-files 會破壞 file-local helper closure\n// @renderer-symmetry-allow: pre-existing Select architecture(2026-05-08 D-path)— selectedItemRenderer 由 CustomSelectTriggerContent 消費(edit + trigger 模式),ReadonlyDisplay 走 separate bare-span path(no D-path)。display→edit unify deferred 下 cycle per spec contract (a) note。本 turn 只加 `nakedCellRowModeAlign` import,no behavior change to renderer symmetry contract。\nimport * as React from 'react'\nimport { X, ChevronDown } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant } from '@/design-system/components/Field/field-types'\nimport { fieldWrapperStyles, bareInputStyles, EMPTY_DISPLAY, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'\nimport { Tag } from '@/design-system/components/Tag/tag'\nimport { ItemInlineAction, ItemPrefix, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid } from '@/design-system/components/Field/field-context'\nimport { SelectMenu, type SelectMenuOption } from '@/design-system/components/SelectMenu/select-menu'\nimport { useIsTouchDevice } from '@/design-system/hooks/use-is-touch-device'\nimport { useControllable } from '@/design-system/hooks/use-controllable'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n// ── Tag padding per size ────────────────────────────────────────────────────\nconst tagPadding: Record<string, string> = {\n sm: 'px-[calc((var(--field-height-sm)_-_1.25rem)_/_2)]',\n md: 'px-[calc((var(--field-height-md)_-_1.5rem)_/_2)]',\n lg: 'px-[calc((var(--field-height-lg)_-_1.5rem)_/_2)]',\n}\n\n// ── Display ─────────────────────────────────────────────────────────────────\n\n/**\n * Select 用的 option schema(2026-05-10 Issue 4 + post-prune unify):**explicit extends\n * SelectMenuOption(primitive SSOT)** — 任何 SelectMenuOption 加 field 都自動繼承,不會 drift。\n *\n * Why `extends SelectMenuOption`(per user 「全盤檢查避免下次又改壞或是偏移」要求):\n * - **schema SSOT 機械強制**:TypeScript inheritance 跟著 primitive 走,wrapper consumer 永遠\n * 拿得到 primitive 所有 surface field\n * - **Hook lint**(M30 `check_wrapper_primitive_schema_drift.sh`):grep `interface .*Option`\n * 未 `extends` SelectMenuOption / 同名重複 declare 直接 BLOCK\n *\n * Wrapper-only field(`tagVariant`)— Select 獨有 `display='tag'` 用,SelectMenu primitive 不該知道\n * 此 wrapper-only concern,所以 wrapper 層 extend 加上,不污染 primitive。\n *\n * 對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown 的 wrapper-vs-primitive\n * schema-extension idiom。\n */\nexport interface SelectOption extends SelectMenuOption {\n /** Tag 模式的顏色。只在 display='tag' 時生效,對應 Tag 的 variant。Wrapper-only。 */\n tagVariant?: string\n}\n\n/** 分組設定 — 對齊 SelectMenuGroupConfig SSOT */\nexport interface SelectGroupConfig {\n key: string\n label: string\n}\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface SelectProps\n extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size' | 'value' | 'defaultValue' | 'onChange'> {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n options: SelectOption[]\n /** 分組顯示(對齊 SelectMenu groups SSOT)。option.group 對應 groups[].key */\n groups?: SelectGroupConfig[]\n /** Controlled value(consumer 自管 state)。傳 `value` + `onChange` 表示 controlled mode。 */\n value?: string | null\n /** Uncontrolled 初始值(2026-05-21 D3 audit add per user verbatim「決策三照妳建議」+「都給我做到好」)。\n * 不傳 `value` 時 Select 自管 internal state,以 `defaultValue` 為初始值,選變更時 fire `onChange`\n * callback 通知 consumer(但 state 仍歸 Select)。對齊 Radix Select(`defaultValue`)+ shadcn Input\n * (`defaultValue`)+ React `<input>` dual-mode canonical。\n * 互斥規則:同時傳 `value` + `defaultValue` 走 controlled(value 勝),`defaultValue` 僅 first-mount 用。 */\n defaultValue?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n clearable?: boolean\n display?: 'plain' | 'tag'\n startIcon?: LucideIcon\n /** 啟用搜尋(desktop 時 field 變 input,打字即篩選) */\n searchable?: boolean\n /** Loading state(2026-05-15 audit B fix per user verbatim「dropdown 隨時可開,讀取在 panel 中間 CircularProgress」)。\n * Forward 給 SelectMenu primitive SSOT;dropdown 開啟時取代 options 顯 CircularProgress + loadingText。\n * Trigger 不變(chevron 保留 user 隨時可點開)。對齊 Field family loading SSOT + Empty 元件 `<Empty icon={CircularProgress}/>` compose。*/\n loading?: boolean\n\n /** Menu list 最小列數(空狀態 / 選項少時的視覺一致 reserve)。預設 3 — 選項 < 3 時顯式縮(如 And/Or 兩選項) */\n minRows?: number\n /** Initial open state(uncontrolled)。對齊 Radix Popover defaultOpen canonical;DataTable cell-as-input\n * click → 1 step open menu(Airtable / Notion canonical),consumer pass `defaultOpen` 達成。\n * Note:Native Select(mobile)無 popover 概念,此 prop 僅 Custom path 生效。 */\n defaultOpen?: boolean\n /** open state 變更 callback(對齊 Radix Popover onOpenChange canonical)。\n * DataTable cell-as-input 用:open=false 時 cell 自動 exit edit mode(避免 dismiss 後卡住)。 */\n onOpenChange?: (open: boolean) => void\n /**\n * Display mode 顯 picker intrinsic end icon(2026-05-08 D path Phase 1)。\n * 預設 false:`mode=\"display\"` 純展示 bare span(向後相容)。\n * `variant=\"naked\" && mode=\"display\"` 場景(DataTable cell)opt-in 設 true → wrap 進\n * Field naked-display + 渲 ChevronDown ItemSuffix。**只 display mode 生效**;readonly /\n * disabled / edit 已有 Field wrapper + suffix(不受此 prop 影響)。\n * Authority:`data-table.spec.md:204` + `inline-action.spec.md:157`「Field family endAction(自動繼承)」。\n * @default false\n */\n showDisplayEndIcon?: boolean\n /**\n * Trigger 內「已選項目」客製 render(2026-05-07 v15.5)。\n *\n * 設了 → trigger 不走純文字 / Tag 預設 path,改用 consumer 提供的 ReactNode(收 selectedOpt)。\n * Searchable+open 仍走 input(搜尋優先)。Empty value(no selection)仍走 placeholder。\n *\n * 用例:PeoplePicker 用此 slot 把 single 選中的 person render 成 PersonDisplay\n * (avatar + name)而非純文字 label。對齊 PeoplePicker = Select wrapper SSOT。\n */\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}\n\n// ── Icon / size helpers ─────────────────────────────────────────────────────\n// 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反)\nconst getIconSize = (size: string) => ICON_SIZE[size as 'sm' | 'md' | 'lg']\n\n// ── Shared sub-components ───────────────────────────────────────────────────\n\n/**\n * Inline clear button for Select trigger.\n * 共用 SSOT — Native + Custom 兩變體統一消費。差別僅 onClick 內是否 stopPropagation\n * (Custom trigger 是 combobox `<div>`,點 clear 不可冒泡到打開 menu;Native `<select>` 自有原生\n * 行為,不需 stopPropagation)。\n *\n * 消費的 SSOT:\n * - patterns/element-anatomy/item-anatomy.spec.md → ItemInlineAction(canonical row inline action)\n */\nfunction SelectClearButton({\n size,\n onClear,\n stopPropagation = false,\n}: {\n size: 'sm' | 'md' | 'lg'\n onClear: () => void\n stopPropagation?: boolean\n}) {\n return (\n <span className=\"relative z-10\">\n <ItemInlineAction\n size={size}\n action={{\n icon: X,\n label: '清除選取', // i18n-allow: DS default inline-action label\n onClick: stopPropagation ? (e) => { e?.stopPropagation(); onClear() } : () => onClear(),\n }}\n />\n </span>\n )\n}\nSelectClearButton.displayName = 'SelectClearButton'\n\n/**\n * Trigger content for CustomSelect — 三種顯示模式分支(searchable+open / text / tag)\n * 抽出降低 `CustomSelect` forwardRef body 長度;邏輯本質是純展示分流,無 hook / ref。\n */\nfunction CustomSelectTriggerContent({\n searchable,\n open,\n isTextDisplay,\n size,\n value,\n selectedLabel,\n selectedOpt,\n SelectedIcon,\n StartIcon,\n iconSize,\n placeholder,\n search,\n setSearch,\n inputRef,\n selectedItemRenderer,\n}: {\n searchable: boolean\n open: boolean\n isTextDisplay: boolean\n size: 'sm' | 'md' | 'lg'\n value?: string | null\n selectedLabel: string\n selectedOpt?: SelectOption\n SelectedIcon?: LucideIcon\n StartIcon?: LucideIcon\n iconSize: number\n placeholder?: string\n search: string\n setSearch: (v: string) => void\n inputRef: React.RefObject<HTMLInputElement | null>\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}): React.ReactNode {\n // Searchable + open: 顯示搜尋 input\n // 2026-05-15 Bug 2 fix(Claude+Codex Step 5 比稿 consensus,user verbatim「就 A」):\n // 撤掉 native `<input placeholder=selectedLabel>` 不可靠 ellipsis renderer(browser-specific\n // placeholder painting,user 抓「placeholder 直接被截掉沒 ellipsis」)。改 span overlay:\n // - input native placeholder 限「搜尋…」/「請選擇人員」trigger empty hint(無 selectedLabel)\n // - sibling `<span aria-hidden pointer-events-none absolute inset-0 truncate>` 在 search='' 且\n // 有 selectedLabel 時 overlay 顯該人名(memory aid,truncate-with-ellipsis 可控)\n // 對齊 spec.md §B row 4「open + inline-search + 選 1 人 → input cursor + placeholder = 該人名 + ellipsis」。\n // a11y guard(per codex Q2 reply):input aria-label / accessible name 來自 field/label/aria-label,\n // **不**依賴 placeholder 當 label;overlay span aria-hidden + pointer-events-none。\n if (searchable && open) {\n const triggerEmptyPlaceholder = placeholder || '搜尋…' // i18n-allow: DS fallback\n const showSelectedOverlay = !search && selectedLabel\n return (\n <span className=\"relative flex-1 min-w-0 inline-flex items-center\">\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n // Native placeholder 限 trigger empty hint(無 selectedLabel 時);若已 selected,留空交給 overlay span\n placeholder={showSelectedOverlay ? '' : triggerEmptyPlaceholder}\n className={cn(bareInputStyles, 'cursor-text')}\n autoFocus\n />\n {showSelectedOverlay && (\n // 2026-05-16 Bug B 真 root cause fix(Claude+Codex M31 Step 5 比稿 consensus,user verbatim\n // 「修了一百次還沒好」+ codex cite W3C CSS Overflow / MDN / Mozilla Bug 972664#c1):\n // 原 `inline-flex items-center truncate` 套同一 span,text 變 anonymous flex item →\n // `text-overflow:ellipsis` 對 anonymous item 不 styleable → ellipsis dots 不可見(text 純 clip)。\n // 對齊 `person-display.tsx:148` 既有 DS canonical:outer flex container + inner truncate 真實 box。\n // DS-wide grep 29 個 truncate 都遵此 pattern,只本處違反 — 修齊。\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 flex items-center text-fg-muted\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{selectedLabel}</span>\n </span>\n )}\n </span>\n )\n }\n // **selectedItemRenderer slot**(2026-05-07 v15.5):consumer 客製 selected display(e.g.\n // PeoplePicker 接 PersonDisplay)。優先於 isTextDisplay / Tag 預設 path,但 empty value\n // 仍走 placeholder。對齊 PeoplePicker = Select wrapper SSOT。\n if (selectedItemRenderer && value && selectedOpt) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {/* 2026-05-14 item-anatomy SSOT fix(per codex H2 propagation 斷點):加 nakedCellRowModeAlign\n → autoRowHeight cell 內 selected renderer 也對齊 first-line,不再 vertical-center 整 row。 */}\n <span className={cn(\"flex-1 min-w-0 inline-flex items-center\", nakedCellRowModeAlign)}>{selectedItemRenderer(selectedOpt)}</span>\n </>\n )\n }\n // Text display: 純文字 + optional value icon\n if (isTextDisplay) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedIcon && value && <ItemPrefix><SelectedIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', !value && 'text-fg-muted')}>\n {value ? selectedLabel : (placeholder ?? '選擇…')}\n </span>\n </>\n )\n }\n // Tag display: 用 option 的 tagVariant\n return (\n <>\n {value && selectedOpt?.tagVariant\n ? <Tag size={size} color={selectedOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : value\n ? <Tag size={size} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : <span className=\"text-fg-muted\">{placeholder ?? '選擇…'}</span>\n }\n <span className=\"flex-1\" />\n </>\n )\n}\nCustomSelectTriggerContent.displayName = 'CustomSelectTriggerContent'\n\n// ── Shared readonly/disabled/display render ─────────────────────────────────\nfunction ReadonlyDisplay({\n mode, variant: variantProp, size, options, value, display, startIcon: StartIcon, className, placeholder, showDisplayEndIcon,\n}: Pick<SelectProps, 'mode' | 'variant' | 'size' | 'options' | 'value' | 'display' | 'startIcon' | 'className' | 'placeholder' | 'showDisplayEndIcon'>) {\n const resolvedMode = mode ?? 'readonly'\n const variant = variantProp ?? 'default'\n const sz = size ?? 'md'\n const iconSize = getIconSize(sz)\n const label = options?.find(o => o.value === value)?.label ?? value\n const iconColor = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const isTextDisplay = display !== 'tag'\n // K10+K14 fix(2026-05-04):disabled mode placeholder/empty 顯示色 → fg-disabled(neutral-6),非 fg-muted(neutral-7)\n // user canonical:disabled 顯著性優於 muted。同時 plain mode 必須 respect placeholder prop(之前忽略 = bug)\n const emptyColorCls = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const emptyText = placeholder ?? EMPTY_DISPLAY\n\n // mode='display':2 path(2026-05-08 D path Phase 1 Select canary)\n // ❌ 預設(無 showDisplayEndIcon):純內容輸出 bare span/Tag(原行為,backward compat)\n // 對齊原 SelectDisplay sub-component(retired)。readonly / disabled 仍走下方 fieldWrapperStyles。\n // ✅ showDisplayEndIcon=true(DataTable cell opt-in):Field naked-display wrapper +\n // ChevronDown ItemSuffix。SSOT canonical 跟 readonly/edit/disabled mode 同 DOM 結構。\n // Authority: data-table.spec.md:204 + inline-action.spec.md:157「Field family endAction」\n if (resolvedMode === 'display') {\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 必套\n // `fieldDisplayTextClass(sz)`(sm/md→text-body,lg→text-body-lg)— 對齊跨 Field\n // family display 視覺尺寸統一。\n if (!value) return <span className={cn(fieldDisplayTextClass(sz), 'text-fg-muted', className)}>{emptyText}</span>\n if (isTextDisplay) return <span className={cn(fieldDisplayTextClass(sz), 'truncate', className)}>{label}</span>\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return <Tag size={sz} color={tVariant} className={className}>{label}</Tag>\n }\n // D path opt-in: Field naked-display wrapper + ItemSuffix ChevronDown\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: 'display', variant, size: sz }), value && !isTextDisplay && tagPadding[sz], className)}\n data-field-mode=\"display\"\n >\n {isTextDisplay ? (\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && emptyColorCls)}>\n {value ? label : emptyText}\n </span>\n ) : value ? (\n <Tag size={sz} color={tVariant}>{label}</Tag>\n ) : (\n <span className={cn('flex-1 min-w-0', emptyColorCls)}>{emptyText}</span>\n )}\n <ItemSuffix><ChevronDown size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemSuffix>\n </div>\n )\n }\n\n // 2026-06-26 類型身份 indicator 規則:edit 顯示 / readonly 不顯示(純值、不可開下拉,箭頭會誤導) /\n // disabled 保留(fg-disabled,對齊原生 <select disabled> 灰示箭頭 + Accordion M24 precedent)。\n // naked cell 情境依 showDisplayEndIcon = isEditable,維持 2026-05-10 cell canonical「非可編欄不顯」。\n // aria-disabled:styled-disabled(非 native disabled 元素)需明告 AT「inactive」,同時讓 axe 正確\n // 豁免 disabled 文字的 color-contrast(WCAG 1.4.3 inactive UI 例外)。\n const showIndicator = variant === 'naked' ? !!showDisplayEndIcon : resolvedMode === 'disabled'\n const ariaDisabled = resolvedMode === 'disabled' ? true : undefined\n\n if (isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className)} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className={cn('pointer-events-none', iconColor)} aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', resolvedMode === 'disabled' && 'text-fg-disabled')}>\n {value ? label : <span className={emptyColorCls}>{emptyText}</span>}\n </span>\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n }\n\n const selectedOpt = options?.find(o => o.value === value)\n const tagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), value && tagPadding[sz], className)} style={{ paddingRight: 'var(--field-px)' }} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {value ? <Tag size={sz} color={tagVariant}>{label}</Tag> : <span className={emptyColorCls}>{emptyText}</span>}\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n}\n\n// ── Native Select (mobile) ─────────────────────────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst NativeSelect = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, ...props }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(同 CustomSelect)\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const handleNativeChange = (v: string) => setValue(v)\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n const selectRef = React.useRef<HTMLSelectElement | null>(null)\n const setSelectRef = React.useCallback((el: HTMLSelectElement | null) => {\n selectRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLSelectElement | null>).current = el\n }, [ref])\n\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n const selectEl = (\n <select\n ref={setSelectRef}\n id={idProp ?? fieldCtx?.id}\n value={value ?? ''}\n onChange={(e) => handleNativeChange(e.target.value)}\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n className={cn(bareInputStyles, 'cursor-pointer appearance-none', !value && 'text-fg-muted', !isTextDisplay && value && 'absolute inset-0 w-full h-full opacity-0 z-0')}\n {...props}\n >\n {placeholder && <option value=\"\" disabled>{placeholder}</option>}\n {options.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}\n </select>\n )\n\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => handleNativeChange('')} />\n ) : null\n\n const chevronEl = (\n <ItemSuffix className=\"relative z-10 pointer-events-none\">\n <ChevronDown size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )\n const selectedOpt = options?.find(o => o.value === value)\n const label = selectedOpt?.label ?? value\n const nativeTagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n const SelectedOptIcon = selectedOpt?.icon\n\n if (!isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }), value && tagPadding[size], 'relative',\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n style={{ paddingRight: 'var(--field-px)' }} data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {value ? <Tag size={size} color={nativeTagVariant} className=\"shrink-0 relative z-10 pointer-events-none\">{label}</Tag> : <span className=\"text-fg-muted\">{placeholder ?? '選擇...'}</span>}\n {selectEl}\n <span className=\"flex-1\" />\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'], className)}\n data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedOptIcon && value && <ItemPrefix><SelectedOptIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n {selectEl}\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n)\nNativeSelect.displayName = 'NativeSelect'\n\n// ── Custom Select (desktop — consumes SelectMenu) ────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst CustomSelect = React.forwardRef<HTMLDivElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, groups, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, searchable = false, loading, minRows, defaultOpen = false, onOpenChange, selectedItemRenderer, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, 'aria-label': ariaLabel }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(M17 對齊,取代自刻 isControlled pattern)。\n // Phase B codex 抓:之前 Custom clear 走 `onChange?.('')` 沒 setInternalValue → uncontrolled clear 失效。useControllable 統一 setter 修。\n // onChange forward coerce null → ''(consumer 簽名 `(value: string) => void`,null 是 internal empty signal)。\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n\n const [open, setOpen] = React.useState(defaultOpen)\n const [search, setSearch] = React.useState('')\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n // 關閉時清搜尋\n React.useEffect(() => { if (!open) setSearch('') }, [open])\n\n // **React #310 fix(2026-05-04)**:所有 hooks 必在任何 early return 前 call,\n // 否則 disabled→edit 切換時 hook count 變動 → React 死亡。\n // 原本 useMemo(L280, L291) 在 early return 之後 = latent bug,K13 觸發(filter Op 從 disabled\n // 變 edit 當 user 選欄位)。修法:把所有 useMemo 提到 early return 之前。\n const selectedOpt = options?.find(o => o.value === value)\n // 2026-05-06 v9.1:value 不在 options 也要顯示原值(不沉默丟失)。原 fallback `''` 致\n // SelectCell 開 edit 時若 cell value 不在當前 options(e.g. 上游資料漂移 / options async\n // 後到 / 跨 dataset),trigger 顯示空白 — user 報「value 不見」。對齊 ReadonlyDisplay 同\n // 級 fallback `?? value`。\n const selectedLabel = selectedOpt?.label ?? value ?? ''\n const SelectedIcon = selectedOpt?.icon\n // ── 過濾選項 ──\n const filteredOptions = searchable && search\n ? options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : options\n // ── 轉換 SelectOption → SelectMenuOption(必在 early return 前) ──\n // Issue 4(2026-05-10):forward avatar / description / disabled SSOT(per SelectMenuOption schema)。\n const menuOptions: SelectMenuOption[] = React.useMemo(\n () => filteredOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n icon: isTextDisplay ? opt.icon : undefined,\n avatar: opt.avatar,\n description: opt.description,\n disabled: opt.disabled,\n group: opt.group,\n })),\n [filteredOptions, isTextDisplay]\n )\n // ── Tag display 自訂 label 渲染(必在 early return 前) ──\n const renderLabel = React.useMemo(() => {\n if (isTextDisplay) return undefined\n return (menuOpt: SelectMenuOption) => {\n const srcOpt = options.find(o => o.value === menuOpt.value)\n if (srcOpt?.tagVariant) {\n return <Tag size={size} color={srcOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'}>{menuOpt.label}</Tag>\n }\n return menuOpt.label\n }\n }, [isTextDisplay, options, size])\n\n // **React #310 fix v2(2026-05-04)**:`handleValueChange` useCallback 也必在 early return 前\n // 原本 L306(early return 後)→ disabled→edit 切換時 hook count 仍變 → #310 持續\n // 2026-05-21 D3:`useControllable` 統一 controlled / uncontrolled state + onChange forward,不再手動 if-branch。\n const handleValueChange = React.useCallback(\n (newValue: string | string[]) => {\n setValue(Array.isArray(newValue) ? newValue[0] : newValue)\n },\n [setValue]\n )\n\n // Early return AFTER all hooks(disabled / readonly / display mode 走 ReadonlyDisplay)\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n // 2026-05-21 D3 Phase B codex 抓:Custom clear 用 setValue 不直接 onChange,uncontrolled clear 才能真清 internal state。\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => setValue('')} stopPropagation />\n ) : null\n\n const chevronEl = (\n <ItemSuffix>\n <ChevronDown size={iconSize} className={cn('text-fg-muted transition-transform', open && 'rotate-180')} aria-hidden />\n </ItemSuffix>\n )\n\n const triggerContent = (\n <CustomSelectTriggerContent\n searchable={searchable}\n open={open}\n isTextDisplay={isTextDisplay}\n size={size}\n value={value}\n selectedLabel={selectedLabel}\n selectedOpt={selectedOpt}\n SelectedIcon={SelectedIcon}\n StartIcon={StartIcon}\n iconSize={iconSize}\n placeholder={placeholder}\n search={search}\n setSearch={setSearch}\n inputRef={inputRef}\n selectedItemRenderer={selectedItemRenderer}\n />\n )\n\n // hooks(filteredOptions / menuOptions / renderLabel / handleValueChange)已全 hoist(React #310 fix v2)\n\n const trigger = (\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n tabIndex={0}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size }),\n !isTextDisplay && value && !searchable && tagPadding[size],\n // 2026-05-06 v13.3 SSOT retire:per-control `open && 'border-primary'` 移除。Field default\n // state machine `data-[state=open]:border-border-hover`(灰深)處理 open;若 trigger focused\n // (Radix focus on open),focus-within:!border-primary 強制勝出顯藍。focus dominates everything\n // 全 DS 一致(Material/Polaris/Ant 共識),改 Field default 一處全 control 自動跟動。\n error && ['border-error hover:border-error-hover', 'focus-within:border-error focus-within:hover:border-error'],\n 'cursor-pointer',\n className,\n )}\n style={!isTextDisplay ? { paddingRight: 'var(--field-px)' } : undefined}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n // 2026-06-11 P0 a11y(R2 deep-audit):原 guard `!searchable` 連「關閉時的鍵盤開啟」一起擋\n // → searchable Select / PeoplePicker single 鍵盤打不開(WCAG 2.1.1)。原意只是開啟後\n // 別吃掉搜尋框的 Space/Enter → 正確 guard = !open(關閉才攔;開啟後不干擾 input 輸入)。\n if (!open) { e.preventDefault(); setOpen(true) }\n }\n // APG combobox 展開鍵:ArrowDown 也可開(對齊 combobox.tsx 同 pattern;open 後不攔讓方向鍵導覽選單)\n if (e.key === 'ArrowDown' && !open) { e.preventDefault(); setOpen(true) }\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n {triggerContent}\n {clearEl}\n {chevronEl}\n </div>\n )\n\n return (\n <SelectMenu\n options={menuOptions}\n groups={groups}\n value={value ?? null}\n onValueChange={handleValueChange}\n searchable={false}\n loading={loading}\n size={size}\n minRows={minRows}\n open={open}\n onOpenChange={(o) => { setOpen(o); onOpenChange?.(o) }}\n renderLabel={renderLabel}\n onOpenAutoFocus={searchable ? (e) => { e.preventDefault(); inputRef.current?.focus() } : undefined}\n >\n {trigger}\n </SelectMenu>\n )\n }\n)\nCustomSelect.displayName = 'CustomSelect'\n\n// ── Public component(自動偵測 mobile / desktop)──────────────────────────────\n\nconst Select = React.forwardRef<HTMLSelectElement | HTMLDivElement, SelectProps>(\n (props, ref) => {\n const isMobile = useIsTouchDevice()\n\n if (isMobile) {\n return <NativeSelect ref={ref as React.Ref<HTMLSelectElement>} {...props} />\n }\n\n return <CustomSelect ref={ref as React.Ref<HTMLDivElement>} {...props} />\n }\n)\nSelect.displayName = 'Select'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const selectMeta = {\n component: 'Select',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: [],\n fg: ['text-fg-disabled', 'text-fg-muted'],\n ring: [],\n },\n} as const\n\nexport { Select }\n"],"names":["selOpt","tVariant"],"mappings":"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"}
1
+ {"version":3,"file":"select.js","sources":["../../../src/components/Select/select.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 — Select 含 3 子元件(NativeSelect/CustomSelect/ReadonlyDisplay)+ helpers + 4-mode renderer + Field SSOT consumption,split-into-files 會破壞 file-local helper closure\n// @renderer-symmetry-allow: pre-existing Select architecture(2026-05-08 D-path)— selectedItemRenderer 由 CustomSelectTriggerContent 消費(edit + trigger 模式),ReadonlyDisplay 走 separate bare-span path(no D-path)。display→edit unify deferred 下 cycle per spec contract (a) note。本 turn 只加 `nakedCellRowModeAlign` import,no behavior change to renderer symmetry contract。\nimport * as React from 'react'\nimport { X, ChevronDown } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport type { FieldMode, FieldVariant } from '@/design-system/components/Field/field-types'\nimport { fieldWrapperStyles, bareInputStyles, EMPTY_DISPLAY, nakedCellRowModeAlign, fieldDisplayTextClass } from '@/design-system/components/Field/field-wrapper'\nimport { Tag } from '@/design-system/components/Tag/tag'\nimport { ItemInlineAction, ItemPrefix, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'\nimport { useFieldContext, useResolvedFieldSize, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant, useResolvedFieldInvalid } from '@/design-system/components/Field/field-context'\nimport { SelectMenu, forwardKeyToListbox, useActiveDescendant, type SelectMenuOption } from '@/design-system/components/SelectMenu/select-menu'\nimport { useIsTouchDevice } from '@/design-system/hooks/use-is-touch-device'\nimport { useControllable } from '@/design-system/hooks/use-controllable'\nimport { ICON_SIZE } from '@/design-system/tokens/uiSize/icon-size'\n\n// ── Tag padding per size ────────────────────────────────────────────────────\nconst tagPadding: Record<string, string> = {\n sm: 'px-[calc((var(--field-height-sm)_-_1.25rem)_/_2)]',\n md: 'px-[calc((var(--field-height-md)_-_1.5rem)_/_2)]',\n lg: 'px-[calc((var(--field-height-lg)_-_1.5rem)_/_2)]',\n}\n\n// ── Display ─────────────────────────────────────────────────────────────────\n\n/**\n * Select 用的 option schema(2026-05-10 Issue 4 + post-prune unify):**explicit extends\n * SelectMenuOption(primitive SSOT)** — 任何 SelectMenuOption 加 field 都自動繼承,不會 drift。\n *\n * Why `extends SelectMenuOption`(per user 「全盤檢查避免下次又改壞或是偏移」要求):\n * - **schema SSOT 機械強制**:TypeScript inheritance 跟著 primitive 走,wrapper consumer 永遠\n * 拿得到 primitive 所有 surface field\n * - **Hook lint**(M30 `check_wrapper_primitive_schema_drift.sh`):grep `interface .*Option`\n * 未 `extends` SelectMenuOption / 同名重複 declare 直接 BLOCK\n *\n * Wrapper-only field(`tagVariant`)— Select 獨有 `display='tag'` 用,SelectMenu primitive 不該知道\n * 此 wrapper-only concern,所以 wrapper 層 extend 加上,不污染 primitive。\n *\n * 對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown 的 wrapper-vs-primitive\n * schema-extension idiom。\n */\nexport interface SelectOption extends SelectMenuOption {\n /** Tag 模式的顏色。只在 display='tag' 時生效,對應 Tag 的 variant。Wrapper-only。 */\n tagVariant?: string\n}\n\n/** 分組設定 — 對齊 SelectMenuGroupConfig SSOT */\nexport interface SelectGroupConfig {\n key: string\n label: string\n}\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface SelectProps\n extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size' | 'value' | 'defaultValue' | 'onChange'> {\n mode?: FieldMode\n /** Field chrome variant. Default = context.variant ?? 'default'. Per-prop override. */\n variant?: FieldVariant\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n options: SelectOption[]\n /** 分組顯示(對齊 SelectMenu groups SSOT)。option.group 對應 groups[].key */\n groups?: SelectGroupConfig[]\n /** Controlled value(consumer 自管 state)。傳 `value` + `onChange` 表示 controlled mode。 */\n value?: string | null\n /** Uncontrolled 初始值(2026-05-21 D3 audit add per user verbatim「決策三照妳建議」+「都給我做到好」)。\n * 不傳 `value` 時 Select 自管 internal state,以 `defaultValue` 為初始值,選變更時 fire `onChange`\n * callback 通知 consumer(但 state 仍歸 Select)。對齊 Radix Select(`defaultValue`)+ shadcn Input\n * (`defaultValue`)+ React `<input>` dual-mode canonical。\n * 互斥規則:同時傳 `value` + `defaultValue` 走 controlled(value 勝),`defaultValue` 僅 first-mount 用。 */\n defaultValue?: string | null\n onChange?: (value: string) => void\n placeholder?: string\n clearable?: boolean\n display?: 'plain' | 'tag'\n startIcon?: LucideIcon\n /** 啟用搜尋(desktop 時 field 變 input,打字即篩選) */\n searchable?: boolean\n /** Loading state(2026-05-15 audit B fix;2026-07-04 Q3 拍板措辭修訂)。\n * Forward 給 SelectMenu primitive SSOT;spinner 只在**無可顯示選項時**佔 empty slot(cmdk CommandEmpty\n * 機制)— 已有 stale options 時保留顯示不清空(對齊 MUI Autocomplete「only if there are no suggestions」)。\n * Trigger 不變(chevron 保留 user 隨時可點開)。*/\n loading?: boolean\n\n /** Menu list 最小列數(空狀態 / 選項少時的視覺一致 reserve)。預設 3 — 選項 < 3 時顯式縮(如 And/Or 兩選項) */\n minRows?: number\n /** Initial open state(uncontrolled)。對齊 Radix Popover defaultOpen canonical;DataTable cell-as-input\n * click → 1 step open menu(Airtable / Notion canonical),consumer pass `defaultOpen` 達成。\n * Note:Native Select(mobile)無 popover 概念,此 prop 僅 Custom path 生效。 */\n defaultOpen?: boolean\n /** open state 變更 callback(對齊 Radix Popover onOpenChange canonical)。\n * DataTable cell-as-input 用:open=false 時 cell 自動 exit edit mode(避免 dismiss 後卡住)。 */\n onOpenChange?: (open: boolean) => void\n /**\n * Display mode 顯 picker intrinsic end icon(2026-05-08 D path Phase 1)。\n * 預設 false:`mode=\"display\"` 純展示 bare span(向後相容)。\n * `variant=\"naked\" && mode=\"display\"` 場景(DataTable cell)opt-in 設 true → wrap 進\n * Field naked-display + 渲 ChevronDown ItemSuffix。**只 display mode 生效**;readonly /\n * disabled / edit 已有 Field wrapper + suffix(不受此 prop 影響)。\n * Authority:`data-table.spec.md:204` + `inline-action.spec.md:157`「Field family endAction(自動繼承)」。\n * @default false\n */\n showDisplayEndIcon?: boolean\n /**\n * Trigger 內「已選項目」客製 render(2026-05-07 v15.5)。\n *\n * 設了 → trigger 不走純文字 / Tag 預設 path,改用 consumer 提供的 ReactNode(收 selectedOpt)。\n * Searchable+open 仍走 input(搜尋優先)。Empty value(no selection)仍走 placeholder。\n *\n * 用例:PeoplePicker 用此 slot 把 single 選中的 person render 成 PersonDisplay\n * (avatar + name)而非純文字 label。對齊 PeoplePicker = Select wrapper SSOT。\n */\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n /** 搜尋無結果提示(2026-07-04 Q4 拍板接線 — 原 spec 宣稱可覆寫但 prop 從未轉發)。\n * Forward 給 SelectMenu primitive SSOT(default 在 SelectMenu 層「沒有符合的選項」);\n * 僅 Custom path(searchable dropdown)生效,Native path 無搜尋空狀態。\n * 對齊 MUI noOptionsText / Ant notFoundContent / Polaris emptyState 三家公開覆寫點共識。 */\n emptyText?: string\n}\n\n// ── Icon / size helpers ─────────────────────────────────────────────────────\n// 2026-05-18 改 import ICON_SIZE SSOT(per user『做完』approval,消除 M17 違反)\nconst getIconSize = (size: string) => ICON_SIZE[size as 'sm' | 'md' | 'lg']\n\n// ── Shared sub-components ───────────────────────────────────────────────────\n\n/**\n * Inline clear button for Select trigger.\n * 共用 SSOT — Native + Custom 兩變體統一消費。差別僅 onClick 內是否 stopPropagation\n * (Custom trigger 是 combobox `<div>`,點 clear 不可冒泡到打開 menu;Native `<select>` 自有原生\n * 行為,不需 stopPropagation)。\n *\n * 消費的 SSOT:\n * - patterns/element-anatomy/item-anatomy.spec.md → ItemInlineAction(canonical row inline action)\n */\nfunction SelectClearButton({\n size,\n onClear,\n stopPropagation = false,\n}: {\n size: 'sm' | 'md' | 'lg'\n onClear: () => void\n stopPropagation?: boolean\n}) {\n return (\n <span className=\"relative z-10\">\n <ItemInlineAction\n size={size}\n action={{\n icon: X,\n label: '清除選取', // i18n-allow: DS default inline-action label\n onClick: stopPropagation ? (e) => { e?.stopPropagation(); onClear() } : () => onClear(),\n }}\n />\n </span>\n )\n}\nSelectClearButton.displayName = 'SelectClearButton'\n\n/**\n * Trigger content for CustomSelect — 三種顯示模式分支(searchable+open / text / tag)\n * 抽出降低 `CustomSelect` forwardRef body 長度;邏輯本質是純展示分流,無 hook / ref。\n */\nfunction CustomSelectTriggerContent({\n searchable,\n open,\n isTextDisplay,\n size,\n value,\n selectedLabel,\n selectedOpt,\n SelectedIcon,\n StartIcon,\n iconSize,\n placeholder,\n search,\n setSearch,\n inputRef,\n activeDescendantId,\n ariaLabel,\n labelId,\n selectedItemRenderer,\n}: {\n searchable: boolean\n open: boolean\n isTextDisplay: boolean\n size: 'sm' | 'md' | 'lg'\n value?: string | null\n selectedLabel: string\n selectedOpt?: SelectOption\n SelectedIcon?: LucideIcon\n StartIcon?: LucideIcon\n iconSize: number\n placeholder?: string\n search: string\n setSearch: (v: string) => void\n inputRef: React.RefObject<HTMLInputElement | null>\n activeDescendantId?: string\n ariaLabel?: string\n labelId?: string\n selectedItemRenderer?: (selectedOpt: SelectOption) => React.ReactNode\n}): React.ReactNode {\n // Searchable + open: 顯示搜尋 input\n // 2026-05-15 Bug 2 fix(Claude+Codex Step 5 比稿 consensus,user verbatim「就 A」):\n // 撤掉 native `<input placeholder=selectedLabel>` 不可靠 ellipsis renderer(browser-specific\n // placeholder painting,user 抓「placeholder 直接被截掉沒 ellipsis」)。改 span overlay:\n // - input native placeholder 限「搜尋…」/「請選擇人員」trigger empty hint(無 selectedLabel)\n // - sibling `<span aria-hidden pointer-events-none absolute inset-0 truncate>` 在 search='' 且\n // 有 selectedLabel 時 overlay 顯該人名(memory aid,truncate-with-ellipsis 可控)\n // 對齊 spec.md §B row 4「open + inline-search + 選 1 人 → input cursor + placeholder = 該人名 + ellipsis」。\n // a11y(2026-07-05 backlog 補接):搜尋 input 是 open 時實際聚焦的元素,accessible name 必接在\n // input 本身(原 codex Q2 guard 註解宣稱「來自 field/label/aria-label」,但接線全在外層 trigger\n // div,焦點所在的 input 無 name)— aria-labelledby 接 FieldLabel labelId、consumer aria-label\n // 優先(對齊 trigger div 同款 guard),兩者皆無時 fallback aria-label「搜尋選項」(對齊\n // combobox.tsx searchAriaLabel canonical default);**不**依賴 placeholder 當 label;overlay\n // span aria-hidden + pointer-events-none。APG「combobox role 移到 input 本身」屬中期重構另案。\n if (searchable && open) {\n const triggerEmptyPlaceholder = placeholder || '搜尋…' // i18n-allow: DS fallback\n const showSelectedOverlay = !search && selectedLabel\n return (\n <span className=\"relative flex-1 min-w-0 inline-flex items-center\">\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n // a11y(2026-07-05 D4):cmdk active item id(useActiveDescendant)→ SR 播報方向鍵導覽中的 option\n aria-activedescendant={activeDescendantId}\n // accessible name:aria-labelledby(Field label)> consumer aria-label > DS default(accname 優先序)\n aria-label={ariaLabel ?? '搜尋選項'} // i18n-allow: DS default(對齊 combobox.tsx searchAriaLabel canonical)\n aria-labelledby={ariaLabel ? undefined : labelId}\n // Native placeholder 限 trigger empty hint(無 selectedLabel 時);若已 selected,留空交給 overlay span\n placeholder={showSelectedOverlay ? '' : triggerEmptyPlaceholder}\n className={cn(bareInputStyles, 'cursor-text')}\n autoFocus\n />\n {showSelectedOverlay && (\n // 2026-05-16 Bug B 真 root cause fix(Claude+Codex M31 Step 5 比稿 consensus,user verbatim\n // 「修了一百次還沒好」+ codex cite W3C CSS Overflow / MDN / Mozilla Bug 972664#c1):\n // 原 `inline-flex items-center truncate` 套同一 span,text 變 anonymous flex item →\n // `text-overflow:ellipsis` 對 anonymous item 不 styleable → ellipsis dots 不可見(text 純 clip)。\n // 對齊 `person-display.tsx:148` 既有 DS canonical:outer flex container + inner truncate 真實 box。\n // DS-wide grep 29 個 truncate 都遵此 pattern,只本處違反 — 修齊。\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 flex items-center text-fg-muted\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{selectedLabel}</span>\n </span>\n )}\n </span>\n )\n }\n // **selectedItemRenderer slot**(2026-05-07 v15.5):consumer 客製 selected display(e.g.\n // PeoplePicker 接 PersonDisplay)。優先於 isTextDisplay / Tag 預設 path,但 empty value\n // 仍走 placeholder。對齊 PeoplePicker = Select wrapper SSOT。\n if (selectedItemRenderer && value && selectedOpt) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {/* 2026-05-14 item-anatomy SSOT fix(per codex H2 propagation 斷點):加 nakedCellRowModeAlign\n → autoRowHeight cell 內 selected renderer 也對齊 first-line,不再 vertical-center 整 row。 */}\n <span className={cn(\"flex-1 min-w-0 inline-flex items-center\", nakedCellRowModeAlign)}>{selectedItemRenderer(selectedOpt)}</span>\n </>\n )\n }\n // Text display: 純文字 + optional value icon\n if (isTextDisplay) {\n return (\n <>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedIcon && value && <ItemPrefix><SelectedIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', !value && 'text-fg-muted')}>\n {value ? selectedLabel : (placeholder ?? '選擇…')}\n </span>\n </>\n )\n }\n // Tag display: 用 option 的 tagVariant\n return (\n <>\n {value && selectedOpt?.tagVariant\n ? <Tag size={size} color={selectedOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : value\n ? <Tag size={size} className=\"shrink-0 pointer-events-none\">{selectedLabel}</Tag>\n : <span className=\"text-fg-muted\">{placeholder ?? '選擇…'}</span>\n }\n <span className=\"flex-1\" />\n </>\n )\n}\nCustomSelectTriggerContent.displayName = 'CustomSelectTriggerContent'\n\n// ── Shared readonly/disabled/display render ─────────────────────────────────\nfunction ReadonlyDisplay({\n mode, variant: variantProp, size, options, value, display, startIcon: StartIcon, className, placeholder, showDisplayEndIcon,\n}: Pick<SelectProps, 'mode' | 'variant' | 'size' | 'options' | 'value' | 'display' | 'startIcon' | 'className' | 'placeholder' | 'showDisplayEndIcon'>) {\n const resolvedMode = mode ?? 'readonly'\n const variant = variantProp ?? 'default'\n const sz = size ?? 'md'\n const iconSize = getIconSize(sz)\n const label = options?.find(o => o.value === value)?.label ?? value\n const iconColor = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const isTextDisplay = display !== 'tag'\n // K10+K14 fix(2026-05-04):disabled mode placeholder/empty 顯示色 → fg-disabled(neutral-6),非 fg-muted(neutral-7)\n // user canonical:disabled 顯著性優於 muted。同時 plain mode 必須 respect placeholder prop(之前忽略 = bug)\n const emptyColorCls = resolvedMode === 'disabled' ? 'text-fg-disabled' : 'text-fg-muted'\n const emptyText = placeholder ?? EMPTY_DISPLAY\n\n // mode='display':2 path(2026-05-08 D path Phase 1 Select canary)\n // ❌ 預設(無 showDisplayEndIcon):純內容輸出 bare span/Tag(原行為,backward compat)\n // 對齊原 SelectDisplay sub-component(retired)。readonly / disabled 仍走下方 fieldWrapperStyles。\n // ✅ showDisplayEndIcon=true(DataTable cell opt-in):Field naked-display wrapper +\n // ChevronDown ItemSuffix。SSOT canonical 跟 readonly/edit/disabled mode 同 DOM 結構。\n // Authority: data-table.spec.md:204 + inline-action.spec.md:157「Field family endAction」\n if (resolvedMode === 'display') {\n if (!showDisplayEndIcon) {\n // 2026-05-14 I2 fix(spec contract (e) display typography canonical):bare span 必套\n // `fieldDisplayTextClass(sz)`(sm/md→text-body,lg→text-body-lg)— 對齊跨 Field\n // family display 視覺尺寸統一。\n if (!value) return <span className={cn(fieldDisplayTextClass(sz), 'text-fg-muted', className)}>{emptyText}</span>\n if (isTextDisplay) return <span className={cn(fieldDisplayTextClass(sz), 'truncate', className)}>{label}</span>\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return <Tag size={sz} color={tVariant} className={className}>{label}</Tag>\n }\n // D path opt-in: Field naked-display wrapper + ItemSuffix ChevronDown\n const selOpt = options?.find(o => o.value === value)\n const tVariant = selOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n return (\n <div\n className={cn(fieldWrapperStyles({ mode: 'display', variant, size: sz }), value && !isTextDisplay && tagPadding[sz], className)}\n data-field-mode=\"display\"\n >\n {isTextDisplay ? (\n <span className={cn(bareInputStyles, 'flex-1 min-w-0 truncate', !value && emptyColorCls)}>\n {value ? label : emptyText}\n </span>\n ) : value ? (\n <Tag size={sz} color={tVariant}>{label}</Tag>\n ) : (\n <span className={cn('flex-1 min-w-0', emptyColorCls)}>{emptyText}</span>\n )}\n <ItemSuffix><ChevronDown size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemSuffix>\n </div>\n )\n }\n\n // 2026-06-26 類型身份 indicator 規則:edit 顯示 / readonly 不顯示(純值、不可開下拉,箭頭會誤導) /\n // disabled 保留(fg-disabled,對齊原生 <select disabled> 灰示箭頭 + Accordion M24 precedent)。\n // naked cell 情境依 showDisplayEndIcon = isEditable,維持 2026-05-10 cell canonical「非可編欄不顯」。\n // aria-disabled:styled-disabled(非 native disabled 元素)需明告 AT「inactive」,同時讓 axe 正確\n // 豁免 disabled 文字的 color-contrast(WCAG 1.4.3 inactive UI 例外)。\n const showIndicator = variant === 'naked' ? !!showDisplayEndIcon : resolvedMode === 'disabled'\n const ariaDisabled = resolvedMode === 'disabled' ? true : undefined\n\n if (isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), className)} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className={cn('pointer-events-none', iconColor)} aria-hidden /></ItemPrefix>}\n <span className={cn('flex-1 min-w-0 truncate', resolvedMode === 'disabled' && 'text-fg-disabled')}>\n {value ? label : <span className={emptyColorCls}>{emptyText}</span>}\n </span>\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n }\n\n const selectedOpt = options?.find(o => o.value === value)\n const tagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: resolvedMode, variant, size: sz }), value && tagPadding[sz], className)} style={{ paddingRight: 'var(--field-px)' }} data-field-mode={resolvedMode} aria-disabled={ariaDisabled}>\n {value ? <Tag size={sz} color={tagVariant}>{label}</Tag> : <span className={emptyColorCls}>{emptyText}</span>}\n {showIndicator && <ItemSuffix className=\"pointer-events-none\"><ChevronDown size={iconSize} className={cn('shrink-0', iconColor)} aria-hidden /></ItemSuffix>}\n </div>\n )\n}\n\n// ── Native Select (mobile) ─────────────────────────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst NativeSelect = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp,\n // 2026-07-04:Custom-path-only props 顯式 destructure 丟棄(不 spread 到原生 <select> 消 React\n // unknown-prop warning);各 prop docblock 已註「僅 Custom path 生效」語意\n searchable: _searchable, groups: _groups, loading: _loading, minRows: _minRows, emptyText: _emptyText, defaultOpen: _defaultOpen, onOpenChange: _onOpenChange, selectedItemRenderer: _selectedItemRenderer,\n ...props }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(同 CustomSelect)\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const handleNativeChange = (v: string) => setValue(v)\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n const selectRef = React.useRef<HTMLSelectElement | null>(null)\n const setSelectRef = React.useCallback((el: HTMLSelectElement | null) => {\n selectRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLSelectElement | null>).current = el\n }, [ref])\n\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n const selectEl = (\n <select\n ref={setSelectRef}\n id={idProp ?? fieldCtx?.id}\n value={value ?? ''}\n onChange={(e) => handleNativeChange(e.target.value)}\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n className={cn(bareInputStyles, 'cursor-pointer appearance-none', !value && 'text-fg-muted', !isTextDisplay && value && 'absolute inset-0 w-full h-full opacity-0 z-0')}\n {...props}\n >\n {placeholder && <option value=\"\" disabled>{placeholder}</option>}\n {/* disabled forward(2026-07-04):對齊桌機 path menuOptions disabled forward — 觸控原生 option 同樣不可選(spec「disabled 選項」邊界案例) */}\n {options.map(opt => <option key={opt.value} value={opt.value} disabled={opt.disabled}>{opt.label}</option>)}\n </select>\n )\n\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => handleNativeChange('')} />\n ) : null\n\n const chevronEl = (\n <ItemSuffix className=\"relative z-10 pointer-events-none\">\n <ChevronDown size={iconSize} className=\"text-fg-muted\" aria-hidden />\n </ItemSuffix>\n )\n const selectedOpt = options?.find(o => o.value === value)\n const label = selectedOpt?.label ?? value\n const nativeTagVariant = selectedOpt?.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral' | undefined\n const SelectedOptIcon = selectedOpt?.icon\n\n if (!isTextDisplay) {\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }), value && tagPadding[size], 'relative',\n className)}\n style={{ paddingRight: 'var(--field-px)' }} data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {value ? <Tag size={size} color={nativeTagVariant} className=\"shrink-0 relative z-10 pointer-events-none\">{label}</Tag> : <span className=\"text-fg-muted\">{placeholder ?? '選擇...'}</span>}\n {selectEl}\n <span className=\"flex-1\" />\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n\n return (\n <div className={cn(fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }),\n className)}\n data-field-mode=\"edit\" data-error={error ? '' : undefined}>\n {StartIcon && <ItemPrefix><StartIcon size={iconSize} className=\"text-fg-muted pointer-events-none\" aria-hidden /></ItemPrefix>}\n {!StartIcon && SelectedOptIcon && value && <ItemPrefix><SelectedOptIcon size={iconSize} className=\"pointer-events-none\" aria-hidden /></ItemPrefix>}\n {selectEl}\n {clearEl}\n {chevronEl}\n </div>\n )\n }\n)\nNativeSelect.displayName = 'NativeSelect'\n\n// ── Custom Select (desktop — consumes SelectMenu) ────────────────────────\n\n// code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding\nconst CustomSelect = React.forwardRef<HTMLDivElement, SelectProps>(\n ({ mode, variant: variantProp, error: errorProp = false, size: sizeProp, options, groups, value: valueProp, defaultValue, onChange, placeholder, className, disabled: disabledProp, clearable = false, display = 'plain', startIcon: StartIcon, searchable = false, loading, minRows, emptyText, defaultOpen = false, onOpenChange, selectedItemRenderer, showDisplayEndIcon, id: idProp, 'aria-describedby': ariaDescribedByProp, 'aria-errormessage': ariaErrorMessageProp, 'aria-label': ariaLabel }, ref) => {\n const fieldCtx = useFieldContext()\n const error = useResolvedFieldInvalid(errorProp)\n const disabled = useResolvedFieldDisabled(disabledProp)\n // 2026-05-31 #11:size 從 Field context cascade(對齊 Input/NumberInput + MUI FormControl)\n const size = useResolvedFieldSize(sizeProp)\n // 2026-06-08 SSOT:mode 經 useResolvedFieldMode(prop > 有效 disabled > fieldCtx.mode > 'edit');修 <Field mode=\"display\"> 漏 cascade\n const resolvedMode = useResolvedFieldMode({ mode, disabled })\n const variant: FieldVariant = useResolvedFieldVariant(variantProp)\n const iconSize = getIconSize(size)\n // 2026-05-21 D3 audit:Controlled / Uncontrolled dual-mode via 既有 SSOT hook(M17 對齊,取代自刻 isControlled pattern)。\n // Phase B codex 抓:之前 Custom clear 走 `onChange?.('')` 沒 setInternalValue → uncontrolled clear 失效。useControllable 統一 setter 修。\n // onChange forward coerce null → ''(consumer 簽名 `(value: string) => void`,null 是 internal empty signal)。\n const [value, setValue] = useControllable<string | null>({\n value: valueProp,\n defaultValue: defaultValue ?? null,\n onChange: onChange ? (next) => onChange(next ?? '') : undefined,\n })\n const showClear = clearable && value && resolvedMode === 'edit'\n const isTextDisplay = display === 'plain'\n\n const [open, setOpen] = React.useState(defaultOpen)\n const [search, setSearch] = React.useState('')\n const inputRef = React.useRef<HTMLInputElement>(null)\n // a11y(2026-07-04):listbox 容器 id——trigger aria-controls 指向 SelectMenu PopoverContent\n // (對齊姊妹元件 combobox.tsx:677 既有 canonical;React.useId SSR/CSR 穩定)。\n const listboxId = React.useId()\n // a11y(2026-07-05 D4):追蹤 cmdk active item id → searchable trigger input 綁 aria-activedescendant\n // (機制詳 select-menu.tsx useActiveDescendant docblock;必在 early return 前呼叫 — React #310 hook 順序)。\n const activeOptionId = useActiveDescendant(listboxId, open)\n\n // 關閉時清搜尋\n React.useEffect(() => { if (!open) setSearch('') }, [open])\n\n // **React #310 fix(2026-05-04)**:所有 hooks 必在任何 early return 前 call,\n // 否則 disabled→edit 切換時 hook count 變動 → React 死亡。\n // 原本 useMemo(L280, L291) 在 early return 之後 = latent bug,K13 觸發(filter Op 從 disabled\n // 變 edit 當 user 選欄位)。修法:把所有 useMemo 提到 early return 之前。\n const selectedOpt = options?.find(o => o.value === value)\n // 2026-05-06 v9.1:value 不在 options 也要顯示原值(不沉默丟失)。原 fallback `''` 致\n // SelectCell 開 edit 時若 cell value 不在當前 options(e.g. 上游資料漂移 / options async\n // 後到 / 跨 dataset),trigger 顯示空白 — user 報「value 不見」。對齊 ReadonlyDisplay 同\n // 級 fallback `?? value`。\n const selectedLabel = selectedOpt?.label ?? value ?? ''\n const SelectedIcon = selectedOpt?.icon\n // ── 過濾選項 ──\n const filteredOptions = searchable && search\n ? options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))\n : options\n // ── 轉換 SelectOption → SelectMenuOption(必在 early return 前) ──\n // Issue 4(2026-05-10):forward avatar / description / disabled SSOT(per SelectMenuOption schema)。\n const menuOptions: SelectMenuOption[] = React.useMemo(\n () => filteredOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n icon: isTextDisplay ? opt.icon : undefined,\n avatar: opt.avatar,\n description: opt.description,\n disabled: opt.disabled,\n group: opt.group,\n })),\n [filteredOptions, isTextDisplay]\n )\n // ── Tag display 自訂 label 渲染(必在 early return 前) ──\n const renderLabel = React.useMemo(() => {\n if (isTextDisplay) return undefined\n return (menuOpt: SelectMenuOption) => {\n const srcOpt = options.find(o => o.value === menuOpt.value)\n if (srcOpt?.tagVariant) {\n return <Tag size={size} color={srcOpt.tagVariant as 'blue' | 'green' | 'red' | 'yellow' | 'neutral'}>{menuOpt.label}</Tag>\n }\n return menuOpt.label\n }\n }, [isTextDisplay, options, size])\n\n // **React #310 fix v2(2026-05-04)**:`handleValueChange` useCallback 也必在 early return 前\n // 原本 L306(early return 後)→ disabled→edit 切換時 hook count 仍變 → #310 持續\n // 2026-05-21 D3:`useControllable` 統一 controlled / uncontrolled state + onChange forward,不再手動 if-branch。\n const handleValueChange = React.useCallback(\n (newValue: string | string[]) => {\n setValue(Array.isArray(newValue) ? newValue[0] : newValue)\n },\n [setValue]\n )\n\n // Early return AFTER all hooks(disabled / readonly / display mode 走 ReadonlyDisplay)\n if (resolvedMode !== 'edit') {\n return <ReadonlyDisplay mode={resolvedMode} variant={variant} size={size} options={options} value={value} display={display} startIcon={StartIcon} className={className} placeholder={placeholder} showDisplayEndIcon={showDisplayEndIcon} />\n }\n\n // 2026-05-21 D3 Phase B codex 抓:Custom clear 用 setValue 不直接 onChange,uncontrolled clear 才能真清 internal state。\n const clearEl = showClear ? (\n <SelectClearButton size={size ?? 'md'} onClear={() => setValue('')} stopPropagation />\n ) : null\n\n const chevronEl = (\n <ItemSuffix>\n <ChevronDown size={iconSize} className={cn('text-fg-muted transition-transform', open && 'rotate-180')} aria-hidden />\n </ItemSuffix>\n )\n\n const triggerContent = (\n <CustomSelectTriggerContent\n searchable={searchable}\n open={open}\n isTextDisplay={isTextDisplay}\n size={size}\n value={value}\n selectedLabel={selectedLabel}\n selectedOpt={selectedOpt}\n SelectedIcon={SelectedIcon}\n StartIcon={StartIcon}\n iconSize={iconSize}\n placeholder={placeholder}\n search={search}\n setSearch={setSearch}\n inputRef={inputRef}\n activeDescendantId={activeOptionId}\n ariaLabel={ariaLabel}\n labelId={fieldCtx?.labelId}\n selectedItemRenderer={selectedItemRenderer}\n />\n )\n\n // hooks(filteredOptions / menuOptions / renderLabel / handleValueChange)已全 hoist(React #310 fix v2)\n\n const trigger = (\n <div\n ref={ref}\n id={idProp ?? fieldCtx?.id}\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-label={ariaLabel}\n // a11y(2026-07-04):div-based role=combobox 的 <label for> 無效,接 FieldLabel labelId\n // (field-context.ts labelId jsDoc 明文);consumer aria-label 優先(對齊 slider.tsx:166 guard canonical)。\n aria-labelledby={ariaLabel ? undefined : fieldCtx?.labelId}\n aria-invalid={error || undefined}\n aria-required={fieldCtx?.required || undefined}\n aria-describedby={ariaDescribedByProp ?? fieldCtx?.descriptionId}\n aria-errormessage={ariaErrorMessageProp ?? (error ? fieldCtx?.errorId : undefined)}\n tabIndex={0}\n className={cn(\n fieldWrapperStyles({ mode: 'edit', variant: variant, size, error }),\n !isTextDisplay && value && !searchable && tagPadding[size],\n // 2026-05-06 v13.3 SSOT retire:per-control `open && 'border-primary'` 移除。Field default\n // state machine `data-[state=open]:border-border-hover`(灰深)處理 open。\n // 2026-07-04 Q1:error border 同樣收進 fieldWrapperStyles error variant(error 勝 focus 色)。\n 'cursor-pointer',\n className,\n )}\n style={!isTextDisplay ? { paddingRight: 'var(--field-px)' } : undefined}\n data-field-mode=\"edit\"\n data-error={error ? '' : undefined}\n onKeyDown={(e) => {\n // 2026-07-05 D4 P0:open 後 ArrowUp/Down/Enter 轉送 cmdk root(見 select-menu.tsx\n // forwardKeyToListbox docblock — 原「open 後不攔讓方向鍵導覽」在跨 DOM 子樹機制上不成立)\n if (open && forwardKeyToListbox(listboxId, e)) return\n if (e.key === 'Enter' || e.key === ' ') {\n // 2026-06-11 P0 a11y(R2 deep-audit):原 guard `!searchable` 連「關閉時的鍵盤開啟」一起擋\n // → searchable Select / PeoplePicker single 鍵盤打不開(WCAG 2.1.1)。原意只是開啟後\n // 別吃掉搜尋框的 Space/Enter → 正確 guard = !open(關閉才攔;開啟後不干擾 input 輸入)。\n if (!open) { e.preventDefault(); setOpen(true) }\n }\n // APG combobox 展開鍵:ArrowDown 也可開(對齊 combobox.tsx 同 pattern;open 後不攔讓方向鍵導覽選單)\n if (e.key === 'ArrowDown' && !open) { e.preventDefault(); setOpen(true) }\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n {triggerContent}\n {clearEl}\n {chevronEl}\n </div>\n )\n\n return (\n <SelectMenu\n options={menuOptions}\n groups={groups}\n value={value ?? null}\n onValueChange={handleValueChange}\n searchable={false}\n loading={loading}\n emptyText={emptyText}\n size={size}\n minRows={minRows}\n open={open}\n onOpenChange={(o) => { setOpen(o); onOpenChange?.(o) }}\n contentId={listboxId}\n renderLabel={renderLabel}\n onOpenAutoFocus={searchable ? (e) => { e.preventDefault(); inputRef.current?.focus() } : undefined}\n >\n {trigger}\n </SelectMenu>\n )\n }\n)\nCustomSelect.displayName = 'CustomSelect'\n\n// ── Public component(自動偵測 mobile / desktop)──────────────────────────────\n\nconst Select = React.forwardRef<HTMLSelectElement | HTMLDivElement, SelectProps>(\n (props, ref) => {\n const isMobile = useIsTouchDevice()\n\n if (isMobile) {\n return <NativeSelect ref={ref as React.Ref<HTMLSelectElement>} {...props} />\n }\n\n return <CustomSelect ref={ref as React.Ref<HTMLDivElement>} {...props} />\n }\n)\nSelect.displayName = 'Select'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const selectMeta = {\n component: 'Select',\n family: 4,\n variants: {\n\n },\n sizes: {\n\n },\n // 'active' 移除 — trigger 走 Field chrome、menu row 走 MenuItem(其 meta 無 active)(2026-07-07 詞彙統一 DS-wide 按壓訊號盤點:檔內 0 active: utility / 0 *-active token)。\n states: ['default', 'hover', 'focus-visible', 'disabled'],\n tokens: {\n bg: [],\n fg: ['text-fg-disabled', 'text-fg-muted'],\n ring: [],\n },\n} as const\n\nexport { Select }\n"],"names":["selOpt","tVariant"],"mappings":";;;;;;;;;;;AAkBA,MAAM,aAAqC;AAAA,EACzC,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAsGA,MAAM,cAAc,CAAC,SAAiB,UAAU,IAA0B;AAa1E,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA,kBAAkB;AACpB,GAIG;AACD,SACE,oBAAC,QAAA,EAAK,WAAU,iBACd,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA;AAAA,QACP,SAAS,kBAAkB,CAAC,MAAM;AAAE,iCAAG;AAAmB,kBAAA;AAAA,QAAU,IAAI,MAAM,QAAA;AAAA,MAAQ;AAAA,IACxF;AAAA,EAAA,GAEJ;AAEJ;AACA,kBAAkB,cAAc;AAMhC,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAmBoB;AAelB,MAAI,cAAc,MAAM;AACtB,UAAM,0BAA0B,eAAe;AAC/C,UAAM,sBAAsB,CAAC,UAAU;AACvC,WACE,qBAAC,QAAA,EAAK,WAAU,oDACb,UAAA;AAAA,MAAA,aAAa,oBAAC,YAAA,EAAW,UAAA,oBAAC,WAAA,EAAU,MAAM,UAAU,WAAU,qCAAoC,eAAW,KAAA,CAAC,EAAA,CAAE;AAAA,MACjH;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,KAAK;AAAA,UAEzC,yBAAuB;AAAA,UAEvB,cAAY,aAAa;AAAA,UACzB,mBAAiB,YAAY,SAAY;AAAA,UAEzC,aAAa,sBAAsB,KAAK;AAAA,UACxC,WAAW,GAAG,iBAAiB,aAAa;AAAA,UAC5C,WAAS;AAAA,QAAA;AAAA,MAAA;AAAA,MAEV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UAEV,UAAA,oBAAC,QAAA,EAAK,WAAU,2BAA2B,UAAA,cAAA,CAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAC3D,GAEJ;AAAA,EAEJ;AAIA,MAAI,wBAAwB,SAAS,aAAa;AAChD,WACE,qBAAA,UAAA,EACG,UAAA;AAAA,MAAA,aAAa,oBAAC,YAAA,EAAW,UAAA,oBAAC,WAAA,EAAU,MAAM,UAAU,WAAU,qCAAoC,eAAW,KAAA,CAAC,EAAA,CAAE;AAAA,MAGjH,oBAAC,UAAK,WAAW,GAAG,2CAA2C,qBAAqB,GAAI,UAAA,qBAAqB,WAAW,EAAA,CAAE;AAAA,IAAA,GAC5H;AAAA,EAEJ;AAEA,MAAI,eAAe;AACjB,WACE,qBAAA,UAAA,EACG,UAAA;AAAA,MAAA,aAAa,oBAAC,YAAA,EAAW,UAAA,oBAAC,WAAA,EAAU,MAAM,UAAU,WAAU,qCAAoC,eAAW,KAAA,CAAC,EAAA,CAAE;AAAA,MAChH,CAAC,aAAa,gBAAgB,6BAAU,YAAA,EAAW,UAAA,oBAAC,cAAA,EAAa,MAAM,UAAU,WAAU,uBAAsB,eAAW,MAAC,GAAE;AAAA,MAChI,oBAAC,QAAA,EAAK,WAAW,GAAG,2BAA2B,CAAC,SAAS,eAAe,GACrE,UAAA,QAAQ,gBAAiB,eAAe,MAAA,CAC3C;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,SACE,qBAAA,UAAA,EACG,UAAA;AAAA,IAAA,UAAS,2CAAa,cACnB,oBAAC,KAAA,EAAI,MAAY,OAAO,YAAY,YAA+D,WAAU,gCAAgC,UAAA,cAAA,CAAc,IAC3J,QACE,oBAAC,KAAA,EAAI,MAAY,WAAU,gCAAgC,UAAA,eAAc,IACzE,oBAAC,QAAA,EAAK,WAAU,iBAAiB,UAAA,eAAe,OAAM;AAAA,IAE5D,oBAAC,QAAA,EAAK,WAAU,SAAA,CAAS;AAAA,EAAA,GAC3B;AAEJ;AACA,2BAA2B,cAAc;AAGzC,SAAS,gBAAgB;AAAA,EACvB;AAAA,EAAM,SAAS;AAAA,EAAa;AAAA,EAAM;AAAA,EAAS;AAAA,EAAO;AAAA,EAAS,WAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAa;AAC3G,GAAwJ;;AACtJ,QAAM,eAAe,QAAQ;AAC7B,QAAM,UAAU,eAAe;AAC/B,QAAM,KAAK,QAAQ;AACnB,QAAM,WAAW,YAAY,EAAE;AAC/B,QAAM,UAAQ,wCAAS,KAAK,CAAA,MAAK,EAAE,UAAU,WAA/B,mBAAuC,UAAS;AAC9D,QAAM,YAAY,iBAAiB,aAAa,qBAAqB;AACrE,QAAM,gBAAgB,YAAY;AAGlC,QAAM,gBAAgB,iBAAiB,aAAa,qBAAqB;AACzE,QAAM,YAAY,eAAe;AAQjC,MAAI,iBAAiB,WAAW;AAC9B,QAAI,CAAC,oBAAoB;AAIvB,UAAI,CAAC,MAAO,QAAO,oBAAC,QAAA,EAAK,WAAW,GAAG,sBAAsB,EAAE,GAAG,iBAAiB,SAAS,GAAI,UAAA,UAAA,CAAU;AAC1G,UAAI,cAAe,QAAO,oBAAC,QAAA,EAAK,WAAW,GAAG,sBAAsB,EAAE,GAAG,YAAY,SAAS,GAAI,UAAA,MAAA,CAAM;AACxG,YAAMA,UAAS,mCAAS,KAAK,CAAA,MAAK,EAAE,UAAU;AAC9C,YAAMC,YAAWD,mCAAQ;AACzB,iCAAQ,KAAA,EAAI,MAAM,IAAI,OAAOC,WAAU,WAAuB,UAAA,OAAM;AAAA,IACtE;AAEA,UAAM,SAAS,mCAAS,KAAK,CAAA,MAAK,EAAE,UAAU;AAC9C,UAAM,WAAW,iCAAQ;AACzB,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,GAAG,mBAAmB,EAAE,MAAM,WAAW,SAAS,MAAM,GAAA,CAAI,GAAG,SAAS,CAAC,iBAAiB,WAAW,EAAE,GAAG,SAAS;AAAA,QAC9H,mBAAgB;AAAA,QAEf,UAAA;AAAA,UAAA,gBACC,oBAAC,QAAA,EAAK,WAAW,GAAG,iBAAiB,2BAA2B,CAAC,SAAS,aAAa,GACpF,UAAA,QAAQ,QAAQ,WACnB,IACE,QACF,oBAAC,KAAA,EAAI,MAAM,IAAI,OAAO,UAAW,UAAA,MAAA,CAAM,IAEvC,oBAAC,QAAA,EAAK,WAAW,GAAG,kBAAkB,aAAa,GAAI,UAAA,WAAU;AAAA,UAEnE,oBAAC,YAAA,EAAW,UAAA,oBAAC,aAAA,EAAY,MAAM,UAAU,WAAU,qCAAoC,eAAW,KAAA,CAAC,EAAA,CAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAG3G;AAOA,QAAM,gBAAgB,YAAY,UAAU,CAAC,CAAC,qBAAqB,iBAAiB;AACpF,QAAM,eAAe,iBAAiB,aAAa,OAAO;AAE1D,MAAI,eAAe;AACjB,gCACG,OAAA,EAAI,WAAW,GAAG,mBAAmB,EAAE,MAAM,cAAc,SAAS,MAAM,GAAA,CAAI,GAAG,SAAS,GAAG,mBAAiB,cAAc,iBAAe,cACzI,UAAA;AAAA,MAAA,aAAa,oBAAC,YAAA,EAAW,UAAA,oBAAC,WAAA,EAAU,MAAM,UAAU,WAAW,GAAG,uBAAuB,SAAS,GAAG,eAAW,MAAC,GAAE;AAAA,0BACnH,QAAA,EAAK,WAAW,GAAG,2BAA2B,iBAAiB,cAAc,kBAAkB,GAC7F,UAAA,QAAQ,QAAQ,oBAAC,QAAA,EAAK,WAAW,eAAgB,qBAAU,GAC9D;AAAA,MACC,iBAAiB,oBAAC,YAAA,EAAW,WAAU,uBAAsB,8BAAC,aAAA,EAAY,MAAM,UAAU,WAAW,GAAG,YAAY,SAAS,GAAG,eAAW,MAAC,EAAA,CAAE;AAAA,IAAA,GACjJ;AAAA,EAEJ;AAEA,QAAM,cAAc,mCAAS,KAAK,CAAA,MAAK,EAAE,UAAU;AACnD,QAAM,aAAa,2CAAa;AAEhC,SACE,qBAAC,OAAA,EAAI,WAAW,GAAG,mBAAmB,EAAE,MAAM,cAAc,SAAS,MAAM,GAAA,CAAI,GAAG,SAAS,WAAW,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,cAAc,kBAAA,GAAqB,mBAAiB,cAAc,iBAAe,cAC9M,UAAA;AAAA,IAAA,QAAQ,oBAAC,KAAA,EAAI,MAAM,IAAI,OAAO,YAAa,UAAA,MAAA,CAAM,IAAS,oBAAC,QAAA,EAAK,WAAW,eAAgB,UAAA,WAAU;AAAA,IACrG,iBAAiB,oBAAC,YAAA,EAAW,WAAU,uBAAsB,8BAAC,aAAA,EAAY,MAAM,UAAU,WAAW,GAAG,YAAY,SAAS,GAAG,eAAW,MAAC,EAAA,CAAE;AAAA,EAAA,GACjJ;AAEJ;AAKA,MAAM,eAAe,MAAM;AAAA,EACzB,CAAC;AAAA,IAAE;AAAA,IAAM,SAAS;AAAA,IAAa,OAAO,YAAY;AAAA,IAAO,MAAM;AAAA,IAAU;AAAA,IAAS,OAAO;AAAA,IAAW;AAAA,IAAc;AAAA,IAAU;AAAA,IAAa;AAAA,IAAW,UAAU;AAAA,IAAc,YAAY;AAAA,IAAO,UAAU;AAAA,IAAS,WAAW;AAAA,IAAW;AAAA,IAAoB,IAAI;AAAA,IAAQ,oBAAoB;AAAA,IAAqB,qBAAqB;AAAA;AAAA;AAAA,IAGpU,YAAY;AAAA,IAAa,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAU,SAAS;AAAA,IAAU,WAAW;AAAA,IAAY,aAAa;AAAA,IAAc,cAAc;AAAA,IAAe,sBAAsB;AAAA,IACrL,GAAG;AAAA,EAAA,GAAS,QAAQ;AACpB,UAAM,WAAW,gBAAA;AACjB,UAAM,QAAQ,wBAAwB,SAAS;AAC/C,UAAM,WAAW,yBAAyB,YAAY;AAEtD,UAAM,OAAO,qBAAqB,QAAQ;AAE1C,UAAM,eAAe,qBAAqB,EAAE,MAAM,UAAU;AAC5D,UAAM,UAAwB,wBAAwB,WAAW;AACjE,UAAM,WAAW,YAAY,IAAI;AAEjC,UAAM,CAAC,OAAO,QAAQ,IAAI,gBAA+B;AAAA,MACvD,OAAO;AAAA,MACP,cAAc,gBAAgB;AAAA,MAC9B,UAAU,WAAW,CAAC,SAAS,SAAS,QAAQ,EAAE,IAAI;AAAA,IAAA,CACvD;AACD,UAAM,qBAAqB,CAAC,MAAc,SAAS,CAAC;AACpD,UAAM,YAAY,aAAa,SAAS,iBAAiB;AACzD,UAAM,gBAAgB,YAAY;AAClC,UAAM,YAAY,MAAM,OAAiC,IAAI;AAC7D,UAAM,eAAe,MAAM,YAAY,CAAC,OAAiC;AACvE,gBAAU,UAAU;AACpB,UAAI,OAAO,QAAQ,WAAY,KAAI,EAAE;AAAA,eAC5B,IAAM,KAAyD,UAAU;AAAA,IACpF,GAAG,CAAC,GAAG,CAAC;AAER,QAAI,iBAAiB,QAAQ;AAC3B,aAAO,oBAAC,iBAAA,EAAgB,MAAM,cAAc,SAAkB,MAAY,SAAkB,OAAc,SAAkB,WAAW,WAAW,WAAsB,aAA0B,oBAAwC;AAAA,IAC5O;AAEA,UAAM,WACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,IAAI,WAAU,qCAAU;AAAA,QACxB,OAAO,SAAS;AAAA,QAChB,UAAU,CAAC,MAAM,mBAAmB,EAAE,OAAO,KAAK;AAAA,QAClD;AAAA,QACA,gBAAc,SAAS;AAAA,QACvB,kBAAe,qCAAU,aAAY;AAAA,QACrC,oBAAkB,wBAAuB,qCAAU;AAAA,QACnD,qBAAmB,yBAAyB,QAAQ,qCAAU,UAAU;AAAA,QACxE,WAAW,GAAG,iBAAiB,kCAAkC,CAAC,SAAS,iBAAiB,CAAC,iBAAiB,SAAS,8CAA8C;AAAA,QACpK,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,mCAAgB,UAAA,EAAO,OAAM,IAAG,UAAQ,MAAE,UAAA,aAAY;AAAA,UAEtD,QAAQ,IAAI,CAAA,QAAO,oBAAC,YAAuB,OAAO,IAAI,OAAO,UAAU,IAAI,UAAW,UAAA,IAAI,MAAA,GAA1D,IAAI,KAA4D,CAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAI9G,UAAM,UAAU,YACd,oBAAC,mBAAA,EAAkB,MAAM,QAAQ,MAAM,SAAS,MAAM,mBAAmB,EAAE,EAAA,CAAG,IAC5E;AAEJ,UAAM,YACJ,oBAAC,YAAA,EAAW,WAAU,qCACpB,UAAA,oBAAC,aAAA,EAAY,MAAM,UAAU,WAAU,iBAAgB,eAAW,MAAC,GACrE;AAEF,UAAM,cAAc,mCAAS,KAAK,CAAA,MAAK,EAAE,UAAU;AACnD,UAAM,SAAQ,2CAAa,UAAS;AACpC,UAAM,mBAAmB,2CAAa;AACtC,UAAM,kBAAkB,2CAAa;AAErC,QAAI,CAAC,eAAe;AAClB,aACE;AAAA,QAAC;AAAA,QAAA;AAAA,UAAI,WAAW;AAAA,YAAG,mBAAmB,EAAE,MAAM,QAAQ,SAAkB,MAAM,OAAO;AAAA,YAAG,SAAS,WAAW,IAAI;AAAA,YAAG;AAAA,YACjH;AAAA,UAAA;AAAA,UACA,OAAO,EAAE,cAAc,kBAAA;AAAA,UAAqB,mBAAgB;AAAA,UAAO,cAAY,QAAQ,KAAK;AAAA,UAC3F,UAAA;AAAA,YAAA,QAAQ,oBAAC,KAAA,EAAI,MAAY,OAAO,kBAAkB,WAAU,8CAA8C,UAAA,MAAA,CAAM,IAAS,oBAAC,QAAA,EAAK,WAAU,iBAAiB,yBAAe,SAAQ;AAAA,YACjL;AAAA,YACD,oBAAC,QAAA,EAAK,WAAU,SAAA,CAAS;AAAA,YACxB;AAAA,YACA;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAGP;AAEA,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QAAI,WAAW;AAAA,UAAG,mBAAmB,EAAE,MAAM,QAAQ,SAAkB,MAAM,OAAO;AAAA,UACnF;AAAA,QAAA;AAAA,QACA,mBAAgB;AAAA,QAAO,cAAY,QAAQ,KAAK;AAAA,QAC/C,UAAA;AAAA,UAAA,aAAa,oBAAC,YAAA,EAAW,UAAA,oBAAC,WAAA,EAAU,MAAM,UAAU,WAAU,qCAAoC,eAAW,KAAA,CAAC,EAAA,CAAE;AAAA,UAChH,CAAC,aAAa,mBAAmB,6BAAU,YAAA,EAAW,UAAA,oBAAC,iBAAA,EAAgB,MAAM,UAAU,WAAU,uBAAsB,eAAW,MAAC,GAAE;AAAA,UACrI;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,aAAa,cAAc;AAK3B,MAAM,eAAe,MAAM;AAAA,EACzB,CAAC,EAAE,MAAM,SAAS,aAAa,OAAO,YAAY,OAAO,MAAM,UAAU,SAAS,QAAQ,OAAO,WAAW,cAAc,UAAU,aAAa,WAAW,UAAU,cAAc,YAAY,OAAO,UAAU,SAAS,WAAW,WAAW,aAAa,OAAO,SAAS,SAAS,WAAW,cAAc,OAAO,cAAc,sBAAsB,oBAAoB,IAAI,QAAQ,oBAAoB,qBAAqB,qBAAqB,sBAAsB,cAAc,UAAA,GAAa,QAAQ;AAC/e,UAAM,WAAW,gBAAA;AACjB,UAAM,QAAQ,wBAAwB,SAAS;AAC/C,UAAM,WAAW,yBAAyB,YAAY;AAEtD,UAAM,OAAO,qBAAqB,QAAQ;AAE1C,UAAM,eAAe,qBAAqB,EAAE,MAAM,UAAU;AAC5D,UAAM,UAAwB,wBAAwB,WAAW;AACjE,UAAM,WAAW,YAAY,IAAI;AAIjC,UAAM,CAAC,OAAO,QAAQ,IAAI,gBAA+B;AAAA,MACvD,OAAO;AAAA,MACP,cAAc,gBAAgB;AAAA,MAC9B,UAAU,WAAW,CAAC,SAAS,SAAS,QAAQ,EAAE,IAAI;AAAA,IAAA,CACvD;AACD,UAAM,YAAY,aAAa,SAAS,iBAAiB;AACzD,UAAM,gBAAgB,YAAY;AAElC,UAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,WAAW;AAClD,UAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,EAAE;AAC7C,UAAM,WAAW,MAAM,OAAyB,IAAI;AAGpD,UAAM,YAAY,MAAM,MAAA;AAGxB,UAAM,iBAAiB,oBAAoB,WAAW,IAAI;AAG1D,UAAM,UAAU,MAAM;AAAE,UAAI,CAAC,KAAM,WAAU,EAAE;AAAA,IAAE,GAAG,CAAC,IAAI,CAAC;AAM1D,UAAM,cAAc,mCAAS,KAAK,CAAA,MAAK,EAAE,UAAU;AAKnD,UAAM,iBAAgB,2CAAa,UAAS,SAAS;AACrD,UAAM,eAAe,2CAAa;AAElC,UAAM,kBAAkB,cAAc,SAClC,QAAQ,OAAO,CAAA,MAAK,EAAE,MAAM,YAAA,EAAc,SAAS,OAAO,YAAA,CAAa,CAAC,IACxE;AAGJ,UAAM,cAAkC,MAAM;AAAA,MAC5C,MAAM,gBAAgB,IAAI,CAAA,SAAQ;AAAA,QAChC,OAAO,IAAI;AAAA,QACX,OAAO,IAAI;AAAA,QACX,MAAM,gBAAgB,IAAI,OAAO;AAAA,QACjC,QAAQ,IAAI;AAAA,QACZ,aAAa,IAAI;AAAA,QACjB,UAAU,IAAI;AAAA,QACd,OAAO,IAAI;AAAA,MAAA,EACX;AAAA,MACF,CAAC,iBAAiB,aAAa;AAAA,IAAA;AAGjC,UAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAI,cAAe,QAAO;AAC1B,aAAO,CAAC,YAA8B;AACpC,cAAM,SAAS,QAAQ,KAAK,OAAK,EAAE,UAAU,QAAQ,KAAK;AAC1D,YAAI,iCAAQ,YAAY;AACtB,qCAAQ,KAAA,EAAI,MAAY,OAAO,OAAO,YAAgE,kBAAQ,OAAM;AAAA,QACtH;AACA,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF,GAAG,CAAC,eAAe,SAAS,IAAI,CAAC;AAKjC,UAAM,oBAAoB,MAAM;AAAA,MAC9B,CAAC,aAAgC;AAC/B,iBAAS,MAAM,QAAQ,QAAQ,IAAI,SAAS,CAAC,IAAI,QAAQ;AAAA,MAC3D;AAAA,MACA,CAAC,QAAQ;AAAA,IAAA;AAIX,QAAI,iBAAiB,QAAQ;AAC3B,aAAO,oBAAC,iBAAA,EAAgB,MAAM,cAAc,SAAkB,MAAY,SAAkB,OAAc,SAAkB,WAAW,WAAW,WAAsB,aAA0B,oBAAwC;AAAA,IAC5O;AAGA,UAAM,UAAU,YACd,oBAAC,mBAAA,EAAkB,MAAM,QAAQ,MAAM,SAAS,MAAM,SAAS,EAAE,GAAG,iBAAe,MAAC,IAClF;AAEJ,UAAM,YACJ,oBAAC,YAAA,EACC,UAAA,oBAAC,eAAY,MAAM,UAAU,WAAW,GAAG,sCAAsC,QAAQ,YAAY,GAAG,eAAW,MAAC,GACtH;AAGF,UAAM,iBACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB;AAAA,QACA,SAAS,qCAAU;AAAA,QACnB;AAAA,MAAA;AAAA,IAAA;AAMJ,UAAM,UACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,IAAI,WAAU,qCAAU;AAAA,QACxB,MAAK;AAAA,QACL,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd,iBAAe;AAAA,QACf,cAAY;AAAA,QAGZ,mBAAiB,YAAY,SAAY,qCAAU;AAAA,QACnD,gBAAc,SAAS;AAAA,QACvB,kBAAe,qCAAU,aAAY;AAAA,QACrC,oBAAkB,wBAAuB,qCAAU;AAAA,QACnD,qBAAmB,yBAAyB,QAAQ,qCAAU,UAAU;AAAA,QACxE,UAAU;AAAA,QACV,WAAW;AAAA,UACT,mBAAmB,EAAE,MAAM,QAAQ,SAAkB,MAAM,OAAO;AAAA,UAClE,CAAC,iBAAiB,SAAS,CAAC,cAAc,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA,UAIzD;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO,CAAC,gBAAgB,EAAE,cAAc,sBAAsB;AAAA,QAC9D,mBAAgB;AAAA,QAChB,cAAY,QAAQ,KAAK;AAAA,QACzB,WAAW,CAAC,MAAM;AAGhB,cAAI,QAAQ,oBAAoB,WAAW,CAAC,EAAG;AAC/C,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAItC,gBAAI,CAAC,MAAM;AAAE,gBAAE,eAAA;AAAkB,sBAAQ,IAAI;AAAA,YAAE;AAAA,UACjD;AAEA,cAAI,EAAE,QAAQ,eAAe,CAAC,MAAM;AAAE,cAAE,eAAA;AAAkB,oBAAQ,IAAI;AAAA,UAAE;AACxE,cAAI,EAAE,QAAQ,SAAU,SAAQ,KAAK;AAAA,QACvC;AAAA,QAEC,UAAA;AAAA,UAAA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAIL,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT;AAAA,QACA,OAAO,SAAS;AAAA,QAChB,eAAe;AAAA,QACf,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,CAAC,MAAM;AAAE,kBAAQ,CAAC;AAAG,uDAAe;AAAA,QAAG;AAAA,QACrD,WAAW;AAAA,QACX;AAAA,QACA,iBAAiB,aAAa,CAAC,MAAM;;AAAE,YAAE,eAAA;AAAkB,yBAAS,YAAT,mBAAkB;AAAA,QAAQ,IAAI;AAAA,QAExF,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,aAAa,cAAc;AAI3B,MAAM,SAAS,MAAM;AAAA,EACnB,CAAC,OAAO,QAAQ;AACd,UAAM,WAAW,iBAAA;AAEjB,QAAI,UAAU;AACZ,aAAO,oBAAC,cAAA,EAAa,KAA2C,GAAG,MAAA,CAAO;AAAA,IAC5E;AAEA,WAAO,oBAAC,cAAA,EAAa,KAAwC,GAAG,MAAA,CAAO;AAAA,EACzE;AACF;AACA,OAAO,cAAc;AAId,MAAM,aAAa;AAAA,EACxB,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,UAAU,CAAA;AAAA,EAGV,OAAO,CAAA;AAAA;AAAA,EAIP,QAAQ,CAAC,WAAW,SAAS,iBAAiB,UAAU;AAAA,EACxD,QAAQ;AAAA,IACN,IAAI,CAAA;AAAA,IACJ,IAAI,CAAC,oBAAoB,eAAe;AAAA,IACxC,MAAM,CAAA;AAAA,EAAC;AAEX;"}
@@ -1,6 +1,8 @@
1
- import { SelectMenu, selectMenuMeta } from "./select-menu.js";
1
+ import { SelectMenu, forwardKeyToListbox, selectMenuMeta, useActiveDescendant } from "./select-menu.js";
2
2
  export {
3
3
  SelectMenu,
4
- selectMenuMeta
4
+ forwardKeyToListbox,
5
+ selectMenuMeta,
6
+ useActiveDescendant
5
7
  };
6
8
  //# sourceMappingURL=index.js.map
@@ -59,10 +59,13 @@ export interface SelectMenuProps {
59
59
  searchPlaceholder?: string;
60
60
  /** 空選項提示 */
61
61
  emptyText?: string;
62
- /** Loading 狀態(2026-05-15 audit B fix per user verbatim「dropdown 隨時可開,讀取在 panel 中間 CircularProgress」)
63
- * true → render `<Empty icon={<CircularProgress size={48}/>} className="py-6" />` 取代 options(純 spinner,無 description);
64
- * trigger 不變,user 隨時可開 dropdown。對齊 MUI Autocomplete loading dropdown-body + Ant Select
65
- * loading idiom + DS 既有 `empty.spec.md:191` 「全頁 loading = Empty + CircularProgress compose」SSOT。
62
+ /** 多選 footer 全選列文字(2026-07-05 D4:原「全部」字面 hardcode,無法覆寫也無法 i18n) */
63
+ selectAllLabel?: string;
64
+ /** Loading 狀態(2026-05-15 audit B fix;2026-07-04 Q3 拍板措辭修訂)
65
+ * true 無可顯示選項時 empty slot(cmdk CommandEmpty)渲 `<Empty icon={<CircularProgress size={48}/>} className="py-6" />`
66
+ * (純 spinner,無 description);已有 options 時保留顯示不清空(MUI Autocomplete「only if there are
67
+ * no suggestions」共識)。trigger 不變,user 隨時可開 dropdown。DS `empty.spec.md`「loading = Empty +
68
+ * CircularProgress compose」SSOT。
66
69
  */
67
70
  loading?: boolean;
68
71
  /** 尺寸 */
@@ -97,12 +100,34 @@ export declare const selectMenuMeta: {
97
100
  readonly family: 4;
98
101
  readonly variants: {};
99
102
  readonly sizes: {};
100
- readonly states: readonly ["default", "hover", "active", "focus-visible", "disabled"];
103
+ readonly states: readonly ["default", "hover", "active", "selected", "focus-visible", "disabled"];
101
104
  readonly tokens: {
102
- readonly bg: readonly ["bg-surface-raised", "bg-transparent"];
105
+ readonly bg: readonly ["bg-neutral-selected", "bg-neutral-selected-active", "bg-surface-raised", "bg-transparent"];
103
106
  readonly fg: readonly ["text-fg-muted"];
104
107
  readonly ring: readonly [];
105
108
  };
106
109
  };
110
+ /**
111
+ * 2026-07-05 D4 P0 修(searchable 鍵盤死路):trigger 內的裸 <input> 與 portal 內的 cmdk root
112
+ * 在不同 DOM 子樹 — 鍵盤事件永遠 bubble 不到 cmdk 的 ArrowUp/Down/Enter handler([cmdk-root]
113
+ * onKeyDown)→ searchable Select / PeoplePicker single / Combobox searchIn='trigger' 開啟後
114
+ * 只能 Esc。修法 = APG combobox-with-list:trigger input 把三鍵 re-dispatch 給 cmdk root
115
+ * (native KeyboardEvent bubbles 經 React root delegation 觸發 cmdk synthetic handler)。
116
+ * Home/End 刻意不轉送(文字輸入的 caret 語意優先,對齊 MUI/Ant Autocomplete)。
117
+ * aria-activedescendant 綁回 trigger input → 見下方 useActiveDescendant(2026-07-05 D4 補齊)。
118
+ */
119
+ export declare function forwardKeyToListbox(contentId: string | undefined, e: React.KeyboardEvent): boolean;
120
+ /**
121
+ * 2026-07-05 D4 補齊(APG combobox aria-activedescendant):追蹤 cmdk 目前 virtual-focus item
122
+ * 的 DOM id,供 trigger 端搜尋 input 綁 `aria-activedescendant` —— SR 才會在方向鍵導覽 /
123
+ * 打字過濾時播報 active option 名。機制:trigger 與 portal 內 cmdk 分屬不同 DOM 子樹,cmdk
124
+ * 只把 active id 綁在自己的 Command.Input / List(cmdk source:item 自帶 auto-generated id +
125
+ * `data-selected="true"` 標記 virtual focus)→ trigger 端用 MutationObserver 監聽 popover 容器
126
+ * (contentId = PopoverContent id)內 `data-selected` 屬性變化 + childList(打字過濾 re-render
127
+ * 換 item 節點),單一機制涵蓋全部更新路徑:開啟初始 auto-highlight / forwardKeyToListbox
128
+ * 方向鍵轉送 / 搜尋過濾後 cmdk 自動移 cursor / pointer hover。
129
+ * 關閉時清 undefined —— ARIA 要求 id 必指向存在於 DOM 的節點,不可留 stale id。
130
+ */
131
+ export declare function useActiveDescendant(contentId: string | undefined, open: boolean): string | undefined;
107
132
  export { SelectMenu };
108
133
  //# sourceMappingURL=select-menu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"select-menu.d.ts","sourceRoot":"","sources":["../../../src/components/SelectMenu/select-menu.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAG9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AAa1E;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,KAAK,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAIjC,MAAM,WAAW,eAAe;IAC9B,WAAW;IACX,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,gCAAgC;IAChC,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAEhC,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IAChC,mBAAmB;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAA;IAElD,WAAW;IACX,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY;IACZ,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAEvC,oBAAoB;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,sBAAsB;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,SAAS;IACT,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW;IACX,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,iBAAiB;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sGAAsG;IACtG,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yBAAyB;IACzB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAEtC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAA;IAC3D,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IAEpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,QAAA,MAAM,UAAU,qFA6Sd,CAAA;AAMF,eAAO,MAAM,cAAc;;;;;;;;;;;CAejB,CAAA;AAEV,OAAO,EAAE,UAAU,EAAE,CAAA"}
1
+ {"version":3,"file":"select-menu.d.ts","sourceRoot":"","sources":["../../../src/components/SelectMenu/select-menu.tsx"],"names":[],"mappings":"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"}