@qijenchen/design-system 0.1.0-beta.10

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 (507) hide show
  1. package/README.md +163 -0
  2. package/dist/components/Accordion/accordion.d.ts +37 -0
  3. package/dist/components/Accordion/accordion.d.ts.map +1 -0
  4. package/dist/components/Accordion/accordion.js +78 -0
  5. package/dist/components/Accordion/accordion.js.map +1 -0
  6. package/dist/components/Alert/alert.d.ts +47 -0
  7. package/dist/components/Alert/alert.d.ts.map +1 -0
  8. package/dist/components/Alert/alert.js +132 -0
  9. package/dist/components/Alert/alert.js.map +1 -0
  10. package/dist/components/AppShell/_demo-helpers.d.ts +49 -0
  11. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -0
  12. package/dist/components/AppShell/app-shell.d.ts +76 -0
  13. package/dist/components/AppShell/app-shell.d.ts.map +1 -0
  14. package/dist/components/AppShell/app-shell.js +214 -0
  15. package/dist/components/AppShell/app-shell.js.map +1 -0
  16. package/dist/components/AspectRatio/aspect-ratio.d.ts +40 -0
  17. package/dist/components/AspectRatio/aspect-ratio.d.ts.map +1 -0
  18. package/dist/components/AspectRatio/aspect-ratio.js +23 -0
  19. package/dist/components/AspectRatio/aspect-ratio.js.map +1 -0
  20. package/dist/components/Avatar/avatar.d.ts +85 -0
  21. package/dist/components/Avatar/avatar.d.ts.map +1 -0
  22. package/dist/components/Avatar/avatar.js +195 -0
  23. package/dist/components/Avatar/avatar.js.map +1 -0
  24. package/dist/components/Badge/badge.d.ts +43 -0
  25. package/dist/components/Badge/badge.d.ts.map +1 -0
  26. package/dist/components/Badge/badge.js +69 -0
  27. package/dist/components/Badge/badge.js.map +1 -0
  28. package/dist/components/Breadcrumb/breadcrumb.d.ts +163 -0
  29. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -0
  30. package/dist/components/Breadcrumb/breadcrumb.js +300 -0
  31. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -0
  32. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +46 -0
  33. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -0
  34. package/dist/components/BulkActionBar/bulk-action-bar.js +78 -0
  35. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -0
  36. package/dist/components/Button/button-group.d.ts +49 -0
  37. package/dist/components/Button/button-group.d.ts.map +1 -0
  38. package/dist/components/Button/button-group.js +46 -0
  39. package/dist/components/Button/button-group.js.map +1 -0
  40. package/dist/components/Button/button.d.ts +203 -0
  41. package/dist/components/Button/button.d.ts.map +1 -0
  42. package/dist/components/Button/button.js +309 -0
  43. package/dist/components/Button/button.js.map +1 -0
  44. package/dist/components/Calendar/calendar.d.ts +81 -0
  45. package/dist/components/Calendar/calendar.d.ts.map +1 -0
  46. package/dist/components/Calendar/calendar.js +282 -0
  47. package/dist/components/Calendar/calendar.js.map +1 -0
  48. package/dist/components/Carousel/carousel.d.ts +61 -0
  49. package/dist/components/Carousel/carousel.d.ts.map +1 -0
  50. package/dist/components/Carousel/carousel.js +276 -0
  51. package/dist/components/Carousel/carousel.js.map +1 -0
  52. package/dist/components/Chart/chart.d.ts +94 -0
  53. package/dist/components/Chart/chart.d.ts.map +1 -0
  54. package/dist/components/Chart/chart.js +233 -0
  55. package/dist/components/Chart/chart.js.map +1 -0
  56. package/dist/components/Checkbox/checkbox-group.d.ts +58 -0
  57. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -0
  58. package/dist/components/Checkbox/checkbox-group.js +28 -0
  59. package/dist/components/Checkbox/checkbox-group.js.map +1 -0
  60. package/dist/components/Checkbox/checkbox.d.ts +73 -0
  61. package/dist/components/Checkbox/checkbox.d.ts.map +1 -0
  62. package/dist/components/Checkbox/checkbox.js +125 -0
  63. package/dist/components/Checkbox/checkbox.js.map +1 -0
  64. package/dist/components/Chip/chip.d.ts +54 -0
  65. package/dist/components/Chip/chip.d.ts.map +1 -0
  66. package/dist/components/Chip/chip.js +224 -0
  67. package/dist/components/Chip/chip.js.map +1 -0
  68. package/dist/components/CircularProgress/circular-progress.d.ts +40 -0
  69. package/dist/components/CircularProgress/circular-progress.d.ts.map +1 -0
  70. package/dist/components/CircularProgress/circular-progress.js +118 -0
  71. package/dist/components/CircularProgress/circular-progress.js.map +1 -0
  72. package/dist/components/Coachmark/coachmark.d.ts +100 -0
  73. package/dist/components/Coachmark/coachmark.d.ts.map +1 -0
  74. package/dist/components/Coachmark/coachmark.js +107 -0
  75. package/dist/components/Coachmark/coachmark.js.map +1 -0
  76. package/dist/components/Combobox/combobox.d.ts +150 -0
  77. package/dist/components/Combobox/combobox.d.ts.map +1 -0
  78. package/dist/components/Combobox/combobox.js +595 -0
  79. package/dist/components/Combobox/combobox.js.map +1 -0
  80. package/dist/components/Command/command.d.ts +106 -0
  81. package/dist/components/Command/command.d.ts.map +1 -0
  82. package/dist/components/Command/command.js +123 -0
  83. package/dist/components/Command/command.js.map +1 -0
  84. package/dist/components/DataTable/active-editor-controller.d.ts +66 -0
  85. package/dist/components/DataTable/active-editor-controller.d.ts.map +1 -0
  86. package/dist/components/DataTable/cell-registry.d.ts +37 -0
  87. package/dist/components/DataTable/cell-registry.d.ts.map +1 -0
  88. package/dist/components/DataTable/cell-registry.js +377 -0
  89. package/dist/components/DataTable/cell-registry.js.map +1 -0
  90. package/dist/components/DataTable/column-types.d.ts +145 -0
  91. package/dist/components/DataTable/column-types.d.ts.map +1 -0
  92. package/dist/components/DataTable/column-types.js +17 -0
  93. package/dist/components/DataTable/column-types.js.map +1 -0
  94. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +49 -0
  95. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -0
  96. package/dist/components/DataTable/data-table-filter-panel.d.ts +30 -0
  97. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -0
  98. package/dist/components/DataTable/data-table-interaction-layer.d.ts +78 -0
  99. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -0
  100. package/dist/components/DataTable/data-table-interaction-layer.js +220 -0
  101. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -0
  102. package/dist/components/DataTable/data-table-sort-manager.d.ts +19 -0
  103. package/dist/components/DataTable/data-table-sort-manager.d.ts.map +1 -0
  104. package/dist/components/DataTable/data-table.d.ts +181 -0
  105. package/dist/components/DataTable/data-table.d.ts.map +1 -0
  106. package/dist/components/DataTable/data-table.js +1851 -0
  107. package/dist/components/DataTable/data-table.js.map +1 -0
  108. package/dist/components/DataTable/filter-operators.d.ts +116 -0
  109. package/dist/components/DataTable/filter-operators.d.ts.map +1 -0
  110. package/dist/components/DataTable/filter-tree.d.ts +66 -0
  111. package/dist/components/DataTable/filter-tree.d.ts.map +1 -0
  112. package/dist/components/DataTable/lib/column-meta.d.ts +49 -0
  113. package/dist/components/DataTable/lib/column-meta.d.ts.map +1 -0
  114. package/dist/components/DateGrid/date-grid.d.ts +61 -0
  115. package/dist/components/DateGrid/date-grid.d.ts.map +1 -0
  116. package/dist/components/DateGrid/date-grid.js +168 -0
  117. package/dist/components/DateGrid/date-grid.js.map +1 -0
  118. package/dist/components/DatePicker/date-picker.d.ts +119 -0
  119. package/dist/components/DatePicker/date-picker.d.ts.map +1 -0
  120. package/dist/components/DatePicker/date-picker.js +743 -0
  121. package/dist/components/DatePicker/date-picker.js.map +1 -0
  122. package/dist/components/DescriptionList/description-list.d.ts +60 -0
  123. package/dist/components/DescriptionList/description-list.d.ts.map +1 -0
  124. package/dist/components/DescriptionList/description-list.js +77 -0
  125. package/dist/components/DescriptionList/description-list.js.map +1 -0
  126. package/dist/components/Dialog/dialog.d.ts +54 -0
  127. package/dist/components/Dialog/dialog.d.ts.map +1 -0
  128. package/dist/components/Dialog/dialog.js +151 -0
  129. package/dist/components/Dialog/dialog.js.map +1 -0
  130. package/dist/components/DropdownMenu/dropdown-menu.d.ts +111 -0
  131. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -0
  132. package/dist/components/DropdownMenu/dropdown-menu.js +288 -0
  133. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -0
  134. package/dist/components/Empty/empty.d.ts +40 -0
  135. package/dist/components/Empty/empty.d.ts.map +1 -0
  136. package/dist/components/Empty/empty.js +66 -0
  137. package/dist/components/Empty/empty.js.map +1 -0
  138. package/dist/components/Field/field-context.d.ts +77 -0
  139. package/dist/components/Field/field-context.d.ts.map +1 -0
  140. package/dist/components/Field/field-context.js +37 -0
  141. package/dist/components/Field/field-context.js.map +1 -0
  142. package/dist/components/Field/field-types.d.ts +5 -0
  143. package/dist/components/Field/field-types.d.ts.map +1 -0
  144. package/dist/components/Field/field-types.js +13 -0
  145. package/dist/components/Field/field-types.js.map +1 -0
  146. package/dist/components/Field/field-wrapper.d.ts +17 -0
  147. package/dist/components/Field/field-wrapper.d.ts.map +1 -0
  148. package/dist/components/Field/field-wrapper.js +252 -0
  149. package/dist/components/Field/field-wrapper.js.map +1 -0
  150. package/dist/components/Field/field.d.ts +127 -0
  151. package/dist/components/Field/field.d.ts.map +1 -0
  152. package/dist/components/Field/field.js +295 -0
  153. package/dist/components/Field/field.js.map +1 -0
  154. package/dist/components/FieldControlGroup/field-control-group.d.ts +74 -0
  155. package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -0
  156. package/dist/components/FieldControlGroup/field-control-group.js +62 -0
  157. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -0
  158. package/dist/components/FileItem/file-item.d.ts +44 -0
  159. package/dist/components/FileItem/file-item.d.ts.map +1 -0
  160. package/dist/components/FileItem/file-item.js +202 -0
  161. package/dist/components/FileItem/file-item.js.map +1 -0
  162. package/dist/components/FileUpload/file-upload.d.ts +97 -0
  163. package/dist/components/FileUpload/file-upload.d.ts.map +1 -0
  164. package/dist/components/FileUpload/file-upload.js +231 -0
  165. package/dist/components/FileUpload/file-upload.js.map +1 -0
  166. package/dist/components/FileViewer/file-viewer-types.d.ts +73 -0
  167. package/dist/components/FileViewer/file-viewer-types.d.ts.map +1 -0
  168. package/dist/components/FileViewer/file-viewer.d.ts +82 -0
  169. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -0
  170. package/dist/components/FileViewer/file-viewer.js +752 -0
  171. package/dist/components/FileViewer/file-viewer.js.map +1 -0
  172. package/dist/components/FileViewer/image-renderer.d.ts +9 -0
  173. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -0
  174. package/dist/components/FileViewer/image-renderer.js +165 -0
  175. package/dist/components/FileViewer/image-renderer.js.map +1 -0
  176. package/dist/components/HoverCard/hover-card.d.ts +30 -0
  177. package/dist/components/HoverCard/hover-card.d.ts.map +1 -0
  178. package/dist/components/HoverCard/hover-card.js +61 -0
  179. package/dist/components/HoverCard/hover-card.js.map +1 -0
  180. package/dist/components/Input/input.d.ts +72 -0
  181. package/dist/components/Input/input.d.ts.map +1 -0
  182. package/dist/components/Input/input.js +148 -0
  183. package/dist/components/Input/input.js.map +1 -0
  184. package/dist/components/LinkInput/link-input.d.ts +46 -0
  185. package/dist/components/LinkInput/link-input.d.ts.map +1 -0
  186. package/dist/components/LinkInput/link-input.js +215 -0
  187. package/dist/components/LinkInput/link-input.js.map +1 -0
  188. package/dist/components/Menu/menu-item.d.ts +83 -0
  189. package/dist/components/Menu/menu-item.d.ts.map +1 -0
  190. package/dist/components/Menu/menu-item.js +209 -0
  191. package/dist/components/Menu/menu-item.js.map +1 -0
  192. package/dist/components/NameCard/name-card.d.ts +85 -0
  193. package/dist/components/NameCard/name-card.d.ts.map +1 -0
  194. package/dist/components/NameCard/name-card.js +153 -0
  195. package/dist/components/NameCard/name-card.js.map +1 -0
  196. package/dist/components/Notice/notice.d.ts +69 -0
  197. package/dist/components/Notice/notice.d.ts.map +1 -0
  198. package/dist/components/Notice/notice.js +121 -0
  199. package/dist/components/Notice/notice.js.map +1 -0
  200. package/dist/components/NumberInput/number-input.d.ts +57 -0
  201. package/dist/components/NumberInput/number-input.d.ts.map +1 -0
  202. package/dist/components/NumberInput/number-input.js +131 -0
  203. package/dist/components/NumberInput/number-input.js.map +1 -0
  204. package/dist/components/OverflowIndicator/overflow-indicator.d.ts +23 -0
  205. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -0
  206. package/dist/components/OverflowIndicator/overflow-indicator.js +111 -0
  207. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -0
  208. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +57 -0
  209. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts.map +1 -0
  210. package/dist/components/PeoplePicker/avatar-stack-overflow.js +35 -0
  211. package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -0
  212. package/dist/components/PeoplePicker/people-picker-helpers.d.ts +7 -0
  213. package/dist/components/PeoplePicker/people-picker-helpers.d.ts.map +1 -0
  214. package/dist/components/PeoplePicker/people-picker-helpers.js +25 -0
  215. package/dist/components/PeoplePicker/people-picker-helpers.js.map +1 -0
  216. package/dist/components/PeoplePicker/people-picker.d.ts +77 -0
  217. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -0
  218. package/dist/components/PeoplePicker/people-picker.js +263 -0
  219. package/dist/components/PeoplePicker/people-picker.js.map +1 -0
  220. package/dist/components/PeoplePicker/person-display.d.ts +66 -0
  221. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -0
  222. package/dist/components/PeoplePicker/person-display.js +203 -0
  223. package/dist/components/PeoplePicker/person-display.js.map +1 -0
  224. package/dist/components/Popover/popover.d.ts +50 -0
  225. package/dist/components/Popover/popover.d.ts.map +1 -0
  226. package/dist/components/Popover/popover.js +113 -0
  227. package/dist/components/Popover/popover.js.map +1 -0
  228. package/dist/components/ProgressBar/progress-bar.d.ts +37 -0
  229. package/dist/components/ProgressBar/progress-bar.d.ts.map +1 -0
  230. package/dist/components/ProgressBar/progress-bar.js +86 -0
  231. package/dist/components/ProgressBar/progress-bar.js.map +1 -0
  232. package/dist/components/RadioGroup/radio-group.d.ts +78 -0
  233. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -0
  234. package/dist/components/RadioGroup/radio-group.js +153 -0
  235. package/dist/components/RadioGroup/radio-group.js.map +1 -0
  236. package/dist/components/Rating/rating.d.ts +46 -0
  237. package/dist/components/Rating/rating.d.ts.map +1 -0
  238. package/dist/components/Rating/rating.js +179 -0
  239. package/dist/components/Rating/rating.js.map +1 -0
  240. package/dist/components/ScrollArea/scroll-area.d.ts +45 -0
  241. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -0
  242. package/dist/components/ScrollArea/scroll-area.js +65 -0
  243. package/dist/components/ScrollArea/scroll-area.js.map +1 -0
  244. package/dist/components/SegmentedControl/segmented-control.d.ts +102 -0
  245. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -0
  246. package/dist/components/SegmentedControl/segmented-control.js +171 -0
  247. package/dist/components/SegmentedControl/segmented-control.js.map +1 -0
  248. package/dist/components/Select/select.d.ts +102 -0
  249. package/dist/components/Select/select.d.ts.map +1 -0
  250. package/dist/components/Select/select.js +435 -0
  251. package/dist/components/Select/select.js.map +1 -0
  252. package/dist/components/SelectMenu/select-menu.d.ts +103 -0
  253. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -0
  254. package/dist/components/SelectMenu/select-menu.js +239 -0
  255. package/dist/components/SelectMenu/select-menu.js.map +1 -0
  256. package/dist/components/SelectionControl/selection-item.d.ts +69 -0
  257. package/dist/components/SelectionControl/selection-item.d.ts.map +1 -0
  258. package/dist/components/SelectionControl/selection-item.js +142 -0
  259. package/dist/components/SelectionControl/selection-item.js.map +1 -0
  260. package/dist/components/Separator/separator.d.ts +17 -0
  261. package/dist/components/Separator/separator.d.ts.map +1 -0
  262. package/dist/components/Separator/separator.js +39 -0
  263. package/dist/components/Separator/separator.js.map +1 -0
  264. package/dist/components/Sheet/sheet.d.ts +56 -0
  265. package/dist/components/Sheet/sheet.d.ts.map +1 -0
  266. package/dist/components/Sheet/sheet.js +145 -0
  267. package/dist/components/Sheet/sheet.js.map +1 -0
  268. package/dist/components/Sidebar/sidebar.d.ts +195 -0
  269. package/dist/components/Sidebar/sidebar.d.ts.map +1 -0
  270. package/dist/components/Sidebar/sidebar.js +826 -0
  271. package/dist/components/Sidebar/sidebar.js.map +1 -0
  272. package/dist/components/Skeleton/skeleton.d.ts +16 -0
  273. package/dist/components/Skeleton/skeleton.d.ts.map +1 -0
  274. package/dist/components/Skeleton/skeleton.js +30 -0
  275. package/dist/components/Skeleton/skeleton.js.map +1 -0
  276. package/dist/components/Slider/slider.d.ts +48 -0
  277. package/dist/components/Slider/slider.d.ts.map +1 -0
  278. package/dist/components/Slider/slider.js +108 -0
  279. package/dist/components/Slider/slider.js.map +1 -0
  280. package/dist/components/Steps/steps.d.ts +71 -0
  281. package/dist/components/Steps/steps.d.ts.map +1 -0
  282. package/dist/components/Steps/steps.js +583 -0
  283. package/dist/components/Steps/steps.js.map +1 -0
  284. package/dist/components/Switch/switch.d.ts +112 -0
  285. package/dist/components/Switch/switch.d.ts.map +1 -0
  286. package/dist/components/Switch/switch.js +179 -0
  287. package/dist/components/Switch/switch.js.map +1 -0
  288. package/dist/components/Tabs/tabs.d.ts +104 -0
  289. package/dist/components/Tabs/tabs.d.ts.map +1 -0
  290. package/dist/components/Tabs/tabs.js +316 -0
  291. package/dist/components/Tabs/tabs.js.map +1 -0
  292. package/dist/components/Tag/tag.d.ts +86 -0
  293. package/dist/components/Tag/tag.d.ts.map +1 -0
  294. package/dist/components/Tag/tag.js +172 -0
  295. package/dist/components/Tag/tag.js.map +1 -0
  296. package/dist/components/Textarea/textarea.d.ts +74 -0
  297. package/dist/components/Textarea/textarea.d.ts.map +1 -0
  298. package/dist/components/Textarea/textarea.js +224 -0
  299. package/dist/components/Textarea/textarea.js.map +1 -0
  300. package/dist/components/TimePicker/time-columns.d.ts +46 -0
  301. package/dist/components/TimePicker/time-columns.d.ts.map +1 -0
  302. package/dist/components/TimePicker/time-columns.js +173 -0
  303. package/dist/components/TimePicker/time-columns.js.map +1 -0
  304. package/dist/components/TimePicker/time-picker.d.ts +94 -0
  305. package/dist/components/TimePicker/time-picker.d.ts.map +1 -0
  306. package/dist/components/TimePicker/time-picker.js +253 -0
  307. package/dist/components/TimePicker/time-picker.js.map +1 -0
  308. package/dist/components/Toast/toast.d.ts +61 -0
  309. package/dist/components/Toast/toast.d.ts.map +1 -0
  310. package/dist/components/Toast/toast.js +76 -0
  311. package/dist/components/Toast/toast.js.map +1 -0
  312. package/dist/components/Tooltip/tooltip.d.ts +20 -0
  313. package/dist/components/Tooltip/tooltip.d.ts.map +1 -0
  314. package/dist/components/Tooltip/tooltip.js +53 -0
  315. package/dist/components/Tooltip/tooltip.js.map +1 -0
  316. package/dist/components/TreeView/tree-view.d.ts +166 -0
  317. package/dist/components/TreeView/tree-view.d.ts.map +1 -0
  318. package/dist/components/TreeView/tree-view.js +617 -0
  319. package/dist/components/TreeView/tree-view.js.map +1 -0
  320. package/dist/hooks/use-controllable.d.ts +16 -0
  321. package/dist/hooks/use-controllable.d.ts.map +1 -0
  322. package/dist/hooks/use-controllable.js +26 -0
  323. package/dist/hooks/use-controllable.js.map +1 -0
  324. package/dist/hooks/use-is-narrow-viewport.d.ts +2 -0
  325. package/dist/hooks/use-is-narrow-viewport.d.ts.map +1 -0
  326. package/dist/hooks/use-is-narrow-viewport.js +19 -0
  327. package/dist/hooks/use-is-narrow-viewport.js.map +1 -0
  328. package/dist/hooks/use-is-touch-device.d.ts +8 -0
  329. package/dist/hooks/use-is-touch-device.d.ts.map +1 -0
  330. package/dist/hooks/use-is-touch-device.js +16 -0
  331. package/dist/hooks/use-is-touch-device.js.map +1 -0
  332. package/dist/hooks/use-overflow-items.d.ts +124 -0
  333. package/dist/hooks/use-overflow-items.d.ts.map +1 -0
  334. package/dist/hooks/use-overflow-items.js +97 -0
  335. package/dist/hooks/use-overflow-items.js.map +1 -0
  336. package/dist/index.d.ts +74 -0
  337. package/dist/index.d.ts.map +1 -0
  338. package/dist/index.js +371 -0
  339. package/dist/index.js.map +1 -0
  340. package/dist/lib/drag-visual.d.ts +158 -0
  341. package/dist/lib/drag-visual.d.ts.map +1 -0
  342. package/dist/lib/drag-visual.js +96 -0
  343. package/dist/lib/drag-visual.js.map +1 -0
  344. package/dist/lib/i18n/i18n-context.d.ts +105 -0
  345. package/dist/lib/i18n/i18n-context.d.ts.map +1 -0
  346. package/dist/lib/multi-select-ordering.d.ts +54 -0
  347. package/dist/lib/multi-select-ordering.d.ts.map +1 -0
  348. package/dist/lib/multi-select-ordering.js +13 -0
  349. package/dist/lib/multi-select-ordering.js.map +1 -0
  350. package/dist/lib/utils.d.ts +12 -0
  351. package/dist/lib/utils.d.ts.map +1 -0
  352. package/dist/lib/utils.js +79 -0
  353. package/dist/lib/utils.js.map +1 -0
  354. package/dist/patterns/element-anatomy/item-anatomy.d.ts +370 -0
  355. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -0
  356. package/dist/patterns/element-anatomy/item-anatomy.js +272 -0
  357. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -0
  358. package/dist/patterns/header-canonical/chrome-header.d.ts +80 -0
  359. package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -0
  360. package/dist/patterns/header-canonical/chrome-header.js +75 -0
  361. package/dist/patterns/header-canonical/chrome-header.js.map +1 -0
  362. package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts +101 -0
  363. package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts.map +1 -0
  364. package/dist/patterns/horizontal-overflow/horizontal-overflow.js +105 -0
  365. package/dist/patterns/horizontal-overflow/horizontal-overflow.js.map +1 -0
  366. package/dist/patterns/overlay-surface/overlay-surface.d.ts +28 -0
  367. package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -0
  368. package/dist/patterns/overlay-surface/overlay-surface.js +85 -0
  369. package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -0
  370. package/dist/patterns/resize-handle/resize-handle.d.ts +102 -0
  371. package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -0
  372. package/dist/patterns/resize-handle/resize-handle.js +74 -0
  373. package/dist/patterns/resize-handle/resize-handle.js.map +1 -0
  374. package/dist/react-day-picker.css +457 -0
  375. package/dist/stories-helpers/anatomy/anatomy-utils.d.ts +40 -0
  376. package/dist/stories-helpers/anatomy/anatomy-utils.d.ts.map +1 -0
  377. package/dist/tokens/elevation/overlay-geometry.d.ts +12 -0
  378. package/dist/tokens/elevation/overlay-geometry.d.ts.map +1 -0
  379. package/dist/tokens/elevation/overlay-geometry.js +7 -0
  380. package/dist/tokens/elevation/overlay-geometry.js.map +1 -0
  381. package/dist/tokens/motion/motion.d.ts +15 -0
  382. package/dist/tokens/motion/motion.d.ts.map +1 -0
  383. package/dist/tokens/motion/motion.js +9 -0
  384. package/dist/tokens/motion/motion.js.map +1 -0
  385. package/dist/tokens/uiSize/icon-size.d.ts +53 -0
  386. package/dist/tokens/uiSize/icon-size.d.ts.map +1 -0
  387. package/package.json +92 -0
  388. package/src/README.md +32 -0
  389. package/src/components/Accordion/accordion.tsx +104 -0
  390. package/src/components/Alert/alert.tsx +188 -0
  391. package/src/components/AppShell/_demo-helpers.tsx +198 -0
  392. package/src/components/AppShell/app-shell.tsx +364 -0
  393. package/src/components/AspectRatio/aspect-ratio.tsx +58 -0
  394. package/src/components/Avatar/avatar.tsx +368 -0
  395. package/src/components/Badge/badge.tsx +104 -0
  396. package/src/components/Breadcrumb/breadcrumb.tsx +619 -0
  397. package/src/components/BulkActionBar/bulk-action-bar.tsx +156 -0
  398. package/src/components/Button/button-group.tsx +96 -0
  399. package/src/components/Button/button.tsx +539 -0
  400. package/src/components/Calendar/calendar.tsx +411 -0
  401. package/src/components/Carousel/carousel.tsx +371 -0
  402. package/src/components/Chart/chart.tsx +376 -0
  403. package/src/components/Checkbox/checkbox-group.tsx +94 -0
  404. package/src/components/Checkbox/checkbox.tsx +237 -0
  405. package/src/components/Chip/chip.tsx +359 -0
  406. package/src/components/CircularProgress/circular-progress.tsx +204 -0
  407. package/src/components/Coachmark/coachmark.tsx +255 -0
  408. package/src/components/Combobox/combobox.tsx +826 -0
  409. package/src/components/Command/command.tsx +187 -0
  410. package/src/components/DataTable/active-editor-controller.ts +72 -0
  411. package/src/components/DataTable/cell-registry.tsx +520 -0
  412. package/src/components/DataTable/column-types.ts +180 -0
  413. package/src/components/DataTable/data-table-column-visibility-panel.tsx +261 -0
  414. package/src/components/DataTable/data-table-filter-panel.tsx +813 -0
  415. package/src/components/DataTable/data-table-interaction-layer.tsx +483 -0
  416. package/src/components/DataTable/data-table-sort-manager.tsx +210 -0
  417. package/src/components/DataTable/data-table.css +165 -0
  418. package/src/components/DataTable/data-table.tsx +2924 -0
  419. package/src/components/DataTable/filter-operators.ts +225 -0
  420. package/src/components/DataTable/filter-tree.ts +313 -0
  421. package/src/components/DataTable/lib/column-meta.ts +79 -0
  422. package/src/components/DateGrid/date-grid.tsx +209 -0
  423. package/src/components/DatePicker/date-picker.tsx +1114 -0
  424. package/src/components/DescriptionList/description-list.tsx +141 -0
  425. package/src/components/Dialog/dialog.tsx +267 -0
  426. package/src/components/DropdownMenu/dropdown-menu.tsx +475 -0
  427. package/src/components/Empty/empty.tsx +108 -0
  428. package/src/components/Field/field-context.ts +136 -0
  429. package/src/components/Field/field-types.ts +52 -0
  430. package/src/components/Field/field-wrapper.tsx +348 -0
  431. package/src/components/Field/field.tsx +535 -0
  432. package/src/components/FieldControlGroup/field-control-group.tsx +136 -0
  433. package/src/components/FileItem/file-item.tsx +322 -0
  434. package/src/components/FileUpload/file-upload.tsx +326 -0
  435. package/src/components/FileViewer/file-viewer-types.ts +76 -0
  436. package/src/components/FileViewer/file-viewer.tsx +1065 -0
  437. package/src/components/FileViewer/image-renderer.tsx +256 -0
  438. package/src/components/HoverCard/hover-card.tsx +79 -0
  439. package/src/components/Input/input.tsx +233 -0
  440. package/src/components/LinkInput/link-input.tsx +304 -0
  441. package/src/components/Menu/menu-item.tsx +334 -0
  442. package/src/components/NameCard/name-card.tsx +319 -0
  443. package/src/components/Notice/notice.tsx +196 -0
  444. package/src/components/NumberInput/number-input.tsx +203 -0
  445. package/src/components/OverflowIndicator/overflow-indicator.tsx +156 -0
  446. package/src/components/PeoplePicker/avatar-stack-overflow.ts +100 -0
  447. package/src/components/PeoplePicker/people-picker-helpers.ts +76 -0
  448. package/src/components/PeoplePicker/people-picker.tsx +455 -0
  449. package/src/components/PeoplePicker/person-display.tsx +358 -0
  450. package/src/components/Popover/popover.tsx +183 -0
  451. package/src/components/ProgressBar/progress-bar.tsx +157 -0
  452. package/src/components/README.md +58 -0
  453. package/src/components/RadioGroup/radio-group.tsx +261 -0
  454. package/src/components/Rating/rating.tsx +295 -0
  455. package/src/components/ScrollArea/scroll-area.tsx +110 -0
  456. package/src/components/SegmentedControl/segmented-control.tsx +304 -0
  457. package/src/components/Select/select.tsx +658 -0
  458. package/src/components/SelectMenu/select-menu.tsx +430 -0
  459. package/src/components/SelectionControl/selection-item.tsx +261 -0
  460. package/src/components/Separator/separator.tsx +48 -0
  461. package/src/components/Sheet/sheet.tsx +240 -0
  462. package/src/components/Sidebar/sidebar.tsx +1280 -0
  463. package/src/components/Skeleton/skeleton.tsx +35 -0
  464. package/src/components/Slider/slider.tsx +158 -0
  465. package/src/components/Steps/steps.tsx +850 -0
  466. package/src/components/Switch/switch.tsx +285 -0
  467. package/src/components/Tabs/tabs.tsx +515 -0
  468. package/src/components/Tag/tag.tsx +246 -0
  469. package/src/components/Textarea/textarea.tsx +280 -0
  470. package/src/components/TimePicker/time-columns.tsx +260 -0
  471. package/src/components/TimePicker/time-picker.tsx +419 -0
  472. package/src/components/Toast/toast.tsx +129 -0
  473. package/src/components/Tooltip/tooltip.tsx +68 -0
  474. package/src/components/TreeView/tree-view.tsx +1031 -0
  475. package/src/hooks/use-controllable.ts +40 -0
  476. package/src/hooks/use-is-narrow-viewport.ts +19 -0
  477. package/src/hooks/use-is-touch-device.ts +21 -0
  478. package/src/hooks/use-overflow-items.ts +256 -0
  479. package/src/index.ts +85 -0
  480. package/src/lib/README.md +82 -0
  481. package/src/lib/drag-visual.ts +272 -0
  482. package/src/lib/i18n/README.md +60 -0
  483. package/src/lib/i18n/i18n-context.tsx +129 -0
  484. package/src/lib/multi-select-ordering.ts +61 -0
  485. package/src/lib/utils.ts +93 -0
  486. package/src/patterns/README.md +67 -0
  487. package/src/patterns/element-anatomy/item-anatomy.tsx +744 -0
  488. package/src/patterns/header-canonical/chrome-header.tsx +175 -0
  489. package/src/patterns/header-canonical/header-canonical.css +27 -0
  490. package/src/patterns/horizontal-overflow/horizontal-overflow.tsx +217 -0
  491. package/src/patterns/overlay-surface/overlay-surface.tsx +191 -0
  492. package/src/patterns/resize-handle/resize-handle.tsx +188 -0
  493. package/src/stories-helpers/anatomy/anatomy-utils.tsx +64 -0
  494. package/src/styles/preset.css +31 -0
  495. package/src/styles/tokens.css +35 -0
  496. package/src/tokens/README.md +53 -0
  497. package/src/tokens/color/primitives.css +429 -0
  498. package/src/tokens/color/semantic.css +539 -0
  499. package/src/tokens/elevation/overlay-geometry.ts +13 -0
  500. package/src/tokens/layoutSpace/layoutSpace.css +36 -0
  501. package/src/tokens/motion/motion.css +30 -0
  502. package/src/tokens/motion/motion.ts +17 -0
  503. package/src/tokens/opacity/opacity.css +23 -0
  504. package/src/tokens/radius/radius.css +19 -0
  505. package/src/tokens/typography/typography.css +118 -0
  506. package/src/tokens/uiSize/icon-size.ts +52 -0
  507. package/src/tokens/uiSize/uiSize.css +125 -0
