@k2b/ui 0.27.0 → 0.28.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 (191) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +30 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/Dropdown.js +184 -158
  6. package/dist/browser/actions/Dropdown.js.map +1 -1
  7. package/dist/browser/actions/GestureMenu.js +71 -138
  8. package/dist/browser/actions/GestureMenu.js.map +1 -1
  9. package/dist/browser/actions/Toolbar.js +379 -48
  10. package/dist/browser/actions/Toolbar.js.map +1 -1
  11. package/dist/browser/actions/index.js.map +1 -1
  12. package/dist/browser/actions/menu-rows.js +15 -0
  13. package/dist/browser/actions/menu-rows.js.map +1 -0
  14. package/dist/browser/actions/menu-sheet.js +154 -0
  15. package/dist/browser/actions/menu-sheet.js.map +1 -0
  16. package/dist/browser/actions/toolbar-messages.js +20 -0
  17. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  18. package/dist/browser/chart-inspection.js +3 -0
  19. package/dist/browser/chart-inspection.js.map +1 -0
  20. package/dist/browser/chat/ChatComposer.js +581 -397
  21. package/dist/browser/chat/ChatComposer.js.map +1 -1
  22. package/dist/browser/chat/chat-messages.js +19 -1
  23. package/dist/browser/chat/chat-messages.js.map +1 -1
  24. package/dist/browser/chat/command-search.js +3 -0
  25. package/dist/browser/chat/command-search.js.map +1 -1
  26. package/dist/browser/chat/index.js +2 -0
  27. package/dist/browser/chat/index.js.map +1 -1
  28. package/dist/browser/chat/reaction-people.js +15 -0
  29. package/dist/browser/chat/reaction-people.js.map +1 -0
  30. package/dist/browser/content/Chart.js +6 -15
  31. package/dist/browser/content/Chart.js.map +1 -1
  32. package/dist/browser/content/ChartSnapshotView.js +7 -10
  33. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  34. package/dist/browser/content/MessageRow.js +330 -448
  35. package/dist/browser/content/MessageRow.js.map +1 -1
  36. package/dist/browser/content/ReactionBar.js +419 -0
  37. package/dist/browser/content/ReactionBar.js.map +1 -0
  38. package/dist/browser/content/chart-inspection-core.js +557 -0
  39. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  40. package/dist/browser/content/chart-inspection.js +10 -445
  41. package/dist/browser/content/chart-inspection.js.map +1 -1
  42. package/dist/browser/content/chart-line-gaps.js +1 -1
  43. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  44. package/dist/browser/content/chart-snapshot.js +1 -1
  45. package/dist/browser/content/chart-snapshot.js.map +1 -1
  46. package/dist/browser/content/index.js +1 -0
  47. package/dist/browser/content/index.js.map +1 -1
  48. package/dist/browser/feedback/dialog-core.js +135 -23
  49. package/dist/browser/feedback/dialog-core.js.map +1 -1
  50. package/dist/browser/index.js +1 -0
  51. package/dist/browser/index.js.map +1 -1
  52. package/dist/browser/input-mode.js +40 -0
  53. package/dist/browser/input-mode.js.map +1 -0
  54. package/dist/browser/inputs/FileDropTarget.js +24 -9
  55. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  56. package/dist/browser/inputs/FileInputs.js +2 -2
  57. package/dist/browser/inputs/FileInputs.js.map +1 -1
  58. package/dist/browser/inputs/SelectChip.js +9 -0
  59. package/dist/browser/inputs/SelectChip.js.map +1 -1
  60. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  61. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  62. package/dist/browser/inputs/file-drop.js.map +1 -1
  63. package/dist/browser/layout/DetailPanel.js +283 -197
  64. package/dist/browser/layout/DetailPanel.js.map +1 -1
  65. package/dist/browser/layout/Discussion.js +233 -185
  66. package/dist/browser/layout/Discussion.js.map +1 -1
  67. package/dist/browser/layout/TableOfContents.js +10 -2
  68. package/dist/browser/layout/TableOfContents.js.map +1 -1
  69. package/dist/browser/layout/detail-panel-messages.js +35 -0
  70. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  71. package/dist/browser/surfaces/Avatar.js +50 -20
  72. package/dist/browser/surfaces/Avatar.js.map +1 -1
  73. package/dist/browser/surfaces/AvatarStack.js +406 -0
  74. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  75. package/dist/browser/surfaces/avatar-messages.js +8 -2
  76. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  77. package/dist/browser/surfaces/index.js +1 -0
  78. package/dist/browser/surfaces/index.js.map +1 -1
  79. package/dist/ssr/actions/ContextMenu.js +21 -3
  80. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  81. package/dist/ssr/actions/Dropdown.js +140 -72
  82. package/dist/ssr/actions/Dropdown.js.map +1 -1
  83. package/dist/ssr/actions/GestureMenu.js +52 -106
  84. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  85. package/dist/ssr/actions/Toolbar.js +294 -14
  86. package/dist/ssr/actions/Toolbar.js.map +1 -1
  87. package/dist/ssr/actions/index.js.map +1 -1
  88. package/dist/ssr/actions/menu-rows.js +15 -0
  89. package/dist/ssr/actions/menu-rows.js.map +1 -0
  90. package/dist/ssr/actions/menu-sheet.js +138 -0
  91. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  92. package/dist/ssr/actions/toolbar-messages.js +20 -0
  93. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  94. package/dist/ssr/chart-inspection.js +3 -0
  95. package/dist/ssr/chart-inspection.js.map +1 -0
  96. package/dist/ssr/chat/ChatComposer.js +263 -89
  97. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  98. package/dist/ssr/chat/chat-messages.js +19 -1
  99. package/dist/ssr/chat/chat-messages.js.map +1 -1
  100. package/dist/ssr/chat/command-search.js +3 -0
  101. package/dist/ssr/chat/command-search.js.map +1 -1
  102. package/dist/ssr/chat/index.js +2 -0
  103. package/dist/ssr/chat/index.js.map +1 -1
  104. package/dist/ssr/chat/reaction-people.js +15 -0
  105. package/dist/ssr/chat/reaction-people.js.map +1 -0
  106. package/dist/ssr/content/Chart.js +6 -15
  107. package/dist/ssr/content/Chart.js.map +1 -1
  108. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  109. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  110. package/dist/ssr/content/MessageRow.js +98 -152
  111. package/dist/ssr/content/MessageRow.js.map +1 -1
  112. package/dist/ssr/content/ReactionBar.js +304 -0
  113. package/dist/ssr/content/ReactionBar.js.map +1 -0
  114. package/dist/ssr/content/chart-inspection-core.js +557 -0
  115. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  116. package/dist/ssr/content/chart-inspection.js +10 -445
  117. package/dist/ssr/content/chart-inspection.js.map +1 -1
  118. package/dist/ssr/content/chart-line-gaps.js +1 -1
  119. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  120. package/dist/ssr/content/chart-snapshot.js +1 -1
  121. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  122. package/dist/ssr/content/index.js +1 -0
  123. package/dist/ssr/content/index.js.map +1 -1
  124. package/dist/ssr/feedback/dialog-core.js +135 -23
  125. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  126. package/dist/ssr/index.js +1 -0
  127. package/dist/ssr/index.js.map +1 -1
  128. package/dist/ssr/input-mode.js +40 -0
  129. package/dist/ssr/input-mode.js.map +1 -0
  130. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  131. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  132. package/dist/ssr/inputs/FileInputs.js +2 -2
  133. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  134. package/dist/ssr/inputs/SelectChip.js +9 -0
  135. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  136. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  137. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  138. package/dist/ssr/inputs/file-drop.js.map +1 -1
  139. package/dist/ssr/layout/DetailPanel.js +112 -58
  140. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  141. package/dist/ssr/layout/Discussion.js +63 -36
  142. package/dist/ssr/layout/Discussion.js.map +1 -1
  143. package/dist/ssr/layout/TableOfContents.js +10 -2
  144. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  145. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  146. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  147. package/dist/ssr/surfaces/Avatar.js +20 -2
  148. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  149. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  150. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  151. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  152. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  153. package/dist/ssr/surfaces/index.js +1 -0
  154. package/dist/ssr/surfaces/index.js.map +1 -1
  155. package/dist/styles.css +1 -1
  156. package/dist/types/actions/ContextMenu.d.ts +8 -0
  157. package/dist/types/actions/Dropdown.d.ts +12 -5
  158. package/dist/types/actions/GestureMenu.d.ts +6 -4
  159. package/dist/types/actions/Toolbar.d.ts +20 -0
  160. package/dist/types/actions/index.d.ts +1 -1
  161. package/dist/types/actions/menu-rows.d.ts +5 -0
  162. package/dist/types/actions/menu-sheet.d.ts +22 -0
  163. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  164. package/dist/types/chart-inspection.d.ts +2 -0
  165. package/dist/types/chat/ChatComposer.d.ts +7 -0
  166. package/dist/types/chat/chat-messages.d.ts +10 -2
  167. package/dist/types/chat/command-search.d.ts +2 -0
  168. package/dist/types/chat/index.d.ts +2 -0
  169. package/dist/types/chat/reaction-people.d.ts +9 -0
  170. package/dist/types/content/Chart.d.ts +2 -2
  171. package/dist/types/content/MessageRow.d.ts +3 -10
  172. package/dist/types/content/ReactionBar.d.ts +32 -0
  173. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  174. package/dist/types/content/chart-inspection.d.ts +4 -20
  175. package/dist/types/content/chart-snapshot.d.ts +1 -1
  176. package/dist/types/content/index.d.ts +2 -1
  177. package/dist/types/feedback/dialog-core.d.ts +16 -1
  178. package/dist/types/index.d.ts +1 -0
  179. package/dist/types/input-mode.d.ts +7 -0
  180. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  181. package/dist/types/inputs/SelectChip.d.ts +2 -0
  182. package/dist/types/inputs/file-drop.d.ts +2 -0
  183. package/dist/types/layout/DetailPanel.d.ts +11 -0
  184. package/dist/types/layout/Discussion.d.ts +8 -0
  185. package/dist/types/layout/TableOfContents.d.ts +2 -0
  186. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  187. package/dist/types/surfaces/Avatar.d.ts +12 -0
  188. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  189. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  190. package/dist/types/surfaces/index.d.ts +3 -1
  191. package/package.json +6 -1
