@ngrok/mantle 0.81.1 → 0.82.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 (115) hide show
  1. package/dist/accordion.js +1 -1
  2. package/dist/agent.json +4 -1
  3. package/dist/alert-BWwNPOMI.d.ts +391 -0
  4. package/dist/alert-center.d.ts +647 -0
  5. package/dist/alert-center.js +1 -0
  6. package/dist/alert-dialog.js +1 -1
  7. package/dist/alert-vwFd7qdp.js +1 -0
  8. package/dist/alert.d.ts +1 -390
  9. package/dist/alert.js +1 -1
  10. package/dist/{anchor-DfeXTpKW.js → anchor-3OGK2UKU.js} +1 -1
  11. package/dist/anchor.js +1 -1
  12. package/dist/app-layout.d.ts +566 -0
  13. package/dist/app-layout.js +1 -0
  14. package/dist/area-chart.js +1 -1
  15. package/dist/badge.js +1 -1
  16. package/dist/bar-chart.js +1 -1
  17. package/dist/breadcrumb.d.ts +1 -1
  18. package/dist/breadcrumb.js +1 -1
  19. package/dist/browser-only-CmEEzfU3.js +1 -0
  20. package/dist/browser-only.js +1 -1
  21. package/dist/{button-DjpEKt2X.js → button-Cnja9Bsr.js} +1 -1
  22. package/dist/{button-D9n09xUg.js → button-DmJkYfyl.js} +1 -1
  23. package/dist/{button-BAno7KIU.js → button-IlxHhjPK.js} +1 -1
  24. package/dist/button.js +1 -1
  25. package/dist/calendar.d.ts +1 -1
  26. package/dist/card.js +1 -1
  27. package/dist/centered-layout.d.ts +9 -9
  28. package/dist/centered-layout.js +1 -1
  29. package/dist/chart-B3pAvmkk.js +2 -0
  30. package/dist/{choice-BHwFSSyv.js → choice-CnwfjSEu.js} +1 -1
  31. package/dist/choice.js +1 -1
  32. package/dist/code-block.js +1 -1
  33. package/dist/code.js +1 -1
  34. package/dist/combobox.js +1 -1
  35. package/dist/command.js +1 -1
  36. package/dist/cookie-ca4g5CKp.js +1 -0
  37. package/dist/{copy-to-clipboard-BsCQ9m6K.js → copy-to-clipboard-B4UB6pts.js} +1 -1
  38. package/dist/data-slot-EM6s2WEU.js +1 -0
  39. package/dist/data-table.js +1 -1
  40. package/dist/description-list.js +1 -1
  41. package/dist/{dialog-DWZWd5Jt.js → dialog-DozL6n-F.js} +1 -1
  42. package/dist/dialog.d.ts +1 -1
  43. package/dist/dialog.js +1 -1
  44. package/dist/dropdown-menu-BRH0Wd_z.js +1 -0
  45. package/dist/dropdown-menu.js +1 -1
  46. package/dist/empty.js +1 -1
  47. package/dist/field.d.ts +1 -1
  48. package/dist/field.js +1 -1
  49. package/dist/hooks.js +1 -1
  50. package/dist/{icons-DLCs1hLP.js → icons-Bb_zF2OV.js} +1 -1
  51. package/dist/icons.js +1 -1
  52. package/dist/input.js +1 -1
  53. package/dist/line-chart.js +1 -1
  54. package/dist/{list-51KQvENW.js → list-CJABVHwi.js} +1 -1
  55. package/dist/list.js +1 -1
  56. package/dist/llms.txt +4 -1
  57. package/dist/main.d.ts +35 -1
  58. package/dist/main.js +1 -1
  59. package/dist/mantle.css +21 -1
  60. package/dist/media-object.js +1 -1
  61. package/dist/multi-select.d.ts +10 -2
  62. package/dist/multi-select.js +1 -1
  63. package/dist/otp-input.js +1 -1
  64. package/dist/pagination.js +1 -1
  65. package/dist/platform-BVD3gpKD.js +1 -0
  66. package/dist/{primitive-trJDqIXJ.js → primitive-D-9GIFWb.js} +1 -1
  67. package/dist/progress.d.ts +8 -8
  68. package/dist/qr-code.js +1 -1
  69. package/dist/radio-group.d.ts +10 -0
  70. package/dist/radio-group.js +1 -1
  71. package/dist/sandboxed-on-click.js +1 -1
  72. package/dist/scatter-plot.d.ts +2 -1
  73. package/dist/scatter-plot.js +1 -1
  74. package/dist/{select-BCHWvmyC.js → select-BReznXaw.js} +1 -1
  75. package/dist/select.js +1 -1
  76. package/dist/selectable-list.js +1 -1
  77. package/dist/{separator-bpE_kooz.js → separator-D0D6VyyM.js} +1 -1
  78. package/dist/separator.js +1 -1
  79. package/dist/sheet-BxvTfPLM.js +1 -0
  80. package/dist/sheet.d.ts +1 -1
  81. package/dist/sheet.js +1 -1
  82. package/dist/sidebar.d.ts +2558 -0
  83. package/dist/sidebar.js +1 -0
  84. package/dist/{skeleton-CsbUHbBA.js → skeleton-BhcJMpem.js} +1 -1
  85. package/dist/skeleton.js +1 -1
  86. package/dist/skip-to-main-link.js +1 -1
  87. package/dist/slot-DdgxmuI5.d.ts +67 -0
  88. package/dist/slot-DpNWVci8.js +1 -0
  89. package/dist/slot.d.ts +1 -1
  90. package/dist/slot.js +1 -1
  91. package/dist/split-button.js +1 -1
  92. package/dist/tabs.js +1 -1
  93. package/dist/theme-BorfgnNh.js +1 -0
  94. package/dist/theme-switcher.d.ts +1 -1
  95. package/dist/theme-switcher.js +1 -1
  96. package/dist/theme.js +1 -1
  97. package/dist/toast.js +1 -1
  98. package/dist/tooltip-Dnu35cjU.js +1 -0
  99. package/dist/tooltip-mrpLz4DZ.d.ts +218 -0
  100. package/dist/tooltip.d.ts +1 -217
  101. package/dist/tooltip.js +1 -1
  102. package/dist/use-breakpoint-Wd7_5-Mu.js +1 -0
  103. package/dist/use-copy-to-clipboard-CSyp4Zk0.js +1 -0
  104. package/dist/use-is-hydrated-DDCqXmju.js +1 -0
  105. package/dist/{use-prefers-reduced-motion-CagaNRgm.js → use-prefers-reduced-motion-Bk5zAfHY.js} +1 -1
  106. package/dist/utils.js +1 -1
  107. package/dist/well.js +1 -1
  108. package/package.json +16 -13
  109. package/dist/browser-only-CPH56Xw_.js +0 -1
  110. package/dist/chart-Do2qkrxl.js +0 -2
  111. package/dist/dropdown-menu-RyDWoKHx.js +0 -1
  112. package/dist/slot-BtwKJTLq.d.ts +0 -25
  113. package/dist/slot-CDk0Bb9z.js +0 -1
  114. package/dist/theme-C26-Xolp.js +0 -1
  115. package/dist/use-copy-to-clipboard-DqQ0_N3E.js +0 -1
