diff options
| author | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
|---|---|---|
| committer | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
| commit | d41eff9eccf66644c4c60f53cb516bf079937a28 (patch) | |
| tree | 248a0863a3181369f943d678ec4273911d35efac /src/components/Callout.astro | |
Using astro-erudite for static site generation
Diffstat (limited to 'src/components/Callout.astro')
| -rw-r--r-- | src/components/Callout.astro | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/components/Callout.astro b/src/components/Callout.astro new file mode 100644 index 0000000..98ef07d --- /dev/null +++ b/src/components/Callout.astro @@ -0,0 +1,183 @@ +--- +import { cn } from '@/lib/utils' +import { Icon } from 'astro-icon/components' +import { cva, type VariantProps } from 'class-variance-authority' + +const calloutConfig = { + note: { + style: 'border-blue-500 dark:bg-blue-950/5', + textColor: 'text-blue-700 dark:text-blue-300', + icon: 'lucide:info', + }, + tip: { + style: 'border-green-500 dark:bg-green-950/5', + textColor: 'text-green-700 dark:text-green-300', + icon: 'lucide:lightbulb', + }, + warning: { + style: 'border-amber-500 dark:bg-amber-950/5', + textColor: 'text-amber-700 dark:text-amber-300', + icon: 'lucide:alert-triangle', + }, + danger: { + style: 'border-red-500 dark:bg-red-950/5', + textColor: 'text-red-700 dark:text-red-300', + icon: 'lucide:shield-alert', + }, + important: { + style: 'border-purple-500 dark:bg-purple-950/5', + textColor: 'text-purple-700 dark:text-purple-300', + icon: 'lucide:message-square-warning', + }, + definition: { + style: 'border-purple-500 dark:bg-purple-950/5', + textColor: 'text-purple-700 dark:text-purple-300', + icon: 'lucide:book-open', + }, + theorem: { + style: 'border-teal-500 dark:bg-teal-950/5', + textColor: 'text-teal-700 dark:text-teal-300', + icon: 'lucide:check-circle', + }, + lemma: { + style: 'border-sky-400 dark:bg-sky-950/5', + textColor: 'text-sky-700 dark:text-sky-300', + icon: 'lucide:puzzle', + }, + proof: { + style: 'border-gray-500 dark:bg-gray-950/5', + textColor: 'text-gray-700 dark:text-gray-300', + icon: 'lucide:check-square', + }, + corollary: { + style: 'border-cyan-500 dark:bg-cyan-950/5', + textColor: 'text-cyan-700 dark:text-cyan-300', + icon: 'lucide:git-branch', + }, + proposition: { + style: 'border-slate-500 dark:bg-slate-950/5', + textColor: 'text-slate-700 dark:text-slate-300', + icon: 'lucide:file-text', + }, + axiom: { + style: 'border-violet-600 dark:bg-violet-950/5', + textColor: 'text-violet-700 dark:text-violet-300', + icon: 'lucide:anchor', + }, + conjecture: { + style: 'border-pink-500 dark:bg-pink-950/5', + textColor: 'text-pink-700 dark:text-pink-300', + icon: 'lucide:help-circle', + }, + notation: { + style: 'border-slate-400 dark:bg-slate-950/5', + textColor: 'text-slate-700 dark:text-slate-300', + icon: 'lucide:pen-tool', + }, + remark: { + style: 'border-gray-400 dark:bg-gray-950/5', + textColor: 'text-gray-700 dark:text-gray-300', + icon: 'lucide:message-circle', + }, + intuition: { + style: 'border-yellow-500 dark:bg-yellow-950/5', + textColor: 'text-yellow-700 dark:text-yellow-300', + icon: 'lucide:lightbulb', + }, + recall: { + style: 'border-blue-300 dark:bg-blue-950/5', + textColor: 'text-blue-600 dark:text-blue-300', + icon: 'lucide:rotate-ccw', + }, + explanation: { + style: 'border-lime-500 dark:bg-lime-950/5', + textColor: 'text-lime-700 dark:text-lime-300', + icon: 'lucide:help-circle', + }, + example: { + style: 'border-emerald-500 dark:bg-emerald-950/5', + textColor: 'text-emerald-700 dark:text-emerald-300', + icon: 'lucide:code', + }, + exercise: { + style: 'border-indigo-500 dark:bg-indigo-950/5', + textColor: 'text-indigo-700 dark:text-indigo-300', + icon: 'lucide:dumbbell', + }, + problem: { + style: 'border-orange-600 dark:bg-orange-950/5', + textColor: 'text-orange-700 dark:text-orange-300', + icon: 'lucide:alert-circle', + }, + answer: { + style: 'border-teal-500 dark:bg-teal-950/5', + textColor: 'text-teal-700 dark:text-teal-300', + icon: 'lucide:check', + }, + solution: { + style: 'border-emerald-600 dark:bg-emerald-950/5', + textColor: 'text-emerald-700 dark:text-emerald-300', + icon: 'lucide:check-circle-2', + }, + summary: { + style: 'border-sky-500 dark:bg-sky-950/5', + textColor: 'text-sky-700 dark:text-sky-300', + icon: 'lucide:list', + }, +} as const + +const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1) + +const calloutVariants = cva('relative px-4 py-3 my-6 border-l-4 text-sm', { + variants: { + variant: Object.fromEntries( + Object.entries(calloutConfig).map(([key, config]) => [key, config.style]), + ), + }, + defaultVariants: { + variant: 'note', + }, +}) + +interface Props extends VariantProps<typeof calloutVariants> { + title?: string + class?: string + variant?: keyof typeof calloutConfig + defaultOpen?: boolean +} + +const { title, variant = 'note', defaultOpen = true, ...rest } = Astro.props +--- + +<details + class={cn( + calloutVariants({ variant }), + rest.class, + '[&[open]>summary_svg:last-child]:rotate-180 [&[open]>summary]:mb-3', + )} + {...rest} + open={defaultOpen} +> + <summary + class="flex cursor-pointer items-center font-medium [&::-webkit-details-marker]:hidden" + > + <Icon + name={calloutConfig[variant].icon} + class={cn('mr-2 size-4 shrink-0', calloutConfig[variant].textColor)} + /> + <span class={cn('font-medium mr-2', calloutConfig[variant].textColor)}> + {capitalize(variant)} + {title && <span class="font-normal opacity-70"> ({title})</span>} + </span> + <Icon + name="lucide:chevron-down" + class={cn( + 'ml-auto h-4 w-4 shrink-0 transition-transform duration-200', + calloutConfig[variant].textColor, + )} + /> + </summary> + <div> + <slot /> + </div> +</details> |