@@ -0,0 +1,475 @@
1
+ import * as React from "react"
2
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
3
+ import { ChevronRight, type LucideIcon } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+ import type { AvatarData } from "@/design-system/components/Avatar/avatar"
7
+ import { MenuItem } from "@/design-system/components/Menu/menu-item"
8
+ import { ScrollArea } from "@/design-system/components/ScrollArea/scroll-area"
9
+ import { OVERLAY_SIDE_OFFSET, OVERLAY_COLLISION_PADDING } from "@/design-system/tokens/elevation/overlay-geometry"
10
+ import {
11
+ RowSizeProvider,
12
+ useRowSize,
13
+ ICON_SIZE as ROW_ICON_SIZE,
14
+ type RowSize,
15
+ } from "@/design-system/patterns/element-anatomy/item-anatomy"
16
+
17
+ /**
18
+ * DropdownMenu — Radix DropdownMenu + MenuItem visual layer
19
+ *
20
+ * 架構分工:
21
+ * - Radix primitives:behavior(keyboard nav, focus management, aria roles)
22
+ * - MenuItem:visual(layout, padding, icon alignment, typography)
23
+ *
24
+ * Radix primitive 是外層容器,控制 `data-[highlighted]:bg-neutral-hover`。
25
+ * MenuItem 內層只負責佈局,不加互動樣式。
26
+ *
27
+ * ── Hover / highlight canonical(2026-04-22 修正)──
28
+ * 用 Radix 官方的 `data-[highlighted]` attribute,**不用 `:focus-visible` / `:hover` /
29
+ * `:focus`**:
30
+ * - Radix 在 **mouse hover、keyboard arrow nav、focus move in** 時自動 set `data-highlighted`
31
+ * - mouse leave / focus move out / menu close 時自動清掉
32
+ * - 不會在 click 後留殘影(Radix 內部已處理)
33
+ * - 跨瀏覽器一致(不依賴 `:focus-visible` 的 heuristic)
34
+ *
35
+ * 曾經用過 `focus-visible:bg-neutral-hover` 的理由:避免 click 後殘影。但實測:mouse hover
36
+ * 觸發 Radix 程式化 `.focus()`,Chromium / Safari / Firefox 對 programmatic focus 是否 fire
37
+ * `:focus-visible` 行為不一致,導致 mouse hover 有時無 bg。改用 `data-[highlighted]:` 後行為
38
+ * 一致 —— 世界級 canonical(shadcn / Radix docs / Ariakit 皆此)。
39
+ */
40
+
41
+ // ── Floating layer 共用樣式 ──
42
+ const floatingLayerClass = [
43
+ 'z-50 overflow-hidden rounded-lg border border-border bg-surface-raised',
44
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out motion-reduce:animate-none',
45
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
46
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
47
+ 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
48
+ 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
49
+ 'origin-[var(--radix-dropdown-menu-content-transform-origin)]',
50
+ ].join(' ')
51
+
52
+ // ── Size:統一用 RowSizeContext(item-layout module),消除本地 SizeContext 漂移 ──
53
+ type SizeKey = RowSize
54
+ // Re-export for backward compat(內部命名)
55
+ const ICON_SIZE = ROW_ICON_SIZE
56
+
57
+ // ── Shared item classes on Radix primitive ──
58
+ // Highlight(hover + keyboard nav): 用 Radix `data-[highlighted]` canonical(見 docblock)
59
+ const radixItemClass = [
60
+ 'relative cursor-pointer select-none outline-none',
61
+ 'transition-colors duration-150',
62
+ 'data-[highlighted]:bg-neutral-hover',
63
+ 'data-[disabled]:pointer-events-none data-[disabled]:text-fg-disabled data-[disabled]:cursor-default',
64
+ ].join(' ')
65
+
66
+ // ── Root ──
67
+ const DropdownMenu = DropdownMenuPrimitive.Root
68
+ const DropdownMenuTrigger = React.forwardRef<
69
+ React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
70
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>
71
+ >(({ className, ...props }, ref) => (
72
+ <DropdownMenuPrimitive.Trigger
73
+ ref={ref}
74
+ className={cn('outline-none', className)}
75
+ {...props}
76
+ />
77
+ ))
78
+ DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName
79
+ // DropdownMenuGroup — 對齊 MenuGroup 的 group separation 設計語言
80
+ //
81
+ // 設計語言(跨 Menu-like 元件統一,SSOT 見 item-anatomy.spec.md
82
+ // 「Group auto-separation」):
83
+ // 每個 group 上下各 8px padding,相鄰 group 之間用 border-divider 分隔
84
+ // 兩個 group 之間視覺 gap = 8px(上一個 bottom)+ 8px(下一個 top)= 16px + border
85
+ //
86
+ // MenuGroup(menu-item.tsx)實作:`py-2 [&+&]:border-t [&+&]:border-divider`
87
+ // (在 Command.List 下提供 Content 邊界 8px + group 間 16px gap)
88
+ //
89
+ // DropdownMenuGroup(本元件)實作:`[&+&]:mt-2 [&+&]:pt-2 [&+&]:border-t
90
+ // [&+&]:border-divider`(因為 DropdownMenuContent 已有 py-2 提供 Content 邊界
91
+ // 的 8px,只需在第二個起的 group 加 8+8 = 16px gap + border)
92
+ //
93
+ // **視覺結果等同**:兩種實作的 visual output 一致,只是「padding 住在哪層」
94
+ // 不同。不強制統一 CSS 表達式——DropdownMenuContent 的 py-2 是既有 Radix
95
+ // 期望的行為,移除會影響 trigger 鍵盤導覽的 focus offset。
96
+ const DropdownMenuGroup = React.forwardRef<
97
+ React.ElementRef<typeof DropdownMenuPrimitive.Group>,
98
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Group>
99
+ >(({ className, ...props }, ref) => (
100
+ <DropdownMenuPrimitive.Group
101
+ ref={ref}
102
+ className={cn('[&+&]:border-t [&+&]:border-divider [&+&]:mt-2 [&+&]:pt-2', className)}
103
+ {...props}
104
+ />
105
+ ))
106
+ DropdownMenuGroup.displayName = 'DropdownMenuGroup'
107
+
108
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal
109
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub
110
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
111
+
112
+ // ── Content ──
113
+ interface DropdownMenuContentProps
114
+ extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> {
115
+ size?: SizeKey
116
+ /** 最小寬度(px),預設跟隨觸發元件寬度 */
117
+ minWidth?: number
118
+ /** 最大高度(px),超過時捲動 */
119
+ maxHeight?: number
120
+ }
121
+
122
+ const DropdownMenuContent = React.forwardRef<
123
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
124
+ DropdownMenuContentProps
125
+ >(({ className, size = 'md', sideOffset = OVERLAY_SIDE_OFFSET, collisionPadding = OVERLAY_COLLISION_PADDING, align = 'start', minWidth, maxHeight, children, ...props }, ref) => (
126
+ <DropdownMenuPrimitive.Portal>
127
+ <DropdownMenuPrimitive.Content
128
+ ref={ref}
129
+ sideOffset={sideOffset}
130
+ collisionPadding={collisionPadding}
131
+ align={align}
132
+ onCloseAutoFocus={(e) => e.preventDefault()}
133
+ className={cn(floatingLayerClass, !maxHeight && 'py-2', className)}
134
+ style={{
135
+ boxShadow: 'var(--elevation-200)',
136
+ minWidth: minWidth ?? 'max(180px, var(--radix-dropdown-menu-trigger-width))',
137
+ maxHeight,
138
+ }}
139
+ {...props}
140
+ >
141
+ <RowSizeProvider value={size}>
142
+ {maxHeight ? (
143
+ // 長選單用 ScrollArea 跨 OS 一致捲動(不吃寬度,macOS/Windows 視覺一致)
144
+ // py-2 移到內層,ScrollArea Viewport 才能 scroll 整個 padded 區
145
+ <ScrollArea className="max-h-[inherit]">
146
+ <div className="py-2">{children}</div>
147
+ </ScrollArea>
148
+ ) : (
149
+ children
150
+ )}
151
+ </RowSizeProvider>
152
+ </DropdownMenuPrimitive.Content>
153
+ </DropdownMenuPrimitive.Portal>
154
+ ))
155
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
156
+
157
+ // ── SubContent ──
158
+ const DropdownMenuSubContent = React.forwardRef<
159
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
160
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
161
+ >(({ className, children, ...props }, ref) => {
162
+ const size = useRowSize()
163
+ return (
164
+ <DropdownMenuPrimitive.SubContent
165
+ ref={ref}
166
+ sideOffset={OVERLAY_SIDE_OFFSET}
167
+ className={cn(floatingLayerClass, 'py-2', className)}
168
+ style={{ boxShadow: 'var(--elevation-200)', minWidth: 180 }}
169
+ {...props}
170
+ >
171
+ <RowSizeProvider value={size}>
172
+ {children}
173
+ </RowSizeProvider>
174
+ </DropdownMenuPrimitive.SubContent>
175
+ )
176
+ })
177
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName
178
+
179
+ // ── Helper: build endContent from badge + endIcon + shortcut ──
180
+ function buildEndContent(
181
+ size: SizeKey,
182
+ badge?: React.ReactNode,
183
+ endIcon?: LucideIcon,
184
+ shortcut?: string,
185
+ ): React.ReactNode | undefined {
186
+ const EndIcon = endIcon
187
+ if (!badge && !EndIcon && !shortcut) return undefined
188
+ const iconPx = ICON_SIZE[size]
189
+ return (
190
+ <>
191
+ {badge}
192
+ {EndIcon && <EndIcon size={iconPx} className="text-fg-muted" aria-hidden />}
193
+ {shortcut && <span className="text-caption text-fg-muted">{shortcut}</span>}
194
+ </>
195
+ )
196
+ }
197
+
198
+ // ── Item ──
199
+ interface DropdownMenuItemProps
200
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>, 'children'> {
201
+ children: React.ReactNode
202
+ /** 左側 icon */
203
+ startIcon?: LucideIcon
204
+ /** 左側頭像資料(AvatarData),與 startIcon 互斥 */
205
+ avatar?: AvatarData
206
+ /** 次要說明文字 */
207
+ description?: React.ReactNode
208
+ /** 後綴 Tag(ReactNode) */
209
+ tag?: React.ReactNode
210
+ /** 後綴 Badge(ReactNode) */
211
+ badge?: React.ReactNode
212
+ /** 後綴指示型 icon(LucideIcon),fg-muted */
213
+ endIcon?: LucideIcon
214
+ /** 鍵盤快捷鍵 */
215
+ shortcut?: string
216
+ /** 單選選中(bg-neutral-selected,持續選中狀態)*/
217
+ selected?: boolean
218
+ }
219
+
220
+ const DropdownMenuItem = React.forwardRef<
221
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
222
+ DropdownMenuItemProps
223
+ >(({ className, children, startIcon, avatar, description, tag, badge, endIcon, shortcut, selected, disabled, ...props }, ref) => {
224
+ const size = useRowSize()
225
+ const endContent = buildEndContent(size, badge, endIcon, shortcut)
226
+
227
+ return (
228
+ <DropdownMenuPrimitive.Item
229
+ ref={ref}
230
+ disabled={disabled}
231
+ className={cn(
232
+ radixItemClass,
233
+ selected && 'bg-neutral-selected',
234
+ className,
235
+ )}
236
+ {...props}
237
+ >
238
+ <MenuItem
239
+ size={size}
240
+ startIcon={startIcon}
241
+ avatar={avatar}
242
+ description={description}
243
+ tag={tag}
244
+ endContent={endContent}
245
+ disabled={disabled}
246
+ // Pure visual — Radix parent handles role/aria/interaction
247
+ role="presentation"
248
+ className="!bg-transparent hover:!bg-transparent pointer-events-none"
249
+ >
250
+ {children}
251
+ </MenuItem>
252
+ </DropdownMenuPrimitive.Item>
253
+ )
254
+ })
255
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
256
+
257
+ // ── SubTrigger(子選單觸發器,自動附加 ChevronRight)──
258
+ interface DropdownMenuSubTriggerProps
259
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger>, 'children'> {
260
+ children: React.ReactNode
261
+ /** 左側 icon */
262
+ startIcon?: LucideIcon
263
+ /** 子選單目前狀態值文字(如 "深色") */
264
+ value?: string
265
+ /** 子選單狀態 badge */
266
+ badge?: React.ReactNode
267
+ }
268
+
269
+ const DropdownMenuSubTrigger = React.forwardRef<
270
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
271
+ DropdownMenuSubTriggerProps
272
+ >(({ className, children, startIcon, value, badge, ...props }, ref) => {
273
+ const size = useRowSize()
274
+ const iconPx = ICON_SIZE[size]
275
+
276
+ // SubTrigger suffix: [value?] [badge?] [ChevronRight] with gap-1
277
+ const endContent = (
278
+ <div className="flex items-center gap-1">
279
+ {value && <span className="text-fg-muted">{value}</span>}
280
+ {badge}
281
+ <ChevronRight size={iconPx} className="text-fg-muted" />
282
+ </div>
283
+ )
284
+
285
+ return (
286
+ <DropdownMenuPrimitive.SubTrigger
287
+ ref={ref}
288
+ className={cn(
289
+ radixItemClass,
290
+ 'data-[state=open]:bg-neutral-hover',
291
+ className,
292
+ )}
293
+ {...props}
294
+ >
295
+ <MenuItem
296
+ size={size}
297
+ startIcon={startIcon}
298
+ endContent={endContent}
299
+ role="presentation"
300
+ className="!bg-transparent hover:!bg-transparent pointer-events-none"
301
+ >
302
+ {children}
303
+ </MenuItem>
304
+ </DropdownMenuPrimitive.SubTrigger>
305
+ )
306
+ })
307
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName
308
+
309
+ // ── CheckboxItem ──
310
+ interface DropdownMenuCheckboxItemProps
311
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>, 'children'> {
312
+ children: React.ReactNode
313
+ /** 左側 icon */
314
+ startIcon?: LucideIcon
315
+ /** 次要說明文字 */
316
+ description?: React.ReactNode
317
+ }
318
+
319
+ const DropdownMenuCheckboxItem = React.forwardRef<
320
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
321
+ DropdownMenuCheckboxItemProps
322
+ >(({ className, children, startIcon, description, checked, disabled, ...props }, ref) => {
323
+ const size = useRowSize()
324
+
325
+ return (
326
+ <DropdownMenuPrimitive.CheckboxItem
327
+ ref={ref}
328
+ checked={checked}
329
+ disabled={disabled}
330
+ onSelect={(e) => e.preventDefault()}
331
+ className={cn(radixItemClass, className)}
332
+ {...props}
333
+ >
334
+ <MenuItem
335
+ size={size}
336
+ checkbox
337
+ checked={!!checked}
338
+ startIcon={startIcon}
339
+ description={description}
340
+ disabled={disabled}
341
+ role="presentation"
342
+ className="!bg-transparent hover:!bg-transparent pointer-events-none"
343
+ >
344
+ {children}
345
+ </MenuItem>
346
+ </DropdownMenuPrimitive.CheckboxItem>
347
+ )
348
+ })
349
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName
350
+
351
+ // ── Label(群組標題)──
352
+ const DropdownMenuLabel = React.forwardRef<
353
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
354
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>
355
+ >(({ className, children, ...props }, ref) => {
356
+ const size = useRowSize()
357
+ return (
358
+ <DropdownMenuPrimitive.Label
359
+ ref={ref}
360
+ className={cn('outline-none', className)}
361
+ {...props}
362
+ >
363
+ <MenuItem
364
+ size={size}
365
+ header
366
+ role="presentation"
367
+ className="pointer-events-none"
368
+ >
369
+ {children}
370
+ </MenuItem>
371
+ </DropdownMenuPrimitive.Label>
372
+ )
373
+ })
374
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
375
+
376
+ // ── Separator ──
377
+ const DropdownMenuSeparator = React.forwardRef<
378
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
379
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
380
+ >(({ className, ...props }, ref) => (
381
+ <DropdownMenuPrimitive.Separator
382
+ ref={ref}
383
+ className={cn("my-2 h-px bg-divider", className)}
384
+ {...props}
385
+ />
386
+ ))
387
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
388
+
389
+ // ── RadioItem(單選,排序方式等)──
390
+ // Radix handles checked state; visual用 MenuItem 的 selected highlight。
391
+ interface DropdownMenuRadioItemProps
392
+ extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> {
393
+ /** Prefix icon(LucideIcon) */
394
+ startIcon?: LucideIcon
395
+ /** 次要說明文字 */
396
+ description?: React.ReactNode
397
+ }
398
+
399
+ const DropdownMenuRadioItem = React.forwardRef<
400
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
401
+ DropdownMenuRadioItemProps
402
+ >(({ className, children, startIcon, description, disabled, ...props }, ref) => {
403
+ const size = useRowSize()
404
+
405
+ return (
406
+ <DropdownMenuPrimitive.RadioItem
407
+ ref={ref}
408
+ disabled={disabled}
409
+ onSelect={(e) => e.preventDefault()}
410
+ className={cn(radixItemClass, 'data-[state=checked]:[&>*]:bg-neutral-selected', className)}
411
+ {...props}
412
+ >
413
+ <MenuItem
414
+ size={size}
415
+ startIcon={startIcon}
416
+ description={description}
417
+ disabled={disabled}
418
+ role="presentation"
419
+ className="!bg-transparent hover:!bg-transparent pointer-events-none"
420
+ >
421
+ {children}
422
+ </MenuItem>
423
+ </DropdownMenuPrimitive.RadioItem>
424
+ )
425
+ })
426
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
427
+
428
+ // ── Shortcut(鍵盤快捷鍵提示,ml-auto 靠右)──
429
+ // 作為 MenuItem children 的後綴,視覺為 fg-muted 小字。
430
+ const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (
431
+ <span
432
+ className={cn('ml-auto text-footnote text-fg-muted tracking-shortcut', className)}
433
+ {...props}
434
+ />
435
+ )
436
+ DropdownMenuShortcut.displayName = 'DropdownMenuShortcut'
437
+
438
+ // Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
439
+ // Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
440
+ export const dropdownMenuMeta = {
441
+ component: 'DropdownMenu',
442
+ family: null, // non-family composite / overlay / layout
443
+ variants: {
444
+
445
+ },
446
+ sizes: {
447
+
448
+ },
449
+ states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
450
+ tokens: {
451
+ bg: ['bg-neutral-hover', 'bg-surface-raised', 'bg-transparent'],
452
+ fg: ['text-fg-disabled', 'text-fg-muted'],
453
+ ring: [],
454
+ },
455
+ } as const
456
+
457
+ export {
458
+ DropdownMenu,
459
+ DropdownMenuTrigger,
460
+ DropdownMenuContent,
461
+ DropdownMenuItem,
462
+ DropdownMenuCheckboxItem,
463
+ DropdownMenuLabel,
464
+ DropdownMenuSeparator,
465
+ DropdownMenuGroup,
466
+ DropdownMenuPortal,
467
+ DropdownMenuSub,
468
+ DropdownMenuSubContent,
469
+ DropdownMenuSubTrigger,
470
+ DropdownMenuRadioGroup,
471
+ DropdownMenuRadioItem,
472
+ DropdownMenuShortcut,
473
+ floatingLayerClass,
474
+ }
475
+ export type { SizeKey, DropdownMenuItemProps }
@@ -0,0 +1,108 @@
1
+ import * as React from 'react'
2
+ import type { LucideIcon } from 'lucide-react'
3
+ import { cn } from '@/lib/utils'
4
+ import { Avatar } from '@/design-system/components/Avatar/avatar'
5
+ import { useRowSize } from '@/design-system/patterns/element-anatomy/item-anatomy'
6
+
7
+ /**
8
+ * Empty — 空狀態視覺元件
9
+ *
10
+ * 居中垂直堆疊:icon(Avatar) → title → description → action。
11
+ * 所有 slot 皆可選,預設只需 description。
12
+ *
13
+ * 間距固定,不隨 density 變(Empty 是展示性元件,不是工作區域元件):
14
+ * icon → text = mb-4(16px)
15
+ * desc → action = mt-6(24px)
16
+ * title → desc = `var(--item-gap-label-desc)`(token,預設 2px,item-anatomy SSOT)
17
+ *
18
+ * Outer padding 由 consumer 容器決定(py-12 / py-6 / py-16 等)。
19
+ */
20
+
21
+ export interface EmptyProps extends React.HTMLAttributes<HTMLDivElement> {
22
+ /** LucideIcon → 自動包 Avatar 48px neutral;ReactElement → 原樣渲染 */
23
+ icon?: LucideIcon | React.ReactElement
24
+ /** 標題(可選,font-medium,適用於首次引導) */
25
+ title?: string
26
+ /** 說明文字 */
27
+ description?: string
28
+ /** 行動按鈕(可選) */
29
+ action?: React.ReactNode
30
+ }
31
+
32
+ const Empty = React.forwardRef<HTMLDivElement, EmptyProps>(
33
+ ({ icon, title, description, action, className, ...props }, ref) => {
34
+ // 字體 tier:讀 RowSizeContext(menu 內自動對齊 menu items 的字體)
35
+ // 沒有 context(standalone)→ fallback 'md' → text-body (14px)
36
+ const rowSize = useRowSize('md')
37
+ const descFont = rowSize === 'lg' ? 'text-body-lg' : 'text-body'
38
+
39
+ // Icon rendering: ReactElement → as-is;LucideIcon(component,包括 forwardRef 物件)→ 包 Avatar
40
+ // 注意:Lucide v0.577+ icons 是 forwardRef 物件(`typeof === 'object'`),不是 function。
41
+ // 必用 React.isValidElement 判斷 element vs component(typeof 會把 forwardRef 物件誤歸 object)。
42
+ let iconElement: React.ReactNode = null
43
+ if (icon) {
44
+ if (React.isValidElement(icon)) {
45
+ iconElement = icon
46
+ } else {
47
+ const Icon = icon as LucideIcon
48
+ iconElement = <Avatar icon={Icon} size={48} color="neutral" />
49
+ }
50
+ }
51
+
52
+ return (
53
+ <div
54
+ ref={ref}
55
+ className={cn('flex flex-col items-center text-center', className)}
56
+ {...props}
57
+ >
58
+ {iconElement && (
59
+ <div className="mb-4">{iconElement}</div>
60
+ )}
61
+ {title && (
62
+ <span className="text-body-lg font-medium text-foreground">
63
+ {title}
64
+ </span>
65
+ )}
66
+ {description && (
67
+ <span
68
+ className={cn(
69
+ // 字體跟 RowSizeContext 對齊:sm/md = text-body (14px),lg = text-body-lg (16px)
70
+ // 在 menu 內自動對齊 menu items;standalone 時 fallback text-body
71
+ descFont,
72
+ (title || action) ? 'text-fg-secondary' : 'text-fg-muted',
73
+ // Empty title 永遠 body-lg(16)→ 用 reading-lg token(label tier 決定)
74
+ title && 'mt-[var(--item-gap-label-desc-reading-lg)]',
75
+ )}
76
+ >
77
+ {description}
78
+ </span>
79
+ )}
80
+ {action && (
81
+ <div className="mt-6">{action}</div>
82
+ )}
83
+ </div>
84
+ )
85
+ },
86
+ )
87
+ Empty.displayName = 'Empty'
88
+
89
+ // Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
90
+ // Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
91
+ export const emptyMeta = {
92
+ component: 'Empty',
93
+ family: null, // non-family composite / overlay / layout
94
+ variants: {
95
+
96
+ },
97
+ sizes: {
98
+
99
+ },
100
+ states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
101
+ tokens: {
102
+ bg: [],
103
+ fg: ['text-fg-muted', 'text-fg-secondary', 'text-foreground'],
104
+ ring: [],
105
+ },
106
+ } as const
107
+
108
+ export { Empty }