@stackone/malachite 2.74.0 → 2.76.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.
package/COMPONENTS.md CHANGED
@@ -8,7 +8,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
8
8
 
9
9
  - **`Chat`** — A chat column: `Chat.Thread` scrolls and pins itself to the newest message, `Chat.Composer` keeps its own height and owns the Enter/Shift+Enter convention, and `Chat.Message`, `Chat.ToolCall` and `Chat.Thinking` render one turn each. A user turn sits right and hugs its text; an assistant turn runs full width, and `variant="card"` frames it with its state, copy and rating controls, and a token/model line. `variant="bubble"` is a third treatment, not a repaint of either: tinted bubbles whose flattened corner points at whoever spoke, so authorship reads before the words do. `Chat.Context` lists what the conversation can see — a removable chip per source, and an add affordance only when a handler is given. `Chat.Thinking` and a loading turn draw bars in the shape of the answer rather than a spinner. The row under a composer is `ComposerChip`, `ContextMeter` and `ModelPicker` — PillButton tabs, so it reads as attached to the field; `ModelPicker` opens a portalled menu with a submenu per model. The transcript is a live `log` region, so a streamed reply is announced, and it shows a centred empty state until the first turn. _Key props:_ `Chat`: `children`, `className`. `Thread`: `aria-label`, `emptyTitle`, `emptyDescription`, `emptyIcon`. `Message`: `role`, `variant` (`plain` | `card`), `content`, `children`, `name`, `avatarSrc`, `status` (`streaming` | `completed` | `error`), `loading`, `onCopy`, `onFeedback`, `usage`. `ToolCall`: `name`, `status` (`running` | `completed` | `error`), `callId`, `input`, `output`, `defaultExpanded`. `Thinking`: `label`. `Composer`: `value`, `onChange`, `onSend`, `onStop`, `busy`, `disabled`, `placeholder`, `maxLength`, `rows`, `children`. `ComposerChip`: `label`, `icon`, `trailingIcon`, `onClick`, `disabled`. `ContextMeter`: `used`, `limit`, `cached`, `label`. `ModelPicker`: `models`, `value`, `optionValue`, `onChange`, `openUp`, `disabled`. `Context`: `label`, `items` (`{id, label, onRemove?}`), `onAdd`, `className`.
10
10
  - **`Surface`** — Rounded, bordered card container with the standard elevation shadow. Use `overflow="clip"` to keep the rounded clipping while letting a `position: sticky` descendant still pin (`hidden` would trap it); `visible` disables clipping. _Key props:_ `children`, `padding`, `overflow`, `className`, `style`.
11
- - **`SurfaceRow`** — A full-bleed row inside a Surface (used as `Surface.Row`). Owns hover highlight, colour transition and an optional bottom divider. Pass `onClick`/`href` to make the whole row clickable (renders as a real button/anchor, so keyboard nav works). For a selectable row use `role="radio"` + `selected` and put a presentational `<Radio>` inside as the indicator; `selected` then paints the same treatment `Table` gives `selectedRowKey`. Under `role="checkbox"` it only announces — a multi-select row carries its own checkbox, and a highlight marking one of many says nothing when most rows are checked. `selection` overrides that either way (`highlight` / `announce`). `selected="mixed"` marks a partly selected checkbox row (`aria-checked="mixed"`); it never paints or marks a row current, and counts as not selected under any other role. Use `trailing` for a control that must stay interactive — it renders outside the row button, which a nested control could not be. `revealTrailing` shows that control only on hover, keyboard focus or while a menu it opened is open, keeping it in the tab order and always showing it on a touch screen. `tone="muted"` tints a row whose subject is inactive, which `disabled` does not: a muted row stays clickable. _Key props:_ `divider`, `disabled`, `tone` (`default` | `muted`), `inset` (`none` | `compact` — the row owns an 8px by 16px inset, wrapping `trailing` too, so its content needs no padding wrapper), `onClick`, `href`, `target`, `rel`, `selected` (`boolean` | `"mixed"`), `selection` (`highlight` | `announce`), `trailing`, `revealTrailing`, `role`, `className`, `style`.
11
+ - **`SurfaceRow`** — A full-bleed row inside a Surface (used as `Surface.Row`). Owns hover highlight, colour transition and an optional bottom divider. Pass `onClick`/`href` to make the whole row clickable (renders as a real button/anchor, so keyboard nav works). For a selectable row use `role="radio"` + `selected` and put a presentational `<Radio>` inside as the indicator; `selected` then paints the same treatment `Table` gives `selectedRowKey`. Under `role="checkbox"` it only announces — a multi-select row carries its own checkbox, and a highlight marking one of many says nothing when most rows are checked. `selection` overrides that either way (`highlight` / `announce`). `selected="mixed"` marks a partly selected checkbox row (`aria-checked="mixed"`); it never paints or marks a row current, and counts as not selected under any other role. Use `trailing` for a control that must stay interactive — it renders outside the row button, which a nested control could not be. `revealTrailing` shows that control only on hover, keyboard focus or while a menu it opened is open, keeping it in the tab order and always showing it on a touch screen. `tone="muted"` tints a row whose subject is inactive, which `disabled` does not: a muted row stays clickable. _Key props:_ `divider`, `disabled`, `tone` (`default` | `muted`), `inset` (`none` | `compact` — the row owns an 8px by 16px inset, wrapping `trailing` too, so its content needs no padding wrapper), `onClick`, `href`, `target`, `rel`, `selected` (`boolean` | `"mixed"`), `selection` (`highlight` | `tint` | `announce`; `tint` paints the selected treatment without the accent bar, for a menu whose choice is already marked inside the row), `trailing`, `revealTrailing`, `role`, `className`, `style`.
12
12
  - **`SurfaceExpandableRow`** — A row that opens to reveal a body (used as `Surface.ExpandableRow`), for a line that carries its own controls. Not `Accordion`, which puts its header inside the toggle button, so a header holding a dropdown or a second button would be invalid: here the row surface takes the click and a cell opts out by wrapping its controls in `ExpandableRow.Controls`, while the arrow stays a real button so the keyboard reaches it. That opt-out is explicit rather than sniffing the event target for an interactive ancestor, because a control rendering into a shadow root retargets the event to its host. `sticky` pins the row while its body scrolls, offset by `stickyTopOffset` for whatever is already pinned above it; it only pins while open, since a closed row has nothing to scroll past. _Key props:_ `header`, `children`, `expanded`, `onToggle`, `sticky`, `stickyTopOffset`, `divider`, `tone`, `aria-label`, `className`, `style`.
