Kosmesis
Components

Alert

A static inline notification with Title/Description parts, wrapping Morphos's Alert primitive.

Installation

npx kosmesis add alert
pnpm dlx kosmesis add alert
yarn dlx kosmesis add alert
bunx kosmesis add alert

Install the following dependencies:

npm install @morphos/feedback class-variance-authority
pnpm add @morphos/feedback class-variance-authority
yarn add @morphos/feedback class-variance-authority
bun add @morphos/feedback class-variance-authority

Copy and paste the following code into your project.

alert.tsx
import { cva, type VariantProps } from "class-variance-authority";import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { Alert as MorphosAlert, type AlertProps as MorphosAlertProps  } from "@morphos/feedback";import { cn } from "@/lib/utils";export const alertVariants = cva(  "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",  {    variants: {      variant: {        default: "bg-card text-card-foreground",        destructive:          "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",      },    },    defaultVariants: {      variant: "default",    },  },);export interface AlertProps extends Omit<MorphosAlertProps, "variant">, VariantProps<typeof alertVariants> {}@Component()export class Alert extends StatelessComponent<AlertProps> {  render() {    const { variant, class: cls, title, children, ...rest } = this.props;    return (      <MorphosAlert        class={cn(alertVariants({ variant }), cls)}        variant={variant === "destructive" ? "error" : "info"}        title={title}        {...rest}      >        {children}      </MorphosAlert>    );  }}export interface AlertSlotProps {  class?: string;  id?: string;  children?: Children;}@Component()export class AlertTitle extends StatelessComponent<AlertSlotProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} data-slot="alert-title" class={cn("col-start-2 min-h-4 font-medium tracking-tight", cls)}>        {children}      </div>    );  }}@Component()export class AlertDescription extends StatelessComponent<AlertSlotProps> {  render() {    const { class: cls, id, children } = this.props;    return (      <div        id={id}        data-slot="alert-description"        class={cn("col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed", cls)}      >        {children}      </div>    );  }}

Install the following dependencies:

npm install @morphos/feedback @praxisjs/css
pnpm add @morphos/feedback @praxisjs/css
yarn add @morphos/feedback @praxisjs/css
bun add @morphos/feedback @praxisjs/css

Copy and paste the following code into your project.

alert.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { Alert as MorphosAlert, type AlertProps as MorphosAlertProps  } from "@morphos/feedback";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class AlertStyles extends Stylesheet {  $root = this.css({    position: "relative",    display: "grid",    width: "100%",    gridTemplateColumns: "0 1fr",    alignItems: "start",    rowGap: "0.125rem",    borderRadius: "0.5rem",    border: `1px solid ${t.border}`,    padding: "0.75rem 1rem",    fontSize: "0.875rem",  })    .has(">svg", { gridTemplateColumns: "1rem 1fr", columnGap: "0.75rem" })    .on("& > svg", { width: "1rem", height: "1rem", transform: "translateY(0.125rem)", color: "currentColor" });  $variantDefault = this.css({ backgroundColor: t.card, color: t.cardForeground });  $variantDestructive = this.css({ backgroundColor: t.card, color: t.destructive }).on("& > svg", {    color: "currentColor",  });  $title = this.css({ gridColumnStart: 2, minHeight: "1rem", fontWeight: 500, letterSpacing: "-0.01em" });  $description = this.css({    gridColumnStart: 2,    display: "grid",    justifyItems: "start",    rowGap: "0.25rem",    fontSize: "0.875rem",    color: t.mutedForeground,  }).on("& p", { lineHeight: 1.6 });}export type AlertVariant = "default" | "destructive";export interface AlertProps extends Omit<MorphosAlertProps, "variant"> {  variant?: AlertVariant;}@Component()export class Alert extends StatelessComponent<AlertProps> {  @Styled(AlertStyles) $s!: AlertStyles;  render() {    const { variant = "default", class: cls, title, children, ...rest } = this.props;    const variants: Record<AlertVariant, string> = {      default: this.$s.$variantDefault,      destructive: this.$s.$variantDestructive,    };    return (      <MorphosAlert        class={cx(this.$s.$root, variants[variant], cls)}        variant={variant === "destructive" ? "error" : "info"}        title={title}        {...rest}      >        {children}      </MorphosAlert>    );  }}export interface AlertSlotProps {  class?: string;  id?: string;  children?: Children;}@Component()export class AlertTitle extends StatelessComponent<AlertSlotProps> {  @Styled(AlertStyles) $s!: AlertStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} data-slot="alert-title" class={cx(this.$s.$title, cls)}>        {children}      </div>    );  }}@Component()export class AlertDescription extends StatelessComponent<AlertSlotProps> {  @Styled(AlertStyles) $s!: AlertStyles;  render() {    const { class: cls, id, children } = this.props;    return (      <div id={id} data-slot="alert-description" class={cx(this.$s.$description, cls)}>        {children}      </div>    );  }}

Examples

Usage

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";

<Alert>
  <AlertTitle>Heads up!</AlertTitle>
  <AlertDescription>You can add components using the CLI.</AlertDescription>
</Alert>

<Alert variant="destructive">
  <AlertTitle>Error</AlertTitle>
  <AlertDescription>Your session has expired. Please log in again.</AlertDescription>
</Alert>

Props

PropTypeDefault
variant"default" | "destructive""default"

variant="destructive" maps to Morphos's variant="error" under the hood (and sets aria-live="assertive" accordingly); variant="default" maps to Morphos's "info".

On this page