@tensor_1/react 2.47.0 → 2.49.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 (204) hide show
  1. package/README.md +540 -2
  2. package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
  3. package/dist/announce.d.ts +10 -0
  4. package/dist/announce.js +30 -0
  5. package/dist/chart-analytic.cjs +33 -25
  6. package/dist/chart-preset.cjs +23 -15
  7. package/dist/chart.cjs +23 -15
  8. package/dist/combobox-model.d.ts +10 -1
  9. package/dist/combobox-model.js +15 -0
  10. package/dist/command-palette-model.d.ts +44 -0
  11. package/dist/command-palette-model.js +36 -0
  12. package/dist/components/AccountMenu.d.ts +44 -0
  13. package/dist/components/AccountMenu.js +43 -0
  14. package/dist/components/AppShell.d.ts +45 -2
  15. package/dist/components/AppShell.js +116 -5
  16. package/dist/components/AuditLog.d.ts +128 -0
  17. package/dist/components/AuditLog.js +196 -0
  18. package/dist/components/BrandProfiles.js +4 -3
  19. package/dist/components/Breadcrumbs.d.ts +9 -2
  20. package/dist/components/Breadcrumbs.js +3 -2
  21. package/dist/components/Button.d.ts +12 -5
  22. package/dist/components/Button.js +7 -3
  23. package/dist/components/Card.d.ts +18 -1
  24. package/dist/components/Card.js +5 -1
  25. package/dist/components/ChangeHighlight.d.ts +30 -0
  26. package/dist/components/ChangeHighlight.js +21 -0
  27. package/dist/components/ChartCore.js +2 -1
  28. package/dist/components/Checkbox.d.ts +27 -1
  29. package/dist/components/Checkbox.js +31 -2
  30. package/dist/components/Chip.d.ts +7 -3
  31. package/dist/components/Chip.js +2 -2
  32. package/dist/components/CodeDisplay.d.ts +65 -0
  33. package/dist/components/CodeDisplay.js +124 -0
  34. package/dist/components/Combobox.d.ts +27 -6
  35. package/dist/components/Combobox.js +195 -58
  36. package/dist/components/CommandPalette.d.ts +36 -1
  37. package/dist/components/CommandPalette.js +254 -2
  38. package/dist/components/ContactCard.d.ts +66 -0
  39. package/dist/components/ContactCard.js +74 -0
  40. package/dist/components/Count.d.ts +24 -0
  41. package/dist/components/Count.js +32 -0
  42. package/dist/components/DashboardCanvas.js +14 -0
  43. package/dist/components/DataWorkspace.d.ts +167 -0
  44. package/dist/components/DataWorkspace.js +380 -0
  45. package/dist/components/DateFieldParts.d.ts +2 -1
  46. package/dist/components/DateFieldParts.js +7 -0
  47. package/dist/components/DatePicker.d.ts +9 -2
  48. package/dist/components/DatePicker.js +67 -28
  49. package/dist/components/DateRangePicker.d.ts +12 -2
  50. package/dist/components/DateRangePicker.js +13 -12
  51. package/dist/components/DetailPage.d.ts +7 -1
  52. package/dist/components/DetailPage.js +2 -1
  53. package/dist/components/Dialogs.d.ts +71 -10
  54. package/dist/components/Dialogs.js +130 -30
  55. package/dist/components/DiffViewer.d.ts +23 -3
  56. package/dist/components/DiffViewer.js +26 -12
  57. package/dist/components/DiscardPrompt.js +16 -0
  58. package/dist/components/DisplayPreferences.d.ts +83 -0
  59. package/dist/components/DisplayPreferences.js +185 -0
  60. package/dist/components/EditorialHome.d.ts +23 -3
  61. package/dist/components/EditorialHome.js +16 -11
  62. package/dist/components/EntityPicker.d.ts +20 -3
  63. package/dist/components/EntityPicker.js +32 -13
  64. package/dist/components/FilterEditor.d.ts +18 -4
  65. package/dist/components/FilterEditor.js +141 -19
  66. package/dist/components/FocusOnMount.d.ts +282 -0
  67. package/dist/components/FocusOnMount.js +12 -0
  68. package/dist/components/InfoTip.js +11 -12
  69. package/dist/components/InlineEdit.d.ts +87 -20
  70. package/dist/components/InlineEdit.js +197 -54
  71. package/dist/components/Input.d.ts +12 -2
  72. package/dist/components/Input.js +5 -3
  73. package/dist/components/Kanban.d.ts +14 -3
  74. package/dist/components/Kanban.js +9 -4
  75. package/dist/components/Kbd.d.ts +6 -1
  76. package/dist/components/Kbd.js +6 -6
  77. package/dist/components/Lightbox.d.ts +41 -5
  78. package/dist/components/Lightbox.js +95 -9
  79. package/dist/components/MatchReview.d.ts +40 -1
  80. package/dist/components/MatchReview.js +130 -4
  81. package/dist/components/MetricInput.js +3 -2
  82. package/dist/components/Modal.d.ts +2 -1
  83. package/dist/components/Modal.js +13 -4
  84. package/dist/components/MotionList.d.ts +303 -0
  85. package/dist/components/MotionList.js +175 -0
  86. package/dist/components/NavFavourites.d.ts +5 -0
  87. package/dist/components/NavFavourites.js +7 -7
  88. package/dist/components/OtpInput.d.ts +33 -0
  89. package/dist/components/OtpInput.js +123 -0
  90. package/dist/components/PageHeader.d.ts +7 -1
  91. package/dist/components/PageHeader.js +2 -2
  92. package/dist/components/Pagination.js +6 -5
  93. package/dist/components/PasswordInput.d.ts +34 -0
  94. package/dist/components/PasswordInput.js +101 -0
  95. package/dist/components/Peek.js +3 -3
  96. package/dist/components/Popover.js +11 -0
  97. package/dist/components/PrintLayout.d.ts +63 -0
  98. package/dist/components/PrintLayout.js +114 -0
  99. package/dist/components/QrCode.d.ts +47 -0
  100. package/dist/components/QrCode.js +55 -0
  101. package/dist/components/QrScanner.d.ts +95 -0
  102. package/dist/components/QrScanner.js +266 -0
  103. package/dist/components/RelationshipGraph.d.ts +32 -1
  104. package/dist/components/RelationshipGraph.js +22 -6
  105. package/dist/components/RelationshipGraphLayered.d.ts +1 -1
  106. package/dist/components/RelationshipGraphLayered.js +268 -118
  107. package/dist/components/RelationshipGraphList.js +33 -6
  108. package/dist/components/RuleBuilder.js +39 -7
  109. package/dist/components/SchedulingAgenda.d.ts +3 -1
  110. package/dist/components/SchedulingCalendar.d.ts +3 -1
  111. package/dist/components/SchedulingCalendar.js +43 -4
  112. package/dist/components/SchedulingResourceDay.d.ts +57 -0
  113. package/dist/components/SchedulingResourceDay.js +287 -0
  114. package/dist/components/SchedulingTimeGrid.d.ts +3 -1
  115. package/dist/components/SchedulingTimeline.d.ts +3 -1
  116. package/dist/components/SearchSuggest.d.ts +23 -3
  117. package/dist/components/SearchSuggest.js +56 -18
  118. package/dist/components/Segmented.d.ts +39 -4
  119. package/dist/components/Segmented.js +39 -5
  120. package/dist/components/Select.d.ts +3 -2
  121. package/dist/components/Select.js +7 -1
  122. package/dist/components/ShortcutHint.d.ts +11 -10
  123. package/dist/components/ShortcutHint.js +44 -38
  124. package/dist/components/Sidebar.d.ts +36 -4
  125. package/dist/components/Sidebar.js +37 -12
  126. package/dist/components/SortableList.d.ts +45 -0
  127. package/dist/components/SortableList.js +147 -0
  128. package/dist/components/Stat.d.ts +28 -3
  129. package/dist/components/Stat.js +13 -3
  130. package/dist/components/States.d.ts +33 -1
  131. package/dist/components/States.js +43 -1
  132. package/dist/components/StatusPill.d.ts +14 -3
  133. package/dist/components/StatusPill.js +11 -3
  134. package/dist/components/Steps.js +2 -1
  135. package/dist/components/Table.d.ts +9 -2
  136. package/dist/components/Table.js +4 -2
  137. package/dist/components/TableControls.js +18 -58
  138. package/dist/components/TableOverflowProbe.d.ts +12 -0
  139. package/dist/components/TableOverflowProbe.js +27 -0
  140. package/dist/components/Tabs.d.ts +2 -1
  141. package/dist/components/Tabs.js +10 -2
  142. package/dist/components/TagInput.d.ts +67 -0
  143. package/dist/components/TagInput.js +342 -0
  144. package/dist/components/Textarea.d.ts +5 -0
  145. package/dist/components/Textarea.js +2 -2
  146. package/dist/components/TimePicker.d.ts +80 -0
  147. package/dist/components/TimePicker.js +347 -0
  148. package/dist/components/Toast.d.ts +1 -1
  149. package/dist/components/Toast.js +109 -4
  150. package/dist/components/Tooltip.d.ts +8 -4
  151. package/dist/components/Tooltip.js +86 -28
  152. package/dist/components/Tree.d.ts +8 -0
  153. package/dist/components/Tree.js +11 -5
  154. package/dist/display-preferences-model.d.ts +53 -0
  155. package/dist/display-preferences-model.js +64 -0
  156. package/dist/emoji.cjs +143 -49
  157. package/dist/filter-model.d.ts +59 -3
  158. package/dist/filter-model.js +67 -2
  159. package/dist/hooks/useAnchoredPosition.js +14 -2
  160. package/dist/hooks/useChangeHighlight.d.ts +33 -0
  161. package/dist/hooks/useChangeHighlight.js +44 -0
  162. package/dist/hooks/useDeferredReorder.d.ts +32 -0
  163. package/dist/hooks/useDeferredReorder.js +47 -0
  164. package/dist/hooks/useDialog.d.ts +5 -0
  165. package/dist/hooks/useDialog.js +17 -3
  166. package/dist/hooks/useKeyboardGrab.d.ts +58 -0
  167. package/dist/hooks/useKeyboardGrab.js +118 -0
  168. package/dist/hooks/useOptimisticValue.d.ts +51 -0
  169. package/dist/hooks/useOptimisticValue.js +61 -0
  170. package/dist/hooks/useReducedMotion.d.ts +4 -1
  171. package/dist/hooks/useReducedMotion.js +7 -1
  172. package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
  173. package/dist/hooks/useResolvedFilterLabels.js +34 -0
  174. package/dist/hooks/useSlidingIndicator.d.ts +18 -0
  175. package/dist/hooks/useSlidingIndicator.js +80 -0
  176. package/dist/hooks/useVirtualRows.d.ts +21 -2
  177. package/dist/hooks/useVirtualRows.js +30 -3
  178. package/dist/icons/Icon.d.ts +1 -1
  179. package/dist/index.cjs +19687 -13423
  180. package/dist/index.d.cts +3419 -651
  181. package/dist/index.d.ts +48 -18
  182. package/dist/index.js +153 -9
  183. package/dist/labels-context.d.ts +93 -3
  184. package/dist/motion.d.ts +11 -0
  185. package/dist/motion.js +35 -0
  186. package/dist/overlay-stack.d.ts +6 -0
  187. package/dist/overlay-stack.js +13 -0
  188. package/dist/qr-model.d.ts +65 -0
  189. package/dist/qr-model.js +323 -0
  190. package/dist/relationship-graph-model.d.ts +92 -3
  191. package/dist/relationship-graph-model.js +134 -15
  192. package/dist/reorder.d.ts +30 -0
  193. package/dist/reorder.js +74 -0
  194. package/dist/rich-text.cjs +46 -4
  195. package/dist/scheduling-resource-model.d.ts +76 -0
  196. package/dist/scheduling-resource-model.js +74 -0
  197. package/dist/search-suggest-model.js +3 -1
  198. package/dist/shell-context.d.ts +11 -0
  199. package/dist/shell-context.js +7 -0
  200. package/dist/time-field-model.d.ts +46 -0
  201. package/dist/time-field-model.js +152 -0
  202. package/dist/toast-store.d.ts +22 -3
  203. package/dist/toast-store.js +26 -9
  204. package/package.json +2 -1