@@ -0,0 +1,286 @@
1
+ import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
2
+ import { ssr as _$ssr } from "solid-js/web";
3
+ import { escape as _$escape } from "solid-js/web";
4
+ import { createComponent as _$createComponent } from "solid-js/web";
5
+ var _tmpl$ = ["<span class=\"k2b-avatar-stack__row-badge\">", "</span>"],
6
+ _tmpl$2 = ["<span class=\"k2b-avatar-stack__row-detail\">", "<span>", "</span></span>"],
7
+ _tmpl$3 = ["<span class=\"k2b-avatar-stack__row-copy\"><span class=\"k2b-avatar-stack__row-name\"><span>", "</span>", "</span>", "</span>"],
8
+ _tmpl$4 = ["<span class=\"k2b-avatar-stack__row-trailing\">", "</span>"],
9
+ _tmpl$5 = ["<i", " aria-hidden=\"true\"></i>"],
10
+ _tmpl$6 = ["<li", ">", "</li>"],
11
+ _tmpl$7 = ["<div class=\"k2b-avatar-stack__row\">", "</div>"],
12
+ _tmpl$8 = ["<button type=\"button\" class=\"k2b-avatar-stack__row\">", "</button>"],
13
+ _tmpl$9 = ["<ul class=\"k2b-avatar-stack__rows\" tabindex=\"-1\">", "", "</ul>"],
14
+ _tmpl$0 = ["<header class=\"k2b-avatar-stack__header\"><h3", ">", "</h3><span class=\"k2b-count-chip\">", "</span></header>"],
15
+ _tmpl$1 = ["<p class=\"k2b-avatar-stack__hint\">", "</p>"],
16
+ _tmpl$10 = ["<div class=\"k2b-avatar-stack__sheet\" role=\"group\" aria-labelledby=\"", "\">", "</div>"],
17
+ _tmpl$11 = ["<span class=\"k2b-avatar-stack__more\" aria-hidden=\"true\"", ">+", "</span>"],
18
+ _tmpl$12 = ["<span class=\"", "\"><button type=\"button\" class=\"k2b-avatar-stack__trigger\"", " aria-haspopup=\"dialog\"", "><span class=\"k2b-avatar-stack__faces\" aria-hidden=\"true\">", "</span>", "</button><div", " popover=\"auto\" role=\"dialog\"", " class=\"k2b-avatar-stack__popover\">", "</div></span>"];
19
+ import { createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show } from "solid-js";
20
+ import { dropdownPosition } from "../actions/Dropdown";
21
+ import { prefersMenuSheet } from "../actions/menu-sheet";
22
+ import { dialogCore } from "../feedback/dialog-core";
23
+ import { LocaleProvider, useLocale } from "../intl/locale";
24
+ import BottomSheet, { bottomSheetOptions } from "../layout/BottomSheet";
25
+ import { Avatar } from "./Avatar";
26
+ import { useAvatarMessages } from "./avatar-messages";
27
+ const PersonRows = props => {
28
+ let list;
29
+ /**
30
+ * A focused row that stops being a button (the person can no longer be chosen) or leaves hands focus to the nearest
31
+ * row that still is one, else to the list, so focus never drops out of the open list.
32
+ */
33
+ const keepFocus = button => {
34
+ if (!button.contains(document.activeElement)) return;
35
+ const buttons = Array.from(list.querySelectorAll("button.k2b-avatar-stack__row"));
36
+ const index = buttons.indexOf(button);
37
+ const candidates = [...buttons.slice(index + 1), ...buttons.slice(0, Math.max(0, index)).reverse()];
38
+ queueMicrotask(() => {
39
+ if (!list.isConnected) return;
40
+ (candidates.find(candidate => candidate.isConnected) ?? list).focus();
41
+ });
42
+ };
43
+ const others = () => props.people.filter(person => !person.self);
44
+ const selves = () => props.people.filter(person => person.self);
45
+ // A row reads its person through an accessor, so a live update changes the row in place and a focused row keeps focus.
46
+ const row = person => {
47
+ const content = [_$createComponent(Avatar, {
48
+ get name() {
49
+ return person().name;
50
+ },
51
+ get src() {
52
+ return person().src;
53
+ },
54
+ get icon() {
55
+ return person().icon;
56
+ },
57
+ get shape() {
58
+ return person().shape;
59
+ },
60
+ size: "sm"
61
+ }), _$ssr(_tmpl$3, _$escape(person().name), _$escape(_$createComponent(Show, {
62
+ get when() {
63
+ return person().badge;
64
+ },
65
+ get children() {
66
+ return _$ssr(_tmpl$, _$escape(person().badge));
67
+ }
68
+ })), _$escape(_$createComponent(Show, {
69
+ get when() {
70
+ return person().detail;
71
+ },
72
+ get children() {
73
+ return _$ssr(_tmpl$2, _$escape(_$createComponent(Show, {
74
+ get when() {
75
+ return person().detailIcon;
76
+ },
77
+ children: icon => _$ssr(_tmpl$5, _$ssrAttribute("class", _$escape(icon(), true), false))
78
+ })), _$escape(person().detail));
79
+ }
80
+ }))), _$createComponent(Show, {
81
+ get when() {
82
+ return person().trailing;
83
+ },
84
+ get children() {
85
+ return _$ssr(_tmpl$4, _$escape(person().trailing));
86
+ }
87
+ })];
88
+ return _$ssr(_tmpl$6, _$ssrAttribute("data-self", person().self ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(Show, {
89
+ get when() {
90
+ return Boolean(person().onSelect);
91
+ },
92
+ get fallback() {
93
+ return _$ssr(_tmpl$7, _$escape(content));
94
+ },
95
+ get children() {
96
+ return (() => {
97
+ let button;
98
+ // Browser only: a server render never mounts the button.
99
+ onMount(() => onCleanup(() => keepFocus(button)));
100
+ return _$ssr(_tmpl$8, _$escape(content));
101
+ })();
102
+ }
103
+ })));
104
+ };
105
+ // Rows follow each person by id: a row stays with its person when others leave or the order changes, and still
106
+ // shows that person's latest details.
107
+ const byId = createMemo(() => new Map(props.people.map(person => [person.id, person])));
108
+ const keyed = id => row(() => byId().get(id) ?? {
109
+ id,
110
+ name: ""
111
+ });
112
+ return _$ssr(_tmpl$9, _$escape(_$createComponent(For, {
113
+ get each() {
114
+ return others().map(person => person.id);
115
+ },
116
+ children: keyed
117
+ })), _$escape(_$createComponent(For, {
118
+ get each() {
119
+ return selves().map(person => person.id);
120
+ },
121
+ children: keyed
122
+ })));
123
+ };
124
+ const PeopleList = props => [_$ssr(_tmpl$0, _$ssrAttribute("id", _$escape(props.titleId, true), false), _$escape(props.title), _$escape(props.people.length)), _$createComponent(PersonRows, {
125
+ get people() {
126
+ return props.people;
127
+ },
128
+ get choose() {
129
+ return props.choose;
130
+ }
131
+ }), _$createComponent(Show, {
132
+ get when() {
133
+ return props.hint;
134
+ },
135
+ get children() {
136
+ return _$ssr(_tmpl$1, _$escape(props.hint));
137
+ }
138
+ })];
139
+
140
+ /**
141
+ * A few overlapping faces, then "+n", as one button. It opens the full list of people beside it, or as a bottom sheet
142
+ * on phones. People with `self` are listed last and never shown in the stack.
143
+ */
144
+ export function AvatarStack(props) {
145
+ const locale = useLocale();
146
+ const messages = useAvatarMessages();
147
+ const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, "-");
148
+ const popoverId = `k2b-avatar-stack-${id}`;
149
+ const titleId = `${popoverId}-title`;
150
+ const [open, setOpen] = createSignal(false);
151
+ let trigger;
152
+ let popover;
153
+ let sheetOpen = false;
154
+ const disposed = new AbortController();
155
+ onCleanup(() => disposed.abort());
156
+ const faces = () => props.people.filter(person => !person.self);
157
+ const max = () => Math.max(1, props.max ?? 3);
158
+ const shown = () => faces().slice(0, max());
159
+ const more = () => Math.max(0, faces().length - max());
160
+ const place = () => {
161
+ const rect = dropdownPosition(trigger.getBoundingClientRect(), popover.getBoundingClientRect(), "bottom-left", {
162
+ width: window.innerWidth,
163
+ height: window.innerHeight
164
+ });
165
+ popover.style.left = `${rect.left}px`;
166
+ popover.style.top = `${rect.top}px`;
167
+ };
168
+ // Like a dropdown menu, the open list follows its trigger when the window resizes or scrolls, and its own size.
169
+ let resizeObserver;
170
+ const follow = on => {
171
+ const method = on ? "addEventListener" : "removeEventListener";
172
+ window[method]("resize", place);
173
+ window[method]("scroll", place, true);
174
+ if (on && typeof ResizeObserver !== "undefined") {
175
+ resizeObserver ??= new ResizeObserver(place);
176
+ resizeObserver.observe(popover);
177
+ } else resizeObserver?.disconnect();
178
+ };
179
+ // Only the browser ever follows; a server render has no window to let go of.
180
+ onMount(() => onCleanup(() => follow(false)));
181
+ const openSheet = () => {
182
+ if (sheetOpen) return;
183
+ sheetOpen = true;
184
+ setOpen(true);
185
+ let chosen;
186
+ const current = locale();
187
+ void dialogCore.open((close, context) => _$createComponent(LocaleProvider, {
188
+ locale: current,
189
+ get children() {
190
+ return _$createComponent(BottomSheet, {
191
+ get onDismiss() {
192
+ return context.requestDismiss;
193
+ },
194
+ get children() {
195
+ return _$createComponent(BottomSheet.Body, {
196
+ get children() {
197
+ return _$ssr(_tmpl$10, `${_$escape(titleId, true)}-sheet`, _$escape(_$createComponent(PeopleList, {
198
+ get people() {
199
+ return props.people;
200
+ },
201
+ get title() {
202
+ return props.title;
203
+ },
204
+ titleId: `${titleId}-sheet`,
205
+ get hint() {
206
+ return props.hint;
207
+ },
208
+ choose: person => {
209
+ chosen = person;
210
+ close();
211
+ }
212
+ })));
213
+ }
214
+ });
215
+ }
216
+ });
217
+ }
218
+ }), {
219
+ ...bottomSheetOptions,
220
+ ariaLabel: props.title,
221
+ history: true,
222
+ signal: disposed.signal
223
+ }).then(() => chosen?.onSelect?.()).finally(() => {
224
+ sheetOpen = false;
225
+ setOpen(false);
226
+ });
227
+ };
228
+ const toggle = () => {
229
+ if (prefersMenuSheet()) {
230
+ openSheet();
231
+ return;
232
+ }
233
+ if (popover.matches(":popover-open")) {
234
+ popover.hidePopover();
235
+ return;
236
+ }
237
+ popover.showPopover();
238
+ place();
239
+ };
240
+ return _$ssr(_tmpl$12, `k2b-avatar-stack ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("aria-label", _$escape(props.label, true), false), _$ssrAttribute("aria-expanded", _$escape(open(), true), false) + _$ssrAttribute("aria-controls", _$escape(popoverId, true), false), _$escape(_$createComponent(For, {
241
+ get each() {
242
+ return shown();
243
+ },
244
+ children: person => _$createComponent(Avatar, {
245
+ get name() {
246
+ return person.name;
247
+ },
248
+ get src() {
249
+ return person.src;
250
+ },
251
+ get icon() {
252
+ return person.icon;
253
+ },
254
+ get shape() {
255
+ return person.shape;
256
+ },
257
+ size: "xs",
258
+ alt: ""
259
+ })
260
+ })), _$escape(_$createComponent(Show, {
261
+ get when() {
262
+ return more() > 0;
263
+ },
264
+ get children() {
265
+ return _$ssr(_tmpl$11, _$ssrAttribute("title", _$escape(messages().moreCount({
266
+ count: more()
267
+ }), true), false), _$escape(more()));
268
+ }
269
+ })), _$ssrAttribute("id", _$escape(popoverId, true), false), _$ssrAttribute("aria-labelledby", _$escape(titleId, true), false), _$escape(_$createComponent(PeopleList, {
270
+ get people() {
271
+ return props.people;
272
+ },
273
+ get title() {
274
+ return props.title;
275
+ },
276
+ titleId: titleId,
277
+ get hint() {
278
+ return props.hint;
279
+ },
280
+ choose: person => {
281
+ if (open()) popover.hidePopover();
282
+ person.onSelect?.();
283
+ }
284
+ })));
285
+ }
286
+ //# sourceMappingURL=AvatarStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["surfaces/AvatarStack.tsx"],"sourcesContent":["import { createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { dropdownPosition } from \"../actions/Dropdown\";\nimport { prefersMenuSheet } from \"../actions/menu-sheet\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport BottomSheet, { bottomSheetOptions } from \"../layout/BottomSheet\";\nimport { Avatar, type AvatarShape } from \"./Avatar\";\nimport { useAvatarMessages } from \"./avatar-messages\";\n\nexport type AvatarStackPerson = {\n /** Stable key, such as the account id. */\n id: string;\n name: string;\n src?: string | null;\n /** Shown instead of initials when there is no picture. */\n icon?: string;\n /** `square` for agents and service accounts. */\n shape?: AvatarShape;\n /** A short tag after the name, such as \"Agent\". */\n badge?: JSX.Element;\n /** One line below the name; it ends with an ellipsis instead of wrapping. */\n detail?: JSX.Element;\n /** Icon class before `detail`. */\n detailIcon?: string;\n /** Short text at the end of the row, such as \"2 tabs\". */\n trailing?: JSX.Element;\n /** The person viewing: listed last, below a gap, and never in the stack. */\n self?: boolean;\n /** Makes the row a button. The list closes first. */\n onSelect?: () => void;\n};\n\nexport type AvatarStackProps = {\n people: readonly AvatarStackPerson[];\n /** Title of the list that the stack opens, such as \"Here now\". */\n title: string;\n /** Accessible name of the stack button, such as \"Here now: Jana Berger and 2 more\". */\n label: string;\n /** One quiet line below the list. */\n hint?: JSX.Element;\n /** Faces before \"+n\". Defaults to 3. */\n max?: number;\n class?: string;\n};\n\nconst PersonRows = (props: { people: readonly AvatarStackPerson[]; choose: (person: AvatarStackPerson) => void }): JSX.Element => {\n let list!: HTMLUListElement;\n /**\n * A focused row that stops being a button (the person can no longer be chosen) or leaves hands focus to the nearest\n * row that still is one, else to the list, so focus never drops out of the open list.\n */\n const keepFocus = (button: HTMLButtonElement) => {\n if (!button.contains(document.activeElement)) return;\n const buttons = Array.from(list.querySelectorAll<HTMLButtonElement>(\"button.k2b-avatar-stack__row\"));\n const index = buttons.indexOf(button);\n const candidates = [...buttons.slice(index + 1), ...buttons.slice(0, Math.max(0, index)).reverse()];\n queueMicrotask(() => {\n if (!list.isConnected) return;\n (candidates.find((candidate) => candidate.isConnected) ?? list).focus();\n });\n };\n const others = () => props.people.filter((person) => !person.self);\n const selves = () => props.people.filter((person) => person.self);\n // A row reads its person through an accessor, so a live update changes the row in place and a focused row keeps focus.\n const row = (person: () => AvatarStackPerson) => {\n const content = (\n <>\n <Avatar name={person().name} src={person().src} icon={person().icon} shape={person().shape} size=\"sm\" />\n <span class=\"k2b-avatar-stack__row-copy\">\n <span class=\"k2b-avatar-stack__row-name\">\n <span>{person().name}</span>\n <Show when={person().badge}>\n <span class=\"k2b-avatar-stack__row-badge\">{person().badge}</span>\n </Show>\n </span>\n <Show when={person().detail}>\n <span class=\"k2b-avatar-stack__row-detail\">\n <Show when={person().detailIcon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{person().detail}</span>\n </span>\n </Show>\n </span>\n <Show when={person().trailing}>\n <span class=\"k2b-avatar-stack__row-trailing\">{person().trailing}</span>\n </Show>\n </>\n );\n return (\n <li data-self={person().self ? \"true\" : undefined}>\n <Show when={Boolean(person().onSelect)} fallback={<div class=\"k2b-avatar-stack__row\">{content}</div>}>\n {(() => {\n let button!: HTMLButtonElement;\n // Browser only: a server render never mounts the button.\n onMount(() => onCleanup(() => keepFocus(button)));\n return (\n <button ref={button} type=\"button\" class=\"k2b-avatar-stack__row\" onClick={() => props.choose(person())}>\n {content}\n </button>\n );\n })()}\n </Show>\n </li>\n );\n };\n // Rows follow each person by id: a row stays with its person when others leave or the order changes, and still\n // shows that person's latest details.\n const byId = createMemo(() => new Map(props.people.map((person) => [person.id, person])));\n const keyed = (id: string) => row(() => byId().get(id) ?? { id, name: \"\" });\n return (\n <ul ref={list} class=\"k2b-avatar-stack__rows\" tabIndex={-1}>\n <For each={others().map((person) => person.id)}>{keyed}</For>\n <For each={selves().map((person) => person.id)}>{keyed}</For>\n </ul>\n );\n};\n\nconst PeopleList = (props: {\n people: readonly AvatarStackPerson[];\n title: string;\n titleId: string;\n hint?: JSX.Element;\n choose: (person: AvatarStackPerson) => void;\n}): JSX.Element => (\n <>\n <header class=\"k2b-avatar-stack__header\">\n <h3 id={props.titleId}>{props.title}</h3>\n <span class=\"k2b-count-chip\">{props.people.length}</span>\n </header>\n <PersonRows people={props.people} choose={props.choose} />\n <Show when={props.hint}>\n <p class=\"k2b-avatar-stack__hint\">{props.hint}</p>\n </Show>\n </>\n);\n\n/**\n * A few overlapping faces, then \"+n\", as one button. It opens the full list of people beside it, or as a bottom sheet\n * on phones. People with `self` are listed last and never shown in the stack.\n */\nexport function AvatarStack(props: AvatarStackProps): JSX.Element {\n const locale = useLocale();\n const messages = useAvatarMessages();\n const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const popoverId = `k2b-avatar-stack-${id}`;\n const titleId = `${popoverId}-title`;\n const [open, setOpen] = createSignal(false);\n let trigger!: HTMLButtonElement;\n let popover!: HTMLDivElement;\n let sheetOpen = false;\n const disposed = new AbortController();\n onCleanup(() => disposed.abort());\n\n const faces = () => props.people.filter((person) => !person.self);\n const max = () => Math.max(1, props.max ?? 3);\n const shown = () => faces().slice(0, max());\n const more = () => Math.max(0, faces().length - max());\n\n const place = () => {\n const rect = dropdownPosition(trigger.getBoundingClientRect(), popover.getBoundingClientRect(), \"bottom-left\", {\n width: window.innerWidth,\n height: window.innerHeight,\n });\n popover.style.left = `${rect.left}px`;\n popover.style.top = `${rect.top}px`;\n };\n // Like a dropdown menu, the open list follows its trigger when the window resizes or scrolls, and its own size.\n let resizeObserver: ResizeObserver | undefined;\n const follow = (on: boolean) => {\n const method = on ? \"addEventListener\" : \"removeEventListener\";\n window[method](\"resize\", place);\n window[method](\"scroll\", place, true);\n if (on && typeof ResizeObserver !== \"undefined\") {\n resizeObserver ??= new ResizeObserver(place);\n resizeObserver.observe(popover);\n } else resizeObserver?.disconnect();\n };\n // Only the browser ever follows; a server render has no window to let go of.\n onMount(() => onCleanup(() => follow(false)));\n\n const openSheet = () => {\n if (sheetOpen) return;\n sheetOpen = true;\n setOpen(true);\n let chosen: AvatarStackPerson | undefined;\n const current = locale();\n void dialogCore\n .open<void>(\n (close, context) => (\n <LocaleProvider locale={current}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Body>\n <div class=\"k2b-avatar-stack__sheet\" role=\"group\" aria-labelledby={`${titleId}-sheet`}>\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={`${titleId}-sheet`}\n hint={props.hint}\n choose={(person) => {\n chosen = person;\n close();\n }}\n />\n </div>\n </BottomSheet.Body>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetOptions, ariaLabel: props.title, history: true, signal: disposed.signal },\n )\n .then(() => chosen?.onSelect?.())\n .finally(() => {\n sheetOpen = false;\n setOpen(false);\n });\n };\n\n const toggle = () => {\n if (prefersMenuSheet()) {\n openSheet();\n return;\n }\n if (popover.matches(\":popover-open\")) {\n popover.hidePopover();\n return;\n }\n popover.showPopover();\n place();\n };\n\n return (\n <span class={`k2b-avatar-stack ${props.class ?? \"\"}`}>\n <button\n ref={trigger}\n type=\"button\"\n class=\"k2b-avatar-stack__trigger\"\n aria-label={props.label}\n aria-haspopup=\"dialog\"\n aria-expanded={open()}\n aria-controls={popoverId}\n onClick={toggle}\n >\n <span class=\"k2b-avatar-stack__faces\" aria-hidden=\"true\">\n <For each={shown()}>\n {(person) => <Avatar name={person.name} src={person.src} icon={person.icon} shape={person.shape} size=\"xs\" alt=\"\" />}\n </For>\n </span>\n <Show when={more() > 0}>\n <span class=\"k2b-avatar-stack__more\" aria-hidden=\"true\" title={messages().moreCount({ count: more() })}>\n +{more()}\n </span>\n </Show>\n </button>\n <div\n ref={popover}\n id={popoverId}\n popover=\"auto\"\n role=\"dialog\"\n aria-labelledby={titleId}\n class=\"k2b-avatar-stack__popover\"\n onToggle={(event) => {\n const next = (event as ToggleEvent).newState === \"open\";\n setOpen(next);\n follow(next);\n if (!next && document.activeElement && popover.contains(document.activeElement)) trigger.focus();\n }}\n >\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={titleId}\n hint={props.hint}\n choose={(person) => {\n if (open()) popover.hidePopover();\n person.onSelect?.();\n }}\n />\n </div>\n </span>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -7,13 +7,19 @@ const avatarMessages = i18n.define({
7
7
  avatarLabel: ({
8
8
  name
9
9
  }) => `${name} avatar`,
10
- unknownUser: "Unknown user"
10
+ unknownUser: "Unknown user",
11
+ moreCount: ({
12
+ count
13
+ }) => `${count} more`
11
14
  },
12
15
  de: {
13
16
  avatarLabel: ({
14
17
  name
15
18
  }) => `Avatar von ${name}`,
16
- unknownUser: "Unbekannte Person"
19
+ unknownUser: "Unbekannte Person",
20
+ moreCount: ({
21
+ count
22
+ }) => `${count} weitere`
17
23
  }
18
24
  }
