@fluentui/react-avatar 9.0.4 → 9.1.1

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 (131) hide show
  1. package/CHANGELOG.json +214 -6
  2. package/CHANGELOG.md +52 -7
  3. package/README-AvatarGroup.md +63 -39
  4. package/SPEC-AvatarGroup.md +103 -85
  5. package/dist/index.d.ts +97 -64
  6. package/lib/AvatarGroupPopover.js +2 -0
  7. package/lib/AvatarGroupPopover.js.map +1 -0
  8. package/lib/components/Avatar/useAvatar.js +3 -7
  9. package/lib/components/Avatar/useAvatar.js.map +1 -1
  10. package/lib/components/Avatar/useAvatarStyles.js +2 -2
  11. package/lib/components/Avatar/useAvatarStyles.js.map +1 -1
  12. package/lib/components/AvatarGroup/AvatarGroup.js +4 -2
  13. package/lib/components/AvatarGroup/AvatarGroup.js.map +1 -1
  14. package/lib/components/AvatarGroup/AvatarGroup.types.js.map +1 -1
  15. package/lib/components/AvatarGroup/index.js +1 -0
  16. package/lib/components/AvatarGroup/index.js.map +1 -1
  17. package/lib/components/AvatarGroup/renderAvatarGroup.js +5 -31
  18. package/lib/components/AvatarGroup/renderAvatarGroup.js.map +1 -1
  19. package/lib/components/AvatarGroup/useAvatarGroup.js +4 -62
  20. package/lib/components/AvatarGroup/useAvatarGroup.js.map +1 -1
  21. package/lib/components/AvatarGroup/useAvatarGroupContextValues.js +14 -0
  22. package/lib/components/AvatarGroup/useAvatarGroupContextValues.js.map +1 -0
  23. package/lib/components/AvatarGroup/useAvatarGroupStyles.js +5 -268
  24. package/lib/components/AvatarGroup/useAvatarGroupStyles.js.map +1 -1
  25. package/lib/components/AvatarGroupItem/AvatarGroupItem.js +1 -1
  26. package/lib/components/AvatarGroupItem/AvatarGroupItem.js.map +1 -1
  27. package/lib/components/AvatarGroupItem/AvatarGroupItem.types.js.map +1 -1
  28. package/lib/components/AvatarGroupItem/useAvatarGroupItem.js +10 -11
  29. package/lib/components/AvatarGroupItem/useAvatarGroupItem.js.map +1 -1
  30. package/lib/components/AvatarGroupItem/useAvatarGroupItemStyles.js +51 -59
  31. package/lib/components/AvatarGroupItem/useAvatarGroupItemStyles.js.map +1 -1
  32. package/lib/components/AvatarGroupPopover/AvatarGroupPopover.js +16 -0
  33. package/lib/components/AvatarGroupPopover/AvatarGroupPopover.js.map +1 -0
  34. package/lib/components/AvatarGroupPopover/AvatarGroupPopover.types.js +2 -0
  35. package/lib/components/AvatarGroupPopover/AvatarGroupPopover.types.js.map +1 -0
  36. package/lib/components/AvatarGroupPopover/index.js +6 -0
  37. package/lib/components/AvatarGroupPopover/index.js.map +1 -0
  38. package/lib/components/AvatarGroupPopover/renderAvatarGroupPopover.js +23 -0
  39. package/lib/components/AvatarGroupPopover/renderAvatarGroupPopover.js.map +1 -0
  40. package/lib/components/AvatarGroupPopover/useAvatarGroupPopover.js +102 -0
  41. package/lib/components/AvatarGroupPopover/useAvatarGroupPopover.js.map +1 -0
  42. package/lib/components/AvatarGroupPopover/useAvatarGroupPopoverContextValues.js +10 -0
  43. package/lib/components/AvatarGroupPopover/useAvatarGroupPopoverContextValues.js.map +1 -0
  44. package/lib/components/AvatarGroupPopover/useAvatarGroupPopoverStyles.js +307 -0
  45. package/lib/components/AvatarGroupPopover/useAvatarGroupPopoverStyles.js.map +1 -0
  46. package/lib/contexts/AvatarGroupContext.js +7 -4
  47. package/lib/contexts/AvatarGroupContext.js.map +1 -1
  48. package/lib/index.js +4 -3
  49. package/lib/index.js.map +1 -1
  50. package/lib/utils/index.js +1 -0
  51. package/lib/utils/index.js.map +1 -1
  52. package/lib/utils/partitionAvatarGroupItems.js +30 -0
  53. package/lib/utils/partitionAvatarGroupItems.js.map +1 -0
  54. package/lib-commonjs/{AvatarGroupOverflow.js → AvatarGroupPopover.js} +2 -2
  55. package/lib-commonjs/AvatarGroupPopover.js.map +1 -0
  56. package/lib-commonjs/components/Avatar/useAvatar.js +2 -7
  57. package/lib-commonjs/components/Avatar/useAvatar.js.map +1 -1
  58. package/lib-commonjs/components/Avatar/useAvatarStyles.js +2 -2
  59. package/lib-commonjs/components/Avatar/useAvatarStyles.js.map +1 -1
  60. package/lib-commonjs/components/AvatarGroup/AvatarGroup.js +5 -2
  61. package/lib-commonjs/components/AvatarGroup/AvatarGroup.js.map +1 -1
  62. package/lib-commonjs/components/AvatarGroup/index.js +2 -0
  63. package/lib-commonjs/components/AvatarGroup/index.js.map +1 -1
  64. package/lib-commonjs/components/AvatarGroup/renderAvatarGroup.js +4 -32
  65. package/lib-commonjs/components/AvatarGroup/renderAvatarGroup.js.map +1 -1
  66. package/lib-commonjs/components/AvatarGroup/useAvatarGroup.js +3 -64
  67. package/lib-commonjs/components/AvatarGroup/useAvatarGroup.js.map +1 -1
  68. package/lib-commonjs/components/AvatarGroup/useAvatarGroupContextValues.js +23 -0
  69. package/lib-commonjs/components/AvatarGroup/useAvatarGroupContextValues.js.map +1 -0
  70. package/lib-commonjs/components/AvatarGroup/useAvatarGroupStyles.js +3 -268
  71. package/lib-commonjs/components/AvatarGroup/useAvatarGroupStyles.js.map +1 -1
  72. package/lib-commonjs/components/AvatarGroupItem/AvatarGroupItem.js +2 -2
  73. package/lib-commonjs/components/AvatarGroupItem/AvatarGroupItem.js.map +1 -1
  74. package/lib-commonjs/components/AvatarGroupItem/useAvatarGroupItem.js +8 -9
  75. package/lib-commonjs/components/AvatarGroupItem/useAvatarGroupItem.js.map +1 -1
  76. package/lib-commonjs/components/AvatarGroupItem/useAvatarGroupItemStyles.js +52 -60
  77. package/lib-commonjs/components/AvatarGroupItem/useAvatarGroupItemStyles.js.map +1 -1
  78. package/lib-commonjs/components/AvatarGroupPopover/AvatarGroupPopover.js +29 -0
  79. package/lib-commonjs/components/AvatarGroupPopover/AvatarGroupPopover.js.map +1 -0
  80. package/lib-commonjs/{contexts/AvatarGroupContext.types.js → components/AvatarGroupPopover/AvatarGroupPopover.types.js} +1 -1
  81. package/lib-commonjs/{contexts/AvatarGroupContext.types.js.map → components/AvatarGroupPopover/AvatarGroupPopover.types.js.map} +0 -0
  82. package/lib-commonjs/components/AvatarGroupPopover/index.js +18 -0
  83. package/lib-commonjs/components/AvatarGroupPopover/index.js.map +1 -0
  84. package/lib-commonjs/components/AvatarGroupPopover/renderAvatarGroupPopover.js +36 -0
  85. package/lib-commonjs/components/AvatarGroupPopover/renderAvatarGroupPopover.js.map +1 -0
  86. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopover.js +118 -0
  87. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopover.js.map +1 -0
  88. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopoverContextValues.js +19 -0
  89. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopoverContextValues.js.map +1 -0
  90. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopoverStyles.js +321 -0
  91. package/lib-commonjs/components/AvatarGroupPopover/useAvatarGroupPopoverStyles.js.map +1 -0
  92. package/lib-commonjs/contexts/AvatarGroupContext.js +10 -4
  93. package/lib-commonjs/contexts/AvatarGroupContext.js.map +1 -1
  94. package/lib-commonjs/index.js +60 -4
  95. package/lib-commonjs/index.js.map +1 -1
  96. package/lib-commonjs/utils/index.js +10 -1
  97. package/lib-commonjs/utils/index.js.map +1 -1
  98. package/lib-commonjs/utils/partitionAvatarGroupItems.js +39 -0
  99. package/lib-commonjs/utils/partitionAvatarGroupItems.js.map +1 -0
  100. package/package.json +14 -12
  101. package/MIGRATION-AvatarGroup.md +0 -35
  102. package/dist/tsdoc-metadata.json +0 -11
  103. package/lib/AvatarGroupOverflow.js +0 -2
  104. package/lib/AvatarGroupOverflow.js.map +0 -1
  105. package/lib/components/AvatarGroupOverflow/AvatarGroupOverflow.js +0 -15
  106. package/lib/components/AvatarGroupOverflow/AvatarGroupOverflow.js.map +0 -1
  107. package/lib/components/AvatarGroupOverflow/AvatarGroupOverflow.types.js +0 -2
  108. package/lib/components/AvatarGroupOverflow/AvatarGroupOverflow.types.js.map +0 -1
  109. package/lib/components/AvatarGroupOverflow/index.js +0 -6
  110. package/lib/components/AvatarGroupOverflow/index.js.map +0 -1
  111. package/lib/components/AvatarGroupOverflow/renderAvatarGroupOverflow.js +0 -16
  112. package/lib/components/AvatarGroupOverflow/renderAvatarGroupOverflow.js.map +0 -1
  113. package/lib/components/AvatarGroupOverflow/useAvatarGroupOverflow.js +0 -27
  114. package/lib/components/AvatarGroupOverflow/useAvatarGroupOverflow.js.map +0 -1
  115. package/lib/components/AvatarGroupOverflow/useAvatarGroupOverflowStyles.js +0 -27
  116. package/lib/components/AvatarGroupOverflow/useAvatarGroupOverflowStyles.js.map +0 -1
  117. package/lib/contexts/AvatarGroupContext.types.js +0 -2
  118. package/lib/contexts/AvatarGroupContext.types.js.map +0 -1
  119. package/lib-commonjs/AvatarGroupOverflow.js.map +0 -1
  120. package/lib-commonjs/components/AvatarGroupOverflow/AvatarGroupOverflow.js +0 -26
  121. package/lib-commonjs/components/AvatarGroupOverflow/AvatarGroupOverflow.js.map +0 -1
  122. package/lib-commonjs/components/AvatarGroupOverflow/AvatarGroupOverflow.types.js +0 -6
  123. package/lib-commonjs/components/AvatarGroupOverflow/AvatarGroupOverflow.types.js.map +0 -1
  124. package/lib-commonjs/components/AvatarGroupOverflow/index.js +0 -18
  125. package/lib-commonjs/components/AvatarGroupOverflow/index.js.map +0 -1
  126. package/lib-commonjs/components/AvatarGroupOverflow/renderAvatarGroupOverflow.js +0 -27
  127. package/lib-commonjs/components/AvatarGroupOverflow/renderAvatarGroupOverflow.js.map +0 -1
  128. package/lib-commonjs/components/AvatarGroupOverflow/useAvatarGroupOverflow.js +0 -37
  129. package/lib-commonjs/components/AvatarGroupOverflow/useAvatarGroupOverflow.js.map +0 -1
  130. package/lib-commonjs/components/AvatarGroupOverflow/useAvatarGroupOverflowStyles.js +0 -37
  131. package/lib-commonjs/components/AvatarGroupOverflow/useAvatarGroupOverflowStyles.js.map +0 -1
