Files
v10/site/src/components/Aside.astro
T

79 lines
1.8 KiB
Plaintext

---
import clsx from 'clsx';
import { Info, Lightbulb, OctagonX, TriangleAlert } from 'lucide-react';
import { twMerge } from '@/utils/twMerge';
type AsideType = 'note' | 'tip' | 'caution' | 'danger';
type Props = {
type: AsideType;
title?: string;
class?: string;
};
const { type, title, class: className } = Astro.props;
if (!['note', 'tip', 'caution', 'danger'].includes(type)) {
throw new Error(`Invalid aside type: ${type}`);
}
const icons: Record<AsideType, typeof Info> = {
note: Info,
tip: Lightbulb,
caution: TriangleAlert,
danger: OctagonX,
};
const defaultTitles: Record<AsideType, string> = {
note: 'Note',
tip: 'Tip',
caution: 'Caution',
danger: 'Danger',
};
const Icon = icons[type];
const renderTitle = title ?? defaultTitles[type];
---
<aside
class={twMerge(
clsx(
"mx-auto my-4 flex w-full max-w-3xl overflow-hidden rounded-xs border border-manila-75 dark:border-warm-gray",
),
className,
)}
>
<div
class={clsx(
"w-2 self-stretch",
type === "note" && "bg-magenta",
type === "tip" && "bg-magenta",
type === "caution" && "bg-orange",
type === "danger" && "bg-red",
)}
>
</div>
<div class={clsx("flex flex-1 gap-4 p-4 pl-4")}>
<div class="mt-0.75 shrink-0">
<Icon
size={18}
className={clsx(
clsx(
type === "note" && "text-magenta",
type === "tip" && "text-magenta",
type === "caution" && "text-orange",
type === "danger" && "text-red",
),
)}
/>
</div>
<div class="min-w-0 flex-1">
<p class="mb-2 font-bold">{renderTitle}</p>
<div class="[&>*:last-child]:mb-0! [&>.my-4]:my-2 [&>.my-8]:my-4">
<slot />
</div>
</div>
</div>
</aside>