Refactor UI folder (#2016)

* Added Overview page

* Revised Getting Started page

* Minor revision

* Edited readme, minor modifications to docs

* Removed sweep.yaml, .devcontainer, .ergomake

* Moved security.md to .github, added contributing.md

* changes as per code review

* updated contributing.md

* fixed broken links & added missing links in doc, improved structure

* fixed link in wsl setup

* fixed server link, added https cloning in yarn-setup

* removed package-lock.json

* added doc card, admonitions

* removed underline from nav buttons

* refactoring modules/ui

* refactoring modules/ui

* Change folder case

* Fix theme location

* Fix case 2

* Fix storybook

---------

Co-authored-by: Nimra Ahmed <nimra1408@gmail.com>
Co-authored-by: Nimra Ahmed <50912134+nimraahmed@users.noreply.github.com>
This commit is contained in:
Charles Bochet
2023-10-14 00:04:29 +02:00
committed by GitHub
parent a35ea5e8f9
commit 258685467b
732 changed files with 1106 additions and 1010 deletions

View File

@ -0,0 +1,43 @@
import * as React from 'react';
import { Link as ReactLink } from 'react-router-dom';
import styled from '@emotion/styled';
type ContactLinkProps = {
className?: string;
href: string;
children?: React.ReactNode;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
};
const StyledClickable = styled.div`
display: flex;
overflow: hidden;
white-space: nowrap;
a {
color: inherit;
overflow: hidden;
text-decoration: underline;
text-decoration-color: ${({ theme }) => theme.border.color.strong};
text-overflow: ellipsis;
&:hover {
text-decoration-color: ${({ theme }) => theme.font.color.primary};
}
}
`;
export const ContactLink = ({
className,
href,
children,
onClick,
}: ContactLinkProps) => (
<div>
<StyledClickable className={className}>
<ReactLink target="_blank" onClick={onClick} to={href}>
{children}
</ReactLink>
</StyledClickable>
</div>
);

View File

@ -0,0 +1,37 @@
import * as React from 'react';
import { Link as ReactLink } from 'react-router-dom';
import styled from '@emotion/styled';
type RawLinkProps = {
className?: string;
href: string;
children?: React.ReactNode;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
};
const StyledClickable = styled.div`
display: flex;
overflow: hidden;
white-space: nowrap;
a {
color: inherit;
overflow: hidden;
text-overflow: ellipsis;
}
`;
export const RawLink = ({
className,
href,
children,
onClick,
}: RawLinkProps) => (
<div>
<StyledClickable className={className}>
<ReactLink target="_blank" onClick={onClick} to={href}>
{children}
</ReactLink>
</StyledClickable>
</div>
);

View File

@ -0,0 +1,41 @@
import * as React from 'react';
import { Link as ReactLink } from 'react-router-dom';
import styled from '@emotion/styled';
import { Chip, ChipSize, ChipVariant } from '@/ui/display/chip/components/Chip';
type RoundedLinkProps = {
href: string;
children?: React.ReactNode;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
};
const StyledClickable = styled.div`
overflow: hidden;
white-space: nowrap;
a {
color: inherit;
overflow: hidden;
text-decoration: none;
text-overflow: ellipsis;
}
`;
export const RoundedLink = ({ children, href, onClick }: RoundedLinkProps) => (
<div>
{children !== '' ? (
<StyledClickable>
<ReactLink target="_blank" to={href} onClick={onClick}>
<Chip
label={`${children}`}
variant={ChipVariant.Rounded}
size={ChipSize.Small}
/>
</ReactLink>
</StyledClickable>
) : (
<></>
)}
</div>
);

View File

@ -0,0 +1,64 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { RoundedLink } from './RoundedLink';
export enum LinkType {
Url = 'url',
LinkedIn = 'linkedin',
Twitter = 'twitter',
}
type SocialLinkProps = {
href: string;
children?: React.ReactNode;
type?: LinkType;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
};
const StyledRawLink = styled(RoundedLink)`
overflow: hidden;
a {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`;
export const SocialLink = ({
children,
href,
onClick,
type,
}: SocialLinkProps) => {
let displayValue = children;
if (type === 'linkedin') {
const matches = href.match(
/(?:https?:\/\/)?(?:www.)?linkedin.com\/(?:in|company)\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/,
);
if (matches && matches[1]) {
displayValue = matches[1];
} else {
displayValue = 'LinkedIn';
}
}
if (type === 'twitter') {
const matches = href.match(
/(?:https?:\/\/)?(?:www.)?twitter.com\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/,
);
if (matches && matches[1]) {
displayValue = `@${matches[1]}`;
} else {
displayValue = '@twitter';
}
}
return (
<StyledRawLink href={href} onClick={onClick}>
{displayValue}
</StyledRawLink>
);
};

View File

@ -0,0 +1,36 @@
import { jest } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { ContactLink } from '../ContactLink';
const meta: Meta<typeof ContactLink> = {
title: 'UI/Link/ContactLink',
component: ContactLink,
decorators: [ComponentWithRouterDecorator],
args: {
className: 'ContactLink',
href: '/test',
children: 'Contact Link',
},
};
export default meta;
type Story = StoryObj<typeof ContactLink>;
const clickJestFn = jest.fn();
export const Email: Story = {
args: {
href: `mailto:${'email@example.com'}`,
children: 'email@example.com',
onClick: clickJestFn,
},
};
export const Phone: Story = {
args: {
children: '11111111111',
onClick: clickJestFn,
},
};

View File

@ -0,0 +1,38 @@
import { expect } from '@storybook/jest';
import { jest } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { RawLink } from '../RawLink';
const meta: Meta<typeof RawLink> = {
title: 'UI/Link/RawLink',
component: RawLink,
decorators: [ComponentWithRouterDecorator],
args: {
className: 'RawLink',
href: '/test',
children: 'Raw Link',
},
};
export default meta;
type Story = StoryObj<typeof RawLink>;
const clickJestFn = jest.fn();
export const Default: Story = {
args: {
onClick: clickJestFn,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(clickJestFn).toHaveBeenCalledTimes(0);
const link = canvas.getByRole('link');
await userEvent.click(link);
await expect(clickJestFn).toHaveBeenCalledTimes(1);
},
};

View File

@ -0,0 +1,37 @@
import { expect } from '@storybook/jest';
import { jest } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { RoundedLink } from '../RoundedLink';
const meta: Meta<typeof RoundedLink> = {
title: 'UI/Link/RoundedLink',
component: RoundedLink,
decorators: [ComponentWithRouterDecorator],
args: {
href: '/test',
children: 'Rounded chip',
},
};
export default meta;
type Story = StoryObj<typeof RoundedLink>;
const clickJestFn = jest.fn();
export const Default: Story = {
args: {
onClick: clickJestFn,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(clickJestFn).toHaveBeenCalledTimes(0);
const link = canvas.getByRole('link');
await userEvent.click(link);
await expect(clickJestFn).toHaveBeenCalledTimes(1);
},
};

View File

@ -0,0 +1,52 @@
import { expect } from '@storybook/jest';
import { jest } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { LinkType, SocialLink } from '../SocialLink';
const meta: Meta<typeof SocialLink> = {
title: 'UI/Link/SocialLink',
component: SocialLink,
decorators: [ComponentWithRouterDecorator],
args: {
href: '/test',
children: 'Social Link',
},
};
export default meta;
type Story = StoryObj<typeof SocialLink>;
const clickJestFn = jest.fn();
const linkedin: LinkType = LinkType.LinkedIn;
const twitter: LinkType = LinkType.Twitter;
export const LinkedIn: Story = {
args: {
href: '/LinkedIn',
children: 'LinkedIn',
onClick: clickJestFn,
type: linkedin,
},
};
export const Twitter: Story = {
args: {
href: '/Twitter',
children: 'Twitter',
onClick: clickJestFn,
type: twitter,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(clickJestFn).toHaveBeenCalledTimes(0);
const link = canvas.getByRole('link');
await userEvent.click(link);
await expect(clickJestFn).toHaveBeenCalledTimes(1);
},
};