I'm working on a simple personal site and want to have a reusable <Link> component that has some styling as well as certain attribute defaults.
I want to essentially be able to do <Link href="/about">About</Link> or <Link href="https://github.com/Ethan-Arrowood">@Ethan-Arrowood</Link> .
So I've created:
---
const { href, target="_blank", rel="noreferrer" } = Astro.props;
---
<style>
a {
color: var(--accent);
position: relative;
text-decoration: none;
}
a::after {
content: '';
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: var(--accent);
transform: scaleX(0);
transform-origin: bottom right;
transition: transform 0.3s ease-in;
}
a:hover::after {
transform: scaleX(1);
transform-origin: bottom left;
}
</style>
<a href={href} target={target} rel={rel}>
<slot />
</a>
And now I'm trying to figure out the types...
This is an okay start
type Props = Partial<HTMLAnchorElement> & Pick<HTMLAnchorElement, 'href'>;
But then I get the error:
'Link' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'HTMLCollection | undefined'.ts(2747)
When I use it as:
<Link href="/about">About</Link>
I've tried adding on & { children: string } , but that creates a new ts error:
This JSX tag's 'children' prop expects type 'HTMLCollection & string' which requires multiple children, but only a single child was provided.ts(2745)
What is the solution here?
I thought of maybe making the text into a prop itself, but I'd rather this act like a <a> element instead.