@qijenchen/design-system 0.1.0-beta.4 → 0.1.0-beta.6

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 (386) hide show
  1. package/dist/components/Accordion/accordion.d.ts +37 -0
  2. package/dist/components/Accordion/accordion.d.ts.map +1 -0
  3. package/dist/components/Accordion/accordion.js +78 -0
  4. package/dist/components/Accordion/accordion.js.map +1 -0
  5. package/dist/components/Alert/alert.d.ts +47 -0
  6. package/dist/components/Alert/alert.d.ts.map +1 -0
  7. package/dist/components/Alert/alert.js +132 -0
  8. package/dist/components/Alert/alert.js.map +1 -0
  9. package/dist/components/AppShell/_demo-helpers.d.ts +49 -0
  10. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -0
  11. package/dist/components/AppShell/app-shell.d.ts +76 -0
  12. package/dist/components/AppShell/app-shell.d.ts.map +1 -0
  13. package/dist/components/AppShell/app-shell.js +214 -0
  14. package/dist/components/AppShell/app-shell.js.map +1 -0
  15. package/dist/components/AspectRatio/aspect-ratio.d.ts +40 -0
  16. package/dist/components/AspectRatio/aspect-ratio.d.ts.map +1 -0
  17. package/dist/components/AspectRatio/aspect-ratio.js +23 -0
  18. package/dist/components/AspectRatio/aspect-ratio.js.map +1 -0
  19. package/dist/components/Avatar/avatar.d.ts +85 -0
  20. package/dist/components/Avatar/avatar.d.ts.map +1 -0
  21. package/dist/components/Avatar/avatar.js +195 -0
  22. package/dist/components/Avatar/avatar.js.map +1 -0
  23. package/dist/components/Badge/badge.d.ts +43 -0
  24. package/dist/components/Badge/badge.d.ts.map +1 -0
  25. package/dist/components/Badge/badge.js +69 -0
  26. package/dist/components/Badge/badge.js.map +1 -0
  27. package/dist/components/Breadcrumb/breadcrumb.d.ts +163 -0
  28. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -0
  29. package/dist/components/Breadcrumb/breadcrumb.js +305 -0
  30. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -0
  31. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +46 -0
  32. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -0
  33. package/dist/components/BulkActionBar/bulk-action-bar.js +78 -0
  34. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -0
  35. package/dist/components/Button/button-group.d.ts +49 -0
  36. package/dist/components/Button/button-group.d.ts.map +1 -0
  37. package/dist/components/Button/button-group.js +46 -0
  38. package/dist/components/Button/button-group.js.map +1 -0
  39. package/dist/components/Button/button.d.ts +203 -0
  40. package/dist/components/Button/button.d.ts.map +1 -0
  41. package/dist/components/Button/button.js +309 -0
  42. package/dist/components/Button/button.js.map +1 -0
  43. package/dist/components/Calendar/calendar.d.ts +81 -0
  44. package/dist/components/Calendar/calendar.d.ts.map +1 -0
  45. package/dist/components/Calendar/calendar.js +282 -0
  46. package/dist/components/Calendar/calendar.js.map +1 -0
  47. package/dist/components/Carousel/carousel.d.ts +61 -0
  48. package/dist/components/Carousel/carousel.d.ts.map +1 -0
  49. package/dist/components/Carousel/carousel.js +276 -0
  50. package/dist/components/Carousel/carousel.js.map +1 -0
  51. package/dist/components/Chart/chart.d.ts +94 -0
  52. package/dist/components/Chart/chart.d.ts.map +1 -0
  53. package/dist/components/Chart/chart.js +233 -0
  54. package/dist/components/Chart/chart.js.map +1 -0
  55. package/dist/components/Checkbox/checkbox-group.d.ts +58 -0
  56. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -0
  57. package/dist/components/Checkbox/checkbox-group.js +28 -0
  58. package/dist/components/Checkbox/checkbox-group.js.map +1 -0
  59. package/dist/components/Checkbox/checkbox.d.ts +73 -0
  60. package/dist/components/Checkbox/checkbox.d.ts.map +1 -0
  61. package/dist/components/Checkbox/checkbox.js +125 -0
  62. package/dist/components/Checkbox/checkbox.js.map +1 -0
  63. package/dist/components/Chip/chip.d.ts +54 -0
  64. package/dist/components/Chip/chip.d.ts.map +1 -0
  65. package/dist/components/Chip/chip.js +224 -0
  66. package/dist/components/Chip/chip.js.map +1 -0
  67. package/dist/components/CircularProgress/circular-progress.d.ts +40 -0
  68. package/dist/components/CircularProgress/circular-progress.d.ts.map +1 -0
  69. package/dist/components/CircularProgress/circular-progress.js +118 -0
  70. package/dist/components/CircularProgress/circular-progress.js.map +1 -0
  71. package/dist/components/Coachmark/coachmark.d.ts +100 -0
  72. package/dist/components/Coachmark/coachmark.d.ts.map +1 -0
  73. package/dist/components/Coachmark/coachmark.js +107 -0
  74. package/dist/components/Coachmark/coachmark.js.map +1 -0
  75. package/dist/components/Combobox/combobox.d.ts +150 -0
  76. package/dist/components/Combobox/combobox.d.ts.map +1 -0
  77. package/dist/components/Combobox/combobox.js +595 -0
  78. package/dist/components/Combobox/combobox.js.map +1 -0
  79. package/dist/components/Command/command.d.ts +106 -0
  80. package/dist/components/Command/command.d.ts.map +1 -0
  81. package/dist/components/Command/command.js +123 -0
  82. package/dist/components/Command/command.js.map +1 -0
  83. package/dist/components/DataTable/active-editor-controller.d.ts +66 -0
  84. package/dist/components/DataTable/active-editor-controller.d.ts.map +1 -0
  85. package/dist/components/DataTable/cell-registry.d.ts +37 -0
  86. package/dist/components/DataTable/cell-registry.d.ts.map +1 -0
  87. package/dist/components/DataTable/cell-registry.js +377 -0
  88. package/dist/components/DataTable/cell-registry.js.map +1 -0
  89. package/dist/components/DataTable/column-types.d.ts +145 -0
  90. package/dist/components/DataTable/column-types.d.ts.map +1 -0
  91. package/dist/components/DataTable/column-types.js +17 -0
  92. package/dist/components/DataTable/column-types.js.map +1 -0
  93. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +49 -0
  94. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -0
  95. package/dist/components/DataTable/data-table-filter-panel.d.ts +30 -0
  96. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -0
  97. package/dist/components/DataTable/data-table-interaction-layer.d.ts +78 -0
  98. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -0
  99. package/dist/components/DataTable/data-table-interaction-layer.js +220 -0
  100. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -0
  101. package/dist/components/DataTable/data-table-sort-manager.d.ts +19 -0
  102. package/dist/components/DataTable/data-table-sort-manager.d.ts.map +1 -0
  103. package/dist/components/DataTable/data-table.d.ts +181 -0
  104. package/dist/components/DataTable/data-table.d.ts.map +1 -0
  105. package/dist/components/DataTable/data-table.js +1851 -0
  106. package/dist/components/DataTable/data-table.js.map +1 -0
  107. package/dist/components/DataTable/filter-operators.d.ts +116 -0
  108. package/dist/components/DataTable/filter-operators.d.ts.map +1 -0
  109. package/dist/components/DataTable/filter-tree.d.ts +66 -0
  110. package/dist/components/DataTable/filter-tree.d.ts.map +1 -0
  111. package/dist/components/DataTable/lib/column-meta.d.ts +49 -0
  112. package/dist/components/DataTable/lib/column-meta.d.ts.map +1 -0
  113. package/dist/components/DateGrid/date-grid.d.ts +61 -0
  114. package/dist/components/DateGrid/date-grid.d.ts.map +1 -0
  115. package/dist/components/DateGrid/date-grid.js +168 -0
  116. package/dist/components/DateGrid/date-grid.js.map +1 -0
  117. package/dist/components/DatePicker/date-picker.d.ts +119 -0
  118. package/dist/components/DatePicker/date-picker.d.ts.map +1 -0
  119. package/dist/components/DatePicker/date-picker.js +743 -0
  120. package/dist/components/DatePicker/date-picker.js.map +1 -0
  121. package/dist/components/DescriptionList/description-list.d.ts +60 -0
  122. package/dist/components/DescriptionList/description-list.d.ts.map +1 -0
  123. package/dist/components/DescriptionList/description-list.js +77 -0
  124. package/dist/components/DescriptionList/description-list.js.map +1 -0
  125. package/dist/components/Dialog/dialog.d.ts +54 -0
  126. package/dist/components/Dialog/dialog.d.ts.map +1 -0
  127. package/dist/components/Dialog/dialog.js +151 -0
  128. package/dist/components/Dialog/dialog.js.map +1 -0
  129. package/dist/components/DropdownMenu/dropdown-menu.d.ts +111 -0
  130. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -0
  131. package/dist/components/DropdownMenu/dropdown-menu.js +288 -0
  132. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -0
  133. package/dist/components/Empty/empty.d.ts +40 -0
  134. package/dist/components/Empty/empty.d.ts.map +1 -0
  135. package/dist/components/Empty/empty.js +66 -0
  136. package/dist/components/Empty/empty.js.map +1 -0
  137. package/dist/components/Field/field-context.d.ts +77 -0
  138. package/dist/components/Field/field-context.d.ts.map +1 -0
  139. package/dist/components/Field/field-context.js +37 -0
  140. package/dist/components/Field/field-context.js.map +1 -0
  141. package/dist/components/Field/field-types.d.ts +5 -0
  142. package/dist/components/Field/field-types.d.ts.map +1 -0
  143. package/dist/components/Field/field-types.js +13 -0
  144. package/dist/components/Field/field-types.js.map +1 -0
  145. package/dist/components/Field/field-wrapper.d.ts +17 -0
  146. package/dist/components/Field/field-wrapper.d.ts.map +1 -0
  147. package/dist/components/Field/field-wrapper.js +252 -0
  148. package/dist/components/Field/field-wrapper.js.map +1 -0
  149. package/dist/components/Field/field.d.ts +127 -0
  150. package/dist/components/Field/field.d.ts.map +1 -0
  151. package/dist/components/Field/field.js +295 -0
  152. package/dist/components/Field/field.js.map +1 -0
  153. package/dist/components/FieldControlGroup/field-control-group.d.ts +74 -0
  154. package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -0
  155. package/dist/components/FieldControlGroup/field-control-group.js +62 -0
  156. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -0
  157. package/dist/components/FileItem/file-item.d.ts +44 -0
  158. package/dist/components/FileItem/file-item.d.ts.map +1 -0
  159. package/dist/components/FileItem/file-item.js +202 -0
  160. package/dist/components/FileItem/file-item.js.map +1 -0
  161. package/dist/components/FileUpload/file-upload.d.ts +97 -0
  162. package/dist/components/FileUpload/file-upload.d.ts.map +1 -0
  163. package/dist/components/FileUpload/file-upload.js +231 -0
  164. package/dist/components/FileUpload/file-upload.js.map +1 -0
  165. package/dist/components/FileViewer/file-viewer-types.d.ts +73 -0
  166. package/dist/components/FileViewer/file-viewer-types.d.ts.map +1 -0
  167. package/dist/components/FileViewer/file-viewer.d.ts +82 -0
  168. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -0
  169. package/dist/components/FileViewer/file-viewer.js +752 -0
  170. package/dist/components/FileViewer/file-viewer.js.map +1 -0
  171. package/dist/components/FileViewer/image-renderer.d.ts +9 -0
  172. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -0
  173. package/dist/components/FileViewer/image-renderer.js +165 -0
  174. package/dist/components/FileViewer/image-renderer.js.map +1 -0
  175. package/dist/components/HoverCard/hover-card.d.ts +30 -0
  176. package/dist/components/HoverCard/hover-card.d.ts.map +1 -0
  177. package/dist/components/HoverCard/hover-card.js +61 -0
  178. package/dist/components/HoverCard/hover-card.js.map +1 -0
  179. package/dist/components/Input/input.d.ts +72 -0
  180. package/dist/components/Input/input.d.ts.map +1 -0
  181. package/dist/components/Input/input.js +148 -0
  182. package/dist/components/Input/input.js.map +1 -0
  183. package/dist/components/LinkInput/link-input.d.ts +46 -0
  184. package/dist/components/LinkInput/link-input.d.ts.map +1 -0
  185. package/dist/components/LinkInput/link-input.js +215 -0
  186. package/dist/components/LinkInput/link-input.js.map +1 -0
  187. package/dist/components/Menu/menu-item.d.ts +83 -0
  188. package/dist/components/Menu/menu-item.d.ts.map +1 -0
  189. package/dist/components/Menu/menu-item.js +209 -0
  190. package/dist/components/Menu/menu-item.js.map +1 -0
  191. package/dist/components/NameCard/name-card.d.ts +85 -0
  192. package/dist/components/NameCard/name-card.d.ts.map +1 -0
  193. package/dist/components/NameCard/name-card.js +153 -0
  194. package/dist/components/NameCard/name-card.js.map +1 -0
  195. package/dist/components/Notice/notice.d.ts +69 -0
  196. package/dist/components/Notice/notice.d.ts.map +1 -0
  197. package/dist/components/Notice/notice.js +121 -0
  198. package/dist/components/Notice/notice.js.map +1 -0
  199. package/dist/components/NumberInput/number-input.d.ts +57 -0
  200. package/dist/components/NumberInput/number-input.d.ts.map +1 -0
  201. package/dist/components/NumberInput/number-input.js +131 -0
  202. package/dist/components/NumberInput/number-input.js.map +1 -0
  203. package/dist/components/OverflowIndicator/overflow-indicator.d.ts +23 -0
  204. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -0
  205. package/dist/components/OverflowIndicator/overflow-indicator.js +111 -0
  206. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -0
  207. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +57 -0
  208. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts.map +1 -0
  209. package/dist/components/PeoplePicker/avatar-stack-overflow.js +35 -0
  210. package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -0
  211. package/dist/components/PeoplePicker/people-picker-helpers.d.ts +7 -0
  212. package/dist/components/PeoplePicker/people-picker-helpers.d.ts.map +1 -0
  213. package/dist/components/PeoplePicker/people-picker-helpers.js +25 -0
  214. package/dist/components/PeoplePicker/people-picker-helpers.js.map +1 -0
  215. package/dist/components/PeoplePicker/people-picker.d.ts +77 -0
  216. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -0
  217. package/dist/components/PeoplePicker/people-picker.js +263 -0
  218. package/dist/components/PeoplePicker/people-picker.js.map +1 -0
  219. package/dist/components/PeoplePicker/person-display.d.ts +66 -0
  220. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -0
  221. package/dist/components/PeoplePicker/person-display.js +203 -0
  222. package/dist/components/PeoplePicker/person-display.js.map +1 -0
  223. package/dist/components/Popover/popover.d.ts +50 -0
  224. package/dist/components/Popover/popover.d.ts.map +1 -0
  225. package/dist/components/Popover/popover.js +112 -0
  226. package/dist/components/Popover/popover.js.map +1 -0
  227. package/dist/components/ProgressBar/progress-bar.d.ts +37 -0
  228. package/dist/components/ProgressBar/progress-bar.d.ts.map +1 -0
  229. package/dist/components/ProgressBar/progress-bar.js +86 -0
  230. package/dist/components/ProgressBar/progress-bar.js.map +1 -0
  231. package/dist/components/RadioGroup/radio-group.d.ts +78 -0
  232. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -0
  233. package/dist/components/RadioGroup/radio-group.js +153 -0
  234. package/dist/components/RadioGroup/radio-group.js.map +1 -0
  235. package/dist/components/Rating/rating.d.ts +46 -0
  236. package/dist/components/Rating/rating.d.ts.map +1 -0
  237. package/dist/components/Rating/rating.js +179 -0
  238. package/dist/components/Rating/rating.js.map +1 -0
  239. package/dist/components/ScrollArea/scroll-area.d.ts +45 -0
  240. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -0
  241. package/dist/components/ScrollArea/scroll-area.js +65 -0
  242. package/dist/components/ScrollArea/scroll-area.js.map +1 -0
  243. package/dist/components/SegmentedControl/segmented-control.d.ts +102 -0
  244. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -0
  245. package/dist/components/SegmentedControl/segmented-control.js +171 -0
  246. package/dist/components/SegmentedControl/segmented-control.js.map +1 -0
  247. package/dist/components/Select/select.d.ts +102 -0
  248. package/dist/components/Select/select.d.ts.map +1 -0
  249. package/dist/components/Select/select.js +435 -0
  250. package/dist/components/Select/select.js.map +1 -0
  251. package/dist/components/SelectMenu/select-menu.d.ts +103 -0
  252. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -0
  253. package/dist/components/SelectMenu/select-menu.js +239 -0
  254. package/dist/components/SelectMenu/select-menu.js.map +1 -0
  255. package/dist/components/SelectionControl/selection-item.d.ts +69 -0
  256. package/dist/components/SelectionControl/selection-item.d.ts.map +1 -0
  257. package/dist/components/SelectionControl/selection-item.js +142 -0
  258. package/dist/components/SelectionControl/selection-item.js.map +1 -0
  259. package/dist/components/Separator/separator.d.ts +17 -0
  260. package/dist/components/Separator/separator.d.ts.map +1 -0
  261. package/dist/components/Separator/separator.js +39 -0
  262. package/dist/components/Separator/separator.js.map +1 -0
  263. package/dist/components/Sheet/sheet.d.ts +56 -0
  264. package/dist/components/Sheet/sheet.d.ts.map +1 -0
  265. package/dist/components/Sheet/sheet.js +145 -0
  266. package/dist/components/Sheet/sheet.js.map +1 -0
  267. package/dist/components/Sidebar/sidebar.d.ts +195 -0
  268. package/dist/components/Sidebar/sidebar.d.ts.map +1 -0
  269. package/dist/components/Sidebar/sidebar.js +826 -0
  270. package/dist/components/Sidebar/sidebar.js.map +1 -0
  271. package/dist/components/Skeleton/skeleton.d.ts +16 -0
  272. package/dist/components/Skeleton/skeleton.d.ts.map +1 -0
  273. package/dist/components/Skeleton/skeleton.js +30 -0
  274. package/dist/components/Skeleton/skeleton.js.map +1 -0
  275. package/dist/components/Slider/slider.d.ts +48 -0
  276. package/dist/components/Slider/slider.d.ts.map +1 -0
  277. package/dist/components/Slider/slider.js +108 -0
  278. package/dist/components/Slider/slider.js.map +1 -0
  279. package/dist/components/Steps/steps.d.ts +71 -0
  280. package/dist/components/Steps/steps.d.ts.map +1 -0
  281. package/dist/components/Steps/steps.js +583 -0
  282. package/dist/components/Steps/steps.js.map +1 -0
  283. package/dist/components/Switch/switch.d.ts +112 -0
  284. package/dist/components/Switch/switch.d.ts.map +1 -0
  285. package/dist/components/Switch/switch.js +179 -0
  286. package/dist/components/Switch/switch.js.map +1 -0
  287. package/dist/components/Tabs/tabs.d.ts +104 -0
  288. package/dist/components/Tabs/tabs.d.ts.map +1 -0
  289. package/dist/components/Tabs/tabs.js +316 -0
  290. package/dist/components/Tabs/tabs.js.map +1 -0
  291. package/dist/components/Tag/tag.d.ts +86 -0
  292. package/dist/components/Tag/tag.d.ts.map +1 -0
  293. package/dist/components/Tag/tag.js +172 -0
  294. package/dist/components/Tag/tag.js.map +1 -0
  295. package/dist/components/Textarea/textarea.d.ts +74 -0
  296. package/dist/components/Textarea/textarea.d.ts.map +1 -0
  297. package/dist/components/Textarea/textarea.js +224 -0
  298. package/dist/components/Textarea/textarea.js.map +1 -0
  299. package/dist/components/TimePicker/time-columns.d.ts +46 -0
  300. package/dist/components/TimePicker/time-columns.d.ts.map +1 -0
  301. package/dist/components/TimePicker/time-columns.js +173 -0
  302. package/dist/components/TimePicker/time-columns.js.map +1 -0
  303. package/dist/components/TimePicker/time-picker.d.ts +94 -0
  304. package/dist/components/TimePicker/time-picker.d.ts.map +1 -0
  305. package/dist/components/TimePicker/time-picker.js +253 -0
  306. package/dist/components/TimePicker/time-picker.js.map +1 -0
  307. package/dist/components/Toast/toast.d.ts +61 -0
  308. package/dist/components/Toast/toast.d.ts.map +1 -0
  309. package/dist/components/Toast/toast.js +76 -0
  310. package/dist/components/Toast/toast.js.map +1 -0
  311. package/dist/components/Tooltip/tooltip.d.ts +20 -0
  312. package/dist/components/Tooltip/tooltip.d.ts.map +1 -0
  313. package/dist/components/Tooltip/tooltip.js +53 -0
  314. package/dist/components/Tooltip/tooltip.js.map +1 -0
  315. package/dist/components/TreeView/tree-view.d.ts +166 -0
  316. package/dist/components/TreeView/tree-view.d.ts.map +1 -0
  317. package/dist/components/TreeView/tree-view.js +617 -0
  318. package/dist/components/TreeView/tree-view.js.map +1 -0
  319. package/dist/hooks/use-controllable.d.ts +16 -0
  320. package/dist/hooks/use-controllable.d.ts.map +1 -0
  321. package/dist/hooks/use-controllable.js +26 -0
  322. package/dist/hooks/use-controllable.js.map +1 -0
  323. package/dist/hooks/use-is-narrow-viewport.d.ts +2 -0
  324. package/dist/hooks/use-is-narrow-viewport.d.ts.map +1 -0
  325. package/dist/hooks/use-is-narrow-viewport.js +19 -0
  326. package/dist/hooks/use-is-narrow-viewport.js.map +1 -0
  327. package/dist/hooks/use-is-touch-device.d.ts +8 -0
  328. package/dist/hooks/use-is-touch-device.d.ts.map +1 -0
  329. package/dist/hooks/use-is-touch-device.js +16 -0
  330. package/dist/hooks/use-is-touch-device.js.map +1 -0
  331. package/dist/hooks/use-overflow-items.d.ts +124 -0
  332. package/dist/hooks/use-overflow-items.d.ts.map +1 -0
  333. package/dist/hooks/use-overflow-items.js +97 -0
  334. package/dist/hooks/use-overflow-items.js.map +1 -0
  335. package/dist/index.d.ts +74 -0
  336. package/dist/index.d.ts.map +1 -0
  337. package/dist/index.js +371 -0
  338. package/dist/index.js.map +1 -0
  339. package/dist/lib/drag-visual.d.ts +158 -0
  340. package/dist/lib/drag-visual.d.ts.map +1 -0
  341. package/dist/lib/drag-visual.js +96 -0
  342. package/dist/lib/drag-visual.js.map +1 -0
  343. package/dist/lib/i18n/i18n-context.d.ts +105 -0
  344. package/dist/lib/i18n/i18n-context.d.ts.map +1 -0
  345. package/dist/lib/multi-select-ordering.d.ts +54 -0
  346. package/dist/lib/multi-select-ordering.d.ts.map +1 -0
  347. package/dist/lib/multi-select-ordering.js +13 -0
  348. package/dist/lib/multi-select-ordering.js.map +1 -0
  349. package/dist/lib/utils.d.ts +12 -0
  350. package/dist/lib/utils.d.ts.map +1 -0
  351. package/dist/lib/utils.js +79 -0
  352. package/dist/lib/utils.js.map +1 -0
  353. package/dist/patterns/element-anatomy/item-anatomy.d.ts +370 -0
  354. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -0
  355. package/dist/patterns/element-anatomy/item-anatomy.js +272 -0
  356. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -0
  357. package/dist/patterns/header-canonical/chrome-header.d.ts +80 -0
  358. package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -0
  359. package/dist/patterns/header-canonical/chrome-header.js +75 -0
  360. package/dist/patterns/header-canonical/chrome-header.js.map +1 -0
  361. package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts +101 -0
  362. package/dist/patterns/horizontal-overflow/horizontal-overflow.d.ts.map +1 -0
  363. package/dist/patterns/horizontal-overflow/horizontal-overflow.js +105 -0
  364. package/dist/patterns/horizontal-overflow/horizontal-overflow.js.map +1 -0
  365. package/dist/patterns/overlay-surface/overlay-surface.d.ts +28 -0
  366. package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -0
  367. package/dist/patterns/overlay-surface/overlay-surface.js +85 -0
  368. package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -0
  369. package/dist/patterns/resize-handle/resize-handle.d.ts +102 -0
  370. package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -0
  371. package/dist/patterns/resize-handle/resize-handle.js +74 -0
  372. package/dist/patterns/resize-handle/resize-handle.js.map +1 -0
  373. package/dist/stories-helpers/anatomy/anatomy-utils.d.ts +40 -0
  374. package/dist/stories-helpers/anatomy/anatomy-utils.d.ts.map +1 -0
  375. package/dist/style.css +457 -0
  376. package/dist/tokens/elevation/overlay-geometry.d.ts +12 -0
  377. package/dist/tokens/elevation/overlay-geometry.d.ts.map +1 -0
  378. package/dist/tokens/elevation/overlay-geometry.js +7 -0
  379. package/dist/tokens/elevation/overlay-geometry.js.map +1 -0
  380. package/dist/tokens/motion/motion.d.ts +15 -0
  381. package/dist/tokens/motion/motion.d.ts.map +1 -0
  382. package/dist/tokens/motion/motion.js +9 -0
  383. package/dist/tokens/motion/motion.js.map +1 -0
  384. package/dist/tokens/uiSize/icon-size.d.ts +53 -0
  385. package/dist/tokens/uiSize/icon-size.d.ts.map +1 -0
  386. package/package.json +3 -10