@@ -0,0 +1,647 @@
1
+ import { t as WithDataSlot } from "./data-slot-CChfb_cv.js";
2
+ import { t as Alert } from "./alert-BWwNPOMI.js";
3
+ import { ComponentProps, ReactNode } from "react";
4
+ //#region src/components/alert-center/alert-center.d.ts
5
+ /**
6
+ * The tone an alert's color communicates — identical to `Alert`'s intent axis,
7
+ * so an item's `intent` flows straight through to the `Alert` chrome that
8
+ * renders it. Also the severity ranking key: `danger` › `warning` ›
9
+ * `important` › `info` › `success` decides which item the bar shows.
10
+ *
11
+ * @see https://mantle.ngrok.com/components/feedback/alert-center
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <AlertCenter.Item id="payment-failed" intent="danger">…</AlertCenter.Item>
16
+ * ```
17
+ */
18
+ type AlertCenterIntent = "danger" | "important" | "info" | "success" | "warning";
19
+ /**
20
+ * Props for {@link AlertCenter.Root} — the expansion's open state. The alerts
21
+ * themselves are authored as `AlertCenter.Item` children.
22
+ *
23
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterroot
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <AlertCenter.Root open={expanded} onOpenChange={setExpanded}>
28
+ * <AlertCenter.Bar />
29
+ * <AlertCenter.Content />
30
+ * <AlertCenter.Item id="payment-failed" intent="danger">…</AlertCenter.Item>
31
+ * </AlertCenter.Root>
32
+ * ```
33
+ */
34
+ type AlertCenterRootProps = {
35
+ /** Controlled expanded state of the additional-alert list. Pair with `onOpenChange`. */
36
+ open?: boolean;
37
+ /**
38
+ * Uncontrolled initial expanded state of the additional-alert list.
39
+ *
40
+ * @default false
41
+ */
42
+ defaultOpen?: boolean;
43
+ /** Called when the additional-alert list expands or collapses. */
44
+ onOpenChange?: (open: boolean) => void;
45
+ /**
46
+ * The `AlertCenter.Bar`, `AlertCenter.Content`, and every `AlertCenter.Item`.
47
+ * Items may be authored anywhere under the root — their children stay in this
48
+ * tree and are projected into the bar or an expansion row by rank.
49
+ */
50
+ children?: ReactNode;
51
+ };
52
+ /**
53
+ * The renderless state owner. It creates the registration store the
54
+ * `AlertCenter.Item` children register into, owns the inline expansion's open
55
+ * state, and mounts the persistent live-region announcer. Compose its `Bar`
56
+ * (and `Content`) inside `AppLayout.Notice`, alongside any other window-level
57
+ * notice, so all top-of-viewport messaging shares one layout slot.
58
+ *
59
+ * Items register client-side (from layout effects), so server-rendered HTML
60
+ * contains no bar; it enters with its height animation after hydration — the
61
+ * same entrance every arriving alert gets by design.
62
+ *
63
+ * **Data attributes:**
64
+ *
65
+ * | Data Attribute | Value | Description |
66
+ * | --- | --- | --- |
67
+ * | `data-slot` | `alert-center-announcer` | On the persistent visually-hidden `role="status"` live region Root mounts. |
68
+ *
69
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterroot
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * <AlertCenter.Root>
74
+ * <AlertCenter.Bar />
75
+ * <AlertCenter.Content />
76
+ * {paymentFailed && (
77
+ * <AlertCenter.Item id="payment-failed" intent="danger">
78
+ * <Alert.Icon />
79
+ * <Alert.Content>
80
+ * <Alert.Title>
81
+ * Payment failed — <a href="/billing">update your card</a>
82
+ * </Alert.Title>
83
+ * </Alert.Content>
84
+ * </AlertCenter.Item>
85
+ * )}
86
+ * </AlertCenter.Root>
87
+ * ```
88
+ */
89
+ declare const Root: ({ children, defaultOpen, onOpenChange, open }: AlertCenterRootProps) => import("react").JSX.Element;
90
+ /**
91
+ * Props for {@link AlertCenter.Item}: the coordination facts the center needs
92
+ * to rank, announce, and label an alert — everything presentational is the
93
+ * authored `children`.
94
+ *
95
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenteritem
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * <AlertCenter.Root>
100
+ * <AlertCenter.Bar />
101
+ * <AlertCenter.Content />
102
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
103
+ * <Alert.Icon />
104
+ * <Alert.Content>
105
+ * <Alert.Title>Approaching your data transfer limit</Alert.Title>
106
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
107
+ * </Alert.Content>
108
+ * </AlertCenter.Item>
109
+ * </AlertCenter.Root>
110
+ * ```
111
+ */
112
+ type AlertCenterItemProps = {
113
+ /**
114
+ * Stable identity. It keys the item's stable host element (children keep
115
+ * their state as the host moves between the bar and a row), pins the
116
+ * item's arrival order (a returning id resumes its original position), and
117
+ * is stamped on the chrome as `data-alert-id` for styling. Must be unique
118
+ * among the items mounted under one `AlertCenter.Root` — a second mounted
119
+ * item claiming the same id throws, since both would project into that
120
+ * id's single host.
121
+ */
122
+ id: string;
123
+ /**
124
+ * The tone the alert's color communicates. Drives both the severity ranking
125
+ * and the intent of the `Alert.Root` chrome the children render inside.
126
+ */
127
+ intent: AlertCenterIntent;
128
+ /** Optional classes for this item's chrome `Alert.Root`, in both placements. */
129
+ className?: string;
130
+ /**
131
+ * The banner content: compose `Alert.Icon`, `Alert.Content`, `Alert.Title`,
132
+ * `Alert.Description`, and `AlertCenter.DismissIconButton`. Do NOT include
133
+ * `Alert.Root` — the center provides the chrome (with this item's `intent`)
134
+ * at whichever placement the item ranks into.
135
+ */
136
+ children: ReactNode;
137
+ };
138
+ /**
139
+ * One account alert, authored as JSX. It registers its coordination facts
140
+ * with the center and renders its children through a portal into a stable
141
+ * per-id host element that `AlertCenter.Bar` / `AlertCenter.Content`
142
+ * physically adopt into their chrome. Mount it to show the alert, unmount it
143
+ * to remove it — dismissal is just your state flipping the condition off.
144
+ *
145
+ * Because the children stay in YOUR React tree (only their DOM lands in the
146
+ * chrome), context providers and error boundaries around the item work, and
147
+ * router-aware links resolve at the authoring location. The host element is
148
+ * stable and moved — not remounted — between the bar and a row, so authored
149
+ * content keeps its state (and, in engines with `Element.moveBefore`, even
150
+ * focus) across re-ranks. While an item ranks nowhere visible (e.g. the
151
+ * expansion is not composed), its children stay mounted on a detached host —
152
+ * rendered by React, contributing nothing to the document.
153
+ *
154
+ * Server rendering emits no alert DOM — the bar enters after hydration with
155
+ * its height animation, the same entrance every arriving alert gets.
156
+ *
157
+ * **Data attributes:**
158
+ *
159
+ * | Data Attribute | Value | Description |
160
+ * | --- | --- | --- |
161
+ * | `data-slot` | `alert-center-item-host` | On the stable per-id host element the item's children portal into. |
162
+ * | `data-alert-host` | the item's `id` | On that same host — which alert's projected children it holds. |
163
+ *
164
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenteritem
165
+ *
166
+ * @example
167
+ * ```tsx
168
+ * <AlertCenter.Root>
169
+ * <AlertCenter.Bar />
170
+ * <AlertCenter.Content />
171
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
172
+ * <Alert.Icon />
173
+ * <Alert.Content>
174
+ * <Alert.Title>
175
+ * You've used 92% of your monthly transfer. <a href="/billing">Upgrade</a>
176
+ * </Alert.Title>
177
+ * <Alert.Description>Free accounts include 5 GB of transfer per month.</Alert.Description>
178
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
179
+ * </Alert.Content>
180
+ * </AlertCenter.Item>
181
+ * </AlertCenter.Root>
182
+ * ```
183
+ */
184
+ declare const Item: ({ children, className, id, intent }: AlertCenterItemProps) => import("react").ReactPortal | null;
185
+ type AlertCenterDismissIconButtonProps = ComponentProps<typeof Alert.DismissIconButton> & WithDataSlot & {
186
+ /**
187
+ * Dismissal is consumer-owned: remove the alert by unmounting its
188
+ * `AlertCenter.Item` (and persist that however you like). Required because a
189
+ * dismiss affordance that does nothing is always an authoring error.
190
+ */
191
+ onClick: NonNullable<ComponentProps<typeof Alert.DismissIconButton>["onClick"]>;
192
+ };
193
+ /**
194
+ * The dismiss affordance for the item it's composed inside. A thin wrapper over
195
+ * `Alert.DismissIconButton` whose label defaults to `Dismiss ${title}`, derived
196
+ * from the enclosing banner's RENDERED `Alert.Title` text and re-read on every
197
+ * commit so the accessible name stays in lockstep with the visible copy (pass
198
+ * `label` to override, e.g. when the title is long). Compose it — or leave it
199
+ * out — per alert; its presence IS the alert's dismissability.
200
+ *
201
+ * Where the control sits in each placement is the chrome's business, not this
202
+ * wrapper's: {@link dismissClearsExpandControl} seats it beside the bar's
203
+ * expand control, and {@link singleLineBarControls} re-centers it in a
204
+ * single-line bar.
205
+ *
206
+ * **Data attributes:**
207
+ *
208
+ * | Data Attribute | Value | Description |
209
+ * | --- | --- | --- |
210
+ * | `data-slot` | `alert-center-dismiss-icon-button` | Replaces `Alert.DismissIconButton`'s own `alert-dismiss-icon-button` on the rendered button. |
211
+ * | `data-alert-dismiss` | present | Read, not stamped — `Alert` emits it, and `AlertCenter`'s bar CSS positions the control with it. |
212
+ *
213
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterdismissiconbutton
214
+ *
215
+ * @example
216
+ * ```tsx
217
+ * <AlertCenter.Root>
218
+ * <AlertCenter.Bar />
219
+ * <AlertCenter.Content />
220
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
221
+ * <Alert.Icon />
222
+ * <Alert.Content>
223
+ * <Alert.Title>Approaching your data transfer limit</Alert.Title>
224
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
225
+ * </Alert.Content>
226
+ * </AlertCenter.Item>
227
+ * </AlertCenter.Root>
228
+ * ```
229
+ */
230
+ declare const DismissIconButton: ({ "data-slot": dataSlot, label, ref, ...props }: AlertCenterDismissIconButtonProps) => import("react").JSX.Element;
231
+ type AlertCenterBarProps = Omit<ComponentProps<typeof Alert.Root>, "appearance" | "intent" | "children"> & WithDataSlot & {
232
+ /** The bar renders the top-ranked item's authored children — it takes none of its own. */
233
+ children?: never;
234
+ };
235
+ /**
236
+ * The always-visible, full-width strip. It renders the single highest-severity
237
+ * item's authored children INLINE — icon, title, description, and its
238
+ * call-to-action — so the top CTA is one glance (and zero extra clicks) away,
239
+ * then appends a count-and-caret control that expands the additional alerts
240
+ * below the bar. Collapses to nothing when there are no alerts (like
241
+ * `AppLayout.Notice`), so it can stay mounted and render unconditionally.
242
+ *
243
+ * The bar renders the top alert as authored, so it is exactly as tall as that
244
+ * content: single-line for a title alone, two lines once an `Alert.Description`
245
+ * is composed (matching how the same alert renders as an expansion row). Its
246
+ * chrome carries `data-placement="bar"` and `data-alert-id` as styling hooks for
247
+ * placement-aware authored content — `in-data-[placement=bar]:hidden` keeps a
248
+ * given element out of the bar and shows it only in the expansion.
249
+ *
250
+ * The bar itself claims NO ARIA landmark (deliberately, like `AppLayout.Notice`)
251
+ * — arrivals and re-ranks are announced by the persistent visually-hidden
252
+ * `role="status"` region that `AlertCenter.Root` mounts.
253
+ *
254
+ * **Data attributes:**
255
+ *
256
+ * | Data Attribute | Value | Description |
257
+ * | --- | --- | --- |
258
+ * | `data-slot` | `alert-center-bar-wrapper` | On the presence wrapper that owns the enter/exit animation. |
259
+ * | `data-slot` | `alert-center-bar` | On the banner chrome (`Alert.Root`) the top item's children render inside. |
260
+ * | `data-slot` | `alert-center-bar-mount` | On the layout-transparent element the top item's host is adopted into. |
261
+ * | `data-state` | `"open"` \| `"closed"` | On the wrapper; drives the enter/exit transition, and stays `closed` while the exit plays. |
262
+ * | `data-placement` | `"bar"` | On the chrome — where the top item's children are currently rendering. |
263
+ * | `data-alert-id` | the top item's `id` | On the chrome; per-alert styling and testing hook. |
264
+ * | `data-alert-dismiss` | present on the dismiss control | Read, not stamped — `Alert` emits it; the bar's CSS centers and offsets the control with it. |
265
+ * | `data-alert-expand` | present on the expand control | Read, not stamped — `Alert` emits it; the bar's CSS centers the control with it. |
266
+ *
267
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterbar
268
+ *
269
+ * @example
270
+ * ```tsx
271
+ * <AlertCenter.Root>
272
+ * <AlertCenter.Bar />
273
+ * <AlertCenter.Content />
274
+ * <AlertCenter.Item id="payment-failed" intent="danger">
275
+ * <Alert.Icon />
276
+ * <Alert.Content>
277
+ * <Alert.Title>
278
+ * Payment failed — we couldn't charge your card.{" "}
279
+ * <a href="/billing">Update payment method</a>
280
+ * </Alert.Title>
281
+ * <Alert.Description>
282
+ * Update your payment method to avoid a service interruption.
283
+ * </Alert.Description>
284
+ * </Alert.Content>
285
+ * </AlertCenter.Item>
286
+ * {!dismissed.has("transfer-limit") && (
287
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
288
+ * <Alert.Icon />
289
+ * <Alert.Content>
290
+ * <Alert.Title>
291
+ * You've used 92% of your monthly transfer.{" "}
292
+ * <a href="/billing/choose-a-plan">Upgrade</a>
293
+ * </Alert.Title>
294
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
295
+ * </Alert.Content>
296
+ * </AlertCenter.Item>
297
+ * )}
298
+ * </AlertCenter.Root>
299
+ * ```
300
+ */
301
+ declare const Bar: ({ className, "data-slot": dataSlot, ref, ...props }: AlertCenterBarProps) => import("react").JSX.Element | null;
302
+ type AlertCenterContentProps = Omit<ComponentProps<"div">, "children" | "id"> & WithDataSlot & {
303
+ /** Rows are the registered items' authored children — Content takes none of its own. */
304
+ children?: never;
305
+ };
306
+ /**
307
+ * The inline expansion below `AlertCenter.Bar`. It renders the additional
308
+ * alerts (every registered item except the bar's top one), ranked
309
+ * highest-severity-first, as full-width banner rows that push the app shell
310
+ * down while expanded. Each row is the item's authored children inside an
311
+ * `Alert.Root` chrome stamped with `data-placement="list"` and
312
+ * `data-alert-id`.
313
+ *
314
+ * `aria-label` (default `"More alerts"`) and `aria-labelledby` name the row
315
+ * list itself — the outer wrapper is `role="generic"`, where ARIA prohibits
316
+ * accessible names, so a name passed here would otherwise be dropped.
317
+ *
318
+ * **Data attributes:**
319
+ *
320
+ * | Data Attribute | Value | Description |
321
+ * | --- | --- | --- |
322
+ * | `data-slot` | `alert-center-content` | On the expansion wrapper that owns the collapse animation. |
323
+ * | `data-slot` | `alert-center-item` | On each row's banner chrome (`Alert.Root`). |
324
+ * | `data-state` | `"open"` \| `"closed"` | On the wrapper; drives the collapse transition. |
325
+ * | `data-placement` | `"list"` | On each row's chrome — where that item's children are currently rendering. |
326
+ * | `data-alert-id` | the row item's `id` | On each row's chrome; per-alert styling and testing hook. |
327
+ * | `data-alert-mount` | the row item's `id` | On the row's layout-transparent mount point — the element that item's host is adopted into. |
328
+ *
329
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcentercontent
330
+ *
331
+ * @example
332
+ * ```tsx
333
+ * <AlertCenter.Root>
334
+ * <AlertCenter.Bar />
335
+ * <AlertCenter.Content aria-label="Autres alertes" />
336
+ * <AlertCenter.Item id="payment-failed" intent="danger">
337
+ * <Alert.Icon />
338
+ * <Alert.Content>
339
+ * <Alert.Title>
340
+ * Payment failed — <a href="/billing">update your card</a>
341
+ * </Alert.Title>
342
+ * </Alert.Content>
343
+ * </AlertCenter.Item>
344
+ * {!dismissed.has("transfer-limit") && (
345
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
346
+ * <Alert.Icon />
347
+ * <Alert.Content>
348
+ * <Alert.Title>Approaching your data transfer limit</Alert.Title>
349
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
350
+ * </Alert.Content>
351
+ * </AlertCenter.Item>
352
+ * )}
353
+ * </AlertCenter.Root>
354
+ * ```
355
+ */
356
+ declare const Content: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className, "data-slot": dataSlot, ref, ...props }: AlertCenterContentProps) => import("react").JSX.Element | null;
357
+ /**
358
+ * A single, top-level entry point for one-to-many account alerts and their
359
+ * upgrade CTAs — the aggregation layer that replaces a stack of independent
360
+ * window banners. Alerts are AUTHORED as `AlertCenter.Item` JSX (mount to
361
+ * show, unmount to dismiss); each item registers its coordination facts, and
362
+ * the center derives the count, the top alert, and the severity ranking from
363
+ * the registrations. `AlertCenter.Bar` shows the highest-severity item inline
364
+ * (with its CTA) and a count-and-caret control; `AlertCenter.Content` expands
365
+ * the remaining items as full-width banners.
366
+ *
367
+ * Ranking is deterministic: severity first (`danger` › `warning` ›
368
+ * `important` › `info` › `success`), then arrival order within an intent —
369
+ * items mounting together rank in tree order, later arrivals append after
370
+ * their same-intent peers, and a dismissed-then-returning id resumes its
371
+ * original position.
372
+ *
373
+ * Compose `Bar` and `Content` into `AppLayout.Notice`, alongside any other
374
+ * window-level notice. Items may be authored anywhere under `Root`: their
375
+ * children stay in the author's React tree (context providers and error
376
+ * boundaries around an item work; router links resolve where the item is
377
+ * written) while their DOM renders through a stable per-id host that the bar
378
+ * and rows physically adopt — so content keeps its state across re-ranks.
379
+ *
380
+ * Siblings: `Alert` (`@ngrok/mantle/alert`) is a single inline banner you place
381
+ * and control yourself; `Toast` (`@ngrok/mantle/toast`) is for transient,
382
+ * ephemeral notifications; `AppLayout.Notice` (`@ngrok/mantle/app-layout`) is
383
+ * the layout slot this composes INTO, not a competitor. `AlertCenter` answers
384
+ * only the one-to-many case: persistent, ACCOUNT-level alerts that must be
385
+ * ranked and collapsed into a single top-level bar.
386
+ *
387
+ * @see https://mantle.ngrok.com/components/feedback/alert-center
388
+ *
389
+ * @example
390
+ * Composition (items render no DOM in place; their children portal into a
391
+ * stable host the bar or a row adopts):
392
+ * ```
393
+ * AlertCenter.Root
394
+ * ├── AlertCenter.Bar ← the top-ranked item's children, in Alert chrome
395
+ * ├── AlertCenter.Content ← every other item's children, as ranked rows
396
+ * └── AlertCenter.Item (0..n, renderless)
397
+ * └── Alert.Icon / Alert.Content / Alert.Title / Alert.Description /
398
+ * AlertCenter.DismissIconButton
399
+ * ```
400
+ *
401
+ * @example
402
+ * ```tsx
403
+ * <AppLayout.Root className="fixed inset-0">
404
+ * <AppLayout.Notice>
405
+ * {showPreviewNotice && <PreviewNotice />}
406
+ * <AlertCenter.Root>
407
+ * <AlertCenter.Bar />
408
+ * <AlertCenter.Content />
409
+ * <AlertCenter.Item id="payment-failed" intent="danger">
410
+ * <Alert.Icon />
411
+ * <Alert.Content>
412
+ * <Alert.Title>
413
+ * Payment failed — we couldn't charge your card.{" "}
414
+ * <a href="/billing">Update payment method</a>
415
+ * </Alert.Title>
416
+ * <Alert.Description>
417
+ * Update your payment method to avoid a service interruption.
418
+ * </Alert.Description>
419
+ * </Alert.Content>
420
+ * </AlertCenter.Item>
421
+ * {!dismissed.has("transfer-limit") && (
422
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
423
+ * <Alert.Icon />
424
+ * <Alert.Content>
425
+ * <Alert.Title>
426
+ * You've used 92% of your monthly transfer.{" "}
427
+ * <a href="/billing/choose-a-plan">Upgrade</a>
428
+ * </Alert.Title>
429
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
430
+ * </Alert.Content>
431
+ * </AlertCenter.Item>
432
+ * )}
433
+ * </AlertCenter.Root>
434
+ * </AppLayout.Notice>
435
+ * <AppLayout.Workspace>…</AppLayout.Workspace>
436
+ * </AppLayout.Root>
437
+ * ```
438
+ */
439
+ declare const AlertCenter: {
440
+ /**
441
+ * The renderless state owner: creates the registration store, owns the
442
+ * expansion's open state, and mounts the persistent live-region announcer.
443
+ *
444
+ * **Data attributes:**
445
+ *
446
+ * | Data Attribute | Value | Description |
447
+ * | --- | --- | --- |
448
+ * | `data-slot` | `alert-center-announcer` | On the persistent visually-hidden `role="status"` live region Root mounts. |
449
+ *
450
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterroot
451
+ *
452
+ * @example
453
+ * ```tsx
454
+ * <AlertCenter.Root>
455
+ * <AlertCenter.Bar />
456
+ * <AlertCenter.Content />
457
+ * <AlertCenter.Item id="payment-failed" intent="danger">
458
+ * <Alert.Icon />
459
+ * <Alert.Content>
460
+ * <Alert.Title>
461
+ * Payment failed — we couldn't charge your card.{" "}
462
+ * <a href="/billing">Update payment method</a>
463
+ * </Alert.Title>
464
+ * <Alert.Description>
465
+ * Update your payment method to avoid a service interruption.
466
+ * </Alert.Description>
467
+ * </Alert.Content>
468
+ * </AlertCenter.Item>
469
+ * {!dismissed.has("transfer-limit") && (
470
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
471
+ * <Alert.Icon />
472
+ * <Alert.Content>
473
+ * <Alert.Title>
474
+ * You've used 92% of your monthly transfer.{" "}
475
+ * <a href="/billing/choose-a-plan">Upgrade</a>
476
+ * </Alert.Title>
477
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
478
+ * </Alert.Content>
479
+ * </AlertCenter.Item>
480
+ * )}
481
+ * </AlertCenter.Root>
482
+ * ```
483
+ */
484
+ readonly Root: typeof Root;
485
+ /**
486
+ * The always-visible strip: the highest-severity item's children inline
487
+ * (icon, title, description, CTA) plus the count-and-caret expansion control.
488
+ * Collapses to nothing when empty. Claims no ARIA landmark; arrivals are
489
+ * announced by Root's persistent live region.
490
+ *
491
+ * **Data attributes:**
492
+ *
493
+ * | Data Attribute | Value | Description |
494
+ * | --- | --- | --- |
495
+ * | `data-slot` | `alert-center-bar-wrapper` | On the presence wrapper that owns the enter/exit animation. |
496
+ * | `data-slot` | `alert-center-bar` | On the banner chrome (`Alert.Root`) the top item's children render inside. |
497
+ * | `data-slot` | `alert-center-bar-mount` | On the layout-transparent element the top item's host is adopted into. |
498
+ * | `data-state` | `"open"` \| `"closed"` | On the wrapper; drives the enter/exit transition, and stays `closed` while the exit plays. |
499
+ * | `data-placement` | `"bar"` | On the chrome — where the top item's children are currently rendering. |
500
+ * | `data-alert-id` | the top item's `id` | On the chrome; per-alert styling and testing hook. |
501
+ * | `data-alert-dismiss` | present on the dismiss control | Read, not stamped — `Alert` emits it; the bar's CSS centers and offsets the control with it. |
502
+ * | `data-alert-expand` | present on the expand control | Read, not stamped — `Alert` emits it; the bar's CSS centers the control with it. |
503
+ *
504
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterbar
505
+ *
506
+ * @example
507
+ * ```tsx
508
+ * <AlertCenter.Root>
509
+ * <AlertCenter.Bar />
510
+ * <AlertCenter.Content />
511
+ * <AlertCenter.Item id="payment-failed" intent="danger">
512
+ * <Alert.Icon />
513
+ * <Alert.Content>
514
+ * <Alert.Title>
515
+ * Payment failed — we couldn't charge your card.{" "}
516
+ * <a href="/billing">Update payment method</a>
517
+ * </Alert.Title>
518
+ * <Alert.Description>
519
+ * Update your payment method to avoid a service interruption.
520
+ * </Alert.Description>
521
+ * </Alert.Content>
522
+ * </AlertCenter.Item>
523
+ * {!dismissed.has("transfer-limit") && (
524
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
525
+ * <Alert.Icon />
526
+ * <Alert.Content>
527
+ * <Alert.Title>
528
+ * You've used 92% of your monthly transfer.{" "}
529
+ * <a href="/billing/choose-a-plan">Upgrade</a>
530
+ * </Alert.Title>
531
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
532
+ * </Alert.Content>
533
+ * </AlertCenter.Item>
534
+ * )}
535
+ * </AlertCenter.Root>
536
+ * ```
537
+ */
538
+ readonly Bar: typeof Bar;
539
+ /**
540
+ * The inline expansion listing every alert hidden by the bar, ranked
541
+ * highest-severity-first as full-width banner rows of the items' authored
542
+ * children.
543
+ *
544
+ * **Data attributes:**
545
+ *
546
+ * | Data Attribute | Value | Description |
547
+ * | --- | --- | --- |
548
+ * | `data-slot` | `alert-center-content` | On the expansion wrapper that owns the collapse animation. |
549
+ * | `data-slot` | `alert-center-item` | On each row's banner chrome (`Alert.Root`). |
550
+ * | `data-state` | `"open"` \| `"closed"` | On the wrapper; drives the collapse transition. |
551
+ * | `data-placement` | `"list"` | On each row's chrome — where that item's children are currently rendering. |
552
+ * | `data-alert-id` | the row item's `id` | On each row's chrome; per-alert styling and testing hook. |
553
+ * | `data-alert-mount` | the row item's `id` | On the row's layout-transparent mount point — the element that item's host is adopted into. |
554
+ *
555
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcentercontent
556
+ *
557
+ * @example
558
+ * ```tsx
559
+ * <AlertCenter.Root>
560
+ * <AlertCenter.Bar />
561
+ * <AlertCenter.Content />
562
+ * <AlertCenter.Item id="payment-failed" intent="danger">
563
+ * <Alert.Icon />
564
+ * <Alert.Content>
565
+ * <Alert.Title>
566
+ * Payment failed — <a href="/billing">update your card</a>
567
+ * </Alert.Title>
568
+ * </Alert.Content>
569
+ * </AlertCenter.Item>
570
+ * {!dismissed.has("transfer-limit") && (
571
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
572
+ * <Alert.Icon />
573
+ * <Alert.Content>
574
+ * <Alert.Title>Approaching your data transfer limit</Alert.Title>
575
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
576
+ * </Alert.Content>
577
+ * </AlertCenter.Item>
578
+ * )}
579
+ * </AlertCenter.Root>
580
+ * ```
581
+ */
582
+ readonly Content: typeof Content;
583
+ /**
584
+ * One authored alert: registers its `{id, intent}` facts and renders its
585
+ * children through a portal into a stable per-id host that the bar or an
586
+ * expansion row adopts by rank — children stay in the author's React tree
587
+ * and keep their state across re-ranks. Mount to show; unmount to dismiss.
588
+ *
589
+ * **Data attributes:**
590
+ *
591
+ * | Data Attribute | Value | Description |
592
+ * | --- | --- | --- |
593
+ * | `data-slot` | `alert-center-item-host` | On the stable per-id host element the item's children portal into. |
594
+ * | `data-alert-host` | the item's `id` | On that same host — which alert's projected children it holds. |
595
+ *
596
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenteritem
597
+ *
598
+ * @example
599
+ * ```tsx
600
+ * <AlertCenter.Root>
601
+ * <AlertCenter.Bar />
602
+ * <AlertCenter.Content />
603
+ * <AlertCenter.Item id="payment-failed" intent="danger">
604
+ * <Alert.Icon />
605
+ * <Alert.Content>
606
+ * <Alert.Title>
607
+ * Payment failed — <a href="/billing">update your card</a>
608
+ * </Alert.Title>
609
+ * </Alert.Content>
610
+ * </AlertCenter.Item>
611
+ * </AlertCenter.Root>
612
+ * ```
613
+ */
614
+ readonly Item: typeof Item;
615
+ /**
616
+ * The per-item dismiss affordance: `Alert.DismissIconButton` wired to the
617
+ * enclosing banner's rendered title and the bar's control centering. Its
618
+ * presence in an item's children is what makes that alert dismissable.
619
+ *
620
+ * **Data attributes:**
621
+ *
622
+ * | Data Attribute | Value | Description |
623
+ * | --- | --- | --- |
624
+ * | `data-slot` | `alert-center-dismiss-icon-button` | Replaces `Alert.DismissIconButton`'s own `alert-dismiss-icon-button` on the rendered button. |
625
+ * | `data-alert-dismiss` | present | Read, not stamped — `Alert` emits it, and `AlertCenter`'s bar CSS positions the control with it. |
626
+ *
627
+ * @see https://mantle.ngrok.com/components/feedback/alert-center#alertcenterdismissiconbutton
628
+ *
629
+ * @example
630
+ * ```tsx
631
+ * <AlertCenter.Root>
632
+ * <AlertCenter.Bar />
633
+ * <AlertCenter.Content />
634
+ * <AlertCenter.Item id="transfer-limit" intent="warning">
635
+ * <Alert.Icon />
636
+ * <Alert.Content>
637
+ * <Alert.Title>Approaching your data transfer limit</Alert.Title>
638
+ * <AlertCenter.DismissIconButton onClick={() => dismiss("transfer-limit")} />
639
+ * </Alert.Content>
640
+ * </AlertCenter.Item>
641
+ * </AlertCenter.Root>
642
+ * ```
643
+ */
644
+ readonly DismissIconButton: typeof DismissIconButton;
645
+ };
646
+ //#endregion
647
+ export { AlertCenter, type AlertCenterIntent, type AlertCenterItemProps, type AlertCenterRootProps };
@@ -0,0 +1 @@
1
+ import{t as e}from"./use-isomorphic-layout-effect-DdTRtMY-.js";import{n as t}from"./compose-refs-BdBMM9ga.js";import{t as n}from"./cx-IiQEAKf5.js";import{t as r}from"./data-slot-EM6s2WEU.js";import{n as i,t as a}from"./alert-vwFd7qdp.js";import{createContext as o,useCallback as s,useContext as c,useEffect as l,useId as u,useMemo as d,useReducer as f,useRef as p,useState as m,useSyncExternalStore as h}from"react";import g from"tiny-invariant";import{jsx as _,jsxs as v}from"react/jsx-runtime";import{createPortal as y}from"react-dom";const b={danger:5,warning:4,important:3,info:2,success:1};function x(e,t){if(t.parentElement===e)return!1;if(typeof e.moveBefore==`function`&&t.isConnected&&e.isConnected)try{return e.moveBefore(t,null),!0}catch{}return e.appendChild(t),!0}function S(e){return e.replace(/\s+/g,` `).trim()}function C(e){let t=e.querySelector(`[data-slot="alert-title"]`);if(t==null)return``;let n=t.cloneNode(!0);if(!(n instanceof Element))return S(t.textContent??``);for(let e of n.querySelectorAll(`button`))e.remove();let r=S(n.textContent??``);for(let e of n.querySelectorAll(`a`))e.remove();let i=S(n.textContent??``);return i===``?r:i}function w(e){return e.toSorted((e,t)=>b[t.intent]-b[e.intent]||e.sequence-t.sequence)}function T(e,t){if(t===0)return``;if(e===``)return`${t} alert${t===1?``:`s`}`;let n=t-1;return n===0?e:`${e}, and ${n} more alert${n===1?``:`s`}`}const E=[];var D=class{#e=new Set;#t=new Map;#n=new Map;#r=new Map;#i=0;#a=E;#o=``;#s=!1;getHost(e){let t=this.#r.get(e);if(t!=null)return t;let n=document.createElement(`div`);return n.style.display=`contents`,n.setAttribute(`data-slot`,`alert-center-item-host`),n.setAttribute(`data-alert-host`,e),this.#r.set(e,n),n}#c=null;captureHostSnapshot(e){if(e!==this.#a[0]?.id)return;let t=this.#r.get(e);t!=null&&t.hasChildNodes()&&(this.#c={id:e,content:t.cloneNode(!0)})}getHostSnapshot=e=>this.#c?.id===e?this.#c.content:null;subscribe=e=>(this.#e.add(e),()=>{this.#e.delete(e)});getSnapshot=()=>this.#a;hasAlert=e=>this.#t.has(e);getTopLabel=()=>this.#o;setTopLabel(e){this.#o!==e&&(this.#o=e,this.#p())}#l=null;requestFocusRestore(e){this.#l=e}flushFocusRestore(){let e=this.#l;e==null||!e.isConnected||(this.#l=null,document.activeElement!==e&&e.focus({preventScroll:!0}))}#u=null;#d=0;getPlacementVersion=()=>this.#d;notifyPlacementChange(){this.#d++,this.#p()}setBarElement(e){this.#u=e}getBarElement=()=>this.#u;getContentMounted=()=>this.#s;setContentMounted(e){this.#s!==e&&(this.#s=e,this.#p())}register(e){g(!this.#t.has(e.id),`AlertCenter.Item id "${e.id}" is already registered by another mounted item — ids must be unique under one <AlertCenter.Root>. Render one item per id, or give each alert its own id.`);let t=this.#n.get(e.id)??this.#i++;this.#n.set(e.id,t);let n={...e,sequence:t};return this.#t.set(e.id,n),this.#f(),()=>{this.#t.get(e.id)===n&&(this.#t.delete(e.id),this.#f())}}#f(){this.#a=w([...this.#t.values()]),this.#p()}#p(){for(let e of this.#e)e()}};const O=o(null),k=o(null);function A(e){let t=c(O);return g(t,`${e} must be rendered inside <AlertCenter.Root>.`),t}function j(e){let t=c(k);return g(t,`${e} must be rendered inside <AlertCenter.Root>.`),t}const M=e=>h(e.subscribe,e.getSnapshot,e.getSnapshot),N=o(!1);function P({store:e}){let t=M(e);return _(`div`,{"data-slot":`alert-center-announcer`,className:`sr-only`,role:`status`,"aria-live":`polite`,children:T(h(e.subscribe,e.getTopLabel,e.getTopLabel),t.length)})}const F=({children:e,defaultOpen:t,onOpenChange:n,open:r})=>{let[i]=m(()=>new D),a=u(),[o,c]=m(t??!1),l=r??o,f=s(e=>{r??c(e),n?.(e)},[r,n]),p=d(()=>({store:i,contentId:a}),[i,a]),h=d(()=>({isExpanded:l,setExpanded:f}),[l,f]);return v(O.Provider,{value:p,children:[_(k.Provider,{value:h,children:e}),_(P,{store:i})]})},I=({children:t,className:n,id:r,intent:a})=>{let{store:o}=A(`AlertCenter.Item`);g(!c(N),`AlertCenter.Item cannot be rendered inside another item's children.`);let[s,l]=m(null);return e(()=>{l(o.getHost(r))},[o,r]),e(()=>o.register({id:r,intent:a,className:n}),[o,r,a,n]),e(()=>{o.captureHostSnapshot(r)}),s==null?null:y(_(i,{intent:a,children:_(N.Provider,{value:!0,children:t})}),s)},L=({"data-slot":n,label:i,ref:o,...s})=>{g(c(N),`AlertCenter.DismissIconButton must be composed inside an <AlertCenter.Item>'s children.`);let{store:l}=A(`AlertCenter.DismissIconButton`);h(l.subscribe,l.getPlacementVersion,l.getPlacementVersion);let u=p(null),d=t(u,o),[f,v]=m(null);return e(()=>{if(i!=null)return;let e=u.current?.closest(`[data-alert-id]`),t=e==null?``:C(e);v(t===``?null:`Dismiss ${t}`)}),_(a.DismissIconButton,{ref:d,label:i??f??void 0,...s,"data-slot":r(n,`alert-center-dismiss-icon-button`)})};function R(e,t){switch(t){case`show`:return`open`;case`hide`:return e===`closed`?`closed`:`closing`;case`exited`:return e===`closing`?`closed`:e}}function z({present:t}){let[n,r]=f(R,t?`open`:`closed`);e(()=>{r(t?`show`:`hide`)},[t]),l(()=>{if(n!==`closing`)return;let e=window.setTimeout(()=>r(`exited`),200);return()=>window.clearTimeout(e)},[n]);let i=s(e=>{e.target===e.currentTarget&&e.propertyName===`height`&&r(`exited`)},[]);return{isMounted:n!==`closed`,dataState:n===`open`?`open`:`closed`,onExitTransitionEnd:i}}function B({containerRef:t,isAttached:n}){let r=p(null);return e(()=>{let e=t.current;if(!n||e==null)return;let i=e=>{e.target instanceof Element&&(r.current=e.target)},a=t=>{t.relatedTarget instanceof Node&&!e.contains(t.relatedTarget)&&(r.current=null)};return e.addEventListener(`focusin`,i),e.addEventListener(`focusout`,a),()=>{e.removeEventListener(`focusin`,i),e.removeEventListener(`focusout`,a)}},[t,n]),{lastFocusedWithinRef:r}}function V(){let e=document.querySelector(`main, [role="main"]`);e!=null&&(e.hasAttribute(`tabindex`)||(e.tabIndex=-1),e.focus({preventScroll:!0}))}function H({isMounted:t,store:n,topId:r}){let i=p(null),{lastFocusedWithinRef:a}=B({containerRef:i,isAttached:t}),o=p(r);return e(()=>{let e=o.current;if(o.current=r,e==null||r===e)return;let t=a.current;if(n.hasAlert(e)){t instanceof HTMLElement&&document.activeElement!==t&&n.requestFocusRestore(t);return}if(t==null||t.isConnected)return;a.current=null;let s=i.current;if(r==null){V();return}s!=null&&(s.querySelector(`[data-alert-dismiss], [data-alert-expand]`)??s).focus()},[n,r]),{wrapperRef:i}}const U=`gap-2 py-2 pr-2 [&_[data-slot=alert-icon]]:shrink-0`,W={Root:F,Bar:({className:t,"data-slot":i,ref:o,...s})=>{let{store:c,contentId:l}=A(`AlertCenter.Bar`),{isExpanded:u,setExpanded:d}=j(`AlertCenter.Bar`),f=M(c),m=h(c.subscribe,c.getContentMounted,c.getContentMounted),g=f[0]??null,y=g!=null,{isMounted:b,dataState:S,onExitTransitionEnd:w}=z({present:y}),T=p(g);e(()=>{g!=null&&(T.current=g)},[g]);let E=g??T.current,D=p(null);e(()=>{let e=D.current;if(e==null)return;if(g!=null){let t=c.getHost(g.id);t.parentElement!==e&&e.childNodes.length>0&&e.replaceChildren(),x(e,t)&&c.notifyPlacementChange(),c.flushFocusRestore();return}let t=E==null?null:c.getHostSnapshot(E.id);t!=null&&t.parentNode!==e&&e.replaceChildren(t)});let{wrapperRef:O}=H({isMounted:b,store:c,topId:g?.id});if(e(()=>{let e=O.current;c.setTopLabel(y&&e!=null?C(e):``)}),e(()=>{let e=O.current;if(e==null)return;let t=new MutationObserver(()=>{c.setTopLabel(y?C(e):``)});return t.observe(e,{subtree:!0,childList:!0,characterData:!0}),()=>{t.disconnect()}},[c,y,b]),e(()=>()=>{c.setTopLabel(``)},[c]),e(()=>{c.setBarElement(O.current)}),e(()=>()=>{c.setBarElement(null)},[c]),!b||E==null)return null;let k=y?f.length-1:0;return _(`div`,{ref:O,"data-slot":`alert-center-bar-wrapper`,tabIndex:-1,inert:!y,className:`shrink-0 overflow-hidden transition-[height,opacity] duration-200 ease-out [interpolate-size:allow-keywords] starting:h-0 starting:opacity-0 data-state-closed:h-0 data-state-closed:opacity-0 data-state-closed:duration-150 motion-reduce:transition-none`,"data-state":S,onTransitionEnd:w,children:v(a.Root,{ref:o,appearance:`banner`,intent:E.intent,className:n(U,`not-has-data-[slot=alert-description]:[&_[data-alert-dismiss],&_[data-alert-expand]]:top-1/2 not-has-data-[slot=alert-description]:[&_[data-alert-dismiss],&_[data-alert-expand]]:-translate-y-1/2`,`has-data-alert-expand:[&_[data-alert-dismiss]]:right-16 md:has-data-alert-expand:[&_[data-alert-dismiss]]:right-24`,t,E.className),...s,"data-slot":r(i,`alert-center-bar`),"data-placement":`bar`,"data-alert-id":E.id,children:[_(`div`,{ref:D,className:`contents`,"data-slot":`alert-center-bar-mount`}),k>0&&m&&_(a.ExpandButton,{count:k,expanded:u,"aria-controls":l,onClick:()=>d(!u)})]})})},Content:({"aria-label":i=`More alerts`,"aria-labelledby":o,className:s,"data-slot":c,ref:l,...u})=>{let{store:d,contentId:f}=A(`AlertCenter.Content`),{isExpanded:m,setExpanded:h}=j(`AlertCenter.Content`),g=M(d).slice(1),v=g.length>0;e(()=>(d.setContentMounted(!0),()=>{d.setContentMounted(!1)}),[d]);let y=p(v);e(()=>{let e=y.current&&!v;y.current=v,e&&m&&h(!1)},[v,m,h]);let b=p(null),S=t(b,l),{lastFocusedWithinRef:C}=B({containerRef:b,isAttached:v}),w=g.map(e=>e.id).join(` `);return e(()=>{let e=b.current;if(e==null)return;let t=!1;for(let n of e.querySelectorAll(`[data-alert-mount]`)){let e=n.getAttribute(`data-alert-mount`);e!=null&&x(n,d.getHost(e))&&(t=!0)}t&&d.notifyPlacementChange(),d.flushFocusRestore()},[d,w]),e(()=>{let e=C.current;if(e==null)return;if(e.isConnected){let t=b.current;e instanceof HTMLElement&&document.activeElement!==e&&(t==null||!t.contains(e))&&(C.current=null,e.focus({preventScroll:!0}));return}C.current=null;let t=b.current?.querySelector(`[data-alert-dismiss]`);if(t!=null){t.focus();return}let n=d.getBarElement()?.querySelector(`[data-alert-dismiss], [data-alert-expand]`);if(n!=null){n.focus();return}V()},[d,w]),g.length===0?null:_(`div`,{...u,ref:S,"data-slot":r(c,`alert-center-content`),id:f,"data-state":m?`open`:`closed`,className:n(`h-0 overflow-hidden invisible [content-visibility:hidden] transition-[height,visibility,content-visibility] transition-discrete duration-200 ease-out [interpolate-size:allow-keywords] data-state-open:h-auto data-state-open:visible data-state-open:[content-visibility:visible] motion-reduce:transition-none`,s),children:_(`ul`,{"aria-label":o==null?i:void 0,"aria-labelledby":o,className:`flex w-full flex-col`,children:g.map(e=>_(`li`,{children:_(a.Root,{appearance:`banner`,intent:e.intent,className:n(U,e.className),"data-slot":`alert-center-item`,"data-placement":`list`,"data-alert-id":e.id,children:_(`div`,{className:`contents`,"data-alert-mount":e.id})})},e.id))})})},Item:I,DismissIconButton:L};export{W as AlertCenter};