shadimage
moduix-react
itemalertsource: ok · hit

Alert

moduix React Alert component.

npx shadcn add "https://moduix.dev/r/react/alert.json"
free

No selection tags yet — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light
ui-primitives@ark-ui/react

Registry dependencies

@moduix-react/foundation

Files3 · source cached 10/14/2026, 12:56:34 PM

src/components/alert/Alert.tsx
import type { HTMLArkProps } from '@ark-ui/react/factory';
import { ark } from '@ark-ui/react/factory';
import { clsx } from 'clsx';
import { forwardRef, type ComponentRef } from 'react';
import styles from './Alert.module.css';

type AlertStatus = 'info' | 'success' | 'warning' | 'error';

type AlertProps = HTMLArkProps<'div'> & {
  status?: AlertStatus;
};

const Alert = forwardRef<ComponentRef<typeof ark.div>, AlertProps>(function Alert(
  { children, className, role, status = 'info', ...props },
  ref,
) {
  return (
    <ark.div
      ref={ref}
      role={role}
      className={clsx(styles.root, className)}
      {...props}
      data-scope="alert"
      data-part="root"
      data-status={status}
      data-slot="alert-root"
    >
      {children}
    </ark.div>
  );
});

const AlertIndicator = forwardRef<ComponentRef<typeof ark.span>, HTMLArkProps<'span'>>(
  function AlertIndicator({ className, ...props }, ref) {
    return (
      <ark.span
        ref={ref}
        aria-hidden="true"
        className={clsx(styles.indicator, className)}
        {...props}
        data-scope="alert"
        data-part="indicator"
        data-slot="alert-indicator"
      />
    );
  },
);

const AlertContent = forwardRef<ComponentRef<typeof ark.div>, HTMLArkProps<'div'>>(
  function AlertContent({ className, ...props }, ref) {
    return (
      <ark.div
        ref={ref}
        className={clsx(styles.content, className)}
        {...props}
        data-scope="alert"
        data-part="content"
        data-slot="alert-content"
      />
    );
  },
);

const AlertTitle = forwardRef<ComponentRef<typeof ark.p>, HTMLArkProps<'p'>>(function AlertTitle(
  { className, ...props },
  ref,
) {
  return (
    <ark.p
      ref={ref}
      className={clsx(styles.title, className)}
      {...props}
      data-scope="alert"
      data-part="title"
      data-slot="alert-title"
    />
  );
});

const AlertDescription = forwardRef<ComponentRef<typeof ark.div>, HTMLArkProps<'div'>>(
  function AlertDescription({ className, ...props }, ref) {
    return (
      <ark.div
        ref={ref}
        className={clsx(styles.description, className)}
        {...props}
        data-scope="alert"
        data-part="description"
        data-slot="alert-description"
      />
    );
  },
);

const AlertActions = forwardRef<ComponentRef<typeof ark.div>, HTMLArkProps<'div'>>(
  function AlertActions({ className, ...props }, ref) {
    return (
      <ark.div
        ref={ref}
        className={clsx(styles.actions, className)}
        {...props}
        data-scope="alert"
        data-part="actions"
        data-slot="alert-actions"
      />
    );
  },
);

