@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,619 @@
1
+ // @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.
2
+ // code-quality-allow: file-size — Breadcrumb 含 BreadcrumbList(主)+ BreadcrumbItem + BreadcrumbEllipsis + items-collapse logic,split 會破壞 collapse/overflow Tooltip subtree
3
+ import * as React from 'react'
4
+ import { Slot } from '@radix-ui/react-slot'
5
+ import { ChevronRight, MoreHorizontal, type LucideIcon } from 'lucide-react'
6
+ import { cn } from '@/lib/utils'
7
+ import { ItemInlineActionButton } from '@/design-system/patterns/element-anatomy/item-anatomy'
8
+ import { Tooltip, TooltipTrigger, TooltipContent } from '@/design-system/components/Tooltip/tooltip'
9
+ import {
10
+ DropdownMenu,
11
+ DropdownMenuTrigger,
12
+ DropdownMenuContent,
13
+ DropdownMenuItem,
14
+ } from '@/design-system/components/DropdownMenu/dropdown-menu'
15
+
16
+ // ── TruncatedLabel ────────────────────────────────────────────────────────────
17
+ // 同 `data-table.tsx:339 TruncateCell` + `tag.tsx:138 isTruncated` SSOT pattern
18
+ // (shared ResizeObserver + scrollWidth > clientWidth → wrap Tooltip)。
19
+ // **TODO** future:Rule-of-3 達 → 抽 `patterns/element-anatomy/truncated-text.tsx` 共用
20
+ // (本 component / DataTable TruncateCell / Tag inner 三處同 idiom,符合 M30 SSOT 抽取門檻)。
21
+
22
+ type RoCallback = (entry: ResizeObserverEntry) => void
23
+ let sharedRO: ResizeObserver | null = null
24
+ const sharedROCallbacks = new WeakMap<Element, RoCallback>()
25
+ function getSharedRO(): ResizeObserver {
26
+ if (sharedRO) return sharedRO
27
+ sharedRO = new ResizeObserver((entries) => {
28
+ entries.forEach((e) => {
29
+ const cb = sharedROCallbacks.get(e.target)
30
+ if (cb) cb(e)
31
+ })
32
+ })
33
+ return sharedRO
34
+ }
35
+ function observeShared(el: Element, cb: RoCallback): () => void {
36
+ const obs = getSharedRO()
37
+ sharedROCallbacks.set(el, cb)
38
+ obs.observe(el)
39
+ return () => { sharedROCallbacks.delete(el); obs.unobserve(el) }
40
+ }
41
+
42
+ function TruncatedLabel({ children, fullText }: { children: React.ReactNode; fullText?: string }) {
43
+ const ref = React.useRef<HTMLSpanElement>(null)
44
+ const [isTruncated, setIsTruncated] = React.useState(false)
45
+ React.useEffect(() => {
46
+ const el = ref.current
47
+ if (!el) return
48
+ const check = () => setIsTruncated(el.scrollWidth > el.clientWidth)
49
+ check()
50
+ // 2026-05-11 fix:首幀 layout 未完成 / 字型 async load → scrollWidth=clientWidth 假陰性。
51
+ // RAF + 短延遲再驗一次,捕獲字型 / 容器尺寸後變(對齊 TruncateCell / Tag SSOT pattern)。
52
+ const raf = requestAnimationFrame(check)
53
+ const t = setTimeout(check, 100)
54
+ const cleanup = observeShared(el, check)
55
+ return () => {
56
+ cancelAnimationFrame(raf)
57
+ clearTimeout(t)
58
+ cleanup()
59
+ }
60
+ }, [])
61
+ // Tooltip canonical:per `tooltip.principles.stories.tsx:190`「Tooltip 是資訊補救 — 文字被
62
+ // truncate 時才顯示完整內容。沒被截斷就不該顯示 tooltip」
63
+ //
64
+ // 2026-05-11 fix(playwright tooltip-on-truncate 卡 hover 沒 tooltip):
65
+ // 原本 isTruncated=false 直接 return 裸 span / true 才 wrap Tooltip → JSX 樹結構改變
66
+ // → React 把 span unmount + remount(因為 wrapper component 變),ref 換到新 span,
67
+ // useEffect [] 不重跑(同 component instance)→ 觀察的 DOM 跟實際 DOM 對不上。
68
+ // Fix:**永遠 wrap Tooltip**(同 DOM 節點生命週期);`open` 由 isTruncated 控制 —
69
+ // 沒被 truncate 就 force `open={false}`,有 truncate 就 `undefined`(uncontrolled,
70
+ // hover 走 Radix default behavior)。對齊 canonical「沒被截斷就不該 tooltip」。
71
+ return (
72
+ <Tooltip open={isTruncated ? undefined : false}>
73
+ <TooltipTrigger asChild>
74
+ <span ref={ref} className="truncate min-w-0 block">{children}</span>
75
+ </TooltipTrigger>
76
+ <TooltipContent>{fullText ?? children}</TooltipContent>
77
+ </Tooltip>
78
+ )
79
+ }
80
+
81
+ /**
82
+ * Breadcrumb — 顯示當前頁面在階層中的位置
83
+ *
84
+ * 基於 shadcn/ui Breadcrumb 結構(純 HTML nav + ol + li + a/span),
85
+ * 橋接設計系統 token。
86
+ *
87
+ * ── 結構 ──
88
+ * <Breadcrumb>
89
+ * <BreadcrumbList size="md">
90
+ * <BreadcrumbItem>
91
+ * <BreadcrumbLink href="/projects">專案</BreadcrumbLink>
92
+ * </BreadcrumbItem>
93
+ * <BreadcrumbSeparator />
94
+ * <BreadcrumbItem>
95
+ * <BreadcrumbPage>目前頁面</BreadcrumbPage>
96
+ * </BreadcrumbItem>
97
+ * </BreadcrumbList>
98
+ * </Breadcrumb>
99
+ *
100
+ * ── Size(跟 page title 配對) ──
101
+ * sm text-body(14) → 建議配 text-h4(20) title —— Dialog / panel / drawer
102
+ * md text-body(14) → 建議配 text-h3(24) title —— 一般頁面 header (預設)
103
+ * lg text-body-lg(16) → 建議配 text-h2(32) title —— Detail page hero / landing
104
+ *
105
+ * ── 視覺 ──
106
+ * Link (預設): text-fg-secondary
107
+ * Link hover: text-primary-hover (canonical「互動高亮」, 跟 Tabs / Chip 用法一致)
108
+ * Page (當前): text-foreground + font-medium
109
+ * Separator: ChevronRight (size 跟 list 一致), text-fg-muted
110
+ *
111
+ * ── 詳見 breadcrumb.spec.md ──
112
+ */
113
+
114
+ // ── Size context ─────────────────────────────────────────────────────────────
115
+
116
+ type BreadcrumbSize = 'sm' | 'md' | 'lg'
117
+
118
+ interface BreadcrumbContextValue {
119
+ size: BreadcrumbSize
120
+ }
121
+
122
+ const BreadcrumbContext = React.createContext<BreadcrumbContextValue>({ size: 'md' })
123
+
124
+ const BREADCRUMB_TEXT_CLASS: Record<BreadcrumbSize, string> = {
125
+ sm: 'text-body',
126
+ md: 'text-body',
127
+ lg: 'text-body-lg',
128
+ }
129
+
130
+ // Separator / ellipsis icon 尺寸 — 對齊 uiSize.spec.md「Icon Size Tier」(field-height-sm/md→16,lg→20)
131
+ // 2026-05-18 改 per user 拍板「A 先改 16/16/20」+「做完」approval:
132
+ // 撤回 text-flow 例外設計,Breadcrumb chevron 跟其他 chrome icon 同 tier。
133
+ // World-class 對齊:Atlassian Breadcrumb chevron 16 default / Material 3 / Ant Design 同。
134
+ const BREADCRUMB_ICON_SIZE: Record<BreadcrumbSize, number> = {
135
+ sm: 16,
136
+ md: 16,
137
+ lg: 20,
138
+ }
139
+
140
+ // ── Breadcrumb (nav root) ────────────────────────────────────────────────────
141
+
142
+ const Breadcrumb = React.forwardRef<
143
+ HTMLElement,
144
+ React.ComponentPropsWithoutRef<'nav'>
145
+ >(({ ...props }, ref) => (
146
+ <nav ref={ref} aria-label="Breadcrumb" {...props} />
147
+ ))
148
+ Breadcrumb.displayName = 'Breadcrumb'
149
+
150
+ // ── BreadcrumbList (ol) ──────────────────────────────────────────────────────
151
+
152
+ /**
153
+ * Phase B(2026-05-10):declarative items mode 啟用 auto-collapse + auto-separator + auto-page-end。
154
+ * 對齊 Material UI source `Breadcrumbs.js renderItemsBeforeAndAfter` mechanism(`maxItems`
155
+ * default 8;本 DS 採 user-tuned 4 — 更積極 collapse 適合 single-line 緊湊 layout)。
156
+ */
157
+ // code-quality-allow: dead-export — public consumer-facing item spec type;對齊 BreadcrumbProps API contract,允許 consumer 構造 items array 外部
158
+ export interface BreadcrumbItemSpec {
159
+ label: React.ReactNode
160
+ href?: string
161
+ asChild?: boolean
162
+ /**
163
+ * 起始 icon(per `ui-development.md`「icon prop 命名 4 條」:slot 只接 icon → `startIcon`)。
164
+ * 業界慣例:Breadcrumb 首項用 Home icon 強化視覺錨點(Material / Atlassian)。
165
+ * 內部消費 `BREADCRUMB_ICON_SIZE[size]` SSOT(sm/md=16, lg=20,對齊 uiSize.spec.md Icon Size Tier)。
166
+ * Consumer **不傳** size,DS 統一管。
167
+ */
168
+ startIcon?: LucideIcon
169
+ }
170
+
171
+ interface BreadcrumbListProps extends Omit<React.ComponentPropsWithoutRef<'ol'>, 'children'> {
172
+ /**
173
+ * 字體尺寸 — 依據與之配對的 page title 選擇:
174
+ * sm → 配 text-h4(20) title (Dialog / panel / drawer)
175
+ * md → 配 text-h3(24) title (一般頁面 header,預設)
176
+ * lg → 配 text-h2(32) title (Detail page hero / landing)
177
+ */
178
+ size?: BreadcrumbSize
179
+ /**
180
+ * Declarative items mode(opt-in)。當 provided 時 `children` 被忽略,List 內部自動:
181
+ * - 插 separator
182
+ * - 末位 spec(無 `href`)自動 BreadcrumbPage(per Title-breadcrumb-end SSOT)
183
+ * - 超 `maxItems` auto-collapse 中段成 BreadcrumbEllipsis + DropdownMenu(對齊 Material UI
184
+ * source `renderItemsBeforeAndAfter`)
185
+ */
186
+ items?: BreadcrumbItemSpec[]
187
+ /**
188
+ * Auto-collapse 閾值。Default 4(user-tuned;Material UI source 預設 8)。`items.length > maxItems`
189
+ * 才 collapse。
190
+ */
191
+ maxItems?: number
192
+ /** Collapse 後保留首 N 個(default 1)。對齊 Material UI source default。 */
193
+ itemsBeforeCollapse?: number
194
+ /** Collapse 後保留末 N 個(default 1)。對齊 Material UI source default。 */
195
+ itemsAfterCollapse?: number
196
+ children?: React.ReactNode
197
+ }
198
+
199
+ // code-quality-allow: long-function — items props × children narrowing × collapse-with-overflow × tooltip 4 軸組合在 BreadcrumbList,拆 sub-fn 會跨 fn 傳 itemsBeforeCollapse/After collapsed-tooltip refs
200
+ const BreadcrumbList = React.forwardRef<HTMLOListElement, BreadcrumbListProps>(
201
+ ({ className, size = 'md', items, maxItems = 4, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, children, ...props }, ref) => {
202
+ // Memoize provider value(2026-04-22 D3 perf audit):單 field wrapper memoize
203
+ const ctxValue = React.useMemo(() => ({ size }), [size])
204
+
205
+ // Declarative mode(items prop provided):自動 render + auto-collapse
206
+ const declarativeContent = React.useMemo(() => {
207
+ if (!items) return null
208
+ const renderItem = (spec: BreadcrumbItemSpec, role: 'root' | 'middle' | 'current') => (
209
+ <BreadcrumbItem key={`${role}-${typeof spec.label === 'string' ? spec.label : Math.random()}`} role={role}>
210
+ {role === 'current'
211
+ ? <BreadcrumbPage startIcon={spec.startIcon}>
212
+ <TruncatedLabel fullText={typeof spec.label === 'string' ? spec.label : undefined}>{spec.label}</TruncatedLabel>
213
+ </BreadcrumbPage>
214
+ : <BreadcrumbLink href={spec.href} asChild={spec.asChild} startIcon={spec.startIcon}>
215
+ <TruncatedLabel fullText={typeof spec.label === 'string' ? spec.label : undefined}>{spec.label}</TruncatedLabel>
216
+ </BreadcrumbLink>
217
+ }
218
+ </BreadcrumbItem>
219
+ )
220
+
221
+ const shouldCollapse = items.length > maxItems
222
+ const beforeN = Math.max(0, itemsBeforeCollapse)
223
+ const afterN = Math.max(1, itemsAfterCollapse) // 末位永遠 ≥ 1(current page)
224
+
225
+ type VisibleItem = { spec: BreadcrumbItemSpec; role: 'root' | 'middle' | 'current' }
226
+ let visible: Array<VisibleItem | { ellipsisOf: BreadcrumbItemSpec[] }>
227
+ if (!shouldCollapse) {
228
+ visible = items.map((spec, i) => ({
229
+ spec,
230
+ role: i === 0 ? 'root' : (i === items.length - 1 ? 'current' : 'middle') as 'root' | 'middle' | 'current',
231
+ }))
232
+ } else {
233
+ const before = items.slice(0, beforeN).map((spec, i) => ({
234
+ spec,
235
+ role: (i === 0 ? 'root' : 'middle') as 'root' | 'middle' | 'current',
236
+ }))
237
+ const collapsed = items.slice(beforeN, items.length - afterN)
238
+ const after = items.slice(items.length - afterN).map((spec, i, arr) => ({
239
+ spec,
240
+ role: (i === arr.length - 1 ? 'current' : 'middle') as 'root' | 'middle' | 'current',
241
+ }))
242
+ visible = [...before, { ellipsisOf: collapsed }, ...after]
243
+ }
244
+
245
+ // Interleave with separators
246
+ const rendered: React.ReactNode[] = []
247
+ visible.forEach((entry, i) => {
248
+ if (i > 0) rendered.push(<BreadcrumbSeparator key={`sep-${i}`} />)
249
+ if ('ellipsisOf' in entry) {
250
+ rendered.push(
251
+ <BreadcrumbItem key="ellipsis" role="ellipsis">
252
+ <DropdownMenu>
253
+ <DropdownMenuTrigger asChild>
254
+ <BreadcrumbEllipsis />
255
+ </DropdownMenuTrigger>
256
+ <DropdownMenuContent align="start">
257
+ {entry.ellipsisOf.map((s, j) => (
258
+ <DropdownMenuItem key={j} asChild={!!s.href}>
259
+ {s.href ? <a href={s.href}>{s.label}</a> : <span>{s.label}</span>}
260
+ </DropdownMenuItem>
261
+ ))}
262
+ </DropdownMenuContent>
263
+ </DropdownMenu>
264
+ </BreadcrumbItem>
265
+ )
266
+ } else {
267
+ rendered.push(renderItem(entry.spec, entry.role))
268
+ }
269
+ })
270
+ return rendered
271
+ }, [items, maxItems, itemsBeforeCollapse, itemsAfterCollapse])
272
+
273
+ // 2026-05-12 fix(user 抓 image 2 Deep story 違反 single-line + max-levels canonical):
274
+ // Compositional path 也走 auto-collapse + flex-shrink hierarchy。Walk children, 找
275
+ // BreadcrumbItem 並按 index 分派 role (first=root / last=current / middle=middle)。
276
+ // > maxItems 自動 collapse 中段成 ellipsis(對齊 declarative path canonical SSOT)。
277
+ const compositionalContent = React.useMemo(() => {
278
+ if (items) return null
279
+ const childArr = React.Children.toArray(children)
280
+ // 抓 BreadcrumbItem children(skip BreadcrumbSeparator — auto re-interleave)
281
+ // 2026-05-12 Round 4.5 fix(codex M31 Layer C 抓):type-identity primary path + displayName fallback。
282
+ // 純 `displayName` check 在 HOC / React.memo / consumer alias 場景脆弱(production build / wrap
283
+ // 可能改寫 displayName)。`c.type === BreadcrumbItem` 是 React fiber reference-identity 最穩
284
+ // primary(對齊 Radix children-walk pattern);displayName fallback 給 HOC 場景。
285
+ const itemChildren = childArr.filter((c): c is React.ReactElement<BreadcrumbItemProps> =>
286
+ React.isValidElement(c) && (c.type === BreadcrumbItem ||
287
+ (c.type as React.ComponentType)?.displayName === 'BreadcrumbItem')
288
+ )
289
+ // 無 item 或全是 separator → pass-through(consumer raw children,e.g. spinners)
290
+ if (itemChildren.length === 0) return children
291
+ // Assign role by position; clone with role prop
292
+ const total = itemChildren.length
293
+ const cloneWithRole = (item: React.ReactElement<BreadcrumbItemProps>, idx: number, role: 'root' | 'middle' | 'current') =>
294
+ React.cloneElement(item, { role: item.props.role ?? role, key: `bc-${role}-${idx}` })
295
+ const shouldCollapse = total > maxItems
296
+ const beforeN = Math.max(0, itemsBeforeCollapse)
297
+ const afterN = Math.max(1, itemsAfterCollapse)
298
+ const rendered: React.ReactNode[] = []
299
+ if (!shouldCollapse) {
300
+ itemChildren.forEach((item, i) => {
301
+ if (i > 0) rendered.push(<BreadcrumbSeparator key={`sep-${i}`} />)
302
+ const role: 'root' | 'middle' | 'current' = i === 0 ? 'root' : (i === total - 1 ? 'current' : 'middle')
303
+ rendered.push(cloneWithRole(item, i, role))
304
+ })
305
+ } else {
306
+ // before(first N) + ellipsis + after(last M)
307
+ const beforeItems = itemChildren.slice(0, beforeN)
308
+ const collapsedItems = itemChildren.slice(beforeN, total - afterN)
309
+ const afterItems = itemChildren.slice(total - afterN)
310
+ beforeItems.forEach((item, i) => {
311
+ if (i > 0) rendered.push(<BreadcrumbSeparator key={`sep-bef-${i}`} />)
312
+ const role: 'root' | 'middle' = i === 0 ? 'root' : 'middle'
313
+ rendered.push(cloneWithRole(item, i, role))
314
+ })
315
+ if (rendered.length > 0) rendered.push(<BreadcrumbSeparator key="sep-ellipsis-before" />)
316
+ rendered.push(
317
+ <BreadcrumbItem key="bc-ellipsis" role="ellipsis">
318
+ <DropdownMenu>
319
+ <DropdownMenuTrigger asChild>
320
+ <BreadcrumbEllipsis />
321
+ </DropdownMenuTrigger>
322
+ <DropdownMenuContent align="start">
323
+ {collapsedItems.map((item, j) => {
324
+ // 2026-05-12 Round 4.5 fix(codex M31 Layer C 抓):consumer BreadcrumbItem children 常包
325
+ // `<BreadcrumbLink href>` = anchor button-like。直接放進 `<DropdownMenuItem>` 會 nested
326
+ // interactive(menuitem within button violates HTML / a11y)。Fix:extract href + label,
327
+ // 用 `asChild` 把 anchor 接到 menuitem 對齊 declarative path line 245 canonical pattern。
328
+ const innerChildren = (item.props as { children?: React.ReactNode }).children
329
+ let href: string | undefined
330
+ let label: React.ReactNode = innerChildren
331
+ React.Children.forEach(innerChildren, (c) => {
332
+ if (React.isValidElement<{ href?: string; children?: React.ReactNode }>(c)) {
333
+ if (c.props.href) href = c.props.href
334
+ if (c.props.children != null) label = c.props.children
335
+ }
336
+ })
337
+ return href
338
+ ? <DropdownMenuItem key={`collapsed-${j}`} asChild><a href={href}>{label}</a></DropdownMenuItem>
339
+ : <DropdownMenuItem key={`collapsed-${j}`}>{label}</DropdownMenuItem>
340
+ })}
341
+ </DropdownMenuContent>
342
+ </DropdownMenu>
343
+ </BreadcrumbItem>
344
+ )
345
+ rendered.push(<BreadcrumbSeparator key="sep-ellipsis-after" />)
346
+ afterItems.forEach((item, i) => {
347
+ if (i > 0) rendered.push(<BreadcrumbSeparator key={`sep-aft-${i}`} />)
348
+ const role: 'middle' | 'current' = i === afterItems.length - 1 ? 'current' : 'middle'
349
+ rendered.push(cloneWithRole(item, i, role))
350
+ })
351
+ }
352
+ return rendered
353
+ }, [items, children, maxItems, itemsBeforeCollapse, itemsAfterCollapse])
354
+
355
+ return (
356
+ <BreadcrumbContext.Provider value={ctxValue}>
357
+ <ol
358
+ ref={ref}
359
+ // gap-1 (4px) — separator 與兩邊 items 間距;緊湊節奏,符合 breadcrumb 密集流動感。
360
+ // 2026-05-10 Phase A single-line canonical(per user + Material UI source verified):
361
+ // `flex-nowrap` 不 wrap。長路徑走中段折疊。
362
+ // 2026-05-12 fix:compositional 也走 auto-collapse + role-assignment(`compositionalContent`)
363
+ // → declarative / compositional 兩 path 都符合 single-line + max-levels + width 分配 canonical SSOT。
364
+ className={cn(
365
+ 'flex flex-nowrap items-center gap-1 text-fg-secondary leading-compact min-w-0',
366
+ BREADCRUMB_TEXT_CLASS[size],
367
+ className
368
+ )}
369
+ {...props}
370
+ >
371
+ {items ? declarativeContent : compositionalContent}
372
+ </ol>
373
+ </BreadcrumbContext.Provider>
374
+ )
375
+ },
376
+ )
377
+ BreadcrumbList.displayName = 'BreadcrumbList'
378
+
379
+ // ── BreadcrumbItem (li) ──────────────────────────────────────────────────────
380
+
381
+ /**
382
+ * Phase B(2026-05-10):`role` prop emit `data-bc-role` attr → CSS flex-shrink hierarchy。
383
+ * Per BreadcrumbItem 在 row 中的角色決定 shrink 優先級:
384
+ * - `root`(首位)→ shrink:3(縮最積極;root context 可弱化)
385
+ * - `middle`(中段)→ shrink:2
386
+ * - `current`(末位 / page)→ shrink:1(最後縮;a11y current page anchor)
387
+ * - `ellipsis`(BreadcrumbEllipsis 包裝)→ shrink:0(永遠完整 ⋯)
388
+ *
389
+ * 設計回應 user 兩 challenges:
390
+ * (a) Root 也 truncate(shrink:3,不是 shrink-0)
391
+ * (b) 不用 fixed max-width — flex-shrink hierarchy 容器寬時自然展開不浪費空間,
392
+ * 窄時按優先級縮 + TruncatedLabel 內部 CSS truncate + tooltip。
393
+ */
394
+ interface BreadcrumbItemProps extends React.ComponentPropsWithoutRef<'li'> {
395
+ role?: 'root' | 'middle' | 'current' | 'ellipsis'
396
+ }
397
+
398
+ const BreadcrumbItem = React.forwardRef<HTMLLIElement, BreadcrumbItemProps>(
399
+ ({ className, role, style, ...props }, ref) => {
400
+ // 2026-05-20 fix v3(user 抓「專案 後方多 4px 間距 / 我的新專案 沒有」chevron 不對稱):
401
+ // v2 `minWidth: '2rem'`(32px)在寬容器強制 li ≥ 32px → 短 label「專案」(natural ~28px)
402
+ // 被撐 4px,長 label「我的新專案」(natural ~70px)hug content → chevron 兩側不對稱。
403
+ //
404
+ // v3 解法:minWidth `2rem` → `1.5rem`(24px)
405
+ // 數學:中文「X…」最小寬度 = 1 char(~14-16px)+ ellipsis(~6-8px)≈ 22-24px → 24px 剛 cover
406
+ // 結果:
407
+ // - 寬容器:所有自然 label ≥ 24px → li hug content,chevron 緊貼,對稱(本 fix 主目的)
408
+ // - 窄容器 truncate:shrink 不過 24px → 「X…」仍可見 ellipsis 保險
409
+ // - 短英文「OK / ID」(natural ~20px)→ 多 ~4px(原 12px → 縮到 4px,顯著改善)
410
+ // 對齊 user verbatim「minWidth 再調小一點」+ ellipsis 數學最小值。
411
+ const shrinkStyle: React.CSSProperties = role === 'root' ? { flexShrink: 3, minWidth: '1.5rem' }
412
+ : role === 'middle' ? { flexShrink: 2, minWidth: '1.5rem' }
413
+ : role === 'current' ? { flexShrink: 1, minWidth: '1.5rem' }
414
+ : role === 'ellipsis' ? { flexShrink: 0 }
415
+ : {}
416
+ return (
417
+ <li
418
+ ref={ref}
419
+ data-bc-role={role}
420
+ className={cn('inline-flex items-center min-w-0', className)}
421
+ style={{ ...shrinkStyle, ...style }}
422
+ {...props}
423
+ />
424
+ )
425
+ }
426
+ )
427
+ BreadcrumbItem.displayName = 'BreadcrumbItem'
428
+
429
+ // ── BreadcrumbLink (a) ───────────────────────────────────────────────────────
430
+
431
+ interface BreadcrumbLinkProps extends React.ComponentPropsWithoutRef<'a'> {
432
+ /** 將樣式套用至子元件(e.g. React Router Link) */
433
+ asChild?: boolean
434
+ /**
435
+ * 起始 icon(per `ui-development.md`「icon prop 命名 4 條」:slot 只接 icon → `startIcon`)。
436
+ * 內部消費 `BREADCRUMB_ICON_SIZE[size]` SSOT,DS 統一尺寸不允許 consumer override。
437
+ * 對齊 uiSize.spec.md Icon Size Tier(2026-05-18 撤回 14 例外,統一 16/16/20)。
438
+ */
439
+ startIcon?: LucideIcon
440
+ }
441
+
442
+ const BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(
443
+ ({ asChild, className, children, startIcon: StartIcon, ...props }, ref) => {
444
+ const { size } = React.useContext(BreadcrumbContext)
445
+ // 2026-05-12 fix(user 抓 image 2 Deep story 麵包屑沒符合 single-line + truncate canonical):
446
+ // 純文字 children → auto-wrap TruncatedLabel(canonical「single-line + ellipsis + tooltip
447
+ // on truncate」per spec.md / Polaris breadcrumb)。Non-string children(consumer 自訂 icon+text
448
+ // 結構)→ pass-through 不 force-wrap(consumer own truncate)。
449
+ const wrappedChildren = typeof children === 'string'
450
+ ? <TruncatedLabel fullText={children}>{children}</TruncatedLabel>
451
+ : children
452
+ const sharedClassName = cn(
453
+ 'inline-flex items-center gap-2',
454
+ 'min-w-0 max-w-full',
455
+ 'text-fg-secondary',
456
+ 'hover:text-primary-hover',
457
+ 'transition-colors duration-150',
458
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
459
+ 'rounded-md',
460
+ className
461
+ )
462
+ // 2026-05-25 fix(user 抓 Breadcrumb asChild story React.Children.only runtime fail):
463
+ // Radix Slot 規範 children 必為單 element;原 unified Comp render 在 asChild path 內
464
+ // 仍輸出「{StartIcon && ...} + {wrappedChildren}」雙 JSX expression → Slot 收到 array
465
+ // → React.Children.only(array) throws「expected to receive a single React element child」。
466
+ // 分支 render 解 — asChild path 只傳 consumer-supplied child(icon 由 consumer 自管,
467
+ // 對齊 Radix Slot canonical「single child contract」);非 asChild path 維持原 native
468
+ // <a> + DS-controlled icon + wrapped label。
469
+ if (asChild) {
470
+ return (
471
+ <Slot ref={ref} className={sharedClassName} {...props}>
472
+ {wrappedChildren}
473
+ </Slot>
474
+ )
475
+ }
476
+ return (
477
+ <a ref={ref} className={sharedClassName} {...props}>
478
+ {StartIcon && <StartIcon size={BREADCRUMB_ICON_SIZE[size]} aria-hidden className="shrink-0" />}
479
+ {wrappedChildren}
480
+ </a>
481
+ )
482
+ }
483
+ )
484
+ BreadcrumbLink.displayName = 'BreadcrumbLink'
485
+
486
+ // ── BreadcrumbPage (current, non-clickable) ──────────────────────────────────
487
+
488
+ interface BreadcrumbPageProps extends React.ComponentPropsWithoutRef<'span'> {
489
+ /** 起始 icon。內部消費 `BREADCRUMB_ICON_SIZE[size]` SSOT。對齊 BreadcrumbLink. */
490
+ startIcon?: LucideIcon
491
+ }
492
+
493
+ const BreadcrumbPage = React.forwardRef<HTMLSpanElement, BreadcrumbPageProps>(
494
+ ({ className, children, startIcon: StartIcon, ...props }, ref) => {
495
+ const { size } = React.useContext(BreadcrumbContext)
496
+ // 2026-05-12 fix(同 BreadcrumbLink):純文字 children → auto-wrap TruncatedLabel。
497
+ const wrappedChildren = typeof children === 'string'
498
+ ? <TruncatedLabel fullText={children}>{children}</TruncatedLabel>
499
+ : children
500
+ return (
501
+ <span
502
+ ref={ref}
503
+ role="link"
504
+ aria-disabled="true"
505
+ aria-current="page"
506
+ className={cn('inline-flex items-center gap-2 min-w-0 max-w-full text-foreground', className)}
507
+ {...props}
508
+ >
509
+ {StartIcon && <StartIcon size={BREADCRUMB_ICON_SIZE[size]} aria-hidden className="shrink-0" />}
510
+ {wrappedChildren}
511
+ </span>
512
+ )
513
+ }
514
+ )
515
+ BreadcrumbPage.displayName = 'BreadcrumbPage'
516
+
517
+ // ── BreadcrumbSeparator ──────────────────────────────────────────────────────
518
+
519
+ interface BreadcrumbSeparatorProps extends React.ComponentPropsWithoutRef<'li'> {
520
+ children?: React.ReactNode
521
+ }
522
+
523
+ // code-quality-allow: long-function — foundational composite main body — 拆 sub-fn 會複雜化 local state / ref / context binding
524
+ const BreadcrumbSeparator = React.forwardRef<HTMLLIElement, BreadcrumbSeparatorProps>(
525
+ ({ children, className, ...props }, ref) => {
526
+ const { size } = React.useContext(BreadcrumbContext)
527
+ return (
528
+ <li
529
+ ref={ref}
530
+ role="presentation"
531
+ aria-hidden="true"
532
+ // Phase B(2026-05-10):separator 永遠 shrink-0(必完整顯示,否則 path 視覺斷裂)
533
+ className={cn('inline-flex items-center text-fg-muted shrink-0', className)}
534
+ {...props}
535
+ >
536
+ {children ?? <ChevronRight size={BREADCRUMB_ICON_SIZE[size]} aria-hidden />}
537
+ </li>
538
+ )
539
+ }
540
+ )
541
+ BreadcrumbSeparator.displayName = 'BreadcrumbSeparator'
542
+
543
+ // ── BreadcrumbEllipsis ───────────────────────────────────────────────────────
544
+
545
+ /**
546
+ * BreadcrumbEllipsis — 折疊路徑的 "⋯" 按鈕
547
+ *
548
+ * 2026-05-10 重寫:消費 `ItemInlineActionButton`(primitive SSOT)取代自刻 `<button>`。
549
+ * Per inline-action.spec.md L106-131 predicate Q1+Q2+Q3 全指向 Inline Action:
550
+ * - Q1 點了要做事嗎?是(展開折疊路徑 dropdown)
551
+ * - Q2 位置?BreadcrumbList row inline flow(host 內)
552
+ * - Q3 row 多大?14-16px text row(compact tier)→ Inline Action
553
+ * + 對齊 M1「視覺決策前必消費 SSOT」+ Mindset #2「優先消費既有」。
554
+ *
555
+ * 配合 DropdownMenuTrigger asChild 使用:
556
+ *
557
+ * ```tsx
558
+ * <DropdownMenu>
559
+ * <DropdownMenuTrigger asChild>
560
+ * <BreadcrumbEllipsis />
561
+ * </DropdownMenuTrigger>
562
+ * <DropdownMenuContent>
563
+ * <DropdownMenuItem asChild><a href="/org">組織</a></DropdownMenuItem>
564
+ * </DropdownMenuContent>
565
+ * </DropdownMenu>
566
+ * ```
567
+ *
568
+ * `overlayTrigger=true` 視覺鎖:DropdownMenu open 期間 button 維持 hover bg(對齊
569
+ * shadcn / Radix Themes / Material 的 overlay trigger canonical,inline-action.spec.md
570
+ * 「Overlay trigger canonical」段)。
571
+ */
572
+ type BreadcrumbEllipsisProps = Omit<React.ComponentPropsWithoutRef<typeof ItemInlineActionButton>, 'icon' | 'size'>
573
+
574
+ const BreadcrumbEllipsis = React.forwardRef<HTMLButtonElement, BreadcrumbEllipsisProps>(
575
+ ({ 'aria-label': ariaLabel = '顯示折疊路徑' /* i18n-allow: DS default; consumer override via aria-label prop */, ...props }, ref) => {
576
+ return (
577
+ <ItemInlineActionButton
578
+ ref={ref}
579
+ icon={MoreHorizontal}
580
+ size="md" // Breadcrumb 不在 RowSizeProvider 樹內,固定 md(16px icon + 18px hover bg,對齊 inline-action.spec.md 尺寸表)
581
+ aria-label={ariaLabel}
582
+ overlayTrigger
583
+ {...props}
584
+ />
585
+ )
586
+ }
587
+ )
588
+ BreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis'
589
+
590
+ // Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
591
+ // Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
592
+ export const breadcrumbMeta = {
593
+ component: 'Breadcrumb',
594
+ family: null, // non-family composite / overlay / layout
595
+ variants: {
596
+
597
+ },
598
+ sizes: {
599
+
600
+ },
601
+ states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
602
+ tokens: {
603
+ bg: [],
604
+ fg: ['text-fg-muted', 'text-fg-secondary', 'text-foreground'],
605
+ ring: ['ring-ring'],
606
+ },
607
+ } as const
608
+
609
+ export {
610
+ Breadcrumb,
611
+ BreadcrumbList,
612
+ BreadcrumbItem,
613
+ BreadcrumbLink,
614
+ BreadcrumbPage,
615
+ BreadcrumbSeparator,
616
+ BreadcrumbEllipsis,
617
+ }
618
+ export type { BreadcrumbSize, BreadcrumbListProps, BreadcrumbEllipsisProps }
619
+ // BreadcrumbItemSpec 已在上方 `export interface BreadcrumbItemSpec` 直接 export