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 · lightui-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';