@mattermost/compass-ui 0.1.0-alpha.27 → 0.1.0-alpha.29

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 (373) hide show
  1. package/dist/compass-ui.css +20 -2
  2. package/dist/components/admin-console-footer/AdminConsoleFooter.css +1 -1
  3. package/dist/components/admin-console-footer/AdminConsoleFooter.module.scss.cjs +1 -1
  4. package/dist/components/admin-console-footer/AdminConsoleFooter.module.scss.js +7 -7
  5. package/dist/components/admin-console-header/AdminConsoleHeader.css +1 -1
  6. package/dist/components/admin-console-header/AdminConsoleHeader.module.scss.cjs +1 -1
  7. package/dist/components/admin-console-header/AdminConsoleHeader.module.scss.js +8 -8
  8. package/dist/components/admin-panel/AdminPanel.css +1 -1
  9. package/dist/components/admin-panel/AdminPanel.module.scss.cjs +1 -1
  10. package/dist/components/admin-panel/AdminPanel.module.scss.js +5 -5
  11. package/dist/components/admin-panel-footer/AdminPanelFooter.css +1 -1
  12. package/dist/components/admin-panel-footer/AdminPanelFooter.module.scss.cjs +1 -1
  13. package/dist/components/admin-panel-footer/AdminPanelFooter.module.scss.js +5 -5
  14. package/dist/components/admin-panel-header/AdminPanelHeader.cjs +1 -1
  15. package/dist/components/admin-panel-header/AdminPanelHeader.cjs.map +1 -1
  16. package/dist/components/admin-panel-header/AdminPanelHeader.css +1 -1
  17. package/dist/components/admin-panel-header/AdminPanelHeader.d.ts +6 -0
  18. package/dist/components/admin-panel-header/AdminPanelHeader.d.ts.map +1 -1
  19. package/dist/components/admin-panel-header/AdminPanelHeader.js +145 -109
  20. package/dist/components/admin-panel-header/AdminPanelHeader.js.map +1 -1
  21. package/dist/components/admin-panel-header/AdminPanelHeader.module.scss.cjs +1 -1
  22. package/dist/components/admin-panel-header/AdminPanelHeader.module.scss.js +11 -10
  23. package/dist/components/admin-panel-header/AdminPanelHeader.module.scss.js.map +1 -1
  24. package/dist/components/attachment-card/AttachmentCard.css +1 -1
  25. package/dist/components/attachment-card/AttachmentCard.module.scss.cjs +1 -1
  26. package/dist/components/attachment-card/AttachmentCard.module.scss.js +22 -19
  27. package/dist/components/attachment-card/AttachmentCard.module.scss.js.map +1 -1
  28. package/dist/components/button/Button.css +1 -1
  29. package/dist/components/button/Button.module.scss.cjs +1 -1
  30. package/dist/components/button/Button.module.scss.js +20 -19
  31. package/dist/components/button/Button.module.scss.js.map +1 -1
  32. package/dist/components/card-button/CardButton.css +1 -1
  33. package/dist/components/card-button/CardButton.module.scss.cjs +1 -1
  34. package/dist/components/card-button/CardButton.module.scss.js +7 -7
  35. package/dist/components/card-button/CardButtonGroup.css +1 -1
  36. package/dist/components/card-button/CardButtonGroup.module.scss.cjs +1 -1
  37. package/dist/components/card-button/CardButtonGroup.module.scss.js +1 -1
  38. package/dist/components/channel-info-msg-header/ChannelInfoMsgHeader.css +1 -1
  39. package/dist/components/channel-info-msg-header/ChannelInfoMsgHeader.module.scss.cjs +1 -1
  40. package/dist/components/channel-info-msg-header/ChannelInfoMsgHeader.module.scss.js +8 -8
  41. package/dist/components/channel-sidebar-item/ChannelSidebarItem.cjs +1 -1
  42. package/dist/components/channel-sidebar-item/ChannelSidebarItem.cjs.map +1 -1
  43. package/dist/components/channel-sidebar-item/ChannelSidebarItem.css +1 -1
  44. package/dist/components/channel-sidebar-item/ChannelSidebarItem.d.ts +66 -7
  45. package/dist/components/channel-sidebar-item/ChannelSidebarItem.d.ts.map +1 -1
  46. package/dist/components/channel-sidebar-item/ChannelSidebarItem.js +163 -93
  47. package/dist/components/channel-sidebar-item/ChannelSidebarItem.js.map +1 -1
  48. package/dist/components/channel-sidebar-item/ChannelSidebarItem.module.scss.cjs +1 -1
  49. package/dist/components/channel-sidebar-item/ChannelSidebarItem.module.scss.js +35 -22
  50. package/dist/components/channel-sidebar-item/ChannelSidebarItem.module.scss.js.map +1 -1
  51. package/dist/components/checkbox/Checkbox.css +1 -1
  52. package/dist/components/checkbox/Checkbox.module.scss.cjs +1 -1
  53. package/dist/components/checkbox/Checkbox.module.scss.js +7 -7
  54. package/dist/components/chip/Chip.cjs +1 -1
  55. package/dist/components/chip/Chip.cjs.map +1 -1
  56. package/dist/components/chip/Chip.css +1 -1
  57. package/dist/components/chip/Chip.d.ts.map +1 -1
  58. package/dist/components/chip/Chip.js +8 -8
  59. package/dist/components/chip/Chip.js.map +1 -1
  60. package/dist/components/chip/Chip.module.scss.cjs +1 -1
  61. package/dist/components/chip/Chip.module.scss.js +13 -10
  62. package/dist/components/chip/Chip.module.scss.js.map +1 -1
  63. package/dist/components/chip/ChipGroup.cjs +1 -1
  64. package/dist/components/chip/ChipGroup.cjs.map +1 -1
  65. package/dist/components/chip/ChipGroup.css +1 -1
  66. package/dist/components/chip/ChipGroup.d.ts +1 -1
  67. package/dist/components/chip/ChipGroup.d.ts.map +1 -1
  68. package/dist/components/chip/ChipGroup.js +30 -30
  69. package/dist/components/chip/ChipGroup.js.map +1 -1
  70. package/dist/components/chip/ChipGroup.module.scss.cjs +1 -1
  71. package/dist/components/chip/ChipGroup.module.scss.js +1 -1
  72. package/dist/components/combobox/Combobox.cjs +1 -1
  73. package/dist/components/combobox/Combobox.cjs.map +1 -1
  74. package/dist/components/combobox/Combobox.css +1 -1
  75. package/dist/components/combobox/Combobox.d.ts +10 -0
  76. package/dist/components/combobox/Combobox.d.ts.map +1 -1
  77. package/dist/components/combobox/Combobox.js +269 -252
  78. package/dist/components/combobox/Combobox.js.map +1 -1
  79. package/dist/components/combobox/Combobox.module.scss.cjs +1 -1
  80. package/dist/components/combobox/Combobox.module.scss.js +34 -31
  81. package/dist/components/combobox/Combobox.module.scss.js.map +1 -1
  82. package/dist/components/date-range-picker/DateRangePicker.cjs +1 -1
  83. package/dist/components/date-range-picker/DateRangePicker.cjs.map +1 -1
  84. package/dist/components/date-range-picker/DateRangePicker.css +1 -1
  85. package/dist/components/date-range-picker/DateRangePicker.d.ts +14 -1
  86. package/dist/components/date-range-picker/DateRangePicker.d.ts.map +1 -1
  87. package/dist/components/date-range-picker/DateRangePicker.js +217 -195
  88. package/dist/components/date-range-picker/DateRangePicker.js.map +1 -1
  89. package/dist/components/date-range-picker/DateRangePicker.module.scss.cjs +1 -1
  90. package/dist/components/date-range-picker/DateRangePicker.module.scss.js +29 -26
  91. package/dist/components/date-range-picker/DateRangePicker.module.scss.js.map +1 -1
  92. package/dist/components/divider/Divider.css +1 -1
  93. package/dist/components/divider/Divider.module.scss.cjs +1 -1
  94. package/dist/components/divider/Divider.module.scss.js +1 -1
  95. package/dist/components/dropdown/Dropdown.css +1 -1
  96. package/dist/components/dropdown/Dropdown.module.scss.cjs +1 -1
  97. package/dist/components/dropdown/Dropdown.module.scss.js +23 -22
  98. package/dist/components/dropdown/Dropdown.module.scss.js.map +1 -1
  99. package/dist/components/emoji/Emoji.css +1 -1
  100. package/dist/components/emoji/Emoji.module.scss.cjs +1 -1
  101. package/dist/components/emoji/Emoji.module.scss.js +12 -12
  102. package/dist/components/emoji-button/EmojiButton.css +1 -1
  103. package/dist/components/emoji-button/EmojiButton.module.scss.cjs +1 -1
  104. package/dist/components/emoji-button/EmojiButton.module.scss.js +12 -9
  105. package/dist/components/emoji-button/EmojiButton.module.scss.js.map +1 -1
  106. package/dist/components/emoji-popover/EmojiPopover.css +1 -1
  107. package/dist/components/emoji-popover/EmojiPopover.module.scss.cjs +1 -1
  108. package/dist/components/emoji-popover/EmojiPopover.module.scss.js +21 -21
  109. package/dist/components/empty-state/EmptyState.css +1 -1
  110. package/dist/components/empty-state/EmptyState.module.scss.cjs +1 -1
  111. package/dist/components/empty-state/EmptyState.module.scss.js +7 -7
  112. package/dist/components/feature-discovery-panel/FeatureDiscoveryPanel.css +1 -1
  113. package/dist/components/feature-discovery-panel/FeatureDiscoveryPanel.module.scss.cjs +1 -1
  114. package/dist/components/feature-discovery-panel/FeatureDiscoveryPanel.module.scss.js +9 -9
  115. package/dist/components/field/FieldClearButton.css +1 -1
  116. package/dist/components/field/FieldClearButton.module.scss.cjs +1 -1
  117. package/dist/components/field/FieldClearButton.module.scss.js +3 -3
  118. package/dist/components/field-message/FieldMessage.css +1 -1
  119. package/dist/components/field-message/FieldMessage.module.scss.cjs +1 -1
  120. package/dist/components/field-message/FieldMessage.module.scss.js +7 -7
  121. package/dist/components/global-banner/GlobalBanner.css +1 -1
  122. package/dist/components/global-banner/GlobalBanner.module.scss.cjs +1 -1
  123. package/dist/components/global-banner/GlobalBanner.module.scss.js +10 -10
  124. package/dist/components/icon/Icon.css +1 -1
  125. package/dist/components/icon/Icon.module.scss.cjs +1 -1
  126. package/dist/components/icon/Icon.module.scss.js +13 -13
  127. package/dist/components/icon-button/IconButton.css +1 -1
  128. package/dist/components/icon-button/IconButton.module.scss.cjs +1 -1
  129. package/dist/components/icon-button/IconButton.module.scss.js +19 -16
  130. package/dist/components/icon-button/IconButton.module.scss.js.map +1 -1
  131. package/dist/components/illustration/Illustration.css +1 -1
  132. package/dist/components/illustration/Illustration.module.scss.cjs +1 -1
  133. package/dist/components/illustration/Illustration.module.scss.js +1 -1
  134. package/dist/components/image-preview/ImagePreview.css +1 -1
  135. package/dist/components/image-preview/ImagePreview.module.scss.cjs +1 -1
  136. package/dist/components/image-preview/ImagePreview.module.scss.js +15 -15
  137. package/dist/components/link-preview/LinkPreview.css +1 -1
  138. package/dist/components/link-preview/LinkPreview.module.scss.cjs +1 -1
  139. package/dist/components/link-preview/LinkPreview.module.scss.js +14 -14
  140. package/dist/components/mention-badge/MentionBadge.css +1 -1
  141. package/dist/components/mention-badge/MentionBadge.module.scss.cjs +1 -1
  142. package/dist/components/mention-badge/MentionBadge.module.scss.js +9 -9
  143. package/dist/components/menu-group-heading/MenuGroupHeading.css +1 -1
  144. package/dist/components/menu-group-heading/MenuGroupHeading.module.scss.cjs +1 -1
  145. package/dist/components/menu-group-heading/MenuGroupHeading.module.scss.js +2 -2
  146. package/dist/components/menu-item/MenuItem.css +1 -1
  147. package/dist/components/menu-item/MenuItem.module.scss.cjs +1 -1
  148. package/dist/components/menu-item/MenuItem.module.scss.js +18 -18
  149. package/dist/components/message-actions/MessageActions.css +1 -1
  150. package/dist/components/message-actions/MessageActions.module.scss.cjs +1 -1
  151. package/dist/components/message-actions/MessageActions.module.scss.js +2 -2
  152. package/dist/components/message-header/MessageHeader.css +1 -1
  153. package/dist/components/message-header/MessageHeader.module.scss.cjs +1 -1
  154. package/dist/components/message-header/MessageHeader.module.scss.js +3 -3
  155. package/dist/components/message-separator/MessageSeparator.css +1 -1
  156. package/dist/components/message-separator/MessageSeparator.module.scss.cjs +1 -1
  157. package/dist/components/message-separator/MessageSeparator.module.scss.js +11 -11
  158. package/dist/components/modal/Modal.cjs +1 -1
  159. package/dist/components/modal/Modal.cjs.map +1 -1
  160. package/dist/components/modal/Modal.css +1 -1
  161. package/dist/components/modal/Modal.d.ts +11 -1
  162. package/dist/components/modal/Modal.d.ts.map +1 -1
  163. package/dist/components/modal/Modal.js +38 -36
  164. package/dist/components/modal/Modal.js.map +1 -1
  165. package/dist/components/modal/Modal.module.scss.cjs +1 -1
  166. package/dist/components/modal/Modal.module.scss.js +11 -11
  167. package/dist/components/modal/ModalOverlay.cjs.map +1 -1
  168. package/dist/components/modal/ModalOverlay.css +1 -1
  169. package/dist/components/modal/ModalOverlay.d.ts +1 -1
  170. package/dist/components/modal/ModalOverlay.js.map +1 -1
  171. package/dist/components/modal/ModalOverlay.module.scss.cjs +1 -1
  172. package/dist/components/modal/ModalOverlay.module.scss.js +5 -5
  173. package/dist/components/modal-footer/ModalFooter.css +1 -1
  174. package/dist/components/modal-footer/ModalFooter.module.scss.cjs +1 -1
  175. package/dist/components/modal-footer/ModalFooter.module.scss.js +11 -11
  176. package/dist/components/modal-header/ModalHeader.cjs +1 -1
  177. package/dist/components/modal-header/ModalHeader.cjs.map +1 -1
  178. package/dist/components/modal-header/ModalHeader.css +1 -1
  179. package/dist/components/modal-header/ModalHeader.d.ts +13 -3
  180. package/dist/components/modal-header/ModalHeader.d.ts.map +1 -1
  181. package/dist/components/modal-header/ModalHeader.js +61 -55
  182. package/dist/components/modal-header/ModalHeader.js.map +1 -1
  183. package/dist/components/modal-header/ModalHeader.module.scss.cjs +1 -1
  184. package/dist/components/modal-header/ModalHeader.module.scss.js +18 -16
  185. package/dist/components/modal-header/ModalHeader.module.scss.js.map +1 -1
  186. package/dist/components/more-unreads-banner/MoreUnreadsBanner.css +1 -1
  187. package/dist/components/more-unreads-banner/MoreUnreadsBanner.module.scss.cjs +1 -1
  188. package/dist/components/more-unreads-banner/MoreUnreadsBanner.module.scss.js +8 -5
  189. package/dist/components/more-unreads-banner/MoreUnreadsBanner.module.scss.js.map +1 -1
  190. package/dist/components/new-message-banner/NewMessageBanner.css +1 -1
  191. package/dist/components/new-message-banner/NewMessageBanner.module.scss.cjs +1 -1
  192. package/dist/components/new-message-banner/NewMessageBanner.module.scss.js +9 -9
  193. package/dist/components/pagination-dots/PaginationDots.css +1 -1
  194. package/dist/components/pagination-dots/PaginationDots.module.scss.cjs +1 -1
  195. package/dist/components/pagination-dots/PaginationDots.module.scss.js +10 -10
  196. package/dist/components/password-input/PasswordInput.css +1 -1
  197. package/dist/components/password-input/PasswordInput.module.scss.cjs +1 -1
  198. package/dist/components/password-input/PasswordInput.module.scss.js +15 -14
  199. package/dist/components/password-input/PasswordInput.module.scss.js.map +1 -1
  200. package/dist/components/permalink-preview/PermalinkPreview.css +1 -1
  201. package/dist/components/permalink-preview/PermalinkPreview.module.scss.cjs +1 -1
  202. package/dist/components/permalink-preview/PermalinkPreview.module.scss.js +13 -13
  203. package/dist/components/pinned-saved-indicators/PinnedSavedIndicators.css +1 -1
  204. package/dist/components/pinned-saved-indicators/PinnedSavedIndicators.module.scss.cjs +1 -1
  205. package/dist/components/pinned-saved-indicators/PinnedSavedIndicators.module.scss.js +7 -7
  206. package/dist/components/popover-menu/PopoverMenu.css +1 -1
  207. package/dist/components/popover-menu/PopoverMenu.module.scss.cjs +1 -1
  208. package/dist/components/popover-menu/PopoverMenu.module.scss.js +13 -13
  209. package/dist/components/popover-notice/PopoverNotice.css +1 -1
  210. package/dist/components/popover-notice/PopoverNotice.module.scss.cjs +1 -1
  211. package/dist/components/popover-notice/PopoverNotice.module.scss.js +14 -14
  212. package/dist/components/profile-popover/ProfilePopover.css +1 -1
  213. package/dist/components/profile-popover/ProfilePopover.module.scss.cjs +1 -1
  214. package/dist/components/profile-popover/ProfilePopover.module.scss.js +33 -33
  215. package/dist/components/progress-bar/ProgressBar.css +1 -1
  216. package/dist/components/progress-bar/ProgressBar.module.scss.cjs +1 -1
  217. package/dist/components/progress-bar/ProgressBar.module.scss.js +9 -9
  218. package/dist/components/radio/Radio.css +1 -1
  219. package/dist/components/radio/Radio.module.scss.cjs +1 -1
  220. package/dist/components/radio/Radio.module.scss.js +12 -12
  221. package/dist/components/reaction-button/ReactionButton.css +1 -1
  222. package/dist/components/reaction-button/ReactionButton.module.scss.cjs +1 -1
  223. package/dist/components/reaction-button/ReactionButton.module.scss.js +8 -8
  224. package/dist/components/reactions-row/ReactionsRow.css +1 -1
  225. package/dist/components/reactions-row/ReactionsRow.module.scss.cjs +1 -1
  226. package/dist/components/reactions-row/ReactionsRow.module.scss.js +8 -8
  227. package/dist/components/right-sidebar-header/RightSidebarHeader.cjs +1 -1
  228. package/dist/components/right-sidebar-header/RightSidebarHeader.cjs.map +1 -1
  229. package/dist/components/right-sidebar-header/RightSidebarHeader.css +1 -1
  230. package/dist/components/right-sidebar-header/RightSidebarHeader.d.ts.map +1 -1
  231. package/dist/components/right-sidebar-header/RightSidebarHeader.js +39 -36
  232. package/dist/components/right-sidebar-header/RightSidebarHeader.js.map +1 -1
  233. package/dist/components/right-sidebar-header/RightSidebarHeader.module.scss.cjs +1 -1
  234. package/dist/components/right-sidebar-header/RightSidebarHeader.module.scss.js +12 -13
  235. package/dist/components/right-sidebar-header/RightSidebarHeader.module.scss.js.map +1 -1
  236. package/dist/components/scrollbar/Scrollbar.css +1 -1
  237. package/dist/components/scrollbar/Scrollbar.module.scss.cjs +1 -1
  238. package/dist/components/scrollbar/Scrollbar.module.scss.js +5 -5
  239. package/dist/components/search-input/SearchInput.css +1 -1
  240. package/dist/components/search-input/SearchInput.module.scss.cjs +1 -1
  241. package/dist/components/search-input/SearchInput.module.scss.js +15 -15
  242. package/dist/components/search-tip-banner/SearchTipBanner.css +1 -1
  243. package/dist/components/search-tip-banner/SearchTipBanner.module.scss.cjs +1 -1
  244. package/dist/components/search-tip-banner/SearchTipBanner.module.scss.js +3 -3
  245. package/dist/components/section-notice/SectionNotice.css +1 -1
  246. package/dist/components/section-notice/SectionNotice.module.scss.cjs +1 -1
  247. package/dist/components/section-notice/SectionNotice.module.scss.js +12 -12
  248. package/dist/components/segmented-control/SegmentedControl.cjs +2 -0
  249. package/dist/components/segmented-control/SegmentedControl.cjs.map +1 -0
  250. package/dist/components/segmented-control/SegmentedControl.css +1 -0
  251. package/dist/components/segmented-control/SegmentedControl.d.ts +71 -0
  252. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -0
  253. package/dist/components/segmented-control/SegmentedControl.js +173 -0
  254. package/dist/components/segmented-control/SegmentedControl.js.map +1 -0
  255. package/dist/components/segmented-control/SegmentedControl.module.scss.cjs +2 -0
  256. package/dist/components/segmented-control/SegmentedControl.module.scss.cjs.map +1 -0
  257. package/dist/components/segmented-control/SegmentedControl.module.scss.js +20 -0
  258. package/dist/components/segmented-control/SegmentedControl.module.scss.js.map +1 -0
  259. package/dist/components/segmented-control/index.cjs +2 -0
  260. package/dist/components/segmented-control/index.cjs.map +1 -0
  261. package/dist/components/segmented-control/index.d.ts +3 -0
  262. package/dist/components/segmented-control/index.d.ts.map +1 -0
  263. package/dist/components/segmented-control/index.js +5 -0
  264. package/dist/components/segmented-control/index.js.map +1 -0
  265. package/dist/components/select/Select.cjs +1 -1
  266. package/dist/components/select/Select.cjs.map +1 -1
  267. package/dist/components/select/Select.css +1 -1
  268. package/dist/components/select/Select.d.ts +14 -0
  269. package/dist/components/select/Select.d.ts.map +1 -1
  270. package/dist/components/select/Select.js +151 -130
  271. package/dist/components/select/Select.js.map +1 -1
  272. package/dist/components/select/Select.module.scss.cjs +1 -1
  273. package/dist/components/select/Select.module.scss.js +28 -26
  274. package/dist/components/select/Select.module.scss.js.map +1 -1
  275. package/dist/components/shortcut-tag/ShortcutTag.css +1 -1
  276. package/dist/components/shortcut-tag/ShortcutTag.module.scss.cjs +1 -1
  277. package/dist/components/shortcut-tag/ShortcutTag.module.scss.js +7 -7
  278. package/dist/components/spinner/Spinner.css +1 -1
  279. package/dist/components/spinner/Spinner.module.scss.cjs +1 -1
  280. package/dist/components/spinner/Spinner.module.scss.js +2 -2
  281. package/dist/components/status-badge/StatusBadge.cjs +1 -1
  282. package/dist/components/status-badge/StatusBadge.cjs.map +1 -1
  283. package/dist/components/status-badge/StatusBadge.css +1 -1
  284. package/dist/components/status-badge/StatusBadge.d.ts +3 -1
  285. package/dist/components/status-badge/StatusBadge.d.ts.map +1 -1
  286. package/dist/components/status-badge/StatusBadge.js +16 -15
  287. package/dist/components/status-badge/StatusBadge.js.map +1 -1
  288. package/dist/components/status-badge/StatusBadge.module.scss.cjs +1 -1
  289. package/dist/components/status-badge/StatusBadge.module.scss.js +11 -11
  290. package/dist/components/switch/Switch.css +1 -1
  291. package/dist/components/switch/Switch.module.scss.cjs +1 -1
  292. package/dist/components/switch/Switch.module.scss.js +8 -8
  293. package/dist/components/tabs/Tabs.css +1 -1
  294. package/dist/components/tabs/Tabs.module.scss.cjs +1 -1
  295. package/dist/components/tabs/Tabs.module.scss.js +16 -13
  296. package/dist/components/tabs/Tabs.module.scss.js.map +1 -1
  297. package/dist/components/tag/Tag.css +1 -1
  298. package/dist/components/tag/Tag.module.scss.cjs +1 -1
  299. package/dist/components/tag/Tag.module.scss.js +11 -11
  300. package/dist/components/team-avatar/TeamAvatar.css +1 -1
  301. package/dist/components/team-avatar/TeamAvatar.module.scss.cjs +1 -1
  302. package/dist/components/team-avatar/TeamAvatar.module.scss.js +17 -17
  303. package/dist/components/text-area/TextArea.css +1 -1
  304. package/dist/components/text-area/TextArea.module.scss.cjs +1 -1
  305. package/dist/components/text-area/TextArea.module.scss.js +12 -12
  306. package/dist/components/text-input/TextInput.css +1 -1
  307. package/dist/components/text-input/TextInput.module.scss.cjs +1 -1
  308. package/dist/components/text-input/TextInput.module.scss.js +19 -19
  309. package/dist/components/thread-footer/ThreadFooter.cjs +1 -1
  310. package/dist/components/thread-footer/ThreadFooter.cjs.map +1 -1
  311. package/dist/components/thread-footer/ThreadFooter.css +1 -1
  312. package/dist/components/thread-footer/ThreadFooter.d.ts.map +1 -1
  313. package/dist/components/thread-footer/ThreadFooter.js +14 -14
  314. package/dist/components/thread-footer/ThreadFooter.js.map +1 -1
  315. package/dist/components/thread-footer/ThreadFooter.module.scss.cjs +1 -1
  316. package/dist/components/thread-footer/ThreadFooter.module.scss.js +19 -20
  317. package/dist/components/thread-footer/ThreadFooter.module.scss.js.map +1 -1
  318. package/dist/components/thread-list-item/ThreadListItem.css +1 -1
  319. package/dist/components/thread-list-item/ThreadListItem.module.scss.cjs +1 -1
  320. package/dist/components/thread-list-item/ThreadListItem.module.scss.js +26 -26
  321. package/dist/components/tile-button/TileButton.css +1 -1
  322. package/dist/components/tile-button/TileButton.module.scss.cjs +1 -1
  323. package/dist/components/tile-button/TileButton.module.scss.js +6 -6
  324. package/dist/components/toast/Toast.css +1 -1
  325. package/dist/components/toast/Toast.module.scss.cjs +1 -1
  326. package/dist/components/toast/Toast.module.scss.js +11 -11
  327. package/dist/components/tooltip/Tooltip.cjs +1 -1
  328. package/dist/components/tooltip/Tooltip.cjs.map +1 -1
  329. package/dist/components/tooltip/Tooltip.css +1 -1
  330. package/dist/components/tooltip/Tooltip.d.ts +10 -1
  331. package/dist/components/tooltip/Tooltip.d.ts.map +1 -1
  332. package/dist/components/tooltip/Tooltip.js +29 -17
  333. package/dist/components/tooltip/Tooltip.js.map +1 -1
  334. package/dist/components/tooltip/Tooltip.module.scss.cjs +1 -1
  335. package/dist/components/tooltip/Tooltip.module.scss.js +7 -6
  336. package/dist/components/tooltip/Tooltip.module.scss.js.map +1 -1
  337. package/dist/components/tooltip/index.d.ts +1 -1
  338. package/dist/components/tooltip/index.d.ts.map +1 -1
  339. package/dist/components/tour-point/TourPoint.css +1 -1
  340. package/dist/components/tour-point/TourPoint.module.scss.cjs +1 -1
  341. package/dist/components/tour-point/TourPoint.module.scss.js +28 -28
  342. package/dist/components/unread-badge/UnreadBadge.css +1 -1
  343. package/dist/components/unread-badge/UnreadBadge.module.scss.cjs +1 -1
  344. package/dist/components/unread-badge/UnreadBadge.module.scss.js +5 -5
  345. package/dist/components/user-avatar/UserAvatar.cjs +1 -1
  346. package/dist/components/user-avatar/UserAvatar.cjs.map +1 -1
  347. package/dist/components/user-avatar/UserAvatar.css +1 -1
  348. package/dist/components/user-avatar/UserAvatar.d.ts +18 -8
  349. package/dist/components/user-avatar/UserAvatar.d.ts.map +1 -1
  350. package/dist/components/user-avatar/UserAvatar.js +84 -52
  351. package/dist/components/user-avatar/UserAvatar.js.map +1 -1
  352. package/dist/components/user-avatar/UserAvatar.module.scss.cjs +1 -1
  353. package/dist/components/user-avatar/UserAvatar.module.scss.js +33 -26
  354. package/dist/components/user-avatar/UserAvatar.module.scss.js.map +1 -1
  355. package/dist/components/user-avatar-group/UserAvatarGroup.css +1 -1
  356. package/dist/components/user-avatar-group/UserAvatarGroup.module.scss.cjs +1 -1
  357. package/dist/components/user-avatar-group/UserAvatarGroup.module.scss.js +14 -14
  358. package/dist/hooks/use-anchored-popup-portal.cjs.map +1 -1
  359. package/dist/hooks/use-anchored-popup-portal.d.ts +1 -1
  360. package/dist/hooks/use-anchored-popup-portal.d.ts.map +1 -1
  361. package/dist/hooks/use-anchored-popup-portal.js.map +1 -1
  362. package/dist/index.cjs +1 -1
  363. package/dist/index.d.ts +1 -0
  364. package/dist/index.d.ts.map +1 -1
  365. package/dist/index.js +57 -55
  366. package/dist/index.js.map +1 -1
  367. package/dist/utils/anchoredPopupPlacement.cjs +1 -1
  368. package/dist/utils/anchoredPopupPlacement.cjs.map +1 -1
  369. package/dist/utils/anchoredPopupPlacement.d.ts +8 -4
  370. package/dist/utils/anchoredPopupPlacement.d.ts.map +1 -1
  371. package/dist/utils/anchoredPopupPlacement.js +18 -18
  372. package/dist/utils/anchoredPopupPlacement.js.map +1 -1
  373. package/package.json +4 -1