@@ -28,16 +28,33 @@ There's only one existent component similar to AvatarGroup in v8 `Facepile`. v0
28
28
  ## Sample Code
29
29
 
30
30
  ```jsx
31
- import { AvatarGroup, Avatar } from '@fluentui/react-avatar';
31
+ const names = [
32
+ 'Johnie McConnell',
33
+ 'Allan Munger',
34
+ 'Erik Nason',
35
+ 'Kristin Patterson',
36
+ 'Daisy Phillips',
37
+ 'Carole Poland',
38
+ 'Carlos Slattery',
39
+ 'Robert Tolbert',
40
+ 'Kevin Sturgis',
41
+ 'Charlotte Waltson',
42
+ 'Elliot Woodward',
43
+ ];
44
+
45
+ const AvatarGroup = () => {
46
+ const { inlineItems, overflowItems } = partitionAvatarGroupItems({ items: names });
32
47
 
33
- const App = () => {
34
48
  return (
35
- <AvatarGroup layout="spread" size={32}>
36
- <Avatar color="colorful" name="Katri Athokas" />
37
- <Avatar color="colorful" name="Elvia Atkins" />
38
- <Avatar color="colorful" name="Cameron Evans" />
39
- <Avatar color="colorful" name="Wanda Howard" />
40
- <Avatar color="colorful" name="Mona Kane" />
49
+ <AvatarGroup {...props}>
50
+ {inlineItems.map(name => (
51
+ <AvatarGroupItem name={name} key={name} />
52
+ ))}
53
+ <AvatarGroupPopover>
54
+ {overflowItems.map(name => (
55
+ <AvatarGroupItem name={name} key={name} />
56
+ ))}
57
+ </AvatarGroupPopover>
41
58
  </AvatarGroup>
42
59
  );
43
60
  };
@@ -49,79 +66,77 @@ There are three layout variants in AvatarGroup:
49
66
 
50
67
  - Spread layout (Default): Avatars are spaced evenly.
51
68
  - Stack layout: Avatars are overlapped evenly.
52
- - Pie layout: For the pie layout there can be a minimum of two Avatars and a maximum of three. This layout does not overflow and provides a popover for more details.
53
-
54
- - If the size of the avatar group is `36` or smaller then only the first letter of the initials will be displayed.
55
- - `maxAvatars` will be ignored when using this layout.
56
-
57
- - The `spread` and `stack` layouts have a maximum of 5 avatars before overflowing by default, which can be overridden via the `maxAvatars` prop.
69
+ - Pie layout: Avatars are "cut" in a pie design. When there are two Avatars inline, the Avatars will be cut in half and placed side by side. When there are three Avatars inline, the first Avatar will be cut in half and other two will be downscaled by 50%.
70
+ - The pie layout must have 3 or less Avatars inline and all Avatars must repeat in the `AvatarGroupPopover`. This is handled by `partitionAvatarGroupItems`.
71
+ - If `partitionAvatarGroupItems` is used, the `spread` and `stack` layouts will have a maximum of 5 avatars before overflowing by default. This can be overridden via the `maxAvatars` option in `partitionAvatarGroupItems`.
58
72
 
59
73
  ## API
60
74
 
61
- See [AvatarGroup.types.ts](./src/components/AvatarGroup/AvatarGroup.types.ts) for more details.
75
+ See [AvatarGroup.types.ts](./src/components/AvatarGroup/AvatarGroup.types.ts), [AvatarGroupPopover.types.ts](./src/components/AvatarGroupPopover/AvatarGroupPopover.types.ts) and [AvatarGroupItem.types.ts](./src/components/AvatarGroupItem/AvatarGroupItem.types.ts) for more details.
62
76
 
63
77
  - `size`: Group size will override the children's current size. This is to ensure that the `AvatarGroup`'s spacing is correct because it changes depending on the group size.
64
- - `popoverSurface`: All Avatars in `popoverSurface` will have a size of 24 and will be encased in a div to apply stylings.
65
- - Avatar `color`: AvatarGroup's colors will follow the order below, but they can be overriden by providing a color specific color on a given avatar.
78
+ - `AvatarGroupPopover`: All Avatars in `AvatarGroupPopover` will have a size of 24 and have a wrapper to apply stylings.
79
+ - AvatarGroupItem `color`: Can be overridden by providing a specific color on a given avatar.
66
80
 
67
81
  #### Color override example:
68
82
 
69
- In this example, the first Avatar will have a `darkRed` color, while all the other avatars will follow the default color order.
83
+ In this example, the first AvatarGroupItem will have a `darkRed` color, while all the other Avatars have their color assigned by Avatar.
70
84
 
71
85
  ```jsx
