creativetimofficial / material-tailwind

@material-tailwind is an easy-to-use components library for Tailwind CSS and Material Design.
https://material-tailwind.com/
MIT License
3.51k stars 307 forks source link

Feature Request for button "as" prop. <Button as={Link} ...> and documentation bug #531

Open don-esteban opened 6 months ago

don-esteban commented 6 months ago

Hi all,

many libraries offer link buttons. In other words, links <a> styled as buttons.

Material Tailwind recommends nesting <Button> inside <a> resulting in invalid HTML. So, this should be fixed (removed?) in the docs. This leads to my feature request.

We need another aproach. A simple and clean solution could introduce an as prop, similar the as prop in <Typography> and in other libs/frameworks like Headless UI. We could use it like this

<Button as="a" ...>

or with components like this (important for Next.js apps)

<Button as={Link} ...>

The only work around I came up is using the <Button> with JavaScript in the onClick handler and role link. This works, but can cause accessibility issues in some cases.

<Button onClick={() => location.href='my-url'} role="link" ..>

In Next.js we should use the useRouter hook for prefetching.

...
const router = useRouter()
...
return (<Button onClick={() => router.push('my-url')} role="link">...)
...

Caveats (work around)

See too

In addition, see this issue #448

YassBaer commented 6 months ago

I'd like to add that I like the asChild-Prop on Radix UI Primitives a lot. It solves the same issue, allows the Child to be anything and is more readable imo than passing the Component as a Prop.

don-esteban commented 6 months ago

I'd like to add that I like the asChild-Prop on Radix UI Primitives a lot. It solves the same issue, allows the Child to be anything and is more readable imo than passing the Component as a Prop.

Yes, that‘s nice too. But Material Tailwind uses the as-prop-approach already (Typography for example). Probably they prefer to stick with one pattern.