Alert
A short message that draws attention, with an optional icon.
Plain HTML
Success! Your changes have been saved
This is an alert with an icon, a title and a description.
Unable to process your payment.
Please verify your billing information and try again.
<script lang="ts">
import * as Alert from '#lib/components/ui/alert/index.js';
</script>
<div class="stack">
<Alert.Root>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="12" cy="12" r="10" />
<path d="m9 12 2 2 4-4" />
</svg>
<Alert.Title>Success! Your changes have been saved</Alert.Title>
<Alert.Description>This is an alert with an icon, a title and a description.</Alert.Description>
</Alert.Root>
<Alert.Root variant="destructive">
<Alert.Title>Unable to process your payment.</Alert.Title>
<Alert.Description>Please verify your billing information and try again.</Alert.Description>
</Alert.Root>
</div>
<style>
.stack {
display: grid;
gap: var(--dui-space-3);
}
</style>
Installation
npx distill-ui add alert- Set up the tokens once, if you haven't: see manual installation.
- Copy these files into your project:
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
</script>
<div {...restProps} class={['description', className]}>
{@render children?.()}
</div>
<style>
.description {
grid-column: -2;
/* Slightly softer than the title; inherits the destructive color in that variant. */
color: color-mix(in oklch, currentColor 85%, transparent);
text-wrap: pretty;
}
</style>
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
</script>
<div {...restProps} class={['title', className]}>
{@render children?.()}
</div>
<style>
.title {
/* The last column, whether or not the alert has an icon. */
grid-column: -2;
font-weight: var(--dui-font-weight-medium);
}
</style>
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
variant = 'default',
class: className,
children,
...restProps
}: HTMLAttributes<HTMLDivElement> & {
ref?: HTMLDivElement | null;
variant?: 'default' | 'destructive';
} = $props();
</script>
<div
{...restProps}
bind:this={ref}
role="alert"
class={['alert', className]}
data-variant={variant}
>
{@render children?.()}
</div>
<!--
Options you can set from a parent or on the alert itself:
--dui-alert-border, --dui-alert-radius, --dui-alert-bg, --dui-alert-fg
-->
<style>
.alert {
position: relative;
display: grid;
grid-template-columns: 1fr;
row-gap: var(--dui-space-0-5);
width: 100%;
padding: var(--dui-space-3) var(--dui-space-4);
border: 1px solid var(--dui-alert-border, var(--dui-color-border));
border-radius: var(--dui-alert-radius, var(--dui-radius-lg));
background: var(--dui-alert-bg, var(--dui-color-card));
color: var(--dui-alert-fg, var(--dui-color-card-foreground));
font-size: var(--dui-text-sm);
line-height: var(--dui-text-sm-line-height);
/* An optional icon passed as the first child gets its own column. */
&:has(> :global(svg)) {
grid-template-columns: auto 1fr;
column-gap: var(--dui-space-2-5);
}
& > :global(svg) {
grid-row: span 2;
width: 1rem;
height: 1rem;
translate: 0 0.125rem;
color: currentColor;
}
}
.alert[data-variant='destructive'] {
/* Pulled toward the foreground so the text passes AA contrast, as in Button. */
color: var(
--dui-alert-fg,
color-mix(in oklch, var(--dui-color-destructive) 80%, var(--dui-color-foreground))
);
}
</style>
import Description from './alert-description.svelte';
import Title from './alert-title.svelte';
import Root from './alert.svelte';
export { Root, Title, Description };
Customizing
Set any of these on the component or on a parent element. See Customizing for how they work.
| Custom property | Default |
|---|---|
--dui-alert-border | var(--dui-color-border) |
--dui-alert-radius | var(--dui-radius-lg) |
--dui-alert-bg | var(--dui-color-card) |
--dui-alert-fg | var(--dui-color-card-foreground) |