@@ -1,16 +1,18 @@
1
1
  import { ImgHTMLAttributes } from 'react';
2
+ import { StatusBadgeStatus } from '../status-badge/StatusBadge';
2
3
  /** Figma User Avatar sizes. */
3
- export type UserAvatarSize = '12' | '16' | '20' | '24' | '28' | '32' | '40' | '48' | '56' | '64' | '72' | '80' | '96' | '120';
4
+ export type UserAvatarSize = '12' | '16' | '20' | '24' | '28' | '32' | '36' | '40' | '48' | '50' | '56' | '64' | '72' | '80' | '96' | '120' | '128';
4
5
  /** Figma User Avatar Fallback colour variants. */
5
- export type UserAvatarFallbackColor = 'red' | 'purple' | 'neutral' | 'blue' | 'cyan' | 'yellow' | 'green' | 'orange';
6
+ export type UserAvatarFallbackColor = 'red' | 'purple' | 'neutral' | 'charcoal' | 'indigo' | 'teal' | 'blue' | 'cyan' | 'yellow' | 'green' | 'orange';
6
7
  export interface UserAvatarProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src' | 'alt' | 'width' | 'height'> {
7
8
  /** Alt text for the avatar image. */
8
9
  alt: string;
9
10
  /** Optional CSS class name. */