72
86
  <AvatarGroup>
73
- <Avatar color="darkRed" name="Katri Athokas" />
74
- <Avatar name="Elvia Atkins" />
75
- <Avatar name="Cameron Evans" />
76
- <Avatar name="Wanda Howard" />
77
- <Avatar name="Mona Kane" />
87
+ <AvatarGroupItem color="darkRed" name="Katri Athokas" />
88
+ <AvatarGroupItem name="Elvia Atkins" />
89
+ <AvatarGroupItem name="Cameron Evans" />
90
+ <AvatarGroupItem name="Wanda Howard" />
91
+ <AvatarGroupItem name="Mona Kane" />
78
92
  </AvatarGroup>
79
93
  ```
80
94
 
81
- #### Color order:
82
-
83
- | | | |
84
- | --------------------- | ------------------ | --------------------- |
85
- | Avatar 1: Red | Avatar 2: Blue | Avatar 3: Purple |
86
- | Avatar 4: Forest | Avatar 5: Pink | Avatar 6: Lavender |
87
- | Avatar 7: Teal | Avatar 8: Gold | Avatar 9: Cranberry |
88
- | Avatar 10: Cornflower | Avatar 11: Lilac | Avatar 12: Anchor |
89
- | Avatar 13: Dark Green | Avatar 14: Pumpkin | Avatar 15: Dark Red |
90
- | Avatar 16: Mink | Avatar 17: Grape | Avatar 18: Platinum |
91
- | Avatar 19: Royal Blue | Avatar 20: Brown | Avatar 21: Peach |
92
- | Avatar 22: Steel | Avatar 23: Navy | Avatar 24: Seafoam |
93
- | Avatar 25: Magenta | Avatar 26: Beige | Avatar 27: Light Teal |
94
- | Avatar 28: Gold | Avatar 29: Plum | Avatar 30: Marigold |
95
-
96
95
  ## Structure
97
96
 
98
97
  - _**Public**_
99
98
 
100
99
  ```jsx
101
100
  <AvatarGroup layout="spread" size={32}>
102
- <Avatar name="Katri Athokas" />
103
- <Avatar name="Elvia Atkins" />
104
- <Avatar name="Cameron Evans" />
105
- <Avatar name="Wanda Howard" />
106
- <Avatar name="Mona Kane" />
101
+ <AvatarGroupItem name="Katri Athokas" />
102
+ <AvatarGroupItem name="Elvia Atkins" />
103
+ <AvatarGroupItem name="Cameron Evans" />
104
+ <AvatarGroupItem name="Wanda Howard" />
105
+ <AvatarGroupPopover>
106
+ <AvatarGroupItem name="Mona Kane" />
107
+ <AvatarGroupItem name="Kristin Patterson" />
108
+ <AvatarGroupItem name="Elliot Woodward" />
109
+ <AvatarGroupItem name="Charlotte Waltson" />
110
+ </AvatarGroupPopover>
107
111
  </AvatarGroup>
108
112
  ```
109
113
 
110
114
  - _**Internal**_
111
115
 
112
116
  ```jsx