13
13
  - **`DisclosureArrow`** — The expand/collapse triangle disclosure UI shares (`Accordion`, `Surface.ExpandableRow`). Owns its colour states so they never drift between usages: `text-primary` when expanded, `text-placeholder` otherwise, and dark on hover inside a `group` ancestor — put `group` on the clickable header or row so that hover state activates. _Key props:_ `expanded`, `size`, `className`.
14
14
  - **`Card`** — Generic content card.
@@ -34,7 +34,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
34
34
  ## Feedback & status
35
35
 
36
36
  - **`ChangeReview`** — Reviewing changes a machine made. `ChangeReview.Item` attaches to one changed thing: it names what changed with an `assistant` Tag, shows the value it displaced struck through, and offers approve and deny as two equally reachable icon buttons — a review affordance that made keeping easier than rejecting would not be one. Given `children`, it wraps the field the change is annotating: the tag/label/actions become a header band above it and the before/after line moves below, so "Was …" reads next to the value it describes instead of stacked with the header; without children it renders as the standalone card it always has. `ChangeReview.Summary` counts what is still undecided across the whole form, which is what a per-item control cannot do and what a caller gates a save on; at zero it either says so or collapses to nothing. `ChangeReview.Removed` is for something the assistant took out: a dashed, tinted card listing what would be lost, because a removal that simply vanished would leave nothing to reject. `ChangeReview.Jump` is a chip an assistant turn carries to point at a field it touched. _Key props:_ `Item`: `label`, `before`, `after`, `kind` (`changed` | `added` | `removed`), `origin`, `children`, `onApprove`, `onDeny`, `disabled`, `className`. `Summary`: `count`, `origin`, `onApproveAll`, `onDenyAll`, `disabled`, `settledMessage`, `className`. `Removed`: `title`, `details` (`{label, value}[]`), `onRestore`, `onDiscard`, `restoreLabel`, `discardLabel`, `origin`, `disabled`, `className`. `Jump`: `label`, `onClick`, `disabled`, `className`. `Item` also takes `onPreviewRevert(previewing)`, fired on hover and on focus.
