Alert
A hand-drawn alert callout styled with shadcn conventions. Like Card, it can carry a paper texture.
Installation
npx shadcn@latest add https://sketchcn.chuwii.com/r/alert.jsonStyles
Alert leans on these rules from sketch.css. The shadcn CLI installs the file with sketch-provider; copying the component by hand means copying them too.
@keyframes sketch-icon-wiggle {
0%,
100% {
transform: rotate(-5deg);
}
50% {
transform: rotate(5deg);
}
}
[data-paper]:not([data-paper="default"])::before,
[data-slot="card"][data-variant]:not([data-variant="default"])::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background-color: var(--paper-pattern);
opacity: var(--paper-opacity, 0.4);
mask-image: var(--paper-image);
-webkit-mask-image: var(--paper-image);
mask-repeat: repeat;
-webkit-mask-repeat: repeat;
}Read the whole file for the drawing variables, paper textures and reduced-motion rules.
Usage
import { Info } from "@matita/icons/react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
export function FreshInk() {
return (
<Alert>
<Info />
<AlertTitle>Fresh ink</AlertTitle>
<AlertDescription>No two outlines match.</AlertDescription>
</Alert>
);
}An svg as the first child becomes the leading icon and the grid switches to two columns automatically.
Parts
| Part | Description |
|---|---|
Alert | The outlined container with role="alert". |
AlertTitle | Heading line. |
AlertDescription | Supporting text. |
AlertAction | Pinned to the right edge, for a dismiss or undo control. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
paper | "default" | "polkadots" | "hexagons" | "graph" | "plus" | "filled-dots" | "default" | Paper texture drawn behind the content. |
variant is the standard default and destructive pair; destructive tints the drawn border along with the text.
Examples
Release note
import { Info } from "@matita/icons/react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
export function ReleaseNote() {
return (
<Alert>
<Info />
<AlertTitle>Sketchcn 1.2 is out</AlertTitle>
<AlertDescription>
Alerts now draw their own outline with RoughJS.
</AlertDescription>
</Alert>
);
}Upload error
import { TriangleAlert } from "@matita/icons/react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
export function UploadError() {
return (
<Alert variant="destructive">
<TriangleAlert />
<AlertTitle>Upload failed</AlertTitle>
<AlertDescription>
The file is larger than the 5 MB limit.
</AlertDescription>
</Alert>
);
}With action
import { CircleCheck } from "@matita/icons/react";
import {
Alert,
AlertAction,
AlertDescription,
AlertTitle,
} from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
export function DraftSaved() {
return (
<Alert>
<CircleCheck />
<AlertTitle>Draft saved</AlertTitle>
<AlertDescription>You can keep sketching from any device.</AlertDescription>
<AlertAction>
<Button size="xs" variant="ghost">
Undo
</Button>
</AlertAction>
</Alert>
);
}Paper texture
import { TriangleAlert } from "@matita/icons/react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
export function MaintenanceNotice() {
return (
<Alert paper="graph" variant="destructive">
<TriangleAlert />
<AlertTitle>Scheduled maintenance</AlertTitle>
<AlertDescription>
Sketches are read-only until 18:00.
</AlertDescription>
</Alert>
);
}Steadier outline
import { Alert, AlertTitle } from "@/components/ui/alert";
export function CalmAlert() {
return (
<Alert className="[--sketch-roughness:0.4] [--sketch-bowing:0.6]">
<AlertTitle>A steadier hand drew this one</AlertTitle>
</Alert>
);
}Animation
Hovering the alert wiggles its leading icon with the sketch-icon-wiggle keyframe from sketch.css.
"hover:*:[svg:not([data-sketch-outline])]:animate-[sketch-icon-wiggle_180ms_ease-in-out_infinite] motion-reduce:hover:*:[svg:not([data-sketch-outline])]:animate-none"The paper texture is drawn through data-paper, so --paper-pattern and --paper-opacity tune it. Alert already lowers the opacity to keep the text readable.
<Alert paper="graph" className="[--paper-opacity:0.4]">
<AlertTitle>Denser paper</AlertTitle>
</Alert>