10
11
  className?: string;
11
12
  /**
12
- * Image URL for the avatar. When omitted, the avatar renders as Fallback
13
- * (initials on a deterministic colour background).
13
+ * Image URL for the avatar. When omitted, or when the image fails to load,
14
+ * the avatar renders as Fallback (initials on a deterministic colour
15
+ * background). A failed image sets `data-image-failed="true"` on the root.
14
16
  */
15
17
  src?: string;
16
18
  /**
@@ -22,13 +24,21 @@ export interface UserAvatarProps extends Omit<ImgHTMLAttributes<HTMLImageElement
22
24
  fallbackColor?: UserAvatarFallbackColor;
23
25
  /** Size variant. Figma: Size. Default: 48. */
24
26
  size?: UserAvatarSize;
25
- /** When true, shows online status badge (green dot with check). Figma: Status = On. */
26
- status?: boolean;
27
+ /**
28
+ * Status badge shown on the avatar: `online`, `away`, `do-not-disturb` or `offline`.
29
+ * Omit (or `false`) to hide it. `true` is kept for backwards compatibility and
30
+ * means `online`. The badge size follows the avatar `size`.
31
+ */
32
+ status?: boolean | StatusBadgeStatus;
33
+ /** Accessible name for the status badge. Defaults to the status value; pass a translated string. */
34
+ statusLabel?: string;
27
35
  }
28
36
  /**
29
37
  * User Avatars represent a person — usually their uploaded photo, with initials on a colour
30
38
  * background as a fallback. Their circular shape distinguishes them from rounded-square Team
31
- * Avatars at a glance.
39
+ * Avatars at a glance. `ref` points at the root element, which is present for both the image and
40
+ * the fallback, so it works as a tooltip or popover anchor.
32
41
  */
33
- export default function UserAvatar({ alt, className, src, name, fallbackColor, size, status, ...imgProps }: UserAvatarProps): import("react/jsx-runtime").JSX.Element;
42
+ declare const UserAvatar: import('react').ForwardRefExoticComponent<UserAvatarProps & import('react').RefAttributes<HTMLDivElement>>;
43
+ export default UserAvatar;
34
44
  //# sourceMappingURL=UserAvatar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserAvatar.d.ts","sourceRoot":"","sources":["../../../src/components/user-avatar/UserAvatar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAM/C,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,CAAC;AAEV,kDAAkD;AAClD,MAAM,MAAM,uBAAuB,GAC/B,KAAK,GACL,QAAQ,GACR,SAAS,GACT,MAAM,GACN,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,iBAAiB,CAAC,gBAAgB,CAAC,EACnC,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CACnC;IACC,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA8CD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,GAAG,EACH,SAAc,EACd,GAAG,EACH,IAAI,EACJ,aAAa,EACb,IAAW,EACX,MAAc,EACd,GAAG,QAAQ,EACZ,EAAE,eAAe,2CA2CjB"}