@@ -0,0 +1,214 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { X } from "lucide-react";
4
+ import { Sheet, SheetContent } from "../Sheet/sheet.js";
5
+ import { Button } from "../Button/button.js";
6
+ import { ScrollArea } from "../ScrollArea/scroll-area.js";
7
+ import { ChromeHeader } from "../../patterns/header-canonical/chrome-header.js";
8
+ import { useIsNarrowViewport } from "../../hooks/use-is-narrow-viewport.js";
9
+ import { cn } from "../../lib/utils.js";
10
+ const AppShellContext = React.createContext(null);
11
+ function useAppShell() {
12
+ const ctx = React.useContext(AppShellContext);
13
+ if (!ctx) throw new Error("AppShellAside must be used within <AppShell>");
14
+ return ctx;
15
+ }
16
+ const XL_BREAKPOINT_PX = 1280;
17
+ function useIsXl() {
18
+ const [isXl, setIsXl] = React.useState(() => {
19
+ if (typeof window === "undefined") return false;
20
+ return window.matchMedia(`(min-width: ${XL_BREAKPOINT_PX}px)`).matches;
21
+ });
22
+ React.useEffect(() => {
23
+ const mq = window.matchMedia(`(min-width: ${XL_BREAKPOINT_PX}px)`);
24
+ const handler = (e) => setIsXl(e.matches);
25
+ mq.addEventListener("change", handler);
26
+ return () => mq.removeEventListener("change", handler);
27
+ }, []);
28
+ return isXl;
29
+ }
30
+ const ASIDE_WIDTH_MIN = 240;
31
+ const ASIDE_WIDTH_MAX = 640;
32
+ const ASIDE_WIDTH_DEFAULT = 320;
33
+ function resolveAsideWidth(width, isXl) {
34
+ if (typeof width === "number") {
35
+ return Math.max(ASIDE_WIDTH_MIN, Math.min(ASIDE_WIDTH_MAX, width));
36
+ }
37
+ if (width && typeof width === "object") {
38
+ const v = (isXl ? width.xl ?? width.md : width.md) ?? ASIDE_WIDTH_DEFAULT;
39
+ return Math.max(ASIDE_WIDTH_MIN, Math.min(ASIDE_WIDTH_MAX, v));
40
+ }
41
+ return ASIDE_WIDTH_DEFAULT;
42
+ }
43
+ function SkipToMain() {
44
+ return /* @__PURE__ */ jsx(
45
+ "a",
46
+ {
47
+ href: "#app-shell-main",
48
+ className: cn(
49
+ "sr-only focus:not-sr-only",
50
+ "focus:fixed focus:top-2 focus:left-2 focus:z-50",
51
+ "focus:px-3 focus:py-2 focus:rounded-md",
52
+ "focus:bg-surface focus:text-foreground focus:shadow-[var(--elevation-200)]",
53
+ "focus:outline-none focus:ring-2 focus:ring-primary"
54
+ ),
55
+ children: "Skip to main content"
56
+ }
57
+ );
58
+ }
59
+ const AppShell = React.forwardRef(
60
+ ({
61
+ layout = "primary-sidebar",
62
+ sidebar,
63
+ header,
64
+ globalHeader,
65
+ aside,
66
+ asideOpen: asideOpenProp,
67
+ onAsideOpenChange,
68
+ children,
69
+ className,
70
+ ...props
71
+ }, ref) => {
72
+ const [asideOpenInternal, setAsideOpenInternal] = React.useState(false);
73
+ const isControlled = asideOpenProp !== void 0;
74
+ const asideOpen = isControlled ? asideOpenProp : asideOpenInternal;
75
+ const setAsideOpen = React.useCallback(
76
+ (open) => {
77
+ if (!isControlled) setAsideOpenInternal(open);
78
+ onAsideOpenChange == null ? void 0 : onAsideOpenChange(open);
79
+ },
80
+ [isControlled, onAsideOpenChange]
81
+ );
82
+ const isMobile = useIsNarrowViewport();
83
+ React.useEffect(() => {
84
+ const onKey = (e) => {
85
+ if (e.key === "." && (e.metaKey || e.ctrlKey)) {
86
+ e.preventDefault();
87
+ setAsideOpen(!asideOpen);
88
+ }
89
+ };
90
+ window.addEventListener("keydown", onKey);
91
+ return () => window.removeEventListener("keydown", onKey);
92
+ }, [asideOpen, setAsideOpen]);
93
+ const ctxValue = React.useMemo(
94
+ () => ({ layout, asideOpen, setAsideOpen, isMobile }),
95
+ [layout, asideOpen, setAsideOpen, isMobile]
96
+ );
97
+ if (layout === "primary-header") {
98
+ return /* @__PURE__ */ jsx(AppShellContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxs(
99
+ "div",
100
+ {
101
+ ref,
102
+ className: cn("flex h-svh w-full flex-col overflow-hidden bg-canvas", className),
103
+ ...props,
104
+ children: [
105
+ /* @__PURE__ */ jsx(SkipToMain, {}),
106
+ globalHeader && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: globalHeader }),
107
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 min-h-0 w-full", children: [
108
+ sidebar,
109
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden", children: [
110
+ header && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: header }),
111
+ /* @__PURE__ */ jsx(
112
+ "main",
113
+ {
114
+ id: "app-shell-main",
115
+ tabIndex: -1,
116
+ className: "flex-1 min-w-0 min-h-0 overflow-y-auto focus:outline-none",
117
+ children
118
+ }
119
+ )
120
+ ] }),
121
+ aside
122
+ ] })
123
+ ]
124
+ }
125
+ ) });
126
+ }
127
+ return /* @__PURE__ */ jsx(AppShellContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxs(
128
+ "div",
129
+ {
130
+ ref,
131
+ className: cn("flex h-svh w-full overflow-hidden bg-canvas", className),
132
+ ...props,
133
+ children: [
134
+ /* @__PURE__ */ jsx(SkipToMain, {}),
135
+ sidebar,
136
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden", children: [
137
+ header && // Header 在 main column 內(main col sibling,非 main descendant)→ 跟 W3C ARIA in HTML
138
+ // banner rule 對照:`<header>` 在 main descendant 才不是 banner,本 ChromeHeader 是 <div>
139
+ // 所以本來就不會被 banner role 計算。仍包 wrap div not <header> 確保不無意觸發 banner。
140
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: header }),
141
+ /* @__PURE__ */ jsx(
142
+ "main",
143
+ {
144
+ id: "app-shell-main",
145
+ tabIndex: -1,
146
+ className: "flex-1 min-h-0 overflow-y-auto focus:outline-none",
147
+ children
148
+ }
149
+ )
150
+ ] }),
151
+ aside
152
+ ]
153
+ }
154
+ ) });
155
+ }
156
+ );
157
+ AppShell.displayName = "AppShell";
158
+ const AppShellAside = React.forwardRef(
159
+ ({ title, width, children, className }, ref) => {
160
+ const { asideOpen, setAsideOpen, isMobile } = useAppShell();
161
+ const isXl = useIsXl();
162
+ const resolvedWidth = resolveAsideWidth(width, isXl);
163
+ const frame = /* @__PURE__ */ jsxs(Fragment, { children: [
164
+ /* @__PURE__ */ jsxs(ChromeHeader, { children: [
165
+ /* @__PURE__ */ jsx("h2", { className: "text-body-lg font-medium flex-1 truncate", children: title }),
166
+ /* @__PURE__ */ jsx(
167
+ Button,
168
+ {
169
+ iconOnly: true,
170
+ dismiss: true,
171
+ size: "sm",
172
+ startIcon: X,
173
+ "aria-label": "關閉",
174
+ onClick: () => setAsideOpen(false)
175
+ }
176
+ )
177
+ ] }),
178
+ /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 min-h-0", children })
179
+ ] });
180
+ if (isMobile) {
181
+ return /* @__PURE__ */ jsx(Sheet, { open: asideOpen, onOpenChange: setAsideOpen, children: /* @__PURE__ */ jsx(
182
+ SheetContent,
183
+ {
184
+ side: "right",
185
+ className: "w-[min(90vw,var(--app-shell-aside-modal-width))] flex flex-col p-0 [&>button]:hidden",
186
+ style: { ["--app-shell-aside-modal-width"]: `${resolvedWidth}px` },
187
+ children: frame
188
+ }
189
+ ) });
190
+ }
191
+ if (!asideOpen) return null;
192
+ return /* @__PURE__ */ jsx(
193
+ "aside",
194
+ {
195
+ ref,
196
+ "aria-label": title,
197
+ className: cn(
198
+ "flex flex-col h-full min-h-0 overflow-hidden",
199
+ "bg-surface border-l border-divider",
200
+ className
201
+ ),
202
+ style: { width: resolvedWidth },
203
+ children: frame
204
+ }
205
+ );
206
+ }
207
+ );
208
+ AppShellAside.displayName = "AppShellAside";
209
+ export {
210
+ AppShell,
211
+ AppShellAside,
212
+ useAppShell
213
+ };
214
+ //# sourceMappingURL=app-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-shell.js","sources":["../../../src/components/AppShell/app-shell.tsx"],"sourcesContent":["// @benchmark-cited: 2026-05-19 — Mantine AppShell / Ant Layout / Material 3 Drawer / Atlassian Navigation System cite in app-shell.spec.md frontmatter.\n/**\n * AppShell — web service page-level layout primitive。\n *\n * 組合 Sidebar + ChromeHeader + Aside + main 成完整 page shell。SSOT 邊界:本 pattern only\n * own slot composition + layout mode + Aside responsive mode;不 own sidebar / header /\n * sheet 視覺(各自 spec own)。\n *\n * 對齊 Mantine AppShell compound API + Ant Layout slot 模式 + Material 3 standard/modal\n * drawer canonical(per spec.md frontmatter cite)。\n *\n * Spec SSOT:`patterns/app-shell/app-shell.spec.md`\n */\n\nimport * as React from 'react'\nimport { X as XIcon } from 'lucide-react'\nimport {\n Sheet,\n SheetContent,\n} from '@/design-system/components/Sheet/sheet'\nimport { Button } from '@/design-system/components/Button/button'\nimport { ScrollArea } from '@/design-system/components/ScrollArea/scroll-area'\nimport { ChromeHeader } from '@/design-system/patterns/header-canonical/chrome-header'\nimport { useIsNarrowViewport } from '@/design-system/hooks/use-is-narrow-viewport'\nimport { cn } from '@/lib/utils'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\ntype AppShellLayout = 'primary-sidebar' | 'primary-header'\n\nexport interface AppShellProps extends React.HTMLAttributes<HTMLDivElement> {\n /** primary-sidebar (Linear/Notion 派) | primary-header (GitHub/Slack 派);預設 primary-sidebar */\n layout?: AppShellLayout\n /** Sidebar 元素(必傳 Sidebar primitive,per Consumer 紀律)*/\n sidebar?: React.ReactNode\n /**\n * Local page header(永遠 render 在 main column 頂部,當前頁 actions / breadcrumb / page-level filter)。\n * 兩 layout mode 都會 render 此 slot — `primary-header` mode 多了 globalHeader 在上方,\n * **不取代** local header(per 2026-05-20 user clarification「primary-header = primary-sidebar + 一條 global header」)。\n */\n header?: React.ReactNode\n /**\n * Global header(僅 `primary-header` mode render)。橫跨整 viewport 的頂部 bar:\n * account avatar / workspace switcher / global search / notifications。\n * 對齊 GitHub top nav / Slack workspace bar / Gmail logo bar 慣例。\n * `primary-sidebar` mode 傳此 prop 會被忽略。\n */\n globalHeader?: React.ReactNode\n /** Aside 元素(`<AppShellAside>` sub-component);可選 */\n aside?: React.ReactNode\n /** Aside open state(modal mode 必須)*/\n asideOpen?: boolean\n onAsideOpenChange?: (open: boolean) => void\n /** Main content;`<main>` landmark + padding=0 */\n children: React.ReactNode\n}\n\nexport interface AppShellAsideProps {\n /** Required:modal mode 走 Sheet → aria-labelledby 強制,per sheet.spec.md:98 */\n title: string\n /** Width(number 或 breakpoint-keyed object);clamp min:240 max:640 */\n width?: number | { md?: number; xl?: number }\n /** Children content */\n children: React.ReactNode\n className?: string\n}\n\n// ── Context ──────────────────────────────────────────────────────────────────\n\ninterface AppShellContextValue {\n layout: AppShellLayout\n asideOpen: boolean\n setAsideOpen: (open: boolean) => void\n isMobile: boolean\n}\n\nconst AppShellContext = React.createContext<AppShellContextValue | null>(null)\n\nfunction useAppShell(): AppShellContextValue {\n const ctx = React.useContext(AppShellContext)\n if (!ctx) throw new Error('AppShellAside must be used within <AppShell>')\n return ctx\n}\n\n// Mobile breakpoint:**消費既有 `useIsNarrowViewport`**(`hooks/use-is-narrow-viewport.ts` SSOT,\n// 768px,跟 Sidebar SSOT 同源)— 不發明 local hook,per codex Layer B D2/D4 verdict 避 drift。\n\n// xl breakpoint(對齊 Tailwind v4 xl = 1280px,DS-wide consensus)\nconst XL_BREAKPOINT_PX = 1280\n\nfunction useIsXl(): boolean {\n const [isXl, setIsXl] = React.useState<boolean>(() => {\n if (typeof window === 'undefined') return false\n return window.matchMedia(`(min-width: ${XL_BREAKPOINT_PX}px)`).matches\n })\n\n React.useEffect(() => {\n const mq = window.matchMedia(`(min-width: ${XL_BREAKPOINT_PX}px)`)\n const handler = (e: MediaQueryListEvent) => setIsXl(e.matches)\n mq.addEventListener('change', handler)\n return () => mq.removeEventListener('change', handler)\n }, [])\n\n return isXl\n}\n\n// ── Width resolve(consumer 自傳 + clamp 240-640)──────────────────────────────\n\nconst ASIDE_WIDTH_MIN = 240\nconst ASIDE_WIDTH_MAX = 640\nconst ASIDE_WIDTH_DEFAULT = 320\n\nfunction resolveAsideWidth(width: AppShellAsideProps['width'], isXl: boolean): number {\n if (typeof width === 'number') {\n return Math.max(ASIDE_WIDTH_MIN, Math.min(ASIDE_WIDTH_MAX, width))\n }\n if (width && typeof width === 'object') {\n // breakpoint-keyed:xl viewport(≥1280px)用 xl,否則 md\n const v = (isXl ? width.xl ?? width.md : width.md) ?? ASIDE_WIDTH_DEFAULT\n return Math.max(ASIDE_WIDTH_MIN, Math.min(ASIDE_WIDTH_MAX, v))\n }\n return ASIDE_WIDTH_DEFAULT\n}\n\n// ── Skip-to-main link(a11y WCAG 2.4.1)───────────────────────────────────────\n\nfunction SkipToMain() {\n return (\n <a\n href=\"#app-shell-main\"\n className={cn(\n 'sr-only focus:not-sr-only',\n 'focus:fixed focus:top-2 focus:left-2 focus:z-50',\n 'focus:px-3 focus:py-2 focus:rounded-md',\n 'focus:bg-surface focus:text-foreground focus:shadow-[var(--elevation-200)]',\n 'focus:outline-none focus:ring-2 focus:ring-primary'\n )}\n >\n Skip to main content\n </a>\n )\n}\n\n// ── AppShell root ────────────────────────────────────────────────────────────\n\nconst AppShell = React.forwardRef<HTMLDivElement, AppShellProps>(\n (\n {\n layout = 'primary-sidebar',\n sidebar,\n header,\n globalHeader,\n aside,\n asideOpen: asideOpenProp,\n onAsideOpenChange,\n children,\n className,\n ...props\n },\n ref\n ) => {\n const [asideOpenInternal, setAsideOpenInternal] = React.useState(false)\n const isControlled = asideOpenProp !== undefined\n const asideOpen = isControlled ? asideOpenProp : asideOpenInternal\n\n const setAsideOpen = React.useCallback(\n (open: boolean) => {\n if (!isControlled) setAsideOpenInternal(open)\n onAsideOpenChange?.(open)\n },\n [isControlled, onAsideOpenChange]\n )\n\n const isMobile = useIsNarrowViewport()\n\n // ── Keyboard: cmd+. toggle aside ──\n // ⌘B sidebar toggle by Sidebar SSOT(本 component 不重覆 register)\n React.useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === '.' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n setAsideOpen(!asideOpen)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [asideOpen, setAsideOpen])\n\n const ctxValue = React.useMemo<AppShellContextValue>(\n () => ({ layout, asideOpen, setAsideOpen, isMobile }),\n [layout, asideOpen, setAsideOpen, isMobile]\n )\n\n // ── Layout grid(2 mode)──\n // primary-sidebar:\n // row1: [sidebar (頂天)][main col (header + main)][aside (頂天)]\n // primary-header:\n // row1: [header (橫跨整 viewport, banner role)]\n // row2: [sidebar][main][aside]\n\n // AppShellAside 自決 inline vs modal mode(via AppShellContext.isMobile)。\n // AppShell 一律只 render `{aside}` 一次,AppShellAside 內部根據 isMobile 決定 render 形式。\n\n if (layout === 'primary-header') {\n // primary-header layout(2026-05-21 v2 — user clarification「primary-header = primary-sidebar + 一條 global header」):\n // 結構:row1 globalHeader(全寬 global bar)/ row2 [sidebar][main col: localHeader + main][aside]\n // - globalHeader = 跨頁 account / workspace switcher / notifications(對齊 GitHub top nav / Slack workspace bar)\n // - header = local page header,**仍存在**(per page actions / breadcrumb,對齊 GitHub repo header / Slack channel header / Gmail email-list toolbar 2-layer 慣例)\n // Consumer 必傳 `<Sidebar viewportInsetTop=\"var(--chrome-header-height)\">` 讓 sidebar 從 globalHeader 下方起算。\n return (\n <AppShellContext.Provider value={ctxValue}>\n <div\n ref={ref}\n className={cn('flex h-svh w-full flex-col overflow-hidden bg-canvas', className)}\n {...props}\n >\n <SkipToMain />\n {/* Row 1:Global header(account / workspace switcher / notifications,橫跨整 viewport)*/}\n {globalHeader && <div className=\"flex-shrink-0\">{globalHeader}</div>}\n {/* Row 2:[sidebar][main col][aside]horizontal row */}\n <div className=\"flex flex-1 min-h-0 w-full\">\n {sidebar}\n {/* Main column:local header + main content(per user model「primary-header = primary-sidebar + global header」)*/}\n <div className=\"flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden\">\n {header && <div className=\"flex-shrink-0\">{header}</div>}\n <main\n id=\"app-shell-main\"\n tabIndex={-1}\n className=\"flex-1 min-w-0 min-h-0 overflow-y-auto focus:outline-none\"\n >\n {children}\n </main>\n </div>\n {aside}\n </div>\n </div>\n </AppShellContext.Provider>\n )\n }\n\n // primary-sidebar layout\n return (\n <AppShellContext.Provider value={ctxValue}>\n <div\n ref={ref}\n className={cn('flex h-svh w-full overflow-hidden bg-canvas', className)}\n {...props}\n >\n <SkipToMain />\n {/* Sidebar — 頂天 */}\n {sidebar}\n {/* Main column(header + main 垂直堆)*/}\n <div className=\"flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden\">\n {header && (\n // Header 在 main column 內(main col sibling,非 main descendant)→ 跟 W3C ARIA in HTML\n // banner rule 對照:`<header>` 在 main descendant 才不是 banner,本 ChromeHeader 是 <div>\n // 所以本來就不會被 banner role 計算。仍包 wrap div not <header> 確保不無意觸發 banner。\n <div className=\"flex-shrink-0\">{header}</div>\n )}\n <main\n id=\"app-shell-main\"\n tabIndex={-1}\n className=\"flex-1 min-h-0 overflow-y-auto focus:outline-none\"\n >\n {children}\n </main>\n </div>\n {/* Aside slot — desktop inline OR mobile Sheet,內部自決 */}\n {aside}\n </div>\n </AppShellContext.Provider>\n )\n }\n)\nAppShell.displayName = 'AppShell'\n\n// ── AppShellAside sub-component ──────────────────────────────────────────────\n\n/**\n * AppShellAside — right panel:standard inline(desktop) vs modal overlay(mobile)。\n *\n * Desktop(viewport ≥ 768px):\n * - Render 直接放 layout grid 右側(asideOpen=true 才 mount,close hide via parent)\n * - 不蓋 mask / background 可操作 / 佔 layout 寬\n * - Vertical extent:primary-sidebar → 頂天立地 / primary-header → header 下方\n *\n * Mobile(viewport < 768px):\n * - Render 走 Sheet primitive(side=\"right\",per sheet.spec.md)\n * - Mask 蓋 / background 不可操作 / 不佔 layout 寬\n * - title 強制(aria-labelledby per sheet.spec.md:98)\n */\nconst AppShellAside = React.forwardRef<HTMLElement, AppShellAsideProps>(\n ({ title, width, children, className }, ref) => {\n const { asideOpen, setAsideOpen, isMobile } = useAppShell()\n const isXl = useIsXl()\n const resolvedWidth = resolveAsideWidth(width, isXl)\n\n // Shared frame:always-on header(title + close X)+ body(ScrollArea + layoutSpace 規則 1B 父層 padding)\n // 對齊 codex Layer B 2026-05-20「container mode 可變,panel role/content 不該變」+ Notion/Figma right\n // panel 共識(modal vs inline 結構相同,host wrapper 不同)。\n // 2026-05-20 migrate 消費 ChromeHeader primitive(撤回自刻 + 撤回 bg-surface 疊加 — 對齊\n // `header-canonical.spec.md`「6. Background ownership」段「Nested chrome header 透明繼承\n // parent」:aside container 自身已 bg-surface,內 header 不該再畫 bg 避免疊加 drift)。\n const frame = (\n <>\n <ChromeHeader>\n <h2 className=\"text-body-lg font-medium flex-1 truncate\">{title}</h2>\n <Button\n iconOnly\n dismiss\n size=\"sm\"\n startIcon={XIcon}\n aria-label=\"關閉\"\n onClick={() => setAsideOpen(false)}\n />\n </ChromeHeader>\n <ScrollArea className=\"flex-1 min-h-0\">\n {children}\n </ScrollArea>\n </>\n )\n\n // Modal mode(mobile)— Sheet from right\n if (isMobile) {\n return (\n <Sheet open={asideOpen} onOpenChange={setAsideOpen}>\n <SheetContent\n side=\"right\"\n className=\"w-[min(90vw,var(--app-shell-aside-modal-width))] flex flex-col p-0 [&>button]:hidden\"\n style={{ ['--app-shell-aside-modal-width' as string]: `${resolvedWidth}px` }}\n >\n {frame}\n </SheetContent>\n </Sheet>\n )\n }\n\n // Standard inline mode(desktop)\n if (!asideOpen) return null\n\n return (\n <aside\n ref={ref}\n aria-label={title}\n className={cn(\n 'flex flex-col h-full min-h-0 overflow-hidden',\n 'bg-surface border-l border-divider',\n className\n )}\n style={{ width: resolvedWidth }}\n >\n {frame}\n </aside>\n )\n }\n)\nAppShellAside.displayName = 'AppShellAside'\n\n// ── Exports ──────────────────────────────────────────────────────────────────\n\n// code-quality-allow: dead-export useAppShell — public compound API hook(consumer 可自拼 custom aside layout,\n// 對齊 Radix `useDialogContext` / MUI `useFormControl` 慣例)。內部 AppShellAside 已消費(L294),\n// audit script 抓「無 cross-file import」是 false positive(2026-05-21 D2 codify)。\nexport { AppShell, AppShellAside, useAppShell }\n"],"names":["XIcon"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
3
+ /**
4
+ * AspectRatio — 固定長寬比容器(Radix AspectRatio primitive 薄包裝)
5
+ *
6
+ * 世界級對照:shadcn `AspectRatio` / Ant 無獨立元件(CSS 方案)/ Material 無
7
+ *
8
+ * ── 為什麼需要 ──
9
+ * CSS `aspect-ratio` 屬性雖然現代瀏覽器都支援,但 Radix primitive 提供 SSR-safe
10
+ * padding-bottom 方案 + consistent API,避免邊緣 bug(image 未載入時容器坍塌 /
11
+ * content-fit 差異)。保 safe + 一致視覺。
12
+ *
13
+ * ── 標準 ratio(DS 慣例) ──
14
+ * 16/9 — 寬螢幕影片、onboarding feature tour 截圖(Coachmark media 預設)
15
+ * 4/3 — 老電視 / 照片基本 ratio、產品 thumbnail
16
+ * 1/1 — Avatar / 方形貼文預覽 / icon preview
17
+ * 3/4 — 直式照片(人物 portrait)
18
+ * 21/9 — Ultra-wide banner(hero section)
19
+ *
20
+ * Consumer 傳 `ratio={n/m}` 數字計算(如 16/9 = 1.7777)。
21
+ *
22
+ * ── 常見消費者 ──
23
+ * Coachmark media / Carousel item image / Card thumbnail(未來)/ Chart preview
24
+ */
25
+ export type AspectRatioProps = React.ComponentPropsWithoutRef<typeof AspectRatioPrimitive.Root>;
26
+ declare const AspectRatio: React.ForwardRefExoticComponent<Omit<AspectRatioPrimitive.AspectRatioProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
27
+ export declare const aspectRatioMeta: {
28
+ readonly component: "AspectRatio";
29
+ readonly family: null;
30
+ readonly variants: {};
31
+ readonly sizes: {};
32
+ readonly states: readonly ["default", "hover", "active", "focus-visible", "disabled"];
33
+ readonly tokens: {
34
+ readonly bg: readonly [];
35
+ readonly fg: readonly [];
36
+ readonly ring: readonly [];
37
+ };
38
+ };
39
+ export { AspectRatio };
40
+ //# sourceMappingURL=aspect-ratio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aspect-ratio.d.ts","sourceRoot":"","sources":["../../../src/components/AspectRatio/aspect-ratio.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAA;AAEpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAA;AAK/F,QAAA,MAAM,WAAW,iKAGoD,CAAA;AAKrE,eAAO,MAAM,eAAe;;;;;;;;;;;CAelB,CAAA;AAEV,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
4
+ const AspectRatio = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { ref, ...props }));
5
+ AspectRatio.displayName = "AspectRatio";
6
+ const aspectRatioMeta = {
7
+ component: "AspectRatio",
8
+ family: null,
9
+ // non-family composite / overlay / layout
10
+ variants: {},
11
+ sizes: {},
12
+ states: ["default", "hover", "active", "focus-visible", "disabled"],
13
+ tokens: {
14
+ bg: [],
15
+ fg: [],
16
+ ring: []
17
+ }
18
+ };
19
+ export {
20
+ AspectRatio,
21
+ aspectRatioMeta
22
+ };
23
+ //# sourceMappingURL=aspect-ratio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aspect-ratio.js","sources":["../../../src/components/AspectRatio/aspect-ratio.tsx"],"sourcesContent":["// @benchmark-unverified-blanket: file-level retraction per M22 (d) — claims herein not individually URL-cited; treat as unverified visual/usage rumor unless retrofit per-claim. Hook escape preserved.\nimport * as React from 'react'\nimport * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'\n\n/**\n * AspectRatio — 固定長寬比容器(Radix AspectRatio primitive 薄包裝)\n *\n * 世界級對照:shadcn `AspectRatio` / Ant 無獨立元件(CSS 方案)/ Material 無\n *\n * ── 為什麼需要 ──\n * CSS `aspect-ratio` 屬性雖然現代瀏覽器都支援,但 Radix primitive 提供 SSR-safe\n * padding-bottom 方案 + consistent API,避免邊緣 bug(image 未載入時容器坍塌 /\n * content-fit 差異)。保 safe + 一致視覺。\n *\n * ── 標準 ratio(DS 慣例) ──\n * 16/9 — 寬螢幕影片、onboarding feature tour 截圖(Coachmark media 預設)\n * 4/3 — 老電視 / 照片基本 ratio、產品 thumbnail\n * 1/1 — Avatar / 方形貼文預覽 / icon preview\n * 3/4 — 直式照片(人物 portrait)\n * 21/9 — Ultra-wide banner(hero section)\n *\n * Consumer 傳 `ratio={n/m}` 數字計算(如 16/9 = 1.7777)。\n *\n * ── 常見消費者 ──\n * Coachmark media / Carousel item image / Card thumbnail(未來)/ Chart preview\n */\n\nexport type AspectRatioProps = React.ComponentPropsWithoutRef<typeof AspectRatioPrimitive.Root>\n\n// shadcn canonical:顯式 forwardRef + displayName(雖 Radix primitive 已 forwardRef,\n// 此 wrapper 確保本 DS 每個 named export 在 Inspector 顯示正確 displayName,\n// 且 props passthrough + ref 行為在 code 層面明確可見)\nconst AspectRatio = React.forwardRef<\n React.ElementRef<typeof AspectRatioPrimitive.Root>,\n AspectRatioProps\n>((props, ref) => <AspectRatioPrimitive.Root ref={ref} {...props} />)\nAspectRatio.displayName = 'AspectRatio'\n\n// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)\n// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs\nexport const aspectRatioMeta = {\n component: 'AspectRatio',\n family: null, // non-family composite / overlay / layout\n variants: {\n\n },\n sizes: {\n\n },\n states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],\n tokens: {\n bg: [],\n fg: [],\n ring: [],\n },\n} as const\n\nexport { AspectRatio }\n"],"names":[],"mappings":";;;AAgCA,MAAM,cAAc,MAAM,WAGxB,CAAC,OAAO,QAAQ,oBAAC,qBAAqB,MAArB,EAA0B,KAAW,GAAG,OAAO,CAAE;AACpE,YAAY,cAAc;AAInB,MAAM,kBAAkB;AAAA,EAC7B,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EACR,UAAU,CAAA;AAAA,EAGV,OAAO,CAAA;AAAA,EAGP,QAAQ,CAAC,WAAW,SAAS,UAAU,iBAAiB,UAAU;AAAA,EAClE,QAAQ;AAAA,IACN,IAAI,CAAA;AAAA,IACJ,IAAI,CAAA;AAAA,IACJ,MAAM,CAAA;AAAA,EAAC;AAEX;"}
@@ -0,0 +1,85 @@
1
+ import * as React from 'react';
2
+ import type { LucideIcon } from 'lucide-react';
3
+ /**
4
+ * Avatar — 頭像元件
5
+ *
6
+ * 三種內容模式(按優先順序):
7
+ * 1. src → 圖片
8
+ * 2. icon → icon 在底色圓/方形內
9
+ * 3. alt → 取首字作文字 fallback
10
+ * 4. 都沒有 → 預設 User icon
11
+ *
12
+ * ── 尺寸 ──
13
+ * size 接受任意 px 值,icon 自動 = round_even(size × 0.6)
14
+ * 文字 fallback 字體 = size × 0.5
15
+ *
16
+ * ── 形狀 ──
17
+ * circle(預設)→ rounded-full,用於人物
18
+ * square → rounded-md (4px),用於實體(專案、組織、App)
19
+ */
20
+ type ColorKey = 'neutral' | 'blue' | 'red' | 'green' | 'yellow' | 'turquoise' | 'purple' | 'magenta' | 'indigo';
21
+ export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
22
+ /** 尺寸:number (px) 或 'fill'(填滿父容器,由父層決定大小)。預設 32 */
23
+ size?: number | 'fill';
24
+ /** 形狀:circle(人物)或 square(實體),預設 circle */
25
+ shape?: 'circle' | 'square';
26
+ /** 圖片 URL */
27
+ src?: string;
28
+ /** 替代文字(圖片失敗時取首字作 fallback) */
29
+ alt?: string;
30
+ /** Icon 模式(LucideIcon) */
31
+ icon?: LucideIcon;
32
+ /** Icon / text fallback 的背景色,預設 neutral */
33
+ color?: ColorKey;
34
+ /** 深底白字模式(step-6 背景 + 白色前景,warning 例外),預設 false */
35
+ solid?: boolean;
36
+ /**
37
+ * 在線狀態指示器(presence),顯示在 avatar **右下角**。
38
+ * 世界級對照:Slack / Teams / Discord — `online` 是最廣泛被理解的術語。
39
+ * 位置語義:右下 = "此人的 presence"(使用者聚焦於「這個人是誰 + 現在 在不在」)。
40
+ */
41
+ status?: 'online' | 'away' | 'busy' | 'offline';
42
+ /**
43
+ * 未讀 / 通知計數 badge,顯示在 avatar **右上角**。
44
+ * 世界級對照:chat app(iMessage / Slack thread / LINE / WhatsApp)一律右上角。
45
+ * 位置語義:右上 = "關於此對話的新事件數量"(使用者聚焦於「有多少未處理」);
46
+ * 與右下的 presence 共存不衝突(不同角、不同語義)。
47
+ * `> 99` 自動顯示 "99+"(交給內部 Badge 的 `max` 行為)。
48
+ */
49
+ badgeCount?: number;
50
+ /**
51
+ * 傳入 HoverCard 內容(如 NameCard),hover avatar 時自動顯示。
52
+ * 只有人員 avatar 需要傳;實體 avatar(專案、組織)不傳。
53
+ */
54
+ hoverCard?: React.ReactNode;
55
+ }
56
+ export interface AvatarData {
57
+ /** 圖片 URL */
58
+ src?: string;
59
+ /** 替代文字(圖片失敗時取首字作 fallback) */
60
+ alt: string;
61
+ /** Icon / text fallback 的背景色,預設 neutral */
62
+ color?: ColorKey;
63
+ /**
64
+ * Person avatar hover NameCard(DS-wide canonical,person avatar 預設必有,見 avatar.spec.md)。
65
+ * Entity avatar(專案 / 組織 logo)不帶 → consumer 不傳 hoverCard 即豁免。
66
+ * 所有消費 AvatarData 的 primitive(MenuItem / DropdownMenu / SelectMenu / SelectionItem / NameCard)
67
+ * 需 forward 此 prop 到內部 <Avatar hoverCard={avatar.hoverCard} />。
68
+ */
69
+ hoverCard?: React.ReactNode;
70
+ }
71
+ export declare const avatarMeta: {
72
+ readonly component: "Avatar";
73
+ readonly family: null;
74
+ readonly variants: {};
75
+ readonly sizes: {};
76
+ readonly states: readonly ["default", "hover", "active", "focus-visible", "disabled"];
77
+ readonly tokens: {
78
+ readonly bg: readonly ["bg-surface-raised"];
79
+ readonly fg: readonly ["--foreground", "--on-emphasis"];
80
+ readonly ring: readonly ["ring-ring"];
81
+ };
82
+ };
83
+ declare const Avatar: React.MemoExoticComponent<React.ForwardRefExoticComponent<AvatarProps & React.RefAttributes<HTMLDivElement>>>;
84
+ export { Avatar };
85
+ //# sourceMappingURL=avatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/components/Avatar/avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAO9C;;;;;;;;;;;;;;;;GAgBG;AAMH,KAAK,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AA2E/G,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACvE,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC3B,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0BAA0B;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC/C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B;AA4LD,MAAM,WAAW,UAAU;IACzB,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B;AAID,eAAO,MAAM,UAAU;;;;;;;;;;;CAeb,CAAA;AAGV,QAAA,MAAM,MAAM,+GAA0B,CAAA;AAEtC,OAAO,EAAE,MAAM,EAAE,CAAA"}
@@ -0,0 +1,195 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { User } from "lucide-react";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { HoverCard, HoverCardTrigger, HoverCardContent } from "../HoverCard/hover-card.js";
6
+ import { HOVER_DELAY_CLOSE_MS, HOVER_DELAY_RICH_MS } from "../../tokens/motion/motion.js";
7
+ import { Badge } from "../Badge/badge.js";
8
+ import { useTableIsScrolling, useFieldContext } from "../Field/field-context.js";
9
+ const COLOR_MAP = {
10
+ subtle: {
11
+ neutral: { bg: "var(--muted)", text: "var(--foreground)" },
12
+ blue: { bg: "var(--color-blue-1)", text: "var(--color-blue-7)" },
13
+ red: { bg: "var(--color-deep-orange-1)", text: "var(--color-deep-orange-7)" },
14
+ green: { bg: "var(--color-green-1)", text: "var(--color-green-7)" },
15
+ yellow: { bg: "var(--color-yellow-1)", text: "var(--color-yellow-7)" },
16
+ turquoise: { bg: "var(--color-turquoise-1)", text: "var(--color-turquoise-7)" },
17
+ purple: { bg: "var(--color-purple-1)", text: "var(--color-purple-7)" },
18
+ magenta: { bg: "var(--color-magenta-1)", text: "var(--color-magenta-7)" },
19
+ indigo: { bg: "var(--color-indigo-1)", text: "var(--color-indigo-7)" }
20
+ },
21
+ solid: {
22
+ neutral: { bg: "var(--color-neutral-9)", text: "var(--inverse-fg)" },
23
+ blue: { bg: "var(--color-blue-6)", text: "var(--on-emphasis)" },
24
+ red: { bg: "var(--color-deep-orange-6)", text: "var(--on-emphasis)" },
25
+ green: { bg: "var(--color-green-6)", text: "var(--on-emphasis)" },
26
+ yellow: { bg: "var(--color-yellow-6)", text: "var(--warning-foreground)" },
27
+ turquoise: { bg: "var(--color-turquoise-6)", text: "var(--on-emphasis)" },
28
+ purple: { bg: "var(--color-purple-6)", text: "var(--on-emphasis)" },
29
+ magenta: { bg: "var(--color-magenta-6)", text: "var(--on-emphasis)" },
30
+ indigo: { bg: "var(--color-indigo-6)", text: "var(--on-emphasis)" }
31
+ }
32
+ };
33
+ function getIconSize(avatarSize) {
34
+ return Math.round(avatarSize * 0.6 / 2) * 2;
35
+ }
36
+ function getInitial(text) {
37
+ return text.trim().charAt(0).toUpperCase();
38
+ }
39
+ const STATUS_DOT_COLOR = {
40
+ online: "var(--status-online)",
41
+ away: "var(--status-away)",
42
+ busy: "var(--status-busy)",
43
+ offline: "var(--status-offline)"
44
+ };
45
+ function useDocumentTheme() {
46
+ const [theme, setTheme] = React.useState(
47
+ () => typeof document !== "undefined" ? document.documentElement.getAttribute("data-theme") : null
48
+ );
49
+ React.useEffect(() => {
50
+ if (typeof document === "undefined") return;
51
+ const root = document.documentElement;
52
+ const update = () => setTheme(root.getAttribute("data-theme"));
53
+ update();
54
+ const obs = new MutationObserver(update);
55
+ obs.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
56
+ return () => obs.disconnect();
57
+ }, []);
58
+ return theme;
59
+ }
60
+ const AvatarInner = React.forwardRef(
61
+ ({ size = 32, shape = "circle", src, alt, icon: Icon, color = "neutral", solid = false, status, badgeCount, hoverCard, className, style, ...props }, ref) => {
62
+ var _a;
63
+ const [imgError, setImgError] = React.useState(false);
64
+ const documentTheme = useDocumentTheme();
65
+ const isTableScrolling = useTableIsScrolling();
66
+ const fieldCtx = useFieldContext();
67
+ const isDisabledInField = (fieldCtx == null ? void 0 : fieldCtx.mode) === "disabled" && (fieldCtx == null ? void 0 : fieldCtx.hasFieldWrapper) === true;
68
+ const isFill = size === "fill";
69
+ const numSize = isFill ? 32 : size;
70
+ const iconPx = getIconSize(numSize);
71
+ const fontSizePx = Math.round(numSize * 0.5);
72
+ const variantKey = solid ? "solid" : "subtle";
73
+ const colors = ((_a = COLOR_MAP[variantKey]) == null ? void 0 : _a[color]) ?? COLOR_MAP.subtle.neutral;
74
+ const radius = shape === "circle" ? "9999px" : "4px";
75
+ const showImage = src && !imgError;
76
+ const showIcon = !showImage && (Icon || !alt);
77
+ const showText = !showImage && !showIcon && alt;
78
+ const FallbackIcon = Icon ?? User;
79
+ const dotSize = isFill ? 10 : Math.max(8, Math.min(16, Math.round(numSize * 0.28)));
80
+ const dotBorder = dotSize >= 12 ? 3 : 2;
81
+ const avatarEl = /* @__PURE__ */ jsxs(
82
+ "div",
83
+ {
84
+ className: cn(
85
+ "inline-flex items-center justify-center shrink-0 overflow-hidden select-none",
86
+ isFill && "w-full h-full",
87
+ // 2026-05-13 R3.5 self-dim:Avatar 在 disabled Field wrapper context 內自 dim
88
+ // (取代 field-wrapper.tsx default/bare/naked disabled blanket opacity-disabled 逃生艙)
89
+ isDisabledInField && "opacity-disabled"
90
+ ),
91
+ style: {
92
+ ...isFill ? { containerType: "inline-size" } : { width: numSize, height: numSize },
93
+ borderRadius: radius,
94
+ backgroundColor: showImage ? void 0 : colors.bg,
95
+ color: showImage ? void 0 : colors.text
96
+ },
97
+ "data-avatar-size": isFill ? "fill" : numSize,
98
+ children: [
99
+ showImage && /* @__PURE__ */ jsx(
100
+ "img",
101
+ {
102
+ src,
103
+ alt: alt ?? "",
104
+ className: "w-full h-full object-cover",
105
+ onError: () => setImgError(true)
106
+ }
107
+ ),
108
+ showIcon && (isFill ? /* @__PURE__ */ jsx(FallbackIcon, { className: "w-[60%] h-[60%]", "aria-hidden": true }) : /* @__PURE__ */ jsx(FallbackIcon, { size: iconPx, "aria-hidden": true })),
109
+ showText && /* @__PURE__ */ jsx(
110
+ "span",
111
+ {
112
+ className: "font-medium leading-none",
113
+ style: { fontSize: isFill ? "50cqi" : fontSizePx },
114
+ "aria-hidden": true,
115
+ children: getInitial(alt)
116
+ }
117
+ )
118
+ ]
119
+ }
120
+ );
121
+ const hasOverlay = status || typeof badgeCount === "number";
122
+ const focusableProps = hoverCard ? {
123
+ tabIndex: 0,
124
+ role: "button",
125
+ "aria-haspopup": "dialog",
126
+ "aria-label": alt ?? "View profile"
127
+ } : {};
128
+ const focusableClass = hoverCard ? "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 rounded-full" : "";
129
+ const baseEl = !hasOverlay ? /* @__PURE__ */ jsx("div", { ref, className: cn("inline-flex shrink-0", focusableClass, className), style, ...focusableProps, ...props, children: avatarEl }) : /* @__PURE__ */ jsxs("div", { ref, className: cn("relative inline-flex shrink-0", focusableClass, className), style, ...focusableProps, ...props, children: [
130
+ avatarEl,
131
+ status && /* @__PURE__ */ jsx(
132
+ "span",
133
+ {
134
+ className: "absolute block rounded-full",
135
+ style: {
136
+ width: dotSize,
137
+ height: dotSize,
138
+ bottom: 0,
139
+ right: 0,
140
+ backgroundColor: STATUS_DOT_COLOR[status],
141
+ boxShadow: `0 0 0 ${dotBorder}px var(--surface-raised, var(--canvas))`
142
+ },
143
+ "aria-hidden": true
144
+ }
145
+ ),
146
+ typeof badgeCount === "number" && badgeCount > 0 && /* @__PURE__ */ jsx(
147
+ Badge,
148
+ {
149
+ variant: "critical",
150
+ count: badgeCount,
151
+ max: 99,
152
+ className: "absolute -top-1 -right-1",
153
+ style: {
154
+ boxShadow: `0 0 0 2px var(--surface-raised, var(--canvas))`
155
+ },
156
+ "aria-label": `${badgeCount} unread`
157
+ }
158
+ )
159
+ ] });
160
+ if (!hoverCard || isTableScrolling) return baseEl;
161
+ return /* @__PURE__ */ jsxs(HoverCard, { openDelay: HOVER_DELAY_RICH_MS, closeDelay: HOVER_DELAY_CLOSE_MS, children: [
162
+ /* @__PURE__ */ jsx(HoverCardTrigger, { asChild: true, children: baseEl }),
163
+ /* @__PURE__ */ jsx(
164
+ HoverCardContent,
165
+ {
166
+ "data-theme": documentTheme ?? void 0,
167
+ className: "bg-surface-raised rounded-lg border border-border overflow-hidden",
168
+ style: { boxShadow: "var(--elevation-200)" },
169
+ children: hoverCard
170
+ }
171
+ )
172
+ ] });
173
+ }
174
+ );
175
+ AvatarInner.displayName = "AvatarInner";
176
+ const avatarMeta = {
177
+ component: "Avatar",
178
+ family: null,
179
+ // non-family composite / overlay / layout
180
+ variants: {},
181
+ sizes: {},
182
+ states: ["default", "hover", "active", "focus-visible", "disabled"],
183
+ tokens: {
184
+ bg: ["bg-surface-raised"],
185
+ fg: ["--foreground", "--on-emphasis"],
186
+ ring: ["ring-ring"]
187
+ }
188
+ };
189
+ AvatarInner.displayName = "Avatar";
190
+ const Avatar = React.memo(AvatarInner);
191
+ export {
192
+ Avatar,
193
+ avatarMeta
194
+ };
195
+ //# sourceMappingURL=avatar.js.map