@stackone/malachite 2.75.0 → 2.77.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
@@ -26,15 +26,15 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
26
26
  - **`OverflowRow`** — Horizontal row that collapses items that do not fit into an overflow affordance.
27
27
  - **`ActionBar`** — A row of actions that collapses into a single `ActionMenu` once its container drops below `collapseBelow`. Measures the nearest genuinely-wider ancestor rather than itself, since the row shrinks to its own content. `dividerBefore` renders a vertical rule in the row and a divider in the collapsed menu, so both forms group the actions the same way. _Key props:_ `buttons` (`label`, `onClick`, `icon`, `variant`, `size`, `radius`, `tooltip`, `disabled`, `dividerBefore`), `collapseBelow`, `menuLabel`, `className`.
28
28
  - **`Popover`** — An anchored, non-modal panel for arbitrary content — a workspace switcher, an org flyout. The panel renders in its own shadow root, so malachite components inside it are styled, and joins the top layer like the other overlays. It prefers its `placement` and flips to the opposite side when there is no room, clamping along the other axis. Click-opened panels take focus and hand it back to the trigger on close; `openOn="hover"` also opens on focus and stays open while the pointer or focus is in the panel. A nested Popover counts as inside its parent for outside-press and hover dismissal, and Escape closes the topmost only. A click panel also closes when focus moves somewhere outside it and its trigger, and on close it hands focus back to the trigger only if focus would otherwise fall to the page. _Key props:_ `trigger`, `children`, `open`, `defaultOpen`, `onOpenChange`, `placement` (`bottom-start` | `bottom-end` | `top-start` | `top-end` | `top-center` | `right-start` | `right-end` | `left-start`), `openOn` (`click` | `hover`), `width` (`content` | `trigger`), `padding` (`none` | `small` | `medium`), `anchorRef` (position against another element, e.g. the section a trigger row sits in), `offset` (`small` 8px | `medium` 12px | `large` 14px), `elevation` (`default` | `raised`), `initialFocus` (a ref, or a function read when the panel is shown, for what takes focus in place of the first focusable; it is read again as the panel's content changes, so focus follows content that mounts late or a focused element that is removed, but never leaves an element the user moved to; `initialFocusRef` is its deprecated form, read on open only), `openOnArrowKey` (a click panel also opens, focus inside, on the arrow key its placement points at — ArrowDown for a `bottom-*` placement; a text field trigger keeps its arrow keys), `role` (`dialog` | `menu` | `listbox`; `menu` brings no roving focus of its own), `aria-label` or `aria-labelledby` (one is required), `className`. The panel is capped to the viewport width, and only overlays opened from inside it (menus, dropdowns, modals) count as inside for outside-press dismissal. A side placement stays level with its anchor and scrolls within the room below, sliding up only when under 160px is left. Parts for the panel body: `Popover.Header` (`title`, `action`, `divider` — `false` drops the rule and sits it 4px over the list, as its label), `Popover.Action` (`icon`, `aria-label`, `onClick`, `href` (a link that opens in a new tab on Cmd/Ctrl-click or a middle click; a plain click runs `onClick` when one is given), `disabled`, `tooltip`), `Popover.List` (a scrolling list; `scrollToSelected` scrolls the list, never the page, to its selected row, one marked `aria-current`, `aria-selected` or a checked radio, each time the popover is shown, once that row mounts), `Popover.Section` (a bordered section), `Popover.Empty` (an empty-state line), `Popover.Search` (pads a `Search` above the list without a second rule), `Popover.Note` (a footnote section in small secondary text) and `Popover.Status` (`message`, `tone` (`default` | `error`), `action` (`label`, `onClick`, `pending`), `focusable`): one `status` live region for the panel's life, announcing each message it is given and staying mounted, visually hidden, while there is none, so clear `message` rather than unmounting it. Errors announce through the same region. `focusable` with a ref makes it an `initialFocus` target; resolve to it only while it has a message, since an empty one is invisible. Reach for `Status` when the message changes while the panel is open or carries an action (loading, failed, sign-in needed), and `Empty` for a static line in a list that simply has nothing in it.
29
- - **`Modal`** — Centred dialog over a scrim, with header slots (icon/title/subtitle/extra), a scrolling body and a pinned footer. Locks background scroll and dismisses on ESC, the close button, or a scrim click unless `closeOnOverlayClick` is off; `busy` suppresses the two pointer routes while a request is in flight and sets `aria-busy`, so a stray click cannot tear the dialog down mid-write — but never ESC, which is the only guaranteed keyboard exit from a focus trap and so always reaches `onClose`. ESC, the Tab focus trap and `aria-modal` all apply to the topmost overlay only, so these may be stacked — a dialog opened from a panel keeps Tab to itself and the panel stops claiming to be modal. The Tab trap follows focus into a malachite popup portaled out of the dialog’s own tree — a `MultiSelect` listbox or a `Popover` opened from the body — and traps Tab within that popup while it holds focus, so Tab walks and wraps that popup’s own stops rather than being yanked back to the dialog’s first control or escaping the dialog altogether. A `Dropdown` list or an `ActionMenu` is dismissed by Tab rather than trapping it: it closes and focus returns to its trigger, so Tab carries on from there. A consumer’s own portaled popup is not known to the trap and Tab will pull focus out of it. Set `role="alertdialog"` for a consequential choice, which asks assistive tech to announce the body and not just the name, and point `aria-describedby` at whichever element carries it. Width comes from the `size` union (`small` 420px | `medium` 612px | `large` 760px) rather than a raw pixel prop. `titleAdornment` sits immediately after the title behind a hairline divider, for naming the thing being acted on — distinct from `headerExtra`, which pins to the far right. `tray` paints a tinted plate around the card and hangs a `caption` beneath it; the plate is the dialog element itself, so that caption stays inside the `aria-modal` subtree rather than being stranded outside it by the visual nesting, and it is added to `aria-describedby` automatically because it says what the dialog is asking. It takes a tone (`neutral` | `warning` | `error` | `success`) rather than a colour, so no consumer can paint it off-palette — and the tone sets the plate and its caption colour together, so the two cannot disagree. The caption is a `{ label?, message }` pair rather than a node, because its row height, type scale and colour belong to the plate. `size` names the card, and the plate’s 4px ring is added on top. Like `SidePanel` it sits in a z-index band from 1000 — one step per stacked overlay, so what paints on top is what holds the keyboard — and stays out of the browser top layer, so a host app’s own dialogs can still cover it. `callouts` stacks full-bleed `Alert` bands at the top of the body, as on `SidePanel`; they ignore `bodyPadding` and lead `aria-describedby`, ahead of the consumer’s own description and the tray caption. For a confirmation use `ConfirmationDialog`, which is a preset over this. _Key props:_ `open`, `onClose`, `title`, `subtitle`, `icon`, `headerExtra`, `titleAdornment`, `tray`, `callouts`, `renderLink`, `headerDivider`, `footer`, `size`, `showCloseButton`, `closeOnOverlayClick`, `bodyPadding`, `bodyHeight` (`auto` | `tall` — 600px, or the viewport less 160px when smaller, for an embedded iframe at `height: 100%`), `busy`, `role` (`dialog` | `alertdialog`), `aria-label`, `aria-labelledby`, `aria-describedby`.
30
- - **`SidePanel`** — Right-hand slide-in overlay panel (drawer) with header slots (back/icon/title/subtitle/extra), scrollable body and optional footer. `subtitlePlacement="below"` stacks the subtitle on its own line under the title row, so neither truncates the other in a narrow panel. `toolbar` pins content between the header and the scrolling body (16px sides, 16px above, 8px below, no divider), such as a Search over the list it filters. Locks background scroll and dismisses on ESC, an overlay click or close. ESC and the Tab focus trap apply to the topmost overlay only, so a `Modal` may be stacked over it. The Tab trap follows focus into a malachite popup portaled out of the panel’s own tree — a `MultiSelect` listbox or a `Popover` opened from the body — and traps Tab within that popup while it holds focus, so Tab walks and wraps that popup’s own stops rather than being yanked back to the panel’s first control or escaping the panel altogether. A `Dropdown` list or an `ActionMenu` is dismissed by Tab rather than trapping it: it closes and focus returns to its trigger, so Tab carries on from there. A consumer’s own portaled popup is not known to the trap and Tab will pull focus out of it. `callouts` stacks full-bleed `Alert` bands at the top of the body, above `children` and unaffected by `bodyPadding` — the same band `ConfirmationDialog` gives its `callout` — and `renderLink` routes their root-relative markdown links through the app’s router. The callouts are announced as the panel’s description, ahead of `description`.
29
+ - **`Modal`** — Centred dialog over a scrim, with header slots (icon/title/subtitle/extra), a scrolling body and a pinned footer. Locks background scroll and dismisses on ESC, the close button, or a scrim click unless `closeOnOverlayClick` is off; `busy` suppresses the two pointer routes while a request is in flight and sets `aria-busy`, so a stray click cannot tear the dialog down mid-write — but never ESC, which is the only guaranteed keyboard exit from a focus trap and so always reaches `onClose`. ESC, the Tab focus trap and `aria-modal` all apply to the topmost overlay only, so these may be stacked — a dialog opened from a panel keeps Tab to itself and the panel stops claiming to be modal. The Tab trap follows focus into a malachite popup portaled out of the dialog’s own tree — a `MultiSelect` listbox or a `Popover` opened from the body — and traps Tab within that popup while it holds focus, so Tab walks and wraps that popup’s own stops rather than being yanked back to the dialog’s first control or escaping the dialog altogether. A `Dropdown` list or an `ActionMenu` is dismissed by Tab rather than trapping it: it closes and focus returns to its trigger, so Tab carries on from there. A consumer’s own portaled popup is not known to the trap and Tab will pull focus out of it. Set `role="alertdialog"` for a consequential choice, which asks assistive tech to announce the body and not just the name, and point `aria-describedby` at whichever element carries it. Width comes from the `size` union (`small` 420px | `medium` 612px | `large` 760px | `fullscreen`, which fills the window in both directions) rather than a raw pixel prop. `titleAdornment` sits immediately after the title behind a hairline divider, for naming the thing being acted on — distinct from `headerExtra`, which pins to the far right. `tray` paints a tinted plate around the card and hangs a `caption` beneath it; the plate is the dialog element itself, so that caption stays inside the `aria-modal` subtree rather than being stranded outside it by the visual nesting, and it is added to `aria-describedby` automatically because it says what the dialog is asking. It takes a tone (`neutral` | `warning` | `error` | `success`) rather than a colour, so no consumer can paint it off-palette — and the tone sets the plate and its caption colour together, so the two cannot disagree. The caption is a `{ label?, message }` pair rather than a node, because its row height, type scale and colour belong to the plate. `size` names the card, and the plate’s 4px ring is added on top. Like `SidePanel` it sits in a z-index band from 1000 — one step per stacked overlay, so what paints on top is what holds the keyboard — and stays out of the browser top layer, so a host app’s own dialogs can still cover it. `callouts` stacks full-bleed `Alert` bands at the top of the body, as on `SidePanel`; they ignore `bodyPadding` and lead `aria-describedby`, ahead of the consumer’s own description and the tray caption. For a confirmation use `ConfirmationDialog`, which is a preset over this. _Key props:_ `open`, `onClose`, `title`, `subtitle`, `icon`, `headerExtra`, `titleAdornment`, `tray`, `callouts`, `renderLink`, `headerDivider`, `footer`, `size`, `showCloseButton`, `closeOnOverlayClick`, `bodyPadding`, `bodyHeight` (`auto` | `tall` — 600px, or the viewport less 160px when smaller, for an embedded iframe at `height: 100%`), `busy`, `role` (`dialog` | `alertdialog`), `aria-label`, `aria-labelledby`, `aria-describedby`.
30
+ - **`SidePanel`** — Right-hand slide-in overlay panel (drawer) with header slots (back/icon/title/subtitle/extra), scrollable body and optional footer. `subtitlePlacement="below"` stacks the subtitle on its own line under the title row, so neither truncates the other in a narrow panel. `toolbar` pins content between the header and the scrolling body (16px sides, 16px above, 8px below, no divider), such as a Search over the list it filters. Locks background scroll and dismisses on ESC, an overlay click or close. ESC and the Tab focus trap apply to the topmost overlay only, so a `Modal` may be stacked over it. The Tab trap follows focus into a malachite popup portaled out of the panel’s own tree — a `MultiSelect` listbox or a `Popover` opened from the body — and traps Tab within that popup while it holds focus, so Tab walks and wraps that popup’s own stops rather than being yanked back to the panel’s first control or escaping the panel altogether. A `Dropdown` list or an `ActionMenu` is dismissed by Tab rather than trapping it: it closes and focus returns to its trigger, so Tab carries on from there. A consumer’s own portaled popup is not known to the trap and Tab will pull focus out of it. `callouts` stacks full-bleed `Alert` bands at the top of the body, above `children` and unaffected by `bodyPadding` — the same band `ConfirmationDialog` gives its `callout` — and `renderLink` routes their root-relative markdown links through the app’s router. The callouts are announced as the panel’s description, ahead of `description`. `aside` opens a full-height column to the left, as wide again as `maxWidth`, for help that sits beside the content — a setup guide beside a form. The panel’s own header, body and footer keep their width and place, and the aside’s `title` (with an optional `headerExtra`, such as a `Stepper`) and `footer` line up with the panel’s header and footer; `bodyPadding` works as the panel’s does. The aside is never narrower than 360px, so a window too narrow for both columns scrolls the panel sideways.
31
31
  - **`useHasOpenOverlay`** — Hook reporting whether any modal-type overlay - `SidePanel` or `Modal` - is open anywhere in the app. For host chrome that has to get out of an overlay’s way, a floating support widget being the case it was added for: overlays render through a portal, so a host has no DOM signal of its own to read, and reading the library’s internal markers would couple it to something it does not own. Dropdowns and tooltips are deliberately not counted - they do not trap focus, and chrome does not need to move for them. _Key props:_ No arguments. Returns a boolean.
32
32
  - **`SidePanelNavFooter`** — Keyboard-hint footer for SidePanel: up/down keycaps to step between records and an esc-to-close hint, with an optional right-aligned actions slot.
33
33
 
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`.
@@ -45,7 +45,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
45
45
  - **`UsageCard`** — A small metered card: a title (optionally a link via `titleLink`, drawn with a trailing arrow), a right-aligned `detail` such as "700/1,000", and a body, usually a `Progress`. Used by `Sidebar.Usage`, and fine on its own, e.g. on a billing page. _Key props:_ `title`, `titleLink`, `detail`, `children`, `aria-label` (required; names the group), `busy` (sets `aria-busy` only).
46
46
  - **`Progress`** — Progress bar.
47
47
  - **`LoadingBar`** — Indeterminate full-width loading line; the variant colour sweeps across a pale track for work of unknown duration. Toggle `active` rather than unmounting, so the reserved height prevents layout shift. _Key props:_ `active`, `LoadingBarVariant` (`default` | `warning` | `error`), `LoadingBarSize` (`small` | `medium` | `large`), `aria-label`, `aria-labelledby`, `className`, `style`.
48
- - **`ToastProvider`** — Transient top-centre toasts for the outcome of an action. Wrap the app once in `ToastProvider` and call `useToast().show({ message, variant })` anywhere beneath it. Each toast auto-dismisses, pauses while hovered and dismisses on click; at most three show at once. Toasts are announced through always-mounted live regions (`status` for success, `alert` for error), and the pills themselves are hidden from assistive tech and never take focus, so they cannot fight a dialog's focus trap. The host mounts on the first toast and joins the top layer, so toasts paint above elevated side panels. _Key props:_ `ToastProvider`: `children`, `duration` (ms, default 3000). `useToast()` → `show({ message, variant })`, `ToastVariant` (`success` | `error`, default `success`).
48
+ - **`ToastProvider`** — Transient top-centre toasts for the outcome of an action. Wrap the app once in `ToastProvider` and call `useToast().show({ message, variant })` anywhere beneath it. Corners match a medium button. Each toast auto-dismisses, pauses while hovered and dismisses on click; at most three show at once. Toasts are announced through always-mounted live regions (`status` for success, `alert` for error), and the pills themselves are hidden from assistive tech and never take focus, so they cannot fight a dialog's focus trap. The host mounts on the first toast and joins the top layer, so toasts paint above elevated side panels. _Key props:_ `ToastProvider`: `children`, `duration` (ms, default 3000). `useToast()` → `show({ message, variant })`, `ToastVariant` (`success` | `error`, default `success`).
49
49
  - **`Spinner`** — Loading spinner.
50
50
  - **`Skeleton`** — Loading placeholders. Includes `Skeleton.Avatar` and `Skeleton.Input`. The shimmer stops under `prefers-reduced-motion`, leaving the plain placeholder.
51
51
  - **`Tooltip`** — Hover/focus tooltip; also works on disabled controls (see CLAUDE.md). It describes its trigger once shown, so `describesTrigger={false}` where the same sentence is already on screen and referenced — otherwise a screen reader reads it twice. _Key props:_ `text`, `placement`, `delay`, `maxWidth`, `shouldShow`, `triggerAs`, `describesTrigger`, `isShrinkable`, `fill`, `wrapChildren`, `suppressed` (holds the tooltip back, e.g. while the popup its trigger opens is up), `showOnFocus` (false where script can move focus onto the trigger, e.g. an option a panel focuses on open), `focusableTrigger` (makes a trigger that cannot take focus — text, a static `Tag` — a tab stop, so the tooltip is not mouse-only; not for focusable children).
@@ -122,7 +122,7 @@ The catalog of components exported from `@stackone/malachite`. **Reach for one o
122
122
  - **`AppLogo`** — A connector's mark, optionally with its name and version tag. Builds on `Avatar`, so a missing or broken logo falls back to the generic "no logo available" placeholder, a neutral grey tile with a darker square, the same mark stackone-logos.com serves. The gap tightens below 18px so the mark and label still read as one unit. _Key props:_ `src`, `name`, `showName`, `size`, `nameSize`, `nameWeight`, `version`, `truncate`, `className`.
123
123
  - **`ConnectionHeader`** — Two tilted logo tiles (from → to) showing a connection between apps. _Key props:_ `from`, `to` (`ConnectionEndpoint`: `icon`, `label`, `background`).
124
124
  - **`CodeBlock`** — Syntax-styled code block. _Key props:_ `code`.
125
- - **`Stepper`** — Progress dots/segments for a multi-step flow; optionally clickable. _Key props:_ `steps`, `active`, `onChange`.
125
+ - **`Stepper`** — Progress dots/segments for a multi-step flow; optionally clickable. `groups` takes a long flow in labelled sections: the active step’s group opens into one bar per step across the full width and every other group folds to a short bar. Folded bars keep a fixed width and the open group shares what is left, so allow about 20px per other group and 12px per step in the open group. With `onChange` each folded bar is a button named after its group. _Key props:_ `steps` or `groups` (`{ label, steps }[]`), `active`, `onChange`.
126
126
  - **`Swatch`** — Colour swatch preview.
127
127
 
128
128
  ## Theming & utility
@@ -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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"}