@@ -2,6 +2,8 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { CalendarWeekday } from './calendar-model.js';
4
4
  import { MoveProposal, MonthSpanLayout } from './scheduling-calendar-model.js';
5
+ import { SchedulingSlotSelection } from './components/SchedulingResourceDay.js';
6
+ import { SchedulingAvailabilityKind, SchedulingResource, SchedulingResourceSpan } from './scheduling-resource-model.js';
5
7
 
6
8
  interface TimeGridEntryContext {
7
9
  /** Whole text lines that fit in the item: 0 shows the markers only. */
@@ -236,6 +238,18 @@ interface SchedulingCalendarLabels {
236
238
  moveCancelled?: string;
237
239
  /** Announced when the time asked for does not exist that day. `{time}` is the time used instead. */
238
240
  gapForward?: string;
241
+ /** Names the resource day (HAR-983). `{date}` placeholder. */
242
+ resourceGrid?: string;
243
+ /** The words for the kinds of a resource span. */
244
+ availability?: Partial<Record<SchedulingAvailabilityKind, string>>;
245
+ /** Time of a resource that no span covers: no schedule, which is not free. */
246
+ noSchedule?: string;
247
+ /** A resource slot's or booking's accessible name. `{resource}`, `{start}`, `{end}`, `{kind}`, `{label}`. */
248
+ slotName?: string;
249
+ /** How to move in the resource day, read with it. */
250
+ resourceHint?: string;
251
+ /** The resource day with no resources. */
252
+ noResources?: string;
239
253
  }
240
254
  declare const DEFAULT_SCHEDULING_CALENDAR_LABELS: SchedulingCalendarLabels;
241
255
  interface SchedulingCalendarProps {
@@ -376,13 +390,48 @@ interface SchedulingCalendarProps {
376
390
  topLaneCap?: number;
377
391
  /** Lanes side by side in one day column of the time grid, at most. Fewer are used when the column is narrow. Default 4. */
378
392
  maxLanes?: number;
393
+ /**
394
+ * With `view="day"`, one column per resource (a practitioner, a room) instead of the time grid
395
+ * (HAR-983). Their stretches of the day come from `resourceSpans`; a time no span covers is
396
+ * shown as "no schedule", never as free.
397
+ */
398
+ resources?: SchedulingResource[];
399
+ /** The free, booked and off stretches of each resource, as the server composed them. */
400
+ resourceSpans?: SchedulingResourceSpan[];
401
+ /** Minutes per slot of the resource day: each free span is cut into bookable slots of this length. Default 15. */
402
+ slotMinutes?: number;
403
+ /** The first local time of the resource day's axis, `HH:MM`. Default `'07:00'`. */
404
+ dayStart?: string;
405
+ /** The local time the resource day's axis ends, `HH:MM`. Default `'19:00'`. */
406
+ dayEnd?: string;
407
+ /** Called by a click, Enter or Space on a free slot (its own start and end) or a booking. */
408
+ onSelectSlot?: (slot: SchedulingSlotSelection) => void;
409
+ /** Marks the slot or booking that holds this instant for this resource, e.g. while its popover is open. */
410
+ selectedSlot?: {
411
+ resourceId: string;
412
+ start: string;
413
+ };
414
+ /**
415
+ * `auto` (default): columns, and a list of one resource after another when the calendar is
416
+ * narrower than `resourceListBelow`. `columns` or `list` fixes one.
417
+ */
418
+ resourceLayout?: 'auto' | 'columns' | 'list';
419
+ /** The width in CSS pixels under which `auto` shows the list. Default 480. */
420
+ resourceListBelow?: number;
421
+ /**
422
+ * The first load shows skeletons; a refetch keeps what is on screen, dimmed and `aria-busy`
423
+ * (the resource day; the other views show `labels.loading` instead).
424
+ */
379
425
  loading?: boolean;
380
426
  error?: string;
381
427
  onRetry?: () => void;
382
428
  className?: string;
383
429
  labels?: Partial<SchedulingCalendarLabels>;
384
430
  }
385
- /** Month/week/agenda calendar for UTC ranges rendered in an explicit IANA time zone. */
386
- declare function SchedulingCalendar({ entries, anchorDate, timeZone, view: controlledView, onViewChange, onAnchorDateChange, onSelectEntry, overlays, onSelectOverlay, filter, renderEntry, locale, weekStartsOn, formatDate, formatInstant: formatInstantProp, maxEntriesPerDay, onShowMore, renderDayBadge, days: dayInfo, dayEntries, spanLayout, windowLaneCap, spanLaneCap, legend, legendCaption, showHeader, notice, emptyNote, onSelectDate, agendaGroups, agendaHeadingLevel, virtualizeAbove, monthDensity, timeGrid, now, canMove, step, onProposeMove, topLaneCrossMidnightMinutes, topLaneCap, maxLanes, loading, error, onRetry, className, labels: labelOverrides, }: SchedulingCalendarProps): react.JSX.Element;
431
+ /**
432
+ * Month/week/day/agenda calendar for UTC ranges rendered in an explicit IANA time zone. With
433
+ * `resources`, the day view is one column per resource (HAR-983).
434
+ */
435
+ declare function SchedulingCalendar({ entries, anchorDate, timeZone, view: controlledView, onViewChange, onAnchorDateChange, onSelectEntry, overlays, onSelectOverlay, filter, renderEntry, locale, weekStartsOn, formatDate, formatInstant: formatInstantProp, maxEntriesPerDay, onShowMore, renderDayBadge, days: dayInfo, dayEntries, spanLayout, windowLaneCap, spanLaneCap, legend, legendCaption, showHeader, notice, emptyNote, onSelectDate, agendaGroups, agendaHeadingLevel, virtualizeAbove, monthDensity, timeGrid, now, canMove, step, onProposeMove, topLaneCrossMidnightMinutes, topLaneCap, maxLanes, resources, resourceSpans, slotMinutes, dayStart, dayEnd, onSelectSlot, selectedSlot, resourceLayout, resourceListBelow, loading, error, onRetry, className, labels: labelOverrides, }: SchedulingCalendarProps): react.JSX.Element;
387
436
 
388
437
  export { DEFAULT_SCHEDULING_CALENDAR_LABELS as D, type SchedulingAgendaGroup as S, type TimeGridEntryContext as T, type SchedulingBand as a, SchedulingCalendar as b, type SchedulingCalendarDay as c, type SchedulingCalendarEntry as d, type SchedulingCalendarLabels as e, type SchedulingCalendarOverlay as f, type SchedulingCalendarProps as g, type SchedulingCalendarView as h, type SchedulingDatePart as i, type SchedulingEntryState as j, type SchedulingLegendItem as k, type SchedulingMarker as l, type SchedulingMarkerEmphasis as m, type SchedulingOverlayKind as n, type SchedulingOverlayPattern as o, type SchedulingStatus as p, SchedulingTimeGrid as q, type SchedulingTimeGridProps as r };
@@ -0,0 +1,10 @@
1
+ /** Create the polite region `announcePolite(…, from)` will use, ahead of its first message. */
2
+ declare function ensureAnnouncer(from?: Element | null): void;
3
+ /**
4
+ * Say `text` through a polite live region (`[data-uix-announcer]`): the page's, or the open
5
+ * dialog's when `from` is inside one. The region is cleared first and filled a moment later,
6
+ * so the same words twice are spoken twice; a newer message replaces one not yet spoken.
7
+ */
8
+ declare function announcePolite(text: string, from?: Element | null): void;
9
+
10
+ export { announcePolite, ensureAnnouncer };
@@ -0,0 +1,30 @@
1
+ const timers = /* @__PURE__ */ new WeakMap();
2
+ function ensureAnnouncer(from) {
3
+ liveRegion(from);
4
+ }
5
+ function liveRegion(from) {
6
+ if (typeof document === "undefined") return null;
7
+ const container = from?.closest("dialog") ?? document.body;
8
+ let region = container.querySelector(":scope > [data-uix-announcer]");
9
+ if (!region) {
10
+ region = document.createElement("div");
11
+ region.setAttribute("role", "status");
12
+ region.setAttribute("data-uix-announcer", "");
13
+ region.className = "uix-visually-hidden";
14
+ container.append(region);
15
+ }
16
+ return region;
17
+ }
18
+ function announcePolite(text, from) {
19
+ const el = liveRegion(from);
20
+ if (!el) return;
21
+ clearTimeout(timers.get(el));
22
+ el.textContent = "";
23
+ timers.set(el, setTimeout(() => {
24
+ el.textContent = text;
25
+ }, 0));
26
+ }
27
+ export {
28
+ announcePolite,
29
+ ensureAnnouncer
30
+ };
@@ -73,7 +73,7 @@ var import_components = require("echarts/components");
73
73
  var import_renderers = require("echarts/renderers");
74
74
 
75
75
  // src/components/ChartCore.tsx
76
- var import_react = require("react");
76
+ var import_react2 = require("react");
77
77
 
78
78
  // src/cx.ts
79
79
  function cx(...args) {
@@ -177,6 +177,14 @@ function mergeChartTheme(theme, option) {
177
177
  return merged;
178
178
  }
179
179
 
180
+ // src/hooks/useReducedMotion.ts
181
+ var import_react = require("react");
182
+ var QUERY = "(prefers-reduced-motion: reduce)";
183
+ function prefersReducedMotion() {
184
+ if (typeof document !== "undefined" && document.documentElement.getAttribute("data-motion") === "reduce") return true;
185
+ return typeof matchMedia !== "undefined" && matchMedia(QUERY).matches;
186
+ }
187
+
180
188
  // src/components/ChartCore.tsx
181
189
  var import_jsx_runtime = require("react/jsx-runtime");
182
190
  function readToken(name) {
@@ -191,7 +199,7 @@ function themed(option, theme, element) {
191
199
  return theme === "none" ? resolved : mergeChartTheme(uixChartTheme(element), resolved);
192
200
  }
193
201
  function motionSafe(option) {
194
- if (typeof matchMedia !== "undefined" && matchMedia("(prefers-reduced-motion: reduce)").matches) {
202
+ if (prefersReducedMotion()) {
195
203
  return { ...option, animation: false };
196
204
  }
197
205
  return option;
@@ -225,23 +233,23 @@ function ChartCore({
225
233
  tables
226
234
  }) {
227
235
  const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
228
- const containerRef = (0, import_react.useRef)(null);
229
- const chartRef = (0, import_react.useRef)(null);
230
- const appliedOptionRef = (0, import_react.useRef)(null);
231
- const onEventsRef = (0, import_react.useRef)(onEvents);
236
+ const containerRef = (0, import_react2.useRef)(null);
237
+ const chartRef = (0, import_react2.useRef)(null);
238
+ const appliedOptionRef = (0, import_react2.useRef)(null);
239
+ const onEventsRef = (0, import_react2.useRef)(onEvents);
232
240
  onEventsRef.current = onEvents;
233
- const latestOptionRef = (0, import_react.useRef)(option);
234
- const onReadyRef = (0, import_react.useRef)(onReady);
235
- const tableId = (0, import_react.useId)();
241
+ const latestOptionRef = (0, import_react2.useRef)(option);
242
+ const onReadyRef = (0, import_react2.useRef)(onReady);
243
+ const tableId = (0, import_react2.useId)();
236
244
  const hasEmpty = empty != null;
237
245
  const hasTextAlternative = Boolean(ariaLabel || title || tableData?.length || tables?.length);
238
- const hasTextAlternativeRef = (0, import_react.useRef)(hasTextAlternative);
239
- const themeRef = (0, import_react.useRef)(theme);
246
+ const hasTextAlternativeRef = (0, import_react2.useRef)(hasTextAlternative);
247
+ const themeRef = (0, import_react2.useRef)(theme);
240
248
  latestOptionRef.current = option;
241
249
  themeRef.current = theme;
242
250
  onReadyRef.current = onReady;
243
251
  hasTextAlternativeRef.current = hasTextAlternative;
244
- (0, import_react.useEffect)(() => {
252
+ (0, import_react2.useEffect)(() => {
245
253
  const element = containerRef.current;
246
254
  if (!element) return;
247
255
  const chart = engine.init(element, null, { renderer: "svg" });
@@ -287,7 +295,7 @@ function ChartCore({
287
295
  };
288
296
  }, [engine, hasEmpty]);
289
297
  const eventNames = Object.keys(onEvents ?? {}).sort().join("|");
290
- (0, import_react.useEffect)(() => {
298
+ (0, import_react2.useEffect)(() => {
291
299
  const chart = chartRef.current;
292
300
  if (!chart || !eventNames) return;
293
301
  const bound = eventNames.split("|").map((name) => {
@@ -300,7 +308,7 @@ function ChartCore({
300
308
  for (const [name, handler] of bound) chart.off(name, handler);
301
309
  };
302
310
  }, [engine, hasEmpty, eventNames]);
303
- (0, import_react.useEffect)(() => {
311
+ (0, import_react2.useEffect)(() => {
304
312
  const chart = chartRef.current;
305
313
  if (!chart || !group) return;
306
314
  chart.group = group;
@@ -309,7 +317,7 @@ function ChartCore({
309
317
  if (!chart.isDisposed()) chart.group = "";
310
318
  };
311
319
  }, [engine, hasEmpty, group]);
312
- (0, import_react.useEffect)(() => {
320
+ (0, import_react2.useEffect)(() => {
313
321
  const chart = chartRef.current;
314
322
  const element = containerRef.current;
315
323
  if (!chart || !element || appliedOptionRef.current === option) return;
@@ -373,7 +381,7 @@ function ChartLegendItem({ label, color, swatch = "block", className, style, ...
373
381
  }
374
382
 
375
383
  // src/components/ChartPanels.tsx
376
- var import_react2 = require("react");
384
+ var import_react3 = require("react");
377
385
 
378
386
  // src/chart-analytic-model.ts
379
387
  var DEFAULT_ANALYTIC_LABELS = {
@@ -1195,10 +1203,10 @@ function ChartPanelsCore({
1195
1203
  onEventClick,
1196
1204
  legend
1197
1205
  }) {
1198
- const spec = (0, import_react2.useMemo)(() => ({ x, panels, events, partialLast, zoom }), [x, panels, events, partialLast, zoom]);
1199
- const layout = (0, import_react2.useMemo)(() => chartPanelsModel(spec, CSS_VAR_TOKENS, labels), [spec, labels]);
1200
- const option = (0, import_react2.useMemo)(() => (tokens) => chartPanelsModel(spec, tokens, labels).option, [spec, labels]);
1201
- const onEvents = (0, import_react2.useMemo)(() => ({
1206
+ const spec = (0, import_react3.useMemo)(() => ({ x, panels, events, partialLast, zoom }), [x, panels, events, partialLast, zoom]);
1207
+ const layout = (0, import_react3.useMemo)(() => chartPanelsModel(spec, CSS_VAR_TOKENS, labels), [spec, labels]);
1208
+ const option = (0, import_react3.useMemo)(() => (tokens) => chartPanelsModel(spec, tokens, labels).option, [spec, labels]);
1209
+ const onEvents = (0, import_react3.useMemo)(() => ({
1202
1210
  click: (raw) => {
1203
1211
  const params = raw;
1204
1212
  const value = Array.isArray(params.value) ? params.value : [];
@@ -1266,14 +1274,14 @@ function CorrelationScatterCore({
1266
1274
  height = 280,
1267
1275
  onPointClick
1268
1276
  }) {
1269
- const spec = (0, import_react2.useMemo)(
1277
+ const spec = (0, import_react3.useMemo)(
1270
1278
  () => ({ points, xLabel, yLabel, trend, percentiles, thresholds, breakpoint, minPoints }),
1271
1279
  [points, xLabel, yLabel, trend, percentiles, thresholds, breakpoint, minPoints]
1272
1280
  );
1273
- const layout = (0, import_react2.useMemo)(() => correlationScatterModel(spec, CSS_VAR_TOKENS, labels), [spec, labels]);
1274
- const option = (0, import_react2.useMemo)(() => (tokens) => correlationScatterModel(spec, tokens, labels).option, [spec, labels]);
1275
- const usable = (0, import_react2.useMemo)(() => spec.points.filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)), [spec.points]);
1276
- const onEvents = (0, import_react2.useMemo)(() => ({
1281
+ const layout = (0, import_react3.useMemo)(() => correlationScatterModel(spec, CSS_VAR_TOKENS, labels), [spec, labels]);
1282
+ const option = (0, import_react3.useMemo)(() => (tokens) => correlationScatterModel(spec, tokens, labels).option, [spec, labels]);
1283
+ const usable = (0, import_react3.useMemo)(() => spec.points.filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)), [spec.points]);
1284
+ const onEvents = (0, import_react3.useMemo)(() => ({
1277
1285
  click: (raw) => {
1278
1286
  const params = raw;
1279
1287
  if (params.seriesId !== layout.hitSeriesId || !Array.isArray(params.value)) return;
@@ -49,7 +49,7 @@ var import_components = require("echarts/components");
49
49
  var import_renderers = require("echarts/renderers");
50
50
 
51
51
  // src/components/ChartCore.tsx
52
- var import_react = require("react");
52
+ var import_react2 = require("react");
53
53
 
54
54
  // src/cx.ts
55
55
  function cx(...args) {
@@ -153,6 +153,14 @@ function mergeChartTheme(theme, option) {
153
153
  return merged;
154
154
  }
155
155
 
156
+ // src/hooks/useReducedMotion.ts
157
+ var import_react = require("react");
158
+ var QUERY = "(prefers-reduced-motion: reduce)";
159
+ function prefersReducedMotion() {
160
+ if (typeof document !== "undefined" && document.documentElement.getAttribute("data-motion") === "reduce") return true;
161
+ return typeof matchMedia !== "undefined" && matchMedia(QUERY).matches;
162
+ }
163
+
156
164
  // src/components/ChartCore.tsx
157
165
  var import_jsx_runtime = require("react/jsx-runtime");
158
166
  function readToken(name) {
@@ -167,7 +175,7 @@ function themed(option, theme, element) {
167
175
  return theme === "none" ? resolved : mergeChartTheme(uixChartTheme(element), resolved);
168
176
  }
169
177
  function motionSafe(option) {
170
- if (typeof matchMedia !== "undefined" && matchMedia("(prefers-reduced-motion: reduce)").matches) {
178
+ if (prefersReducedMotion()) {
171
179
  return { ...option, animation: false };
172
180
  }
173
181
  return option;
@@ -201,23 +209,23 @@ function ChartCore({
201
209
  tables
202
210
  }) {
203
211
  const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
204
- const containerRef = (0, import_react.useRef)(null);
205
- const chartRef = (0, import_react.useRef)(null);
206
- const appliedOptionRef = (0, import_react.useRef)(null);
207
- const onEventsRef = (0, import_react.useRef)(onEvents);
212
+ const containerRef = (0, import_react2.useRef)(null);
213
+ const chartRef = (0, import_react2.useRef)(null);
214
+ const appliedOptionRef = (0, import_react2.useRef)(null);
215
+ const onEventsRef = (0, import_react2.useRef)(onEvents);
208
216
  onEventsRef.current = onEvents;
209
- const latestOptionRef = (0, import_react.useRef)(option);
210
- const onReadyRef = (0, import_react.useRef)(onReady);
211
- const tableId = (0, import_react.useId)();
217
+ const latestOptionRef = (0, import_react2.useRef)(option);
218
+ const onReadyRef = (0, import_react2.useRef)(onReady);
219
+ const tableId = (0, import_react2.useId)();
212
220
  const hasEmpty = empty != null;
213
221
  const hasTextAlternative = Boolean(ariaLabel || title || tableData?.length || tables?.length);
214
- const hasTextAlternativeRef = (0, import_react.useRef)(hasTextAlternative);
215
- const themeRef = (0, import_react.useRef)(theme);
222
+ const hasTextAlternativeRef = (0, import_react2.useRef)(hasTextAlternative);
223
+ const themeRef = (0, import_react2.useRef)(theme);
216
224
  latestOptionRef.current = option;
217
225
  themeRef.current = theme;
218
226
  onReadyRef.current = onReady;
219
227
  hasTextAlternativeRef.current = hasTextAlternative;
220
- (0, import_react.useEffect)(() => {
228
+ (0, import_react2.useEffect)(() => {
221
229
  const element = containerRef.current;
222
230
  if (!element) return;
223
231
  const chart = engine.init(element, null, { renderer: "svg" });
@@ -263,7 +271,7 @@ function ChartCore({
263
271
  };
264
272
  }, [engine, hasEmpty]);
265
273
  const eventNames = Object.keys(onEvents ?? {}).sort().join("|");
266
- (0, import_react.useEffect)(() => {
274
+ (0, import_react2.useEffect)(() => {
267
275
  const chart = chartRef.current;
268
276
  if (!chart || !eventNames) return;
269
277
  const bound = eventNames.split("|").map((name) => {
@@ -276,7 +284,7 @@ function ChartCore({
276
284
  for (const [name, handler] of bound) chart.off(name, handler);
277
285
  };
278
286
  }, [engine, hasEmpty, eventNames]);
279
- (0, import_react.useEffect)(() => {
287
+ (0, import_react2.useEffect)(() => {
280
288
  const chart = chartRef.current;
281
289
  if (!chart || !group) return;
282
290
  chart.group = group;
@@ -285,7 +293,7 @@ function ChartCore({
285
293
  if (!chart.isDisposed()) chart.group = "";
286
294
  };
287
295
  }, [engine, hasEmpty, group]);
288
- (0, import_react.useEffect)(() => {
296
+ (0, import_react2.useEffect)(() => {
289
297
  const chart = chartRef.current;
290
298
  const element = containerRef.current;
291
299
  if (!chart || !element || appliedOptionRef.current === option) return;
package/dist/chart.cjs CHANGED
@@ -47,7 +47,7 @@ module.exports = __toCommonJS(chart_exports);
47
47
  var echarts = __toESM(require("echarts"), 1);
48
48
 
49
49
  // src/components/ChartCore.tsx
50
- var import_react = require("react");
50
+ var import_react2 = require("react");
51
51
 
52
52
  // src/cx.ts
53
53
  function cx(...args) {
@@ -151,6 +151,14 @@ function mergeChartTheme(theme, option) {
151
151
  return merged;
152
152
  }
153
153
 
154
+ // src/hooks/useReducedMotion.ts
155
+ var import_react = require("react");
156
+ var QUERY = "(prefers-reduced-motion: reduce)";
157
+ function prefersReducedMotion() {
158
+ if (typeof document !== "undefined" && document.documentElement.getAttribute("data-motion") === "reduce") return true;
159
+ return typeof matchMedia !== "undefined" && matchMedia(QUERY).matches;
160
+ }
161
+
154
162
  // src/components/ChartCore.tsx
155
163
  var import_jsx_runtime = require("react/jsx-runtime");
156
164
  function readToken(name) {
@@ -165,7 +173,7 @@ function themed(option, theme, element) {
165
173
  return theme === "none" ? resolved : mergeChartTheme(uixChartTheme(element), resolved);
166
174
  }
167
175
  function motionSafe(option) {
168
- if (typeof matchMedia !== "undefined" && matchMedia("(prefers-reduced-motion: reduce)").matches) {
176
+ if (prefersReducedMotion()) {
169
177
  return { ...option, animation: false };
170
178
  }
171
179
  return option;
@@ -199,23 +207,23 @@ function ChartCore({
199
207
  tables
200
208
  }) {
201
209
  const labels = { ...DEFAULT_CHART_LABELS, ...labelOverrides };
202
- const containerRef = (0, import_react.useRef)(null);
203
- const chartRef = (0, import_react.useRef)(null);
204
- const appliedOptionRef = (0, import_react.useRef)(null);
205
- const onEventsRef = (0, import_react.useRef)(onEvents);
210
+ const containerRef = (0, import_react2.useRef)(null);
211
+ const chartRef = (0, import_react2.useRef)(null);
212
+ const appliedOptionRef = (0, import_react2.useRef)(null);
213
+ const onEventsRef = (0, import_react2.useRef)(onEvents);
206
214
  onEventsRef.current = onEvents;
207
- const latestOptionRef = (0, import_react.useRef)(option);
208
- const onReadyRef = (0, import_react.useRef)(onReady);
209
- const tableId = (0, import_react.useId)();
215
+ const latestOptionRef = (0, import_react2.useRef)(option);
216
+ const onReadyRef = (0, import_react2.useRef)(onReady);
217
+ const tableId = (0, import_react2.useId)();
210
218
  const hasEmpty = empty != null;
211
219
  const hasTextAlternative = Boolean(ariaLabel || title || tableData?.length || tables?.length);
212
- const hasTextAlternativeRef = (0, import_react.useRef)(hasTextAlternative);
213
- const themeRef = (0, import_react.useRef)(theme);
220
+ const hasTextAlternativeRef = (0, import_react2.useRef)(hasTextAlternative);
221
+ const themeRef = (0, import_react2.useRef)(theme);
214
222
  latestOptionRef.current = option;
215
223
  themeRef.current = theme;
216
224
  onReadyRef.current = onReady;
217
225
  hasTextAlternativeRef.current = hasTextAlternative;
218
- (0, import_react.useEffect)(() => {
226
+ (0, import_react2.useEffect)(() => {
219
227
  const element = containerRef.current;
220
228
  if (!element) return;
221
229
  const chart = engine.init(element, null, { renderer: "svg" });
@@ -261,7 +269,7 @@ function ChartCore({
261
269
  };
262
270
  }, [engine, hasEmpty]);
263
271
  const eventNames = Object.keys(onEvents ?? {}).sort().join("|");
264
- (0, import_react.useEffect)(() => {
272
+ (0, import_react2.useEffect)(() => {
265
273
  const chart = chartRef.current;
266
274
  if (!chart || !eventNames) return;
267
275
  const bound = eventNames.split("|").map((name) => {
@@ -274,7 +282,7 @@ function ChartCore({
274
282
  for (const [name, handler] of bound) chart.off(name, handler);
275
283
  };
276
284
  }, [engine, hasEmpty, eventNames]);
277
- (0, import_react.useEffect)(() => {
285
+ (0, import_react2.useEffect)(() => {
278
286
  const chart = chartRef.current;
279
287
  if (!chart || !group) return;
280
288
  chart.group = group;
@@ -283,7 +291,7 @@ function ChartCore({
283
291
  if (!chart.isDisposed()) chart.group = "";
284
292
  };
285
293
  }, [engine, hasEmpty, group]);
286
- (0, import_react.useEffect)(() => {
294
+ (0, import_react2.useEffect)(() => {
287
295
  const chart = chartRef.current;
288
296
  const element = containerRef.current;
289
297
  if (!chart || !element || appliedOptionRef.current === option) return;
@@ -4,6 +4,15 @@ interface ComboboxOption {
4
4
  keywords?: readonly string[];
5
5
  disabled?: boolean;
6
6
  }
7
+ /** A titled group of options (HAR-1588). */
8
+ interface ComboboxGroup {
9
+ label: string;
10
+ options: readonly ComboboxOption[];
11
+ /** Disables every option in the group. */
12
+ disabled?: boolean;
13
+ }
7
14
  declare function filterComboboxOptions(options: readonly ComboboxOption[], query: string): ComboboxOption[];
15
+ /** Options and groups that match `query` (label, value or keywords); a group stays when any of its options does. */
16
+ declare function filterComboboxItems(items: readonly (ComboboxOption | ComboboxGroup)[], query: string): (ComboboxOption | ComboboxGroup)[];
8
17
 
9
- export { type ComboboxOption, filterComboboxOptions };
18
+ export { type ComboboxGroup, type ComboboxOption, filterComboboxItems, filterComboboxOptions };
@@ -1,3 +1,4 @@
1
+ const isGroup = (item) => Array.isArray(item.options);
1
2
  function filterComboboxOptions(options, query) {
2
3
  const needle = query.trim().toLocaleLowerCase();
3
4
  if (!needle) return [...options];
@@ -5,6 +6,20 @@ function filterComboboxOptions(options, query) {
5
6
  (option) => [option.label, option.value, ...option.keywords ?? []].some((part) => part.toLocaleLowerCase().includes(needle))
6
7
  );
7
8
  }
9
+ function filterComboboxItems(items, query) {
10
+ if (!query.trim()) return [...items];
11
+ const out = [];
12
+ for (const item of items) {
13
+ if (isGroup(item)) {
14
+ const options = filterComboboxOptions(item.options, query);
15
+ if (options.length) out.push({ ...item, options });
16
+ } else if (filterComboboxOptions([item], query).length) {
17
+ out.push(item);
18
+ }
19
+ }
20
+ return out;
21
+ }
8
22
  export {
23
+ filterComboboxItems,
9
24
  filterComboboxOptions
10
25
  };
@@ -0,0 +1,44 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ /** One command of a `CommandPalette` in items mode. */
4
+ interface CommandPaletteItem {
5
+ /** Unique among the items; also the option's id suffix. */
6
+ id: string;
7
+ label: string;
8
+ /** Group heading the item is listed under. Items without one form a group without a heading. */
9
+ group?: string;
10
+ /** More words that find the item but are not shown: synonyms, an old name, a record number. */
11
+ keywords?: readonly string[];
12
+ /** A second line, e.g. where the command leads. Not searched. */
13
+ description?: string;
14
+ /** Leading icon (decorative). */
15
+ icon?: ReactNode;
16
+ /** Key names (`['Mod', 'K']`) shown at the end of the row and set as `aria-keyshortcuts`. */
17
+ shortcut?: readonly string[];
18
+ /** Runs when the item is chosen. */
19
+ onSelect?: () => void;
20
+ /** Where the item leads: `onNavigate(href)`, else the browser goes there. */
21
+ href?: string;
22
+ /** Shown but not choosable; skipped by the arrow keys. */
23
+ disabled?: boolean;
24
+ }
25
+ /** A group of found commands, in the order they are shown. */
26
+ interface CommandPaletteGroup {
27
+ /** The group heading; `undefined` for items without a group. */
28
+ label: string | undefined;
29
+ items: CommandPaletteItem[];
30
+ }
31
+ /**
32
+ * The commands `query` finds, best first (HAR-1378): a label that starts with the query, then
33
+ * labels where every word of the query starts a word, then labels that contain every word, then
34
+ * matches through `keywords`. Equal matches keep the order they were given in. An empty query
35
+ * finds every item, in order.
36
+ */
37
+ declare function filterCommandItems(items: readonly CommandPaletteItem[], query: string): CommandPaletteItem[];
38
+ /**
39
+ * `items` in groups, each group where its first item is, its items in their given order. With a
40
+ * ranked list (from `filterCommandItems`) the group of the best match comes first.
41
+ */
42
+ declare function groupCommandItems(items: readonly CommandPaletteItem[]): CommandPaletteGroup[];
43
+
44
+ export { type CommandPaletteGroup, type CommandPaletteItem, filterCommandItems, groupCommandItems };
@@ -0,0 +1,36 @@
1
+ import { foldForSearch } from "./search-suggest-model.js";
2
+ const words = (folded) => folded.split(/[\s\-_/.,:;()[\]'"›>·|]+/u).filter(Boolean);
3
+ function score(item, query, tokens) {
4
+ const label = foldForSearch(item.label).text;
5
+ if (label.startsWith(query)) return 0;
6
+ const labelWords = words(label);
7
+ if (tokens.every((t) => labelWords.some((w) => w.startsWith(t)))) return 1;
8
+ if (tokens.every((t) => label.includes(t))) return 2;
9
+ const keywords = (item.keywords ?? []).map((k) => foldForSearch(k).text);
10
+ if (tokens.every((t) => label.includes(t) || keywords.some((k) => k.includes(t)))) return 3;
11
+ return -1;
12
+ }
13
+ function filterCommandItems(items, query) {
14
+ const folded = foldForSearch(query.trim()).text;
15
+ if (!folded) return [...items];
16
+ const tokens = folded.split(/\s+/).filter(Boolean);
17
+ return items.map((item, index) => ({ item, index, rank: score(item, folded, tokens) })).filter((entry) => entry.rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map((entry) => entry.item);
18
+ }
19
+ function groupCommandItems(items) {
20
+ const groups = [];
21
+ const byLabel = /* @__PURE__ */ new Map();
22
+ for (const item of items) {
23
+ let group = byLabel.get(item.group);
24
+ if (!group) {
25
+ group = { label: item.group, items: [] };
26
+ byLabel.set(item.group, group);
27
+ groups.push(group);
28
+ }
29
+ group.items.push(item);
30
+ }
31
+ return groups;
32
+ }
33
+ export {
34
+ filterCommandItems,
35
+ groupCommandItems
36
+ };
@@ -0,0 +1,44 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { AvatarPresence } from './Avatar.js';
4
+ import { Placement } from '../overlay-position.js';
5
+
6
+ interface AccountMenuUser {
7
+ /** The person's name, shown on the trigger and used for the avatar's initials. */
8
+ name: string;
9
+ /** A second line: an email, a role, a branch. */
10
+ sub?: ReactNode;
11
+ /** A photo URL, or your own avatar content. Without it the avatar shows the initials. */
12
+ avatar?: string | ReactNode;
13
+ /** A presence dot on the avatar (`online`, `busy`, `away`, `offline`). */
14
+ status?: AvatarPresence;
15
+ }
16
+ interface AccountMenuLabels {
17
+ /** The menu's name (`aria-label` of the list). Default "Account". */
18
+ menu: string;
19
+ }
20
+ declare const DEFAULT_ACCOUNT_MENU_LABELS: AccountMenuLabels;
21
+ interface AccountMenuProps {
22
+ user: AccountMenuUser;
23
+ /**
24
+ * The menu's rows: `MenuItem` (profile, preferences, sign out with `tone="danger"`),
25
+ * `MenuRadioGroup` for a presence choice, `MenuSeparator`.
26
+ */
27
+ items?: ReactNode;
28
+ /**
29
+ * The rail form: the trigger shows the avatar only; the name stays the button's accessible
30
+ * name. Pair it with `Sidebar nav="rail"`.
31
+ */
32
+ collapsed?: boolean;
33
+ /** Where the menu opens. Default `top-start`: the trigger usually sits at the bottom of a sidebar. */
34
+ placement?: Placement;
35
+ labels?: Partial<AccountMenuLabels>;
36
+ /** The spoken presence words (after the name and second line), e.g. `{ online: 'Dostupan' }`. */
37
+ presenceLabels?: Partial<Record<AvatarPresence, string>>;
38
+ className?: string;
39
+ }
40
+ /** Up to two initials from a name, first and last word: "Ada Lovelace" → "AL", "Dževad Hodžić" → "DH". */
41
+ declare function accountInitials(name: string): string;
42
+ declare function AccountMenu({ user, items, collapsed, placement, labels: labelOverrides, presenceLabels, className }: AccountMenuProps): react.JSX.Element;
43
+
44
+ export { AccountMenu, type AccountMenuLabels, type AccountMenuProps, type AccountMenuUser, DEFAULT_ACCOUNT_MENU_LABELS, accountInitials };
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { cx } from "../cx.js";
4
+ import { useUixLabels } from "../labels-context.js";
5
+ import { ChevronsUpDownIcon } from "../icons/components.js";
6
+ import { Avatar, DEFAULT_PRESENCE_LABELS } from "./Avatar.js";
7
+ import { Menu } from "./Menu.js";
8
+ import { useInShellDrawer } from "../shell-context.js";
9
+ const DEFAULT_ACCOUNT_MENU_LABELS = { menu: "Account" };
10
+ function accountInitials(name) {
11
+ const words = name.trim().split(/\s+/).filter(Boolean);
12
+ if (words.length === 0) return "";
13
+ const first = [...words[0]][0] ?? "";
14
+ const last = words.length > 1 ? [...words[words.length - 1]][0] ?? "" : "";
15
+ return (first + last).toLocaleUpperCase();
16
+ }
17
+ const SILENT_PRESENCE = { online: "", busy: "", away: "", offline: "" };
18
+ function AccountMenu({ user, items, collapsed = false, placement = "top-start", labels: labelOverrides, presenceLabels, className }) {
19
+ const uixLabels = useUixLabels();
20
+ const labels = { ...DEFAULT_ACCOUNT_MENU_LABELS, ...uixLabels.accountMenu, ...labelOverrides };
21
+ const inDrawer = useInShellDrawer();
22
+ const rail = collapsed && !inDrawer;
23
+ const photo = typeof user.avatar === "string" ? user.avatar : void 0;
24
+ const custom = typeof user.avatar === "string" ? void 0 : user.avatar;
25
+ const trigger = /* @__PURE__ */ jsxs("button", { type: "button", className: cx("uix-account-menu", rail && "uix-account-menu--collapsed", className), children: [
26
+ /* @__PURE__ */ jsx(Avatar, { src: photo, alt: "", presence: user.status, presenceLabels: SILENT_PRESENCE, className: "uix-account-menu__avatar", children: custom ?? (photo ? null : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: accountInitials(user.name) })) }),
27
+ /* @__PURE__ */ jsxs("span", { className: "uix-account-menu__text", children: [
28
+ /* @__PURE__ */ jsx("span", { className: "uix-account-menu__name", children: user.name }),
29
+ user.sub != null && /* @__PURE__ */ jsx("span", { className: "uix-account-menu__sub", children: user.sub }),
30
+ user.status && /* @__PURE__ */ jsxs("span", { className: "uix-visually-hidden", children: [
31
+ ", ",
32
+ presenceLabels?.[user.status] ?? DEFAULT_PRESENCE_LABELS[user.status]
33
+ ] })
34
+ ] }),
35
+ /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "uix-account-menu__chevron" })
36
+ ] });
37
+ return /* @__PURE__ */ jsx(Menu, { trigger, label: labels.menu, placement, children: items });
38
+ }
39
+ export {
40
+ AccountMenu,
41
+ DEFAULT_ACCOUNT_MENU_LABELS,
42
+ accountInitials
43
+ };