19
25
  });
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/avatar-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\nimport { useLocale } from \"../intl/locale\";\n\nconst avatarMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n avatarLabel: ({ name }: { name: string }) => `${name} avatar`,\n unknownUser: \"Unknown user\",\n },\n de: {\n avatarLabel: ({ name }) => `Avatar von ${name}`,\n unknownUser: \"Unbekannte Person\",\n },\n },\n});\n\nexport type AvatarMessages = ReturnType<(typeof avatarMessages)[\"resolve\"]>[\"t\"];\n\n/** Resolved from the inherited render locale. */\nexport const useAvatarMessages = (): (() => AvatarMessages) => {\n const locale = useLocale();\n return () => avatarMessages.resolve([locale()]).t;\n};\n\nexport const checkAvatarMessages = () => avatarMessages.check();\n"],"mappings":"AAAA,SAAS,IAAI,QAAQ,aAAa;AAClC,SAAS,SAAS,QAAQ,gBAAgB;AAE1C,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;EACjC,UAAU,EAAE,IAAI;EAChB,QAAQ,EAAE;IACR,EAAE,EAAE;MACF,WAAW,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,SAAS;MAC7D,WAAW,EAAE;IACf,CAAC;IACD,EAAE,EAAE;MACF,WAAW,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,cAAc,IAAI,EAAE;MAC/C,WAAW,EAAE;IACf;EACF;AACF,CAAC,CAAC;AAIF;AACA,OAAO,MAAM,iBAAiB,GAAG,MAA8B;EAC7D,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,OAAO,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,OAAO,MAAM,mBAAmB,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/avatar-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\nimport { useLocale } from \"../intl/locale\";\n\nconst avatarMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n avatarLabel: ({ name }: { name: string }) => `${name} avatar`,\n unknownUser: \"Unknown user\",\n moreCount: ({ count }: { count: number }) => `${count} more`,\n },\n de: {\n avatarLabel: ({ name }) => `Avatar von ${name}`,\n unknownUser: \"Unbekannte Person\",\n moreCount: ({ count }) => `${count} weitere`,\n },\n },\n});\n\nexport type AvatarMessages = ReturnType<(typeof avatarMessages)[\"resolve\"]>[\"t\"];\n\n/** Resolved from the inherited render locale. */\nexport const useAvatarMessages = (): (() => AvatarMessages) => {\n const locale = useLocale();\n return () => avatarMessages.resolve([locale()]).t;\n};\n\nexport const checkAvatarMessages = () => avatarMessages.check();\n"],"mappings":"AAAA,SAAS,IAAI,QAAQ,aAAa;AAClC,SAAS,SAAS,QAAQ,gBAAgB;AAE1C,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;EACjC,UAAU,EAAE,IAAI;EAChB,QAAQ,EAAE;IACR,EAAE,EAAE;MACF,WAAW,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,SAAS;MAC7D,WAAW,EAAE,cAAc;MAC3B,SAAS,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,GAAG,KAAK;IACvD,CAAC;IACD,EAAE,EAAE;MACF,WAAW,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,cAAc,IAAI,EAAE;MAC/C,WAAW,EAAE,mBAAmB;MAChC,SAAS,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,GAAG,KAAK;IACpC;EACF;AACF,CAAC,CAAC;AAIF;AACA,OAAO,MAAM,iBAAiB,GAAG,MAA8B;EAC7D,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,OAAO,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,OAAO,MAAM,mBAAmB,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  export { Avatar } from "./Avatar";
2
+ export { AvatarStack } from "./AvatarStack";
2
3
  export { DescriptionList } from "./DescriptionList";