37
- - **`Alert`** — Inline alert/callout. Four severities (info, success, warning, error) plus `assistant` — a violet, sparkle-marked ground that says a machine wrote the message rather than that anything is wrong, so provenance never has to borrow a severity colour. `action` puts a control at the end — the link or button that resolves what the alert reports — and `icon` replaces the status icon; an svg that paints with `currentColor` (a CustomIcon) is drawn in the colour and size of the built-in one. _Key props:_ `type`, `message`, `lead` (a bold sentence the message runs on from; plain text), `layout` (`inline` | `banner` — a 48px page-wide band with a 16px icon, for `WizardLayout`'s `banner` slot; an expandable alert stays inline), `align` (`start` | `center`, the banner icon and text gathered mid-band), `action`, `icon`, `hasMargin`, `live` (makes the message a live region — `role="alert"` for error/warning, announced as it mounts; `status` otherwise, announced when its `message` changes, so keep it mounted; off by default), `renderLink` (routes root-relative links in `message` through the app’s router, as `MarkdownBlock` does), `children` (expandable body), `isExpanded`, `onToggle`, `className`.
37
+ - **`Alert`** — Inline alert/callout. Four severities (info, success, warning, error) plus `assistant` — a violet, sparkle-marked ground that says a machine wrote the message rather than that anything is wrong, so provenance never has to borrow a severity colour. `action` puts a control at the end — the link or button that resolves what the alert reports — and `icon` replaces the status icon; an svg that paints with `currentColor` (a CustomIcon) is drawn in the colour and size of the built-in one. _Key props:_ `type`, `message`, `lead` (a bold sentence the message runs on from; plain text), `address` (`{ text, emphasis? }`: an address the message runs on into, whole and in mono; `emphasis`, an optional substring to bold wherever it occurs, often the registrable domain) and `addressSuffix` (markdown after the address, joined without a space when it opens with any punctuation character), `layout` (`inline` | `banner` — a 48px page-wide band with a 16px icon, for `WizardLayout`'s `banner` slot; an expandable alert stays inline), `align` (`start` | `center`, the banner icon and text gathered mid-band), `action`, `icon`, `hasMargin`, `live` (makes the message a live region — `role="alert"` for error/warning, announced as it mounts; `status` otherwise, announced when its `message` changes, so keep it mounted; off by default), `renderLink` (routes root-relative links in `message` through the app’s router, as `MarkdownBlock` does), `children` (expandable body), `isExpanded`, `onToggle`, `className`.
38
38
  - **`IconIndicator`** — A non-interactive icon that carries a meaning, such as a capability shown on a page that cannot switch it on. Same square as an icon-only `Button` at each `size`, so it lines up where a sibling view shows the button. Renders `role="img"`, named by `aria-label`; with a `tooltip` it takes focus so the tooltip is reachable by keyboard. Reach for it instead of a hand-sized `<span>` around an icon. _Key props:_ `icon`, `aria-label`, `tooltip`, `size`.
39
39
  - **`IconBadge`** — A small filled tile carrying a 12px glyph, for a dialog or panel header such as `SidePanel`’s `icon`. Decorative and always `aria-hidden`: the title beside it carries the meaning, so reach for `IconIndicator` when the icon itself has to say something. `variant` picks a semantic fill (`default` neutral, `accent` the interaction colour, `warning`, `destructive`, `success`) rather than taking a colour, and the glyph is drawn in the card background. `ConfirmationDialog` draws its badge with it. _Key props:_ `icon`, `variant` (`default` | `accent` | `warning` | `destructive` | `success`), `className`.
40
40
  - **`StatusBadge`** — Large status indicator (e.g. success checkmark) for terminal/confirmation screens. _Key props:_ `type`.
@@ -1,16 +1,16 @@
1
- import { jsxs as s, jsx as e, Fragment as y } from "react/jsx-runtime";
2
- import { useState as W } from "react";
3
- import { Button as H } from "./Button.js";
4
- import M from "./CustomIcons/CaretDownIcon.js";
5
- import T from "./CustomIcons/CaretUpIcon.js";
6
- import Y from "./CustomIcons/CheckCircleFilled.js";
7
- import $ from "./CustomIcons/ErrorCircleFilled.js";
8
- import D from "./CustomIcons/InfoCircleFilled.js";
9
- import L from "./CustomIcons/SparkleIcon.js";
10
- import U from "./CustomIcons/WarningCircleFilled.js";
11
- import q from "./Typography/MarkdownBlock.js";
12
- import { getTextColor as j, getFontSize as G } from "./Typography/textStyles.js";
13
- const p = (r) => {
1
+ import { jsxs as i, jsx as e, Fragment as u } from "react/jsx-runtime";
2
+ import M, { useState as P } from "react";
3
+ import { Button as U } from "./Button.js";
4
+ import Y from "./CustomIcons/CaretDownIcon.js";
5
+ import $ from "./CustomIcons/CaretUpIcon.js";
6
+ import D from "./CustomIcons/CheckCircleFilled.js";
7
+ import L from "./CustomIcons/ErrorCircleFilled.js";
8
+ import q from "./CustomIcons/InfoCircleFilled.js";
9
+ import G from "./CustomIcons/SparkleIcon.js";
10
+ import J from "./CustomIcons/WarningCircleFilled.js";
11
+ import E from "./Typography/MarkdownBlock.js";
12
+ import { getTextColor as z, getFontSize as K } from "./Typography/textStyles.js";
13
+ const g = (r) => {
14
14
  switch (r) {
15
15
  case "info":
16
16
  return "primary";
@@ -27,147 +27,186 @@ const p = (r) => {
27
27
  default:
28
28
  return "primary";
29
29
  }
30
- }, a = {
30
+ }, m = {
31
31
  width: "13px",
32
32
  height: "13px",
33
33
  flexShrink: 0
34
- }, o = {
34
+ }, h = {
35
35
  info: "var(--malachite-alert-info-foreground)",
36
36
  success: "var(--malachite-alert-success-foreground)",
37
37
  error: "var(--malachite-alert-error-foreground)",
38
38
  warning: "var(--malachite-alert-warning-foreground)",
39
39
  assistant: "var(--malachite-alert-assistant-foreground)"
40
- }, _ = {
41
- info: /* @__PURE__ */ e(D, { style: { ...a, color: o.info } }),
42
- success: /* @__PURE__ */ e(Y, { style: { ...a, color: o.success } }),
43
- error: /* @__PURE__ */ e($, { style: { ...a, color: o.error } }),
44
- warning: /* @__PURE__ */ e(U, { style: { ...a, color: o.warning } }),
40
+ }, F = {
41
+ info: /* @__PURE__ */ e(q, { style: { ...m, color: h.info } }),
42
+ success: /* @__PURE__ */ e(D, { style: { ...m, color: h.success } }),
43
+ error: /* @__PURE__ */ e(L, { style: { ...m, color: h.error } }),
44
+ warning: /* @__PURE__ */ e(J, { style: { ...m, color: h.warning } }),
45
45
  // The same sparkle the control that produced the message carries, so the two read as
46
46
  // one thread rather than two unrelated affordances.
47
- assistant: /* @__PURE__ */ e(L, { style: { ...a, color: o.assistant } })
48
- }, J = { ...a, width: "16px", height: "16px" }, S = (r, t, l = !1) => !t && !l ? _[r] : /* @__PURE__ */ e(
47
+ assistant: /* @__PURE__ */ e(G, { style: { ...m, color: h.assistant } })
48
+ }, Q = { ...m, width: "16px", height: "16px" }, S = (r, l, t = !1) => !l && !t ? F[r] : /* @__PURE__ */ e(
49
49
  "span",
50
50
  {
51
51
  className: "alert-status-icon inline-flex shrink-0 [&_svg]:size-full!",
52
- style: { ...l ? J : a, color: o[r] },
53
- children: t || _[r]
52
+ style: { ...t ? Q : m, color: h[r] },
53
+ children: l || F[r]
54
54
  }
55
- ), v = ({ text: r, type: t, lead: l, renderLink: c }) => l ? /* @__PURE__ */ s("div", { className: "alert-lead", children: [
56
- /* @__PURE__ */ e(
57
- "strong",
58
- {
59
- style: {
60
- color: j(p(t)),
61
- fontSize: G("small"),
62
- fontWeight: 600
63
- },
64
- children: l
65
- }
66
- ),
67
- " ",
68
- /* @__PURE__ */ e(v, { text: r, type: t, renderLink: c })
69
- ] }) : /* @__PURE__ */ e(
70
- q,
55
+ ), V = ({ text: r, emphasis: l }) => {
56
+ if (!l)
57
+ return [{ text: r, bold: !1, offset: 0 }];
58
+ const t = [], a = (n, s, o) => {
59
+ n && t.push({ text: n, bold: s, offset: o });
60
+ }, c = r.split(l);
61
+ return c.reduce((n, s, o) => (a(s, !1, n), o < c.length - 1 && a(l, !0, n + s.length), n + s.length + l.length), 0), t;
62
+ }, X = ({ address: r, color: l }) => /* @__PURE__ */ e(
63
+ "code",
71
64
  {
72
- text: r,
73
- color: p(t),
74
- size: "small",
75
- omitMargin: !0,
76
- renderLink: c
65
+ className: "alert-address",
66
+ style: {
67
+ fontFamily: "var(--malachite-font-mono, monospace)",
68
+ fontSize: "0.9em",
69
+ color: l,
70
+ overflowWrap: "anywhere"
71
+ },
72
+ children: V(r).map(
73
+ (t) => t.bold ? /* @__PURE__ */ e("strong", { style: { fontWeight: 600 }, children: t.text }, t.offset) : /* @__PURE__ */ e(M.Fragment, { children: t.text }, t.offset)
74
+ )
77
75
  }
78
- ), ie = ({
76
+ ), Z = new RegExp("^\\p{P}", "u"), j = ({ text: r, type: l, lead: t, address: a, addressSuffix: c, renderLink: n }) => {
77
+ const s = z(g(l)), o = /* @__PURE__ */ e(
78
+ E,
79
+ {
80
+ text: r,
81
+ color: g(l),
82
+ size: "small",
83
+ omitMargin: !0,
84
+ renderLink: n
85
+ }
86
+ );
87
+ return !t && !a ? o : /* @__PURE__ */ i("div", { className: "alert-lead", children: [
88
+ t ? /* @__PURE__ */ i(u, { children: [
89
+ /* @__PURE__ */ e("strong", { style: { color: s, fontSize: K("small"), fontWeight: 600 }, children: t }),
90
+ " "
91
+ ] }) : null,
92
+ o,
93
+ a ? /* @__PURE__ */ i(u, { children: [
94
+ " ",
95
+ /* @__PURE__ */ e(X, { address: a, color: s })
96
+ ] }) : null,
97
+ a && c ? /* @__PURE__ */ i(u, { children: [
98
+ Z.test(c) ? "" : " ",
99
+ /* @__PURE__ */ e(
100
+ E,
101
+ {
102
+ text: c,
103
+ color: g(l),
104
+ size: "small",
105
+ omitMargin: !0,
106
+ renderLink: n
107
+ }
108
+ )
109
+ ] }) : null
110
+ ] });
111
+ }, he = ({
79
112
  type: r = "info",
80
- message: t,
81
- hasMargin: l = !0,
82
- className: c,
83
- children: g,
84
- isExpanded: x,
85
- onToggle: h,
86
- action: m,
87
- icon: w,
88
- live: E = !1,
89
- renderLink: N,
90
- layout: k = "inline",
113
+ message: l,
114
+ hasMargin: t = !0,
115
+ className: a,
116
+ children: c,
117
+ isExpanded: n,
118
+ onToggle: s,
119
+ action: o,
120
+ icon: N,
121
+ live: O = !1,
122
+ renderLink: w,
123
+ layout: W = "inline",
91
124
  lead: C,
92
- align: B = "start"
125
+ address: b,
126
+ addressSuffix: y,
127
+ align: k = "start"
93
128
  }) => {
94
- const n = !!g, f = k === "banner" && !n, u = f && B === "center", b = E ? r === "error" || r === "warning" ? "alert" : "status" : void 0, [F, z] = W(!1), i = x !== void 0 ? x : F, O = () => {
95
- const d = !i;
96
- x === void 0 && z(d), h == null || h(d);
129
+ const d = !!c, p = W === "banner" && !d, v = p && k === "center", _ = O ? r === "error" || r === "warning" ? "alert" : "status" : void 0, [A, B] = P(!1), f = n !== void 0 ? n : A, T = () => {
130
+ const x = !f;
131
+ n === void 0 && B(x), s == null || s(x);
97
132
  }, I = [
98
133
  "alert-base",
99
134
  `alert-${r}`,
100
135
  "flex",
101
136
  "w-full",
102
137
  // Ensure full width
103
- f ? "alert-banner" : n && i ? "flex-col" : "gap-2 items-center min-h-[2rem]",
104
- l ? "" : "alert-no-margin",
105
- u ? "text-center" : "text-left",
106
- f ? "" : n ? "rounded-xl !p-0" : "!px-2.5 !py-1.5",
138
+ p ? "alert-banner" : d && f ? "flex-col" : "gap-2 items-center min-h-[2rem]",
139
+ t ? "" : "alert-no-margin",
140
+ v ? "text-center" : "text-left",
141
+ p ? "" : d ? "rounded-xl !p-0" : "!px-2.5 !py-1.5",
107
142
  // Slightly more vertical padding for centering
108
- c
109
- ].filter(Boolean).join(" "), A = [
143
+ a
144
+ ].filter(Boolean).join(" "), R = [
110
145
  "flex items-center justify-between w-full",
111
- n ? "gap-2 px-2.5 py-1" : "gap-2",
112
- n && i ? "rounded-t-xl" : n ? "rounded-xl" : ""
113
- ].filter(Boolean).join(" "), R = ["w-full", "overflow-hidden"].filter(Boolean).join(" ");
114
- if (!n) {
115
- const d = /* @__PURE__ */ s(y, { children: [
116
- S(r, w, f),
117
- /* @__PURE__ */ e("div", { className: u ? "flex items-center" : "flex-1 flex items-center", children: /* @__PURE__ */ e("div", { className: "[&>div]:mb-0", role: b, children: /* @__PURE__ */ e(
118
- v,
146
+ d ? "gap-2 px-2.5 py-1" : "gap-2",
147
+ d && f ? "rounded-t-xl" : d ? "rounded-xl" : ""
148
+ ].filter(Boolean).join(" "), H = ["w-full", "overflow-hidden"].filter(Boolean).join(" ");
149
+ if (!d) {
150
+ const x = /* @__PURE__ */ i(u, { children: [
151
+ S(r, N, p),
152
+ /* @__PURE__ */ e("div", { className: v ? "flex items-center" : "flex-1 flex items-center", children: /* @__PURE__ */ e("div", { className: "[&>div]:mb-0", role: _, children: /* @__PURE__ */ e(
153
+ j,
119
154
  {
120
- text: t,
155
+ text: l,
121
156
  type: r,
122
157
  lead: C,
123
- renderLink: N
158
+ address: b,
159
+ addressSuffix: y,
160
+ renderLink: w
124
161
  }
125
162
  ) }) })
126
163
  ] });
127
- return /* @__PURE__ */ s("div", { className: I, children: [
128
- u ? (
164
+ return /* @__PURE__ */ i("div", { className: I, children: [
165
+ v ? (
129
166
  // Its own group, so an `action` stays at the end while this sits mid-band.
130
- /* @__PURE__ */ e("div", { className: "alert-centred flex-1 flex items-center justify-center gap-[10px]", children: d })
131
- ) : d,
132
- m && /* @__PURE__ */ e("div", { className: "alert-action shrink-0 flex items-center", children: m })
167
+ /* @__PURE__ */ e("div", { className: "alert-centred flex-1 flex items-center justify-center gap-[10px]", children: x })
168
+ ) : x,
169
+ o && /* @__PURE__ */ e("div", { className: "alert-action shrink-0 flex items-center", children: o })
133
170
  ] });
134
171
  }
135
- return /* @__PURE__ */ s("div", { className: `${I} alert-expandable`, children: [
136
- /* @__PURE__ */ s("div", { className: A, children: [
137
- /* @__PURE__ */ s("div", { className: "flex-1 flex gap-2 items-center", children: [
138
- S(r, w),
139
- /* @__PURE__ */ e("div", { className: "flex-1 flex items-center", children: /* @__PURE__ */ e("div", { className: "[&>div]:mb-0", role: b, children: /* @__PURE__ */ e(
140
- v,
172
+ return /* @__PURE__ */ i("div", { className: `${I} alert-expandable`, children: [
173
+ /* @__PURE__ */ i("div", { className: R, children: [
174
+ /* @__PURE__ */ i("div", { className: "flex-1 flex gap-2 items-center", children: [
175
+ S(r, N),
176
+ /* @__PURE__ */ e("div", { className: "flex-1 flex items-center", children: /* @__PURE__ */ e("div", { className: "[&>div]:mb-0", role: _, children: /* @__PURE__ */ e(
177
+ j,
141
178
  {
142
- text: t,
179
+ text: l,
143
180
  lead: C,
181
+ address: b,
182
+ addressSuffix: y,
144
183
  type: r,
145
- renderLink: N
184
+ renderLink: w
146
185
  }
147
186
  ) }) })
148
187
  ] }),
149
- /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
150
- m && /* @__PURE__ */ e("div", { className: "alert-action flex items-center", children: m }),
188
+ /* @__PURE__ */ i("div", { className: "flex items-center gap-2", children: [
189
+ o && /* @__PURE__ */ e("div", { className: "alert-action flex items-center", children: o }),
151
190
  /* @__PURE__ */ e(
152
- H,
191
+ U,
153
192
  {
154
193
  variant: "no-style",
155
194
  size: "xsmall",
156
- onClick: O,
157
- "aria-label": i ? "Collapse" : "Expand",
195
+ onClick: T,
196
+ "aria-label": f ? "Collapse" : "Expand",
158
197
  style: {
159
- color: j(p(r))
198
+ color: z(g(r))
160
199
  },
161
- children: i ? /* @__PURE__ */ e(T, { style: { minWidth: "13px", minHeight: "13px" } }) : /* @__PURE__ */ e(M, { style: { minWidth: "13px", minHeight: "13px" } })
200
+ children: f ? /* @__PURE__ */ e($, { style: { minWidth: "13px", minHeight: "13px" } }) : /* @__PURE__ */ e(Y, { style: { minWidth: "13px", minHeight: "13px" } })
162
201
  }
163
202
  )
164
203
  ] })
165
204
  ] }),
166
- i && /* @__PURE__ */ e(y, { children: /* @__PURE__ */ e("div", { className: R, children: /* @__PURE__ */ e("div", { className: "bg-white rounded-[var(--malachite-radius-10,10px)] shadow-[0px_1px_0px_0px_rgba(0,0,0,0.15)] border border-[#e8e8e8] border-solid mx-2 mb-2 max-h-[553px] overflow-y-auto", children: g }) }) })
205
+ f && /* @__PURE__ */ e(u, { children: /* @__PURE__ */ e("div", { className: H, children: /* @__PURE__ */ e("div", { className: "bg-white rounded-[var(--malachite-radius-10,10px)] shadow-[0px_1px_0px_0px_rgba(0,0,0,0.15)] border border-[#e8e8e8] border-solid mx-2 mb-2 max-h-[553px] overflow-y-auto", children: c }) }) })
167
206
  ] });
168
207
  };
169
208
  export {
170
- ie as Alert,
171
- ie as default
209
+ he as Alert,
210
+ he as default
172
211
  };
173
212
  //# sourceMappingURL=Alert.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.js","sources":["../../src/components/Alert.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Button, ButtonVariant } from './Button';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CaretUpIcon from './CustomIcons/CaretUpIcon';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport SparkleIcon from './CustomIcons/SparkleIcon';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport type { RenderLink } from './PageLayout/types';\nimport MarkdownBlock from './Typography/MarkdownBlock';\nimport type { TextColor } from './Typography/Text';\nimport { getFontSize, getTextColor } from './Typography/textStyles';\n\nexport type AlertType = 'info' | 'success' | 'error' | 'warning' | 'assistant';\n\nexport type AlertLayout = 'inline' | 'banner';\n\ninterface AlertButtonConfig {\n label: string;\n onClick: () => void;\n variant?: ButtonVariant;\n icon?: React.ReactNode;\n}\n\ninterface AlertProps {\n type?: AlertType;\n message: string;\n hasMargin?: boolean;\n className?: string;\n children?: React.ReactNode;\n isExpanded?: boolean;\n onToggle?: (expanded: boolean) => void;\n /** A control at the end of the alert — a link or button that resolves what it reports. */\n action?: React.ReactNode;\n /** Replaces the type's status icon: an svg painting with `currentColor`, such as a CustomIcon,\n * is drawn in the type's colour at the same size. */\n icon?: React.ReactNode;\n /** Makes its message a live region: `role=\"alert\"` for error and warning, `status` otherwise.\n * Screen readers reliably announce an `alert` as it mounts; a `status` is read when its\n * `message` changes, so keep a live info or success alert mounted. Off by default. */\n live?: boolean;\n /** Routes root-relative links in `message` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n /** `banner`: a 48px page-wide band. Applies only without `children`. */\n layout?: AlertLayout;\n /** `center` gathers a banner's icon and text in the middle of the band, for a wide page. */\n align?: 'start' | 'center';\n /** A bold sentence the message runs on from. Plain text, not markdown. */\n lead?: string;\n}\n\n// Distinct from the imported `getTextColor`, which maps a TextColor to a CSS variable.\n// This maps an AlertType to a TextColor token; both are used in this file.\nconst getAlertTextColor = (alertType: AlertType): TextColor => {\n switch (alertType) {\n case 'info':\n return 'primary';\n case 'success':\n return 'success';\n case 'error':\n return 'error';\n case 'warning':\n return 'warning';\n // The violet is on `.alert-assistant` itself; inheriting it keeps one definition\n // rather than a TextColor token that only this alert would ever name.\n case 'assistant':\n return 'inherit';\n default:\n return 'primary';\n }\n};\n\nconst ICON_STYLE = {\n width: '13px',\n height: '13px',\n flexShrink: 0,\n};\n\nconst ICON_COLOR: Record<AlertType, string> = {\n info: 'var(--malachite-alert-info-foreground)',\n success: 'var(--malachite-alert-success-foreground)',\n error: 'var(--malachite-alert-error-foreground)',\n warning: 'var(--malachite-alert-warning-foreground)',\n assistant: 'var(--malachite-alert-assistant-foreground)',\n};\n\nconst AlertIcon = {\n info: <InfoCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.info }} />,\n success: <CheckCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.success }} />,\n error: <ErrorCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.error }} />,\n warning: <WarningCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.warning }} />,\n // The same sparkle the control that produced the message carries, so the two read as\n // one thread rather than two unrelated affordances.\n assistant: <SparkleIcon style={{ ...ICON_STYLE, color: ICON_COLOR.assistant }} />,\n};\n\nconst BANNER_ICON_STYLE = { ...ICON_STYLE, width: '16px', height: '16px' };\n\nconst statusIcon = (type: AlertType, icon: React.ReactNode, banner = false) => {\n if (!icon && !banner) return AlertIcon[type];\n const style = banner ? BANNER_ICON_STYLE : ICON_STYLE;\n return (\n <span\n className=\"alert-status-icon inline-flex shrink-0 [&_svg]:size-full!\"\n style={{ ...style, color: ICON_COLOR[type] }}\n >\n {icon || AlertIcon[type]}\n </span>\n );\n};\n\nconst SimpleTextRenderer: React.FC<{\n text: string;\n type: AlertType;\n lead?: string;\n renderLink?: RenderLink;\n}> = ({ text, type, lead, renderLink }) => {\n if (lead) {\n return (\n <div className=\"alert-lead\">\n <strong\n style={{\n color: getTextColor(getAlertTextColor(type)),\n fontSize: getFontSize('small'),\n fontWeight: 600,\n }}\n >\n {lead}\n </strong>{' '}\n <SimpleTextRenderer text={text} type={type} renderLink={renderLink} />\n </div>\n );\n }\n return (\n <MarkdownBlock\n text={text}\n color={getAlertTextColor(type)}\n size=\"small\"\n omitMargin\n renderLink={renderLink}\n />\n );\n};\n\nconst Alert: React.FC<AlertProps> = ({\n type = 'info',\n message,\n hasMargin = true,\n className,\n children,\n isExpanded,\n onToggle,\n action,\n icon,\n live = false,\n renderLink,\n layout = 'inline',\n lead,\n align = 'start',\n}) => {\n const isExpandable = !!children;\n const banner = layout === 'banner' && !isExpandable;\n const centred = banner && align === 'center';\n const urgent = type === 'error' || type === 'warning';\n const liveRole = live ? (urgent ? 'alert' : 'status') : undefined;\n const [internalExpanded, setInternalExpanded] = useState(false);\n\n // Use controlled state if isExpanded is provided, otherwise use internal state\n const expanded = isExpanded !== undefined ? isExpanded : internalExpanded;\n\n const handleToggle = () => {\n const newExpanded = !expanded;\n if (isExpanded === undefined) {\n // Uncontrolled mode\n setInternalExpanded(newExpanded);\n }\n // Call onToggle if provided (for both controlled and uncontrolled)\n onToggle?.(newExpanded);\n };\n\n const alertClasses = [\n 'alert-base',\n `alert-${type}`,\n 'flex',\n 'w-full', // Ensure full width\n banner\n ? 'alert-banner'\n : isExpandable && expanded\n ? 'flex-col'\n : 'gap-2 items-center min-h-[2rem]',\n !hasMargin ? 'alert-no-margin' : '',\n centred ? 'text-center' : 'text-left',\n banner ? '' : isExpandable ? 'rounded-xl !p-0' : '!px-2.5 !py-1.5', // Slightly more vertical padding for centering\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const headerClasses = [\n 'flex items-center justify-between w-full',\n isExpandable ? 'gap-2 px-2.5 py-1' : 'gap-2',\n isExpandable && expanded ? 'rounded-t-xl' : isExpandable ? 'rounded-xl' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const expandableContentClasses = ['w-full', 'overflow-hidden'].filter(Boolean).join(' ');\n\n // Non-expandable alert (original behavior)\n if (!isExpandable) {\n const content = (\n <>\n {statusIcon(type, icon, banner)}\n <div className={centred ? 'flex items-center' : 'flex-1 flex items-center'}>\n <div className=\"[&>div]:mb-0\" role={liveRole}>\n <SimpleTextRenderer\n text={message}\n type={type}\n lead={lead}\n renderLink={renderLink}\n />\n </div>\n </div>\n </>\n );\n return (\n <div className={alertClasses}>\n {centred ? (\n // Its own group, so an `action` stays at the end while this sits mid-band.\n <div className=\"alert-centred flex-1 flex items-center justify-center gap-[10px]\">\n {content}\n </div>\n ) : (\n content\n )}\n {action && <div className=\"alert-action shrink-0 flex items-center\">{action}</div>}\n </div>\n );\n }\n\n // Expandable alert\n return (\n <div className={`${alertClasses} alert-expandable`}>\n {/* Header section with title and expand/collapse button */}\n <div className={headerClasses}>\n <div className=\"flex-1 flex gap-2 items-center\">\n {statusIcon(type, icon)}\n <div className=\"flex-1 flex items-center\">\n <div className=\"[&>div]:mb-0\" role={liveRole}>\n <SimpleTextRenderer\n text={message}\n lead={lead}\n type={type}\n renderLink={renderLink}\n />\n </div>\n </div>\n </div>\n\n {/* Right side buttons container */}\n <div className=\"flex items-center gap-2\">\n {action && <div className=\"alert-action flex items-center\">{action}</div>}\n {/* Expand/collapse button */}\n <Button\n variant=\"no-style\"\n size=\"xsmall\"\n onClick={handleToggle}\n aria-label={expanded ? 'Collapse' : 'Expand'}\n style={{\n color: getTextColor(getAlertTextColor(type)),\n }}\n >\n {expanded ? (\n <CaretUpIcon style={{ minWidth: '13px', minHeight: '13px' }} />\n ) : (\n <CaretDownIcon style={{ minWidth: '13px', minHeight: '13px' }} />\n )}\n </Button>\n </div>\n </div>\n\n {/* Expandable content */}\n {expanded && (\n <>\n <div className={expandableContentClasses}>\n <div className=\"bg-white rounded-[var(--malachite-radius-10,10px)] shadow-[0px_1px_0px_0px_rgba(0,0,0,0.15)] border border-[#e8e8e8] border-solid mx-2 mb-2 max-h-[553px] overflow-y-auto\">\n {children}\n </div>\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport default Alert;\nexport { Alert };\nexport type { AlertButtonConfig };\n"],"names":["getAlertTextColor","alertType","ICON_STYLE","ICON_COLOR","AlertIcon","jsx","InfoCircleFilled","CheckCircleFilled","ErrorCircleFilled","WarningCircleFilled","SparkleIcon","BANNER_ICON_STYLE","statusIcon","type","icon","banner","SimpleTextRenderer","text","lead","renderLink","jsxs","getTextColor","getFontSize","MarkdownBlock","Alert","message","hasMargin","className","children","isExpanded","onToggle","action","live","layout","align","isExpandable","centred","liveRole","internalExpanded","setInternalExpanded","useState","expanded","handleToggle","newExpanded","alertClasses","headerClasses","expandableContentClasses","content","Fragment","Button","CaretUpIcon","CaretDownIcon"],"mappings":"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"}
1
+ {"version":3,"file":"Alert.js","sources":["../../src/components/Alert.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Button, ButtonVariant } from './Button';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CaretUpIcon from './CustomIcons/CaretUpIcon';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport SparkleIcon from './CustomIcons/SparkleIcon';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport type { RenderLink } from './PageLayout/types';\nimport MarkdownBlock from './Typography/MarkdownBlock';\nimport type { TextColor } from './Typography/Text';\nimport { getFontSize, getTextColor } from './Typography/textStyles';\n\nexport type AlertType = 'info' | 'success' | 'error' | 'warning' | 'assistant';\n\nexport type AlertLayout = 'inline' | 'banner';\n\nexport interface AlertAddress {\n /** The full address, shown whole in mono; it wraps rather than truncates. */\n text: string;\n /** The part to set in bold, such as the registrable domain; every occurrence is bolded. */\n emphasis?: string;\n}\n\ninterface AlertButtonConfig {\n label: string;\n onClick: () => void;\n variant?: ButtonVariant;\n icon?: React.ReactNode;\n}\n\ninterface AlertProps {\n type?: AlertType;\n message: string;\n hasMargin?: boolean;\n className?: string;\n children?: React.ReactNode;\n isExpanded?: boolean;\n onToggle?: (expanded: boolean) => void;\n /** A control at the end of the alert — a link or button that resolves what it reports. */\n action?: React.ReactNode;\n /** Replaces the type's status icon: an svg painting with `currentColor`, such as a CustomIcon,\n * is drawn in the type's colour at the same size. */\n icon?: React.ReactNode;\n /** Makes its message a live region: `role=\"alert\"` for error and warning, `status` otherwise.\n * Screen readers reliably announce an `alert` as it mounts; a `status` is read when its\n * `message` changes, so keep a live info or success alert mounted. Off by default. */\n live?: boolean;\n /** Routes root-relative links in `message` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n /** `banner`: a 48px page-wide band. Applies only without `children`. */\n layout?: AlertLayout;\n /** `center` gathers a banner's icon and text in the middle of the band, for a wide page. */\n align?: 'start' | 'center';\n /** A bold sentence the message runs on from. Plain text, not markdown. */\n lead?: string;\n /** An address the message runs on into, in mono; `emphasis`, an optional substring such as the registrable domain, is bold wherever it occurs. */\n address?: AlertAddress;\n /** Markdown that runs on after the address; it joins without a space when it opens with any punctuation. */\n addressSuffix?: string;\n}\n\n// Distinct from the imported `getTextColor`, which maps a TextColor to a CSS variable.\n// This maps an AlertType to a TextColor token; both are used in this file.\nconst getAlertTextColor = (alertType: AlertType): TextColor => {\n switch (alertType) {\n case 'info':\n return 'primary';\n case 'success':\n return 'success';\n case 'error':\n return 'error';\n case 'warning':\n return 'warning';\n // The violet is on `.alert-assistant` itself; inheriting it keeps one definition\n // rather than a TextColor token that only this alert would ever name.\n case 'assistant':\n return 'inherit';\n default:\n return 'primary';\n }\n};\n\nconst ICON_STYLE = {\n width: '13px',\n height: '13px',\n flexShrink: 0,\n};\n\nconst ICON_COLOR: Record<AlertType, string> = {\n info: 'var(--malachite-alert-info-foreground)',\n success: 'var(--malachite-alert-success-foreground)',\n error: 'var(--malachite-alert-error-foreground)',\n warning: 'var(--malachite-alert-warning-foreground)',\n assistant: 'var(--malachite-alert-assistant-foreground)',\n};\n\nconst AlertIcon = {\n info: <InfoCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.info }} />,\n success: <CheckCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.success }} />,\n error: <ErrorCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.error }} />,\n warning: <WarningCircleFilled style={{ ...ICON_STYLE, color: ICON_COLOR.warning }} />,\n // The same sparkle the control that produced the message carries, so the two read as\n // one thread rather than two unrelated affordances.\n assistant: <SparkleIcon style={{ ...ICON_STYLE, color: ICON_COLOR.assistant }} />,\n};\n\nconst BANNER_ICON_STYLE = { ...ICON_STYLE, width: '16px', height: '16px' };\n\nconst statusIcon = (type: AlertType, icon: React.ReactNode, banner = false) => {\n if (!icon && !banner) return AlertIcon[type];\n const style = banner ? BANNER_ICON_STYLE : ICON_STYLE;\n return (\n <span\n className=\"alert-status-icon inline-flex shrink-0 [&_svg]:size-full!\"\n style={{ ...style, color: ICON_COLOR[type] }}\n >\n {icon || AlertIcon[type]}\n </span>\n );\n};\n\ninterface AddressSegment {\n text: string;\n bold: boolean;\n offset: number;\n}\n\n// The text cut at every occurrence of the emphasis, each cut remembering where it started.\nconst addressSegments = ({ text, emphasis }: AlertAddress): AddressSegment[] => {\n if (!emphasis) {\n return [{ text, bold: false, offset: 0 }];\n }\n const segments: AddressSegment[] = [];\n const push = (part: string, bold: boolean, offset: number) => {\n if (part) segments.push({ text: part, bold, offset });\n };\n const cuts = text.split(emphasis);\n cuts.reduce((offset, cut, index) => {\n push(cut, false, offset);\n if (index < cuts.length - 1) push(emphasis, true, offset + cut.length);\n return offset + cut.length + emphasis.length;\n }, 0);\n return segments;\n};\n\nconst AddressText: React.FC<{ address: AlertAddress; color: string }> = ({ address, color }) => (\n <code\n className=\"alert-address\"\n style={{\n fontFamily: 'var(--malachite-font-mono, monospace)',\n fontSize: '0.9em',\n color,\n overflowWrap: 'anywhere',\n }}\n >\n {addressSegments(address).map((segment) =>\n segment.bold ? (\n <strong key={segment.offset} style={{ fontWeight: 600 }}>\n {segment.text}\n </strong>\n ) : (\n <React.Fragment key={segment.offset}>{segment.text}</React.Fragment>\n ),\n )}\n </code>\n);\n\nconst OPENS_WITH_PUNCTUATION = /^\\p{P}/u;\n\nconst SimpleTextRenderer: React.FC<{\n text: string;\n type: AlertType;\n lead?: string;\n address?: AlertAddress;\n addressSuffix?: string;\n renderLink?: RenderLink;\n}> = ({ text, type, lead, address, addressSuffix, renderLink }) => {\n const color = getTextColor(getAlertTextColor(type));\n const message = (\n <MarkdownBlock\n text={text}\n color={getAlertTextColor(type)}\n size=\"small\"\n omitMargin\n renderLink={renderLink}\n />\n );\n if (!lead && !address) {\n return message;\n }\n return (\n <div className=\"alert-lead\">\n {lead ? (\n <>\n <strong style={{ color, fontSize: getFontSize('small'), fontWeight: 600 }}>\n {lead}\n </strong>{' '}\n </>\n ) : null}\n {message}\n {address ? (\n <>\n {' '}\n <AddressText address={address} color={color} />\n </>\n ) : null}\n {address && addressSuffix ? (\n <>\n {OPENS_WITH_PUNCTUATION.test(addressSuffix) ? '' : ' '}\n <MarkdownBlock\n text={addressSuffix}\n color={getAlertTextColor(type)}\n size=\"small\"\n omitMargin\n renderLink={renderLink}\n />\n </>\n ) : null}\n </div>\n );\n};\n\nconst Alert: React.FC<AlertProps> = ({\n type = 'info',\n message,\n hasMargin = true,\n className,\n children,\n isExpanded,\n onToggle,\n action,\n icon,\n live = false,\n renderLink,\n layout = 'inline',\n lead,\n address,\n addressSuffix,\n align = 'start',\n}) => {\n const isExpandable = !!children;\n const banner = layout === 'banner' && !isExpandable;\n const centred = banner && align === 'center';\n const urgent = type === 'error' || type === 'warning';\n const liveRole = live ? (urgent ? 'alert' : 'status') : undefined;\n const [internalExpanded, setInternalExpanded] = useState(false);\n\n // Use controlled state if isExpanded is provided, otherwise use internal state\n const expanded = isExpanded !== undefined ? isExpanded : internalExpanded;\n\n const handleToggle = () => {\n const newExpanded = !expanded;\n if (isExpanded === undefined) {\n // Uncontrolled mode\n setInternalExpanded(newExpanded);\n }\n // Call onToggle if provided (for both controlled and uncontrolled)\n onToggle?.(newExpanded);\n };\n\n const alertClasses = [\n 'alert-base',\n `alert-${type}`,\n 'flex',\n 'w-full', // Ensure full width\n banner\n ? 'alert-banner'\n : isExpandable && expanded\n ? 'flex-col'\n : 'gap-2 items-center min-h-[2rem]',\n !hasMargin ? 'alert-no-margin' : '',\n centred ? 'text-center' : 'text-left',\n banner ? '' : isExpandable ? 'rounded-xl !p-0' : '!px-2.5 !py-1.5', // Slightly more vertical padding for centering\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const headerClasses = [\n 'flex items-center justify-between w-full',\n isExpandable ? 'gap-2 px-2.5 py-1' : 'gap-2',\n isExpandable && expanded ? 'rounded-t-xl' : isExpandable ? 'rounded-xl' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const expandableContentClasses = ['w-full', 'overflow-hidden'].filter(Boolean).join(' ');\n\n // Non-expandable alert (original behavior)\n if (!isExpandable) {\n const content = (\n <>\n {statusIcon(type, icon, banner)}\n <div className={centred ? 'flex items-center' : 'flex-1 flex items-center'}>\n <div className=\"[&>div]:mb-0\" role={liveRole}>\n <SimpleTextRenderer\n text={message}\n type={type}\n lead={lead}\n address={address}\n addressSuffix={addressSuffix}\n renderLink={renderLink}\n />\n </div>\n </div>\n </>\n );\n return (\n <div className={alertClasses}>\n {centred ? (\n // Its own group, so an `action` stays at the end while this sits mid-band.\n <div className=\"alert-centred flex-1 flex items-center justify-center gap-[10px]\">\n {content}\n </div>\n ) : (\n content\n )}\n {action && <div className=\"alert-action shrink-0 flex items-center\">{action}</div>}\n </div>\n );\n }\n\n // Expandable alert\n return (\n <div className={`${alertClasses} alert-expandable`}>\n {/* Header section with title and expand/collapse button */}\n <div className={headerClasses}>\n <div className=\"flex-1 flex gap-2 items-center\">\n {statusIcon(type, icon)}\n <div className=\"flex-1 flex items-center\">\n <div className=\"[&>div]:mb-0\" role={liveRole}>\n <SimpleTextRenderer\n text={message}\n lead={lead}\n address={address}\n addressSuffix={addressSuffix}\n type={type}\n renderLink={renderLink}\n />\n </div>\n </div>\n </div>\n\n {/* Right side buttons container */}\n <div className=\"flex items-center gap-2\">\n {action && <div className=\"alert-action flex items-center\">{action}</div>}\n {/* Expand/collapse button */}\n <Button\n variant=\"no-style\"\n size=\"xsmall\"\n onClick={handleToggle}\n aria-label={expanded ? 'Collapse' : 'Expand'}\n style={{\n color: getTextColor(getAlertTextColor(type)),\n }}\n >\n {expanded ? (\n <CaretUpIcon style={{ minWidth: '13px', minHeight: '13px' }} />\n ) : (\n <CaretDownIcon style={{ minWidth: '13px', minHeight: '13px' }} />\n )}\n </Button>\n </div>\n </div>\n\n {/* Expandable content */}\n {expanded && (\n <>\n <div className={expandableContentClasses}>\n <div className=\"bg-white rounded-[var(--malachite-radius-10,10px)] shadow-[0px_1px_0px_0px_rgba(0,0,0,0.15)] border border-[#e8e8e8] border-solid mx-2 mb-2 max-h-[553px] overflow-y-auto\">\n {children}\n </div>\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport default Alert;\nexport { Alert };\nexport type { AlertButtonConfig };\n"],"names":["getAlertTextColor","alertType","ICON_STYLE","ICON_COLOR","AlertIcon","jsx","InfoCircleFilled","CheckCircleFilled","ErrorCircleFilled","WarningCircleFilled","SparkleIcon","BANNER_ICON_STYLE","statusIcon","type","icon","banner","addressSegments","text","emphasis","segments","push","part","bold","offset","cuts","cut","index","AddressText","address","color","segment","React","OPENS_WITH_PUNCTUATION","SimpleTextRenderer","lead","addressSuffix","renderLink","getTextColor","message","MarkdownBlock","jsxs","Fragment","getFontSize","Alert","hasMargin","className","children","isExpanded","onToggle","action","live","layout","align","isExpandable","centred","liveRole","internalExpanded","setInternalExpanded","useState","expanded","handleToggle","newExpanded","alertClasses","headerClasses","expandableContentClasses","content","Button","CaretUpIcon","CaretDownIcon"],"mappings":"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"}