export { Alert, AlertActions, AlertContent, AlertDescription, AlertIndicator, AlertTitle };
src/components/alert/Alert.module.css
@layer moduix.components {
  .root {
    box-sizing: border-box;
    display: flex;
    align-items: start;
    width: 100%;
    min-width: 0;
    gap: var(--moduix-alert-gap, var(--moduix-spacing-3));
    border: var(--moduix-alert-border-width, var(--moduix-border-width-sm)) solid
      var(
        --moduix-alert-border-color,
        var(--_alert-border-color-default, var(--moduix-color-border))
      );
    border-radius: var(--moduix-alert-radius, var(--moduix-radius-lg));
    padding: var(--moduix-alert-padding, var(--moduix-spacing-3));
    background-color: var(--moduix-alert-bg, var(--_alert-bg-default, var(--moduix-color-card)));
    color: var(
      --moduix-alert-color,
      var(--_alert-color-default, var(--moduix-color-card-foreground))
    );
    box-shadow: var(--moduix-alert-shadow, none);
    --_alert-bg-default: var(--moduix-alert-info-bg, var(--moduix-color-card));
    --_alert-border-color-default: var(
      --moduix-alert-info-border-color,
      var(--moduix-color-border)
    );
    --_alert-color-default: var(--moduix-alert-info-color, var(--moduix-color-card-foreground));
    --_alert-indicator-color-default: var(
      --moduix-alert-info-indicator-color,
      var(--moduix-color-muted-foreground)
    );

    &[data-status='success'] {
      --_alert-bg-default: var(
        --moduix-alert-success-bg,
        color-mix(in oklab, var(--moduix-color-success) 10%, var(--moduix-color-background))
      );
      --_alert-border-color-default: var(
        --moduix-alert-success-border-color,
        color-mix(in oklab, var(--moduix-color-success) 34%, transparent)
      );
      --_alert-color-default: var(--moduix-alert-success-color, var(--moduix-color-foreground));
      --_alert-indicator-color-default: var(
        --moduix-alert-success-indicator-color,
        var(--moduix-color-success)
      );
    }

    &[data-status='warning'] {
      --_alert-bg-default: var(
        --moduix-alert-warning-bg,
        color-mix(in oklab, var(--moduix-color-warning) 13%, var(--moduix-color-background))
      );
      --_alert-border-color-default: var(
        --moduix-alert-warning-border-color,
        color-mix(in oklab, var(--moduix-color-warning) 38%, transparent)
      );
      --_alert-color-default: var(--moduix-alert-warning-color, var(--moduix-color-foreground));
      --_alert-indicator-color-default: var(
        --moduix-alert-warning-indicator-color,
        var(--moduix-color-warning)
      );
    }

    &[data-status='error'] {
      --_alert-bg-default: var(
        --moduix-alert-error-bg,
        color-mix(in oklab, var(--moduix-color-destructive) 9%, var(--moduix-color-background))
      );
      --_alert-border-color-default: var(
        --moduix-alert-error-border-color,
        color-mix(in oklab, var(--moduix-color-destructive) 35%, transparent)
      );
      --_alert-color-default: var(--moduix-alert-error-color, var(--moduix-color-foreground));
      --_alert-indicator-color-default: var(
        --moduix-alert-error-indicator-color,
        var(--moduix-color-destructive)
      );
    }
  }

  .indicator {
    display: inline-flex;
    width: var(--moduix-alert-indicator-size, var(--moduix-spacing-4));
    height: var(--moduix-alert-indicator-size, var(--moduix-spacing-4));
    align-items: center;
    justify-content: center;
    color: var(--moduix-alert-indicator-color, var(--_alert-indicator-color-default, currentColor));
    margin-block-start: var(--moduix-alert-indicator-offset, var(--moduix-spacing-0-5));

    & :where(svg) {
      width: var(--moduix-alert-indicator-size, var(--moduix-spacing-4));
      height: var(--moduix-alert-indicator-size, var(--moduix-spacing-4));
      flex-shrink: 0;
      pointer-events: none;
    }
  }

  .content {
    display: grid;
    flex: 1;
    min-width: 0;
    gap: var(--moduix-alert-content-gap, var(--moduix-spacing-1));
  }

  .title {
    margin: 0;
    min-width: 0;
    color: var(--moduix-alert-title-color, var(--moduix-alert-color, var(--_alert-color-default)));
    font-size: var(--moduix-alert-title-font-size, var(--moduix-text-sm));
    font-weight: var(--moduix-alert-title-font-weight, var(--moduix-weight-semibold));
    line-height: var(--moduix-alert-title-line-height, var(--moduix-line-height-text-sm));
    overflow-wrap: anywhere;
  }

  .description {
    min-width: 0;
    color: var(--moduix-alert-description-color, var(--moduix-color-muted-foreground));
    font-size: var(--moduix-alert-description-font-size, var(--moduix-text-sm));
    line-height: var(--moduix-alert-description-line-height, var(--moduix-line-height-text-sm));
    overflow-wrap: anywhere;

    & > :first-child {
      margin-block-start: 0;
    }

    & > :last-child {
      margin-bottom: 0;
    }
  }

  .actions {
    display: flex;
    flex-wrap: wrap;
    margin-block-start: var(--moduix-alert-actions-margin-top, var(--moduix-spacing-2));
    gap: var(--moduix-alert-actions-gap, var(--moduix-spacing-2));
  }
}
src/components/alert/index.ts
export * from './Alert.js';

More from moduix-react

Browse all components in this library →