1
+ {"version":3,"file":"UserAvatar.d.ts","sourceRoot":"","sources":["../../../src/components/user-avatar/UserAvatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,sCAAsC,CAAC;AAI9C,+BAA+B;AAC/B,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,KAAK,CAAC;AAEV,kDAAkD;AAClD,MAAM,MAAM,uBAAuB,GAC/B,KAAK,GACL,QAAQ,GACR,SAAS,GACT,UAAU,GACV,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,iBAAiB,CAAC,gBAAgB,CAAC,EACnC,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CACnC;IACC,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACrC,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAqDD;;;;;GAKG;AACH,QAAA,MAAM,UAAU,4GAiFf,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,8 +1,9 @@
1
- import { jsxs as x, jsx as o } from "react/jsx-runtime";
2
- import C from "../status-badge/StatusBadge.js";
3
- import { toKebab as m } from "../../utils/string.js";
4
- import e from "./UserAvatar.module.scss.js";
5
- const c = [
1
+ import { jsxs as j, jsx as o } from "react/jsx-runtime";
2
+ import { forwardRef as w, useState as L } from "react";
3
+ import R from "../status-badge/StatusBadge.js";
4
+ import { toKebab as f } from "../../utils/string.js";
5
+ import t from "./UserAvatar.module.scss.js";
6
+ const g = [
6
7
  "red",
7
8
  "purple",
8
9
  "neutral",
@@ -10,71 +11,102 @@ const c = [
10
11
  "cyan",
11
12
  "yellow",
12
13
  "green",
13
- "orange"
14
- ], v = {
14
+ "orange",
15
+ "charcoal",
16
+ "indigo",
17
+ "teal"
18
+ ], U = {
15
19
  12: "xx-small",
16
20
  16: "xx-small",
17
21
  20: "x-small",
18
22
  24: "x-small",
19
23
  28: "x-small",
20
24
  32: "small",
25
+ 36: "small",
21
26
  40: "small",
22
27
  48: "small",
28
+ 50: "small",
23
29
  56: "medium",
24
30
  64: "medium",
25
31
  72: "medium",
26
32
  80: "medium",
27
33
  96: "large",
28
- 120: "large"
34
+ 120: "large",
35
+ 128: "large"
29
36
  };
30
- function A(l) {
31
- let s = 0;
32
- for (let a = 0; a < l.length; a++)
33
- s = s * 31 + l.charCodeAt(a) | 0;
34
- return c[Math.abs(s) % c.length];
37
+ function O(s) {
38
+ let a = 0;
39
+ for (let e = 0; e < s.length; e++)
40
+ a = a * 31 + s.charCodeAt(e) | 0;
41
+ return g[Math.abs(a) % g.length];
35
42
  }
36
- function N(l) {
37
- var r;
38
- const s = l.trim();
39
- if (!s) return "";
40
- const a = s.split(/\s+/)[0];
41
- return a[0].toUpperCase() + (((r = a[1]) == null ? void 0 : r.toLowerCase()) ?? "");
43
+ function z(s) {
44
+ var l;
45
+ const a = s.trim();
46
+ if (!a) return "";
47
+ const e = a.split(/\s+/)[0];
48
+ return e[0].toUpperCase() + (((l = e[1]) == null ? void 0 : l.toLowerCase()) ?? "");
42
49
  }
43
- function L({
44
- alt: l,
45
- className: s = "",
46
- src: a,
47
- name: r,
48
- fallbackColor: u,
49
- size: t = "48",
50
- status: f = !1,
51
- ...d
52
- }) {
53
- const h = e[`user-avatar--size-${m(t)}`], p = [e["user-avatar"], h, s].filter(Boolean).join(" "), n = !a, i = r ?? l, _ = n ? N(i) : "", b = u ?? A(i), g = n ? e[`user-avatar__fallback--${m(b)}`] : "";
54
- return /* @__PURE__ */ x("div", { className: p, "data-size": t, children: [
55
- n ? /* @__PURE__ */ o(
56
- "span",
50
+ const G = w(
51
+ function({
52
+ alt: a,
53
+ className: e = "",
54
+ src: l,
55
+ name: b,
56
+ fallbackColor: _,
57
+ size: r = "48",
58
+ status: n,
59
+ statusLabel: h,
60
+ onError: i,
61
+ ...p
62
+ }, v) {
63
+ const [x, C] = L(), A = t[`user-avatar--size-${f(r)}`], N = [t["user-avatar"], A, e].filter(Boolean).join(" "), c = !!l && l === x, m = !l || c, u = b ?? a, S = m ? z(u) : "", k = _ ?? O(u), y = m ? t[`user-avatar__fallback--${f(k)}`] : "", d = n === !0 ? "online" : n || void 0, B = U[r];
64
+ return /* @__PURE__ */ j(
65
+ "div",
57
66
  {
58
- className: [e["user-avatar__fallback"], g].filter(Boolean).join(" "),
59
- role: "img",
60
- "aria-label": l,
61
- children: _
67
+ ref: v,
68
+ className: N,
69
+ "data-size": r,
70
+ "data-image-failed": c ? "true" : void 0,
71
+ children: [
72
+ m ? /* @__PURE__ */ o(
73
+ "span",
74
+ {
75
+ className: [t["user-avatar__fallback"], y].filter(Boolean).join(" "),
76
+ role: "img",
77
+ "aria-label": a,
78
+ children: S
79
+ }
80
+ ) : /* @__PURE__ */ o(
81
+ "img",
82
+ {
83
+ loading: "lazy",
84
+ ...p,
85
+ onError: (F) => {
86
+ i == null || i(F), C(l);
87
+ },
88
+ alt: a,
89
+ className: t["user-avatar__image"],
90
+ src: l,
91
+ width: Number(r),
92
+ height: Number(r)
93
+ }
94
+ ),
95
+ d && /* @__PURE__ */ o("span", { className: t["user-avatar__status"], children: /* @__PURE__ */ o(
96
+ R,
97
+ {
98
+ status: d,
99
+ size: B,
100
+ label: h,
101
+ className: t["user-avatar__badge"]
102
+ }
103
+ ) })
104
+ ]
62
105
  }
63
- ) : /* @__PURE__ */ o(
64
- "img",
65
- {
66
- ...d,
67
- alt: l,
68
- className: e["user-avatar__image"],
69
- src: a,
70
- width: Number(t),
71
- height: Number(t)
72
- }
73
- ),
74
- f && /* @__PURE__ */ o("span", { className: e["user-avatar__status"], children: /* @__PURE__ */ o(C, { status: "online", size: v[t] }) })
75
- ] });
76
- }
106
+ );
107
+ }
108
+ );
77
109
  export {
78
- L as default
110
+ G as default
79
111
  };
80
112
  //# sourceMappingURL=UserAvatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserAvatar.js","sources":["../../../src/components/user-avatar/UserAvatar.tsx"],"sourcesContent":["import type { ImgHTMLAttributes } from 'react';\nimport StatusBadge from '@/components/status-badge/StatusBadge';\nimport type { StatusBadgeSize } from '@/components/status-badge/StatusBadge';\nimport { toKebab } from '@/utils/string';\nimport styles from './UserAvatar.module.scss';\n\n/** Figma User Avatar sizes. */\nexport type UserAvatarSize =\n | '12'\n | '16'\n | '20'\n | '24'\n | '28'\n | '32'\n | '40'\n | '48'\n | '56'\n | '64'\n | '72'\n | '80'\n | '96'\n | '120';\n\n/** Figma User Avatar Fallback colour variants. */\nexport type UserAvatarFallbackColor =\n | 'red'\n | 'purple'\n | 'neutral'\n | 'blue'\n | 'cyan'\n | 'yellow'\n | 'green'\n | 'orange';\n\nexport interface UserAvatarProps extends Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n 'src' | 'alt' | 'width' | 'height'\n> {\n /** Alt text for the avatar image. */\n alt: string;\n /** Optional CSS class name. */\n className?: string;\n /**\n * Image URL for the avatar. When omitted, the avatar renders as Fallback\n * (initials on a deterministic colour background).\n */\n src?: string;\n /**\n * Display name used to derive initials and the fallback colour. Defaults\n * to `alt` when not provided.\n */\n name?: string;\n /** Force a specific fallback colour. Hashed from `name`/`alt` if omitted. */\n fallbackColor?: UserAvatarFallbackColor;\n /** Size variant. Figma: Size. Default: 48. */\n size?: UserAvatarSize;\n /** When true, shows online status badge (green dot with check). Figma: Status = On. */\n status?: boolean;\n}\n\nconst FALLBACK_COLORS: readonly UserAvatarFallbackColor[] = [\n 'red',\n 'purple',\n 'neutral',\n 'blue',\n 'cyan',\n 'yellow',\n 'green',\n 'orange',\n];\n\n/** Map UserAvatar size to StatusBadge size (Figma scale). */\nconst USER_AVATAR_TO_BADGE_SIZE: Record<UserAvatarSize, StatusBadgeSize> = {\n '12': 'xx-small',\n '16': 'xx-small',\n '20': 'x-small',\n '24': 'x-small',\n '28': 'x-small',\n '32': 'small',\n '40': 'small',\n '48': 'small',\n '56': 'medium',\n '64': 'medium',\n '72': 'medium',\n '80': 'medium',\n '96': 'large',\n '120': 'large',\n};\n\nfunction hashFallbackColor(s: string): UserAvatarFallbackColor {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = (h * 31 + s.charCodeAt(i)) | 0;\n }\n return FALLBACK_COLORS[Math.abs(h) % FALLBACK_COLORS.length];\n}\n\nfunction getInitials(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) return '';\n const firstName = trimmed.split(/\\s+/)[0]!;\n return firstName[0]!.toUpperCase() + (firstName[1]?.toLowerCase() ?? '');\n}\n\n/**\n * User Avatars represent a person — usually their uploaded photo, with initials on a colour\n * background as a fallback. Their circular shape distinguishes them from rounded-square Team\n * Avatars at a glance.\n */\nexport default function UserAvatar({\n alt,\n className = '',\n src,\n name,\n fallbackColor,\n size = '48',\n status = false,\n ...imgProps\n}: UserAvatarProps) {\n const sizeClass = styles[`user-avatar--size-${toKebab(size)}`];\n const rootClass = [styles['user-avatar'], sizeClass, className]\n .filter(Boolean)\n .join(' ');\n\n const isFallback = !src;\n const displayName = name ?? alt;\n const initials = isFallback ? getInitials(displayName) : '';\n const color = fallbackColor ?? hashFallbackColor(displayName);\n const fallbackColorClass = isFallback\n ? styles[`user-avatar__fallback--${toKebab(color)}`]\n : '';\n\n return (\n <div className={rootClass} data-size={size}>\n {isFallback ? (\n <span\n className={[styles['user-avatar__fallback'], fallbackColorClass]\n .filter(Boolean)\n .join(' ')}\n role=\"img\"\n aria-label={alt}\n >\n {initials}\n </span>\n ) : (\n <img\n {...imgProps}\n alt={alt}\n className={styles['user-avatar__image']}\n src={src}\n width={Number(size)}\n height={Number(size)}\n />\n )}\n {status && (\n <span className={styles['user-avatar__status']}>\n <StatusBadge status=\"online\" size={USER_AVATAR_TO_BADGE_SIZE[size]} />\n </span>\n )}\n </div>\n );\n}\n"],"names":["FALLBACK_COLORS","USER_AVATAR_TO_BADGE_SIZE","hashFallbackColor","s","h","i","getInitials","name","trimmed","firstName","_a","UserAvatar","alt","className","src","fallbackColor","size","status","imgProps","sizeClass","styles","toKebab","rootClass","isFallback","displayName","initials","color","fallbackColorClass","jsxs","jsx","StatusBadge"],"mappings":";;;;AA4DA,MAAMA,IAAsD;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGMC,IAAqE;AAAA,EACzE,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,KAAO;AACT;AAEA,SAASC,EAAkBC,GAAoC;AAC7D,MAAIC,IAAI;AACR,WAASC,IAAI,GAAGA,IAAIF,EAAE,QAAQE;AAC5B,IAAAD,IAAKA,IAAI,KAAKD,EAAE,WAAWE,CAAC,IAAK;AAEnC,SAAOL,EAAgB,KAAK,IAAII,CAAC,IAAIJ,EAAgB,MAAM;AAC7D;AAEA,SAASM,EAAYC,GAAsB;;AACzC,QAAMC,IAAUD,EAAK,KAAA;AACrB,MAAI,CAACC,EAAS,QAAO;AACrB,QAAMC,IAAYD,EAAQ,MAAM,KAAK,EAAE,CAAC;AACxC,SAAOC,EAAU,CAAC,EAAG,YAAA,OAAiBC,IAAAD,EAAU,CAAC,MAAX,gBAAAC,EAAc,kBAAiB;AACvE;AAOA,SAAwBC,EAAW;AAAA,EACjC,KAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,KAAAC;AAAA,EACA,MAAAP;AAAA,EACA,eAAAQ;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,QAAAC,IAAS;AAAA,EACT,GAAGC;AACL,GAAoB;AAClB,QAAMC,IAAYC,EAAO,qBAAqBC,EAAQL,CAAI,CAAC,EAAE,GACvDM,IAAY,CAACF,EAAO,aAAa,GAAGD,GAAWN,CAAS,EAC3D,OAAO,OAAO,EACd,KAAK,GAAG,GAELU,IAAa,CAACT,GACdU,IAAcjB,KAAQK,GACtBa,IAAWF,IAAajB,EAAYkB,CAAW,IAAI,IACnDE,IAAQX,KAAiBb,EAAkBsB,CAAW,GACtDG,IAAqBJ,IACvBH,EAAO,0BAA0BC,EAAQK,CAAK,CAAC,EAAE,IACjD;AAEJ,SACE,gBAAAE,EAAC,OAAA,EAAI,WAAWN,GAAW,aAAWN,GACnC,UAAA;AAAA,IAAAO,IACC,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,CAACT,EAAO,uBAAuB,GAAGO,CAAkB,EAC5D,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,QACX,MAAK;AAAA,QACL,cAAYf;AAAA,QAEX,UAAAa;AAAA,MAAA;AAAA,IAAA,IAGH,gBAAAI;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAGX;AAAA,QACJ,KAAAN;AAAA,QACA,WAAWQ,EAAO,oBAAoB;AAAA,QACtC,KAAAN;AAAA,QACA,OAAO,OAAOE,CAAI;AAAA,QAClB,QAAQ,OAAOA,CAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAGtBC,KACC,gBAAAY,EAAC,QAAA,EAAK,WAAWT,EAAO,qBAAqB,GAC3C,UAAA,gBAAAS,EAACC,GAAA,EAAY,QAAO,UAAS,MAAM7B,EAA0Be,CAAI,GAAG,EAAA,CACtE;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"UserAvatar.js","sources":["../../../src/components/user-avatar/UserAvatar.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react';\nimport type { ImgHTMLAttributes } from 'react';\nimport StatusBadge from '@/components/status-badge/StatusBadge';\nimport type {\n StatusBadgeSize,\n StatusBadgeStatus,\n} from '@/components/status-badge/StatusBadge';\nimport { toKebab } from '@/utils/string';\nimport styles from './UserAvatar.module.scss';\n\n/** Figma User Avatar sizes. */\nexport type UserAvatarSize =\n | '12'\n | '16'\n | '20'\n | '24'\n | '28'\n | '32'\n | '36'\n | '40'\n | '48'\n | '50'\n | '56'\n | '64'\n | '72'\n | '80'\n | '96'\n | '120'\n | '128';\n\n/** Figma User Avatar Fallback colour variants. */\nexport type UserAvatarFallbackColor =\n | 'red'\n | 'purple'\n | 'neutral'\n | 'charcoal'\n | 'indigo'\n | 'teal'\n | 'blue'\n | 'cyan'\n | 'yellow'\n | 'green'\n | 'orange';\n\nexport interface UserAvatarProps extends Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n 'src' | 'alt' | 'width' | 'height'\n> {\n /** Alt text for the avatar image. */\n alt: string;\n /** Optional CSS class name. */\n className?: string;\n /**\n * Image URL for the avatar. When omitted, or when the image fails to load,\n * the avatar renders as Fallback (initials on a deterministic colour\n * background). A failed image sets `data-image-failed=\"true\"` on the root.\n */\n src?: string;\n /**\n * Display name used to derive initials and the fallback colour. Defaults\n * to `alt` when not provided.\n */\n name?: string;\n /** Force a specific fallback colour. Hashed from `name`/`alt` if omitted. */\n fallbackColor?: UserAvatarFallbackColor;\n /** Size variant. Figma: Size. Default: 48. */\n size?: UserAvatarSize;\n /**\n * Status badge shown on the avatar: `online`, `away`, `do-not-disturb` or `offline`.\n * Omit (or `false`) to hide it. `true` is kept for backwards compatibility and\n * means `online`. The badge size follows the avatar `size`.\n */\n status?: boolean | StatusBadgeStatus;\n /** Accessible name for the status badge. Defaults to the status value; pass a translated string. */\n statusLabel?: string;\n}\n\n/** Colours picked by the name hash when `fallbackColor` is not set. */\nconst FALLBACK_COLORS: readonly UserAvatarFallbackColor[] = [\n 'red',\n 'purple',\n 'neutral',\n 'blue',\n 'cyan',\n 'yellow',\n 'green',\n 'orange',\n 'charcoal',\n 'indigo',\n 'teal',\n];\n\n/** Map UserAvatar size to StatusBadge size (Figma scale). */\nconst USER_AVATAR_TO_BADGE_SIZE: Record<UserAvatarSize, StatusBadgeSize> = {\n '12': 'xx-small',\n '16': 'xx-small',\n '20': 'x-small',\n '24': 'x-small',\n '28': 'x-small',\n '32': 'small',\n '36': 'small',\n '40': 'small',\n '48': 'small',\n '50': 'small',\n '56': 'medium',\n '64': 'medium',\n '72': 'medium',\n '80': 'medium',\n '96': 'large',\n '120': 'large',\n '128': 'large',\n};\n\nfunction hashFallbackColor(s: string): UserAvatarFallbackColor {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = (h * 31 + s.charCodeAt(i)) | 0;\n }\n return FALLBACK_COLORS[Math.abs(h) % FALLBACK_COLORS.length];\n}\n\nfunction getInitials(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) return '';\n const firstName = trimmed.split(/\\s+/)[0]!;\n return firstName[0]!.toUpperCase() + (firstName[1]?.toLowerCase() ?? '');\n}\n\n/**\n * User Avatars represent a person — usually their uploaded photo, with initials on a colour\n * background as a fallback. Their circular shape distinguishes them from rounded-square Team\n * Avatars at a glance. `ref` points at the root element, which is present for both the image and\n * the fallback, so it works as a tooltip or popover anchor.\n */\nconst UserAvatar = forwardRef<HTMLDivElement, UserAvatarProps>(\n function UserAvatar(\n {\n alt,\n className = '',\n src,\n name,\n fallbackColor,\n size = '48',\n status,\n statusLabel,\n onError,\n ...imgProps\n },\n ref,\n ) {\n // The src that failed to load; a new src is tried again.\n const [failedSrc, setFailedSrc] = useState<string>();\n const sizeClass = styles[`user-avatar--size-${toKebab(size)}`];\n const rootClass = [styles['user-avatar'], sizeClass, className]\n .filter(Boolean)\n .join(' ');\n\n const imageFailed = !!src && src === failedSrc;\n const isFallback = !src || imageFailed;\n const displayName = name ?? alt;\n const initials = isFallback ? getInitials(displayName) : '';\n const color = fallbackColor ?? hashFallbackColor(displayName);\n const fallbackColorClass = isFallback\n ? styles[`user-avatar__fallback--${toKebab(color)}`]\n : '';\n\n const badgeStatus: StatusBadgeStatus | undefined =\n status === true ? 'online' : status || undefined;\n const badgeSize = USER_AVATAR_TO_BADGE_SIZE[size];\n\n return (\n <div\n ref={ref}\n className={rootClass}\n data-size={size}\n data-image-failed={imageFailed ? 'true' : undefined}\n >\n {isFallback ? (\n <span\n className={[styles['user-avatar__fallback'], fallbackColorClass]\n .filter(Boolean)\n .join(' ')}\n role=\"img\"\n aria-label={alt}\n >\n {initials}\n </span>\n ) : (\n <img\n loading=\"lazy\"\n {...imgProps}\n onError={(e) => {\n onError?.(e);\n setFailedSrc(src);\n }}\n alt={alt}\n className={styles['user-avatar__image']}\n src={src}\n width={Number(size)}\n height={Number(size)}\n />\n )}\n {badgeStatus && (\n <span className={styles['user-avatar__status']}>\n <StatusBadge\n status={badgeStatus}\n size={badgeSize}\n label={statusLabel}\n className={styles['user-avatar__badge']}\n />\n </span>\n )}\n </div>\n );\n },\n);\n\nexport default UserAvatar;\n"],"names":["FALLBACK_COLORS","USER_AVATAR_TO_BADGE_SIZE","hashFallbackColor","h","i","getInitials","name","trimmed","firstName","_a","UserAvatar","forwardRef","alt","className","src","fallbackColor","size","status","statusLabel","onError","imgProps","ref","failedSrc","setFailedSrc","useState","sizeClass","styles","toKebab","rootClass","imageFailed","isFallback","displayName","initials","color","fallbackColorClass","badgeStatus","badgeSize","jsxs","jsx","e","StatusBadge"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./UserAvatar.css');const a={"user-avatar":"_user-avatar_1csb5_2","user-avatar__image":"_user-avatar__image_1csb5_8","user-avatar__fallback":"_user-avatar__fallback_1csb5_16","user-avatar__fallback--red":"_user-avatar__fallback--red_1csb5_29","user-avatar__fallback--purple":"_user-avatar__fallback--purple_1csb5_32","user-avatar__fallback--neutral":"_user-avatar__fallback--neutral_1csb5_35","user-avatar__fallback--blue":"_user-avatar__fallback--blue_1csb5_38","user-avatar__fallback--cyan":"_user-avatar__fallback--cyan_1csb5_41","user-avatar__fallback--yellow":"_user-avatar__fallback--yellow_1csb5_44","user-avatar__fallback--green":"_user-avatar__fallback--green_1csb5_47","user-avatar__fallback--orange":"_user-avatar__fallback--orange_1csb5_50","user-avatar__status":"_user-avatar__status_1csb5_53","user-avatar--size-12":"_user-avatar--size-12_1csb5_62","user-avatar--size-16":"_user-avatar--size-16_1csb5_73","user-avatar--size-20":"_user-avatar--size-20_1csb5_84","user-avatar--size-24":"_user-avatar--size-24_1csb5_95","user-avatar--size-28":"_user-avatar--size-28_1csb5_106","user-avatar--size-32":"_user-avatar--size-32_1csb5_117","user-avatar--size-40":"_user-avatar--size-40_1csb5_128","user-avatar--size-48":"_user-avatar--size-48_1csb5_139","user-avatar--size-56":"_user-avatar--size-56_1csb5_150","user-avatar--size-64":"_user-avatar--size-64_1csb5_161","user-avatar--size-72":"_user-avatar--size-72_1csb5_172","user-avatar--size-80":"_user-avatar--size-80_1csb5_183","user-avatar--size-96":"_user-avatar--size-96_1csb5_194","user-avatar--size-120":"_user-avatar--size-120_1csb5_205"};exports.default=a;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./UserAvatar.css');const a={"user-avatar":"_user-avatar_enh1y_13","user-avatar__image":"_user-avatar__image_enh1y_19","user-avatar__fallback":"_user-avatar__fallback_enh1y_27","user-avatar__fallback--red":"_user-avatar__fallback--red_enh1y_40","user-avatar__fallback--purple":"_user-avatar__fallback--purple_enh1y_43","user-avatar__fallback--neutral":"_user-avatar__fallback--neutral_enh1y_46","user-avatar__fallback--charcoal":"_user-avatar__fallback--charcoal_enh1y_49","user-avatar__fallback--indigo":"_user-avatar__fallback--indigo_enh1y_52","user-avatar__fallback--teal":"_user-avatar__fallback--teal_enh1y_55","user-avatar__fallback--blue":"_user-avatar__fallback--blue_enh1y_58","user-avatar__fallback--cyan":"_user-avatar__fallback--cyan_enh1y_61","user-avatar__fallback--yellow":"_user-avatar__fallback--yellow_enh1y_64","user-avatar__fallback--green":"_user-avatar__fallback--green_enh1y_67","user-avatar__fallback--orange":"_user-avatar__fallback--orange_enh1y_70","user-avatar__status":"_user-avatar__status_enh1y_73","user-avatar--size-12":"_user-avatar--size-12_enh1y_82","user-avatar--size-16":"_user-avatar--size-16_enh1y_93","user-avatar--size-20":"_user-avatar--size-20_enh1y_104","user-avatar--size-24":"_user-avatar--size-24_enh1y_115","user-avatar--size-28":"_user-avatar--size-28_enh1y_126","user-avatar--size-32":"_user-avatar--size-32_enh1y_137","user-avatar--size-36":"_user-avatar--size-36_enh1y_148","user-avatar--size-40":"_user-avatar--size-40_enh1y_159","user-avatar--size-48":"_user-avatar--size-48_enh1y_170","user-avatar--size-50":"_user-avatar--size-50_enh1y_181","user-avatar--size-56":"_user-avatar--size-56_enh1y_192","user-avatar__badge":"_user-avatar__badge_enh1y_199","user-avatar--size-64":"_user-avatar--size-64_enh1y_207","user-avatar--size-72":"_user-avatar--size-72_enh1y_222","user-avatar--size-80":"_user-avatar--size-80_enh1y_237","user-avatar--size-96":"_user-avatar--size-96_enh1y_252","user-avatar--size-120":"_user-avatar--size-120_enh1y_263","user-avatar--size-128":"_user-avatar--size-128_enh1y_274"};exports.default=a;
2
2
  //# sourceMappingURL=UserAvatar.module.scss.cjs.map
@@ -1,30 +1,37 @@
1
1
  import './UserAvatar.css';const a = {
2
- "user-avatar": "_user-avatar_1csb5_2",
3
- "user-avatar__image": "_user-avatar__image_1csb5_8",
4
- "user-avatar__fallback": "_user-avatar__fallback_1csb5_16",
5
- "user-avatar__fallback--red": "_user-avatar__fallback--red_1csb5_29",
6
- "user-avatar__fallback--purple": "_user-avatar__fallback--purple_1csb5_32",
7
- "user-avatar__fallback--neutral": "_user-avatar__fallback--neutral_1csb5_35",
8
- "user-avatar__fallback--blue": "_user-avatar__fallback--blue_1csb5_38",
9
- "user-avatar__fallback--cyan": "_user-avatar__fallback--cyan_1csb5_41",
10
- "user-avatar__fallback--yellow": "_user-avatar__fallback--yellow_1csb5_44",
11
- "user-avatar__fallback--green": "_user-avatar__fallback--green_1csb5_47",
12
- "user-avatar__fallback--orange": "_user-avatar__fallback--orange_1csb5_50",
13
- "user-avatar__status": "_user-avatar__status_1csb5_53",
14
- "user-avatar--size-12": "_user-avatar--size-12_1csb5_62",
15
- "user-avatar--size-16": "_user-avatar--size-16_1csb5_73",
16
- "user-avatar--size-20": "_user-avatar--size-20_1csb5_84",
17
- "user-avatar--size-24": "_user-avatar--size-24_1csb5_95",
18
- "user-avatar--size-28": "_user-avatar--size-28_1csb5_106",
19
- "user-avatar--size-32": "_user-avatar--size-32_1csb5_117",
20
- "user-avatar--size-40": "_user-avatar--size-40_1csb5_128",
21
- "user-avatar--size-48": "_user-avatar--size-48_1csb5_139",
22
- "user-avatar--size-56": "_user-avatar--size-56_1csb5_150",
23
- "user-avatar--size-64": "_user-avatar--size-64_1csb5_161",
24
- "user-avatar--size-72": "_user-avatar--size-72_1csb5_172",
25
- "user-avatar--size-80": "_user-avatar--size-80_1csb5_183",
26
- "user-avatar--size-96": "_user-avatar--size-96_1csb5_194",
27
- "user-avatar--size-120": "_user-avatar--size-120_1csb5_205"
2
+ "user-avatar": "_user-avatar_enh1y_13",
3
+ "user-avatar__image": "_user-avatar__image_enh1y_19",
4
+ "user-avatar__fallback": "_user-avatar__fallback_enh1y_27",
5
+ "user-avatar__fallback--red": "_user-avatar__fallback--red_enh1y_40",
6
+ "user-avatar__fallback--purple": "_user-avatar__fallback--purple_enh1y_43",
7
+ "user-avatar__fallback--neutral": "_user-avatar__fallback--neutral_enh1y_46",
8
+ "user-avatar__fallback--charcoal": "_user-avatar__fallback--charcoal_enh1y_49",
9
+ "user-avatar__fallback--indigo": "_user-avatar__fallback--indigo_enh1y_52",
10
+ "user-avatar__fallback--teal": "_user-avatar__fallback--teal_enh1y_55",
11
+ "user-avatar__fallback--blue": "_user-avatar__fallback--blue_enh1y_58",
12
+ "user-avatar__fallback--cyan": "_user-avatar__fallback--cyan_enh1y_61",
13
+ "user-avatar__fallback--yellow": "_user-avatar__fallback--yellow_enh1y_64",
14
+ "user-avatar__fallback--green": "_user-avatar__fallback--green_enh1y_67",
15
+ "user-avatar__fallback--orange": "_user-avatar__fallback--orange_enh1y_70",
16
+ "user-avatar__status": "_user-avatar__status_enh1y_73",
17
+ "user-avatar--size-12": "_user-avatar--size-12_enh1y_82",
18
+ "user-avatar--size-16": "_user-avatar--size-16_enh1y_93",
19
+ "user-avatar--size-20": "_user-avatar--size-20_enh1y_104",
20
+ "user-avatar--size-24": "_user-avatar--size-24_enh1y_115",
21
+ "user-avatar--size-28": "_user-avatar--size-28_enh1y_126",
22
+ "user-avatar--size-32": "_user-avatar--size-32_enh1y_137",
23
+ "user-avatar--size-36": "_user-avatar--size-36_enh1y_148",
24
+ "user-avatar--size-40": "_user-avatar--size-40_enh1y_159",
25
+ "user-avatar--size-48": "_user-avatar--size-48_enh1y_170",
26
+ "user-avatar--size-50": "_user-avatar--size-50_enh1y_181",
27
+ "user-avatar--size-56": "_user-avatar--size-56_enh1y_192",
28
+ "user-avatar__badge": "_user-avatar__badge_enh1y_199",
29
+ "user-avatar--size-64": "_user-avatar--size-64_enh1y_207",
30
+ "user-avatar--size-72": "_user-avatar--size-72_enh1y_222",
31
+ "user-avatar--size-80": "_user-avatar--size-80_enh1y_237",
32
+ "user-avatar--size-96": "_user-avatar--size-96_enh1y_252",
33
+ "user-avatar--size-120": "_user-avatar--size-120_enh1y_263",
34
+ "user-avatar--size-128": "_user-avatar--size-128_enh1y_274"
28
35
  };
29
36
  export {
30
37
  a as default
@@ -1 +1 @@
1
- {"version":3,"file":"UserAvatar.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"UserAvatar.module.scss.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- ._user-avatar-group_17zfx_2{display:inline-flex;align-items:center;padding-right:var(--spacing-xxxxs)}._user-avatar-group__item_17zfx_7{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;margin-right:-2px;border-radius:var(--radius-pill);outline:1px solid var(--center-channel-bg, var(--color-neutral-0));transform:scale(1);transition:transform var(--duration-quick) var(--ease-transition),box-shadow var(--duration-quick) var(--ease-transition)}._user-avatar-group__item_17zfx_7:hover{z-index:10;transform:scale(1.04);box-shadow:var(--elevation-2)}._user-avatar-group__item_17zfx_7:hover ._user-avatar-group__tooltip-layer_17zfx_26{opacity:1;visibility:visible;transition:opacity var(--duration-quick) var(--ease-entrance),visibility 0s linear 0s}._user-avatar-group__trigger_17zfx_31{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:inherit;overflow:hidden}._user-avatar-group__tooltip-layer_17zfx_26{position:absolute;left:50%;bottom:100%;z-index:20;margin-bottom:var(--spacing-xxxxs);transform:translate(-50%);opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--duration-quick) var(--ease-exit),visibility 0s linear var(--duration-quick)}._user-avatar-group__tooltip_17zfx_26{flex-shrink:0}._user-avatar-group__overflow_17zfx_55{display:inline-flex;align-items:center;justify-content:center;background-color:var(--center-channel-bg);background-image:linear-gradient(rgba(var(--center-channel-color-rgb),.08),rgba(var(--center-channel-color-rgb),.08));color:rgba(var(--center-channel-color-rgb),.56);font-size:var(--font-size-25);font-weight:var(--font-weight-semibold);letter-spacing:.01em;border-radius:var(--radius-pill)}._user-avatar-group--size-24_17zfx_67{padding-right:3px}._user-avatar-group--size-24_17zfx_67 ._user-avatar-group__item_17zfx_7{width:24px;height:24px;margin-right:-3px;outline-width:1px}._user-avatar-group--size-24_17zfx_67 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-50)}._user-avatar-group--size-28_17zfx_79{padding-right:3px}._user-avatar-group--size-28_17zfx_79 ._user-avatar-group__item_17zfx_7{width:28px;height:28px;margin-right:-3px;outline-width:2px}._user-avatar-group--size-28_17zfx_79 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-75)}._user-avatar-group--size-32_17zfx_91{padding-right:3px}._user-avatar-group--size-32_17zfx_91 ._user-avatar-group__item_17zfx_7{width:32px;height:32px;margin-right:-3px;outline-width:2px}._user-avatar-group--size-32_17zfx_91 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-75)}._user-avatar-group--size-40_17zfx_103{padding-right:5px}._user-avatar-group--size-40_17zfx_103 ._user-avatar-group__item_17zfx_7{width:40px;height:40px;margin-right:-5px;outline-width:2px}._user-avatar-group--size-40_17zfx_103 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-100)}._user-avatar-group--size-48_17zfx_115{padding-right:7px}._user-avatar-group--size-48_17zfx_115 ._user-avatar-group__item_17zfx_7{width:48px;height:48px;margin-right:-7px;outline-width:2px}._user-avatar-group--size-48_17zfx_115 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-200)}._user-avatar-group--size-56_17zfx_127{padding-right:8px}._user-avatar-group--size-56_17zfx_127 ._user-avatar-group__item_17zfx_7{width:56px;height:56px;margin-right:-8px;outline-width:2px}._user-avatar-group--size-56_17zfx_127 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-300)}._user-avatar-group--size-64_17zfx_139{padding-right:9px}._user-avatar-group--size-64_17zfx_139 ._user-avatar-group__item_17zfx_7{width:64px;height:64px;margin-right:-9px;outline-width:2px}._user-avatar-group--size-64_17zfx_139 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-400)}._user-avatar-group--size-72_17zfx_151{padding-right:10px}._user-avatar-group--size-72_17zfx_151 ._user-avatar-group__item_17zfx_7{width:72px;height:72px;margin-right:-10px;outline-width:2px}._user-avatar-group--size-72_17zfx_151 ._user-avatar-group__overflow_17zfx_55{font-size:var(--font-size-500)}
1
+ ._user-avatar-group_keccc_13{display:inline-flex;align-items:center;padding-right:var(--spacing-xxxxs)}._user-avatar-group__item_keccc_18{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;margin-right:calc(-1 * var(--spacing-xxxxs));border-radius:var(--radius-pill);outline:1px solid var(--center-channel-bg, var(--color-neutral-0));transform:scale(1);transition:transform var(--duration-quick) var(--ease-transition),box-shadow var(--duration-quick) var(--ease-transition)}._user-avatar-group__item_keccc_18:hover{z-index:10;transform:scale(1.04);box-shadow:var(--elevation-2)}._user-avatar-group__item_keccc_18:hover ._user-avatar-group__tooltip-layer_keccc_37{opacity:1;visibility:visible;transition:opacity var(--duration-quick) var(--ease-entrance),visibility 0s linear 0s}._user-avatar-group__trigger_keccc_42{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:inherit;overflow:hidden}._user-avatar-group__tooltip-layer_keccc_37{position:absolute;left:50%;bottom:100%;z-index:20;margin-bottom:var(--spacing-xxxxs);transform:translate(-50%);opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--duration-quick) var(--ease-exit),visibility 0s linear var(--duration-quick)}._user-avatar-group__tooltip_keccc_37{flex-shrink:0}._user-avatar-group__overflow_keccc_66{display:inline-flex;align-items:center;justify-content:center;background-color:var(--center-channel-bg);background-image:linear-gradient(rgba(var(--center-channel-color-rgb),.08),rgba(var(--center-channel-color-rgb),.08));color:rgba(var(--center-channel-color-rgb),.56);font-size:var(--font-size-25);font-weight:var(--font-weight-semibold);letter-spacing:.01em;border-radius:var(--radius-pill)}._user-avatar-group--size-24_keccc_78{padding-right:3px}._user-avatar-group--size-24_keccc_78 ._user-avatar-group__item_keccc_18{width:24px;height:24px;margin-right:-3px;outline-width:1px}._user-avatar-group--size-24_keccc_78 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-50)}._user-avatar-group--size-28_keccc_90{padding-right:3px}._user-avatar-group--size-28_keccc_90 ._user-avatar-group__item_keccc_18{width:28px;height:28px;margin-right:-3px;outline-width:2px}._user-avatar-group--size-28_keccc_90 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-75)}._user-avatar-group--size-32_keccc_102{padding-right:3px}._user-avatar-group--size-32_keccc_102 ._user-avatar-group__item_keccc_18{width:32px;height:32px;margin-right:-3px;outline-width:2px}._user-avatar-group--size-32_keccc_102 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-75)}._user-avatar-group--size-40_keccc_114{padding-right:5px}._user-avatar-group--size-40_keccc_114 ._user-avatar-group__item_keccc_18{width:40px;height:40px;margin-right:-5px;outline-width:2px}._user-avatar-group--size-40_keccc_114 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-100)}._user-avatar-group--size-48_keccc_126{padding-right:7px}._user-avatar-group--size-48_keccc_126 ._user-avatar-group__item_keccc_18{width:48px;height:48px;margin-right:-7px;outline-width:2px}._user-avatar-group--size-48_keccc_126 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-200)}._user-avatar-group--size-56_keccc_138{padding-right:8px}._user-avatar-group--size-56_keccc_138 ._user-avatar-group__item_keccc_18{width:56px;height:56px;margin-right:-8px;outline-width:2px}._user-avatar-group--size-56_keccc_138 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-300)}._user-avatar-group--size-64_keccc_150{padding-right:9px}._user-avatar-group--size-64_keccc_150 ._user-avatar-group__item_keccc_18{width:64px;height:64px;margin-right:-9px;outline-width:2px}._user-avatar-group--size-64_keccc_150 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-400)}._user-avatar-group--size-72_keccc_162{padding-right:10px}._user-avatar-group--size-72_keccc_162 ._user-avatar-group__item_keccc_18{width:72px;height:72px;margin-right:-10px;outline-width:2px}._user-avatar-group--size-72_keccc_162 ._user-avatar-group__overflow_keccc_66{font-size:var(--font-size-500)}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./UserAvatarGroup.css');const r={"user-avatar-group":"_user-avatar-group_17zfx_2","user-avatar-group__item":"_user-avatar-group__item_17zfx_7","user-avatar-group__tooltip-layer":"_user-avatar-group__tooltip-layer_17zfx_26","user-avatar-group__trigger":"_user-avatar-group__trigger_17zfx_31","user-avatar-group__tooltip":"_user-avatar-group__tooltip_17zfx_26","user-avatar-group__overflow":"_user-avatar-group__overflow_17zfx_55","user-avatar-group--size-24":"_user-avatar-group--size-24_17zfx_67","user-avatar-group--size-28":"_user-avatar-group--size-28_17zfx_79","user-avatar-group--size-32":"_user-avatar-group--size-32_17zfx_91","user-avatar-group--size-40":"_user-avatar-group--size-40_17zfx_103","user-avatar-group--size-48":"_user-avatar-group--size-48_17zfx_115","user-avatar-group--size-56":"_user-avatar-group--size-56_17zfx_127","user-avatar-group--size-64":"_user-avatar-group--size-64_17zfx_139","user-avatar-group--size-72":"_user-avatar-group--size-72_17zfx_151"};exports.default=r;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./UserAvatarGroup.css');const r={"user-avatar-group":"_user-avatar-group_keccc_13","user-avatar-group__item":"_user-avatar-group__item_keccc_18","user-avatar-group__tooltip-layer":"_user-avatar-group__tooltip-layer_keccc_37","user-avatar-group__trigger":"_user-avatar-group__trigger_keccc_42","user-avatar-group__tooltip":"_user-avatar-group__tooltip_keccc_37","user-avatar-group__overflow":"_user-avatar-group__overflow_keccc_66","user-avatar-group--size-24":"_user-avatar-group--size-24_keccc_78","user-avatar-group--size-28":"_user-avatar-group--size-28_keccc_90","user-avatar-group--size-32":"_user-avatar-group--size-32_keccc_102","user-avatar-group--size-40":"_user-avatar-group--size-40_keccc_114","user-avatar-group--size-48":"_user-avatar-group--size-48_keccc_126","user-avatar-group--size-56":"_user-avatar-group--size-56_keccc_138","user-avatar-group--size-64":"_user-avatar-group--size-64_keccc_150","user-avatar-group--size-72":"_user-avatar-group--size-72_keccc_162"};exports.default=r;
2
2
  //# sourceMappingURL=UserAvatarGroup.module.scss.cjs.map