3
4
  export { LinkCard } from "./LinkCard";
4
5
  export { NotFoundState } from "./NotFoundState";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/index.ts"],"sourcesContent":["export type { AvatarProps, AvatarSize } from \"./Avatar\";\nexport { Avatar } from \"./Avatar\";\nexport type { DescriptionListItem, DescriptionListProps } from \"./DescriptionList\";\nexport { DescriptionList } from \"./DescriptionList\";\nexport type { LinkCardColor, LinkCardProps } from \"./LinkCard\";\nexport { LinkCard } from \"./LinkCard\";\nexport type { NotFoundStateAction, NotFoundStateProps } from \"./NotFoundState\";\nexport { NotFoundState } from \"./NotFoundState\";\nexport type { NoticeCardProps, NoticeGridProps, NoticeTone } from \"./NoticeCard\";\nexport { NOTICE_CARD_CLASSES, NoticeCard } from \"./NoticeCard\";\nexport type { PaperProps, PaperTag } from \"./Paper\";\nexport { Paper } from \"./Paper\";\nexport type {\n PlaceholderAlign,\n PlaceholderProps,\n PlaceholderState,\n PlaceholderSurface,\n PlaceholderVariant,\n} from \"./Placeholder\";\nexport { default as Placeholder } from \"./Placeholder\";\nexport type { ProgressBarProps, ProgressBarTone } from \"./ProgressBar\";\nexport { ProgressBar } from \"./ProgressBar\";\nexport type { ProgressRingProps, ProgressRingTone } from \"./ProgressRing\";\nexport { ProgressRing } from \"./ProgressRing\";\nexport type { ResourceCardProps, ResourceCardState } from \"./ResourceCard\";\nexport { ResourceCard } from \"./ResourceCard\";\nexport type { StatCellAccent, StatCellProps, StatCellTone } from \"./StatCell\";\nexport { StatCell } from \"./StatCell\";\nexport type {\n StatGridAction,\n StatGridColumns,\n StatGridProps,\n StatGridSize,\n StatGridSurface,\n} from \"./StatGrid\";\nexport { StatGrid } from \"./StatGrid\";\nexport type { StatusBadgeProps, StatusTone } from \"./StatusBadge\";\nexport { StatusBadge } from \"./StatusBadge\";\nexport type { TagProps, TagSize } from \"./Tag\";\nexport { Tag } from \"./Tag\";\n"],"mappings":"AACA,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,eAAe,QAAQ,mBAAmB;AAEnD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,mBAAmB,EAAE,UAAU,QAAQ,cAAc;AAE9D,SAAS,KAAK,QAAQ,SAAS;AAQ/B,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,GAAG,QAAQ,OAAO","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/index.ts"],"sourcesContent":["export type { AvatarProps, AvatarRing, AvatarShape, AvatarSize } from \"./Avatar\";\nexport { Avatar } from \"./Avatar\";\nexport type { AvatarStackPerson, AvatarStackProps } from \"./AvatarStack\";\nexport { AvatarStack } from \"./AvatarStack\";\nexport type { DescriptionListItem, DescriptionListProps } from \"./DescriptionList\";\nexport { DescriptionList } from \"./DescriptionList\";\nexport type { LinkCardColor, LinkCardProps } from \"./LinkCard\";\nexport { LinkCard } from \"./LinkCard\";\nexport type { NotFoundStateAction, NotFoundStateProps } from \"./NotFoundState\";\nexport { NotFoundState } from \"./NotFoundState\";\nexport type { NoticeCardProps, NoticeGridProps, NoticeTone } from \"./NoticeCard\";\nexport { NOTICE_CARD_CLASSES, NoticeCard } from \"./NoticeCard\";\nexport type { PaperProps, PaperTag } from \"./Paper\";\nexport { Paper } from \"./Paper\";\nexport type {\n PlaceholderAlign,\n PlaceholderProps,\n PlaceholderState,\n PlaceholderSurface,\n PlaceholderVariant,\n} from \"./Placeholder\";\nexport { default as Placeholder } from \"./Placeholder\";\nexport type { ProgressBarProps, ProgressBarTone } from \"./ProgressBar\";\nexport { ProgressBar } from \"./ProgressBar\";\nexport type { ProgressRingProps, ProgressRingTone } from \"./ProgressRing\";\nexport { ProgressRing } from \"./ProgressRing\";\nexport type { ResourceCardProps, ResourceCardState } from \"./ResourceCard\";\nexport { ResourceCard } from \"./ResourceCard\";\nexport type { StatCellAccent, StatCellProps, StatCellTone } from \"./StatCell\";\nexport { StatCell } from \"./StatCell\";\nexport type {\n StatGridAction,\n StatGridColumns,\n StatGridProps,\n StatGridSize,\n StatGridSurface,\n} from \"./StatGrid\";\nexport { StatGrid } from \"./StatGrid\";\nexport type { StatusBadgeProps, StatusTone } from \"./StatusBadge\";\nexport { StatusBadge } from \"./StatusBadge\";\nexport type { TagProps, TagSize } from \"./Tag\";\nexport { Tag } from \"./Tag\";\n"],"mappings":"AACA,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,eAAe,QAAQ,mBAAmB;AAEnD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,mBAAmB,EAAE,UAAU,QAAQ,cAAc;AAE9D,SAAS,KAAK,QAAQ,SAAS;AAQ/B,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,GAAG,QAAQ,OAAO","ignoreList":[]}