flowbite-react icon indicating copy to clipboard operation
flowbite-react copied to clipboard

forwardRef for button component

Open hotrush opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe.

Seems it's not possible to use buttons with Link component at Next.js

import { Button } from 'flowbite-react'
import Link from 'next/link'

<Link href="/page" passHref>
  <Button>
    Go somewhere
  </Button>
</Link>

This code throws a warning

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Would be good to add forwardRef for button component to increase compatibility with next.js

Describe the solution you'd like Solution is described at docs https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-functional-component

hotrush avatar Aug 23 '22 20:08 hotrush

I'm wondering if this one can't be solved by implementing the as= component modifier.

What do you think @tulup-conner ?

rluders avatar Aug 24 '22 09:08 rluders

I had a look into the source code, and I guess in order to achieve this we would have to update this part

const Component = isLink ? 'a' : 'button';

and if is a button we need to add: ref={ref}

Here there is some more info on how to use this forwardRef

fs-innonova avatar Sep 22 '22 14:09 fs-innonova

There is a workaround using a HoC and copying displayName, defaultProps and propTypes with Object.assign.

import type { NextPage } from 'next';
import Link from 'next/link';
import { type FC, type ForwardedRef, forwardRef, LegacyRef } from 'react';
import { Button } from 'flowbite-react';

const withRef = <T, P = {}>(
    render: FC<P & { ref?: LegacyRef<T> | undefined }>
) =>
    Object.assign(
        forwardRef<T, P>((props, ref) => render({ ...props, ref })),
        render
    );

const ButtonWithRef = withRef(Button);

const Home: NextPage = () => {
    return (
        <Link href="/" passHref>
            <ButtonWithRef>Hello World</ButtonWithRef>
        </Link>
    );
};

export default Home;

@rluders If you want, I can provide a PR tomorrow to wrap the component with forwardRef.

myabeaver avatar Oct 16 '22 19:10 myabeaver