117
+ // AvatarGroup
118
+ <AvatarGroupProvider value={contextValues.avatarGroup}>
119
+ <slots.root {...slotProps.root} />
120
+ </AvatarGroupProvider>
121
+
122
+ // AvatarGroupPopover
123
+ <slots.root {...(slotProps.root as PopoverProps)}>
124
+ <PopoverTrigger>
125
+ <slots.tooltip {...(slotProps.tooltip as TooltipProps)}>
126
+ <slots.triggerButton {...slotProps.triggerButton} />
127
+ </slots.tooltip>
128
+ </PopoverTrigger>
129
+ <slots.popoverSurface {...slotProps.popoverSurface}>
130
+ <AvatarGroupProvider value={contextValues.avatarGroup}>
131
+ <slots.content {...slotProps.content} />
132
+ </AvatarGroupProvider>
133
+ </slots.popoverSurface>
134
+ </slots.root>
135
+
136
+ // AvatarGroupItem
113
137
  <slots.root {...slotProps.root}>
114
- {state.root.children}
115
- {slots.popoverSurface && slots.popoverTrigger && slotProps.popoverSurface.children && (
116
- <Popover trapFocus size="small">
117
- <PopoverTrigger>
118
- <Tooltip content={state.tooltipContent} relationship="description" appearance="inverted">
119
- <slots.popoverTrigger {...slotProps.popoverTrigger} />
120
- </Tooltip>
121
- </PopoverTrigger>
122
- <slots.popoverSurface {...slotProps.popoverSurface} />
123
- </Popover>
124
- )}
138
+ <slots.avatar {...slotProps.avatar} />
139
+ {state.isOverflowItem && <slots.overflowLabel {...slotProps.overflowLabel} />}
125
140
  </slots.root>
126
141
  ```
127
142
 
@@ -129,46 +144,49 @@ In this example, the first Avatar will have a `darkRed` color, while all the oth
129
144
 
130
145
  ```html
131
146
  <div className="fui-AvatarGroup" role="group">
132
- <Avatar />
133
- <Avatar />
134
- <Avatar />
135
- <Avatar />
136
- <button>+1</button>
137
- </div>
138
-
139
- // on document.body
140
- <div class="fui-AvatarGroup__popoverSurface" role="complementary">
141
- <div class="fui-AvatarGroup__popoverSurfaceItem">
147
+ <div class="fui-AvatarGroupItem">
142
148
  <Avatar />
143
- <label />
144
149
  </div>
145
- <!-- ... -->
146
- <div class="fui-AvatarGroup__popoverSurfaceItem">
150
+ <div class="fui-AvatarGroupItem">
147
151
  <Avatar />
148
- <label />
149
152
  </div>
153
+ <button>+1</button>
154
+ </div>
155
+
156
+ // on document.body
157
+ <div class="fui-AvatarGroupPopover" role="dialog" aria-label="Overflow">
158
+ <ul>
159
+ <li class="fui-AvatarGroupItem">
160
+ <Avatar />
161
+ <label />
162
+ </li>
163
+ <li class="fui-AvatarGroupItem">
164
+ <Avatar />
165
+ <label />
166
+ </li>
167
+ </ul>
150
168
  </div>