@@ -1,18 +1,18 @@
1
1
  import './UserAvatarGroup.css';const r = {
2
- "user-avatar-group": "_user-avatar-group_17zfx_2",
3
- "user-avatar-group__item": "_user-avatar-group__item_17zfx_7",
4
- "user-avatar-group__tooltip-layer": "_user-avatar-group__tooltip-layer_17zfx_26",
5
- "user-avatar-group__trigger": "_user-avatar-group__trigger_17zfx_31",
6
- "user-avatar-group__tooltip": "_user-avatar-group__tooltip_17zfx_26",
7
- "user-avatar-group__overflow": "_user-avatar-group__overflow_17zfx_55",
8
- "user-avatar-group--size-24": "_user-avatar-group--size-24_17zfx_67",
9
- "user-avatar-group--size-28": "_user-avatar-group--size-28_17zfx_79",
10
- "user-avatar-group--size-32": "_user-avatar-group--size-32_17zfx_91",
11
- "user-avatar-group--size-40": "_user-avatar-group--size-40_17zfx_103",
12
- "user-avatar-group--size-48": "_user-avatar-group--size-48_17zfx_115",
13
- "user-avatar-group--size-56": "_user-avatar-group--size-56_17zfx_127",
14
- "user-avatar-group--size-64": "_user-avatar-group--size-64_17zfx_139",
15
- "user-avatar-group--size-72": "_user-avatar-group--size-72_17zfx_151"
2
+ "user-avatar-group": "_user-avatar-group_keccc_13",
3
+ "user-avatar-group__item": "_user-avatar-group__item_keccc_18",
4
+ "user-avatar-group__tooltip-layer": "_user-avatar-group__tooltip-layer_keccc_37",
5
+ "user-avatar-group__trigger": "_user-avatar-group__trigger_keccc_42",
6
+ "user-avatar-group__tooltip": "_user-avatar-group__tooltip_keccc_37",
7
+ "user-avatar-group__overflow": "_user-avatar-group__overflow_keccc_66",
8
+ "user-avatar-group--size-24": "_user-avatar-group--size-24_keccc_78",
9
+ "user-avatar-group--size-28": "_user-avatar-group--size-28_keccc_90",
10
+ "user-avatar-group--size-32": "_user-avatar-group--size-32_keccc_102",
11
+ "user-avatar-group--size-40": "_user-avatar-group--size-40_keccc_114",
12
+ "user-avatar-group--size-48": "_user-avatar-group--size-48_keccc_126",
13
+ "user-avatar-group--size-56": "_user-avatar-group--size-56_keccc_138",
14
+ "user-avatar-group--size-64": "_user-avatar-group--size-64_keccc_150",
15
+ "user-avatar-group--size-72": "_user-avatar-group--size-72_keccc_162"
16
16
  };
