Skip to content

Commit

Permalink
(ModalCardBase): Remove cascade offset using Spacing component (#6230)
Browse files Browse the repository at this point in the history
Убираем, по возможности, отступы заданные с помощью каскада.

Для случая с `UserStack` и `FormField` стараемся отобразить это в migration guide, упирая на то, что следует использовать `Spacing` для того, чтобы соответствовать дизайн-системе.

Стараемся использовать `Spacing` во всех примерах где используется `ModalCardBase`.
  • Loading branch information
mendrew authored Dec 18, 2023
1 parent 5d258ff commit 48cf4a8
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 151 deletions.
9 changes: 0 additions & 9 deletions packages/vkui/src/components/FormField/FormField.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,6 @@
z-index: var(--vkui_internal--z_index_form_field_border_hover);
}

/**
* CMP:
* ModalCardBase
*/
:global(.vkuiInternalModalCardBase__header) + .FormField,
:global(.vkuiInternalModalCardBase__subheader) + .FormField {
margin-block-start: 16px;
}

/**
* CMP:
* NativeSelect
Expand Down
81 changes: 48 additions & 33 deletions packages/vkui/src/components/ModalCard/ModalCard.e2e-playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Button } from '../Button/Button';
import { ButtonGroup } from '../ButtonGroup/ButtonGroup';
import { Image } from '../Image/Image';
import { ModalRoot } from '../ModalRoot/ModalRootAdaptive';
import { Spacing } from '../Spacing/Spacing';
import { Textarea } from '../Textarea/Textarea';
import { UsersStack } from '../UsersStack/UsersStack';
import { ModalCard, type ModalCardProps } from './ModalCard';
Expand All @@ -31,9 +32,12 @@ export const ModalCardPlayground = (props: ComponentPlaygroundProps) => {
header: ['Отправляйте деньги друзьям, используя банковскую карту'],
subheader: ['Номер карты получателя не нужен — он сам решит, куда зачислить средства.'],
actions: [
<Button size="l" mode="primary" stretched key="button">
Попробовать
</Button>,
<React.Fragment key="actions">
<Spacing size={16} />
<Button size="l" mode="primary" stretched>
Попробовать
</Button>
</React.Fragment>,
],
},
{
Expand All @@ -44,26 +48,26 @@ export const ModalCardPlayground = (props: ComponentPlaygroundProps) => {
'Игра появится под списком разделов на экране меню и будет всегда под рукой.',
],
actions: [
<ButtonGroup mode="vertical" gap="m" stretched key="buttons">
<Button size="l" mode="primary" stretched>
Присоединиться
</Button>
<Button size="l" mode="secondary" stretched>
Скопировать приглашение
</Button>
</ButtonGroup>,
<React.Fragment key="actions">
<Spacing size={8} />
<ButtonGroup mode="vertical" gap="m" stretched>
<Button size="l" mode="primary" stretched>
Присоединиться
</Button>
<Button size="l" mode="secondary" stretched>
Скопировать приглашение
</Button>
</ButtonGroup>
</React.Fragment>,
],
children: [
<UsersStack
photos={['', '', '', '']}
size="l"
visibleCount={3}
key="usersstack"
direction="column"
>
Алексей, Илья, Михаил
<br />и ещё 3 человека
</UsersStack>,
<React.Fragment key="userstack">
<Spacing size={20} />
<UsersStack photos={['', '', '', '']} size="l" visibleCount={3} direction="column">
Алексей, Илья, Михаил
<br />и ещё 3 человека
</UsersStack>
</React.Fragment>,
],
},
{
Expand All @@ -74,7 +78,12 @@ export const ModalCardPlayground = (props: ComponentPlaygroundProps) => {
Сохранить
</Button>,
],
children: [<Textarea key="textarea" defaultValue="В Грузии" />],
children: [
<React.Fragment key="textarea">
<Spacing size={16} />
<Textarea defaultValue="В Грузии" />
</React.Fragment>,
],
},
{
nav: ['4'],
Expand All @@ -83,23 +92,29 @@ export const ModalCardPlayground = (props: ComponentPlaygroundProps) => {
'Гиппопотомомонстросесквиппедалиофобия — боязнь длинных слов, таких как метоксихлордиэтиламинометилбутиламиноакридин',
],
actions: [
<ButtonGroup mode="horizontal" gap="s" stretched key="buttons">
<Button size="l" mode="primary" stretched>
Гиппопотомомонстросесквиппедалиофобия
</Button>
<Button size="l" mode="primary" stretched>
Метоксихлордиэтиламинометилбутиламиноакридин
</Button>
</ButtonGroup>,
<React.Fragment key="actions">
<Spacing size={16} />
<ButtonGroup mode="horizontal" gap="s" stretched>
<Button size="l" mode="primary" stretched>
Гиппопотомомонстросесквиппедалиофобия
</Button>
<Button size="l" mode="primary" stretched>
Метоксихлордиэтиламинометилбутиламиноакридин
</Button>
</ButtonGroup>
</React.Fragment>,
],
},
{
nav: ['4'],
header: ['Расскажите о себе'],
actions: [
<Button size="l" mode="primary" stretched key="button">
Сохранить
</Button>,
<React.Fragment key="actions">
<Spacing size={16} />
<Button size="l" mode="primary" stretched>
Сохранить
</Button>
</React.Fragment>,
],
dismissButtonMode: ['inside', 'outside'],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,16 @@
color: var(--vkui--color_text_subhead);
}

.ModalCardBase__header + .ModalCardBase__subheader {
margin-block-start: 8px;
}

.ModalCardBase__icon {
margin-block: 8px 16px;
margin-inline: auto;
color: var(--vkui--color_icon_accent);
}

.ModalCardBase__actions {
display: flex;
margin-block-start: 16px;
}

:global(.vkuiInternalUsersStack) + .ModalCardBase__actions {
margin-block-start: 24px;
}

.ModalCardBase__header + .ModalCardBase__actions,
.ModalCardBase__subheader + .ModalCardBase__actions {
margin-block-start: 32px;
}

.ModalCardBase__dismiss {
position: absolute;
inset-block-start: 0;
Expand Down
19 changes: 7 additions & 12 deletions packages/vkui/src/components/ModalCardBase/ModalCardBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { usePlatform } from '../../hooks/usePlatform';
import { HTMLAttributesWithRootRef } from '../../types';
import { AdaptivityContext } from '../AdaptivityProvider/AdaptivityContext';
import { RootComponent } from '../RootComponent/RootComponent';
import { Spacing } from '../Spacing/Spacing';
import { Subhead } from '../Typography/Subhead/Subhead';
import { Title } from '../Typography/Title/Title';
import { ModalCardBaseCloseButton } from './ModalCardBaseCloseButton';
Expand Down Expand Up @@ -97,6 +98,8 @@ export const ModalCardBase = ({
const withSafeZone =
!icon && (dismissButtonMode === 'inside' || (platform === 'ios' && !isDesktop));

const hasHeader = hasReactNode(header);
const hasSubheader = hasReactNode(subheader);
return (
<RootComponent
{...restProps}
Expand All @@ -122,24 +125,16 @@ export const ModalCardBase = ({
<Title
level="2"
weight="2"
className={classNames(
styles['ModalCardBase__header'],
'vkuiInternalModalCardBase__header',
)}
className={styles['ModalCardBase__header']}
Component={headerComponent}
>
{header}
</Title>
)}
{hasReactNode(subheader) && (
{hasHeader && hasSubheader && <Spacing size={8} />}
{hasSubheader && (
<AdaptivityContext.Provider value={{ sizeY: 'regular' }}>
<Subhead
className={classNames(
styles['ModalCardBase__subheader'],
'vkuiInternalModalCardBase__subheader',
)}
Component={subheaderComponent}
>
<Subhead className={styles['ModalCardBase__subheader']} Component={subheaderComponent}>
{subheader}
</Subhead>
</AdaptivityContext.Provider>
Expand Down
83 changes: 71 additions & 12 deletions packages/vkui/src/components/ModalCardBase/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,68 @@
header="Отправляйте деньги друзьям, используя банковскую карту"
subheader="Номер карты получателя не нужен — он сам решит, куда зачислить средства."
actions={
<Button size="l" mode="primary" stretched>
Попробовать
</Button>
<React.Fragment>
<Spacing size={16} />
<Button size="l" mode="primary" stretched>
Попробовать
</Button>
</React.Fragment>
}
icon={<Icon56MoneyTransferOutline />}
/>
</AdaptivityProvider>
<Text style={{ marginBottom: 10 }}>Мобильная версия</Text>
<Text>Мобильная версия</Text>
<Spacing size={10} />
<AdaptivityProvider viewWidth={ViewWidth.MOBILE}>
<ModalCardBase
style={{ width: 320 }}
icon={<Image borderRadius="l" src={getAvatarUrl('app_zagadki', 200)} size={72} />}
header="Добавить игру «Загадки детства» в меню?"
subheader="Игра появится под списком разделов на экране меню и будет всегда под рукой."
actions={
<ButtonGroup mode="horizontal" gap="s" stretched>
<Button size="l" mode="primary" stretched>
Да
</Button>
<Button size="l" mode="secondary" stretched>
Позже
</Button>
</ButtonGroup>
<React.Fragment>
<Spacing size={16} />
<ButtonGroup mode="horizontal" gap="s" stretched>
<Button size="l" mode="primary" stretched>
Да
</Button>
<Button size="l" mode="secondary" stretched>
Позже
</Button>
</ButtonGroup>
</React.Fragment>
}
/>
</AdaptivityProvider>
<Spacing size={30} />
<Text>С UserStack в качестве children (имеет особенный отступ c actions)</Text>
<Spacing size={10} />
<AdaptivityProvider viewWidth={ViewWidth.MOBILE}>
<ModalCardBase
style={{ width: 320 }}
icon={<Image borderRadius="l" src={getAvatarUrl('app_zagadki', 200)} size={72} />}
header="Добавить игру «Загадки детства» в меню?"
subheader="Игра появится под списком разделов на экране меню и будет всегда под рукой."
actions={
<React.Fragment>
<Spacing size={8} />
<ButtonGroup mode="horizontal" gap="s" stretched>
<Button size="l" mode="primary" stretched>
Да
</Button>
<Button size="l" mode="secondary" stretched>
Позже
</Button>
</ButtonGroup>
</React.Fragment>
}
>
<Spacing size={20} />
<UsersStack photos={[getAvatarUrl('user_lihachyov')]}>
Понравилось Муртолу Левзачеву
</UsersStack>
</ModalCardBase>
</AdaptivityProvider>
</div>
```

Expand All @@ -44,6 +80,29 @@
Согласно нашим дизайн-гайдам, `dismissButtonMode=outside` отображается только для `compact`-режима (десктопная и планшетные версии).
Для `iOS` всегда будет применяться `dismissButtonMode=inside` в `regular`-режиме (мобильная версия).

## Отступы между контентом и кнопками действий (`actions`)

По умолчанию верхний отступ от кнопок действий `actions` равняется `16px`. Согласно дизайн-системе отступ может быть больше в зависимости от того какие данные отображаются внутри `ModalCardBase`.
Если необходимо увеличить отступ, то передавайте в `actions` компонент [Spacing](#/Spacing).

```jsx static
<ModalCardBase
dismissButtonMode="inside"
dismissLabel="Закрыть"
style={{ width: 450, marginBottom: 20 }}
header="Десктопная и планшетная версии с крестиком внутри"
subheader="Сверху будет безопасный отступ до иконки"
actions={
<React.Fragment>
<Spacing size={16} />
<Button size="l" mode="primary" stretched>
Некая кнопка
</Button>
</React.Fragment>
}
/>
```

## Цифровая доступность (a11y)

Чтобы кнопка для закрытия была доступной для ассистивных технологий, мы передаем в нее скрытый визуально текст, который сможет прочитать скринридер. Чтобы заменить текст, передайте его в `dismissLabel`.
Expand Down
Loading

0 comments on commit 48cf4a8

Please sign in to comment.