@mortenbrudvik/waveui 0.7.0 → 0.8.0

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 (408) hide show
  1. package/README.md +395 -132
  2. package/dist/components/button/Button.cjs +1 -1
  3. package/dist/components/button/Button.cjs.map +1 -1
  4. package/dist/components/button/Button.mjs +36 -35
  5. package/dist/components/button/Button.mjs.map +1 -1
  6. package/dist/components/button/Button.slots.cjs +1 -1
  7. package/dist/components/button/Button.slots.cjs.map +1 -1
  8. package/dist/components/button/Button.slots.mjs +31 -21
  9. package/dist/components/button/Button.slots.mjs.map +1 -1
  10. package/dist/components/button/CompoundButton.cjs +1 -1
  11. package/dist/components/button/CompoundButton.cjs.map +1 -1
  12. package/dist/components/button/CompoundButton.mjs +31 -29
  13. package/dist/components/button/CompoundButton.mjs.map +1 -1
  14. package/dist/components/button/Link.cjs +1 -1
  15. package/dist/components/button/Link.cjs.map +1 -1
  16. package/dist/components/button/Link.mjs +24 -23
  17. package/dist/components/button/Link.mjs.map +1 -1
  18. package/dist/components/button/MenuButton.cjs +1 -1
  19. package/dist/components/button/MenuButton.cjs.map +1 -1
  20. package/dist/components/button/MenuButton.mjs +29 -28
  21. package/dist/components/button/MenuButton.mjs.map +1 -1
  22. package/dist/components/button/SplitButton.cjs +1 -1
  23. package/dist/components/button/SplitButton.cjs.map +1 -1
  24. package/dist/components/button/SplitButton.mjs +46 -45
  25. package/dist/components/button/SplitButton.mjs.map +1 -1
  26. package/dist/components/button/ToggleButton.cjs +1 -1
  27. package/dist/components/button/ToggleButton.cjs.map +1 -1
  28. package/dist/components/button/ToggleButton.mjs +38 -35
  29. package/dist/components/button/ToggleButton.mjs.map +1 -1
  30. package/dist/components/button/Toolbar.cjs +1 -1
  31. package/dist/components/button/Toolbar.cjs.map +1 -1
  32. package/dist/components/button/Toolbar.mjs +43 -42
  33. package/dist/components/button/Toolbar.mjs.map +1 -1
  34. package/dist/components/button/Toolbar.parts.cjs +1 -1
  35. package/dist/components/button/Toolbar.parts.cjs.map +1 -1
  36. package/dist/components/button/Toolbar.parts.mjs +76 -81
  37. package/dist/components/button/Toolbar.parts.mjs.map +1 -1
  38. package/dist/components/data-display/Avatar.cjs +1 -1
  39. package/dist/components/data-display/Avatar.cjs.map +1 -1
  40. package/dist/components/data-display/Avatar.mjs +72 -67
  41. package/dist/components/data-display/Avatar.mjs.map +1 -1
  42. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  43. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  44. package/dist/components/data-display/AvatarGroup.mjs +89 -88
  45. package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
  46. package/dist/components/data-display/Badge.cjs +1 -1
  47. package/dist/components/data-display/Badge.cjs.map +1 -1
  48. package/dist/components/data-display/Badge.mjs +17 -16
  49. package/dist/components/data-display/Badge.mjs.map +1 -1
  50. package/dist/components/data-display/CounterBadge.cjs +1 -1
  51. package/dist/components/data-display/CounterBadge.cjs.map +1 -1
  52. package/dist/components/data-display/CounterBadge.mjs +18 -17
  53. package/dist/components/data-display/CounterBadge.mjs.map +1 -1
  54. package/dist/components/data-display/Divider.cjs +1 -1
  55. package/dist/components/data-display/Divider.cjs.map +1 -1
  56. package/dist/components/data-display/Divider.mjs +31 -30
  57. package/dist/components/data-display/Divider.mjs.map +1 -1
  58. package/dist/components/data-display/Image.cjs +1 -1
  59. package/dist/components/data-display/Image.cjs.map +1 -1
  60. package/dist/components/data-display/Image.mjs +16 -15
  61. package/dist/components/data-display/Image.mjs.map +1 -1
  62. package/dist/components/data-display/InfoLabel.cjs +1 -1
  63. package/dist/components/data-display/InfoLabel.cjs.map +1 -1
  64. package/dist/components/data-display/InfoLabel.mjs +74 -73
  65. package/dist/components/data-display/InfoLabel.mjs.map +1 -1
  66. package/dist/components/data-display/List.cjs +1 -1
  67. package/dist/components/data-display/List.cjs.map +1 -1
  68. package/dist/components/data-display/List.mjs +175 -174
  69. package/dist/components/data-display/List.mjs.map +1 -1
  70. package/dist/components/data-display/Persona.cjs +1 -1
  71. package/dist/components/data-display/Persona.cjs.map +1 -1
  72. package/dist/components/data-display/Persona.mjs +31 -29
  73. package/dist/components/data-display/Persona.mjs.map +1 -1
  74. package/dist/components/data-display/PresenceBadge.cjs +1 -1
  75. package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
  76. package/dist/components/data-display/PresenceBadge.mjs +25 -24
  77. package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
  78. package/dist/components/data-display/Tag.cjs +1 -1
  79. package/dist/components/data-display/Tag.cjs.map +1 -1
  80. package/dist/components/data-display/Tag.mjs +87 -82
  81. package/dist/components/data-display/Tag.mjs.map +1 -1
  82. package/dist/components/feedback/MessageBar.cjs +1 -1
  83. package/dist/components/feedback/MessageBar.cjs.map +1 -1
  84. package/dist/components/feedback/MessageBar.mjs +129 -71
  85. package/dist/components/feedback/MessageBar.mjs.map +1 -1
  86. package/dist/components/feedback/MessageBar.parts.cjs +2 -0
  87. package/dist/components/feedback/MessageBar.parts.cjs.map +1 -0
  88. package/dist/components/feedback/MessageBar.parts.mjs +84 -0
  89. package/dist/components/feedback/MessageBar.parts.mjs.map +1 -0
  90. package/dist/components/feedback/MessageBar.reflow.cjs +2 -0
  91. package/dist/components/feedback/MessageBar.reflow.cjs.map +1 -0
  92. package/dist/components/feedback/MessageBar.reflow.mjs +74 -0
  93. package/dist/components/feedback/MessageBar.reflow.mjs.map +1 -0
  94. package/dist/components/feedback/MessageBar.status.cjs +1 -1
  95. package/dist/components/feedback/MessageBar.status.cjs.map +1 -1
  96. package/dist/components/feedback/MessageBar.status.mjs +2 -1
  97. package/dist/components/feedback/MessageBar.status.mjs.map +1 -1
  98. package/dist/components/feedback/ProgressBar.cjs +1 -1
  99. package/dist/components/feedback/ProgressBar.cjs.map +1 -1
  100. package/dist/components/feedback/ProgressBar.mjs +44 -43
  101. package/dist/components/feedback/ProgressBar.mjs.map +1 -1
  102. package/dist/components/feedback/Skeleton.cjs +1 -1
  103. package/dist/components/feedback/Skeleton.cjs.map +1 -1
  104. package/dist/components/feedback/Skeleton.mjs +26 -24
  105. package/dist/components/feedback/Skeleton.mjs.map +1 -1
  106. package/dist/components/feedback/Spinner.cjs +1 -1
  107. package/dist/components/feedback/Spinner.cjs.map +1 -1
  108. package/dist/components/feedback/Spinner.mjs +32 -31
  109. package/dist/components/feedback/Spinner.mjs.map +1 -1
  110. package/dist/components/feedback/Toast.cjs +1 -1
  111. package/dist/components/feedback/Toast.cjs.map +1 -1
  112. package/dist/components/feedback/Toast.context.cjs +2 -0
  113. package/dist/components/feedback/Toast.context.cjs.map +1 -0
  114. package/dist/components/feedback/Toast.context.mjs +23 -0
  115. package/dist/components/feedback/Toast.context.mjs.map +1 -0
  116. package/dist/components/feedback/Toast.mjs +10 -342
  117. package/dist/components/feedback/Toast.mjs.map +1 -1
  118. package/dist/components/feedback/Toast.parts.cjs +2 -0
  119. package/dist/components/feedback/Toast.parts.cjs.map +1 -0
  120. package/dist/components/feedback/Toast.parts.mjs +98 -0
  121. package/dist/components/feedback/Toast.parts.mjs.map +1 -0
  122. package/dist/components/feedback/Toast.root.cjs +2 -0
  123. package/dist/components/feedback/Toast.root.cjs.map +1 -0
  124. package/dist/components/feedback/Toast.root.mjs +109 -0
  125. package/dist/components/feedback/Toast.root.mjs.map +1 -0
  126. package/dist/components/feedback/Toaster.cjs +2 -0
  127. package/dist/components/feedback/Toaster.cjs.map +1 -0
  128. package/dist/components/feedback/Toaster.mjs +564 -0
  129. package/dist/components/feedback/Toaster.mjs.map +1 -0
  130. package/dist/components/input/AlphaSlider.cjs +2 -0
  131. package/dist/components/input/AlphaSlider.cjs.map +1 -0
  132. package/dist/components/input/AlphaSlider.mjs +115 -0
  133. package/dist/components/input/AlphaSlider.mjs.map +1 -0
  134. package/dist/components/input/Checkbox.cjs +1 -1
  135. package/dist/components/input/Checkbox.cjs.map +1 -1
  136. package/dist/components/input/Checkbox.mjs +47 -46
  137. package/dist/components/input/Checkbox.mjs.map +1 -1
  138. package/dist/components/input/ColorArea.cjs +2 -0
  139. package/dist/components/input/ColorArea.cjs.map +1 -0
  140. package/dist/components/input/ColorArea.mjs +204 -0
  141. package/dist/components/input/ColorArea.mjs.map +1 -0
  142. package/dist/components/input/ColorPicker.cjs +5 -5
  143. package/dist/components/input/ColorPicker.cjs.map +1 -1
  144. package/dist/components/input/ColorPicker.mjs +142 -165
  145. package/dist/components/input/ColorPicker.mjs.map +1 -1
  146. package/dist/components/input/ColorPicker.parts.cjs +2 -0
  147. package/dist/components/input/ColorPicker.parts.cjs.map +1 -0
  148. package/dist/components/input/ColorPicker.parts.mjs +192 -0
  149. package/dist/components/input/ColorPicker.parts.mjs.map +1 -0
  150. package/dist/components/input/ColorSlider.cjs +2 -0
  151. package/dist/components/input/ColorSlider.cjs.map +1 -0
  152. package/dist/components/input/ColorSlider.mjs +138 -0
  153. package/dist/components/input/ColorSlider.mjs.map +1 -0
  154. package/dist/components/input/Combobox.cjs +1 -1
  155. package/dist/components/input/Combobox.cjs.map +1 -1
  156. package/dist/components/input/Combobox.expand.cjs +1 -1
  157. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  158. package/dist/components/input/Combobox.expand.mjs +9 -9
  159. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  160. package/dist/components/input/Combobox.mjs +90 -85
  161. package/dist/components/input/Combobox.mjs.map +1 -1
  162. package/dist/components/input/DatePicker.cjs +1 -1
  163. package/dist/components/input/DatePicker.cjs.map +1 -1
  164. package/dist/components/input/DatePicker.mjs +186 -185
  165. package/dist/components/input/DatePicker.mjs.map +1 -1
  166. package/dist/components/input/Dropdown.cjs +1 -1
  167. package/dist/components/input/Dropdown.cjs.map +1 -1
  168. package/dist/components/input/Dropdown.mjs +71 -68
  169. package/dist/components/input/Dropdown.mjs.map +1 -1
  170. package/dist/components/input/Field.cjs +1 -1
  171. package/dist/components/input/Field.cjs.map +1 -1
  172. package/dist/components/input/Field.mjs +113 -112
  173. package/dist/components/input/Field.mjs.map +1 -1
  174. package/dist/components/input/Input.cjs +1 -1
  175. package/dist/components/input/Input.cjs.map +1 -1
  176. package/dist/components/input/Input.mjs +55 -54
  177. package/dist/components/input/Input.mjs.map +1 -1
  178. package/dist/components/input/Label.cjs +1 -1
  179. package/dist/components/input/Label.cjs.map +1 -1
  180. package/dist/components/input/Label.mjs +12 -11
  181. package/dist/components/input/Label.mjs.map +1 -1
  182. package/dist/components/input/Option.cjs +1 -1
  183. package/dist/components/input/Option.cjs.map +1 -1
  184. package/dist/components/input/Option.mjs +100 -98
  185. package/dist/components/input/Option.mjs.map +1 -1
  186. package/dist/components/input/RadioGroup.cjs +1 -1
  187. package/dist/components/input/RadioGroup.cjs.map +1 -1
  188. package/dist/components/input/RadioGroup.mjs +89 -88
  189. package/dist/components/input/RadioGroup.mjs.map +1 -1
  190. package/dist/components/input/Rating.cjs +1 -1
  191. package/dist/components/input/Rating.cjs.map +1 -1
  192. package/dist/components/input/Rating.mjs +110 -109
  193. package/dist/components/input/Rating.mjs.map +1 -1
  194. package/dist/components/input/SearchBox.cjs +1 -1
  195. package/dist/components/input/SearchBox.cjs.map +1 -1
  196. package/dist/components/input/SearchBox.mjs +118 -119
  197. package/dist/components/input/SearchBox.mjs.map +1 -1
  198. package/dist/components/input/Select.cjs +1 -1
  199. package/dist/components/input/Select.cjs.map +1 -1
  200. package/dist/components/input/Select.mjs +25 -24
  201. package/dist/components/input/Select.mjs.map +1 -1
  202. package/dist/components/input/Slider.cjs +1 -1
  203. package/dist/components/input/Slider.cjs.map +1 -1
  204. package/dist/components/input/Slider.mjs +47 -46
  205. package/dist/components/input/Slider.mjs.map +1 -1
  206. package/dist/components/input/SpinButton.cjs +1 -1
  207. package/dist/components/input/SpinButton.cjs.map +1 -1
  208. package/dist/components/input/SpinButton.mjs +76 -75
  209. package/dist/components/input/SpinButton.mjs.map +1 -1
  210. package/dist/components/input/SwatchPicker.cjs +1 -1
  211. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  212. package/dist/components/input/SwatchPicker.mjs +38 -37
  213. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  214. package/dist/components/input/Switch.cjs +1 -1
  215. package/dist/components/input/Switch.cjs.map +1 -1
  216. package/dist/components/input/Switch.mjs +65 -64
  217. package/dist/components/input/Switch.mjs.map +1 -1
  218. package/dist/components/input/TagPicker.cjs +1 -1
  219. package/dist/components/input/TagPicker.cjs.map +1 -1
  220. package/dist/components/input/TagPicker.mjs +161 -157
  221. package/dist/components/input/TagPicker.mjs.map +1 -1
  222. package/dist/components/input/Textarea.cjs +1 -1
  223. package/dist/components/input/Textarea.cjs.map +1 -1
  224. package/dist/components/input/Textarea.mjs +24 -23
  225. package/dist/components/input/Textarea.mjs.map +1 -1
  226. package/dist/components/input/TimePicker.cjs +1 -1
  227. package/dist/components/input/TimePicker.cjs.map +1 -1
  228. package/dist/components/input/TimePicker.mjs +202 -199
  229. package/dist/components/input/TimePicker.mjs.map +1 -1
  230. package/dist/components/input/colorName.cjs +2 -0
  231. package/dist/components/input/colorName.cjs.map +1 -0
  232. package/dist/components/input/colorName.mjs +30 -0
  233. package/dist/components/input/colorName.mjs.map +1 -0
  234. package/dist/components/input/colorUtils.cjs +1 -1
  235. package/dist/components/input/colorUtils.cjs.map +1 -1
  236. package/dist/components/input/colorUtils.mjs +154 -56
  237. package/dist/components/input/colorUtils.mjs.map +1 -1
  238. package/dist/components/layout/Accordion.cjs +1 -1
  239. package/dist/components/layout/Accordion.cjs.map +1 -1
  240. package/dist/components/layout/Accordion.mjs +130 -129
  241. package/dist/components/layout/Accordion.mjs.map +1 -1
  242. package/dist/components/layout/Card.cjs +1 -1
  243. package/dist/components/layout/Card.cjs.map +1 -1
  244. package/dist/components/layout/Card.mjs +78 -77
  245. package/dist/components/layout/Card.mjs.map +1 -1
  246. package/dist/components/layout/Carousel.cjs +1 -1
  247. package/dist/components/layout/Carousel.cjs.map +1 -1
  248. package/dist/components/layout/Carousel.mjs +111 -110
  249. package/dist/components/layout/Carousel.mjs.map +1 -1
  250. package/dist/components/layout/Flex.cjs +1 -1
  251. package/dist/components/layout/Flex.cjs.map +1 -1
  252. package/dist/components/layout/Flex.mjs +22 -21
  253. package/dist/components/layout/Flex.mjs.map +1 -1
  254. package/dist/components/layout/Grid.cjs +1 -1
  255. package/dist/components/layout/Grid.cjs.map +1 -1
  256. package/dist/components/layout/Grid.mjs +19 -18
  257. package/dist/components/layout/Grid.mjs.map +1 -1
  258. package/dist/components/layout/Overflow.cjs +1 -1
  259. package/dist/components/layout/Overflow.cjs.map +1 -1
  260. package/dist/components/layout/Overflow.mjs +92 -91
  261. package/dist/components/layout/Overflow.mjs.map +1 -1
  262. package/dist/components/layout/Stack.cjs +1 -1
  263. package/dist/components/layout/Stack.cjs.map +1 -1
  264. package/dist/components/layout/Stack.mjs +14 -13
  265. package/dist/components/layout/Stack.mjs.map +1 -1
  266. package/dist/components/layout/TabList.cjs +1 -1
  267. package/dist/components/layout/TabList.cjs.map +1 -1
  268. package/dist/components/layout/TabList.mjs +118 -117
  269. package/dist/components/layout/TabList.mjs.map +1 -1
  270. package/dist/components/layout/Tree.cjs +1 -1
  271. package/dist/components/layout/Tree.cjs.map +1 -1
  272. package/dist/components/layout/Tree.context.cjs +2 -0
  273. package/dist/components/layout/Tree.context.cjs.map +1 -0
  274. package/dist/components/layout/Tree.context.mjs +33 -0
  275. package/dist/components/layout/Tree.context.mjs.map +1 -0
  276. package/dist/components/layout/Tree.core.cjs +2 -0
  277. package/dist/components/layout/Tree.core.cjs.map +1 -0
  278. package/dist/components/layout/Tree.core.mjs +416 -0
  279. package/dist/components/layout/Tree.core.mjs.map +1 -0
  280. package/dist/components/layout/Tree.itemPersonaLayout.cjs +2 -0
  281. package/dist/components/layout/Tree.itemPersonaLayout.cjs.map +1 -0
  282. package/dist/components/layout/Tree.itemPersonaLayout.mjs +46 -0
  283. package/dist/components/layout/Tree.itemPersonaLayout.mjs.map +1 -0
  284. package/dist/components/layout/Tree.mjs +7 -215
  285. package/dist/components/layout/Tree.mjs.map +1 -1
  286. package/dist/components/layout/Tree.selection.cjs +2 -0
  287. package/dist/components/layout/Tree.selection.cjs.map +1 -0
  288. package/dist/components/layout/Tree.selection.mjs +73 -0
  289. package/dist/components/layout/Tree.selection.mjs.map +1 -0
  290. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  291. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  292. package/dist/components/navigation/Breadcrumb.mjs +76 -75
  293. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  294. package/dist/components/navigation/Menu.group.cjs +1 -1
  295. package/dist/components/navigation/Menu.group.cjs.map +1 -1
  296. package/dist/components/navigation/Menu.group.mjs +39 -37
  297. package/dist/components/navigation/Menu.group.mjs.map +1 -1
  298. package/dist/components/navigation/Menu.items.cjs +1 -1
  299. package/dist/components/navigation/Menu.items.cjs.map +1 -1
  300. package/dist/components/navigation/Menu.items.mjs +67 -61
  301. package/dist/components/navigation/Menu.items.mjs.map +1 -1
  302. package/dist/components/navigation/Menu.link.cjs +1 -1
  303. package/dist/components/navigation/Menu.link.cjs.map +1 -1
  304. package/dist/components/navigation/Menu.link.mjs +34 -28
  305. package/dist/components/navigation/Menu.link.mjs.map +1 -1
  306. package/dist/components/navigation/Menu.popover.cjs +1 -1
  307. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  308. package/dist/components/navigation/Menu.popover.mjs +110 -109
  309. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  310. package/dist/components/navigation/Menu.root.cjs +1 -1
  311. package/dist/components/navigation/Menu.root.cjs.map +1 -1
  312. package/dist/components/navigation/Menu.root.mjs +171 -170
  313. package/dist/components/navigation/Menu.root.mjs.map +1 -1
  314. package/dist/components/navigation/Menu.selectable.cjs +1 -1
  315. package/dist/components/navigation/Menu.selectable.cjs.map +1 -1
  316. package/dist/components/navigation/Menu.selectable.mjs +85 -63
  317. package/dist/components/navigation/Menu.selectable.mjs.map +1 -1
  318. package/dist/components/navigation/Menu.splitGroup.cjs +1 -1
  319. package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -1
  320. package/dist/components/navigation/Menu.splitGroup.mjs +27 -26
  321. package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -1
  322. package/dist/components/navigation/Menu.trigger.cjs +1 -1
  323. package/dist/components/navigation/Menu.trigger.cjs.map +1 -1
  324. package/dist/components/navigation/Menu.trigger.mjs +6 -6
  325. package/dist/components/navigation/Nav.cjs +1 -1
  326. package/dist/components/navigation/Nav.cjs.map +1 -1
  327. package/dist/components/navigation/Nav.mjs +170 -155
  328. package/dist/components/navigation/Nav.mjs.map +1 -1
  329. package/dist/components/navigation/Pagination.cjs +1 -1
  330. package/dist/components/navigation/Pagination.cjs.map +1 -1
  331. package/dist/components/navigation/Pagination.mjs +73 -65
  332. package/dist/components/navigation/Pagination.mjs.map +1 -1
  333. package/dist/components/navigation/Stepper.cjs +1 -1
  334. package/dist/components/navigation/Stepper.cjs.map +1 -1
  335. package/dist/components/navigation/Stepper.mjs +110 -109
  336. package/dist/components/navigation/Stepper.mjs.map +1 -1
  337. package/dist/components/overlays/Dialog.cjs +1 -1
  338. package/dist/components/overlays/Dialog.cjs.map +1 -1
  339. package/dist/components/overlays/Dialog.mjs +109 -108
  340. package/dist/components/overlays/Dialog.mjs.map +1 -1
  341. package/dist/components/overlays/Drawer.cjs +1 -1
  342. package/dist/components/overlays/Drawer.cjs.map +1 -1
  343. package/dist/components/overlays/Drawer.mjs +110 -109
  344. package/dist/components/overlays/Drawer.mjs.map +1 -1
  345. package/dist/components/overlays/Popover.cjs +1 -1
  346. package/dist/components/overlays/Popover.cjs.map +1 -1
  347. package/dist/components/overlays/Popover.mjs +229 -227
  348. package/dist/components/overlays/Popover.mjs.map +1 -1
  349. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  350. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  351. package/dist/components/overlays/TeachingPopover.mjs +41 -37
  352. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  353. package/dist/components/overlays/Tooltip.cjs +1 -1
  354. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  355. package/dist/components/overlays/Tooltip.mjs +87 -86
  356. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  357. package/dist/components/portal/Portal.cjs +1 -1
  358. package/dist/components/portal/Portal.cjs.map +1 -1
  359. package/dist/components/portal/Portal.mjs +33 -32
  360. package/dist/components/portal/Portal.mjs.map +1 -1
  361. package/dist/components/provider/WaveProvider.cjs +1 -1
  362. package/dist/components/provider/WaveProvider.cjs.map +1 -1
  363. package/dist/components/provider/WaveProvider.mjs +31 -30
  364. package/dist/components/provider/WaveProvider.mjs.map +1 -1
  365. package/dist/components/table/DataGrid.cjs +1 -1
  366. package/dist/components/table/DataGrid.cjs.map +1 -1
  367. package/dist/components/table/DataGrid.mjs +228 -227
  368. package/dist/components/table/DataGrid.mjs.map +1 -1
  369. package/dist/components/table/Table.cjs +1 -1
  370. package/dist/components/table/Table.cjs.map +1 -1
  371. package/dist/components/table/Table.mjs +60 -59
  372. package/dist/components/table/Table.mjs.map +1 -1
  373. package/dist/components/typography/Text.cjs +1 -1
  374. package/dist/components/typography/Text.cjs.map +1 -1
  375. package/dist/components/typography/Text.mjs +12 -11
  376. package/dist/components/typography/Text.mjs.map +1 -1
  377. package/dist/hooks/useMediaQuery.cjs +2 -0
  378. package/dist/hooks/useMediaQuery.cjs.map +1 -0
  379. package/dist/hooks/useMediaQuery.mjs +20 -0
  380. package/dist/hooks/useMediaQuery.mjs.map +1 -0
  381. package/dist/hooks/usePrefersReducedMotion.cjs +1 -1
  382. package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -1
  383. package/dist/hooks/usePrefersReducedMotion.mjs +4 -18
  384. package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -1
  385. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  386. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  387. package/dist/hooks/useRovingTabIndex.mjs +3 -3
  388. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  389. package/dist/index.cjs +1 -1
  390. package/dist/index.d.cts +2089 -102
  391. package/dist/index.d.ts +2089 -102
  392. package/dist/index.mjs +99 -87
  393. package/dist/lib/classNames.cjs +2 -0
  394. package/dist/lib/classNames.cjs.map +1 -0
  395. package/dist/lib/classNames.mjs +415 -0
  396. package/dist/lib/classNames.mjs.map +1 -0
  397. package/dist/lib/color.cjs +2 -0
  398. package/dist/lib/color.cjs.map +1 -0
  399. package/dist/lib/color.mjs +86 -0
  400. package/dist/lib/color.mjs.map +1 -0
  401. package/dist/lib/globalRegistry.cjs.map +1 -1
  402. package/dist/lib/globalRegistry.mjs.map +1 -1
  403. package/dist/lib/toaster.cjs +2 -0
  404. package/dist/lib/toaster.cjs.map +1 -0
  405. package/dist/lib/toaster.mjs +77 -0
  406. package/dist/lib/toaster.mjs.map +1 -0
  407. package/dist/styles.css +1 -1
  408. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.parts.mjs","names":["React","BaseButton","Button","verticalButtonClasses","verticalIconBoxClasses","withIconBox","slotRendersContent","icon","resolved","resolveSlot","box","ToolbarButton","rest","props","toolbar","useToolbarContext","effectiveSize","size","vertical","cn","className","useRegisterCheckable","register","name","value","ToolbarToggleButton","ToggleButton","checked","composeEventHandlers","onClick","event","ToolbarRadioButton","ToolbarRadioGroup","ariaLabel","ariaLabelledBy","warnOnce","handleCrossAxisKeyDown","group","intent","orientation","getArrowIntent","getDirection","radios","current","radio","step","count","offset","candidate","onKeyDown","ToolbarGroup","named","role","ToolbarDivider","forcedColors"],"sources":["../../../src/components/button/Toolbar.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { resolveSlot, slotRendersContent } from '../../lib/slot';\nimport type { SlotObject } from '../../lib/slot';\nimport { forcedColors } from '../../lib/styles';\nimport type { Size, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\nimport { ToggleButton } from './ToggleButton';\nimport type { ToggleButtonProps } from './ToggleButton';\nimport { useToolbarContext } from './Toolbar.context';\n\n/*\n * The parts of a Toolbar: `Toolbar.Button`, `Toolbar.ToggleButton`, `Toolbar.RadioGroup`,\n * `Toolbar.RadioButton`, `Toolbar.Group` and `Toolbar.Divider` (attached in `Toolbar.tsx`, which\n * also exports their flat names).\n */\n\n// ---------------------------------------------------------------------------\n// Toolbar.Button\n// ---------------------------------------------------------------------------\n\n/** Toolbar.Button's own props: Button's, plus `vertical`. Default appearance `'subtle'`. */\nexport interface ToolbarButtonOwnProps extends ButtonOwnProps {\n /** The icon above the label (a 24 px icon box and a caption-size label). @default false */\n vertical?: boolean;\n}\n\n/** Props of {@link ToolbarButton} rendered as `C` (default `'button'`), including `ref`. */\nexport type ToolbarButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ToolbarButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarButtonImplProps = ToolbarButtonOwnProps & { className?: string };\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/** The layout of a vertical button: the icon above a caption-size label, no minimum width. */\nconst verticalButtonClasses = 'h-auto min-w-0 flex-col gap-0.5 px-2 py-1 text-caption-1';\n\n/** The icon box of a vertical button per size: 24 px, 20 px at the two small sizes. */\nconst verticalIconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-5 justify-center [&>svg]:size-full',\n small: 'size-5 justify-center [&>svg]:size-full',\n medium: 'size-6 justify-center [&>svg]:size-full',\n large: 'size-6 justify-center [&>svg]:size-full',\n 'extra-large': 'size-6 justify-center [&>svg]:size-full',\n};\n\n/**\n * `icon` as a slot object whose element also carries `box`: shorthand content becomes the\n * children of a span with `box`, a slot object keeps its element and attributes and gets `box`\n * before its own classes. An icon that renders nothing stays as it is (no icon).\n */\nfunction withIconBox(icon: Slot<'span'> | undefined, box: string): Slot<'span'> | undefined {\n if (!slotRendersContent(icon)) return icon;\n const resolved = resolveSlot(icon, 'span', box);\n if (!resolved) return icon;\n return {\n ...resolved.props,\n as: resolved.Component,\n children: resolved.children,\n } as SlotObject<'span'>;\n}\n\n/**\n * A Button with the toolbar's size and the `subtle` appearance by default (your `size` and\n * `appearance` win). `vertical` puts the icon above a caption-size label, for ribbon-style\n * toolbars. Polymorphic like Button (`as=\"a\"`, a router link). Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.Button` in client files).\n *\n * @example\n * <Toolbar.Button icon={<ShareIcon />}>Share</Toolbar.Button>\n * <Toolbar.Button vertical icon={<PasteIcon />}>Paste</Toolbar.Button>\n */\nexport const ToolbarButton: PolymorphicComponent<'button', ToolbarButtonOwnProps> = (props) => {\n const {\n vertical = false,\n appearance = 'subtle',\n size,\n icon,\n className,\n ...rest\n } = props as ToolbarButtonImplProps;\n const toolbar = useToolbarContext('Toolbar.Button');\n const effectiveSize = size ?? toolbar.size;\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={effectiveSize}\n icon={vertical ? withIconBox(icon, verticalIconBoxClasses[effectiveSize]) : icon}\n data-vertical={vertical ? '' : undefined}\n className={cn(vertical && verticalButtonClasses, className)}\n />\n );\n};\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.ToggleButton and Toolbar.RadioButton\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.ToggleButton: ToggleButton's, bound to the Toolbar's `checkedValues`. */\nexport interface ToolbarToggleButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value'\n> {\n /** The group: a key of the Toolbar's `checkedValues`. */\n name: string;\n /** The value in `checkedValues[name]` while the toggle is pressed. */\n value: string;\n}\n\n/** Properties for Toolbar.RadioButton: one choice of a `Toolbar.RadioGroup`. */\nexport interface ToolbarRadioButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value' | 'role'\n> {\n /** The group: a key of the Toolbar's `checkedValues`; radio buttons of one `name` are exclusive. */\n name: string;\n /** The group's value while this radio is checked. */\n value: string;\n}\n\n/** Registers a part's `name`/`value` with its toolbar (the duplicate-pair warning). */\nfunction useRegisterCheckable(\n register: (name: string, value: string) => () => void,\n name: string,\n value: string,\n): void {\n React.useEffect(() => register(name, value), [register, name, value]);\n}\n\n/**\n * A ToggleButton with the toolbar's size and the `subtle` appearance by default, pressed while\n * `value` is in the Toolbar's `checkedValues[name]`. A click adds or removes it (your `onClick`\n * runs first; `event.preventDefault()` cancels the change) and calls the Toolbar's\n * `onCheckedValuesChange`. `name` and `value` are binding keys, not rendered as attributes.\n * `isAccessible` and `disabledFocusable` work as on ToggleButton. Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.ToggleButton` in client\n * files).\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * </Toolbar>\n */\nexport const ToolbarToggleButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarToggleButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.ToggleButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.toggle(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarToggleButton.displayName = 'ToolbarToggleButton';\n\n/**\n * A ToggleButton with `role=\"radio\"` (it reports its state with `aria-checked` and\n * `data-checked`, besides `data-pressed`), the toolbar's size and the `subtle` appearance by\n * default: one choice of a `Toolbar.RadioGroup`, checked while `value` is the Toolbar's\n * `checkedValues[name]`. Space, Enter or a click checks it (your `onClick` runs first;\n * `event.preventDefault()` cancels); the arrow keys only move focus. A click on the checked radio\n * changes nothing. Must be rendered inside a {@link Toolbar}; flat export for React Server\n * Components (`Toolbar.RadioButton` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarRadioButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.RadioButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n role=\"radio\"\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.select(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarRadioButton.displayName = 'ToolbarRadioButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.RadioGroup\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.RadioGroup. */\nexport interface ToolbarRadioGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A set of `Toolbar.RadioButton`s of which one is checked (`role=\"radiogroup\"`; name it with\n * `aria-label`). Its radios are part of the toolbar's arrow-key order; Up and Down (Left and Right\n * in a vertical toolbar) also move among the group's radios, wrapping inside the group. Arrows\n * only move focus; Space, Enter or a click checks.\n *\n * - The cross-axis keys skip natively disabled radios; a `disabledFocusable` one stays reachable,\n * as in the toolbar's own arrow order. A consumer `onKeyDown` runs first\n * (`event.preventDefault()` cancels the move).\n * - Without `aria-label` or `aria-labelledby` it warns once in development.\n * - Its `role` is always `radiogroup` (a `role` you pass is ignored): its radios need it.\n * - Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.RadioGroup` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\">Left</Toolbar.RadioButton>\n * <Toolbar.RadioButton name=\"align\" value=\"right\">Right</Toolbar.RadioButton>\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioGroup = ({\n className,\n onKeyDown,\n ref,\n ...rest\n}: ToolbarRadioGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.RadioGroup');\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n React.useEffect(() => {\n if (ariaLabel || ariaLabelledBy) return;\n warnOnce(\n 'Toolbar.RadioGroup:name',\n 'Toolbar.RadioGroup: a radio group needs an accessible name that says what it chooses (e.g. \"Text alignment\"). Pass `aria-label` or `aria-labelledby`.',\n );\n }, [ariaLabel, ariaLabelledBy]);\n\n // The cross axis (APG Toolbar): Down/Up in a horizontal toolbar, \"next\"/\"previous\" of Left/Right\n // in a vertical one, move among the group's radios with wrap and check nothing. The toolbar's\n // roving hook records the newly focused radio as its tab stop through its focus handler.\n const handleCrossAxisKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n const group = event.currentTarget;\n const intent =\n orientation === 'vertical'\n ? getArrowIntent(event.key, { orientation: 'horizontal', dir: getDirection(group) })\n : getArrowIntent(event.key, { orientation: 'vertical', dir: 'ltr' });\n if (!intent) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const current = radios.findIndex((radio) => radio.contains(event.target as Node));\n if (current === -1) return;\n event.preventDefault();\n const step = intent === 'next' ? 1 : -1;\n const count = radios.length;\n for (let offset = 1; offset < count; offset++) {\n const candidate = radios[(((current + step * offset) % count) + count) % count];\n if (candidate.matches(':disabled')) continue;\n candidate.focus();\n // A radio that CSS hides does not take focus: try the next one.\n if (candidate.ownerDocument.activeElement === candidate) return;\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n // Its radios and the cross-axis keys need the radiogroup: the role is not replaceable.\n role=\"radiogroup\"\n data-roving-transparent=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, handleCrossAxisKeyDown)}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarRadioGroup.displayName = 'ToolbarRadioGroup';\n\n// ---------------------------------------------------------------------------\n// Toolbar.Group and Toolbar.Divider\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.Group. */\nexport interface ToolbarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Lays out related controls in the toolbar's direction. It is `role=\"presentation\"`, or\n * `role=\"group\"` when you name it with `aria-label` or `aria-labelledby` (a `role` you pass\n * wins). Its controls stay in the toolbar's arrow-key order. Renders `data-orientation`. Must be\n * rendered inside a {@link Toolbar}; flat export for React Server Components (`Toolbar.Group` in\n * client files).\n *\n * @example\n * <Toolbar.Group aria-label=\"Sharing\">\n * <Toolbar.Button>Share</Toolbar.Button>\n * </Toolbar.Group>\n */\nexport const ToolbarGroup = ({ role, className, ref, ...rest }: ToolbarGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.Group');\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n return (\n <div\n role={role ?? (named ? 'group' : 'presentation')}\n data-orientation={orientation}\n {...rest}\n ref={ref}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarGroup.displayName = 'ToolbarGroup';\n\n/** Properties for Toolbar.Divider. */\nexport interface ToolbarDividerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Ref to the separator element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A separator between groups, drawn across the toolbar (vertical in a horizontal toolbar):\n * `role=\"separator\"` with `aria-orientation`. It is not focusable, so the arrow keys pass it.\n * Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.Divider` in client files).\n */\nexport const ToolbarDivider = ({ className, ref, ...rest }: ToolbarDividerProps) => {\n const { orientation } = useToolbarContext('Toolbar.Divider');\n const vertical = orientation === 'vertical';\n return (\n <div\n role=\"separator\"\n aria-orientation={vertical ? 'horizontal' : 'vertical'}\n {...rest}\n ref={ref}\n className={cn(\n vertical\n ? 'my-1 h-0 shrink-0 self-stretch border-t border-border'\n : 'mx-1 w-0 shrink-0 self-stretch border-s border-border',\n forcedColors.border,\n className,\n )}\n />\n );\n};\nToolbarDivider.displayName = 'ToolbarDivider';\n"],"mappings":"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"}
1
+ {"version":3,"file":"Toolbar.parts.mjs","names":["React","BaseButton","Button","verticalButtonClasses","verticalIconBoxClasses","ToolbarButton","rest","props","toolbar","useToolbarContext","effectiveSize","size","withPartClass","vertical","icon","toolbarButtonClassNames","cn","className","useRegisterCheckable","register","name","value","ToolbarToggleButton","ToggleButton","toolbarToggleButtonClassNames","checked","composeEventHandlers","onClick","event","ToolbarRadioButton","toolbarRadioButtonClassNames","ToolbarRadioGroup","ariaLabel","ariaLabelledBy","warnOnce","handleCrossAxisKeyDown","group","intent","orientation","getArrowIntent","getDirection","radios","current","radio","step","count","offset","candidate","onKeyDown","toolbarRadioGroupClassNames","ToolbarGroup","named","role","toolbarGroupClassNames","ToolbarDivider","toolbarDividerClassNames","forcedColors"],"sources":["../../../src/components/button/Toolbar.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport {\n toolbarButtonClassNames,\n toolbarDividerClassNames,\n toolbarGroupClassNames,\n toolbarRadioButtonClassNames,\n toolbarRadioGroupClassNames,\n toolbarToggleButtonClassNames,\n} from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { forcedColors } from '../../lib/styles';\nimport type { Size } from '../../lib/types';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\nimport { ToggleButton } from './ToggleButton';\nimport type { ToggleButtonProps } from './ToggleButton';\nimport { withPartClass } from './Button.slots';\nimport { useToolbarContext } from './Toolbar.context';\n\n/*\n * The parts of a Toolbar: `Toolbar.Button`, `Toolbar.ToggleButton`, `Toolbar.RadioGroup`,\n * `Toolbar.RadioButton`, `Toolbar.Group` and `Toolbar.Divider` (attached in `Toolbar.tsx`, which\n * also exports their flat names).\n */\n\n// ---------------------------------------------------------------------------\n// Toolbar.Button\n// ---------------------------------------------------------------------------\n\n/** Toolbar.Button's own props: Button's, plus `vertical`. Default appearance `'subtle'`. */\nexport interface ToolbarButtonOwnProps extends ButtonOwnProps {\n /** The icon above the label (a 24 px icon box and a caption-size label). @default false */\n vertical?: boolean;\n}\n\n/** Props of {@link ToolbarButton} rendered as `C` (default `'button'`), including `ref`. */\nexport type ToolbarButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ToolbarButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarButtonImplProps = ToolbarButtonOwnProps & { className?: string };\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/** The layout of a vertical button: the icon above a caption-size label, no minimum width. */\nconst verticalButtonClasses = 'h-auto min-w-0 flex-col gap-0.5 px-2 py-1 text-caption-1';\n\n/** The icon box of a vertical button per size: 24 px, 20 px at the two small sizes. */\nconst verticalIconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-5 justify-center [&>svg]:size-full',\n small: 'size-5 justify-center [&>svg]:size-full',\n medium: 'size-6 justify-center [&>svg]:size-full',\n large: 'size-6 justify-center [&>svg]:size-full',\n 'extra-large': 'size-6 justify-center [&>svg]:size-full',\n};\n\n/**\n * A Button with the toolbar's size and the `subtle` appearance by default (your `size` and\n * `appearance` win). `vertical` puts the icon above a caption-size label, for ribbon-style\n * toolbars. Polymorphic like Button (`as=\"a\"`, a router link). Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.Button` in client files).\n *\n * @example\n * <Toolbar.Button icon={<ShareIcon />}>Share</Toolbar.Button>\n * <Toolbar.Button vertical icon={<PasteIcon />}>Paste</Toolbar.Button>\n */\nexport const ToolbarButton: PolymorphicComponent<'button', ToolbarButtonOwnProps> = (props) => {\n const {\n vertical = false,\n appearance = 'subtle',\n size,\n icon,\n className,\n ...rest\n } = props as ToolbarButtonImplProps;\n const toolbar = useToolbarContext('Toolbar.Button');\n const effectiveSize = size ?? toolbar.size;\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={effectiveSize}\n icon={withPartClass(\n vertical ? withPartClass(icon, verticalIconBoxClasses[effectiveSize]) : icon,\n toolbarButtonClassNames.icon,\n )}\n data-vertical={vertical ? '' : undefined}\n className={cn(toolbarButtonClassNames.root, vertical && verticalButtonClasses, className)}\n />\n );\n};\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.ToggleButton and Toolbar.RadioButton\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.ToggleButton: ToggleButton's, bound to the Toolbar's `checkedValues`. */\nexport interface ToolbarToggleButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value'\n> {\n /** The group: a key of the Toolbar's `checkedValues`. */\n name: string;\n /** The value in `checkedValues[name]` while the toggle is pressed. */\n value: string;\n}\n\n/** Properties for Toolbar.RadioButton: one choice of a `Toolbar.RadioGroup`. */\nexport interface ToolbarRadioButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value' | 'role'\n> {\n /** The group: a key of the Toolbar's `checkedValues`; radio buttons of one `name` are exclusive. */\n name: string;\n /** The group's value while this radio is checked. */\n value: string;\n}\n\n/** Registers a part's `name`/`value` with its toolbar (the duplicate-pair warning). */\nfunction useRegisterCheckable(\n register: (name: string, value: string) => () => void,\n name: string,\n value: string,\n): void {\n React.useEffect(() => register(name, value), [register, name, value]);\n}\n\n/**\n * A ToggleButton with the toolbar's size and the `subtle` appearance by default, pressed while\n * `value` is in the Toolbar's `checkedValues[name]`. A click adds or removes it (your `onClick`\n * runs first; `event.preventDefault()` cancels the change) and calls the Toolbar's\n * `onCheckedValuesChange`. `name` and `value` are binding keys, not rendered as attributes.\n * `isAccessible` and `disabledFocusable` work as on ToggleButton. Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.ToggleButton` in client\n * files).\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * </Toolbar>\n */\nexport const ToolbarToggleButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n icon,\n className,\n onClick,\n ...rest\n}: ToolbarToggleButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.ToggleButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n icon={withPartClass(icon, toolbarToggleButtonClassNames.icon)}\n className={cn(toolbarToggleButtonClassNames.root, className)}\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.toggle(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarToggleButton.displayName = 'ToolbarToggleButton';\n\n/**\n * A ToggleButton with `role=\"radio\"` (it reports its state with `aria-checked` and\n * `data-checked`, besides `data-pressed`), the toolbar's size and the `subtle` appearance by\n * default: one choice of a `Toolbar.RadioGroup`, checked while `value` is the Toolbar's\n * `checkedValues[name]`. Space, Enter or a click checks it (your `onClick` runs first;\n * `event.preventDefault()` cancels); the arrow keys only move focus. A click on the checked radio\n * changes nothing. Must be rendered inside a {@link Toolbar}; flat export for React Server\n * Components (`Toolbar.RadioButton` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n icon,\n className,\n onClick,\n ...rest\n}: ToolbarRadioButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.RadioButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n icon={withPartClass(icon, toolbarRadioButtonClassNames.icon)}\n className={cn(toolbarRadioButtonClassNames.root, className)}\n role=\"radio\"\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.select(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarRadioButton.displayName = 'ToolbarRadioButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.RadioGroup\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.RadioGroup. */\nexport interface ToolbarRadioGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A set of `Toolbar.RadioButton`s of which one is checked (`role=\"radiogroup\"`; name it with\n * `aria-label`). Its radios are part of the toolbar's arrow-key order; Up and Down (Left and Right\n * in a vertical toolbar) also move among the group's radios, wrapping inside the group. Arrows\n * only move focus; Space, Enter or a click checks.\n *\n * - The cross-axis keys skip natively disabled radios; a `disabledFocusable` one stays reachable,\n * as in the toolbar's own arrow order. A consumer `onKeyDown` runs first\n * (`event.preventDefault()` cancels the move).\n * - Without `aria-label` or `aria-labelledby` it warns once in development.\n * - Its `role` is always `radiogroup` (a `role` you pass is ignored): its radios need it.\n * - Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.RadioGroup` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\">Left</Toolbar.RadioButton>\n * <Toolbar.RadioButton name=\"align\" value=\"right\">Right</Toolbar.RadioButton>\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioGroup = ({\n className,\n onKeyDown,\n ref,\n ...rest\n}: ToolbarRadioGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.RadioGroup');\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n React.useEffect(() => {\n if (ariaLabel || ariaLabelledBy) return;\n warnOnce(\n 'Toolbar.RadioGroup:name',\n 'Toolbar.RadioGroup: a radio group needs an accessible name that says what it chooses (e.g. \"Text alignment\"). Pass `aria-label` or `aria-labelledby`.',\n );\n }, [ariaLabel, ariaLabelledBy]);\n\n // The cross axis (APG Toolbar): Down/Up in a horizontal toolbar, \"next\"/\"previous\" of Left/Right\n // in a vertical one, move among the group's radios with wrap and check nothing. The toolbar's\n // roving hook records the newly focused radio as its tab stop through its focus handler.\n const handleCrossAxisKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n const group = event.currentTarget;\n const intent =\n orientation === 'vertical'\n ? getArrowIntent(event.key, { orientation: 'horizontal', dir: getDirection(group) })\n : getArrowIntent(event.key, { orientation: 'vertical', dir: 'ltr' });\n if (!intent) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const current = radios.findIndex((radio) => radio.contains(event.target as Node));\n if (current === -1) return;\n event.preventDefault();\n const step = intent === 'next' ? 1 : -1;\n const count = radios.length;\n for (let offset = 1; offset < count; offset++) {\n const candidate = radios[(((current + step * offset) % count) + count) % count];\n if (candidate.matches(':disabled')) continue;\n candidate.focus();\n // A radio that CSS hides does not take focus: try the next one.\n if (candidate.ownerDocument.activeElement === candidate) return;\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n // Its radios and the cross-axis keys need the radiogroup: the role is not replaceable.\n role=\"radiogroup\"\n data-roving-transparent=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, handleCrossAxisKeyDown)}\n className={cn(\n toolbarRadioGroupClassNames.root,\n 'flex gap-1',\n orientation === 'vertical' && 'flex-col',\n className,\n )}\n />\n );\n};\nToolbarRadioGroup.displayName = 'ToolbarRadioGroup';\n\n// ---------------------------------------------------------------------------\n// Toolbar.Group and Toolbar.Divider\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.Group. */\nexport interface ToolbarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Lays out related controls in the toolbar's direction. It is `role=\"presentation\"`, or\n * `role=\"group\"` when you name it with `aria-label` or `aria-labelledby` (a `role` you pass\n * wins). Its controls stay in the toolbar's arrow-key order. Renders `data-orientation`. Must be\n * rendered inside a {@link Toolbar}; flat export for React Server Components (`Toolbar.Group` in\n * client files).\n *\n * @example\n * <Toolbar.Group aria-label=\"Sharing\">\n * <Toolbar.Button>Share</Toolbar.Button>\n * </Toolbar.Group>\n */\nexport const ToolbarGroup = ({ role, className, ref, ...rest }: ToolbarGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.Group');\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n return (\n <div\n role={role ?? (named ? 'group' : 'presentation')}\n data-orientation={orientation}\n {...rest}\n ref={ref}\n className={cn(\n toolbarGroupClassNames.root,\n 'flex gap-1',\n orientation === 'vertical' && 'flex-col',\n className,\n )}\n />\n );\n};\nToolbarGroup.displayName = 'ToolbarGroup';\n\n/** Properties for Toolbar.Divider. */\nexport interface ToolbarDividerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Ref to the separator element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A separator between groups, drawn across the toolbar (vertical in a horizontal toolbar):\n * `role=\"separator\"` with `aria-orientation`. It is not focusable, so the arrow keys pass it.\n * Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.Divider` in client files).\n */\nexport const ToolbarDivider = ({ className, ref, ...rest }: ToolbarDividerProps) => {\n const { orientation } = useToolbarContext('Toolbar.Divider');\n const vertical = orientation === 'vertical';\n return (\n <div\n role=\"separator\"\n aria-orientation={vertical ? 'horizontal' : 'vertical'}\n {...rest}\n ref={ref}\n className={cn(\n toolbarDividerClassNames.root,\n vertical\n ? 'my-1 h-0 shrink-0 self-stretch border-t border-border'\n : 'mx-1 w-0 shrink-0 self-stretch border-s border-border',\n forcedColors.border,\n className,\n )}\n />\n );\n};\nToolbarDivider.displayName = 'ToolbarDivider';\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/slot.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../hooks/useMergedRefs.cjs"),ee=require("../../lib/aria.cjs"),te=require("../../lib/icons.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("react/jsx-runtime");var s={"extra-small":`w-6 h-6 text-[10px]`,small:`w-8 h-8 text-xs`,medium:`w-10 h-10 text-sm`,large:`w-12 h-12 text-base`,"extra-large":`w-14 h-14 text-lg`},c=`w-full h-full object-cover`;function ne(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?``:((Array.from(t[0])[0]??``)+(t.length>1?Array.from(t[t.length-1])[0]??``:``)).toUpperCase()}function l(e){return e?.trim().replace(/\s+/g,` `)||void 0}function re(e){if(a.isValidElement(e))return e.props;if(typeof e==`object`&&e&&!(Symbol.iterator in e))return e}function ie(e,t,n){if(e===void 0)return[void 0,void 0,n||void 0,void 0];if(typeof e==`string`)return[void 0,void 0,e,void 0];let r=a.isValidElement(e)?e:void 0;return[r?.type,r?.key,t?.src,t?.srcSet]}function u(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function d(e,t){if(Object.is(e,t))return!0;if(!u(e)||!u(t))return!1;let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&Object.is(e[n],t[n]))}function ae(e,t){return e.every((e,n)=>d(e,t[n]))}var f=({src:e,name:u,size:d=`medium`,icon:f,image:p,badge:m,decorative:h=!1,className:g,ref:_,role:v,"aria-label":y,"aria-labelledby":b,"aria-describedby":x,"aria-description":S,"aria-details":C,...w})=>{let T=p==null||typeof p==`boolean`||p===``?void 0:p,E=re(T),D=ie(T,E,e),[oe,O]=a.useState(!1),[k,A]=a.useState(D);ae(k,D)||(A(D),O(!1));let j=a.useRef(null);a.useLayoutEffect(()=>{let e=j.current?.querySelector(`img`);if(!e||!e.complete||e.naturalWidth!==0)return;let t=!0,n=e.getAttribute(`src`),r=e.getAttribute(`srcset`),i=()=>{t&&e.isConnected&&e.getAttribute(`src`)===n&&e.getAttribute(`srcset`)===r&&O(!0)};return typeof e.decode==`function`?e.decode().then(void 0,i):queueMicrotask(i),()=>{t=!1}},[]);let M=i.useMergedRefs(_,j),N=y!==void 0||b!==void 0,P=v!==void 0&&v!==`presentation`&&v!==`none`,F=l(u),I=h||N||P?``:F??``,L=()=>O(!0),R=E?.alt,z=R!=null,B=z?R:I,V={"aria-describedby":x,"aria-description":S,"aria-details":C},H=!h&&!N&&!P&&typeof B==`string`&&B.trim()!==``,U=H?V:{},W=null;if(!oe){if(typeof T==`string`)W=(0,o.jsx)(`img`,{src:T,alt:I,...U,className:c,onError:L});else if(T!==void 0){let e={onError:r.composeEventHandlers(E?.onError,L)};if(z||(e.alt=I),H){let t=E?.[`aria-describedby`];e[`aria-describedby`]=ee.joinIds(x,typeof t==`string`?t:void 0)}let t=a.isValidElement(T)?a.cloneElement(T,e):E?{...T,...e}:T;W=n.renderSlot(t,`img`,c,{alt:I,...U})}else e&&(W=(0,o.jsx)(`img`,{src:e,alt:I,...U,className:c,onError:L}))}let G=W!==null&&H?{}:V,K=W===null&&f&&n.slotRendersContent(f)?n.renderSlot(f,`span`,`inline-flex`,{"aria-hidden":!0}):null,q=W===null&&K===null&&u?ne(u):``,J,Y;W===null?K===null?q?(J=(0,o.jsx)(`span`,{"aria-hidden":`true`,children:q}),Y=`bg-primary text-primary-foreground`):(J=(0,o.jsx)(te.PersonIcon,{size:`60%`}),Y=`bg-muted text-muted-foreground`):(J=K,Y=`bg-muted text-muted-foreground`):J=W;let se=W!==null&&P&&typeof B==`string`?l(B):void 0,ce=typeof R==`string`?l(R):void 0,X=y??(W===null?F??ce:P?se??F:void 0),Z;Z=h?{"aria-hidden":!0,...G}:X!==void 0||b!==void 0?{role:v??`img`,"aria-label":X,"aria-labelledby":b,...G}:W!==null||v!==void 0?{role:v,...G}:{"aria-hidden":!0,...G};let Q=m&&n.slotRendersContent(m)?n.renderSlot(m,`span`,`absolute bottom-0 end-0 inline-flex`):null,le=Q!==null,$=t.cn(`inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold`,s[d],Y);return le?(0,o.jsxs)(`span`,{ref:_,...w,className:t.cn(`relative inline-flex shrink-0`,g),children:[(0,o.jsx)(`span`,{ref:j,...Z,className:$,children:J}),Q]}):(0,o.jsx)(`span`,{ref:M,...Z,...w,className:t.cn($,g),children:J})};f.displayName=`Avatar`,exports.Avatar=f,exports.avatarSizeClasses=s;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/slot.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useMergedRefs.cjs"),ee=require("../../lib/aria.cjs"),te=require("../../lib/icons.cjs");let o=require("react");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c={"extra-small":`w-6 h-6 text-[10px]`,small:`w-8 h-8 text-xs`,medium:`w-10 h-10 text-sm`,large:`w-12 h-12 text-base`,"extra-large":`w-14 h-14 text-lg`},l=`w-full h-full object-cover`;function ne(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?``:((Array.from(t[0])[0]??``)+(t.length>1?Array.from(t[t.length-1])[0]??``:``)).toUpperCase()}function u(e){return e?.trim().replace(/\s+/g,` `)||void 0}function d(e){if(o.isValidElement(e))return e.props;if(typeof e==`object`&&e&&!(Symbol.iterator in e))return e}function re(e,t,n){if(e===void 0)return[void 0,void 0,n||void 0,void 0];if(typeof e==`string`)return[void 0,void 0,e,void 0];let r=o.isValidElement(e)?e:void 0;return[r?.type,r?.key,t?.src,t?.srcSet]}function f(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function p(e,t){if(Object.is(e,t))return!0;if(!f(e)||!f(t))return!1;let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&Object.is(e[n],t[n]))}function ie(e,t){return e.every((e,n)=>p(e,t[n]))}var m=({src:e,name:f,size:p=`medium`,icon:m,image:h,badge:g,decorative:_=!1,className:v,ref:y,role:b,"aria-label":x,"aria-labelledby":S,"aria-describedby":C,"aria-description":ae,"aria-details":oe,...w})=>{let T=h==null||typeof h==`boolean`||h===``?void 0:h,E=d(T),D=re(T,E,e),[se,O]=o.useState(!1),[k,A]=o.useState(D);ie(k,D)||(A(D),O(!1));let j=o.useRef(null);o.useLayoutEffect(()=>{let e=j.current?.querySelector(`img`);if(!e||!e.complete||e.naturalWidth!==0)return;let t=!0,n=e.getAttribute(`src`),r=e.getAttribute(`srcset`),i=()=>{t&&e.isConnected&&e.getAttribute(`src`)===n&&e.getAttribute(`srcset`)===r&&O(!0)};return typeof e.decode==`function`?e.decode().then(void 0,i):queueMicrotask(i),()=>{t=!1}},[]);let M=a.useMergedRefs(y,j),N=x!==void 0||S!==void 0,P=b!==void 0&&b!==`presentation`&&b!==`none`,F=u(f),I=_||N||P?``:F??``,L=()=>O(!0),R=E?.alt,z=R!=null,B=z?R:I,V={"aria-describedby":C,"aria-description":ae,"aria-details":oe},H=!_&&!N&&!P&&typeof B==`string`&&B.trim()!==``,U=H?V:{},W=null;if(!se){if(typeof T==`string`)W=(0,s.jsx)(`img`,{src:T,alt:I,...U,className:t.cn(i.avatarClassNames.image,l),onError:L});else if(T!==void 0){let e={onError:r.composeEventHandlers(E?.onError,L)};if(z||(e.alt=I),H){let t=E?.[`aria-describedby`];e[`aria-describedby`]=ee.joinIds(C,typeof t==`string`?t:void 0)}let a=o.isValidElement(T)?o.cloneElement(T,e):E?{...T,...e}:T;W=n.renderSlot(a,`img`,t.cn(i.avatarClassNames.image,l),{alt:I,...U})}else e&&(W=(0,s.jsx)(`img`,{src:e,alt:I,...U,className:t.cn(i.avatarClassNames.image,l),onError:L}))}let G=W!==null&&H?{}:V,K=W===null&&m&&n.slotRendersContent(m)?n.renderSlot(m,`span`,t.cn(i.avatarClassNames.icon,`inline-flex`),{"aria-hidden":!0}):null,q=W===null&&K===null&&f?ne(f):``,J,Y;W===null?K===null?q?(J=(0,s.jsx)(`span`,{"aria-hidden":`true`,className:i.avatarClassNames.initials,children:q}),Y=`bg-primary text-primary-foreground`):(J=(0,s.jsx)(te.PersonIcon,{size:`60%`,className:i.avatarClassNames.icon}),Y=`bg-muted text-muted-foreground`):(J=K,Y=`bg-muted text-muted-foreground`):J=W;let ce=W!==null&&P&&typeof B==`string`?u(B):void 0,le=typeof R==`string`?u(R):void 0,X=x??(W===null?F??le:P?ce??F:void 0),Z;Z=_?{"aria-hidden":!0,...G}:X!==void 0||S!==void 0?{role:b??`img`,"aria-label":X,"aria-labelledby":S,...G}:W!==null||b!==void 0?{role:b,...G}:{"aria-hidden":!0,...G};let Q=g&&n.slotRendersContent(g)?n.renderSlot(g,`span`,t.cn(i.avatarClassNames.badge,`absolute bottom-0 end-0 inline-flex`)):null,ue=Q!==null,$=t.cn(i.avatarClassNames.visual,`inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold`,c[p],Y);return ue?(0,s.jsxs)(`span`,{ref:y,...w,className:t.cn(i.avatarClassNames.root,`relative inline-flex shrink-0`,v),children:[(0,s.jsx)(`span`,{ref:j,...Z,className:$,children:J}),Q]}):(0,s.jsx)(`span`,{ref:M,...Z,...w,className:t.cn(i.avatarClassNames.root,$,v),children:J})};m.displayName=`Avatar`,exports.Avatar=m,exports.avatarSizeClasses=c;
2
2
  //# sourceMappingURL=Avatar.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.cjs","names":["React","useMergedRefs","composeEventHandlers","joinIds","renderSlot","slotRendersContent","PersonIcon","cn","require_runtime","require_cn","require_slot","require_composeEventHandlers","require_useMergedRefs","require_aria","require_icons","react","react_jsx_runtime","avatarSizeClasses","IMAGE_CLASS","getInitials","parts","name","normaliseName","readSlotProps","slot","getImageKey","imageSlot","src","element","slotProps","isPlainObject","value","proto","sameKeyPart","a","b","keys","k","sameImageKey","part","i","Avatar","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaDescription","ariaDetails","rest","image","imageKey","failed","setFailed","prevImageKey","setPrevImageKey","visualRef","img","active","checkedSrc","checkedSrcSet","markFailed","rootVisualRef","ref","hasConsumerName","roleCarriesName","role","normalisedName","imageAlt","decorative","handleError","ownAlt","hasOwnAlt","renderedAlt","description","imageIsNamed","imageDescription","imageNode","overrides","ownIds","visualDescription","iconNode","icon","initials","content","colorClass","imageName","slotAltName","label","a11yProps","badgeNode","badge","hasBadge","visualClassName","size","className"],"sources":["../../../src/components/data-display/Avatar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { PersonIcon } from '../../lib/icons';\nimport type { Size, Slot } from '../../lib/types';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\n\n/** Properties for the Avatar component. */\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * URL of the avatar image. When it fails to load (also before hydration, for server-rendered\n * markup), the avatar falls back to its icon or initials; a new `src` is tried again.\n */\n src?: string;\n /**\n * Full name of the person. It names the avatar for assistive technology (the image `alt`; in\n * initials and icon mode, or with a consumer `role`, the avatar's `aria-label`, with\n * `role=\"img\"` unless `role` is given) and generates the initials shown when there is no image.\n */\n name?: string;\n /** Size of the avatar.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon shown instead of the initials when there is no image. Rendered in an `aria-hidden`\n * `<span>` (a slot object can override its attributes). A falsy value (`null`, `false`, `''`,\n * `0`, `NaN`, e.g. `icon={count && <Icon />}`) counts as no icon, as in 0.4, and so does an\n * array, `Set` or generator whose items render nothing. Without `icon` and without a usable\n * `name`, a generic person glyph is shown.\n */\n icon?: Slot<'span'>;\n /**\n * Custom image. Accepts a URL string (treated like `src`), an element (rendered as the image\n * itself, e.g. `<img>` or a framework image component) or an object of `<img>` attributes\n * (`{ src, alt, … }`). Takes precedence over `src`; its `alt` defaults to `name` (an `alt` that\n * is `undefined` counts as not given). When its alt names the avatar, the avatar's\n * `aria-describedby` ids are joined with the slot's own, while the slot's own `aria-description`\n * and `aria-details` win over the avatar's. When the image fails to load, an avatar without a\n * `name` keeps the name of the slot's own `alt`. After a load failure, a new image is tried\n * again: another `src` or `srcSet` of any type (an equal inline object is the same image), or\n * for an element slot another component type or `key`.\n */\n image?: Slot<'img'>;\n /**\n * Badge shown at the bottom end corner, e.g. `<PresenceBadge status=\"busy\" />`. With a badge\n * the avatar is wrapped in an outer `<span>` that receives `ref`, `className` and the other\n * props; `role`, `aria-label`, `aria-labelledby`, `aria-describedby`, `aria-description` and\n * `aria-details` stay on the avatar visual, so the badge keeps its own accessible name. A falsy\n * value (`null`, `false`, `''`, `0`, `NaN`, e.g. `badge={count && <CounterBadge count={count} />}`)\n * counts as no badge, as in 0.4, and so does an array, `Set` or generator whose items render\n * nothing: the avatar then renders without the wrapper.\n */\n badge?: Slot<'span'>;\n /**\n * Hides the avatar visual from assistive technology (`aria-hidden`, empty image `alt`, no\n * `role=\"img\"`). Use it when the name is already shown next to the avatar (Persona). A badge\n * stays exposed.\n * @default false\n */\n decorative?: boolean;\n /** Ref to the root `<span>`: the avatar itself, or the badge wrapper when `badge` is set. */\n ref?: React.Ref<HTMLSpanElement>;\n}\n\n/**\n * Width, height and text size classes of the avatar per `size`. Module-only (not in the barrel):\n * AvatarGroup sizes its overflow button with the same classes, so the two always match.\n */\nexport const avatarSizeClasses: Readonly<Record<Size, string>> = {\n 'extra-small': 'w-6 h-6 text-[10px]', // 24px\n small: 'w-8 h-8 text-xs', // 32px\n medium: 'w-10 h-10 text-sm', // 40px\n large: 'w-12 h-12 text-base', // 48px\n 'extra-large': 'w-14 h-14 text-lg', // 56px\n};\n\nconst IMAGE_CLASS = 'w-full h-full object-cover';\n\n/** First letter of the first and last word, upper-cased; `''` for a blank name. */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '';\n const first = Array.from(parts[0]!)[0] ?? '';\n const last = parts.length > 1 ? (Array.from(parts[parts.length - 1]!)[0] ?? '') : '';\n return (first + last).toUpperCase();\n}\n\n/** A name with its whitespace collapsed, or `undefined` when it is blank. */\nfunction normaliseName(name: string | undefined): string | undefined {\n return name?.trim().replace(/\\s+/g, ' ') || undefined;\n}\n\ntype ImageErrorHandler = React.ReactEventHandler<HTMLImageElement>;\n\n/** Description props that go to the element carrying the avatar's name (data-display#19). */\ntype DescriptionProps = Pick<\n React.HTMLAttributes<HTMLElement>,\n 'aria-describedby' | 'aria-description' | 'aria-details'\n>;\n\n/** Props the avatar sets on an element or object image slot, over the slot's own. */\ninterface SlotOverrides {\n onError: ImageErrorHandler;\n alt?: string;\n 'aria-describedby'?: string;\n}\n\n/** The props of an element or object image slot that the avatar reads. */\ninterface ImageSlotProps {\n src?: unknown;\n srcSet?: unknown;\n alt?: unknown;\n onError?: unknown;\n 'aria-describedby'?: unknown;\n}\n\n/** The props of an element or object image slot (to read its `src`, `alt` and handlers). */\nfunction readSlotProps(slot: unknown): ImageSlotProps | undefined {\n if (React.isValidElement(slot)) return slot.props as ImageSlotProps;\n if (typeof slot === 'object' && slot !== null && !(Symbol.iterator in slot)) {\n return slot as ImageSlotProps;\n }\n return undefined;\n}\n\n/**\n * What identifies the image, so a load failure is kept for it and a new image is tried again\n * (data-display#4): the `src` and `srcSet`, of any type (a framework image component may take a\n * static-import object), and for an element slot also its type and `key`.\n */\ntype ImageKey = readonly [type: unknown, key: unknown, src: unknown, srcSet: unknown];\n\nfunction getImageKey(\n imageSlot: unknown,\n slotProps: ImageSlotProps | undefined,\n src: string | undefined,\n): ImageKey {\n if (imageSlot === undefined) return [undefined, undefined, src || undefined, undefined];\n if (typeof imageSlot === 'string') return [undefined, undefined, imageSlot, undefined];\n const element = React.isValidElement(imageSlot) ? imageSlot : undefined;\n return [element?.type, element?.key, slotProps?.src, slotProps?.srcSet];\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/** Same value, or plain objects with the same entries (an inline `src={{ … }}` on each render). */\nfunction sameKeyPart(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const keys = Object.keys(a);\n return (\n keys.length === Object.keys(b).length &&\n keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && Object.is(a[k], b[k]))\n );\n}\n\nfunction sameImageKey(a: ImageKey, b: ImageKey): boolean {\n return a.every((part, i) => sameKeyPart(part, b[i]));\n}\n\n/**\n * A circular picture of a person: their image, an icon, or the initials of their `name`.\n *\n * - **Image**: `image` (URL string, element or `{ src, alt }` object) or `src`. If the image fails\n * to load, the avatar falls back to `icon`, the initials or a person glyph, with their\n * background; a new image is tried again. A server-rendered image that failed before hydration\n * is detected after mount (settled without a natural size, confirmed by `decode()`).\n * - **Accessible name**: an image uses `name` (whitespace collapsed) as its `alt`, or `''` when the\n * name is blank. Without an image (none given, or it failed to load) the avatar is `role=\"img\"`\n * with `aria-label={name}` (without a name: the image slot's own `alt`) and the initials/icon\n * are hidden; without either (and without `aria-label`/`aria-labelledby`) it is decorative\n * (`aria-hidden`). A consumer `aria-label`, `aria-labelledby` or `role` (other than\n * `presentation`/`none`) puts the name on the avatar visual, and an image inside it gets\n * `alt=\"\"`. `decorative` hides it in every mode. `aria-describedby`, `aria-description` and\n * `aria-details` go to the element that carries the name: the `<img>` when a non-blank `alt`\n * names it, otherwise the avatar visual (never an `alt=\"\"` image).\n * - **Badge**: `badge` renders at the bottom end corner (logical, RTL-safe) as a sibling of the\n * avatar visual, so a `PresenceBadge` keeps its own name. With a badge, `ref`, `className` and\n * the rest props go to the outer wrapper.\n *\n * @example\n * <Avatar name=\"Jane Doe\" src=\"/jane.jpg\" badge={<PresenceBadge status=\"available\" />} />\n */\nexport const Avatar = ({\n src,\n name,\n size = 'medium',\n icon,\n image,\n badge,\n decorative = false,\n className,\n ref,\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n ...rest\n}: AvatarProps) => {\n const imageSlot =\n image === null || image === undefined || typeof image === 'boolean' || image === ''\n ? undefined\n : image;\n const slotProps = readSlotProps(imageSlot);\n const imageKey = getImageKey(imageSlot, slotProps, src);\n\n // Load failure of the current image; a new image is tried again (C-HOOKS: adjust state during\n // render on prop change).\n const [failed, setFailed] = React.useState(false);\n const [prevImageKey, setPrevImageKey] = React.useState(imageKey);\n if (!sameImageKey(prevImageKey, imageKey)) {\n setPrevImageKey(imageKey);\n setFailed(false);\n }\n\n // An image that failed before hydration (a fast 404 of server-rendered markup) never reaches\n // `onError`: React attaches the listener while hydrating and does not replay the event. After\n // mount, a settled image without a natural size is broken, unless it is an SVG without one, so\n // `decode()` (which rejects for a broken image) confirms it where the browser supports it. Later\n // images, rendered by the client, report their errors through `onError`.\n const visualRef = React.useRef<HTMLSpanElement>(null);\n React.useLayoutEffect(() => {\n const img = visualRef.current?.querySelector('img');\n if (!img || !img.complete || img.naturalWidth !== 0) return;\n let active = true;\n const checkedSrc = img.getAttribute('src');\n const checkedSrcSet = img.getAttribute('srcset');\n const markFailed = () => {\n // Deferred (C-HOOKS); skipped if the image was replaced or got another source meanwhile.\n if (\n active &&\n img.isConnected &&\n img.getAttribute('src') === checkedSrc &&\n img.getAttribute('srcset') === checkedSrcSet\n ) {\n setFailed(true);\n }\n };\n if (typeof img.decode === 'function') img.decode().then(undefined, markFailed);\n else queueMicrotask(markFailed);\n return () => {\n active = false;\n };\n }, []);\n const rootVisualRef = useMergedRefs(ref, visualRef);\n\n const hasConsumerName = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n // A consumer role goes to the visual span together with the name (data-display#19), so the\n // image inside it is presentational (`alt=\"\"`), as with a consumer `aria-label`: the children\n // of `role=\"img\"` are not exposed. A presentational role (`presentation`, `none`) cannot carry\n // a name, so the image keeps it.\n const roleCarriesName = role !== undefined && role !== 'presentation' && role !== 'none';\n const normalisedName = normaliseName(name);\n const imageAlt = decorative || hasConsumerName || roleCarriesName ? '' : (normalisedName ?? '');\n const handleError: ImageErrorHandler = () => setFailed(true);\n\n // The alt text the image renders with: an element or object slot's own `alt` wins over ours. An\n // `alt` that is `undefined` (an optional `alt: user.photoAlt`, a wrapper forwarding `alt={alt}`)\n // or `null` is not given, so ours applies (the slot's own value would otherwise override it).\n const ownAlt = slotProps?.alt;\n const hasOwnAlt = ownAlt !== undefined && ownAlt !== null;\n const renderedAlt: unknown = hasOwnAlt ? ownAlt : imageAlt;\n\n // The description goes to the element that carries the name: the image itself when a non-blank\n // `alt` names it (the visual span then has no role, or a presentational one), otherwise the\n // visual span. An image with an empty `alt` is presentational, and a description on it would\n // conflict with that role.\n const description: DescriptionProps = {\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n };\n const imageIsNamed =\n !decorative &&\n !hasConsumerName &&\n !roleCarriesName &&\n typeof renderedAlt === 'string' &&\n renderedAlt.trim() !== '';\n const imageDescription: DescriptionProps = imageIsNamed ? description : {};\n\n let imageNode: React.ReactNode = null;\n if (!failed) {\n if (typeof imageSlot === 'string') {\n imageNode = (\n <img\n src={imageSlot}\n alt={imageAlt}\n {...imageDescription}\n className={IMAGE_CLASS}\n onError={handleError}\n />\n );\n } else if (imageSlot !== undefined) {\n // The slot's own props win over renderSlot's defaults, so the composed `onError`, the\n // default `alt` (when the slot gives none) and the joined `aria-describedby` (the avatar's\n // ids, then the slot's) are set on the slot itself. A slot's own `aria-description` and\n // `aria-details` win over the avatar's.\n const overrides: SlotOverrides = {\n onError: composeEventHandlers(\n slotProps?.onError as ImageErrorHandler | undefined,\n handleError,\n ),\n };\n if (!hasOwnAlt) overrides.alt = imageAlt;\n if (imageIsNamed) {\n const ownIds = slotProps?.['aria-describedby'];\n overrides['aria-describedby'] = joinIds(\n ariaDescribedBy,\n typeof ownIds === 'string' ? ownIds : undefined,\n );\n }\n const slot = React.isValidElement(imageSlot)\n ? React.cloneElement(imageSlot as React.ReactElement<SlotOverrides>, overrides)\n : slotProps\n ? { ...(imageSlot as object), ...overrides }\n : imageSlot;\n imageNode = renderSlot(slot as Slot<'img'>, 'img', IMAGE_CLASS, {\n alt: imageAlt,\n ...imageDescription,\n });\n } else if (src) {\n imageNode = (\n <img\n src={src}\n alt={imageAlt}\n {...imageDescription}\n className={IMAGE_CLASS}\n onError={handleError}\n />\n );\n }\n }\n const visualDescription = imageNode !== null && imageIsNamed ? {} : description;\n\n // A falsy icon (`icon={count && <Icon />}` with count 0) is no icon, as in 0.4, and so is a\n // collection whose items render nothing (`icon={items.map(…)}` mapping to nothing). The check\n // does not consume a generator: renderSlot still renders its items.\n const iconNode =\n imageNode === null && icon && slotRendersContent(icon)\n ? renderSlot(icon, 'span', 'inline-flex', { 'aria-hidden': true })\n : null;\n const initials = imageNode === null && iconNode === null && name ? getInitials(name) : '';\n\n let content: React.ReactNode;\n let colorClass: string | undefined;\n if (imageNode !== null) {\n content = imageNode;\n } else if (iconNode !== null) {\n content = iconNode;\n colorClass = 'bg-muted text-muted-foreground';\n } else if (initials) {\n content = <span aria-hidden=\"true\">{initials}</span>;\n colorClass = 'bg-primary text-primary-foreground';\n } else {\n content = <PersonIcon size=\"60%\" />;\n colorClass = 'bg-muted text-muted-foreground';\n }\n\n // Accessible name of the avatar visual (data-display#19, #27). With a consumer role and an\n // image it is the name the image would carry: an element or object slot's own alt, else `name`.\n // Without an image (none given, or it failed to load) it is `name`, else the slot's own alt: an\n // avatar named only by its image alt keeps that name when the image fails.\n const imageName =\n imageNode !== null && roleCarriesName && typeof renderedAlt === 'string'\n ? normaliseName(renderedAlt)\n : undefined;\n const slotAltName = typeof ownAlt === 'string' ? normaliseName(ownAlt) : undefined;\n const label =\n ariaLabel ??\n (imageNode === null\n ? (normalisedName ?? slotAltName)\n : roleCarriesName\n ? (imageName ?? normalisedName)\n : undefined);\n let a11yProps: React.HTMLAttributes<HTMLSpanElement>;\n if (decorative) {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n } else if (label !== undefined || ariaLabelledBy !== undefined) {\n a11yProps = {\n role: role ?? 'img',\n 'aria-label': label,\n 'aria-labelledby': ariaLabelledBy,\n ...visualDescription,\n };\n } else if (imageNode !== null || role !== undefined) {\n a11yProps = { role, ...visualDescription };\n } else {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n }\n\n // A falsy or empty badge (`badge={count && <CounterBadge … />}` with count 0) is no badge, as in\n // 0.4 and like `icon`: no stray \"0\" in the corner, and no wrapper taking the root props.\n const badgeNode =\n badge && slotRendersContent(badge)\n ? renderSlot(badge, 'span', 'absolute bottom-0 end-0 inline-flex')\n : null;\n const hasBadge = badgeNode !== null;\n\n const visualClassName = cn(\n 'inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold',\n avatarSizeClasses[size],\n colorClass,\n );\n\n if (!hasBadge) {\n return (\n <span ref={rootVisualRef} {...a11yProps} {...rest} className={cn(visualClassName, className)}>\n {content}\n </span>\n );\n }\n\n return (\n <span ref={ref} {...rest} className={cn('relative inline-flex shrink-0', className)}>\n <span ref={visualRef} {...a11yProps} className={visualClassName}>\n {content}\n </span>\n {badgeNode}\n </span>\n );\n};\n\nAvatar.displayName = 'Avatar';\n"],"mappings":"4WAuEA,IAAaiB,EAAoD,CAC/D,cAAe,sBACf,MAAO,kBACP,OAAQ,oBACR,MAAO,sBACP,cAAe,mBACjB,EAEMC,EAAc,6BAGpB,SAASC,GAAY,EAAsB,CACzC,IAAMC,EAAQC,EAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO,EAIrD,OAHID,EAAM,SAAW,EAAU,KACjB,MAAM,KAAKA,EAAM,EAAG,CAAC,CAAC,IAAM,KAC7BA,EAAM,OAAS,EAAK,MAAM,KAAKA,EAAMA,EAAM,OAAS,EAAG,CAAC,CAAC,IAAM,GAAM,IAAA,CAC5D,YAAY,CACpC,CAGA,SAASE,EAAc,EAA8C,CACnE,OAAOD,GAAM,KAAK,CAAC,CAAC,QAAQ,OAAQ,GAAG,GAAK,IAAA,EAC9C,CA2BA,SAASE,GAAc,EAA2C,CAChE,GAAIvB,EAAM,eAAewB,CAAI,EAAG,OAAOA,EAAK,MAC5C,GAAI,OAAOA,GAAS,UAAYA,GAAiB,EAAE,OAAO,YAAYA,GACpE,OAAOA,CAGX,CASA,SAASC,GACP,EACA,EACA,EACU,CACV,GAAIC,IAAc,IAAA,GAAW,MAAO,CAAC,IAAA,GAAW,IAAA,GAAWC,GAAO,IAAA,GAAW,IAAA,EAAS,EACtF,GAAI,OAAOD,GAAc,SAAU,MAAO,CAAC,IAAA,GAAW,IAAA,GAAWA,EAAW,IAAA,EAAS,EACrF,IAAME,EAAU5B,EAAM,eAAe0B,CAAS,EAAIA,EAAY,IAAA,GAC9D,MAAO,CAACE,GAAS,KAAMA,GAAS,IAAKC,GAAW,IAAKA,GAAW,MAAM,CACxE,CAEA,SAASC,EAAc,EAAkD,CACvE,GAAI,OAAOC,GAAU,WAAYA,EAAgB,MAAO,GACxD,IAAMC,EAAiB,OAAO,eAAeD,CAAK,EAClD,OAAOC,IAAU,OAAO,WAAaA,IAAU,IACjD,CAGA,SAASC,EAAY,EAAY,EAAqB,CACpD,GAAI,OAAO,GAAGC,EAAGC,CAAC,EAAG,MAAO,GAC5B,GAAI,CAACL,EAAcI,CAAC,GAAK,CAACJ,EAAcK,CAAC,EAAG,MAAO,GACnD,IAAMC,EAAO,OAAO,KAAKF,CAAC,EAC1B,OACEE,EAAK,SAAW,OAAO,KAAKD,CAAC,CAAC,CAAC,QAC/BC,EAAK,MAAO,GAAM,OAAO,UAAU,eAAe,KAAKD,EAAGE,CAAC,GAAK,OAAO,GAAGH,EAAEG,GAAIF,EAAEE,EAAE,CAAC,CAEzF,CAEA,SAASC,GAAa,EAAa,EAAsB,CACvD,OAAOJ,EAAE,OAAO,EAAM,IAAMD,EAAYM,EAAMJ,EAAEK,EAAE,CAAC,CACrD,CAyBA,IAAaC,GAAU,CACrB,MACA,OACA,OAAO,SACP,OACA,QACA,QACA,aAAa,GACb,YACA,MACA,OACA,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,mBAAoBC,EACpB,eAAgBC,EAChB,GAAGC,KACc,CACjB,IAAMrB,EACJsB,GAAU,MAA+B,OAAOA,GAAU,WAAaA,IAAU,GAC7E,IAAA,GACAA,EACAnB,EAAYN,GAAcG,CAAS,EACnCuB,EAAWxB,GAAYC,EAAWG,EAAWF,CAAG,EAIhD,CAACuB,GAAQC,GAAanD,EAAM,SAAS,EAAK,EAC1C,CAACoD,EAAcC,GAAmBrD,EAAM,SAASiD,CAAQ,EAC1DX,GAAac,EAAcH,CAAQ,IACtCI,EAAgBJ,CAAQ,EACxBE,EAAU,EAAK,GAQjB,IAAMG,EAAYtD,EAAM,OAAwB,IAAI,EACpDe,EAAM,oBAAsB,CAC1B,IAAMwC,EAAMD,EAAU,SAAS,cAAc,KAAK,EAClD,GAAI,CAACC,GAAO,CAACA,EAAI,UAAYA,EAAI,eAAiB,EAAG,OACrD,IAAIC,EAAS,GACPC,EAAaF,EAAI,aAAa,KAAK,EACnCG,EAAgBH,EAAI,aAAa,QAAQ,EACzCI,MAAmB,CAGrBH,GACAD,EAAI,aACJA,EAAI,aAAa,KAAK,IAAME,GAC5BF,EAAI,aAAa,QAAQ,IAAMG,GAE/BP,EAAU,EAAI,CAElB,EAGA,OAFI,OAAOI,EAAI,QAAW,WAAYA,EAAI,OAAO,CAAC,CAAC,KAAK,IAAA,GAAWI,CAAU,EACxE,eAAeA,CAAU,MACjB,CACX,EAAS,EACX,CACF,EAAG,CAAC,CAAC,EACL,IAAMC,EAAgB3D,EAAAA,cAAc4D,EAAKP,CAAS,EAE5CQ,EAAkBpB,IAAc,IAAA,IAAaC,IAAmB,IAAA,GAKhEoB,EAAkBC,IAAS,IAAA,IAAaA,IAAS,gBAAkBA,IAAS,OAC5EC,EAAiB3C,EAAcD,CAAI,EACnC6C,EAAWC,GAAcL,GAAmBC,EAAkB,GAAME,GAAkB,GACtFG,MAAuCjB,EAAU,EAAI,EAKrDkB,EAASxC,GAAW,IACpByC,EAAYD,GAAmC,KAC/CE,EAAuBD,EAAYD,EAASH,EAM5CM,EAAgC,CACpC,mBAAoB5B,EACpB,mBAAoBC,EACpB,eAAgBC,CAClB,EACM2B,EACJ,CAACN,GACD,CAACL,GACD,CAACC,GACD,OAAOQ,GAAgB,UACvBA,EAAY,KAAK,IAAM,GACnBG,EAAqCD,EAAeD,EAAc,CAAC,EAErEG,EAA6B,KACjC,GAAI,CAACzB,GAAQ,CACX,GAAI,OAAOxB,GAAc,SACvB,GACE,EAAAV,EAAA,IAAA,CAAC,MAAD,CACE,IAAKU,EACL,IAAKwC,EACL,GAAIQ,EACJ,UAAWxD,EACX,QAASkD,CACV,CAAA,OAEE,GAAI1C,IAAc,IAAA,GAAW,CAKlC,IAAMkD,EAA2B,CAC/B,QAAS1E,EAAAA,qBACP2B,GAAW,QACXuC,CACF,CACF,EAEA,GADKE,IAAW,EAAU,IAAMJ,GAC5BO,EAAc,CAChB,IAAMI,EAAShD,IAAY,oBAC3B,EAAU,oBAAsB1B,GAAAA,QAC9ByC,EACA,OAAOiC,GAAW,SAAWA,EAAS,IAAA,EACxC,CACF,CACA,IAAMrD,EAAOxB,EAAM,eAAe0B,CAAS,EACvC1B,EAAM,aAAa0B,EAAgDkD,CAAS,EAC5E/C,EACE,CAAE,GAAIH,EAAsB,GAAGkD,CAAU,EACzClD,EACN,EAAYtB,EAAAA,WAAWoB,EAAqB,MAAON,EAAa,CAC9D,IAAKgD,EACL,GAAGQ,CACL,CAAC,CACH,MAAW/C,IACT,GACE,EAAAX,EAAA,IAAA,CAAC,MAAD,CACO,MACL,IAAKkD,EACL,GAAIQ,EACJ,UAAWxD,EACX,QAASkD,CACV,CAAA,EAGP,CACA,IAAMU,EAAoBH,IAAc,MAAQF,EAAe,CAAC,EAAID,EAK9DO,EACJJ,IAAc,MAAQK,GAAQ3E,EAAAA,mBAAmB2E,CAAI,EACjD5E,EAAAA,WAAW4E,EAAM,OAAQ,cAAe,CAAE,cAAe,EAAK,CAAC,EAC/D,KACAC,EAAWN,IAAc,MAAQI,IAAa,MAAQ1D,EAAOF,GAAYE,CAAI,EAAI,GAEnF6D,EACAC,EACAR,IAAc,KAEPI,IAAa,KAGbE,GACT,GAAU,EAAAjE,EAAA,IAAA,CAAC,OAAD,CAAM,cAAY,OAAQ,SAAAiE,CAAe,CAAA,EACnD,EAAa,uCAEb,GAAU,EAAAjE,EAAA,IAAA,CAACV,GAAAA,WAAD,CAAY,KAAK,KAAO,CAAA,EAClC,EAAa,mCAPb,EAAUyE,EACV,EAAa,kCAHb,EAAUJ,EAgBZ,IAAMS,GACJT,IAAc,MAAQZ,GAAmB,OAAOQ,GAAgB,SAC5DjD,EAAciD,CAAW,EACzB,IAAA,GACAc,GAAc,OAAOhB,GAAW,SAAW/C,EAAc+C,CAAM,EAAI,IAAA,GACnEiB,EACJ5C,IACCiC,IAAc,KACVV,GAAkBoB,GACnBtB,EACGqB,IAAanB,EACd,IAAA,IACJsB,EACJ,AAYEA,EAZEpB,EACU,CAAE,cAAe,GAAM,GAAGW,CAAkB,EAC/CQ,IAAU,IAAA,IAAa3C,IAAmB,IAAA,GACvC,CACV,KAAMqB,GAAQ,MACd,aAAcsB,EACd,kBAAmB3C,EACnB,GAAGmC,CACL,EACSH,IAAc,MAAQX,IAAS,IAAA,GAC5B,CAAE,OAAM,GAAGc,CAAkB,EAE7B,CAAE,cAAe,GAAM,GAAGA,CAAkB,EAK1D,IAAMU,EACJC,GAASpF,EAAAA,mBAAmBoF,CAAK,EAC7BrF,EAAAA,WAAWqF,EAAO,OAAQ,qCAAqC,EAC/D,KACAC,GAAWF,IAAc,KAEzBG,EAAkBpF,EAAAA,GACtB,0FACAU,EAAkB2E,GAClBT,CACF,EAUA,OARKO,IASH,EAAA1E,EAAA,KAAA,CAAC,OAAD,CAAW,MAAK,GAAI+B,EAAM,UAAWxC,EAAAA,GAAG,gCAAiCsF,CAAS,EAAlF,SAAA,EACE,EAAA7E,EAAA,IAAA,CAAC,OAAD,CAAM,IAAKsC,EAAW,GAAIiC,EAAW,UAAWI,EAC7C,SAAAT,CACG,CAAA,EACLM,CACG,KAZJ,EAAAxE,EAAA,IAAA,CAAC,OAAD,CAAM,IAAK4C,EAAe,GAAI2B,EAAW,GAAIxC,EAAM,UAAWxC,EAAAA,GAAGoF,EAAiBE,CAAS,EACxF,SAAAX,CACG,CAAA,CAYZ,EAEA,EAAO,YAAc"}
1
+ {"version":3,"file":"Avatar.cjs","names":["React","useMergedRefs","cn","avatarClassNames","composeEventHandlers","joinIds","renderSlot","slotRendersContent","PersonIcon","require_runtime","require_cn","require_slot","require_composeEventHandlers","require_classNames","require_useMergedRefs","require_aria","require_icons","react","react_jsx_runtime","avatarSizeClasses","IMAGE_CLASS","getInitials","parts","name","normaliseName","readSlotProps","slot","getImageKey","imageSlot","src","element","slotProps","isPlainObject","value","proto","sameKeyPart","a","b","keys","k","sameImageKey","part","i","Avatar","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaDescription","ariaDetails","rest","image","imageKey","failed","setFailed","prevImageKey","setPrevImageKey","visualRef","img","active","checkedSrc","checkedSrcSet","markFailed","rootVisualRef","ref","hasConsumerName","roleCarriesName","role","normalisedName","imageAlt","decorative","handleError","ownAlt","hasOwnAlt","renderedAlt","description","imageIsNamed","imageDescription","imageNode","overrides","ownIds","visualDescription","iconNode","icon","initials","content","colorClass","imageName","slotAltName","label","a11yProps","badgeNode","badge","hasBadge","visualClassName","size","className"],"sources":["../../../src/components/data-display/Avatar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { avatarClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { PersonIcon } from '../../lib/icons';\nimport type { Size, Slot } from '../../lib/types';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\n\n/** Properties for the Avatar component. */\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * URL of the avatar image. When it fails to load (also before hydration, for server-rendered\n * markup), the avatar falls back to its icon or initials; a new `src` is tried again.\n */\n src?: string;\n /**\n * Full name of the person. It names the avatar for assistive technology (the image `alt`; in\n * initials and icon mode, or with a consumer `role`, the avatar's `aria-label`, with\n * `role=\"img\"` unless `role` is given) and generates the initials shown when there is no image.\n */\n name?: string;\n /** Size of the avatar.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon shown instead of the initials when there is no image. Rendered in an `aria-hidden`\n * `<span>` (a slot object can override its attributes). A falsy value (`null`, `false`, `''`,\n * `0`, `NaN`, e.g. `icon={count && <Icon />}`) counts as no icon, as in 0.4, and so does an\n * array, `Set` or generator whose items render nothing. Without `icon` and without a usable\n * `name`, a generic person glyph is shown.\n */\n icon?: Slot<'span'>;\n /**\n * Custom image. Accepts a URL string (treated like `src`), an element (rendered as the image\n * itself, e.g. `<img>` or a framework image component) or an object of `<img>` attributes\n * (`{ src, alt, … }`). Takes precedence over `src`; its `alt` defaults to `name` (an `alt` that\n * is `undefined` counts as not given). When its alt names the avatar, the avatar's\n * `aria-describedby` ids are joined with the slot's own, while the slot's own `aria-description`\n * and `aria-details` win over the avatar's. When the image fails to load, an avatar without a\n * `name` keeps the name of the slot's own `alt`. After a load failure, a new image is tried\n * again: another `src` or `srcSet` of any type (an equal inline object is the same image), or\n * for an element slot another component type or `key`.\n */\n image?: Slot<'img'>;\n /**\n * Badge shown at the bottom end corner, e.g. `<PresenceBadge status=\"busy\" />`. With a badge\n * the avatar is wrapped in an outer `<span>` that receives `ref`, `className` and the other\n * props; `role`, `aria-label`, `aria-labelledby`, `aria-describedby`, `aria-description` and\n * `aria-details` stay on the avatar visual, so the badge keeps its own accessible name. A falsy\n * value (`null`, `false`, `''`, `0`, `NaN`, e.g. `badge={count && <CounterBadge count={count} />}`)\n * counts as no badge, as in 0.4, and so does an array, `Set` or generator whose items render\n * nothing: the avatar then renders without the wrapper.\n */\n badge?: Slot<'span'>;\n /**\n * Hides the avatar visual from assistive technology (`aria-hidden`, empty image `alt`, no\n * `role=\"img\"`). Use it when the name is already shown next to the avatar (Persona). A badge\n * stays exposed.\n * @default false\n */\n decorative?: boolean;\n /** Ref to the root `<span>`: the avatar itself, or the badge wrapper when `badge` is set. */\n ref?: React.Ref<HTMLSpanElement>;\n}\n\n/**\n * Width, height and text size classes of the avatar per `size`. Module-only (not in the barrel):\n * AvatarGroup sizes its overflow button with the same classes, so the two always match.\n */\nexport const avatarSizeClasses: Readonly<Record<Size, string>> = {\n 'extra-small': 'w-6 h-6 text-[10px]', // 24px\n small: 'w-8 h-8 text-xs', // 32px\n medium: 'w-10 h-10 text-sm', // 40px\n large: 'w-12 h-12 text-base', // 48px\n 'extra-large': 'w-14 h-14 text-lg', // 56px\n};\n\nconst IMAGE_CLASS = 'w-full h-full object-cover';\n\n/** First letter of the first and last word, upper-cased; `''` for a blank name. */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '';\n const first = Array.from(parts[0]!)[0] ?? '';\n const last = parts.length > 1 ? (Array.from(parts[parts.length - 1]!)[0] ?? '') : '';\n return (first + last).toUpperCase();\n}\n\n/** A name with its whitespace collapsed, or `undefined` when it is blank. */\nfunction normaliseName(name: string | undefined): string | undefined {\n return name?.trim().replace(/\\s+/g, ' ') || undefined;\n}\n\ntype ImageErrorHandler = React.ReactEventHandler<HTMLImageElement>;\n\n/** Description props that go to the element carrying the avatar's name (data-display#19). */\ntype DescriptionProps = Pick<\n React.HTMLAttributes<HTMLElement>,\n 'aria-describedby' | 'aria-description' | 'aria-details'\n>;\n\n/** Props the avatar sets on an element or object image slot, over the slot's own. */\ninterface SlotOverrides {\n onError: ImageErrorHandler;\n alt?: string;\n 'aria-describedby'?: string;\n}\n\n/** The props of an element or object image slot that the avatar reads. */\ninterface ImageSlotProps {\n src?: unknown;\n srcSet?: unknown;\n alt?: unknown;\n onError?: unknown;\n 'aria-describedby'?: unknown;\n}\n\n/** The props of an element or object image slot (to read its `src`, `alt` and handlers). */\nfunction readSlotProps(slot: unknown): ImageSlotProps | undefined {\n if (React.isValidElement(slot)) return slot.props as ImageSlotProps;\n if (typeof slot === 'object' && slot !== null && !(Symbol.iterator in slot)) {\n return slot as ImageSlotProps;\n }\n return undefined;\n}\n\n/**\n * What identifies the image, so a load failure is kept for it and a new image is tried again\n * (data-display#4): the `src` and `srcSet`, of any type (a framework image component may take a\n * static-import object), and for an element slot also its type and `key`.\n */\ntype ImageKey = readonly [type: unknown, key: unknown, src: unknown, srcSet: unknown];\n\nfunction getImageKey(\n imageSlot: unknown,\n slotProps: ImageSlotProps | undefined,\n src: string | undefined,\n): ImageKey {\n if (imageSlot === undefined) return [undefined, undefined, src || undefined, undefined];\n if (typeof imageSlot === 'string') return [undefined, undefined, imageSlot, undefined];\n const element = React.isValidElement(imageSlot) ? imageSlot : undefined;\n return [element?.type, element?.key, slotProps?.src, slotProps?.srcSet];\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/** Same value, or plain objects with the same entries (an inline `src={{ … }}` on each render). */\nfunction sameKeyPart(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const keys = Object.keys(a);\n return (\n keys.length === Object.keys(b).length &&\n keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && Object.is(a[k], b[k]))\n );\n}\n\nfunction sameImageKey(a: ImageKey, b: ImageKey): boolean {\n return a.every((part, i) => sameKeyPart(part, b[i]));\n}\n\n/**\n * A circular picture of a person: their image, an icon, or the initials of their `name`.\n *\n * - **Image**: `image` (URL string, element or `{ src, alt }` object) or `src`. If the image fails\n * to load, the avatar falls back to `icon`, the initials or a person glyph, with their\n * background; a new image is tried again. A server-rendered image that failed before hydration\n * is detected after mount (settled without a natural size, confirmed by `decode()`).\n * - **Accessible name**: an image uses `name` (whitespace collapsed) as its `alt`, or `''` when the\n * name is blank. Without an image (none given, or it failed to load) the avatar is `role=\"img\"`\n * with `aria-label={name}` (without a name: the image slot's own `alt`) and the initials/icon\n * are hidden; without either (and without `aria-label`/`aria-labelledby`) it is decorative\n * (`aria-hidden`). A consumer `aria-label`, `aria-labelledby` or `role` (other than\n * `presentation`/`none`) puts the name on the avatar visual, and an image inside it gets\n * `alt=\"\"`. `decorative` hides it in every mode. `aria-describedby`, `aria-description` and\n * `aria-details` go to the element that carries the name: the `<img>` when a non-blank `alt`\n * names it, otherwise the avatar visual (never an `alt=\"\"` image).\n * - **Badge**: `badge` renders at the bottom end corner (logical, RTL-safe) as a sibling of the\n * avatar visual, so a `PresenceBadge` keeps its own name. With a badge, `ref`, `className` and\n * the rest props go to the outer wrapper.\n *\n * @example\n * <Avatar name=\"Jane Doe\" src=\"/jane.jpg\" badge={<PresenceBadge status=\"available\" />} />\n */\nexport const Avatar = ({\n src,\n name,\n size = 'medium',\n icon,\n image,\n badge,\n decorative = false,\n className,\n ref,\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n ...rest\n}: AvatarProps) => {\n const imageSlot =\n image === null || image === undefined || typeof image === 'boolean' || image === ''\n ? undefined\n : image;\n const slotProps = readSlotProps(imageSlot);\n const imageKey = getImageKey(imageSlot, slotProps, src);\n\n // Load failure of the current image; a new image is tried again (C-HOOKS: adjust state during\n // render on prop change).\n const [failed, setFailed] = React.useState(false);\n const [prevImageKey, setPrevImageKey] = React.useState(imageKey);\n if (!sameImageKey(prevImageKey, imageKey)) {\n setPrevImageKey(imageKey);\n setFailed(false);\n }\n\n // An image that failed before hydration (a fast 404 of server-rendered markup) never reaches\n // `onError`: React attaches the listener while hydrating and does not replay the event. After\n // mount, a settled image without a natural size is broken, unless it is an SVG without one, so\n // `decode()` (which rejects for a broken image) confirms it where the browser supports it. Later\n // images, rendered by the client, report their errors through `onError`.\n const visualRef = React.useRef<HTMLSpanElement>(null);\n React.useLayoutEffect(() => {\n const img = visualRef.current?.querySelector('img');\n if (!img || !img.complete || img.naturalWidth !== 0) return;\n let active = true;\n const checkedSrc = img.getAttribute('src');\n const checkedSrcSet = img.getAttribute('srcset');\n const markFailed = () => {\n // Deferred (C-HOOKS); skipped if the image was replaced or got another source meanwhile.\n if (\n active &&\n img.isConnected &&\n img.getAttribute('src') === checkedSrc &&\n img.getAttribute('srcset') === checkedSrcSet\n ) {\n setFailed(true);\n }\n };\n if (typeof img.decode === 'function') img.decode().then(undefined, markFailed);\n else queueMicrotask(markFailed);\n return () => {\n active = false;\n };\n }, []);\n const rootVisualRef = useMergedRefs(ref, visualRef);\n\n const hasConsumerName = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n // A consumer role goes to the visual span together with the name (data-display#19), so the\n // image inside it is presentational (`alt=\"\"`), as with a consumer `aria-label`: the children\n // of `role=\"img\"` are not exposed. A presentational role (`presentation`, `none`) cannot carry\n // a name, so the image keeps it.\n const roleCarriesName = role !== undefined && role !== 'presentation' && role !== 'none';\n const normalisedName = normaliseName(name);\n const imageAlt = decorative || hasConsumerName || roleCarriesName ? '' : (normalisedName ?? '');\n const handleError: ImageErrorHandler = () => setFailed(true);\n\n // The alt text the image renders with: an element or object slot's own `alt` wins over ours. An\n // `alt` that is `undefined` (an optional `alt: user.photoAlt`, a wrapper forwarding `alt={alt}`)\n // or `null` is not given, so ours applies (the slot's own value would otherwise override it).\n const ownAlt = slotProps?.alt;\n const hasOwnAlt = ownAlt !== undefined && ownAlt !== null;\n const renderedAlt: unknown = hasOwnAlt ? ownAlt : imageAlt;\n\n // The description goes to the element that carries the name: the image itself when a non-blank\n // `alt` names it (the visual span then has no role, or a presentational one), otherwise the\n // visual span. An image with an empty `alt` is presentational, and a description on it would\n // conflict with that role.\n const description: DescriptionProps = {\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n };\n const imageIsNamed =\n !decorative &&\n !hasConsumerName &&\n !roleCarriesName &&\n typeof renderedAlt === 'string' &&\n renderedAlt.trim() !== '';\n const imageDescription: DescriptionProps = imageIsNamed ? description : {};\n\n let imageNode: React.ReactNode = null;\n if (!failed) {\n if (typeof imageSlot === 'string') {\n imageNode = (\n <img\n src={imageSlot}\n alt={imageAlt}\n {...imageDescription}\n className={cn(avatarClassNames.image, IMAGE_CLASS)}\n onError={handleError}\n />\n );\n } else if (imageSlot !== undefined) {\n // The slot's own props win over renderSlot's defaults, so the composed `onError`, the\n // default `alt` (when the slot gives none) and the joined `aria-describedby` (the avatar's\n // ids, then the slot's) are set on the slot itself. A slot's own `aria-description` and\n // `aria-details` win over the avatar's.\n const overrides: SlotOverrides = {\n onError: composeEventHandlers(\n slotProps?.onError as ImageErrorHandler | undefined,\n handleError,\n ),\n };\n if (!hasOwnAlt) overrides.alt = imageAlt;\n if (imageIsNamed) {\n const ownIds = slotProps?.['aria-describedby'];\n overrides['aria-describedby'] = joinIds(\n ariaDescribedBy,\n typeof ownIds === 'string' ? ownIds : undefined,\n );\n }\n const slot = React.isValidElement(imageSlot)\n ? React.cloneElement(imageSlot as React.ReactElement<SlotOverrides>, overrides)\n : slotProps\n ? { ...(imageSlot as object), ...overrides }\n : imageSlot;\n imageNode = renderSlot(slot as Slot<'img'>, 'img', cn(avatarClassNames.image, IMAGE_CLASS), {\n alt: imageAlt,\n ...imageDescription,\n });\n } else if (src) {\n imageNode = (\n <img\n src={src}\n alt={imageAlt}\n {...imageDescription}\n className={cn(avatarClassNames.image, IMAGE_CLASS)}\n onError={handleError}\n />\n );\n }\n }\n const visualDescription = imageNode !== null && imageIsNamed ? {} : description;\n\n // A falsy icon (`icon={count && <Icon />}` with count 0) is no icon, as in 0.4, and so is a\n // collection whose items render nothing (`icon={items.map(…)}` mapping to nothing). The check\n // does not consume a generator: renderSlot still renders its items.\n const iconNode =\n imageNode === null && icon && slotRendersContent(icon)\n ? renderSlot(icon, 'span', cn(avatarClassNames.icon, 'inline-flex'), { 'aria-hidden': true })\n : null;\n const initials = imageNode === null && iconNode === null && name ? getInitials(name) : '';\n\n let content: React.ReactNode;\n let colorClass: string | undefined;\n if (imageNode !== null) {\n content = imageNode;\n } else if (iconNode !== null) {\n content = iconNode;\n colorClass = 'bg-muted text-muted-foreground';\n } else if (initials) {\n content = (\n <span aria-hidden=\"true\" className={avatarClassNames.initials}>\n {initials}\n </span>\n );\n colorClass = 'bg-primary text-primary-foreground';\n } else {\n content = <PersonIcon size=\"60%\" className={avatarClassNames.icon} />;\n colorClass = 'bg-muted text-muted-foreground';\n }\n\n // Accessible name of the avatar visual (data-display#19, #27). With a consumer role and an\n // image it is the name the image would carry: an element or object slot's own alt, else `name`.\n // Without an image (none given, or it failed to load) it is `name`, else the slot's own alt: an\n // avatar named only by its image alt keeps that name when the image fails.\n const imageName =\n imageNode !== null && roleCarriesName && typeof renderedAlt === 'string'\n ? normaliseName(renderedAlt)\n : undefined;\n const slotAltName = typeof ownAlt === 'string' ? normaliseName(ownAlt) : undefined;\n const label =\n ariaLabel ??\n (imageNode === null\n ? (normalisedName ?? slotAltName)\n : roleCarriesName\n ? (imageName ?? normalisedName)\n : undefined);\n let a11yProps: React.HTMLAttributes<HTMLSpanElement>;\n if (decorative) {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n } else if (label !== undefined || ariaLabelledBy !== undefined) {\n a11yProps = {\n role: role ?? 'img',\n 'aria-label': label,\n 'aria-labelledby': ariaLabelledBy,\n ...visualDescription,\n };\n } else if (imageNode !== null || role !== undefined) {\n a11yProps = { role, ...visualDescription };\n } else {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n }\n\n // A falsy or empty badge (`badge={count && <CounterBadge … />}` with count 0) is no badge, as in\n // 0.4 and like `icon`: no stray \"0\" in the corner, and no wrapper taking the root props.\n const badgeNode =\n badge && slotRendersContent(badge)\n ? renderSlot(badge, 'span', cn(avatarClassNames.badge, 'absolute bottom-0 end-0 inline-flex'))\n : null;\n const hasBadge = badgeNode !== null;\n\n const visualClassName = cn(\n avatarClassNames.visual,\n 'inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold',\n avatarSizeClasses[size],\n colorClass,\n );\n\n if (!hasBadge) {\n return (\n <span\n ref={rootVisualRef}\n {...a11yProps}\n {...rest}\n className={cn(avatarClassNames.root, visualClassName, className)}\n >\n {content}\n </span>\n );\n }\n\n return (\n <span\n ref={ref}\n {...rest}\n className={cn(avatarClassNames.root, 'relative inline-flex shrink-0', className)}\n >\n <span ref={visualRef} {...a11yProps} className={visualClassName}>\n {content}\n </span>\n {badgeNode}\n </span>\n );\n};\n\nAvatar.displayName = 'Avatar';\n"],"mappings":"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"}
@@ -2,31 +2,32 @@
2
2
  import { cn as e } from "../../lib/cn.mjs";
3
3
  import { renderSlot as t, slotRendersContent as n } from "../../lib/slot.mjs";
4
4
  import { composeEventHandlers as r } from "../../lib/composeEventHandlers.mjs";
5
- import { useMergedRefs as i } from "../../hooks/useMergedRefs.mjs";
6
- import { joinIds as ee } from "../../lib/aria.mjs";
7
- import { PersonIcon as te } from "../../lib/icons.mjs";
8
- import * as a from "react";
9
- import { jsx as o, jsxs as ne } from "react/jsx-runtime";
5
+ import { avatarClassNames as i } from "../../lib/classNames.mjs";
6
+ import { useMergedRefs as a } from "../../hooks/useMergedRefs.mjs";
7
+ import { joinIds as o } from "../../lib/aria.mjs";
8
+ import { PersonIcon as ee } from "../../lib/icons.mjs";
9
+ import * as s from "react";
10
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
10
11
  //#region src/components/data-display/Avatar.tsx
11
- var s = {
12
+ var u = {
12
13
  "extra-small": "w-6 h-6 text-[10px]",
13
14
  small: "w-8 h-8 text-xs",
14
15
  medium: "w-10 h-10 text-sm",
15
16
  large: "w-12 h-12 text-base",
16
17
  "extra-large": "w-14 h-14 text-lg"
17
- }, c = "w-full h-full object-cover";
18
- function re(e) {
18
+ }, d = "w-full h-full object-cover";
19
+ function te(e) {
19
20
  let t = e.trim().split(/\s+/).filter(Boolean);
20
21
  return t.length === 0 ? "" : ((Array.from(t[0])[0] ?? "") + (t.length > 1 ? Array.from(t[t.length - 1])[0] ?? "" : "")).toUpperCase();
21
22
  }
22
- function l(e) {
23
+ function f(e) {
23
24
  return e?.trim().replace(/\s+/g, " ") || void 0;
24
25
  }
25
- function u(e) {
26
- if (a.isValidElement(e)) return e.props;
26
+ function ne(e) {
27
+ if (s.isValidElement(e)) return e.props;
27
28
  if (typeof e == "object" && e && !(Symbol.iterator in e)) return e;
28
29
  }
29
- function ie(e, t, n) {
30
+ function re(e, t, n) {
30
31
  if (e === void 0) return [
31
32
  void 0,
32
33
  void 0,
@@ -39,7 +40,7 @@ function ie(e, t, n) {
39
40
  e,
40
41
  void 0
41
42
  ];
42
- let r = a.isValidElement(e) ? e : void 0;
43
+ let r = s.isValidElement(e) ? e : void 0;
43
44
  return [
44
45
  r?.type,
45
46
  r?.key,
@@ -47,111 +48,115 @@ function ie(e, t, n) {
47
48
  t?.srcSet
48
49
  ];
49
50
  }
50
- function d(e) {
51
+ function p(e) {
51
52
  if (typeof e != "object" || !e) return !1;
52
53
  let t = Object.getPrototypeOf(e);
53
54
  return t === Object.prototype || t === null;
54
55
  }
55
- function f(e, t) {
56
+ function m(e, t) {
56
57
  if (Object.is(e, t)) return !0;
57
- if (!d(e) || !d(t)) return !1;
58
+ if (!p(e) || !p(t)) return !1;
58
59
  let n = Object.keys(e);
59
60
  return n.length === Object.keys(t).length && n.every((n) => Object.prototype.hasOwnProperty.call(t, n) && Object.is(e[n], t[n]));
60
61
  }
61
- function ae(e, t) {
62
- return e.every((e, n) => f(e, t[n]));
62
+ function ie(e, t) {
63
+ return e.every((e, n) => m(e, t[n]));
63
64
  }
64
- var p = ({ src: d, name: f, size: p = "medium", icon: m, image: h, badge: g, decorative: _ = !1, className: v, ref: y, role: b, "aria-label": x, "aria-labelledby": S, "aria-describedby": C, "aria-description": oe, "aria-details": se, ...w }) => {
65
- let T = h == null || typeof h == "boolean" || h === "" ? void 0 : h, E = u(T), D = ie(T, E, d), [ce, O] = a.useState(!1), [k, A] = a.useState(D);
66
- ae(k, D) || (A(D), O(!1));
67
- let j = a.useRef(null);
68
- a.useLayoutEffect(() => {
65
+ var h = ({ src: p, name: m, size: h = "medium", icon: g, image: _, badge: v, decorative: y = !1, className: b, ref: x, role: S, "aria-label": C, "aria-labelledby": w, "aria-describedby": T, "aria-description": ae, "aria-details": oe, ...E }) => {
66
+ let D = _ == null || typeof _ == "boolean" || _ === "" ? void 0 : _, O = ne(D), k = re(D, O, p), [se, A] = s.useState(!1), [ce, le] = s.useState(k);
67
+ ie(ce, k) || (le(k), A(!1));
68
+ let j = s.useRef(null);
69
+ s.useLayoutEffect(() => {
69
70
  let e = j.current?.querySelector("img");
70
71
  if (!e || !e.complete || e.naturalWidth !== 0) return;
71
72
  let t = !0, n = e.getAttribute("src"), r = e.getAttribute("srcset"), i = () => {
72
- t && e.isConnected && e.getAttribute("src") === n && e.getAttribute("srcset") === r && O(!0);
73
+ t && e.isConnected && e.getAttribute("src") === n && e.getAttribute("srcset") === r && A(!0);
73
74
  };
74
75
  return typeof e.decode == "function" ? e.decode().then(void 0, i) : queueMicrotask(i), () => {
75
76
  t = !1;
76
77
  };
77
78
  }, []);
78
- let M = i(y, j), N = x !== void 0 || S !== void 0, P = b !== void 0 && b !== "presentation" && b !== "none", F = l(f), I = _ || N || P ? "" : F ?? "", L = () => O(!0), R = E?.alt, z = R != null, B = z ? R : I, V = {
79
- "aria-describedby": C,
80
- "aria-description": oe,
81
- "aria-details": se
82
- }, H = !_ && !N && !P && typeof B == "string" && B.trim() !== "", U = H ? V : {}, W = null;
83
- if (!ce) {
84
- if (typeof T == "string") W = /* @__PURE__ */ o("img", {
85
- src: T,
79
+ let M = a(x, j), N = C !== void 0 || w !== void 0, P = S !== void 0 && S !== "presentation" && S !== "none", F = f(m), I = y || N || P ? "" : F ?? "", L = () => A(!0), R = O?.alt, z = R != null, B = z ? R : I, V = {
80
+ "aria-describedby": T,
81
+ "aria-description": ae,
82
+ "aria-details": oe
83
+ }, H = !y && !N && !P && typeof B == "string" && B.trim() !== "", U = H ? V : {}, W = null;
84
+ if (!se) {
85
+ if (typeof D == "string") W = /* @__PURE__ */ c("img", {
86
+ src: D,
86
87
  alt: I,
87
88
  ...U,
88
- className: c,
89
+ className: e(i.image, d),
89
90
  onError: L
90
91
  });
91
- else if (T !== void 0) {
92
- let e = { onError: r(E?.onError, L) };
93
- if (z || (e.alt = I), H) {
94
- let t = E?.["aria-describedby"];
95
- e["aria-describedby"] = ee(C, typeof t == "string" ? t : void 0);
92
+ else if (D !== void 0) {
93
+ let n = { onError: r(O?.onError, L) };
94
+ if (z || (n.alt = I), H) {
95
+ let e = O?.["aria-describedby"];
96
+ n["aria-describedby"] = o(T, typeof e == "string" ? e : void 0);
96
97
  }
97
- let n = a.isValidElement(T) ? a.cloneElement(T, e) : E ? {
98
- ...T,
99
- ...e
100
- } : T;
101
- W = t(n, "img", c, {
98
+ let a = s.isValidElement(D) ? s.cloneElement(D, n) : O ? {
99
+ ...D,
100
+ ...n
101
+ } : D;
102
+ W = t(a, "img", e(i.image, d), {
102
103
  alt: I,
103
104
  ...U
104
105
  });
105
- } else d && (W = /* @__PURE__ */ o("img", {
106
- src: d,
106
+ } else p && (W = /* @__PURE__ */ c("img", {
107
+ src: p,
107
108
  alt: I,
108
109
  ...U,
109
- className: c,
110
+ className: e(i.image, d),
110
111
  onError: L
111
112
  }));
112
113
  }
113
- let G = W !== null && H ? {} : V, K = W === null && m && n(m) ? t(m, "span", "inline-flex", { "aria-hidden": !0 }) : null, q = W === null && K === null && f ? re(f) : "", J, Y;
114
- W === null ? K === null ? q ? (J = /* @__PURE__ */ o("span", {
114
+ let G = W !== null && H ? {} : V, K = W === null && g && n(g) ? t(g, "span", e(i.icon, "inline-flex"), { "aria-hidden": !0 }) : null, q = W === null && K === null && m ? te(m) : "", J, Y;
115
+ W === null ? K === null ? q ? (J = /* @__PURE__ */ c("span", {
115
116
  "aria-hidden": "true",
117
+ className: i.initials,
116
118
  children: q
117
- }), Y = "bg-primary text-primary-foreground") : (J = /* @__PURE__ */ o(te, { size: "60%" }), Y = "bg-muted text-muted-foreground") : (J = K, Y = "bg-muted text-muted-foreground") : J = W;
118
- let le = W !== null && P && typeof B == "string" ? l(B) : void 0, ue = typeof R == "string" ? l(R) : void 0, X = x ?? (W === null ? F ?? ue : P ? le ?? F : void 0), Z;
119
- Z = _ ? {
119
+ }), Y = "bg-primary text-primary-foreground") : (J = /* @__PURE__ */ c(ee, {
120
+ size: "60%",
121
+ className: i.icon
122
+ }), Y = "bg-muted text-muted-foreground") : (J = K, Y = "bg-muted text-muted-foreground") : J = W;
123
+ let ue = W !== null && P && typeof B == "string" ? f(B) : void 0, de = typeof R == "string" ? f(R) : void 0, X = C ?? (W === null ? F ?? de : P ? ue ?? F : void 0), Z;
124
+ Z = y ? {
120
125
  "aria-hidden": !0,
121
126
  ...G
122
- } : X !== void 0 || S !== void 0 ? {
123
- role: b ?? "img",
127
+ } : X !== void 0 || w !== void 0 ? {
128
+ role: S ?? "img",
124
129
  "aria-label": X,
125
- "aria-labelledby": S,
130
+ "aria-labelledby": w,
126
131
  ...G
127
- } : W !== null || b !== void 0 ? {
128
- role: b,
132
+ } : W !== null || S !== void 0 ? {
133
+ role: S,
129
134
  ...G
130
135
  } : {
131
136
  "aria-hidden": !0,
132
137
  ...G
133
138
  };
134
- let Q = g && n(g) ? t(g, "span", "absolute bottom-0 end-0 inline-flex") : null, de = Q !== null, $ = e("inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold", s[p], Y);
135
- return de ? /* @__PURE__ */ ne("span", {
136
- ref: y,
137
- ...w,
138
- className: e("relative inline-flex shrink-0", v),
139
- children: [/* @__PURE__ */ o("span", {
139
+ let Q = v && n(v) ? t(v, "span", e(i.badge, "absolute bottom-0 end-0 inline-flex")) : null, fe = Q !== null, $ = e(i.visual, "inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold", u[h], Y);
140
+ return fe ? /* @__PURE__ */ l("span", {
141
+ ref: x,
142
+ ...E,
143
+ className: e(i.root, "relative inline-flex shrink-0", b),
144
+ children: [/* @__PURE__ */ c("span", {
140
145
  ref: j,
141
146
  ...Z,
142
147
  className: $,
143
148
  children: J
144
149
  }), Q]
145
- }) : /* @__PURE__ */ o("span", {
150
+ }) : /* @__PURE__ */ c("span", {
146
151
  ref: M,
147
152
  ...Z,
148
- ...w,
149
- className: e($, v),
153
+ ...E,
154
+ className: e(i.root, $, b),
150
155
  children: J
151
156
  });
152
157
  };
153
- p.displayName = "Avatar";
158
+ h.displayName = "Avatar";
154
159
  //#endregion
155
- export { p as Avatar, s as avatarSizeClasses };
160
+ export { h as Avatar, u as avatarSizeClasses };
156
161
 
157
162
  //# sourceMappingURL=Avatar.mjs.map