Skip to content

Commit

Permalink
feat(Link): allow to pass all corresponding html props
Browse files Browse the repository at this point in the history
  • Loading branch information
amje committed May 20, 2024
1 parent 0aec983 commit 4ccdea4
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 123 deletions.
68 changes: 34 additions & 34 deletions src/components/Link/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import React from 'react';

import type {DOMProps, QAProps} from '../types';
import type {QAProps} from '../types';
import {block} from '../utils/cn';
import {eventBroker} from '../utils/event-broker';

import './Link.scss';

export type LinkView = 'normal' | 'primary' | 'secondary';

export interface LinkProps extends DOMProps, QAProps {
export interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement>, QAProps {
view?: LinkView;
visitable?: boolean;
title?: string;
href: string;
target?: string;
rel?: string;
id?: string;
children?: React.ReactNode;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
onFocus?: React.FocusEventHandler<HTMLAnchorElement>;
onBlur?: React.FocusEventHandler<HTMLAnchorElement>;
/**
* @deprecated
*/
extraProps?: React.AnchorHTMLAttributes<HTMLAnchorElement>;
}

Expand All @@ -31,44 +26,49 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link
visitable,
href,
target,
rel,
title,
rel: relProp,
children,
extraProps,
onClick,
onFocus,
onBlur,
id,
style,
className,
qa,
onClickCapture,
className,
extraProps,
...restProps
},
ref,
) {
const handleClickCapture = React.useCallback((event: React.SyntheticEvent) => {
eventBroker.publish({
componentId: 'Link',
eventId: 'click',
domEvent: event,
});
}, []);
const handleClickCapture = React.useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => {
eventBroker.publish({
componentId: 'Link',
eventId: 'click',
domEvent: event,
});

if (onClickCapture) {
onClickCapture(event);
}
},
[onClickCapture],
);

const commonProps = {
title,
onClick,
onClickCapture: handleClickCapture,
onFocus,
onBlur,
id,
style,
className: b({view, visitable}, className),
'data-qa': qa,
};

const relProp = target === '_blank' && !rel ? 'noopener noreferrer' : rel;
const rel = target === '_blank' && !relProp ? 'noopener noreferrer' : relProp;

return (
<a {...extraProps} {...commonProps} ref={ref} href={href} target={target} rel={relProp}>
<a
{...commonProps}
ref={ref}
href={href}
target={target}
rel={rel}
{...restProps}
{...extraProps}
>
{children}
</a>
);
Expand Down
27 changes: 9 additions & 18 deletions src/components/Link/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,21 +167,12 @@ LANDING_BLOCK-->

## Properties

| Name | Description | Type | Default |
| :--------- | :----------------------------------------- | :-------------------------------------------------------: | :--------: |
| view | Link appearance | `"normal" \| "primary" \| "secondary"` | `"normal"` |
| visitable | Display `:visitable` CSS state | `boolean \| undefined` |
| href | HTML `href` attribute | `string` |
| target | HTML `target` attribute | `string \| undefined` |
| rel | HTML `rel` attribute | `string \| undefined` |
| title | HTML `title` attribute | `string \| undefined` |
| children | Link content | `React.ReactNode` |
| extraProps | Any additional props | `Record \| undefined` |
| onClick | `click` event handler | `React.MouseEventHandler<HTMLAnchorElement> \| undefined` |
| onFocus | `focus` event handler | `React.FocusEventHandler<HTMLAnchorElement> \| undefined` |
| onBlur | `blur` event handler | `React.FocusEventHandler<HTMLAnchorElement> \| undefined` |
| id | HTML `id` attribute | `string \| undefined` |
| style | HTML `style` attribute | `React.CSSProperties \| undefined` |
| className | HTML `class` attribute | `string \| undefined` |
| qa | HTML `data-qa` attribute, used for testing | `string \| undefined` |
| ref | React ref to Link DOM node | `React.ForwardedRef<HTMLAnchorElement> \| undefined` |
`LinkProps` extends `React.HTMLAnchorElement`.

| Name | Description | Type | Default |
| :-------- | :----------------------------------------- | :----------------------------------: | :--------: |
| children | Link content | `React.ReactNode` | |
| href | HTML `href` attribute | `string` | |
| qa | HTML `data-qa` attribute, used for testing | `string` | |
| view | Link appearance | `"normal"` `"primary"` `"secondary"` | `"normal"` |
| visitable | Display `:visitable` CSS state | `boolean` | |
63 changes: 0 additions & 63 deletions src/components/Link/__stories__/Link.new.stories.tsx

This file was deleted.

40 changes: 32 additions & 8 deletions src/components/Link/__stories__/Link.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';

import type {Meta, StoryFn} from '@storybook/react';
import type {Meta, StoryObj} from '@storybook/react';

import {Showcase} from '../../../demo/Showcase';
import {Link} from '../Link';
import type {LinkProps} from '../Link';
import {LinkShowcase} from '../__stories__/LinkShowcase';

export default {
title: 'Components/Navigation/Link',
Expand All @@ -22,10 +21,35 @@ export default {
},
},
},
} as Meta;
} as Meta<typeof Link>;

const DefaultTemplate: StoryFn<LinkProps> = (args) => <Link {...args}>Link</Link>;
export const Default = DefaultTemplate.bind({});
type Story = StoryObj<typeof Link>;

const ShowcaseTemplate: StoryFn = () => <LinkShowcase />;
export const Showcase = ShowcaseTemplate.bind({});
export const Default: Story = {args: {href: '#', children: 'Link'}};

export const View: Story = {
args: {
...Default.args,
},
render: (args) => (
<Showcase>
<Link {...args} view="normal">
Normal
</Link>
<Link {...args} view="primary">
Primary
</Link>
<Link {...args} view="secondary">
Secondary
</Link>
</Showcase>
),
};

export const Visitable = {
args: {
...Default.args,
visitable: true,
href: '.',
},
};

0 comments on commit 4ccdea4

Please sign in to comment.