151
169
  ```
152
170
 
153
171
  ## Migration
154
172
 
155
- See [MIGRATION-AvatarGroup.md](MIGRATION-AvatarGroup.md) for details.
173
+ See [v8 to v9 migration guide](https://react.fluentui.dev/?path=/docs/concepts-upgrading-from-v8-components-avatargroup-upgrade--page) for details.
156
174
 
157
175
  ## Behaviors
158
176
 
159
177
  _Explain how the component will behave in use, including:_
160
178
 
161
- - _Component States_
162
- - Overflowed state: When there are more Avatars than the `maxAvatars`, an overflow indicator will be rendered that can be clicked to look at the rest of the avatars.
163
- - `Pie` layout: since `maxAvatars` is ignored, the overflow indicator will be rendered strictly when there's more than three avatars.
164
- - _Interaction_
165
- - _Keyboard_: Overflow indicator can be interacted with the keyboard and when enter is pressed a popover that traps focus will be rendered.
166
- - _Cursor_ and _Touch_: When overflow indicator is clicked, the popover is displayed with the avatars that overflow. When the overflow indicator is hovered, a tooltip will read the number of people overflowed (`{numOverflowAvatars} more people` by default).
179
+ - _AvatarGroupPopover Component States_
180
+
181
+ - _Keyboard_: `triggerButton` can be interacted with the keyboard and when enter is pressed a popover that traps focus on the PopoverSurface will be rendered.
182
+ - _Cursor_ and _Touch_: When overflow indicator is clicked, the popover is displayed with the avatars that overflow. When the overflow indicator is hovered, a tooltip will read `View more people.`.
183
+ - _Screen readers_:
184
+ - When the `triggerButton` is focused, its content will be read.
185
+
186
+ - _AvatarGroupItem Component States_
167
187
  - _Screen readers_:
168
- - `Avatar`: logic is handled by `Avatar` component.
169
- - `AvatarGroup`:
170
- - When a label is used alongside `AvatarGroup` and focused, all Avatars are read. If the overflow indicator is rendered, the popover localized text is read.
171
- - Avatars can be focused and the name will be read. To get to the Avatars in the overflow menu, the Popover must be triggered, which will in turn set focus on it and let the user traverse through the set of overflowed Avatars.
188
+ - When AvatarGroupItem is rendered inline, logic is handled by `Avatar` component.
189
+ - When AvatarGroupItem is rendered inside AvatarGroupPopover, the label is disabled via `aria-label` and `Avatar` will handle the screen reader.
172
190
 
173
191
  ## Accessibility
174
192
 
@@ -176,10 +194,10 @@ Base accessibility information is included in the design document. After the spe
176
194
 
177
195
  - There's no native element for this component.
178
196
 
179
- - `AvatarGroup` will have a role of `group` and slots will be handled by their respective slot type.
180
- - Only the overflow indicator will be focusable by the keyboard. After the overflow indicator is pressed, the popover will handle focus using the `trapFocus` prop.
197
+ - `AvatarGroup` will have a role of `group`.
198
+ - Only the `popoverTrigger` will be focusable by the keyboard.
181
199
  - There are no live-regions in `AvatarGroup`.
182
- - A Tooltip will appear when the overflow indicator is hovered or focused.
183
- - Screen reader: when overflow indicator is rendered and focused, screen reader will read the content of the tooltip.
184
- - Tooltip cannot be focused itself.
185
- - Focus will only be trapped when the overflow indicator is triggered.
200
+ - A Tooltip will appear when the `popoverTrigger` is hovered or focused.
201
+ - Focus will only be trapped when the `popoverTrigger` is triggered.
202
+ - The label rendered along with the Avatar inside AvatarGroupPopover is disabled via `aria-label`.
203
+ - A `<ul>` with role list is rendered inside the PopoverSurface.
package/dist/index.d.ts CHANGED
@@ -2,13 +2,18 @@
2
2
 
3
3
  import type { ComponentProps } from '@fluentui/react-utilities';
4
4
  import type { ComponentState } from '@fluentui/react-utilities';
5
+ import { ContextSelector } from '@fluentui/react-context-selector';
6
+ import { FC } from 'react';
5
7
  import type { ForwardRefComponent } from '@fluentui/react-utilities';
6
- import { PopoverSurface } from '@fluentui/react-popover';
8
+ import type { PopoverProps } from '@fluentui/react-popover';
9
+ import type { PopoverSurface } from '@fluentui/react-popover';
7
10
  import { PresenceBadge } from '@fluentui/react-badge';
11
+ import { Provider } from 'react';
12
+ import { ProviderProps } from 'react';
8
13
  import * as React_2 from 'react';
9
14
  import type { Slot } from '@fluentui/react-utilities';
10
15
  import type { SlotClassNames } from '@fluentui/react-utilities';
11
- import { TooltipProps } from '@fluentui/react-tooltip';
16
+ import type { TooltipProps } from '@fluentui/react-tooltip';
12
17
 
13
18
  export declare const Avatar: ForwardRefComponent<AvatarProps>;
14
19
 
@@ -22,6 +27,14 @@ export declare const AvatarGroup: ForwardRefComponent<AvatarGroupProps>;
22
27
 
23
28
  export declare const avatarGroupClassNames: SlotClassNames<AvatarGroupSlots>;
24
29
 
30
+ export declare type AvatarGroupContextValue = Pick<AvatarGroupProps, 'size' | 'layout'> & {
31
+ isOverflow?: boolean;
32
+ };
33
+
34
+ export declare type AvatarGroupContextValues = {
35
+ avatarGroup: AvatarGroupContextValue;
36
+ };
37
+
25
38
  /**
26
39
  * The AvatarGroupItem component represents a single person or entity.
27
40
  * AvatarGroupItem should only be used in an AvatarGroup component.
@@ -36,7 +49,7 @@ export declare const avatarGroupItemClassNames: SlotClassNames<AvatarGroupItemSl
36
49
  export declare type AvatarGroupItemProps = Omit<ComponentProps<Partial<AvatarGroupItemSlots>, 'avatar'>, 'size' | 'shape'>;
37
50
 
38
51
  export declare type AvatarGroupItemSlots = {
39
- root: NonNullable<Slot<'div'>>;
52
+ root: NonNullable<Slot<'div', 'li'>>;
40
53
  /**
41
54
  * Avatar that represents a person or entity.
42
55
  */
@@ -58,93 +71,92 @@ export declare type AvatarGroupItemState = ComponentState<AvatarGroupItemSlots>
58
71
  * @default false
59
72
  */
60
73
  isOverflowItem?: boolean;
61
- nonOverflowAvatarsCount: number;
62
74
  layout: AvatarGroupProps['layout'];
63
75
  size: AvatarSizes;
64
76
  };
65
77
 
66
78
  /**
67
- * AvatarGroupOverflow component - TODO: add more docs
79
+ * The AvatarGroupPopover component provides a button with a Popover containing the children provided.
68
80
  */
69
- export declare const AvatarGroupOverflow: ForwardRefComponent<AvatarGroupOverflowProps>;
70
-
71
- export declare const avatarGroupOverflowClassName = "fui-AvatarGroupOverflow";
81
+ export declare const AvatarGroupPopover: React_2.FC<AvatarGroupPopoverProps>;
72
82
 
73
- export declare const avatarGroupOverflowClassNames: SlotClassNames<AvatarGroupOverflowSlots>;
83
+ export declare const avatarGroupPopoverClassNames: SlotClassNames<AvatarGroupPopoverSlots>;
74
84
 
75
85
  /**
76
- * AvatarGroupOverflow Props
86
+ * AvatarGroupPopover Props
77
87
  */
78
- export declare type AvatarGroupOverflowProps = ComponentProps<AvatarGroupOverflowSlots> & {};
88
+ export declare type AvatarGroupPopoverProps = Omit<ComponentProps<Partial<AvatarGroupPopoverSlots>>, 'children'> & {
89
+ /**
90
+ * Whether the triggerButton should render an icon instead of the number of overflowed AvatarGroupItems.
91
+ * Note: The indicator will default to `icon` when the size is less than 24.
92
+ * @default count
93
+ */
94
+ indicator?: 'count' | 'icon';
95
+ /**
96
+ * Number of AvatarGroupItems that will be rendered.
97
+ *
98
+ * Note: AvatarGroupPopover handles counting the number of children, but when using a react fragment to wrap the
99
+ * children, this is not possible and therefore it has do be added manually.
100
+ */
101
+ count?: number;
102
+ children: React_2.ReactNode;
103
+ };
79
104
 
80
- export declare type AvatarGroupOverflowSlots = {
81
- root: Slot<'div'>;
105
+ export declare type AvatarGroupPopoverSlots = {
106
+ root: NonNullable<Slot<PopoverProps>>;
107
+ /**
108
+ * Button that triggers the Popover.
109
+ */
110
+ triggerButton: NonNullable<Slot<'button'>>;
111
+ /**
112
+ * List that contains the overflowed AvatarGroupItems.
113
+ */
114
+ content: NonNullable<Slot<'ul'>>;
115
+ /**
116
+ * PopoverSurface that contains the content.
117
+ */
118
+ popoverSurface: NonNullable<Slot<typeof PopoverSurface>>;
119
+ /**
120
+ * Tooltip shown when triggerButton is hovered.
121
+ */
122
+ tooltip: NonNullable<Slot<TooltipProps>>;
82
123
  };
83
124
 
84
125
  /**
85
- * State used in rendering AvatarGroupOverflow
126
+ * State used in rendering AvatarGroupPopover
86
127
  */
87
- export declare type AvatarGroupOverflowState = ComponentState<AvatarGroupOverflowSlots>;
128
+ export declare type AvatarGroupPopoverState = ComponentState<AvatarGroupPopoverSlots> & Required<Pick<AvatarGroupPopoverProps, 'indicator'>> & {
129
+ popoverOpen: boolean;
130
+ layout: AvatarGroupProps['layout'];
131
+ size: AvatarSizes;
132
+ };
88
133
 
89
134
  /**
90
135
  * AvatarGroup Props
91
136
  */
92
137
  export declare type AvatarGroupProps = ComponentProps<AvatarGroupSlots> & {
93
138
  /**
94
- * Layout the Avatars should be displayed as.
139
+ * Layout the AvatarGroupItems should be displayed as.
95
140
  * @default spread
96
141
  */
97
142
  layout?: 'spread' | 'stack' | 'pie';
98
143
  /**
99
- * Maximum number of Avatars to be displayed before overflowing.
100
- * Note: if pie layout is used, `maxAvatars` will be ignored.
101
- * @default 5
102
- */
103
- maxAvatars?: number;
104
- /**
105
- * Whether the overflow indicator should render an icon instead of the number of overflowed avatars.
106
- * Note: The overflowIndicator will default to `icon` when the size is less than 24.
107
- * @default count
108
- */
109
- overflowIndicator?: 'count' | 'icon';
110
- /**
111
- * Size of the avatars.
144
+ * Size of the AvatarGroupItems.
112
145
  * @default 32
113
146
  */
114
147
  size?: AvatarSizes;
115
148
  };
116
149
 
150
+ export declare const AvatarGroupProvider: Provider<AvatarGroupContextValue> & FC<ProviderProps<AvatarGroupContextValue>>;
151
+
117
152
  export declare type AvatarGroupSlots = {
118
153
  root: NonNullable<Slot<'div'>>;
119
- /**
120
- * Popover trigger slot that can be used to change the overflow indicator.
121
- */
122
- overflowButton?: NonNullable<Slot<'button'>>;
123
- /**
124
- * List that contains the overflow AvatarGroupItems.
125
- */
126
- overflowContent?: NonNullable<Slot<'div'>>;
127
- /**
128
- * PopoverSurface that contains the overflow content.
129
- */
130
- overflowSurface?: NonNullable<Slot<typeof PopoverSurface>>;
131
154
  };
132
155
 
133
156
  /**
134
157
  * State used in rendering AvatarGroup
135
158
  */
136
- export declare type AvatarGroupState = ComponentState<AvatarGroupSlots> & Required<Pick<AvatarGroupProps, 'layout' | 'size' | 'overflowIndicator'>> & {
137
- /**
138
- * Whether there are more Avatars than `maxAvatars`.
139
- * @default false
140
- */
141
- hasOverflow: boolean;
142
- /**
143
- * Tooltip content for the overflow indicator.
144
- */
145
- tooltipContent: TooltipProps['content'];
146
- nonOverflowAvatarsCount: number;
147
- };
159
+ export declare type AvatarGroupState = ComponentState<AvatarGroupSlots> & Required<Pick<AvatarGroupProps, 'layout' | 'size'>>;
148
160
 
149
161
  /**
150
162
  * A specific named color for the Avatar
@@ -282,12 +294,30 @@ export declare function getInitials(displayName: string | undefined | null, isRt
282
294
  firstInitialOnly?: boolean;
283
295
  }): string;
284
296
 
297
+ /**
298
+ * Get the inline items and overflowing items based on the array of AvatarGroupItems needed for AvatarGroup.
299
+ *
300
+ * @param options - Configure the partition options
301
+ *
302
+ * @returns Two arrays split into inline items and overflow items based on maxInlineItems.
303
+ */
304
+ export declare const partitionAvatarGroupItems: <T>(options: PartitionAvatarGroupItemsOptions<T>) => {
305
+ inlineItems: T[];
306
+ overflowItems: readonly T[];
307
+ };
308
+
309
+ export declare type PartitionAvatarGroupItemsOptions<T> = {
310
+ items: readonly T[];
311
+ layout?: 'spread' | 'stack' | 'pie';
312
+ maxInlineItems?: number;
313
+ };
314
+
285
315
  export declare const renderAvatar_unstable: (state: AvatarState) => JSX.Element;
286
316
 
287
317
  /**
288
318
  * Render the final JSX of AvatarGroup
289
319
  */
290
- export declare const renderAvatarGroup_unstable: (state: AvatarGroupState) => JSX.Element;
320
+ export declare const renderAvatarGroup_unstable: (state: AvatarGroupState, contextValues: AvatarGroupContextValues) => JSX.Element;
291
321
 
292
322
  /**
293
323
  * Render the final JSX of AvatarGroupItem
@@ -295,9 +325,9 @@ export declare const renderAvatarGroup_unstable: (state: AvatarGroupState) => JS
295
325
  export declare const renderAvatarGroupItem_unstable: (state: AvatarGroupItemState) => JSX.Element;
296
326
 
297
327
  /**
298
- * Render the final JSX of AvatarGroupOverflow
328
+ * Render the final JSX of AvatarGroupPopover
299
329
  */
300
- export declare const renderAvatarGroupOverflow_unstable: (state: AvatarGroupOverflowState) => JSX.Element;
330
+ export declare const renderAvatarGroupPopover_unstable: (state: AvatarGroupPopoverState, contextValues: AvatarGroupContextValues) => JSX.Element;
301
331
 
302
332
  export declare const useAvatar_unstable: (props: AvatarProps, ref: React_2.Ref<HTMLElement>) => AvatarState;
303
333
 
@@ -312,6 +342,10 @@ export declare const useAvatar_unstable: (props: AvatarProps, ref: React_2.Ref<H
312
342
  */
313
343
  export declare const useAvatarGroup_unstable: (props: AvatarGroupProps, ref: React_2.Ref<HTMLElement>) => AvatarGroupState;
314
344
 
345
+ export declare const useAvatarGroupContext_unstable: <T>(selector: ContextSelector<AvatarGroupContextValue, T>) => T;
346
+
347
+ export declare const useAvatarGroupContextValues: (state: AvatarGroupState) => AvatarGroupContextValues;
348
+
315
349
  /**
316
350
  * Create the state required to render AvatarGroupItem.
317
351
  *
@@ -329,20 +363,19 @@ export declare const useAvatarGroupItem_unstable: (props: AvatarGroupItemProps,
329
363
  export declare const useAvatarGroupItemStyles_unstable: (state: AvatarGroupItemState) => AvatarGroupItemState;
330
364
 
331
365
  /**
332
- * Create the state required to render AvatarGroupOverflow.
366
+ * Create the state required to render AvatarGroupPopover.
333
367
  *
334
- * The returned state can be modified with hooks such as useAvatarGroupOverflowStyles_unstable,
335
- * before being passed to renderAvatarGroupOverflow_unstable.
368
+ * The returned state can be modified with hooks such as useAvatarGroupPopoverStyles_unstable,
369
+ * before being passed to renderAvatarGroupPopover_unstable.
336
370
  *
337
- * @param props - props from this instance of AvatarGroupOverflow
338
- * @param ref - reference to root HTMLElement of AvatarGroupOverflow
371
+ * @param props - props from this instance of AvatarGroupPopover
339
372
  */
340
- export declare const useAvatarGroupOverflow_unstable: (props: AvatarGroupOverflowProps, ref: React_2.Ref<HTMLElement>) => AvatarGroupOverflowState;
373
+ export declare const useAvatarGroupPopover_unstable: (props: AvatarGroupPopoverProps) => AvatarGroupPopoverState;
341
374
 
342
375
  /**
343
- * Apply styling to the AvatarGroupOverflow slots based on the state
376
+ * Apply styling to the AvatarGroupPopover slots based on the state
344
377
  */
345
- export declare const useAvatarGroupOverflowStyles_unstable: (state: AvatarGroupOverflowState) => AvatarGroupOverflowState;
378
+ export declare const useAvatarGroupPopoverStyles_unstable: (state: AvatarGroupPopoverState) => AvatarGroupPopoverState;
346
379
 
347
380
  /**
348
381
  * Apply styling to the AvatarGroup slots based on the state
@@ -0,0 +1,2 @@
1
+ export * from './components/AvatarGroupPopover/index';
2
+ //# sourceMappingURL=AvatarGroupPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroupPopover.js","sourceRoot":"../src/","sources":["AvatarGroupPopover.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC","sourcesContent":["export * from './components/AvatarGroupPopover/index';\n"]}
@@ -1,10 +1,9 @@
1
1
  import * as React from 'react';
2
- import { getNativeElementProps, resolveShorthand, useId } from '@fluentui/react-utilities';
2
+ import { getNativeElementProps, mergeCallbacks, resolveShorthand, useId } from '@fluentui/react-utilities';
3
3
  import { getInitials } from '../../utils/index';
4
4
  import { PersonRegular } from '@fluentui/react-icons';
5
5
  import { PresenceBadge } from '@fluentui/react-badge';
6
6
  import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
7
- import { useMergedEventCallbacks } from '@fluentui/react-utilities';
8
7
  export const useAvatar_unstable = (props, ref) => {
9
8
  var _a;
10
9
 
@@ -71,12 +70,9 @@ export const useAvatar_unstable = (props, ref) => {
71
70
  }
72
71
  }); // Hide the image if it fails to load and restore it on a successful load
73
72
 
74
- const imageOnError = useMergedEventCallbacks(image === null || image === void 0 ? void 0 : image.onError, () => setImageHidden(true));
75
- const imageOnLoad = useMergedEventCallbacks(image === null || image === void 0 ? void 0 : image.onLoad, () => setImageHidden(undefined));
76
-
77
73
  if (image) {
78
- image.onError = imageOnError;
79
- image.onLoad = imageOnLoad;
74
+ image.onError = mergeCallbacks(image.onError, () => setImageHidden(true));
75
+ image.onLoad = mergeCallbacks(image.onLoad, () => setImageHidden(undefined));
80
76
  }
81
77
 
82
78
  const badge = resolveShorthand(props.badge, {
@@ -1 +1 @@
1
- {"version":3,"sources":["components/Avatar/useAvatar.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { getNativeElementProps, resolveShorthand, useId } from '@fluentui/react-utilities';\nimport { getInitials } from '../../utils/index';\nimport type { AvatarNamedColor, AvatarProps, AvatarState } from './Avatar.types';\nimport { PersonRegular } from '@fluentui/react-icons';\nimport { PresenceBadge } from '@fluentui/react-badge';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useMergedEventCallbacks } from '@fluentui/react-utilities';\n\nexport const useAvatar_unstable = (props: AvatarProps, ref: React.Ref<HTMLElement>): AvatarState => {\n const { dir } = useFluent();\n const { name, size = 32, shape = 'circular', active = 'unset', activeAppearance = 'ring', idForColor } = props;\n let { color = 'neutral' } = props;\n\n // Resolve 'colorful' to a specific color name\n if (color === 'colorful') {\n color = avatarColors[getHashCode(idForColor ?? name ?? '') % avatarColors.length];\n }\n\n const baseId = useId('avatar-');\n\n const root: AvatarState['root'] = getNativeElementProps(\n 'span',\n {\n role: 'img',\n id: baseId,\n // aria-label and/or aria-labelledby are resolved below\n ...props,\n ref,\n },\n /* excludedPropNames: */ ['name'],\n );\n\n // Resolve the initials slot, defaulted to getInitials.\n let initials: AvatarState['initials'] = resolveShorthand(props.initials, {\n required: true,\n defaultProps: {\n children: getInitials(name, dir === 'rtl', { firstInitialOnly: size <= 16 }),\n id: baseId + '__initials',\n },\n });\n\n // Render the icon slot *only if* there aren't any initials to display.\n let icon: AvatarState['icon'] = undefined;\n if (!initials?.children) {\n initials = undefined;\n icon = resolveShorthand(props.icon, {\n required: true,\n defaultProps: {\n children: <PersonRegular />,\n 'aria-hidden': true,\n },\n });\n }\n\n const [imageHidden, setImageHidden] = React.useState<true | undefined>(undefined);\n const image: AvatarState['image'] = resolveShorthand(props.image, {\n defaultProps: {\n alt: '',\n role: 'presentation',\n 'aria-hidden': true,\n hidden: imageHidden,\n },\n });\n\n // Hide the image if it fails to load and restore it on a successful load\n const imageOnError = useMergedEventCallbacks(image?.onError, () => setImageHidden(true));\n const imageOnLoad = useMergedEventCallbacks(image?.onLoad, () => setImageHidden(undefined));\n if (image) {\n image.onError = imageOnError;\n image.onLoad = imageOnLoad;\n }\n\n const badge: AvatarState['badge'] = resolveShorthand(props.badge, {\n defaultProps: {\n size: getBadgeSize(size),\n id: baseId + '__badge',\n },\n });\n\n // Resolve aria-label and/or aria-labelledby if not provided by the user\n if (!root['aria-label'] && !root['aria-labelledby']) {\n if (name) {\n root['aria-label'] = name;\n\n // Include the badge in labelledby if it exists\n if (badge) {\n root['aria-labelledby'] = root.id + ' ' + badge.id;\n }\n } else if (initials) {\n // root's aria-label should be the name, but fall back to being labelledby the initials if name is missing\n root['aria-labelledby'] = initials.id + (badge ? ' ' + badge.id : '');\n }\n }\n\n return {\n size,\n shape,\n active,\n activeAppearance,\n color,\n\n components: {\n root: 'span',\n initials: 'span',\n icon: 'span',\n image: 'img',\n badge: PresenceBadge,\n },\n\n root,\n initials,\n icon,\n image,\n badge,\n };\n};\n\nconst getBadgeSize = (size: AvatarState['size']) => {\n if (size >= 96) {\n return 'extra-large';\n } else if (size >= 64) {\n return 'large';\n } else if (size >= 56) {\n return 'medium';\n } else if (size >= 40) {\n return 'small';\n } else if (size >= 28) {\n return 'extra-small';\n } else {\n return 'tiny';\n }\n};\n\nconst avatarColors: AvatarNamedColor[] = [\n 'dark-red',\n 'cranberry',\n 'red',\n 'pumpkin',\n 'peach',\n 'marigold',\n 'gold',\n 'brass',\n 'brown',\n 'forest',\n 'seafoam',\n 'dark-green',\n 'light-teal',\n 'teal',\n 'steel',\n 'blue',\n 'royal-blue',\n 'cornflower',\n 'navy',\n 'lavender',\n 'purple',\n 'grape',\n 'lilac',\n 'pink',\n 'magenta',\n 'plum',\n 'beige',\n 'mink',\n 'platinum',\n 'anchor',\n];\n\nconst getHashCode = (str: string): number => {\n let hashCode = 0;\n for (let len: number = str.length - 1; len >= 0; len--) {\n const ch = str.charCodeAt(len);\n const shift = len % 8;\n hashCode ^= (ch << shift) + (ch >> (8 - shift)); // eslint-disable-line no-bitwise\n }\n\n return hashCode;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/Avatar/useAvatar.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { getNativeElementProps, mergeCallbacks, resolveShorthand, useId } from '@fluentui/react-utilities';\nimport { getInitials } from '../../utils/index';\nimport type { AvatarNamedColor, AvatarProps, AvatarState } from './Avatar.types';\nimport { PersonRegular } from '@fluentui/react-icons';\nimport { PresenceBadge } from '@fluentui/react-badge';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\n\nexport const useAvatar_unstable = (props: AvatarProps, ref: React.Ref<HTMLElement>): AvatarState => {\n const { dir } = useFluent();\n const { name, size = 32, shape = 'circular', active = 'unset', activeAppearance = 'ring', idForColor } = props;\n let { color = 'neutral' } = props;\n\n // Resolve 'colorful' to a specific color name\n if (color === 'colorful') {\n color = avatarColors[getHashCode(idForColor ?? name ?? '') % avatarColors.length];\n }\n\n const baseId = useId('avatar-');\n\n const root: AvatarState['root'] = getNativeElementProps(\n 'span',\n {\n role: 'img',\n id: baseId,\n // aria-label and/or aria-labelledby are resolved below\n ...props,\n ref,\n },\n /* excludedPropNames: */ ['name'],\n );\n\n // Resolve the initials slot, defaulted to getInitials.\n let initials: AvatarState['initials'] = resolveShorthand(props.initials, {\n required: true,\n defaultProps: {\n children: getInitials(name, dir === 'rtl', { firstInitialOnly: size <= 16 }),\n id: baseId + '__initials',\n },\n });\n\n // Render the icon slot *only if* there aren't any initials to display.\n let icon: AvatarState['icon'] = undefined;\n if (!initials?.children) {\n initials = undefined;\n icon = resolveShorthand(props.icon, {\n required: true,\n defaultProps: {\n children: <PersonRegular />,\n 'aria-hidden': true,\n },\n });\n }\n\n const [imageHidden, setImageHidden] = React.useState<true | undefined>(undefined);\n const image: AvatarState['image'] = resolveShorthand(props.image, {\n defaultProps: {\n alt: '',\n role: 'presentation',\n 'aria-hidden': true,\n hidden: imageHidden,\n },\n });\n\n // Hide the image if it fails to load and restore it on a successful load\n if (image) {\n image.onError = mergeCallbacks(image.onError, () => setImageHidden(true));\n image.onLoad = mergeCallbacks(image.onLoad, () => setImageHidden(undefined));\n }\n\n const badge: AvatarState['badge'] = resolveShorthand(props.badge, {\n defaultProps: {\n size: getBadgeSize(size),\n id: baseId + '__badge',\n },\n });\n\n // Resolve aria-label and/or aria-labelledby if not provided by the user\n if (!root['aria-label'] && !root['aria-labelledby']) {\n if (name) {\n root['aria-label'] = name;\n\n // Include the badge in labelledby if it exists\n if (badge) {\n root['aria-labelledby'] = root.id + ' ' + badge.id;\n }\n } else if (initials) {\n // root's aria-label should be the name, but fall back to being labelledby the initials if name is missing\n root['aria-labelledby'] = initials.id + (badge ? ' ' + badge.id : '');\n }\n }\n\n return {\n size,\n shape,\n active,\n activeAppearance,\n color,\n\n components: {\n root: 'span',\n initials: 'span',\n icon: 'span',\n image: 'img',\n badge: PresenceBadge,\n },\n\n root,\n initials,\n icon,\n image,\n badge,\n };\n};\n\nconst getBadgeSize = (size: AvatarState['size']) => {\n if (size >= 96) {\n return 'extra-large';\n } else if (size >= 64) {\n return 'large';\n } else if (size >= 56) {\n return 'medium';\n } else if (size >= 40) {\n return 'small';\n } else if (size >= 28) {\n return 'extra-small';\n } else {\n return 'tiny';\n }\n};\n\nconst avatarColors: AvatarNamedColor[] = [\n 'dark-red',\n 'cranberry',\n 'red',\n 'pumpkin',\n 'peach',\n 'marigold',\n 'gold',\n 'brass',\n 'brown',\n 'forest',\n 'seafoam',\n 'dark-green',\n 'light-teal',\n 'teal',\n 'steel',\n 'blue',\n 'royal-blue',\n 'cornflower',\n 'navy',\n 'lavender',\n 'purple',\n 'grape',\n 'lilac',\n 'pink',\n 'magenta',\n 'plum',\n 'beige',\n 'mink',\n 'platinum',\n 'anchor',\n];\n\nconst getHashCode = (str: string): number => {\n let hashCode = 0;\n for (let len: number = str.length - 1; len >= 0; len--) {\n const ch = str.charCodeAt(len);\n const shift = len % 8;\n hashCode ^= (ch << shift) + (ch >> (8 - shift)); // eslint-disable-line no-bitwise\n }\n\n return hashCode;\n};\n"],"sourceRoot":"../src/"}