@mortenbrudvik/waveui 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +362 -60
  2. package/dist/components/data-display/Avatar.cjs +1 -1
  3. package/dist/components/data-display/Avatar.cjs.map +1 -1
  4. package/dist/components/data-display/Avatar.colors.cjs +2 -0
  5. package/dist/components/data-display/Avatar.colors.cjs.map +1 -0
  6. package/dist/components/data-display/Avatar.colors.mjs +45 -0
  7. package/dist/components/data-display/Avatar.colors.mjs.map +1 -0
  8. package/dist/components/data-display/Avatar.context.cjs +1 -1
  9. package/dist/components/data-display/Avatar.context.cjs.map +1 -1
  10. package/dist/components/data-display/Avatar.context.mjs +4 -2
  11. package/dist/components/data-display/Avatar.context.mjs.map +1 -1
  12. package/dist/components/data-display/Avatar.mjs +103 -96
  13. package/dist/components/data-display/Avatar.mjs.map +1 -1
  14. package/dist/components/data-display/Avatar.sizes.cjs +2 -0
  15. package/dist/components/data-display/Avatar.sizes.cjs.map +1 -0
  16. package/dist/components/data-display/Avatar.sizes.mjs +41 -0
  17. package/dist/components/data-display/Avatar.sizes.mjs.map +1 -0
  18. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  19. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  20. package/dist/components/data-display/AvatarGroup.context.cjs +2 -0
  21. package/dist/components/data-display/AvatarGroup.context.cjs.map +1 -0
  22. package/dist/components/data-display/AvatarGroup.context.mjs +9 -0
  23. package/dist/components/data-display/AvatarGroup.context.mjs.map +1 -0
  24. package/dist/components/data-display/AvatarGroup.mjs +65 -122
  25. package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
  26. package/dist/components/data-display/AvatarGroup.partition.cjs +2 -0
  27. package/dist/components/data-display/AvatarGroup.partition.cjs.map +1 -0
  28. package/dist/components/data-display/AvatarGroup.partition.mjs +14 -0
  29. package/dist/components/data-display/AvatarGroup.partition.mjs.map +1 -0
  30. package/dist/components/data-display/AvatarGroup.parts.cjs +2 -0
  31. package/dist/components/data-display/AvatarGroup.parts.cjs.map +1 -0
  32. package/dist/components/data-display/AvatarGroup.parts.mjs +178 -0
  33. package/dist/components/data-display/AvatarGroup.parts.mjs.map +1 -0
  34. package/dist/components/data-display/InteractionTag.cjs +1 -1
  35. package/dist/components/data-display/InteractionTag.cjs.map +1 -1
  36. package/dist/components/data-display/InteractionTag.mjs +36 -33
  37. package/dist/components/data-display/InteractionTag.mjs.map +1 -1
  38. package/dist/components/data-display/List.cjs +1 -1
  39. package/dist/components/data-display/List.cjs.map +1 -1
  40. package/dist/components/data-display/List.mjs +245 -195
  41. package/dist/components/data-display/List.mjs.map +1 -1
  42. package/dist/components/data-display/List.registry.cjs.map +1 -1
  43. package/dist/components/data-display/List.registry.mjs.map +1 -1
  44. package/dist/components/data-display/Persona.cjs +1 -1
  45. package/dist/components/data-display/Persona.cjs.map +1 -1
  46. package/dist/components/data-display/Persona.mjs +96 -37
  47. package/dist/components/data-display/Persona.mjs.map +1 -1
  48. package/dist/components/data-display/PresenceBadge.cjs +1 -1
  49. package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
  50. package/dist/components/data-display/PresenceBadge.mjs +42 -28
  51. package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
  52. package/dist/components/data-display/Tag.cjs +1 -1
  53. package/dist/components/data-display/Tag.cjs.map +1 -1
  54. package/dist/components/data-display/Tag.mjs +111 -108
  55. package/dist/components/data-display/Tag.mjs.map +1 -1
  56. package/dist/components/layout/Card.cjs +1 -1
  57. package/dist/components/layout/Card.cjs.map +1 -1
  58. package/dist/components/layout/Card.context.cjs +2 -0
  59. package/dist/components/layout/Card.context.cjs.map +1 -0
  60. package/dist/components/layout/Card.context.mjs +14 -0
  61. package/dist/components/layout/Card.context.mjs.map +1 -0
  62. package/dist/components/layout/Card.mjs +138 -92
  63. package/dist/components/layout/Card.mjs.map +1 -1
  64. package/dist/components/layout/Card.preview.cjs +2 -0
  65. package/dist/components/layout/Card.preview.cjs.map +1 -0
  66. package/dist/components/layout/Card.preview.mjs +22 -0
  67. package/dist/components/layout/Card.preview.mjs.map +1 -0
  68. package/dist/components/layout/Carousel.button.cjs +2 -0
  69. package/dist/components/layout/Carousel.button.cjs.map +1 -0
  70. package/dist/components/layout/Carousel.button.mjs +34 -0
  71. package/dist/components/layout/Carousel.button.mjs.map +1 -0
  72. package/dist/components/layout/Carousel.cjs +1 -1
  73. package/dist/components/layout/Carousel.cjs.map +1 -1
  74. package/dist/components/layout/Carousel.context.cjs +2 -0
  75. package/dist/components/layout/Carousel.context.cjs.map +1 -0
  76. package/dist/components/layout/Carousel.context.mjs +24 -0
  77. package/dist/components/layout/Carousel.context.mjs.map +1 -0
  78. package/dist/components/layout/Carousel.drag.cjs +2 -0
  79. package/dist/components/layout/Carousel.drag.cjs.map +1 -0
  80. package/dist/components/layout/Carousel.drag.mjs +79 -0
  81. package/dist/components/layout/Carousel.drag.mjs.map +1 -0
  82. package/dist/components/layout/Carousel.groups.cjs +2 -0
  83. package/dist/components/layout/Carousel.groups.cjs.map +1 -0
  84. package/dist/components/layout/Carousel.groups.mjs +23 -0
  85. package/dist/components/layout/Carousel.groups.mjs.map +1 -0
  86. package/dist/components/layout/Carousel.mjs +288 -150
  87. package/dist/components/layout/Carousel.mjs.map +1 -1
  88. package/dist/components/layout/Carousel.styles.cjs +2 -0
  89. package/dist/components/layout/Carousel.styles.cjs.map +1 -0
  90. package/dist/components/layout/Carousel.styles.mjs +30 -0
  91. package/dist/components/layout/Carousel.styles.mjs.map +1 -0
  92. package/dist/components/layout/Overflow.cjs +1 -1
  93. package/dist/components/layout/Overflow.cjs.map +1 -1
  94. package/dist/components/layout/Overflow.mjs +240 -192
  95. package/dist/components/layout/Overflow.mjs.map +1 -1
  96. package/dist/components/layout/Overflow.store.cjs +2 -0
  97. package/dist/components/layout/Overflow.store.cjs.map +1 -0
  98. package/dist/components/layout/Overflow.store.mjs +209 -0
  99. package/dist/components/layout/Overflow.store.mjs.map +1 -0
  100. package/dist/components/layout/TabList.cjs +1 -1
  101. package/dist/components/layout/TabList.cjs.map +1 -1
  102. package/dist/components/layout/TabList.mjs +163 -124
  103. package/dist/components/layout/TabList.mjs.map +1 -1
  104. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  105. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  106. package/dist/components/navigation/Breadcrumb.mjs +239 -84
  107. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  108. package/dist/components/overlays/Dialog.slots.cjs +1 -1
  109. package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
  110. package/dist/components/overlays/Dialog.slots.mjs +19 -15
  111. package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
  112. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  113. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  114. package/dist/components/overlays/TeachingPopover.context.cjs +2 -0
  115. package/dist/components/overlays/TeachingPopover.context.cjs.map +1 -0
  116. package/dist/components/overlays/TeachingPopover.context.mjs +51 -0
  117. package/dist/components/overlays/TeachingPopover.context.mjs.map +1 -0
  118. package/dist/components/overlays/TeachingPopover.mjs +15 -185
  119. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  120. package/dist/components/overlays/TeachingPopover.parts.cjs +2 -0
  121. package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -0
  122. package/dist/components/overlays/TeachingPopover.parts.mjs +398 -0
  123. package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -0
  124. package/dist/components/overlays/TeachingPopover.root.cjs +2 -0
  125. package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -0
  126. package/dist/components/overlays/TeachingPopover.root.mjs +150 -0
  127. package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -0
  128. package/dist/components/overlays/TeachingPopover.stack.cjs +2 -0
  129. package/dist/components/overlays/TeachingPopover.stack.cjs.map +1 -0
  130. package/dist/components/overlays/TeachingPopover.stack.mjs +86 -0
  131. package/dist/components/overlays/TeachingPopover.stack.mjs.map +1 -0
  132. package/dist/components/table/DataGrid.cjs +1 -1
  133. package/dist/components/table/DataGrid.cjs.map +1 -1
  134. package/dist/components/table/DataGrid.mjs +540 -311
  135. package/dist/components/table/DataGrid.mjs.map +1 -1
  136. package/dist/components/table/Table.cjs +1 -1
  137. package/dist/components/table/Table.cjs.map +1 -1
  138. package/dist/components/table/Table.mjs +183 -60
  139. package/dist/components/table/Table.mjs.map +1 -1
  140. package/dist/components/table/Table.shared.cjs +2 -0
  141. package/dist/components/table/Table.shared.cjs.map +1 -0
  142. package/dist/components/table/Table.shared.mjs +65 -0
  143. package/dist/components/table/Table.shared.mjs.map +1 -0
  144. package/dist/index.cjs +1 -1
  145. package/dist/index.d.cts +2299 -213
  146. package/dist/index.d.ts +2299 -213
  147. package/dist/index.mjs +135 -127
  148. package/dist/lib/breadcrumb.cjs +2 -0
  149. package/dist/lib/breadcrumb.cjs.map +1 -0
  150. package/dist/lib/breadcrumb.mjs +26 -0
  151. package/dist/lib/breadcrumb.mjs.map +1 -0
  152. package/dist/lib/classNames.cjs +1 -1
  153. package/dist/lib/classNames.cjs.map +1 -1
  154. package/dist/lib/classNames.mjs +143 -95
  155. package/dist/lib/classNames.mjs.map +1 -1
  156. package/dist/lib/events.cjs +1 -1
  157. package/dist/lib/events.cjs.map +1 -1
  158. package/dist/lib/events.mjs +35 -8
  159. package/dist/lib/events.mjs.map +1 -1
  160. package/dist/lib/icons.cjs +1 -1
  161. package/dist/lib/icons.cjs.map +1 -1
  162. package/dist/lib/icons.mjs +34 -20
  163. package/dist/lib/icons.mjs.map +1 -1
  164. package/dist/lib/initials.cjs +2 -0
  165. package/dist/lib/initials.cjs.map +1 -0
  166. package/dist/lib/initials.mjs +21 -0
  167. package/dist/lib/initials.mjs.map +1 -0
  168. package/dist/lib/table.cjs +2 -0
  169. package/dist/lib/table.cjs.map +1 -0
  170. package/dist/lib/table.mjs +16 -0
  171. package/dist/lib/table.mjs.map +1 -0
  172. package/dist/styles.css +1 -1
  173. package/package.json +1 -1
  174. package/src/styles/tokens.css +102 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroup.mjs","names":["useId","useId$1","React","DEFAULT_UNNAMED_MEMBER_LABEL","nonBlank","value","getMemberName","member","isElementOfType","Avatar","label","labelledBy","decorative","name","rendersUnnamed","imageProps","image","AvatarGroup","ariaLabel","ariaLabelledBy","props","items","flattenChildren","children","limit","max","visible","hidden","overflow","unnamed","warnOnce","popupId","open","setOpen","isOpen","overflowLabel","parentLayerId","DismissLayerContext","triggerRef","surfaceRef","surface","setSurface","usePopupPosition","useDismiss","triggerRefs","useMergedRefs","setReference","surfaceRefs","setFloating","handleSurfaceKeyDown","trigger","event","popup","origin","inner","getTabbableElements","next","el","target","order","index","isInsideLayerTree","hasUnnamedMember","node","unnamedMemberLabel","cn","avatarGroupClassNames","className","i","key","avatarSizeClasses","size","Portal","floatingProps"],"sources":["../../../src/components/data-display/AvatarGroup.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { avatarGroupClassNames } from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { getTabbableElements } from '../../lib/focus';\nimport { isInsideLayerTree } from '../../lib/layers';\nimport { focusRing } from '../../lib/styles';\nimport type { Size } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { DismissLayerContext, useDismiss } from '../../hooks/useDismiss';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { Portal } from '../portal/Portal';\nimport { Avatar, avatarSizeClasses } from './Avatar';\nimport type { AvatarProps } from './Avatar';\n\n/** Properties for the AvatarGroup component. */\nexport interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Maximum number of avatars to display. The others are replaced by an overflow button that\n * lists their names. `0` or a negative value shows only the overflow button, a fraction is\n * rounded down, and `NaN` shows every member (as without `max`). The members of a Fragment\n * count one by one.\n */\n max?: number;\n /** Size of the overflow button (match it to the avatars).\n * @default 'medium'\n */\n size?: Size;\n /**\n * Accessible name of the overflow button (and its popup). A function receives the number of\n * hidden members. Localise it here.\n * @default (count) => `${count} more`\n */\n overflowLabel?: string | ((count: number) => string);\n /**\n * Text listed in the overflow popup for a hidden member that has no accessible name (an\n * `Avatar` without `name`, `aria-label`, `aria-labelledby` or image `alt`, or blank text).\n * Localise it here; better still, give every member a name (a development warning asks for it).\n * @default 'Unnamed member'\n */\n unnamedMemberLabel?: string;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Default text listed for a hidden member that would render with no accessible name. */\nconst DEFAULT_UNNAMED_MEMBER_LABEL = 'Unnamed member';\n\nconst nonBlank = (value: unknown): value is string =>\n typeof value === 'string' && value.trim() !== '';\n\n/**\n * The text name of a member for the overflow list: the text of a text member, or the accessible\n * name of an `Avatar` given by its props (`aria-label` before `name`). An `Avatar` labelled by\n * `aria-labelledby` (unless `decorative`) and every other element have none: they are rendered as\n * they are, so a link keeps working and keeps its own label.\n */\nfunction getMemberName(member: React.ReactNode): string | undefined {\n if (typeof member === 'string' || typeof member === 'number') {\n return String(member).trim() || undefined;\n }\n if (!isElementOfType<AvatarProps>(member, Avatar)) return undefined;\n const { decorative, name, 'aria-label': label, 'aria-labelledby': labelledBy } = member.props;\n if (!decorative && nonBlank(labelledBy)) return undefined;\n for (const value of [label, name]) {\n if (nonBlank(value)) return value.trim();\n }\n return undefined;\n}\n\n/**\n * Whether a member without a {@link getMemberName} name would render with no accessible name,\n * so its list item would be empty for assistive technology: blank text, or an `Avatar` that is\n * neither labelled by `aria-labelledby` nor named by its image's `alt` (or is `decorative`).\n * Other elements are rendered as they are, since their content is unknown here.\n */\nfunction rendersUnnamed(member: React.ReactNode): boolean {\n if (typeof member === 'string' || typeof member === 'number') return true;\n if (!isElementOfType<AvatarProps>(member, Avatar)) return false;\n const { decorative, image, 'aria-labelledby': labelledBy } = member.props;\n if (decorative) return true;\n if (nonBlank(labelledBy)) return false;\n const imageProps: unknown = React.isValidElement(image) ? image.props : image;\n const alt =\n typeof imageProps === 'object' && imageProps !== null && 'alt' in imageProps\n ? imageProps.alt\n : undefined;\n return !nonBlank(alt);\n}\n\n/**\n * A row of overlapping avatars (`role=\"group\"`; name it with `aria-label`).\n *\n * With `max`, the avatars beyond the limit are replaced by an overflow `<button>` (\"+3\", named\n * \"3 more\", see `overflowLabel`). It toggles a popup that lists the hidden members' names: an\n * `Avatar` by its `aria-label` or `name` prop, text as it is. Other members, such as an `Avatar`\n * inside a link or one labelled by `aria-labelledby`, are rendered as they are, and an `Avatar` or\n * text with no accessible name is listed as `unnamedMemberLabel` with a development warning.\n * Focus moves into the popup; Escape, a press outside or the button close it and focus returns to\n * the button. Tab and Shift+Tab move through the popup's own tab stops (links in rendered\n * members); Tab from the last one closes the popup and moves on to the element after the button,\n * Shift+Tab from the first one closes it and returns to the button. When the button is the last\n * tab stop (of the page, or of the Wave layer the group is in, such as a dialog), Tab is left to\n * the browser or the enclosing focus trap.\n *\n * @example\n * <AvatarGroup aria-label=\"Project team\" max={3}>\n * <Avatar name=\"Ada Lovelace\" />\n * <Avatar name=\"Alan Turing\" />\n * </AvatarGroup>\n */\nexport const AvatarGroup = ({\n max,\n size = 'medium',\n overflowLabel,\n unnamedMemberLabel = DEFAULT_UNNAMED_MEMBER_LABEL,\n className,\n children,\n ref,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n}: AvatarGroupProps) => {\n // Fragments are flattened, so each member counts, overlaps and is listed on its own (C-COMPOUND).\n const items = flattenChildren(children);\n const limit = max === undefined || Number.isNaN(max) ? Infinity : Math.max(0, Math.floor(max));\n const visible = items.slice(0, limit);\n const hidden = items.slice(visible.length);\n const overflow = hidden.length;\n\n const unnamed = ariaLabel === undefined && ariaLabelledBy === undefined;\n React.useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'AvatarGroup:unnamed',\n 'AvatarGroup: the group has no accessible name. Pass `aria-label` (or `aria-labelledby`) describing the people it shows.',\n );\n }\n }, [unnamed]);\n\n const popupId = useId('avatar-group-overflow');\n const [open, setOpen] = React.useState(false);\n // Nothing is hidden any more: close, so the popup does not reappear when members overflow again.\n if (open && overflow === 0) setOpen(false);\n const isOpen = open && overflow > 0;\n const label =\n typeof overflowLabel === 'function'\n ? overflowLabel(overflow)\n : (overflowLabel ?? `${overflow} more`);\n\n // The layer the group is rendered in (a dialog or popover), if any: the popup's parent layer.\n const parentLayerId = React.useContext(DismissLayerContext);\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: isOpen,\n side: 'bottom',\n align: 'start',\n });\n const { layerId } = useDismiss({\n open: isOpen,\n onDismiss: () => setOpen(false),\n refs: [triggerRef, surfaceRef],\n anchorRef: triggerRef,\n focusOutside: true,\n });\n useRestoreFocus({ enabled: isOpen, container: surface, triggerRef, onlyIfFocusInside: true });\n const triggerRefs = useMergedRefs<HTMLButtonElement>(triggerRef, setReference);\n const surfaceRefs = useMergedRefs<HTMLDivElement>(surfaceRef, setFloating, setSurface);\n\n // Move focus into the popup once it is mounted, so its list is read next.\n React.useEffect(() => {\n if (isOpen && surface) surface.focus({ preventScroll: true });\n }, [isOpen, surface]);\n\n // The popup is portaled, so native tabbing would leave it for the end of the page. Tab moves\n // through the popup's own tab stops (a rendered member can be a link); leaving the last one\n // closes the popup and moves on from the button instead (Shift+Tab before the first one: back to\n // the button), like a focus trap does for a popup anchored in a dialog. When nothing tabbable\n // follows the button, Tab is not prevented: focus returns to the button as the popup closes and\n // the browser (leaving the page) or an enclosing focus trap (wrapping) takes it from there.\n // Inside a parent layer (a dialog, a popover), a tab stop after the button that lies outside that\n // layer is treated the same way: a focus trap that leaves the page outside it interactive would\n // pull focus back from there, while its descendant-layer rule (§2.4) wraps from the button.\n // Tab stops are computed at keydown time, never cached (§2.2 focus utilities). A key that\n // bubbles through React from a portal a member opened is not the popup's: it is ignored.\n const handleSurfaceKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const trigger = triggerRef.current;\n if (event.key !== 'Tab' || event.defaultPrevented || !trigger) return;\n const popup = event.currentTarget;\n // Duck typed (`nodeType`), not `instanceof Node`: a popup portaled into another document (an\n // iframe, a popout window) holds nodes of that realm.\n const origin = event.target as Partial<Node> | null;\n if (!origin || typeof origin.nodeType !== 'number' || !popup.contains(origin as Node)) return;\n const inner = getTabbableElements(popup);\n // -1 while focus is on the popup itself (or on something that is not a tab stop).\n const current = inner.findIndex((el) => el.contains(origin as Node));\n const next = current + (event.shiftKey ? -1 : 1);\n if (next >= 0 && next < inner.length) {\n event.preventDefault();\n inner[next]!.focus();\n return;\n }\n let target: HTMLElement | undefined = trigger;\n if (!event.shiftKey) {\n const order = getTabbableElements(trigger.ownerDocument.body).filter(\n (el) => !popup.contains(el),\n );\n const index = order.indexOf(trigger);\n target = index === -1 ? trigger : order[index + 1];\n if (target && parentLayerId !== null && !isInsideLayerTree(parentLayerId, target)) {\n target = undefined;\n }\n }\n setOpen(false);\n if (!target) return;\n event.preventDefault();\n target.focus();\n };\n\n const hasUnnamedMember =\n isOpen && hidden.some(({ node }) => getMemberName(node) === undefined && rendersUnnamed(node));\n React.useEffect(() => {\n if (hasUnnamedMember) {\n warnOnce(\n 'AvatarGroup:unnamed-member',\n `AvatarGroup: a hidden member has no accessible name and is listed as \"${unnamedMemberLabel}\". Give each member a \\`name\\` or \\`aria-label\\`.`,\n );\n }\n }, [hasUnnamedMember, unnamedMemberLabel]);\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n {...props}\n className={cn(avatarGroupClassNames.root, 'inline-flex items-center', className)}\n >\n {visible.map(({ key, node }, i) => (\n <span\n key={key}\n className={cn(\n avatarGroupClassNames.item,\n 'inline-flex rounded-full ring-2 ring-background',\n i > 0 && '-ms-2',\n )}\n >\n {node}\n </span>\n ))}\n {overflow > 0 && (\n <button\n ref={triggerRefs}\n type=\"button\"\n aria-label={label}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? popupId : undefined}\n className={cn(\n avatarGroupClassNames.overflowButton,\n 'inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full border-0 p-0 font-semibold',\n 'bg-muted text-muted-foreground ring-2 ring-background',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-pressed',\n focusRing,\n visible.length > 0 && '-ms-2',\n avatarSizeClasses[size],\n )}\n onClick={() => setOpen((value) => !value)}\n >\n +{overflow}\n </button>\n )}\n {isOpen && (\n <Portal layerId={layerId}>\n <div\n ref={surfaceRefs}\n id={popupId}\n role=\"dialog\"\n aria-label={label}\n tabIndex={-1}\n data-state=\"open\"\n {...floatingProps}\n className={cn(\n avatarGroupClassNames.surface,\n 'min-w-32 max-w-xs rounded-md border border-border bg-background p-2 text-body-1 text-foreground shadow-16',\n focusRing,\n )}\n onKeyDown={handleSurfaceKeyDown}\n >\n <ul className={cn(avatarGroupClassNames.list, 'm-0 flex list-none flex-col gap-1 p-0')}>\n {hidden.map(({ key, node }) => (\n <li key={key} className={cn(avatarGroupClassNames.listItem, 'px-1 py-0.5')}>\n {getMemberName(node) ?? (rendersUnnamed(node) ? unnamedMemberLabel : node)}\n </li>\n ))}\n </ul>\n </div>\n </Portal>\n )}\n </div>\n );\n};\n\nAvatarGroup.displayName = 'AvatarGroup';\n"],"mappings":"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"}
1
+ {"version":3,"file":"AvatarGroup.mjs","names":["React","pieWedgeClasses","AvatarGroupRoot","DEFAULT_UNNAMED_MEMBER_LABEL","ariaLabel","ariaLabelledBy","props","parts","flattenChildren","children","customPopover","isElementOfType","node","AvatarGroupPopover","items","resolvedSize","size","layout","visible","partitionAvatarGroupItems","max","hidden","overflowItems","hasInlineItems","groupContext","unnamed","warnOnce","cn","avatarGroupClassNames","className","AvatarGroupContext","avatarSizeClassesFor","i","key","overflowIndicator","overflowLabel","AvatarGroup","AvatarGroupItem"],"sources":["../../../src/components/data-display/AvatarGroup.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { avatarGroupClassNames } from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { avatarSizeClassesFor, type AvatarSize } from './Avatar.sizes';\nimport { AvatarGroupContext } from './AvatarGroup.context';\nimport { partitionAvatarGroupItems, type AvatarGroupLayout } from './AvatarGroup.partition';\nimport {\n AvatarGroupItem,\n AvatarGroupPopover,\n DEFAULT_UNNAMED_MEMBER_LABEL,\n type AvatarGroupItemProps,\n type AvatarGroupOpenChangeDetails,\n type AvatarGroupPopoverProps,\n} from './AvatarGroup.parts';\n\nexport { AvatarGroupItem, AvatarGroupPopover };\nexport type { AvatarGroupItemProps, AvatarGroupOpenChangeDetails, AvatarGroupPopoverProps };\nexport type { AvatarGroupLayout };\n\n/** Properties for the AvatarGroup component. */\nexport interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Maximum number of avatars to display. The others are replaced by an overflow button that\n * lists their names. `0` or a negative value shows only the overflow button, a fraction is\n * rounded down, and `NaN` shows every member (as without `max`). The members of a Fragment\n * count one by one. A `pie` shows at most three.\n */\n max?: number;\n /**\n * Size of the avatars. It reaches the members that set no `size` of their own, and the overflow\n * button.\n * @default 'medium' ('large' in a `pie`)\n */\n size?: AvatarSize;\n /**\n * How the members are laid out: `stack` overlaps them, `spread` puts them side by side, `pie`\n * draws up to three of them as the wedges of one circle (the group's name is then the only name).\n * @default 'stack'\n */\n layout?: AvatarGroupLayout;\n /**\n * What the overflow button shows: the number of hidden members (`+3`, capped at `99+`), or an\n * icon.\n * @default 'count'\n */\n overflowIndicator?: 'count' | 'icon';\n /**\n * Accessible name of the overflow button (and its popup). A function receives the number of\n * hidden members. Localise it here.\n * @default (count) => `${count} more`\n */\n overflowLabel?: string | ((count: number) => string);\n /**\n * Text listed in the overflow popup for a hidden member that has no accessible name (an\n * `Avatar` without `name`, `aria-label`, `aria-labelledby` or image `alt`, or blank text).\n * Localise it here; better still, give every member a name (a development warning asks for it).\n * @default 'Unnamed member'\n */\n unnamedMemberLabel?: string;\n /** Whether the overflow popup is open (controlled). */\n open?: boolean;\n /**\n * Whether the overflow popup starts open (uncontrolled).\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called when the overflow popup asks to open or close, with the reason: `trigger` (the button),\n * `escape`, `outside-press` or `focus-outside`.\n */\n onOpenChange?: (open: boolean, details?: AvatarGroupOpenChangeDetails) => void;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The clip of each wedge of a pie, by the number of wedges (one wedge is a full circle). Literal strings only. */\nconst pieWedgeClasses: ReadonlyArray<ReadonlyArray<string>> = [\n [''],\n ['[clip-path:inset(0_50%_0_0)]', '[clip-path:inset(0_0_0_50%)]'],\n [\n '[clip-path:inset(0_50%_0_0)]',\n '[clip-path:inset(0_0_50%_50%)]',\n '[clip-path:inset(50%_0_0_50%)]',\n ],\n];\n\nconst AvatarGroupRoot = ({\n max,\n size,\n layout = 'stack',\n overflowIndicator = 'count',\n overflowLabel,\n unnamedMemberLabel = DEFAULT_UNNAMED_MEMBER_LABEL,\n open,\n defaultOpen,\n onOpenChange,\n className,\n children,\n ref,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n}: AvatarGroupProps) => {\n // Fragments are flattened, so each member counts, overlaps and is listed on its own (C-COMPOUND).\n // A consumer-written AvatarGroup.Popover is the overflow part, not a member.\n const parts = flattenChildren(children);\n const customPopover = parts.find(({ node }) => isElementOfType(node, AvatarGroupPopover));\n const items = parts.filter(({ node }) => !isElementOfType(node, AvatarGroupPopover));\n const resolvedSize: AvatarSize = size ?? (layout === 'pie' ? 'large' : 'medium');\n const { inlineItems: visible, overflowItems } = partitionAvatarGroupItems({\n items,\n maxInlineItems: max,\n layout,\n });\n const hidden = overflowItems ?? [];\n const hasInlineItems = visible.length > 0;\n const groupContext = React.useMemo(\n () => ({ size: resolvedSize, layout, hasInlineItems }),\n [resolvedSize, layout, hasInlineItems],\n );\n\n const unnamed = ariaLabel === undefined && ariaLabelledBy === undefined;\n React.useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'AvatarGroup:unnamed',\n 'AvatarGroup: the group has no accessible name. Pass `aria-label` (or `aria-labelledby`) describing the people it shows.',\n );\n }\n }, [unnamed]);\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-layout={layout}\n {...props}\n className={cn(\n avatarGroupClassNames.root,\n 'inline-flex items-center',\n layout !== 'stack' && 'gap-1',\n className,\n )}\n >\n <AvatarGroupContext.Provider value={groupContext}>\n {layout === 'pie'\n ? visible.length > 0 && (\n <span\n className={cn(\n avatarGroupClassNames.pie,\n 'relative inline-block shrink-0 overflow-hidden rounded-full',\n avatarSizeClassesFor(resolvedSize),\n )}\n >\n {visible.map(({ key, node }, i) => (\n <span\n key={key}\n aria-hidden=\"true\"\n className={cn(\n avatarGroupClassNames.item,\n 'absolute inset-0 inline-flex',\n pieWedgeClasses[visible.length - 1]?.[i],\n )}\n >\n {node}\n </span>\n ))}\n </span>\n )\n : visible.map(({ key, node }, i) => (\n <span\n key={key}\n className={cn(\n avatarGroupClassNames.item,\n 'inline-flex rounded-full ring-2 ring-background',\n layout === 'stack' && i > 0 && '-ms-2',\n )}\n >\n {node}\n </span>\n ))}\n {customPopover\n ? customPopover.node\n : hidden.length > 0 && (\n <AvatarGroupPopover\n count={hidden.length}\n indicator={overflowIndicator}\n label={overflowLabel}\n unnamedMemberLabel={unnamedMemberLabel}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n >\n {hidden.map(({ key, node }) => (\n <React.Fragment key={key}>{node}</React.Fragment>\n ))}\n </AvatarGroupPopover>\n )}\n </AvatarGroupContext.Provider>\n </div>\n );\n};\n\nAvatarGroupRoot.displayName = 'AvatarGroup';\n\n/**\n * A row of avatars (`role=\"group\"`; name it with `aria-label`), laid out as a `stack` (overlapping),\n * `spread` or `pie` (`layout`). `size` reaches the members.\n *\n * With `max`, the avatars beyond the limit are replaced by an overflow `<button>` (\"+3\", named\n * \"3 more\", see `overflowLabel`; `overflowIndicator=\"icon\"` shows an icon, and a count above 99\n * reads \"99+\"). It toggles a popup that lists the hidden members: an `AvatarGroup.Item` as a row\n * with its avatar and name, an `Avatar` by its `aria-label` or `name` prop, text as it is. Other\n * members, such as an `Avatar` inside a link or one labelled by `aria-labelledby`, are rendered as\n * they are, and an `Avatar` or text with no accessible name is listed as `unnamedMemberLabel` with\n * a development warning. Focus moves into the popup; Escape, a press outside or the button close\n * it and focus returns to the button (`open`, `defaultOpen` and `onOpenChange(open, details)`\n * control it). Tab and Shift+Tab move through the popup's own tab stops (links in rendered\n * members); Tab from the last one closes the popup and moves on to the element after the button,\n * Shift+Tab from the first one closes it and returns to the button. When the button is the last\n * tab stop (of the page, or of the Wave layer the group is in, such as a dialog), Tab is left to\n * the browser or the enclosing focus trap.\n *\n * To split the members yourself, render `AvatarGroup.Item`s and an `AvatarGroup.Popover` holding\n * the overflow items (see `partitionAvatarGroupItems`).\n *\n * @example\n * <AvatarGroup aria-label=\"Project team\" max={3}>\n * <AvatarGroup.Item name=\"Ada Lovelace\" />\n * <AvatarGroup.Item name=\"Alan Turing\" />\n * </AvatarGroup>\n */\nexport const AvatarGroup = /* @__PURE__ */ Object.assign(AvatarGroupRoot, {\n Item: AvatarGroupItem,\n Popover: AvatarGroupPopover,\n});\n"],"mappings":";;;;;;;;;;;;AA8EA,IAAMC,IAAwD;CAC5D,CAAC,EAAE;CACH,CAAC,gCAAgC,8BAA8B;CAC/D;EACE;EACA;EACA;CACF;AACF,GAEMC,KAAmB,EACvB,QACA,SACA,YAAS,SACT,uBAAoB,SACpB,kBACA,wBAAqBC,GACrB,SACA,gBACA,iBACA,cACA,aACA,QACA,cAAcC,GACd,mBAAmBC,GACnB,GAAGC,QACmB;CAGtB,IAAMC,IAAQC,EAAgBC,CAAQ,GAChCC,IAAgBH,EAAM,MAAM,EAAE,cAAWI,EAAgBC,GAAMC,CAAkB,CAAC,GAClFC,IAAQP,EAAM,QAAQ,EAAE,cAAW,CAACI,EAAgBC,GAAMC,CAAkB,CAAC,GAC7EE,IAA2BC,MAASC,MAAW,QAAQ,UAAU,WACjE,EAAE,aAAaC,GAAS,qBAAkBC,EAA0B;EACxE;EACA,gBAAgBC;EAChB;CACF,CAAC,GACKC,IAASC,KAAiB,CAAC,GAC3BC,IAAiBL,EAAQ,SAAS,GAClCM,IAAexB,EAAM,eAClB;EAAE,MAAMe;EAAc;EAAQ;CAAe,IACpD;EAACA;EAAcE;EAAQM;CAAc,CACvC,GAEME,IAAUrB,MAAc,KAAA,KAAaC,MAAmB,KAAA;CAU9D,OATAL,EAAM,gBAAgB;EACpB,AAAIyB,KACFC,EACE,uBACA,yHACF;CAEJ,GAAG,CAACD,CAAO,CAAC,GAGV,kBAAC,OAAD;EACO;EACL,MAAK;EACL,cAAYrB;EACZ,mBAAiBC;EACjB,eAAaY;EACb,GAAIX;EACJ,WAAWqB,EACTC,EAAsB,MACtB,4BACAX,MAAW,WAAW,SACtBY,CACF;EAEA,UAAA,kBAACC,EAAmB,UAApB;GAA6B,OAAON;GAApC,UAAA,CACGP,MAAW,QACRC,EAAQ,SAAS,KACf,kBAAC,QAAD;IACE,WAAWS,EACTC,EAAsB,KACtB,+DACAG,EAAqBhB,CAAY,CACnC;IAEC,UAAAG,EAAQ,KAAK,EAAE,QAAK,WAAQ,MAC3B,kBAAC,QAAD;KAEE,eAAY;KACZ,WAAWS,EACTC,EAAsB,MACtB,gCACA3B,EAAgBiB,EAAQ,SAAS,EAAE,GAAGc,EACxC;KAEC,UAAApB;IACG,GATCqB,CASD,CACP;GACG,CAAA,IAERf,EAAQ,KAAK,EAAE,QAAK,WAAQ,MAC1B,kBAAC,QAAD;IAEE,WAAWS,EACTC,EAAsB,MACtB,mDACAX,MAAW,WAAWe,IAAI,KAAK,OACjC;IAEC,UAAApB;GACG,GARCqB,CAQD,CACP,GACJvB,IACGA,EAAc,OACdW,EAAO,SAAS,KACd,kBAACR,GAAD;IACE,OAAOQ,EAAO;IACd,WAAWa;IACX,OAAOC;IACa;IACd;IACO;IACC;IAEb,UAAAd,EAAO,KAAK,EAAE,QAAK,cAClB,kBAACrB,EAAM,UAAP,EAAA,UAA2BY,EAAqB,GAA3BqB,CAA2B,CACjD;GACiB,CAAA,CAEC;;CAC1B,CAAA;AAET;AAEA,EAAgB,cAAc;AA6B9B,IAAaG,IAA8B,uBAAO,OAAOlC,GAAiB;CACxE,MAAMmC;CACN,SAASxB;AACX,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use client";function e({items:e,maxInlineItems:t,layout:n=`stack`}){let r=t===void 0||Number.isNaN(t)?1/0:Math.max(0,Math.floor(t));n===`pie`&&(r=Math.min(r,3));let i=e.slice(0,r);return{inlineItems:i,overflowItems:e.length>i.length?e.slice(i.length):void 0}}exports.partitionAvatarGroupItems=e;
2
+ //# sourceMappingURL=AvatarGroup.partition.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.partition.cjs","names":["partitionAvatarGroupItems","limit","maxInlineItems","layout","inlineItems","items"],"sources":["../../../src/components/data-display/AvatarGroup.partition.ts"],"sourcesContent":["/** The layouts of an AvatarGroup. */\nexport type AvatarGroupLayout = 'stack' | 'spread' | 'pie';\n\n/** Options of {@link partitionAvatarGroupItems}. */\nexport interface PartitionAvatarGroupItemsOptions<T> {\n /** All the items of the group. */\n items: readonly T[];\n /**\n * How many items are shown inline; the rest go to the overflow. A fraction is rounded down, `0`\n * or a negative value shows none, and `undefined` or `NaN` shows all (up to the layout's cap).\n */\n maxInlineItems?: number;\n /**\n * The layout of the group. A `pie` shows at most three items inline.\n * @default 'stack'\n */\n layout?: AvatarGroupLayout;\n}\n\n/** Result of {@link partitionAvatarGroupItems}. */\nexport interface PartitionAvatarGroupItemsResult<T> {\n /** The items shown inline, in order. */\n inlineItems: T[];\n /** The items in the overflow list, in order; `undefined` when nothing overflows. */\n overflowItems: T[] | undefined;\n}\n\n/** The most items a pie shows inline. */\nconst PIE_INLINE_LIMIT = 3;\n\n/**\n * Splits the items of an AvatarGroup into the ones shown inline and the ones in the overflow list.\n * `AvatarGroup` uses it for `max`; use it yourself to render `AvatarGroup.Item`s and\n * `AvatarGroup.Popover` from your own list. Server-safe: it imports nothing.\n *\n * @example\n * const { inlineItems, overflowItems } = partitionAvatarGroupItems({ items: people, maxInlineItems: 4 });\n */\nexport function partitionAvatarGroupItems<T>({\n items,\n maxInlineItems,\n layout = 'stack',\n}: PartitionAvatarGroupItemsOptions<T>): PartitionAvatarGroupItemsResult<T> {\n let limit =\n maxInlineItems === undefined || Number.isNaN(maxInlineItems)\n ? Infinity\n : Math.max(0, Math.floor(maxInlineItems));\n if (layout === 'pie') limit = Math.min(limit, PIE_INLINE_LIMIT);\n const inlineItems = items.slice(0, limit);\n return {\n inlineItems,\n overflowItems: items.length > inlineItems.length ? items.slice(inlineItems.length) : undefined,\n };\n}\n"],"mappings":"aAsCA,SAAgBA,EAA6B,CAC3C,QACA,iBACA,SAAS,SACiE,CAC1E,IAAIC,EACFC,IAAmB,IAAA,IAAa,OAAO,MAAMA,CAAc,EACvD,IACA,KAAK,IAAI,EAAG,KAAK,MAAMA,CAAc,CAAC,EACxCC,IAAW,QAAO,EAAQ,KAAK,IAAIF,EAAO,CAAgB,GAC9D,IAAMG,EAAcC,EAAM,MAAM,EAAGJ,CAAK,EACxC,MAAO,CACL,cACA,cAAeI,EAAM,OAASD,EAAY,OAASC,EAAM,MAAMD,EAAY,MAAM,EAAI,IAAA,EACvF,CACF"}
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ function e({ items: e, maxInlineItems: t, layout: n = "stack" }) {
3
+ let r = t === void 0 || Number.isNaN(t) ? Infinity : Math.max(0, Math.floor(t));
4
+ n === "pie" && (r = Math.min(r, 3));
5
+ let i = e.slice(0, r);
6
+ return {
7
+ inlineItems: i,
8
+ overflowItems: e.length > i.length ? e.slice(i.length) : void 0
9
+ };
10
+ }
11
+ //#endregion
12
+ export { e as partitionAvatarGroupItems };
13
+
14
+ //# sourceMappingURL=AvatarGroup.partition.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.partition.mjs","names":["partitionAvatarGroupItems","limit","maxInlineItems","layout","inlineItems","items"],"sources":["../../../src/components/data-display/AvatarGroup.partition.ts"],"sourcesContent":["/** The layouts of an AvatarGroup. */\nexport type AvatarGroupLayout = 'stack' | 'spread' | 'pie';\n\n/** Options of {@link partitionAvatarGroupItems}. */\nexport interface PartitionAvatarGroupItemsOptions<T> {\n /** All the items of the group. */\n items: readonly T[];\n /**\n * How many items are shown inline; the rest go to the overflow. A fraction is rounded down, `0`\n * or a negative value shows none, and `undefined` or `NaN` shows all (up to the layout's cap).\n */\n maxInlineItems?: number;\n /**\n * The layout of the group. A `pie` shows at most three items inline.\n * @default 'stack'\n */\n layout?: AvatarGroupLayout;\n}\n\n/** Result of {@link partitionAvatarGroupItems}. */\nexport interface PartitionAvatarGroupItemsResult<T> {\n /** The items shown inline, in order. */\n inlineItems: T[];\n /** The items in the overflow list, in order; `undefined` when nothing overflows. */\n overflowItems: T[] | undefined;\n}\n\n/** The most items a pie shows inline. */\nconst PIE_INLINE_LIMIT = 3;\n\n/**\n * Splits the items of an AvatarGroup into the ones shown inline and the ones in the overflow list.\n * `AvatarGroup` uses it for `max`; use it yourself to render `AvatarGroup.Item`s and\n * `AvatarGroup.Popover` from your own list. Server-safe: it imports nothing.\n *\n * @example\n * const { inlineItems, overflowItems } = partitionAvatarGroupItems({ items: people, maxInlineItems: 4 });\n */\nexport function partitionAvatarGroupItems<T>({\n items,\n maxInlineItems,\n layout = 'stack',\n}: PartitionAvatarGroupItemsOptions<T>): PartitionAvatarGroupItemsResult<T> {\n let limit =\n maxInlineItems === undefined || Number.isNaN(maxInlineItems)\n ? Infinity\n : Math.max(0, Math.floor(maxInlineItems));\n if (layout === 'pie') limit = Math.min(limit, PIE_INLINE_LIMIT);\n const inlineItems = items.slice(0, limit);\n return {\n inlineItems,\n overflowItems: items.length > inlineItems.length ? items.slice(inlineItems.length) : undefined,\n };\n}\n"],"mappings":";AAsCA,SAAgBA,EAA6B,EAC3C,UACA,mBACA,YAAS,WACiE;CAC1E,IAAIC,IACFC,MAAmB,KAAA,KAAa,OAAO,MAAMA,CAAc,IACvD,WACA,KAAK,IAAI,GAAG,KAAK,MAAMA,CAAc,CAAC;CAC5C,AAAIC,MAAW,UAAO,IAAQ,KAAK,IAAIF,GAAO,CAAgB;CAC9D,IAAMG,IAAcC,EAAM,MAAM,GAAGJ,CAAK;CACxC,OAAO;EACL;EACA,eAAeI,EAAM,SAASD,EAAY,SAASC,EAAM,MAAMD,EAAY,MAAM,IAAI,KAAA;CACvF;AACF"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/children.cjs"),r=require("../../lib/dev.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useControllable.cjs"),o=require("../../hooks/useId.cjs"),s=require("../../lib/focus.cjs"),c=require("../../hooks/useMergedRefs.cjs"),l=require("../../hooks/usePopupPosition.cjs"),u=require("../../lib/layers.cjs"),d=require("../../hooks/useDismiss.cjs"),f=require("../../hooks/useRestoreFocus.cjs"),p=require("../../lib/styles.cjs"),m=require("../portal/Portal.cjs"),ee=require("./AvatarGroup.context.cjs"),h=require("./Avatar.sizes.cjs"),g=require("./Avatar.cjs");let _=require("react");_=e.__toESM(_,1);let v=require("react/jsx-runtime");var y=`Unnamed member`,b=e=>typeof e==`string`&&e.trim()!==``,x=_.createContext(null);x.displayName=`AvatarGroupOverflowContext`;var S=({className:e,...n})=>{let r=_.useContext(x);if(!r)return(0,v.jsx)(g.Avatar,{...n,className:t.cn(i.avatarGroupItemClassNames.root,e)});let{name:a,"aria-label":o,size:s,ref:c,...l}=n,u=[o,a].find(b)?.trim()??r.unnamedMemberLabel;return(0,v.jsxs)(`span`,{className:t.cn(i.avatarGroupItemClassNames.root,`inline-flex items-center gap-2`,e),children:[(0,v.jsx)(g.Avatar,{...l,name:a,size:s??`small`,decorative:!0}),(0,v.jsx)(`span`,{className:i.avatarGroupItemClassNames.name,children:u})]})};S.displayName=`AvatarGroupItem`;var C=S;function w(e){if(typeof e==`string`||typeof e==`number`)return String(e).trim()||void 0;if(!n.isElementOfType(e,g.Avatar)&&!n.isElementOfType(e,C))return;let{decorative:t,name:r,"aria-label":i,"aria-labelledby":a}=e.props;if(t||!b(a)){for(let e of[i,r])if(b(e))return e.trim()}}function T(e){if(typeof e==`string`||typeof e==`number`)return!0;if(!n.isElementOfType(e,g.Avatar))return!1;let{decorative:t,image:r,"aria-labelledby":i}=e.props;if(t)return!0;if(b(i))return!1;let a=_.isValidElement(r)?r.props:r;return!b(typeof a==`object`&&a&&`alt`in a?a.alt:void 0)}function E(e){return e>99?`99+`:`+${e}`}var D=()=>(0,v.jsxs)(`svg`,{viewBox:`0 0 16 16`,width:`16`,height:`16`,fill:`currentColor`,"aria-hidden":`true`,focusable:`false`,children:[(0,v.jsx)(`circle`,{cx:`3`,cy:`8`,r:`1.5`}),(0,v.jsx)(`circle`,{cx:`8`,cy:`8`,r:`1.5`}),(0,v.jsx)(`circle`,{cx:`13`,cy:`8`,r:`1.5`})]}),O=({children:e,indicator:g=`count`,count:b,label:S,unnamedMemberLabel:O=y,open:k,defaultOpen:A=!1,onOpenChange:j,className:M,ref:N})=>{let P=_.useContext(ee.AvatarGroupContext),F=n.flattenChildren(e),I=b??F.length,L=P?.size??`medium`,R=typeof S==`function`?S(I):S??`${I} more`,z=o.useId(`avatar-group-overflow`),[B,V]=a.useControllable(k,A),H=B&&I>0,U=(e,t,n)=>{e!==H&&(V(e),j?.(e,{reason:t,event:n}))},W=_.useContext(d.DismissLayerContext),G=_.useRef(null),K=_.useRef(null),[q,J]=_.useState(null),{setReference:Y,setFloating:X,floatingProps:Z}=l.usePopupPosition({open:H,side:`bottom`,align:`start`}),{layerId:Q}=d.useDismiss({open:H,onDismiss:(e,t)=>U(!1,e,t),refs:[G,K],anchorRef:G,focusOutside:!0});f.useRestoreFocus({enabled:H,container:q,triggerRef:G,onlyIfFocusInside:!0});let te=c.useMergedRefs(G,Y,N),ne=c.useMergedRefs(K,X,J);_.useEffect(()=>{H&&q&&q.focus({preventScroll:!0})},[H,q]);let re=e=>{let t=G.current;if(e.key!==`Tab`||e.defaultPrevented||!t)return;let n=e.currentTarget,r=e.target;if(!r||typeof r.nodeType!=`number`||!n.contains(r))return;let i=s.getTabbableElements(n),a=i.findIndex(e=>e.contains(r))+(e.shiftKey?-1:1);if(a>=0&&a<i.length){e.preventDefault(),i[a].focus();return}let o=t;if(!e.shiftKey){let e=s.getTabbableElements(t.ownerDocument.body).filter(e=>!n.contains(e)),r=e.indexOf(t);o=r===-1?t:e[r+1],o&&W!==null&&!u.isInsideLayerTree(W,o)&&(o=void 0)}U(!1,`escape`,e.nativeEvent),o&&(e.preventDefault(),o.focus())},$=H&&F.some(({node:e})=>n.isElementOfType(e,C)?w(e)===void 0:w(e)===void 0&&T(e));_.useEffect(()=>{$&&r.warnOnce(`AvatarGroup:unnamed-member`,`AvatarGroup: a hidden member has no accessible name and is listed as "${O}". Give each member a \`name\` or \`aria-label\`.`)},[$,O]);let ie=_.useMemo(()=>({unnamedMemberLabel:O}),[O]);return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(`button`,{ref:te,type:`button`,"aria-label":R,"aria-haspopup":`dialog`,"aria-expanded":H,"aria-controls":H?z:void 0,className:t.cn(i.avatarGroupClassNames.overflowButton,i.avatarGroupPopoverClassNames.root,`inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full border-0 p-0 font-semibold`,`bg-muted text-muted-foreground ring-2 ring-background`,`not-disabled:not-aria-disabled:hover:bg-subtle-pressed`,p.focusRing,P?.layout===`stack`&&P.hasInlineItems&&`-ms-2`,h.avatarSizeClassesFor(L),M),onClick:e=>U(!H,`trigger`,e.nativeEvent),children:g===`icon`?(0,v.jsx)(D,{}):E(I)}),H&&(0,v.jsx)(m.Portal,{layerId:Q,children:(0,v.jsx)(`div`,{ref:ne,id:z,role:`dialog`,"aria-label":R,tabIndex:-1,"data-state":`open`,...Z,className:t.cn(i.avatarGroupClassNames.surface,`min-w-32 max-w-xs rounded-md border border-border bg-background p-2 text-body-1 text-foreground shadow-16`,`focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring`),onKeyDown:re,children:(0,v.jsx)(x.Provider,{value:ie,children:(0,v.jsx)(`ul`,{className:t.cn(i.avatarGroupClassNames.list,`m-0 flex list-none flex-col gap-1 p-0`),children:F.map(({key:e,node:r})=>(0,v.jsx)(`li`,{className:t.cn(i.avatarGroupClassNames.listItem,`px-1 py-0.5`),children:n.isElementOfType(r,C)?r:w(r)??(T(r)?O:r)},e))})})})})]})};O.displayName=`AvatarGroupPopover`;var k=O;exports.AvatarGroupItem=C,exports.AvatarGroupPopover=k,exports.DEFAULT_UNNAMED_MEMBER_LABEL=y,exports.getMemberName=w,exports.rendersUnnamed=T;
2
+ //# sourceMappingURL=AvatarGroup.parts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.parts.cjs","names":["React","Avatar","cn","avatarGroupItemClassNames","isElementOfType","AvatarGroupContext","flattenChildren","useId","useControllable","DismissLayerContext","usePopupPosition","useDismiss","useMergedRefs","getTabbableElements","isInsideLayerTree","_Fragment","avatarGroupClassNames","avatarGroupPopoverClassNames","focusRing","avatarSizeClassesFor","Portal","require_runtime","require_cn","require_children","require_dev","require_classNames","require_useControllable","require_useId","require_focus","require_useMergedRefs","require_usePopupPosition","require_layers","require_useDismiss","require_useRestoreFocus","require_styles","require_Portal","require_AvatarGroup_context","require_Avatar_sizes","require_Avatar","react","react_jsx_runtime","DEFAULT_UNNAMED_MEMBER_LABEL","nonBlank","value","OverflowContext","AvatarGroupItemImpl","props","overflow","className","ariaLabel","avatarProps","text","name","size","AvatarGroupItem","getMemberName","member","label","labelledBy","decorative","rendersUnnamed","imageProps","image","countText","count","MoreIcon","AvatarGroupPopoverImpl","labelProp","openProp","group","items","children","popupId","openState","setOpenState","defaultOpen","isOpen","requestOpen","next","onOpenChange","parentLayerId","triggerRef","surfaceRef","surface","setSurface","reason","event","triggerRefs","setReference","ref","surfaceRefs","setFloating","handleSurfaceKeyDown","trigger","popup","origin","inner","el","target","order","index","hasUnnamedMember","node","unnamedMemberLabel","overflowContext","indicator","floatingProps","key","AvatarGroupPopover"],"sources":["../../../src/components/data-display/AvatarGroup.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport {\n avatarGroupClassNames,\n avatarGroupItemClassNames,\n avatarGroupPopoverClassNames,\n} from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { getTabbableElements } from '../../lib/focus';\nimport { isInsideLayerTree } from '../../lib/layers';\nimport { focusRing } from '../../lib/styles';\nimport type { OpenChangeDetails } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { DismissLayerContext, useDismiss, type DismissReason } from '../../hooks/useDismiss';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { Portal } from '../portal/Portal';\nimport { Avatar } from './Avatar';\nimport type { AvatarProps } from './Avatar';\nimport { avatarSizeClassesFor, type AvatarSize } from './Avatar.sizes';\nimport { AvatarGroupContext } from './AvatarGroup.context';\n\n/** Why the popup of an AvatarGroup opens or closes: its trigger, or a dismissal. */\nexport type AvatarGroupOpenChangeDetails = OpenChangeDetails<DismissReason | 'trigger'>;\n\n/** Default text listed for a hidden member that would render with no accessible name. */\nexport const DEFAULT_UNNAMED_MEMBER_LABEL = 'Unnamed member';\n\nconst nonBlank = (value: unknown): value is string =>\n typeof value === 'string' && value.trim() !== '';\n\n/** Set by the popup around its list: an Item renders as a row (avatar and name) there. */\nconst OverflowContext = React.createContext<{ unnamedMemberLabel: string } | null>(null);\nOverflowContext.displayName = 'AvatarGroupOverflowContext';\n\n/** Properties for the AvatarGroup.Item sub-component: the props of an Avatar. */\nexport type AvatarGroupItemProps = AvatarProps;\n\nconst AvatarGroupItemImpl = ({ className, ...props }: AvatarGroupItemProps) => {\n const overflow = React.useContext(OverflowContext);\n if (!overflow) {\n return <Avatar {...props} className={cn(avatarGroupItemClassNames.root, className)} />;\n }\n const { name, 'aria-label': ariaLabel, size, ref, ...avatarProps } = props;\n const text = [ariaLabel, name].find(nonBlank)?.trim() ?? overflow.unnamedMemberLabel;\n return (\n <span\n className={cn(avatarGroupItemClassNames.root, 'inline-flex items-center gap-2', className)}\n >\n <Avatar {...avatarProps} name={name} size={size ?? 'small'} decorative />\n <span className={avatarGroupItemClassNames.name}>{text}</span>\n </span>\n );\n};\nAvatarGroupItemImpl.displayName = 'AvatarGroupItem';\n/**\n * A member of an AvatarGroup. In the group it renders as an `Avatar`; in the overflow list of the\n * popup it renders as a row with the avatar and the name. It takes the props of an `Avatar`.\n */\nexport const AvatarGroupItem = AvatarGroupItemImpl;\n\n/**\n * The text name of a member for the overflow list: the text of a text member, or the accessible\n * name of an `Avatar` or Item given by its props (`aria-label` before `name`). An `Avatar`\n * labelled by `aria-labelledby` (unless `decorative`) and every other element have none: they are\n * rendered as they are, so a link keeps working and keeps its own label.\n */\nexport function getMemberName(member: React.ReactNode): string | undefined {\n if (typeof member === 'string' || typeof member === 'number') {\n return String(member).trim() || undefined;\n }\n if (\n !isElementOfType<AvatarProps>(member, Avatar) &&\n !isElementOfType<AvatarProps>(member, AvatarGroupItem)\n ) {\n return undefined;\n }\n const { decorative, name, 'aria-label': label, 'aria-labelledby': labelledBy } = member.props;\n if (!decorative && nonBlank(labelledBy)) return undefined;\n for (const value of [label, name]) {\n if (nonBlank(value)) return value.trim();\n }\n return undefined;\n}\n\n/**\n * Whether a member without a {@link getMemberName} name would render with no accessible name,\n * so its list item would be empty for assistive technology: blank text, or an `Avatar` that is\n * neither labelled by `aria-labelledby` nor named by its image's `alt` (or is `decorative`).\n * Other elements are rendered as they are, since their content is unknown here.\n */\nexport function rendersUnnamed(member: React.ReactNode): boolean {\n if (typeof member === 'string' || typeof member === 'number') return true;\n if (!isElementOfType<AvatarProps>(member, Avatar)) return false;\n const { decorative, image, 'aria-labelledby': labelledBy } = member.props;\n if (decorative) return true;\n if (nonBlank(labelledBy)) return false;\n const imageProps: unknown = React.isValidElement(image) ? image.props : image;\n const alt =\n typeof imageProps === 'object' && imageProps !== null && 'alt' in imageProps\n ? imageProps.alt\n : undefined;\n return !nonBlank(alt);\n}\n\n/** The shown count of the overflow button: capped at `99+`. */\nfunction countText(count: number): string {\n return count > 99 ? '99+' : `+${count}`;\n}\n\n/** Properties for the AvatarGroup.Popover sub-component. */\nexport interface AvatarGroupPopoverProps {\n /** The overflow members: `AvatarGroup.Item`s, `Avatar`s, text or other elements. */\n children?: React.ReactNode;\n /**\n * What the overflow button shows: the number of hidden members (`+3`, capped at `99+`), or an\n * icon.\n * @default 'count'\n */\n indicator?: 'count' | 'icon';\n /** The number of hidden members. @default the number of `children` */\n count?: number;\n /**\n * Accessible name of the overflow button and its popup. A function receives the number of hidden\n * members.\n * @default (count) => `${count} more`\n */\n label?: string | ((count: number) => string);\n /**\n * Text listed in the overflow popup for a hidden member that has no accessible name.\n * @default 'Unnamed member'\n */\n unnamedMemberLabel?: string;\n /** Whether the popup is open (controlled). */\n open?: boolean;\n /**\n * Whether the popup starts open (uncontrolled).\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the popup asks to open or close, with the reason (`trigger`, `escape`, …). */\n onOpenChange?: (open: boolean, details?: AvatarGroupOpenChangeDetails) => void;\n /** Extra classes for the overflow button. */\n className?: string;\n /** Ref to the overflow `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\nconst MoreIcon = () => (\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" />\n </svg>\n);\n\nconst AvatarGroupPopoverImpl = ({\n children,\n indicator = 'count',\n count,\n label: labelProp,\n unnamedMemberLabel = DEFAULT_UNNAMED_MEMBER_LABEL,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n className,\n ref,\n}: AvatarGroupPopoverProps) => {\n const group = React.useContext(AvatarGroupContext);\n const items = flattenChildren(children);\n const overflow = count ?? items.length;\n const size: AvatarSize = group?.size ?? 'medium';\n const label =\n typeof labelProp === 'function' ? labelProp(overflow) : (labelProp ?? `${overflow} more`);\n\n const popupId = useId('avatar-group-overflow');\n const [openState, setOpenState] = useControllable(openProp, defaultOpen);\n // Nothing is hidden any more: the popup is closed, and does not reappear when members overflow\n // again unless asked.\n const isOpen = openState && overflow > 0;\n const requestOpen = (\n next: boolean,\n reason: AvatarGroupOpenChangeDetails['reason'],\n event: Event,\n ) => {\n if (next === isOpen) return;\n setOpenState(next);\n onOpenChange?.(next, { reason, event });\n };\n\n // The layer the group is rendered in (a dialog or popover), if any: the popup's parent layer.\n const parentLayerId = React.useContext(DismissLayerContext);\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: isOpen,\n side: 'bottom',\n align: 'start',\n });\n const { layerId } = useDismiss({\n open: isOpen,\n onDismiss: (reason, event) => requestOpen(false, reason, event),\n refs: [triggerRef, surfaceRef],\n anchorRef: triggerRef,\n focusOutside: true,\n });\n useRestoreFocus({ enabled: isOpen, container: surface, triggerRef, onlyIfFocusInside: true });\n const triggerRefs = useMergedRefs<HTMLButtonElement>(triggerRef, setReference, ref);\n const surfaceRefs = useMergedRefs<HTMLDivElement>(surfaceRef, setFloating, setSurface);\n\n // Move focus into the popup once it is mounted, so its list is read next.\n React.useEffect(() => {\n if (isOpen && surface) surface.focus({ preventScroll: true });\n }, [isOpen, surface]);\n\n // The popup is portaled, so native tabbing would leave it for the end of the page. Tab moves\n // through the popup's own tab stops (a rendered member can be a link); leaving the last one\n // closes the popup and moves on from the button instead (Shift+Tab before the first one: back to\n // the button), like a focus trap does for a popup anchored in a dialog. When nothing tabbable\n // follows the button, Tab is not prevented: focus returns to the button as the popup closes and\n // the browser (leaving the page) or an enclosing focus trap (wrapping) takes it from there.\n // Inside a parent layer (a dialog, a popover), a tab stop after the button that lies outside that\n // layer is treated the same way: a focus trap that leaves the page outside it interactive would\n // pull focus back from there, while its descendant-layer rule (§2.4) wraps from the button.\n // Tab stops are computed at keydown time, never cached (§2.2 focus utilities). A key that\n // bubbles through React from a portal a member opened is not the popup's: it is ignored.\n const handleSurfaceKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const trigger = triggerRef.current;\n if (event.key !== 'Tab' || event.defaultPrevented || !trigger) return;\n const popup = event.currentTarget;\n // Duck typed (`nodeType`), not `instanceof Node`: a popup portaled into another document (an\n // iframe, a popout window) holds nodes of that realm.\n const origin = event.target as Partial<Node> | null;\n if (!origin || typeof origin.nodeType !== 'number' || !popup.contains(origin as Node)) return;\n const inner = getTabbableElements(popup);\n // -1 while focus is on the popup itself (or on something that is not a tab stop).\n const current = inner.findIndex((el) => el.contains(origin as Node));\n const next = current + (event.shiftKey ? -1 : 1);\n if (next >= 0 && next < inner.length) {\n event.preventDefault();\n inner[next]!.focus();\n return;\n }\n let target: HTMLElement | undefined = trigger;\n if (!event.shiftKey) {\n const order = getTabbableElements(trigger.ownerDocument.body).filter(\n (el) => !popup.contains(el),\n );\n const index = order.indexOf(trigger);\n target = index === -1 ? trigger : order[index + 1];\n if (target && parentLayerId !== null && !isInsideLayerTree(parentLayerId, target)) {\n target = undefined;\n }\n }\n requestOpen(false, 'escape', event.nativeEvent);\n if (!target) return;\n event.preventDefault();\n target.focus();\n };\n\n const hasUnnamedMember =\n isOpen &&\n items.some(({ node }) =>\n isElementOfType<AvatarProps>(node, AvatarGroupItem)\n ? getMemberName(node) === undefined\n : getMemberName(node) === undefined && rendersUnnamed(node),\n );\n React.useEffect(() => {\n if (hasUnnamedMember) {\n warnOnce(\n 'AvatarGroup:unnamed-member',\n `AvatarGroup: a hidden member has no accessible name and is listed as \"${unnamedMemberLabel}\". Give each member a \\`name\\` or \\`aria-label\\`.`,\n );\n }\n }, [hasUnnamedMember, unnamedMemberLabel]);\n\n const overflowContext = React.useMemo(() => ({ unnamedMemberLabel }), [unnamedMemberLabel]);\n\n return (\n <>\n <button\n ref={triggerRefs}\n type=\"button\"\n aria-label={label}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? popupId : undefined}\n className={cn(\n avatarGroupClassNames.overflowButton,\n avatarGroupPopoverClassNames.root,\n 'inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full border-0 p-0 font-semibold',\n 'bg-muted text-muted-foreground ring-2 ring-background',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-pressed',\n focusRing,\n group?.layout === 'stack' && group.hasInlineItems && '-ms-2',\n avatarSizeClassesFor(size),\n className,\n )}\n onClick={(event) => requestOpen(!isOpen, 'trigger', event.nativeEvent)}\n >\n {indicator === 'icon' ? <MoreIcon /> : countText(overflow)}\n </button>\n {isOpen && (\n <Portal layerId={layerId}>\n <div\n ref={surfaceRefs}\n id={popupId}\n role=\"dialog\"\n aria-label={label}\n tabIndex={-1}\n data-state=\"open\"\n {...floatingProps}\n className={cn(\n avatarGroupClassNames.surface,\n 'min-w-32 max-w-xs rounded-md border border-border bg-background p-2 text-body-1 text-foreground shadow-16',\n focusRing,\n )}\n onKeyDown={handleSurfaceKeyDown}\n >\n <OverflowContext.Provider value={overflowContext}>\n <ul\n className={cn(avatarGroupClassNames.list, 'm-0 flex list-none flex-col gap-1 p-0')}\n >\n {items.map(({ key, node }) => (\n <li key={key} className={cn(avatarGroupClassNames.listItem, 'px-1 py-0.5')}>\n {isElementOfType<AvatarProps>(node, AvatarGroupItem)\n ? node\n : (getMemberName(node) ?? (rendersUnnamed(node) ? unnamedMemberLabel : node))}\n </li>\n ))}\n </ul>\n </OverflowContext.Provider>\n </div>\n </Portal>\n )}\n </>\n );\n};\nAvatarGroupPopoverImpl.displayName = 'AvatarGroupPopover';\n/**\n * The overflow of an AvatarGroup, written by hand: a \"+N\" button that opens a popup listing its\n * children (`AvatarGroup.Item`s, `Avatar`s, text or other elements). Write it as a child of the\n * group to replace the overflow that `max` makes; its `count`, `indicator`, `label`, `open` and\n * `onOpenChange` take over what `max` would have derived. Tab leaves the popup from the button.\n */\nexport const AvatarGroupPopover = AvatarGroupPopoverImpl;\n"],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { flattenChildren as t, isElementOfType as n } from "../../lib/children.mjs";
4
+ import { warnOnce as r } from "../../lib/dev.mjs";
5
+ import { avatarGroupClassNames as i, avatarGroupItemClassNames as a, avatarGroupPopoverClassNames as o } from "../../lib/classNames.mjs";
6
+ import { useControllable as s } from "../../hooks/useControllable.mjs";
7
+ import { useId as c } from "../../hooks/useId.mjs";
8
+ import { getTabbableElements as l } from "../../lib/focus.mjs";
9
+ import { useMergedRefs as u } from "../../hooks/useMergedRefs.mjs";
10
+ import { usePopupPosition as ee } from "../../hooks/usePopupPosition.mjs";
11
+ import { isInsideLayerTree as d } from "../../lib/layers.mjs";
12
+ import { DismissLayerContext as f, useDismiss as p } from "../../hooks/useDismiss.mjs";
13
+ import { useRestoreFocus as m } from "../../hooks/useRestoreFocus.mjs";
14
+ import { focusRing as h } from "../../lib/styles.mjs";
15
+ import { Portal as g } from "../portal/Portal.mjs";
16
+ import { AvatarGroupContext as _ } from "./AvatarGroup.context.mjs";
17
+ import { avatarSizeClassesFor as v } from "./Avatar.sizes.mjs";
18
+ import { Avatar as y } from "./Avatar.mjs";
19
+ import * as b from "react";
20
+ import { Fragment as te, jsx as x, jsxs as S } from "react/jsx-runtime";
21
+ //#region src/components/data-display/AvatarGroup.parts.tsx
22
+ var C = "Unnamed member", w = (e) => typeof e == "string" && e.trim() !== "", T = b.createContext(null);
23
+ T.displayName = "AvatarGroupOverflowContext";
24
+ var E = ({ className: t, ...n }) => {
25
+ let r = b.useContext(T);
26
+ if (!r) return /* @__PURE__ */ x(y, {
27
+ ...n,
28
+ className: e(a.root, t)
29
+ });
30
+ let { name: i, "aria-label": o, size: s, ref: c, ...l } = n, u = [o, i].find(w)?.trim() ?? r.unnamedMemberLabel;
31
+ return /* @__PURE__ */ S("span", {
32
+ className: e(a.root, "inline-flex items-center gap-2", t),
33
+ children: [/* @__PURE__ */ x(y, {
34
+ ...l,
35
+ name: i,
36
+ size: s ?? "small",
37
+ decorative: !0
38
+ }), /* @__PURE__ */ x("span", {
39
+ className: a.name,
40
+ children: u
41
+ })]
42
+ });
43
+ };
44
+ E.displayName = "AvatarGroupItem";
45
+ var D = E;
46
+ function O(e) {
47
+ if (typeof e == "string" || typeof e == "number") return String(e).trim() || void 0;
48
+ if (!n(e, y) && !n(e, D)) return;
49
+ let { decorative: t, name: r, "aria-label": i, "aria-labelledby": a } = e.props;
50
+ if (t || !w(a)) {
51
+ for (let e of [i, r]) if (w(e)) return e.trim();
52
+ }
53
+ }
54
+ function k(e) {
55
+ if (typeof e == "string" || typeof e == "number") return !0;
56
+ if (!n(e, y)) return !1;
57
+ let { decorative: t, image: r, "aria-labelledby": i } = e.props;
58
+ if (t) return !0;
59
+ if (w(i)) return !1;
60
+ let a = b.isValidElement(r) ? r.props : r;
61
+ return !w(typeof a == "object" && a && "alt" in a ? a.alt : void 0);
62
+ }
63
+ function A(e) {
64
+ return e > 99 ? "99+" : `+${e}`;
65
+ }
66
+ var j = () => /* @__PURE__ */ S("svg", {
67
+ viewBox: "0 0 16 16",
68
+ width: "16",
69
+ height: "16",
70
+ fill: "currentColor",
71
+ "aria-hidden": "true",
72
+ focusable: "false",
73
+ children: [
74
+ /* @__PURE__ */ x("circle", {
75
+ cx: "3",
76
+ cy: "8",
77
+ r: "1.5"
78
+ }),
79
+ /* @__PURE__ */ x("circle", {
80
+ cx: "8",
81
+ cy: "8",
82
+ r: "1.5"
83
+ }),
84
+ /* @__PURE__ */ x("circle", {
85
+ cx: "13",
86
+ cy: "8",
87
+ r: "1.5"
88
+ })
89
+ ]
90
+ }), M = ({ children: a, indicator: y = "count", count: w, label: E, unnamedMemberLabel: M = C, open: N, defaultOpen: P = !1, onOpenChange: F, className: I, ref: L }) => {
91
+ let R = b.useContext(_), z = t(a), B = w ?? z.length, V = R?.size ?? "medium", H = typeof E == "function" ? E(B) : E ?? `${B} more`, U = c("avatar-group-overflow"), [W, G] = s(N, P), K = W && B > 0, q = (e, t, n) => {
92
+ e !== K && (G(e), F?.(e, {
93
+ reason: t,
94
+ event: n
95
+ }));
96
+ }, J = b.useContext(f), Y = b.useRef(null), X = b.useRef(null), [Z, ne] = b.useState(null), { setReference: re, setFloating: ie, floatingProps: ae } = ee({
97
+ open: K,
98
+ side: "bottom",
99
+ align: "start"
100
+ }), { layerId: oe } = p({
101
+ open: K,
102
+ onDismiss: (e, t) => q(!1, e, t),
103
+ refs: [Y, X],
104
+ anchorRef: Y,
105
+ focusOutside: !0
106
+ });
107
+ m({
108
+ enabled: K,
109
+ container: Z,
110
+ triggerRef: Y,
111
+ onlyIfFocusInside: !0
112
+ });
113
+ let se = u(Y, re, L), Q = u(X, ie, ne);
114
+ b.useEffect(() => {
115
+ K && Z && Z.focus({ preventScroll: !0 });
116
+ }, [K, Z]);
117
+ let ce = (e) => {
118
+ let t = Y.current;
119
+ if (e.key !== "Tab" || e.defaultPrevented || !t) return;
120
+ let n = e.currentTarget, r = e.target;
121
+ if (!r || typeof r.nodeType != "number" || !n.contains(r)) return;
122
+ let i = l(n), a = i.findIndex((e) => e.contains(r)) + (e.shiftKey ? -1 : 1);
123
+ if (a >= 0 && a < i.length) {
124
+ e.preventDefault(), i[a].focus();
125
+ return;
126
+ }
127
+ let o = t;
128
+ if (!e.shiftKey) {
129
+ let e = l(t.ownerDocument.body).filter((e) => !n.contains(e)), r = e.indexOf(t);
130
+ o = r === -1 ? t : e[r + 1], o && J !== null && !d(J, o) && (o = void 0);
131
+ }
132
+ q(!1, "escape", e.nativeEvent), o && (e.preventDefault(), o.focus());
133
+ }, $ = K && z.some(({ node: e }) => n(e, D) ? O(e) === void 0 : O(e) === void 0 && k(e));
134
+ b.useEffect(() => {
135
+ $ && r("AvatarGroup:unnamed-member", `AvatarGroup: a hidden member has no accessible name and is listed as "${M}". Give each member a \`name\` or \`aria-label\`.`);
136
+ }, [$, M]);
137
+ let le = b.useMemo(() => ({ unnamedMemberLabel: M }), [M]);
138
+ return /* @__PURE__ */ S(te, { children: [/* @__PURE__ */ x("button", {
139
+ ref: se,
140
+ type: "button",
141
+ "aria-label": H,
142
+ "aria-haspopup": "dialog",
143
+ "aria-expanded": K,
144
+ "aria-controls": K ? U : void 0,
145
+ className: e(i.overflowButton, o.root, "inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full border-0 p-0 font-semibold", "bg-muted text-muted-foreground ring-2 ring-background", "not-disabled:not-aria-disabled:hover:bg-subtle-pressed", h, R?.layout === "stack" && R.hasInlineItems && "-ms-2", v(V), I),
146
+ onClick: (e) => q(!K, "trigger", e.nativeEvent),
147
+ children: y === "icon" ? /* @__PURE__ */ x(j, {}) : A(B)
148
+ }), K && /* @__PURE__ */ x(g, {
149
+ layerId: oe,
150
+ children: /* @__PURE__ */ x("div", {
151
+ ref: Q,
152
+ id: U,
153
+ role: "dialog",
154
+ "aria-label": H,
155
+ tabIndex: -1,
156
+ "data-state": "open",
157
+ ...ae,
158
+ className: e(i.surface, "min-w-32 max-w-xs rounded-md border border-border bg-background p-2 text-body-1 text-foreground shadow-16", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"),
159
+ onKeyDown: ce,
160
+ children: /* @__PURE__ */ x(T.Provider, {
161
+ value: le,
162
+ children: /* @__PURE__ */ x("ul", {
163
+ className: e(i.list, "m-0 flex list-none flex-col gap-1 p-0"),
164
+ children: z.map(({ key: t, node: r }) => /* @__PURE__ */ x("li", {
165
+ className: e(i.listItem, "px-1 py-0.5"),
166
+ children: n(r, D) ? r : O(r) ?? (k(r) ? M : r)
167
+ }, t))
168
+ })
169
+ })
170
+ })
171
+ })] });
172
+ };
173
+ M.displayName = "AvatarGroupPopover";
174
+ var N = M;
175
+ //#endregion
176
+ export { D as AvatarGroupItem, N as AvatarGroupPopover, C as DEFAULT_UNNAMED_MEMBER_LABEL, O as getMemberName, k as rendersUnnamed };
177
+
178
+ //# sourceMappingURL=AvatarGroup.parts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.parts.mjs","names":["useId","_Fragment","useId$1","React","DEFAULT_UNNAMED_MEMBER_LABEL","nonBlank","value","OverflowContext","AvatarGroupItemImpl","props","overflow","Avatar","cn","avatarGroupItemClassNames","className","ariaLabel","avatarProps","text","name","size","AvatarGroupItem","getMemberName","member","isElementOfType","label","labelledBy","decorative","rendersUnnamed","imageProps","image","countText","count","MoreIcon","AvatarGroupPopoverImpl","labelProp","openProp","group","AvatarGroupContext","items","flattenChildren","children","popupId","openState","setOpenState","useControllable","defaultOpen","isOpen","requestOpen","next","onOpenChange","parentLayerId","DismissLayerContext","triggerRef","surfaceRef","surface","setSurface","usePopupPosition","useDismiss","reason","event","triggerRefs","useMergedRefs","setReference","ref","surfaceRefs","setFloating","handleSurfaceKeyDown","trigger","popup","origin","inner","getTabbableElements","el","target","order","index","isInsideLayerTree","hasUnnamedMember","node","warnOnce","unnamedMemberLabel","overflowContext","Fragment","avatarGroupClassNames","avatarGroupPopoverClassNames","focusRing","avatarSizeClassesFor","indicator","Portal","floatingProps","key","AvatarGroupPopover"],"sources":["../../../src/components/data-display/AvatarGroup.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport {\n avatarGroupClassNames,\n avatarGroupItemClassNames,\n avatarGroupPopoverClassNames,\n} from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { getTabbableElements } from '../../lib/focus';\nimport { isInsideLayerTree } from '../../lib/layers';\nimport { focusRing } from '../../lib/styles';\nimport type { OpenChangeDetails } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { DismissLayerContext, useDismiss, type DismissReason } from '../../hooks/useDismiss';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePopupPosition } from '../../hooks/usePopupPosition';\nimport { useRestoreFocus } from '../../hooks/useRestoreFocus';\nimport { Portal } from '../portal/Portal';\nimport { Avatar } from './Avatar';\nimport type { AvatarProps } from './Avatar';\nimport { avatarSizeClassesFor, type AvatarSize } from './Avatar.sizes';\nimport { AvatarGroupContext } from './AvatarGroup.context';\n\n/** Why the popup of an AvatarGroup opens or closes: its trigger, or a dismissal. */\nexport type AvatarGroupOpenChangeDetails = OpenChangeDetails<DismissReason | 'trigger'>;\n\n/** Default text listed for a hidden member that would render with no accessible name. */\nexport const DEFAULT_UNNAMED_MEMBER_LABEL = 'Unnamed member';\n\nconst nonBlank = (value: unknown): value is string =>\n typeof value === 'string' && value.trim() !== '';\n\n/** Set by the popup around its list: an Item renders as a row (avatar and name) there. */\nconst OverflowContext = React.createContext<{ unnamedMemberLabel: string } | null>(null);\nOverflowContext.displayName = 'AvatarGroupOverflowContext';\n\n/** Properties for the AvatarGroup.Item sub-component: the props of an Avatar. */\nexport type AvatarGroupItemProps = AvatarProps;\n\nconst AvatarGroupItemImpl = ({ className, ...props }: AvatarGroupItemProps) => {\n const overflow = React.useContext(OverflowContext);\n if (!overflow) {\n return <Avatar {...props} className={cn(avatarGroupItemClassNames.root, className)} />;\n }\n const { name, 'aria-label': ariaLabel, size, ref, ...avatarProps } = props;\n const text = [ariaLabel, name].find(nonBlank)?.trim() ?? overflow.unnamedMemberLabel;\n return (\n <span\n className={cn(avatarGroupItemClassNames.root, 'inline-flex items-center gap-2', className)}\n >\n <Avatar {...avatarProps} name={name} size={size ?? 'small'} decorative />\n <span className={avatarGroupItemClassNames.name}>{text}</span>\n </span>\n );\n};\nAvatarGroupItemImpl.displayName = 'AvatarGroupItem';\n/**\n * A member of an AvatarGroup. In the group it renders as an `Avatar`; in the overflow list of the\n * popup it renders as a row with the avatar and the name. It takes the props of an `Avatar`.\n */\nexport const AvatarGroupItem = AvatarGroupItemImpl;\n\n/**\n * The text name of a member for the overflow list: the text of a text member, or the accessible\n * name of an `Avatar` or Item given by its props (`aria-label` before `name`). An `Avatar`\n * labelled by `aria-labelledby` (unless `decorative`) and every other element have none: they are\n * rendered as they are, so a link keeps working and keeps its own label.\n */\nexport function getMemberName(member: React.ReactNode): string | undefined {\n if (typeof member === 'string' || typeof member === 'number') {\n return String(member).trim() || undefined;\n }\n if (\n !isElementOfType<AvatarProps>(member, Avatar) &&\n !isElementOfType<AvatarProps>(member, AvatarGroupItem)\n ) {\n return undefined;\n }\n const { decorative, name, 'aria-label': label, 'aria-labelledby': labelledBy } = member.props;\n if (!decorative && nonBlank(labelledBy)) return undefined;\n for (const value of [label, name]) {\n if (nonBlank(value)) return value.trim();\n }\n return undefined;\n}\n\n/**\n * Whether a member without a {@link getMemberName} name would render with no accessible name,\n * so its list item would be empty for assistive technology: blank text, or an `Avatar` that is\n * neither labelled by `aria-labelledby` nor named by its image's `alt` (or is `decorative`).\n * Other elements are rendered as they are, since their content is unknown here.\n */\nexport function rendersUnnamed(member: React.ReactNode): boolean {\n if (typeof member === 'string' || typeof member === 'number') return true;\n if (!isElementOfType<AvatarProps>(member, Avatar)) return false;\n const { decorative, image, 'aria-labelledby': labelledBy } = member.props;\n if (decorative) return true;\n if (nonBlank(labelledBy)) return false;\n const imageProps: unknown = React.isValidElement(image) ? image.props : image;\n const alt =\n typeof imageProps === 'object' && imageProps !== null && 'alt' in imageProps\n ? imageProps.alt\n : undefined;\n return !nonBlank(alt);\n}\n\n/** The shown count of the overflow button: capped at `99+`. */\nfunction countText(count: number): string {\n return count > 99 ? '99+' : `+${count}`;\n}\n\n/** Properties for the AvatarGroup.Popover sub-component. */\nexport interface AvatarGroupPopoverProps {\n /** The overflow members: `AvatarGroup.Item`s, `Avatar`s, text or other elements. */\n children?: React.ReactNode;\n /**\n * What the overflow button shows: the number of hidden members (`+3`, capped at `99+`), or an\n * icon.\n * @default 'count'\n */\n indicator?: 'count' | 'icon';\n /** The number of hidden members. @default the number of `children` */\n count?: number;\n /**\n * Accessible name of the overflow button and its popup. A function receives the number of hidden\n * members.\n * @default (count) => `${count} more`\n */\n label?: string | ((count: number) => string);\n /**\n * Text listed in the overflow popup for a hidden member that has no accessible name.\n * @default 'Unnamed member'\n */\n unnamedMemberLabel?: string;\n /** Whether the popup is open (controlled). */\n open?: boolean;\n /**\n * Whether the popup starts open (uncontrolled).\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the popup asks to open or close, with the reason (`trigger`, `escape`, …). */\n onOpenChange?: (open: boolean, details?: AvatarGroupOpenChangeDetails) => void;\n /** Extra classes for the overflow button. */\n className?: string;\n /** Ref to the overflow `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\nconst MoreIcon = () => (\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" />\n </svg>\n);\n\nconst AvatarGroupPopoverImpl = ({\n children,\n indicator = 'count',\n count,\n label: labelProp,\n unnamedMemberLabel = DEFAULT_UNNAMED_MEMBER_LABEL,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n className,\n ref,\n}: AvatarGroupPopoverProps) => {\n const group = React.useContext(AvatarGroupContext);\n const items = flattenChildren(children);\n const overflow = count ?? items.length;\n const size: AvatarSize = group?.size ?? 'medium';\n const label =\n typeof labelProp === 'function' ? labelProp(overflow) : (labelProp ?? `${overflow} more`);\n\n const popupId = useId('avatar-group-overflow');\n const [openState, setOpenState] = useControllable(openProp, defaultOpen);\n // Nothing is hidden any more: the popup is closed, and does not reappear when members overflow\n // again unless asked.\n const isOpen = openState && overflow > 0;\n const requestOpen = (\n next: boolean,\n reason: AvatarGroupOpenChangeDetails['reason'],\n event: Event,\n ) => {\n if (next === isOpen) return;\n setOpenState(next);\n onOpenChange?.(next, { reason, event });\n };\n\n // The layer the group is rendered in (a dialog or popover), if any: the popup's parent layer.\n const parentLayerId = React.useContext(DismissLayerContext);\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n\n const { setReference, setFloating, floatingProps } = usePopupPosition({\n open: isOpen,\n side: 'bottom',\n align: 'start',\n });\n const { layerId } = useDismiss({\n open: isOpen,\n onDismiss: (reason, event) => requestOpen(false, reason, event),\n refs: [triggerRef, surfaceRef],\n anchorRef: triggerRef,\n focusOutside: true,\n });\n useRestoreFocus({ enabled: isOpen, container: surface, triggerRef, onlyIfFocusInside: true });\n const triggerRefs = useMergedRefs<HTMLButtonElement>(triggerRef, setReference, ref);\n const surfaceRefs = useMergedRefs<HTMLDivElement>(surfaceRef, setFloating, setSurface);\n\n // Move focus into the popup once it is mounted, so its list is read next.\n React.useEffect(() => {\n if (isOpen && surface) surface.focus({ preventScroll: true });\n }, [isOpen, surface]);\n\n // The popup is portaled, so native tabbing would leave it for the end of the page. Tab moves\n // through the popup's own tab stops (a rendered member can be a link); leaving the last one\n // closes the popup and moves on from the button instead (Shift+Tab before the first one: back to\n // the button), like a focus trap does for a popup anchored in a dialog. When nothing tabbable\n // follows the button, Tab is not prevented: focus returns to the button as the popup closes and\n // the browser (leaving the page) or an enclosing focus trap (wrapping) takes it from there.\n // Inside a parent layer (a dialog, a popover), a tab stop after the button that lies outside that\n // layer is treated the same way: a focus trap that leaves the page outside it interactive would\n // pull focus back from there, while its descendant-layer rule (§2.4) wraps from the button.\n // Tab stops are computed at keydown time, never cached (§2.2 focus utilities). A key that\n // bubbles through React from a portal a member opened is not the popup's: it is ignored.\n const handleSurfaceKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const trigger = triggerRef.current;\n if (event.key !== 'Tab' || event.defaultPrevented || !trigger) return;\n const popup = event.currentTarget;\n // Duck typed (`nodeType`), not `instanceof Node`: a popup portaled into another document (an\n // iframe, a popout window) holds nodes of that realm.\n const origin = event.target as Partial<Node> | null;\n if (!origin || typeof origin.nodeType !== 'number' || !popup.contains(origin as Node)) return;\n const inner = getTabbableElements(popup);\n // -1 while focus is on the popup itself (or on something that is not a tab stop).\n const current = inner.findIndex((el) => el.contains(origin as Node));\n const next = current + (event.shiftKey ? -1 : 1);\n if (next >= 0 && next < inner.length) {\n event.preventDefault();\n inner[next]!.focus();\n return;\n }\n let target: HTMLElement | undefined = trigger;\n if (!event.shiftKey) {\n const order = getTabbableElements(trigger.ownerDocument.body).filter(\n (el) => !popup.contains(el),\n );\n const index = order.indexOf(trigger);\n target = index === -1 ? trigger : order[index + 1];\n if (target && parentLayerId !== null && !isInsideLayerTree(parentLayerId, target)) {\n target = undefined;\n }\n }\n requestOpen(false, 'escape', event.nativeEvent);\n if (!target) return;\n event.preventDefault();\n target.focus();\n };\n\n const hasUnnamedMember =\n isOpen &&\n items.some(({ node }) =>\n isElementOfType<AvatarProps>(node, AvatarGroupItem)\n ? getMemberName(node) === undefined\n : getMemberName(node) === undefined && rendersUnnamed(node),\n );\n React.useEffect(() => {\n if (hasUnnamedMember) {\n warnOnce(\n 'AvatarGroup:unnamed-member',\n `AvatarGroup: a hidden member has no accessible name and is listed as \"${unnamedMemberLabel}\". Give each member a \\`name\\` or \\`aria-label\\`.`,\n );\n }\n }, [hasUnnamedMember, unnamedMemberLabel]);\n\n const overflowContext = React.useMemo(() => ({ unnamedMemberLabel }), [unnamedMemberLabel]);\n\n return (\n <>\n <button\n ref={triggerRefs}\n type=\"button\"\n aria-label={label}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? popupId : undefined}\n className={cn(\n avatarGroupClassNames.overflowButton,\n avatarGroupPopoverClassNames.root,\n 'inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full border-0 p-0 font-semibold',\n 'bg-muted text-muted-foreground ring-2 ring-background',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-pressed',\n focusRing,\n group?.layout === 'stack' && group.hasInlineItems && '-ms-2',\n avatarSizeClassesFor(size),\n className,\n )}\n onClick={(event) => requestOpen(!isOpen, 'trigger', event.nativeEvent)}\n >\n {indicator === 'icon' ? <MoreIcon /> : countText(overflow)}\n </button>\n {isOpen && (\n <Portal layerId={layerId}>\n <div\n ref={surfaceRefs}\n id={popupId}\n role=\"dialog\"\n aria-label={label}\n tabIndex={-1}\n data-state=\"open\"\n {...floatingProps}\n className={cn(\n avatarGroupClassNames.surface,\n 'min-w-32 max-w-xs rounded-md border border-border bg-background p-2 text-body-1 text-foreground shadow-16',\n focusRing,\n )}\n onKeyDown={handleSurfaceKeyDown}\n >\n <OverflowContext.Provider value={overflowContext}>\n <ul\n className={cn(avatarGroupClassNames.list, 'm-0 flex list-none flex-col gap-1 p-0')}\n >\n {items.map(({ key, node }) => (\n <li key={key} className={cn(avatarGroupClassNames.listItem, 'px-1 py-0.5')}>\n {isElementOfType<AvatarProps>(node, AvatarGroupItem)\n ? node\n : (getMemberName(node) ?? (rendersUnnamed(node) ? unnamedMemberLabel : node))}\n </li>\n ))}\n </ul>\n </OverflowContext.Provider>\n </div>\n </Portal>\n )}\n </>\n );\n};\nAvatarGroupPopoverImpl.displayName = 'AvatarGroupPopover';\n/**\n * The overflow of an AvatarGroup, written by hand: a \"+N\" button that opens a popup listing its\n * children (`AvatarGroup.Item`s, `Avatar`s, text or other elements). Write it as a child of the\n * group to replace the overflow that `max` makes; its `count`, `indicator`, `label`, `open` and\n * `onOpenChange` take over what `max` would have derived. Tab leaves the popup from the button.\n */\nexport const AvatarGroupPopover = AvatarGroupPopoverImpl;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useEventCallback.cjs"),s=require("../../hooks/useId.cjs"),c=require("../../hooks/useMergedRefs.cjs"),l=require("../../lib/aria.cjs"),u=require("../../lib/styles.cjs"),d=require("../button/Button.slots.cjs"),f=require("../../lib/icons.cjs"),p=require("../../lib/labelInName.cjs"),m=require("../../lib/events.cjs"),h=require("./TagGroup.context.cjs"),g=require("./Avatar.context.cjs"),_=require("./tagStyles.cjs");let v=require("react");v=e.__toESM(v,1);let y=require("react/jsx-runtime");var b=()=>{};function x(){let e=0,t=!1,n=new Set,r=()=>{for(let e of n)e()};return{subscribe:e=>(n.add(e),()=>{n.delete(e)}),hasPrimary:()=>!t||e>0,register:()=>(e+=1,r(),()=>{--e,r()}),settle:()=>{t||(t=!0,r())}}}var S={subscribe:()=>b,hasPrimary:()=>!0,register:()=>b,settle:b},C=v.createContext(null);C.displayName=`InteractionTagContext`;var w={size:`medium`,shape:`circular`,look:`filled`,disabled:!1,selected:!1,pressed:void 0,dimDisabled:!0,primaryTextId:``,primaries:S,secondaryRef:null,dismiss:()=>{},toggle:()=>{}};function T(e){return v.useContext(C)||(n.reportMissingContext(e,`InteractionTag`),w)}function E(e,t){return typeof e==`string`&&Object.hasOwn(t,e)}function D(e,n){return t.cn(n?[_.INTERACTION_TAG_DISABLED_CLASSES,d.mergedAriaDisabledClasses]:_.INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,e&&u.forcedColors.disabled)}var O="InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.";function k(e,t){if(e)return t?d.MERGED_DISABLED_FOCUSABLE_PROPS:{disabled:!0}}var A=({value:e,appearance:r,size:i,shape:l,disabled:u=!1,selected:d,role:f,hidden:p,className:m,children:g,ref:b,...S})=>{let w=h.useTagGroupContext(),T=v.useRef(null),D=c.useMergedRefs(T,b),k=v.useRef(null),A=s.useId(`interaction-tag-text`),[j]=v.useState(x);v.useLayoutEffect(()=>{j.settle()},[j]);let M=E(i,_.tagSizeClasses)?i:w?.size??`medium`,N=E(r,_.tagAppearanceClasses)?r:w?.appearance??`filled`,P=E(l,_.tagShapeClasses)?l:w?.shape??`circular`,F=(w?.disabled??!1)||u,I=w?.dimDisabled??!0,L=h.useTagGroupItem(T,e),R=w?.selecting??!1,z=R?w?.isSelected(L)??!1:typeof d==`boolean`?d:void 0,B=z===!0,V=B&&!F?`selected`:N,H=R&&d!==void 0;v.useEffect(()=>{H&&n.warnOnce(`InteractionTag:selected-in-group`,O)},[H]);let U=o.useEventCallback(()=>{w?.dismiss(L),w?.deselect(L)}),W=o.useEventCallback(()=>{w?.toggle(L)}),G=w?.mode===`list`?`listitem`:void 0,K=e!==void 0&&(w?.hiddenValues?.has(e)??!1),q=v.useMemo(()=>({size:M,shape:P,look:V,disabled:F,selected:B,pressed:z,dimDisabled:I,primaryTextId:A,primaries:j,secondaryRef:k,dismiss:U,toggle:W}),[M,P,V,F,B,z,I,A,j,U,W]);return(0,y.jsx)(C.Provider,{value:q,children:(0,y.jsx)(`div`,{"data-appearance":N,"data-size":M,"data-shape":P,"data-selected":B?``:void 0,"data-disabled":F?``:void 0,"data-wave-tag-item":``,role:f??G,hidden:K||p,...S,ref:D,className:t.cn(a.interactionTagClassNames.root,`group/interaction-tag inline-flex items-stretch`,m),children:g})})};A.displayName=`InteractionTag`;var j=({media:e,icon:n,secondaryText:o,disabled:s=!1,"aria-pressed":c,className:l,children:d,onClick:f,onKeyDown:p,onFocus:b,onBlur:x,ref:S,...C})=>{let w=T(`InteractionTag.Primary`),{size:E,look:O}=w,A=w.disabled||s,j=h.useHeldFocus(A),M=w.primaries.register;v.useLayoutEffect(()=>M(),[M]);let N=r.slotRendersContent(e),P=r.slotRendersContent(n),F=r.materialiseSlotContent(o),I=r.slotRendersContent(F),L=v.useMemo(()=>({size:_.TAG_AVATAR_SIZE[E]}),[E]),R=e=>{!A&&m.isOwnEvent(e)&&w.toggle()},z=e=>{if(A||e.target!==e.currentTarget||!h.isDismissKey(e))return;let t=w.secondaryRef?.current;t&&!t.disabled&&(e.preventDefault(),t.click())},B=(0,y.jsx)(`span`,{id:w.primaryTextId||void 0,className:t.cn(a.interactionTagPrimaryClassNames.primaryText,I&&`text-caption-1 leading-3.5`),children:d});return(0,y.jsxs)(`button`,{type:`button`,"aria-pressed":w.pressed??c,"data-selected":w.selected?``:void 0,...C,ref:S,onClick:i.composeEventHandlers(f,R),...k(A,j.held),onKeyDown:i.composeEventHandlers(p,z),onFocus:i.composeEventHandlers(b,j.onFocus,{checkDefaultPrevented:!1}),onBlur:i.composeEventHandlers(x,j.onBlur,{checkDefaultPrevented:!1}),className:t.cn(a.interactionTagPrimaryClassNames.root,_.INTERACTION_TAG_BUTTON_BASE_CLASSES,_.INTERACTION_TAG_PRIMARY_BASE_CLASSES,_.tagSizeClasses[E],_.tagStartInsetClasses[E][N?`media`:P?`icon`:`text`],_.interactionTagPrimaryEndInsetClasses[E],_.interactionTagLookClasses[O],O===`selected`&&[u.forcedColors.selectedContainer,`forced-colors:border-[Highlight]`],_.tagShapeClasses[w.shape],_.INTERACTION_TAG_PRIMARY_JOINED_CLASSES,D(A,w.dimDisabled),u.focusRing,E===`extra-small`&&`before:absolute before:inset-x-0 before:-inset-y-0.5`,l),children:[N&&(0,y.jsx)(g.AvatarSizeContext.Provider,{value:L,children:r.renderSlot(e,`span`,t.cn(a.interactionTagPrimaryClassNames.media,_.tagMediaClasses[E]),{"aria-hidden":!0})}),P&&r.renderSlot(n,`span`,t.cn(a.interactionTagPrimaryClassNames.icon,_.tagIconClasses[E]),{"aria-hidden":!0}),I?(0,y.jsxs)(`span`,{className:_.TAG_TEXT_COLUMN_CLASSES,children:[B,` `,(0,y.jsx)(`span`,{className:t.cn(a.interactionTagPrimaryClassNames.secondaryText,_.TAG_SECONDARY_TEXT_CLASSES),children:F})]}):B]})};j.displayName=`InteractionTagPrimary`;var M="InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.",N=({dismissLabel:e=`Dismiss`,disabled:o=!1,"aria-label":g,"aria-labelledby":x,className:S,children:C,onClick:w,onKeyDown:E,onFocus:O,onBlur:A,ref:j,...N})=>{let P=T(`InteractionTag.Secondary`),{size:F,look:I}=P,L=P.disabled||o,R=h.useHeldFocus(L),z=s.useId(`interaction-tag-dismiss`),B=s.useId(`interaction-tag-dismiss-content`),V=v.useRef(null),H=c.useMergedRefs(V,P.secondaryRef,j);h.useDismissControlFocus(V);let{glyph:U,button:W}=d.unwrapButtonGlyph(C);v.useEffect(()=>{W&&n.warnOnce(`InteractionTag.Secondary:button-child`,M)},[W]);let G=r.materialiseSlotContent(U),K=r.slotRendersContent(G),q=K&&p.hasTextLabel(G),[J,Y]=v.useState(null),X=v.useCallback(e=>J?p.observeTextLabel(J,e):b,[J]),Z=v.useSyncExternalStore(X,()=>J?p.hasRenderedTextLabel(J):q,()=>q),Q=K&&Z,ee=v.useSyncExternalStore(P.primaries.subscribe,P.primaries.hasPrimary,()=>!0),$=g!==void 0||x!==void 0,te=$?x:l.joinIds(Q?B:z,ee?P.primaryTextId:void 0),ne=e=>{m.isOwnEvent(e)&&P.dismiss()},re=e=>{if(e.target===e.currentTarget){if(h.isRepeatedActivation(e)){e.preventDefault();return}h.isDismissKey(e)&&(e.preventDefault(),e.currentTarget.click())}};return(0,y.jsxs)(`button`,{type:`button`,"data-wave-tag-dismiss":``,"data-selected":P.selected?``:void 0,...N,ref:H,"aria-label":g,"aria-labelledby":te,onClick:i.composeEventHandlers(w,ne),...k(L,R.held),onKeyDown:i.composeEventHandlers(E,re),onFocus:i.composeEventHandlers(O,R.onFocus,{checkDefaultPrevented:!1}),onBlur:i.composeEventHandlers(A,R.onBlur,{checkDefaultPrevented:!1}),className:t.cn(a.interactionTagSecondaryClassNames.root,_.INTERACTION_TAG_BUTTON_BASE_CLASSES,_.INTERACTION_TAG_SECONDARY_BASE_CLASSES,_.interactionTagSecondarySizeClasses[F],_.interactionTagLookClasses[I],I===`selected`&&[u.forcedColors.selectedContainer,`forced-colors:border-[Highlight]`],_.interactionTagDividerClasses[I],_.interactionTagSecondaryShapeClasses[P.shape],D(L,P.dimDisabled),u.focusRing,F===`extra-small`&&`before:absolute before:inset-x-0 before:-inset-y-0.5`,S),children:[!$&&(0,y.jsx)(`span`,{id:z,className:`sr-only`,children:e}),K?(0,y.jsx)(`span`,{id:B,ref:Y,className:t.cn(a.interactionTagSecondaryClassNames.dismissIcon,`inline-flex items-center justify-center`,Q&&`px-1.5`),children:G}):(0,y.jsx)(f.DismissIcon,{size:_.TAG_DISMISS_GLYPH_SIZE[F],className:a.interactionTagSecondaryClassNames.dismissIcon})]})};N.displayName=`InteractionTagSecondary`;var P=Object.assign(A,{Primary:j,Secondary:N});exports.InteractionTag=P,exports.InteractionTagPrimary=j,exports.InteractionTagSecondary=N;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useEventCallback.cjs"),s=require("../../hooks/useId.cjs"),c=require("../../hooks/useMergedRefs.cjs"),l=require("../../lib/aria.cjs"),u=require("../../lib/styles.cjs"),d=require("../button/Button.slots.cjs"),f=require("../../lib/icons.cjs"),p=require("../../lib/labelInName.cjs"),m=require("../../lib/events.cjs"),h=require("./TagGroup.context.cjs"),g=require("./Avatar.context.cjs"),_=require("./tagStyles.cjs");let v=require("react");v=e.__toESM(v,1);let y=require("react/jsx-runtime");var b=()=>{};function x(){let e=0,t=!1,n=new Set,r=()=>{for(let e of n)e()};return{subscribe:e=>(n.add(e),()=>{n.delete(e)}),hasPrimary:()=>!t||e>0,register:()=>(e+=1,r(),()=>{--e,r()}),settle:()=>{t||(t=!0,r())}}}var S={subscribe:()=>b,hasPrimary:()=>!0,register:()=>b,settle:b},C=v.createContext(null);C.displayName=`InteractionTagContext`;var w={size:`medium`,shape:`circular`,look:`filled`,disabled:!1,selected:!1,pressed:void 0,dimDisabled:!0,primaryTextId:``,primaries:S,secondaryRef:null,dismiss:()=>{},toggle:()=>{}};function T(e){return v.useContext(C)||(n.reportMissingContext(e,`InteractionTag`),w)}function E(e,t){return typeof e==`string`&&Object.hasOwn(t,e)}function D(e,n){return t.cn(n?[_.INTERACTION_TAG_DISABLED_CLASSES,d.mergedAriaDisabledClasses]:_.INTERACTION_TAG_UNDIMMED_DISABLED_CLASSES,e&&u.forcedColors.disabled)}var O="InteractionTag: `selected` has no effect in a TagGroup that selects (`value`, `defaultValue` or `onValueChange`); the group's `value` decides.";function k(e,t){if(e)return t?d.MERGED_DISABLED_FOCUSABLE_PROPS:{disabled:!0}}var A=({value:e,appearance:r,size:i,shape:l,disabled:u=!1,selected:d,role:f,hidden:p,className:m,children:g,ref:b,...S})=>{let w=h.useTagGroupContext(),T=v.useRef(null),D=c.useMergedRefs(T,b),k=v.useRef(null),A=s.useId(`interaction-tag-text`),[j]=v.useState(x);v.useLayoutEffect(()=>{j.settle()},[j]);let M=E(i,_.tagSizeClasses)?i:w?.size??`medium`,N=E(r,_.tagAppearanceClasses)?r:w?.appearance??`filled`,P=E(l,_.tagShapeClasses)?l:w?.shape??`circular`,F=(w?.disabled??!1)||u,I=w?.dimDisabled??!0,L=h.useTagGroupItem(T,e),R=w?.selecting??!1,z=R?w?.isSelected(L)??!1:typeof d==`boolean`?d:void 0,B=z===!0,V=B&&!F?`selected`:N,H=R&&d!==void 0;v.useEffect(()=>{H&&n.warnOnce(`InteractionTag:selected-in-group`,O)},[H]);let U=o.useEventCallback(()=>{w?.dismiss(L),w?.deselect(L)}),W=o.useEventCallback(()=>{w?.toggle(L)}),G=w?.mode===`list`?`listitem`:void 0,K=e!==void 0&&(w?.hiddenValues?.has(e)??!1),q=v.useMemo(()=>({size:M,shape:P,look:V,disabled:F,selected:B,pressed:z,dimDisabled:I,primaryTextId:A,primaries:j,secondaryRef:k,dismiss:U,toggle:W}),[M,P,V,F,B,z,I,A,j,U,W]);return(0,y.jsx)(C.Provider,{value:q,children:(0,y.jsx)(`div`,{"data-appearance":N,"data-size":M,"data-shape":P,"data-selected":B?``:void 0,"data-disabled":F?``:void 0,"data-wave-tag-item":``,role:f??G,hidden:K||p,...S,ref:D,className:t.cn(a.interactionTagClassNames.root,`group/interaction-tag inline-flex items-stretch`,m),children:g})})};A.displayName=`InteractionTag`;var j=({media:e,icon:n,secondaryText:o,disabled:s=!1,"aria-pressed":c,className:l,children:d,onClick:f,onKeyDown:p,onFocus:b,onBlur:x,ref:S,...C})=>{let w=T(`InteractionTag.Primary`),{size:E,look:O,shape:A}=w,j=w.disabled||s,M=h.useHeldFocus(j),N=w.primaries.register;v.useLayoutEffect(()=>N(),[N]);let P=r.slotRendersContent(e),F=r.slotRendersContent(n),I=r.materialiseSlotContent(o),L=r.slotRendersContent(I),R=v.useMemo(()=>({size:_.TAG_AVATAR_SIZE[E],shape:A===`rounded`?`square`:`circular`}),[E,A]),z=e=>{!j&&m.isOwnEvent(e)&&w.toggle()},B=e=>{if(j||e.target!==e.currentTarget||!h.isDismissKey(e))return;let t=w.secondaryRef?.current;t&&!t.disabled&&(e.preventDefault(),t.click())},V=(0,y.jsx)(`span`,{id:w.primaryTextId||void 0,className:t.cn(a.interactionTagPrimaryClassNames.primaryText,L&&`text-caption-1 leading-3.5`),children:d});return(0,y.jsxs)(`button`,{type:`button`,"aria-pressed":w.pressed??c,"data-selected":w.selected?``:void 0,...C,ref:S,onClick:i.composeEventHandlers(f,z),...k(j,M.held),onKeyDown:i.composeEventHandlers(p,B),onFocus:i.composeEventHandlers(b,M.onFocus,{checkDefaultPrevented:!1}),onBlur:i.composeEventHandlers(x,M.onBlur,{checkDefaultPrevented:!1}),className:t.cn(a.interactionTagPrimaryClassNames.root,_.INTERACTION_TAG_BUTTON_BASE_CLASSES,_.INTERACTION_TAG_PRIMARY_BASE_CLASSES,_.tagSizeClasses[E],_.tagStartInsetClasses[E][P?`media`:F?`icon`:`text`],_.interactionTagPrimaryEndInsetClasses[E],_.interactionTagLookClasses[O],O===`selected`&&[u.forcedColors.selectedContainer,`forced-colors:border-[Highlight]`],_.tagShapeClasses[w.shape],_.INTERACTION_TAG_PRIMARY_JOINED_CLASSES,D(j,w.dimDisabled),u.focusRing,E===`extra-small`&&`before:absolute before:inset-x-0 before:-inset-y-0.5`,l),children:[P&&(0,y.jsx)(g.AvatarSizeContext.Provider,{value:R,children:r.renderSlot(e,`span`,t.cn(a.interactionTagPrimaryClassNames.media,_.tagMediaClasses[E]),{"aria-hidden":!0})}),F&&r.renderSlot(n,`span`,t.cn(a.interactionTagPrimaryClassNames.icon,_.tagIconClasses[E]),{"aria-hidden":!0}),L?(0,y.jsxs)(`span`,{className:_.TAG_TEXT_COLUMN_CLASSES,children:[V,` `,(0,y.jsx)(`span`,{className:t.cn(a.interactionTagPrimaryClassNames.secondaryText,_.TAG_SECONDARY_TEXT_CLASSES),children:I})]}):V]})};j.displayName=`InteractionTagPrimary`;var M="InteractionTag.Secondary: its content received a button. A button cannot contain a button: its children became the content of the Dismiss button and its props were dropped. Pass icon content, and handle the dismissal in `onClick` or in the TagGroup's `onDismiss`.",N=({dismissLabel:e=`Dismiss`,disabled:o=!1,"aria-label":g,"aria-labelledby":x,className:S,children:C,onClick:w,onKeyDown:E,onFocus:O,onBlur:A,ref:j,...N})=>{let P=T(`InteractionTag.Secondary`),{size:F,look:I}=P,L=P.disabled||o,R=h.useHeldFocus(L),z=s.useId(`interaction-tag-dismiss`),B=s.useId(`interaction-tag-dismiss-content`),V=v.useRef(null),H=c.useMergedRefs(V,P.secondaryRef,j);h.useDismissControlFocus(V);let{glyph:U,button:W}=d.unwrapButtonGlyph(C);v.useEffect(()=>{W&&n.warnOnce(`InteractionTag.Secondary:button-child`,M)},[W]);let G=r.materialiseSlotContent(U),K=r.slotRendersContent(G),q=K&&p.hasTextLabel(G),[J,Y]=v.useState(null),X=v.useCallback(e=>J?p.observeTextLabel(J,e):b,[J]),Z=v.useSyncExternalStore(X,()=>J?p.hasRenderedTextLabel(J):q,()=>q),Q=K&&Z,ee=v.useSyncExternalStore(P.primaries.subscribe,P.primaries.hasPrimary,()=>!0),$=g!==void 0||x!==void 0,te=$?x:l.joinIds(Q?B:z,ee?P.primaryTextId:void 0),ne=e=>{m.isOwnEvent(e)&&P.dismiss()},re=e=>{if(e.target===e.currentTarget){if(h.isRepeatedActivation(e)){e.preventDefault();return}h.isDismissKey(e)&&(e.preventDefault(),e.currentTarget.click())}};return(0,y.jsxs)(`button`,{type:`button`,"data-wave-tag-dismiss":``,"data-selected":P.selected?``:void 0,...N,ref:H,"aria-label":g,"aria-labelledby":te,onClick:i.composeEventHandlers(w,ne),...k(L,R.held),onKeyDown:i.composeEventHandlers(E,re),onFocus:i.composeEventHandlers(O,R.onFocus,{checkDefaultPrevented:!1}),onBlur:i.composeEventHandlers(A,R.onBlur,{checkDefaultPrevented:!1}),className:t.cn(a.interactionTagSecondaryClassNames.root,_.INTERACTION_TAG_BUTTON_BASE_CLASSES,_.INTERACTION_TAG_SECONDARY_BASE_CLASSES,_.interactionTagSecondarySizeClasses[F],_.interactionTagLookClasses[I],I===`selected`&&[u.forcedColors.selectedContainer,`forced-colors:border-[Highlight]`],_.interactionTagDividerClasses[I],_.interactionTagSecondaryShapeClasses[P.shape],D(L,P.dimDisabled),u.focusRing,F===`extra-small`&&`before:absolute before:inset-x-0 before:-inset-y-0.5`,S),children:[!$&&(0,y.jsx)(`span`,{id:z,className:`sr-only`,children:e}),K?(0,y.jsx)(`span`,{id:B,ref:Y,className:t.cn(a.interactionTagSecondaryClassNames.dismissIcon,`inline-flex items-center justify-center`,Q&&`px-1.5`),children:G}):(0,y.jsx)(f.DismissIcon,{size:_.TAG_DISMISS_GLYPH_SIZE[F],className:a.interactionTagSecondaryClassNames.dismissIcon})]})};N.displayName=`InteractionTagSecondary`;var P=Object.assign(A,{Primary:j,Secondary:N});exports.InteractionTag=P,exports.InteractionTagPrimary=j,exports.InteractionTagSecondary=N;
2
2
  //# sourceMappingURL=InteractionTag.cjs.map