17
17
  export {
18
18
  r as default
@@ -1 +1 @@
1
- {"version":3,"file":"use-anchored-popup-portal.cjs","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"sourcesContent":["import {\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ANCHORED_POPUP_GAP,\n ANCHORED_POPUP_Z_INDEX,\n computeAnchoredPopupFixedStyle,\n computeAnchoredPopupPlacement,\n getAnchoredPopupContainerFrame,\n type PopupPlacement,\n} from '@/utils/anchoredPopupPlacement';\n\nexport interface UseAnchoredPopupPortalOptions {\n /** Height used for the flip decision when content isn’t measured yet. */\n preferredHeight: number;\n /** Cap for scrollable menus (Select/Combobox). Omit for intrinsic panels. */\n maxHeightCap?: number;\n /** Ref to the portaled panel for measuring intrinsic height (DateRangePicker). */\n contentRef?: RefObject<HTMLElement | null>;\n /**\n * Portal mount node; defaults to `document.body` with viewport-fixed coords.\n * Custom containers must establish a positioning context (`position` other\n * than `static`); coords are converted to that container’s space.\n */\n portalContainer?: HTMLElement | null;\n zIndex?: number;\n /**\n * When true (default), fixed width matches the trigger.\n * DateRangePicker sets false and keeps its CSS width.\n */\n matchWidth?: boolean;\n gap?: number;\n}\n\nexport interface UseAnchoredPopupPortalResult {\n placement: PopupPlacement;\n maxHeight: number;\n style: CSSProperties;\n /** Ref for the portaled surface — pass to `useOutsideClose` as a second root. */\n portalRef: RefObject<HTMLDivElement | null>;\n /** Wraps children in a portal to `portalContainer` or `document.body`. */\n renderPortal: (children: ReactNode) => ReactNode;\n}\n\nconst DEFAULT_PLACEMENT: PopupPlacement = 'below';\n\nfunction resolvePortalMount(\n portalContainer: HTMLElement | null | undefined,\n): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n return portalContainer ?? document.body;\n}\n\nfunction usesViewportFixedCoords(mount: HTMLElement): boolean {\n return mount === document.body;\n}\n\n/**\n * Positions a form-widget popup in a portal with viewport-aware above/below flip.\n * Internal to compass-ui form widgets — not a general overlay positioning API.\n */\nexport function useAnchoredPopupPortal(\n anchorRef: RefObject<HTMLElement | null>,\n isOpen: boolean,\n options: UseAnchoredPopupPortalOptions,\n): UseAnchoredPopupPortalResult {\n const {\n preferredHeight,\n maxHeightCap,\n contentRef,\n portalContainer = null,\n zIndex = ANCHORED_POPUP_Z_INDEX,\n matchWidth = true,\n gap = ANCHORED_POPUP_GAP,\n } = options;\n\n const portalRef = useRef<HTMLDivElement | null>(null);\n const [placement, setPlacement] = useState<PopupPlacement>(DEFAULT_PLACEMENT);\n const [maxHeight, setMaxHeight] = useState(maxHeightCap ?? preferredHeight);\n const [style, setStyle] = useState<CSSProperties>({\n position: 'fixed',\n top: 0,\n left: 0,\n width: matchWidth ? 0 : undefined,\n zIndex,\n });\n\n const update = useCallback(() => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return;\n\n const rect = anchor.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportFixed = usesViewportFixedCoords(mount);\n const containerFrame = viewportFixed\n ? undefined\n : getAnchoredPopupContainerFrame(mount);\n\n const measured =\n contentRef?.current?.offsetHeight ?? portalRef.current?.offsetHeight ?? 0;\n const heightForFlip = measured > 0 ? measured : preferredHeight;\n\n const { placement: nextPlacement, maxHeight: nextMaxHeight } =\n computeAnchoredPopupPlacement(rect, viewportHeight, {\n gap,\n preferredHeight: heightForFlip,\n maxHeightCap,\n bounds: containerFrame?.bounds,\n });\n\n const fixed = computeAnchoredPopupFixedStyle(rect, nextPlacement, {\n gap,\n zIndex,\n width: matchWidth ? rect.width : undefined,\n viewportHeight,\n containerFrame,\n });\n\n setPlacement(nextPlacement);\n setMaxHeight(nextMaxHeight);\n setStyle({\n position: fixed.position,\n left: fixed.left,\n zIndex: fixed.zIndex,\n ...(matchWidth ? { width: fixed.width } : null),\n ...(nextPlacement === 'below'\n ? { top: fixed.top, bottom: 'auto' }\n : { bottom: fixed.bottom, top: 'auto' }),\n });\n }, [\n anchorRef,\n contentRef,\n gap,\n matchWidth,\n maxHeightCap,\n portalContainer,\n preferredHeight,\n zIndex,\n ]);\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n update();\n\n function handle() {\n update();\n }\n\n window.addEventListener('resize', handle);\n // Capture phase so nested scroll containers (modals, RHS) are covered.\n document.addEventListener('scroll', handle, true);\n return () => {\n window.removeEventListener('resize', handle);\n document.removeEventListener('scroll', handle, true);\n };\n }, [isOpen, update]);\n\n // Re-measure after content mounts / changes size (calendar, long lists).\n useLayoutEffect(() => {\n if (!isOpen) return;\n const el = contentRef?.current ?? portalRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n\n const ro = new ResizeObserver(() => update());\n ro.observe(el);\n return () => ro.disconnect();\n }, [isOpen, contentRef, update]);\n\n const renderPortal = useCallback(\n (children: ReactNode) => {\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return null;\n return createPortal(children, mount);\n },\n [portalContainer],\n );\n\n return {\n placement,\n maxHeight,\n style,\n portalRef,\n renderPortal,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","resolvePortalMount","portalContainer","usesViewportFixedCoords","mount","useAnchoredPopupPortal","anchorRef","isOpen","options","preferredHeight","maxHeightCap","contentRef","zIndex","ANCHORED_POPUP_Z_INDEX","matchWidth","gap","ANCHORED_POPUP_GAP","portalRef","useRef","placement","setPlacement","useState","maxHeight","setMaxHeight","style","setStyle","update","useCallback","anchor","rect","viewportHeight","containerFrame","getAnchoredPopupContainerFrame","measured","_a","_b","heightForFlip","nextPlacement","nextMaxHeight","computeAnchoredPopupPlacement","fixed","computeAnchoredPopupFixedStyle","useLayoutEffect","handle","el","ro","renderPortal","children","createPortal"],"mappings":"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"}
1
+ {"version":3,"file":"use-anchored-popup-portal.cjs","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"sourcesContent":["import {\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ANCHORED_POPUP_GAP,\n ANCHORED_POPUP_Z_INDEX,\n computeAnchoredPopupFixedStyle,\n computeAnchoredPopupPlacement,\n getAnchoredPopupContainerFrame,\n type PopupPlacement,\n} from '@/utils/anchoredPopupPlacement';\n\nexport interface UseAnchoredPopupPortalOptions {\n /** Height used for the flip decision when content isn’t measured yet. */\n preferredHeight: number;\n /** Cap for scrollable menus (Select/Combobox). Omit for intrinsic panels. */\n maxHeightCap?: number;\n /** Ref to the portaled panel for measuring intrinsic height (DateRangePicker). */\n contentRef?: RefObject<HTMLElement | null>;\n /**\n * Portal mount node; defaults to `document.body` with viewport-fixed coords.\n * Custom containers must establish a positioning context (`position` other\n * than `static`); coords are converted to that container’s space.\n */\n portalContainer?: HTMLElement | null;\n zIndex?: number | string;\n /**\n * When true (default), fixed width matches the trigger.\n * DateRangePicker sets false and keeps its CSS width.\n */\n matchWidth?: boolean;\n gap?: number;\n}\n\nexport interface UseAnchoredPopupPortalResult {\n placement: PopupPlacement;\n maxHeight: number;\n style: CSSProperties;\n /** Ref for the portaled surface — pass to `useOutsideClose` as a second root. */\n portalRef: RefObject<HTMLDivElement | null>;\n /** Wraps children in a portal to `portalContainer` or `document.body`. */\n renderPortal: (children: ReactNode) => ReactNode;\n}\n\nconst DEFAULT_PLACEMENT: PopupPlacement = 'below';\n\nfunction resolvePortalMount(\n portalContainer: HTMLElement | null | undefined,\n): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n return portalContainer ?? document.body;\n}\n\nfunction usesViewportFixedCoords(mount: HTMLElement): boolean {\n return mount === document.body;\n}\n\n/**\n * Positions a form-widget popup in a portal with viewport-aware above/below flip.\n * Internal to compass-ui form widgets — not a general overlay positioning API.\n */\nexport function useAnchoredPopupPortal(\n anchorRef: RefObject<HTMLElement | null>,\n isOpen: boolean,\n options: UseAnchoredPopupPortalOptions,\n): UseAnchoredPopupPortalResult {\n const {\n preferredHeight,\n maxHeightCap,\n contentRef,\n portalContainer = null,\n zIndex = ANCHORED_POPUP_Z_INDEX,\n matchWidth = true,\n gap = ANCHORED_POPUP_GAP,\n } = options;\n\n const portalRef = useRef<HTMLDivElement | null>(null);\n const [placement, setPlacement] = useState<PopupPlacement>(DEFAULT_PLACEMENT);\n const [maxHeight, setMaxHeight] = useState(maxHeightCap ?? preferredHeight);\n const [style, setStyle] = useState<CSSProperties>({\n position: 'fixed',\n top: 0,\n left: 0,\n width: matchWidth ? 0 : undefined,\n zIndex,\n });\n\n const update = useCallback(() => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return;\n\n const rect = anchor.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportFixed = usesViewportFixedCoords(mount);\n const containerFrame = viewportFixed\n ? undefined\n : getAnchoredPopupContainerFrame(mount);\n\n const measured =\n contentRef?.current?.offsetHeight ?? portalRef.current?.offsetHeight ?? 0;\n const heightForFlip = measured > 0 ? measured : preferredHeight;\n\n const { placement: nextPlacement, maxHeight: nextMaxHeight } =\n computeAnchoredPopupPlacement(rect, viewportHeight, {\n gap,\n preferredHeight: heightForFlip,\n maxHeightCap,\n bounds: containerFrame?.bounds,\n });\n\n const fixed = computeAnchoredPopupFixedStyle(rect, nextPlacement, {\n gap,\n zIndex,\n width: matchWidth ? rect.width : undefined,\n viewportHeight,\n containerFrame,\n });\n\n setPlacement(nextPlacement);\n setMaxHeight(nextMaxHeight);\n setStyle({\n position: fixed.position,\n left: fixed.left,\n zIndex: fixed.zIndex,\n ...(matchWidth ? { width: fixed.width } : null),\n ...(nextPlacement === 'below'\n ? { top: fixed.top, bottom: 'auto' }\n : { bottom: fixed.bottom, top: 'auto' }),\n });\n }, [\n anchorRef,\n contentRef,\n gap,\n matchWidth,\n maxHeightCap,\n portalContainer,\n preferredHeight,\n zIndex,\n ]);\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n update();\n\n function handle() {\n update();\n }\n\n window.addEventListener('resize', handle);\n // Capture phase so nested scroll containers (modals, RHS) are covered.\n document.addEventListener('scroll', handle, true);\n return () => {\n window.removeEventListener('resize', handle);\n document.removeEventListener('scroll', handle, true);\n };\n }, [isOpen, update]);\n\n // Re-measure after content mounts / changes size (calendar, long lists).\n useLayoutEffect(() => {\n if (!isOpen) return;\n const el = contentRef?.current ?? portalRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n\n const ro = new ResizeObserver(() => update());\n ro.observe(el);\n return () => ro.disconnect();\n }, [isOpen, contentRef, update]);\n\n const renderPortal = useCallback(\n (children: ReactNode) => {\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return null;\n return createPortal(children, mount);\n },\n [portalContainer],\n );\n\n return {\n placement,\n maxHeight,\n style,\n portalRef,\n renderPortal,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","resolvePortalMount","portalContainer","usesViewportFixedCoords","mount","useAnchoredPopupPortal","anchorRef","isOpen","options","preferredHeight","maxHeightCap","contentRef","zIndex","ANCHORED_POPUP_Z_INDEX","matchWidth","gap","ANCHORED_POPUP_GAP","portalRef","useRef","placement","setPlacement","useState","maxHeight","setMaxHeight","style","setStyle","update","useCallback","anchor","rect","viewportHeight","containerFrame","getAnchoredPopupContainerFrame","measured","_a","_b","heightForFlip","nextPlacement","nextMaxHeight","computeAnchoredPopupPlacement","fixed","computeAnchoredPopupFixedStyle","useLayoutEffect","handle","el","ro","renderPortal","children","createPortal"],"mappings":"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"}
@@ -13,7 +13,7 @@ export interface UseAnchoredPopupPortalOptions {
13
13
  * than `static`); coords are converted to that container’s space.
14
14
  */
15
15
  portalContainer?: HTMLElement | null;
16
- zIndex?: number;
16
+ zIndex?: number | string;
17
17
  /**
18
18
  * When true (default), fixed width matches the trigger.
19
19
  * DateRangePicker sets false and keeps its CSS width.
@@ -1 +1 @@
1
- {"version":3,"file":"use-anchored-popup-portal.d.ts","sourceRoot":"","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,6BAA6B;IAC5C,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC3C;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,iFAAiF;IACjF,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5C,0EAA0E;IAC1E,YAAY,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC;CAClD;AAeD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,6BAA6B,GACrC,4BAA4B,CA2H9B"}
1
+ {"version":3,"file":"use-anchored-popup-portal.d.ts","sourceRoot":"","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,6BAA6B;IAC5C,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC3C;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,iFAAiF;IACjF,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5C,0EAA0E;IAC1E,YAAY,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC;CAClD;AAeD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,6BAA6B,GACrC,4BAA4B,CA2H9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-anchored-popup-portal.js","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"sourcesContent":["import {\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ANCHORED_POPUP_GAP,\n ANCHORED_POPUP_Z_INDEX,\n computeAnchoredPopupFixedStyle,\n computeAnchoredPopupPlacement,\n getAnchoredPopupContainerFrame,\n type PopupPlacement,\n} from '@/utils/anchoredPopupPlacement';\n\nexport interface UseAnchoredPopupPortalOptions {\n /** Height used for the flip decision when content isn’t measured yet. */\n preferredHeight: number;\n /** Cap for scrollable menus (Select/Combobox). Omit for intrinsic panels. */\n maxHeightCap?: number;\n /** Ref to the portaled panel for measuring intrinsic height (DateRangePicker). */\n contentRef?: RefObject<HTMLElement | null>;\n /**\n * Portal mount node; defaults to `document.body` with viewport-fixed coords.\n * Custom containers must establish a positioning context (`position` other\n * than `static`); coords are converted to that container’s space.\n */\n portalContainer?: HTMLElement | null;\n zIndex?: number;\n /**\n * When true (default), fixed width matches the trigger.\n * DateRangePicker sets false and keeps its CSS width.\n */\n matchWidth?: boolean;\n gap?: number;\n}\n\nexport interface UseAnchoredPopupPortalResult {\n placement: PopupPlacement;\n maxHeight: number;\n style: CSSProperties;\n /** Ref for the portaled surface — pass to `useOutsideClose` as a second root. */\n portalRef: RefObject<HTMLDivElement | null>;\n /** Wraps children in a portal to `portalContainer` or `document.body`. */\n renderPortal: (children: ReactNode) => ReactNode;\n}\n\nconst DEFAULT_PLACEMENT: PopupPlacement = 'below';\n\nfunction resolvePortalMount(\n portalContainer: HTMLElement | null | undefined,\n): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n return portalContainer ?? document.body;\n}\n\nfunction usesViewportFixedCoords(mount: HTMLElement): boolean {\n return mount === document.body;\n}\n\n/**\n * Positions a form-widget popup in a portal with viewport-aware above/below flip.\n * Internal to compass-ui form widgets — not a general overlay positioning API.\n */\nexport function useAnchoredPopupPortal(\n anchorRef: RefObject<HTMLElement | null>,\n isOpen: boolean,\n options: UseAnchoredPopupPortalOptions,\n): UseAnchoredPopupPortalResult {\n const {\n preferredHeight,\n maxHeightCap,\n contentRef,\n portalContainer = null,\n zIndex = ANCHORED_POPUP_Z_INDEX,\n matchWidth = true,\n gap = ANCHORED_POPUP_GAP,\n } = options;\n\n const portalRef = useRef<HTMLDivElement | null>(null);\n const [placement, setPlacement] = useState<PopupPlacement>(DEFAULT_PLACEMENT);\n const [maxHeight, setMaxHeight] = useState(maxHeightCap ?? preferredHeight);\n const [style, setStyle] = useState<CSSProperties>({\n position: 'fixed',\n top: 0,\n left: 0,\n width: matchWidth ? 0 : undefined,\n zIndex,\n });\n\n const update = useCallback(() => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return;\n\n const rect = anchor.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportFixed = usesViewportFixedCoords(mount);\n const containerFrame = viewportFixed\n ? undefined\n : getAnchoredPopupContainerFrame(mount);\n\n const measured =\n contentRef?.current?.offsetHeight ?? portalRef.current?.offsetHeight ?? 0;\n const heightForFlip = measured > 0 ? measured : preferredHeight;\n\n const { placement: nextPlacement, maxHeight: nextMaxHeight } =\n computeAnchoredPopupPlacement(rect, viewportHeight, {\n gap,\n preferredHeight: heightForFlip,\n maxHeightCap,\n bounds: containerFrame?.bounds,\n });\n\n const fixed = computeAnchoredPopupFixedStyle(rect, nextPlacement, {\n gap,\n zIndex,\n width: matchWidth ? rect.width : undefined,\n viewportHeight,\n containerFrame,\n });\n\n setPlacement(nextPlacement);\n setMaxHeight(nextMaxHeight);\n setStyle({\n position: fixed.position,\n left: fixed.left,\n zIndex: fixed.zIndex,\n ...(matchWidth ? { width: fixed.width } : null),\n ...(nextPlacement === 'below'\n ? { top: fixed.top, bottom: 'auto' }\n : { bottom: fixed.bottom, top: 'auto' }),\n });\n }, [\n anchorRef,\n contentRef,\n gap,\n matchWidth,\n maxHeightCap,\n portalContainer,\n preferredHeight,\n zIndex,\n ]);\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n update();\n\n function handle() {\n update();\n }\n\n window.addEventListener('resize', handle);\n // Capture phase so nested scroll containers (modals, RHS) are covered.\n document.addEventListener('scroll', handle, true);\n return () => {\n window.removeEventListener('resize', handle);\n document.removeEventListener('scroll', handle, true);\n };\n }, [isOpen, update]);\n\n // Re-measure after content mounts / changes size (calendar, long lists).\n useLayoutEffect(() => {\n if (!isOpen) return;\n const el = contentRef?.current ?? portalRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n\n const ro = new ResizeObserver(() => update());\n ro.observe(el);\n return () => ro.disconnect();\n }, [isOpen, contentRef, update]);\n\n const renderPortal = useCallback(\n (children: ReactNode) => {\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return null;\n return createPortal(children, mount);\n },\n [portalContainer],\n );\n\n return {\n placement,\n maxHeight,\n style,\n portalRef,\n renderPortal,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","resolvePortalMount","portalContainer","usesViewportFixedCoords","mount","useAnchoredPopupPortal","anchorRef","isOpen","options","preferredHeight","maxHeightCap","contentRef","zIndex","ANCHORED_POPUP_Z_INDEX","matchWidth","gap","ANCHORED_POPUP_GAP","portalRef","useRef","placement","setPlacement","useState","maxHeight","setMaxHeight","style","setStyle","update","useCallback","anchor","rect","viewportHeight","containerFrame","getAnchoredPopupContainerFrame","measured","_a","_b","heightForFlip","nextPlacement","nextMaxHeight","computeAnchoredPopupPlacement","fixed","computeAnchoredPopupFixedStyle","useLayoutEffect","handle","el","ro","renderPortal","children","createPortal"],"mappings":"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"}
1
+ {"version":3,"file":"use-anchored-popup-portal.js","sources":["../../src/hooks/use-anchored-popup-portal.ts"],"sourcesContent":["import {\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ANCHORED_POPUP_GAP,\n ANCHORED_POPUP_Z_INDEX,\n computeAnchoredPopupFixedStyle,\n computeAnchoredPopupPlacement,\n getAnchoredPopupContainerFrame,\n type PopupPlacement,\n} from '@/utils/anchoredPopupPlacement';\n\nexport interface UseAnchoredPopupPortalOptions {\n /** Height used for the flip decision when content isn’t measured yet. */\n preferredHeight: number;\n /** Cap for scrollable menus (Select/Combobox). Omit for intrinsic panels. */\n maxHeightCap?: number;\n /** Ref to the portaled panel for measuring intrinsic height (DateRangePicker). */\n contentRef?: RefObject<HTMLElement | null>;\n /**\n * Portal mount node; defaults to `document.body` with viewport-fixed coords.\n * Custom containers must establish a positioning context (`position` other\n * than `static`); coords are converted to that container’s space.\n */\n portalContainer?: HTMLElement | null;\n zIndex?: number | string;\n /**\n * When true (default), fixed width matches the trigger.\n * DateRangePicker sets false and keeps its CSS width.\n */\n matchWidth?: boolean;\n gap?: number;\n}\n\nexport interface UseAnchoredPopupPortalResult {\n placement: PopupPlacement;\n maxHeight: number;\n style: CSSProperties;\n /** Ref for the portaled surface — pass to `useOutsideClose` as a second root. */\n portalRef: RefObject<HTMLDivElement | null>;\n /** Wraps children in a portal to `portalContainer` or `document.body`. */\n renderPortal: (children: ReactNode) => ReactNode;\n}\n\nconst DEFAULT_PLACEMENT: PopupPlacement = 'below';\n\nfunction resolvePortalMount(\n portalContainer: HTMLElement | null | undefined,\n): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n return portalContainer ?? document.body;\n}\n\nfunction usesViewportFixedCoords(mount: HTMLElement): boolean {\n return mount === document.body;\n}\n\n/**\n * Positions a form-widget popup in a portal with viewport-aware above/below flip.\n * Internal to compass-ui form widgets — not a general overlay positioning API.\n */\nexport function useAnchoredPopupPortal(\n anchorRef: RefObject<HTMLElement | null>,\n isOpen: boolean,\n options: UseAnchoredPopupPortalOptions,\n): UseAnchoredPopupPortalResult {\n const {\n preferredHeight,\n maxHeightCap,\n contentRef,\n portalContainer = null,\n zIndex = ANCHORED_POPUP_Z_INDEX,\n matchWidth = true,\n gap = ANCHORED_POPUP_GAP,\n } = options;\n\n const portalRef = useRef<HTMLDivElement | null>(null);\n const [placement, setPlacement] = useState<PopupPlacement>(DEFAULT_PLACEMENT);\n const [maxHeight, setMaxHeight] = useState(maxHeightCap ?? preferredHeight);\n const [style, setStyle] = useState<CSSProperties>({\n position: 'fixed',\n top: 0,\n left: 0,\n width: matchWidth ? 0 : undefined,\n zIndex,\n });\n\n const update = useCallback(() => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return;\n\n const rect = anchor.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportFixed = usesViewportFixedCoords(mount);\n const containerFrame = viewportFixed\n ? undefined\n : getAnchoredPopupContainerFrame(mount);\n\n const measured =\n contentRef?.current?.offsetHeight ?? portalRef.current?.offsetHeight ?? 0;\n const heightForFlip = measured > 0 ? measured : preferredHeight;\n\n const { placement: nextPlacement, maxHeight: nextMaxHeight } =\n computeAnchoredPopupPlacement(rect, viewportHeight, {\n gap,\n preferredHeight: heightForFlip,\n maxHeightCap,\n bounds: containerFrame?.bounds,\n });\n\n const fixed = computeAnchoredPopupFixedStyle(rect, nextPlacement, {\n gap,\n zIndex,\n width: matchWidth ? rect.width : undefined,\n viewportHeight,\n containerFrame,\n });\n\n setPlacement(nextPlacement);\n setMaxHeight(nextMaxHeight);\n setStyle({\n position: fixed.position,\n left: fixed.left,\n zIndex: fixed.zIndex,\n ...(matchWidth ? { width: fixed.width } : null),\n ...(nextPlacement === 'below'\n ? { top: fixed.top, bottom: 'auto' }\n : { bottom: fixed.bottom, top: 'auto' }),\n });\n }, [\n anchorRef,\n contentRef,\n gap,\n matchWidth,\n maxHeightCap,\n portalContainer,\n preferredHeight,\n zIndex,\n ]);\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n update();\n\n function handle() {\n update();\n }\n\n window.addEventListener('resize', handle);\n // Capture phase so nested scroll containers (modals, RHS) are covered.\n document.addEventListener('scroll', handle, true);\n return () => {\n window.removeEventListener('resize', handle);\n document.removeEventListener('scroll', handle, true);\n };\n }, [isOpen, update]);\n\n // Re-measure after content mounts / changes size (calendar, long lists).\n useLayoutEffect(() => {\n if (!isOpen) return;\n const el = contentRef?.current ?? portalRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n\n const ro = new ResizeObserver(() => update());\n ro.observe(el);\n return () => ro.disconnect();\n }, [isOpen, contentRef, update]);\n\n const renderPortal = useCallback(\n (children: ReactNode) => {\n const mount = resolvePortalMount(portalContainer);\n if (!mount) return null;\n return createPortal(children, mount);\n },\n [portalContainer],\n );\n\n return {\n placement,\n maxHeight,\n style,\n portalRef,\n renderPortal,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","resolvePortalMount","portalContainer","usesViewportFixedCoords","mount","useAnchoredPopupPortal","anchorRef","isOpen","options","preferredHeight","maxHeightCap","contentRef","zIndex","ANCHORED_POPUP_Z_INDEX","matchWidth","gap","ANCHORED_POPUP_GAP","portalRef","useRef","placement","setPlacement","useState","maxHeight","setMaxHeight","style","setStyle","update","useCallback","anchor","rect","viewportHeight","containerFrame","getAnchoredPopupContainerFrame","measured","_a","_b","heightForFlip","nextPlacement","nextMaxHeight","computeAnchoredPopupPlacement","fixed","computeAnchoredPopupFixedStyle","useLayoutEffect","handle","el","ro","renderPortal","children","createPortal"],"mappings":"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"}