Skip to content

Commit

Permalink
Add ExternalLink.stories.tsx
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadorequest committed Jan 15, 2021
1 parent cf96ee5 commit 7b975c8
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 13 deletions.
65 changes: 52 additions & 13 deletions src/components/utils/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,79 @@
import React, { Fragment } from 'react';
import { ReactLinkProps } from '../../types/react/ReactLinkProps';

type Props = {
export type Props = {
/**
* React children, usually text.
*/
children: React.ReactNode;

/**
* CSS classes.
*/
className?: string;

/**
* The path or URL to navigate to.
*/
href: string;
id?: string;

/**
* Tell bots not to follow the link when crawling (you may want to disable this depending on your use case).
*
* @default true
*/
nofollow?: boolean;

/**
* Security, avoids external site opened through your site to have control over your site (always apply "noopener" unless you know what you're doing).
*
* @default true
*/
noopener?: boolean;

/**
* SEO, avoids external site opened through your site to know they have been opened from your site (don't apply "noreferrer" unless you know what you're doing).
*
* @default false
*/
noreferrer?: boolean;
onClick?: (any) => void;

/**
* Helper to avoid link to "stick" with text.
*
* @default " " (whitespace)
*/
prefix?: string;

/**
* Helper to avoid link to "stick" with text.
*
* @default " " (whitespace)
*/
suffix?: string;
}
} & Partial<ReactLinkProps>;

/**
* Link that point to an external website
*
* Use sane default for proper SEO (noreferrer disabled by default), security (nofollow enabled by default) and display (prefix/suffix)
* Link that point to an external website.
*
* @param props
* Use sane default for proper SEO (noreferrer disabled by default), security (nofollow enabled by default) and display (prefix/suffix).
*/
const ExternalLink: React.FunctionComponent<Props> = (props): JSX.Element => {
const {
children,
href,
nofollow = true, // Tell bots not to follow the link when crawling (you may want to disable this depending on your use case)
noopener = true, // Security, avoids external site opened through your site to have control over your site (always apply "noopener" unless you know what you're doing)
noreferrer = false, // SEO, avoids external site opened through your site to know they have been opened from your site (don't apply "noreferrer" unless you know what you're doing)
prefix = ' ', // Helper to avoid link to "stick" with text
suffix = ' ', // Helper to avoid link to "stick" with text
nofollow = true,
noopener = true,
noreferrer = false,
prefix = ' ',
suffix = ' ',
...rest
} = props;

return (
<Fragment>
{prefix}
{/*// @ts-ignore*/}
<a
href={href}
target={'_blank'} // eslint-disable-line react/jsx-no-target-blank
Expand Down
42 changes: 42 additions & 0 deletions src/stories/nrn/form/ExternalLink.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Meta,
Story,
} from '@storybook/react/types-6-0';
import React from 'react';
import ExternalLink, { Props } from '../../../components/utils/ExternalLink';
import withChildrenMock from '../../shared/hocs/withChildrenMock';

type PropsWithChildrenMock = Props & {
text?: string;
};

export default {
title: 'Next Right Now/Form/ExternalLink',
component: ExternalLink,
argTypes: withChildrenMock({}),
} as Meta;

const Template: Story<PropsWithChildrenMock> = (props) => {
const { text } = props;

return (
// @ts-ignore
<ExternalLink
{...props}
onClick={(): void => console.info('Click')}
>
{text || 'Default text'}
</ExternalLink>
);
};

export const DynamicExample: Story<PropsWithChildrenMock> = Template.bind({});
DynamicExample.args = {
text: 'Open (another tab)',
href: '/',
nofollow: true,
noopener: true,
noreferrer: false,
prefix: ' ',
suffix: ' ',
};
14 changes: 14 additions & 0 deletions src/types/react/ReactLinkProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
ButtonHTMLAttributes,
DetailedHTMLProps,
} from 'react';

/**
* React HTML "Link" element properties.
* Meant to be a helper when using custom buttons that should inherit native "<a>" properties.
*
* @example type MyLinkProps = {
* href?: string;
* } & ReactLinkProps;
*/
export type ReactLinkProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLLinkElement>, HTMLLinkElement>;

1 comment on commit 7b975c8

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.