Skip to content
0

Alert ​

useAlert(options) creates a .alert with role="alert" for warning/danger and role="status" for info/success. Dismissible alerts get a button with aria-label="Dismiss". alertClass(options) returns the classes for SSR markup.

Variants ​

ts
import { useAlert } from "@katanakit/ui";

stack.append(
  useAlert({ variant: "info", title: "Heads up", message: "Deploy starts in 10 minutes." }),
  useAlert({ variant: "success", message: "Backup finished." }),
  useAlert({ variant: "warning", message: "Quota at 90%." }),
  useAlert({ variant: "danger", title: "Build failed", message: "Check the logs." }),
);

Dismissible ​

ts
useAlert({
  variant: "info",
  message: "This one can be dismissed.",
  dismissible: true,
  onDismiss: () => console.log("closed"),
});

Contract

Every component in the kit follows one shape. Pure builders return a class string and touch nothing; factories build a DOM element and need a browser.

SurfaceImportNeeds a DOM
Pure class builderalertClassNo — safe during SSR
Element factoryuseAlertYes — throws with a pointer to the pure surface
// Server and templates — pure
<div class={ alertClass({ /* … */ }) }></div>

// Browser — imperative
document.body.append(useAlert({ /* … */ }));

Class names are unprefixed. The root class is alert, not kk-alert, and every component rule is wrapped in @layer katana.

That matters because these names collide 1:1 with daisyUI. Unlayered CSS always beats layered CSS regardless of specificity or import order, so loading both is deterministic instead of "whoever came last". See why.

Options ​

OptionTypeDefaultNotes
variant"info" | "success" | "warning" | "danger""info"Colors and ARIA role.
titlestring—Bold title line.
messagestring—Body text.
dismissiblebooleanfalseAdds the accessible close button.
onDismiss() => void—Called after the alert is removed.

SSR

The factory needs a DOM. On the server use alertClass() and render the markup yourself — the classes are stable strings.

Released under the MIT License.