Design system

Alert & Alert Stack

Inline feedback message with severity variants.

Alert Examples

Copy-ready examples with live previews (including AlertsStack).

Basic usage (controlled)

You own `isOpen` and update it via `onOpenChange`.

Live preview

Saved successfully

Basic (controlled)

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      message="Saved successfully"
      showClose
    />
  );
}

With action button

Use `actionLabel` + `onAction` for quick actions (keep labels short).

Live preview

You have unsaved changes

Action (compact label)

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      message="You have unsaved changes"
      actionLabel="Undo"
      onAction={() => console.log("undo")}
      showClose
    />
  );
}

Two-lines density + ReactNode message

Use `density='two-lines'` for long content, and pass rich content via `message`.

Live preview

This is a longer message designed to wrap into a second line for better readability.

Two-lines + action

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      density="two-lines"
      variant="info"
      message="This is a longer message designed to wrap into a second line for better readability."
      actionLabel="Details"
      onAction={() => console.log("details")}
      showClose
    />
  );
}

Live preview

Heads up: your session will expire soon. Save your work.

ReactNode message

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      variant="warning"
      density="two-lines"
      message={
        <span>
          <strong>Heads up:</strong> your session will expire soon. Save your work.
        </span>
      }
      actionLabel="Save"
      onAction={() => console.log("save")}
      showClose
    />
  );
}

Auto-close

Close automatically after a delay.

Auto-close only schedules when `isOpen === true`.

Live preview

This will close automatically

Auto-close (2500ms)

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      message="This will close automatically"
      autoClose
      autoCloseTimeMs={2500}
      showClose
    />
  );
}

Swipe-to-dismiss

Enable swipe to dismiss the alert (x-axis, 80px threshold).

Live preview

Swipe to dismiss

Swipe enabled

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <Alert
      isOpen={open}
      onOpenChange={setOpen}
      message="Swipe me"
      swipeEnabled
      showClose
    />
  );
}

Style + variant

Use `style` for surface and `variant` for semantic tone.

Live preview

Profile updated
Something went wrong

Outlined + success / Filled + danger

import { useState } from "react";
import Alert from "@/_components/alert/Alert";

export default function Example() {
  const [openA, setOpenA] = useState(true);
  const [openB, setOpenB] = useState(true);

  return (
    <>
      <Alert
        isOpen={openA}
        onOpenChange={setOpenA}
        style="outlined"
        variant="success"
        message="Profile updated"
        showClose
      />

      <Alert
        isOpen={openB}
        onOpenChange={setOpenB}
        style="filled"
        variant="danger"
        message="Something went wrong"
        showClose
      />
    </>
  );
}

AlertsStack (basic)

Use AlertsStack to anchor alerts to a fixed screen position.

Live preview

Saved successfully

Single alert in AlertsStack

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";
import AlertsStack from "@/packages/ui/src/_components/alert_stack/AlertStack";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <AlertsStack placement="bottom-right">
      <Alert
        isOpen={open}
        onOpenChange={setOpen}
        message="Saved successfully"
        showClose
      />
    </AlertsStack>
  );
}

AlertsStack (multiple alerts)

Stack multiple alerts by rendering them as children.

Live preview

One
Two
Auto-close in stack

Multiple alerts

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";
import AlertsStack from "@/packages/ui/src/_components/alert_stack/AlertStack";

export default function Example() {
  const [open1, setOpen1] = useState(true);
  const [open2, setOpen2] = useState(true);

  return (
    <AlertsStack placement="bottom-right">
      <Alert isOpen={open1} onOpenChange={setOpen1} message="One" showClose />
      <Alert isOpen={open2} onOpenChange={setOpen2} message="Two" variant="success" showClose />
    </AlertsStack>
  );
}

AlertsStack (fullWidth)

Optional `fullWidth` modifier (CSS-driven).

Live preview

Full width stack (CSS-driven). Useful for mobile layouts.

Full width bottom-center

import { useState } from "react";
import Alert from "@/packages/ui/src/_components/alert/Alert";
import AlertsStack from "@/packages/ui/src/_components/alert_stack/AlertStack";

export default function Example() {
  const [open, setOpen] = useState(true);

  return (
    <AlertsStack placement="bottom-center" fullWidth>
      <Alert
        isOpen={open}
        onOpenChange={setOpen}
        density="two-lines"
        message="Full width stack (CSS-driven). Useful for mobile layouts."
        variant="primary"
        showClose
      />
    </AlertsStack>
  );
}

On this page

Alert Props

Snackbar/alert-style component for short messages with optional action, optional close button, swipe-to-dismiss, and auto-close.

This is an externally controlled component: to actually close it, you must update `isOpen` in your state.

Dismiss order: `onClose?.()` then `onOpenChange?.(false)`.

Swipe-to-dismiss uses a default threshold of 80px on the x axis.

Auto-close timer is scheduled only when `isOpen === true` and pauses/resumes on hover and focus-within by default.

Alert props
PropTypeRequiredDefaultDescription
isOpenbooleanYesn/aControlled state: true shows, false hides.
onOpenChange(nextOpen: boolean) => voidNoundefinedRecommended callback to keep external state in sync (called with false on dismiss).
style"filled" | "outlined"No"filled"Visual surface style for the container. (Values: filled, outlined)
variant"neutral" | "neutral-inverse" | "primary" | "secondary" | "tertiary" | "info" | "success" | "warning" | "danger"No"neutral-inverse"Semantic/tone variant. (Values: neutral, neutral-inverse, primary, secondary, tertiary, info, success, warning, danger)
density"single-line" | "two-lines"No"single-line"Layout density (one line vs two lines). (Values: single-line, two-lines)
messageReact.ReactNode | stringYesn/aMain alert content.
actionLabelstringNoundefinedIf provided, renders an action button.
onAction() => voidNoundefinedAction button callback.
showClosebooleanNofalseIf true, renders a close icon button.
onClose() => voidNoundefinedAdditional callback fired on any dismiss (auto-close, swipe, or close button).
swipeEnabledbooleanNofalseEnables swipe-to-dismiss (default axis x, threshold 80px).
autoClosebooleanNofalseEnables auto-close when isOpen === true.
autoCloseTimeMsnumberNo4000Delay in ms before auto-dismiss when autoClose=true.

AlertsStack Props

Wrapper container used to stack multiple <Alert /> components in a fixed placement on screen. It only renders a <div> with the right classes — you provide the alerts via `children`.

AlertsStack does not manage queueing or timing — it only positions content.

Recommended: render only <Alert /> children to keep consistent spacing and behavior.

Class hooks: base `cssnt-alerts`, placement modifiers `cssnt-alerts--*`, and `cssnt-alerts--fullwidth` when enabled.

AlertsStack props
PropTypeRequiredDefaultDescription
childrenReact.ReactNodeYesn/aThe alerts (or any nodes) to render inside the stack.
placement"top-left" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right"No"bottom-right"Where the stack is anchored on screen. (Values: top-left, top-right, bottom-left, bottom-center, bottom-right)
fullWidthbooleanNofalseAdds a modifier class to make the stack span the available width (CSS-driven).