Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support NextLink and other custom link components #2004

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface ButtonProps extends DOMProps, QAProps {
type?: 'button' | 'submit' | 'reset';
component?: React.ElementType;
href?: string;
hrefComponent?: React.ElementType;
target?: string;
rel?: string;
extraProps?:
Expand Down Expand Up @@ -80,6 +81,7 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
type = 'button',
component,
href,
hrefComponent,
target,
rel,
extraProps,
Expand Down Expand Up @@ -137,14 +139,17 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
'data-qa': qa,
};

if (typeof href === 'string' || component) {
if (href || component) {
const linkProps = {
href,
target,
rel: target === '_blank' && !rel ? 'noopener noreferrer' : rel,
};

const LinkComponent = hrefComponent || 'a';

return React.createElement(
component || 'a',
component || LinkComponent,
{
...extraProps,
...commonProps,
Expand Down
86 changes: 59 additions & 27 deletions src/components/Button/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,35 +446,67 @@ LANDING_BLOCK-->

<!--/GITHUB_BLOCK-->

## Next.js
By default, the `<Button />` component renders an `<a>` tag for links.

To use the Next.js `<Link />` component, pass it to the `hrefComponent` prop when rendering the `<Button />`.
<!--LANDING_BLOCK

<ExampleBlock
background='rgb(68, 38, 204)'
code={`
import NextLink from 'next/link';

<Button href="#" hrefComponent={NextLink}>NextJS Link</Button>
`}
>
<UIKit.Button view="normal-contrast" size="l">Normal Contrast</UIKit.Button>
<UIKit.Button view="outlined-contrast" size="l">Outlined Contrast</UIKit.Button>
<UIKit.Button view="flat-contrast" size="l">Flat Contrast</UIKit.Button>
</ExampleBlock>

LANDING_BLOCK-->

<!--GITHUB_BLOCK-->

```tsx
import NextLink from 'next/link';

<Button href="#" hrefComponent={NextLink}>NextJS Link</Button>
```

<!--/GITHUB_BLOCK-->

## Properties

| Name | Description | Type | Default |
| :----------- | :----------------------------------------------------------------- | :-----------------------------: | :-------------: |
| children | Button content. You can use both text and the `<Icon/>` component. | `ReactNode` | |
| className | `class` HTML attribute | `string` | |
| component | Overrides the root component | `ElementType<any>` | `"button"` |
| disabled | Toggles the `disabled` state | `false` | `false` |
| extraProps | Additional properties | `Record` | |
| href | `href` HTML attribute | `string` | |
| id | `id` HTML attribute | `string` | |
| loading | Toggles the `loading` state | `false` | `false` |
| onBlur | `blur` event handler | `Function` | |
| onClick | `click` event handler | `Function` | |
| onFocus | `focus` event handler | `Function` | |
| onMouseEnter | `mouseenter` event handler | `Function` | |
| onMouseLeave | `mouseleave` event handler | `Function` | |
| pin | Sets the button edge style | `string` | `"round-round"` |
| qa | `data-qa` HTML attribute, used for testing | `string` | |
| rel | `rel` HTML attribute | `string` | |
| selected | Toggles the `selected` state | | |
| size | Sets the button size | `string` | `"m"` |
| style | `style` HTML attribute | `React.CSSProperties` | |
| tabIndex | `tabIndex` HTML attribute | `number` | |
| target | `target` HTML attribute | `string` | |
| title | `title` HTML attribute | `string` | |
| type | `type` HTML attribute | `"button"` `"submit"` `"reset"` | `"button"` |
| view | Sets the button appearance | `string` | `"normal"` |
| width | `"auto"` `"max"` | `"auto"` `"max"` | |
| Name | Description | Type | Default |
| :------------ | :----------------------------------------------------------------- | :-----------------------------: | :-------------: |
| children | Button content. You can use both text and the `<Icon/>` component. | `ReactNode` | |
| className | `class` HTML attribute | `string` | |
| component | Overrides the root component | `ElementType<any>` | `"button"` |
| disabled | Toggles the `disabled` state | `false` | `false` |
| extraProps | Additional properties | `Record` | |
| href | `href` HTML attribute | `string` | |
| hrefComponent | Sets the custom link component for the button | `React.ElementType` | `"<a>"` |
| id | `id` HTML attribute | `string` | |
| loading | Toggles the `loading` state | `false` | `false` |
| onBlur | `blur` event handler | `Function` | |
| onClick | `click` event handler | `Function` | |
| onFocus | `focus` event handler | `Function` | |
| onMouseEnter | `mouseenter` event handler | `Function` | |
| onMouseLeave | `mouseleave` event handler | `Function` | |
| pin | Sets the button edge style | `string` | `"round-round"` |
| qa | `data-qa` HTML attribute, used for testing | `string` | |
| rel | `rel` HTML attribute | `string` | |
| selected | Toggles the `selected` state | | |
| size | Sets the button size | `string` | `"m"` |
| style | `style` HTML attribute | `React.CSSProperties` | |
| tabIndex | `tabIndex` HTML attribute | `number` | |
| target | `target` HTML attribute | `string` | |
| title | `title` HTML attribute | `string` | |
| type | `type` HTML attribute | `"button"` `"submit"` `"reset"` | `"button"` |
| view | Sets the button appearance | `string` | `"normal"` |
| width | `"auto"` `"max"` | `"auto"` `"max"` | |

## CSS API

Expand Down