Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EditLink component Edit renders correctly 1`] = `
<div>
<div
class="edit"
>
<a
href="https://github.com/nodejs/nodejs.org/edit/major/website-redesign/pages/en/get-involved/contribute.md"
>
<span>
Edit this page on GitHub (English)
</span>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
</a>
</div>
</div>
`;

exports[`EditLink component Translate renders correctly 1`] = `
<div>
<div
class="edit"
>
<a
href="https://github.com/nodejs/nodejs.org/blob/major/website-redesign/TRANSLATION.md"
>
<span>
Interested to help with translations? (Non-English)
</span>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
Comment thread
ovflowd marked this conversation as resolved.
/>
</svg>
</a>
</div>
</div>
`;

exports[`EditLink component renders without a relative path 1`] = `<div />`;
69 changes: 69 additions & 0 deletions components/Article/EditLink/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { render, screen } from '@testing-library/react';
import EditLink from './../index';
import {
exampleAbsolutePath,
exampleEditPath,
exampleRelativePath,
i18nMockDataEnglish,
i18nMockDataNonEnglish,
} from './../mockDataConstants';
import { LocaleProvider } from './../../../../providers/localeProvider';

jest.mock('next/router', () => ({
useRouter: jest.fn().mockImplementation(() => ({
asPath: '',
})),
}));

describe('EditLink component', () => {
it('Edit renders correctly', () => {
const { container } = render(
<LocaleProvider i18nData={i18nMockDataEnglish}>
<EditLink relativePath={exampleRelativePath} />
</LocaleProvider>
);
expect(container).toMatchSnapshot();
});

it('Translate renders correctly', () => {
const { container } = render(
<LocaleProvider i18nData={i18nMockDataNonEnglish}>
<EditLink relativePath={exampleRelativePath} />
</LocaleProvider>
);
expect(container).toMatchSnapshot();
});

it('renders without a relative path', () => {
const { container } = render(
<LocaleProvider i18nData={i18nMockDataEnglish}>
<EditLink relativePath={undefined} />
</LocaleProvider>
);
expect(container).toMatchSnapshot();
});

it('produces correct relative path', () => {
render(
<LocaleProvider i18nData={i18nMockDataEnglish}>
<EditLink relativePath={exampleRelativePath} />
</LocaleProvider>
);
expect(screen.getByRole('link')).toHaveAttribute(
'href',
exampleAbsolutePath
);
});

it('produces correct edit path', () => {
render(
<LocaleProvider i18nData={i18nMockDataEnglish}>
<EditLink editPath={exampleEditPath} />
</LocaleProvider>
);
expect(screen.getByRole('link')).toHaveAttribute(
'href',
exampleAbsolutePath
);
});
});
30 changes: 30 additions & 0 deletions components/Article/EditLink/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.edit {
display: flex;
flex-wrap: wrap;
margin-top: var(--space-48);

a {
color: var(--color-text-secondary);
font-family: var(--sans-serif);
font-size: var(--font-size-body2);
font-weight: var(--font-weight-regular);
margin-left: 0;
text-decoration: none !important;
text-transform: uppercase;
vertical-align: middle;

span {
font-weight: var(--font-weight-regular);
vertical-align: middle;
}

&:hover {
color: var(--brand-light);
}

svg {
margin-left: 0.5rem;
vertical-align: middle;
}
}
}
41 changes: 41 additions & 0 deletions components/Article/EditLink/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
exampleRelativePath,
i18nMockDataEnglish,
i18nMockDataNonEnglish,
} from './mockDataConstants';
import { LocaleProvider } from '../../../providers/localeProvider';
import EditLink from './index';
import type { Meta as MetaObj, StoryObj } from '@storybook/react';

type Story = StoryObj<typeof EditLink>;
type Meta = MetaObj<typeof EditLink>;

export const Edit: Story = {
args: {
relativePath: exampleRelativePath,
},
decorators: [
Story => (
<LocaleProvider i18nData={i18nMockDataEnglish}>
<Story />
</LocaleProvider>
),
],
};

export const Translate: Story = {
args: {
relativePath: exampleRelativePath,
},
decorators: [
Story => (
<LocaleProvider i18nData={i18nMockDataNonEnglish}>
<Story />
</LocaleProvider>
),
],
};

export const Empty: Story = {};

export default { component: EditLink } as Meta;
74 changes: 74 additions & 0 deletions components/Article/EditLink/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { FaPencilAlt } from 'react-icons/fa';
import { FormattedMessage } from 'react-intl';
import styles from './index.module.scss';
import { useLocale } from './../../../hooks/useLocale';
import type { FC } from 'react';

type EditLinkProps = {
absolutePath?: string;
relativePath?: string;
editPath?: string;
};

// TODO(HinataKah0): Change branch from major/website-redesign to main

const baseEditURL =
'https://github.com/nodejs/nodejs.org/edit/major/website-redesign';

const translationReadmeURL =
'https://github.com/nodejs/nodejs.org/blob/major/website-redesign/TRANSLATION.md';

const translationKeyPrefix = 'components.article.editLink.title';

type EditLinkParams = {
translationKey: string;
href: string;
};

const getEditLinkParams = (
{ absolutePath, relativePath, editPath }: EditLinkProps,
lang: string
): EditLinkParams => {
if (lang === 'en') {
// Initial content development is done on GitHub in English
return {
translationKey: `${translationKeyPrefix}.edit`,
href:
absolutePath ||
(relativePath
? `${baseEditURL}/pages/en/${relativePath}`
: `${baseEditURL}/${editPath}`),
};
}

return {
translationKey: `${translationKeyPrefix}.translate`,
href: translationReadmeURL,
};
};

const EditLink: FC<EditLinkProps> = ({
absolutePath,
relativePath,
editPath,
}) => {
const { currentLocale } = useLocale();

if (!relativePath && !editPath && !absolutePath) return null;
Comment thread
ovflowd marked this conversation as resolved.
Outdated

const editLinkParams = getEditLinkParams(
{ absolutePath, relativePath, editPath },
currentLocale.code
);

return (
<div className={styles.edit}>
<a href={editLinkParams.href}>
<FormattedMessage id={editLinkParams.translationKey} tagName="span" />
<FaPencilAlt />
</a>
</div>
);
};

export default EditLink;
26 changes: 26 additions & 0 deletions components/Article/EditLink/mockDataConstants.tsx
Comment thread
ovflowd marked this conversation as resolved.
Outdated
Comment thread
ovflowd marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { AppProps } from '../../../types';

export const exampleAbsolutePath =
Comment thread
ovflowd marked this conversation as resolved.
Outdated
'https://github.com/nodejs/nodejs.org/edit/major/website-redesign/pages/en/get-involved/contribute.md';
export const exampleRelativePath = 'get-involved/contribute.md';
export const exampleEditPath = 'pages/en/get-involved/contribute.md';

export const i18nMockDataEnglish = {
currentLocale: {
code: 'en',
},
localeMessages: {
'components.article.editLink.title.edit':
'Edit this page on GitHub (English)',
},
} as unknown as AppProps['i18nData'];

export const i18nMockDataNonEnglish = {
currentLocale: {
code: 'xx',
},
localeMessages: {
'components.article.editLink.title.translate':
'Interested to help with translations? (Non-English)',
},
} as unknown as AppProps['i18nData'];
2 changes: 2 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,7 @@
"components.common.banner.button.text": "Read More",
"components.article.author.githubLinkLabel": "{username} Github - opens in new tab",
"components.article.authorList.title": "Article Authors",
"components.article.editLink.title.edit": "Edit this page on GitHub",
"components.article.editLink.title.translate": "Interested to help with translations?",
"components.common.languageSelector.button.title": "Switch Language"
}