diff --git a/.cspell-ignore b/.cspell-ignore index eeb84e1bc..81294cd04 100644 --- a/.cspell-ignore +++ b/.cspell-ignore @@ -169,6 +169,11 @@ zeropad бордера бэкдропу Cпособ +валидация +валидации +валидацию +валидацией +валидаций варинте вебвизоре виджете diff --git a/packages/components/src/ComplianceStatus/ComplianceStatus.stories.tsx b/packages/components/src/ComplianceStatus/ComplianceStatus.stories.tsx new file mode 100644 index 000000000..ea84823fa --- /dev/null +++ b/packages/components/src/ComplianceStatus/ComplianceStatus.stories.tsx @@ -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 = { + title: 'Components/ComplianceStatus', + component: ComplianceStatus, +}; + +export default meta; + +type Story = StoryObj; + +export const Interaction: Story = { + args: { + itemsList: [ + { + status: 'default', + text: 'Lorem ipsum dolor sit.', + }, + ], + }, + parameters: { + docs: { + disable: true, + }, + }, +}; + +export const Example = () => { + return ( + ?@[]^_{|}”)', + }, + ]} + /> + ); +}; + +/** + * Пропс для добавления контента после списка + */ +export const Children = () => { + return ( + ?@[]^_{|}”)', + }, + ]} + > + + Пожалуйста, убедитесь что введенное значение соответствует правилам, + указанными выше + + + ); +}; + +/** + * Пропс для добавления контента между заголовком и списком + */ +export const Subtitle = () => { + return ( + + Пожалуйста, убедитесь что введенное значение соответствует указанными + ниже правилам + + } + 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 ( + ?@[]^_{|}”)', + }, + ]} + /> + ); +}; diff --git a/packages/components/src/ComplianceStatus/ComplianceStatus.tsx b/packages/components/src/ComplianceStatus/ComplianceStatus.tsx new file mode 100644 index 000000000..bf9b18840 --- /dev/null +++ b/packages/components/src/ComplianceStatus/ComplianceStatus.tsx @@ -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 = { + default: , + success: , + reject: , +}; + +export const ComplianceStatus = ({ + title, + itemsList, + children, + subtitle, + backgroundColor = 'grey', +}: ComplianceStatusProps) => { + const id = useId(); + + return ( + + {title && ( + + {title} + + )} + {subtitle} + + {itemsList.map(({ text, status }, index) => ( + + {ICON_BY_STATUS[status]} + {text} + + ))} + + {children} + + ); +}; diff --git a/packages/components/src/ComplianceStatus/index.ts b/packages/components/src/ComplianceStatus/index.ts new file mode 100644 index 000000000..d1690dd24 --- /dev/null +++ b/packages/components/src/ComplianceStatus/index.ts @@ -0,0 +1 @@ +export * from './ComplianceStatus'; diff --git a/packages/components/src/ComplianceStatus/styles.ts b/packages/components/src/ComplianceStatus/styles.ts new file mode 100644 index 000000000..a9e21ce92 --- /dev/null +++ b/packages/components/src/ComplianceStatus/styles.ts @@ -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); diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 3d2ad6df5..9fd870b43 100755 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -206,6 +206,12 @@ export * from './PageLayoutContainer'; export * from './Paper'; +export { + ComplianceStatus, + type ComplianceStatusProps, + type ComplianceStatusItem, +} from './ComplianceStatus'; + export * from './PersonalData'; export * from './Placeholder';