Benjamin Read's code garden.

Polymorphic Elements in Astro

Published on

This article is about: javascriptastro

I’m building a component library in Astro, and one of the things I needed to do was to build a component that could render as either a button or an anchor tag. Here’s an example of the outcome I wanted to achieve:


 // renders an <a> tag
<Button href="https://some-link">This is an anchor tag</Button>
 // renders a <button> tag
<Button type="button">Submit</Button>

With Astro you’re writing the best parts of JSX there could be;  for example, there are no abstraction leaks like having to add `key`s to iterables. But also what you’re writing is very obviously much closer to HTML than JSX is, there not being a virtual DOM, or styled components, so this puzzled me for a while. I could either have 2 components and duplicate my styles, or find a way to render either depending on the use case.

Thankfully with some clever prop handling, we can have the best of both worlds:

// button.astro

const { href } = Astro.props

---
<>
  {
    href ? (
      <a href={href}><slot /></a>
    ) : (
      <button
        type="button"
      >
        <slot />
      </button>
    )
  }
</>

With this code, the default output is a

Read more articles about: javascriptastro

Comments

No comments yet. Be the first to comment!


“Wisest are they who know they do not know.”

— Jostein Gaarder