Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Commit

Permalink
feat(UIKIT-1713,ComplianceStatus): Добавлен новый компонент Complianc…
Browse files Browse the repository at this point in the history
…eStatus (#1114)
  • Loading branch information
Ofigelov authored Aug 29, 2024
1 parent 2f39574 commit bf05d65
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .cspell-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ zeropad
бордера
бэкдропу
Cпособ
валидация
валидации
валидацию
валидацией
валидаций
варинте
вебвизоре
виджете
Expand Down
161 changes: 161 additions & 0 deletions packages/components/src/ComplianceStatus/ComplianceStatus.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { type Meta, type StoryObj } from '@storybook/react';

import { Typography } from '../Typography';

import { ComplianceStatus } from './ComplianceStatus';

/**
* ComplianceStatus - это компонент, позволяющий отображать статусы прохождения сложных валидаций
* ### [Figma](https://www.figma.com/design/3ghN4WjSgkKx5rETR64jqh/Sirius-Design-System-(%D0%90%D0%9A%D0%A2%D0%A3%D0%90%D0%9B%D0%AC%D0%9D%D0%9E)?node-id=29582-27134)
* ### [Guide]()
*/

const meta: Meta<typeof ComplianceStatus> = {
title: 'Components/ComplianceStatus',
component: ComplianceStatus,
};

export default meta;

type Story = StoryObj<typeof ComplianceStatus>;

export const Interaction: Story = {
args: {
itemsList: [
{
status: 'default',
text: 'Lorem ipsum dolor sit.',
},
],
},
parameters: {
docs: {
disable: true,
},
},
};

export const Example = () => {
return (
<ComplianceStatus
title="Требования к паролю"
itemsList={[
{
status: 'default',
text: 'Латинские символы разного регистра (A-Z, a-z)',
},
{
status: 'default',
text: 'Не менее 8 символов',
},
{
status: 'success',
text: 'Арабские цифры (0-9)',
},
{
status: 'reject',
text: 'Знаки пунктуации (!”$%&’()+,-./:;<=>?@[]^_{|}”)',
},
]}
/>
);
};

/**
* Пропс для добавления контента после списка
*/
export const Children = () => {
return (
<ComplianceStatus
title="Требования к паролю"
itemsList={[
{
status: 'default',
text: 'Латинские символы разного регистра (A-Z, a-z)',
},
{
status: 'default',
text: 'Не менее 8 символов',
},
{
status: 'success',
text: 'Арабские цифры (0-9)',
},
{
status: 'reject',
text: 'Знаки пунктуации (!”$%&’()+,-./:;<=>?@[]^_{|}”)',
},
]}
>
<Typography>
Пожалуйста, убедитесь что введенное значение соответствует правилам,
указанными выше
</Typography>
</ComplianceStatus>
);
};

/**
* Пропс для добавления контента между заголовком и списком
*/
export const Subtitle = () => {
return (
<ComplianceStatus
title="Требования к паролю"
subtitle={
<Typography>
Пожалуйста, убедитесь что введенное значение соответствует указанными
ниже правилам
</Typography>
}
itemsList={[
{
status: 'default',
text: 'Латинские символы разного регистра (A-Z, a-z)',
},
{
status: 'default',
text: 'Не менее 8 символов',
},
{
status: 'success',
text: 'Арабские цифры (0-9)',
},
{
status: 'reject',
text: 'Знаки пунктуации (!”$%&’()+,-./:;<=>?@[]^_{|}”)',
},
]}
/>
);
};

/**
* Пропс предназначенный для изменения фонового цвета, по умолчанию имеет значение "grey"
*/
export const BackgroundColor = () => {
return (
<ComplianceStatus
title="Требования к паролю"
backgroundColor="primary"
itemsList={[
{
status: 'default',
text: 'Латинские символы разного регистра (A-Z, a-z)',
},
{
status: 'default',
text: 'Не менее 8 символов',
},
{
status: 'success',
text: 'Арабские цифры (0-9)',
},
{
status: 'reject',
text: 'Знаки пунктуации (!”$%&’()+,-./:;<=>?@[]^_{|}”)',
},
]}
/>
);
};
89 changes: 89 additions & 0 deletions packages/components/src/ComplianceStatus/ComplianceStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { type ReactNode } from 'react';

import { useId } from '../hooks/useId';
import { OverflowTypography } from '../OverflowTypography';
import { Typography } from '../Typography';

import {
EmptyIcon,
Inner,
Item,
RejectIcon,
SuccessIcon,
Wrapper,
} from './styles';

type ItemStatus = 'success' | 'reject' | 'default';

type BackgroundColor = 'grey' | 'primary';

export type ComplianceStatusItem = {
/**
* Текст для отображения в элементе списка
*/
text: string;
/**
* Статус элемента
*/
status: ItemStatus;
};

export type ComplianceStatusProps = {
/**
* Основной заголовок элемента
*/
title?: string | null;
/**
* Пропс для добавления контента между заголовком и списком
*/
subtitle?: ReactNode;
/**
* Пропс для добавления контента после списка
*/
children?: ReactNode;
/**
* Элементы списка
*/
itemsList: ComplianceStatusItem[];
/**
* Фоновый цвет
* @default grey
*/
backgroundColor?: BackgroundColor;
};

const ICON_BY_STATUS: Record<ItemStatus, JSX.Element> = {
default: <EmptyIcon />,
success: <SuccessIcon />,
reject: <RejectIcon />,
};

export const ComplianceStatus = ({
title,
itemsList,
children,
subtitle,
backgroundColor = 'grey',
}: ComplianceStatusProps) => {
const id = useId();

return (
<Wrapper $background={backgroundColor}>
{title && (
<OverflowTypography variant="h6" component="h4">
{title}
</OverflowTypography>
)}
{subtitle}
<Inner>
{itemsList.map(({ text, status }, index) => (
<Item key={`${id}_${index}`}>
{ICON_BY_STATUS[status]}
<Typography>{text}</Typography>
</Item>
))}
</Inner>
{children}
</Wrapper>
);
};
1 change: 1 addition & 0 deletions packages/components/src/ComplianceStatus/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ComplianceStatus';
48 changes: 48 additions & 0 deletions packages/components/src/ComplianceStatus/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { CloseFillSm, DotOutlineSm, SuccessFillSm } from '@astral/icons';

import { styled } from '../styles';
import { listContainer } from '../styles/mixins';

export const Wrapper = styled('article')<{ $background: 'grey' | 'primary' }>`
display: grid;
grid-gap: ${({ theme }) => theme.spacing(3)};
padding: ${({ theme }) => theme.spacing(3, 6)};
background-color: ${({ theme, $background }) =>
theme.palette[$background][100]};
border-radius: ${({ theme }) => theme.shape.small};
`;

export const Inner = styled('ul')`
display: grid;
grid-gap: ${({ theme }) => theme.spacing(3)};
${listContainer};
`;

export const Item = styled('li')`
display: grid;
grid-gap: ${({ theme }) => theme.spacing(2)};
grid-template-columns: auto 1fr;
`;

const DefaultIcon = styled.div`
width: 16px;
min-width: 16px;
height: 16px;
min-height: 16px;
margin-top: ${({ theme }) => theme.spacing(0.5)};
`;

export const EmptyIcon = styled(DefaultIcon)`
color: ${({ theme }) => theme.palette.grey[800]};
`.withComponent(DotOutlineSm);

export const RejectIcon = styled(DefaultIcon)`
color: ${({ theme }) => theme.palette.error[900]};
`.withComponent(CloseFillSm);

export const SuccessIcon = styled(DefaultIcon)`
color: ${({ theme }) => theme.palette.success[900]};
`.withComponent(SuccessFillSm);
6 changes: 6 additions & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ export * from './PageLayoutContainer';

export * from './Paper';

export {
ComplianceStatus,
type ComplianceStatusProps,
type ComplianceStatusItem,
} from './ComplianceStatus';

export * from './PersonalData';

export * from './Placeholder';
Expand Down

0 comments on commit bf05d65

Please sign in to comment.