Delightful Astro components
Astro components come in many shapes and sizes. This is one of my favourites.
The following <Example />
component has some interesting properties.
---
import { HTMLTag, Polymorphic } from "astro/types";
import { twMerge } from "tailwind-merge";
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>;
const { as: Tag = "div", class: classes, ...props } = Astro.props;
---
<Tag class={twMerge("mx-auto max-w-2xl", classes)} {...props}>
<slot />
</Tag>
- The outermost tag name can be customised
- The properties passed must conform to the corresponding tag
- Incoming Tailwind classes are merged intelligently with the list of omnipresent classes
- All remaining attributes are passed along
With a simple <Example />
we get the following HTML:
<div class="mx-auto max-w-2xl"></div>
And when we need to get a little more fancy passing in classes, a tag name, and some additional attributes:
<Example as="article" class="text-lg text-red-500" data-feeling="fabulous">
<p>And just for good measure!</p>
</Example>
Astro will kindly generate us some appropriate HTML.
<article class="mx-auto max-w-2xl text-lg text-red-500" data-feeling="fabulous">
<p>And just for good measure!</p>
</article>
The type annotations here aren’t particularly interesting, but once you have your own properties to pass around, they begin to shine.
interface Props extends HTMLAttributes<"a"> {
title: string;
description?: string;
}