From 0cf497bf1c8bced67761a9ecf44514515ffc04ba Mon Sep 17 00:00:00 2001 From: Andrey Medvedev Date: Fri, 30 Aug 2024 12:22:56 +0300 Subject: [PATCH] feat(Group): Add Group.ExpandedContent to ignore group inner paddings (#7396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавили подкомпонент для игнорирования вертикальных и горизонтальных отступов `Group`. Можно игнорировать либо вертикальные, либо горизонтальные отступы. Возможно, что имеет смысл игнорировать сразу все отступы, но это можно сделать отдельным вариантом свойства `direction`. - перетасовали css переменные в `Group`. Потребовалось, чтобы упростить понимание реализации `Group.ExpandedContent`. Так как `Group.ExpandedContent` всегда будет находится внутри `Group` и на него всегда будут влиять внутренние отступы `Group`, будет логично внутренние отступы компенсировать за счёт отрицательных марджинов. Проще всего взять текущее значение паддинга, умножить на -1 и подставить в `margin` `Group.ExpandedContent`. Но чтобы это сделать надо где-то хранить текущее значение паддинга. Так как паддинг по горизонтали и вертикали меняется относительно режима `mode = 'card' | 'plain'` у `Group`, то логично хранить паддинг в двух отдельных css-переменных: `--vkui_internal--Group_padding_inline` и `--vkui_internal--Group_padding_block`. Можно один раз прописать ```css padding-block: var(--vkui_internal--Group_padding_block); padding-inline: var(--vkui_internal--Group_padding_inline); ``` а дальше менять только css-переменные, в зависимости от режима. К сожалению, не удалось избавиться от сss-переменной `--vkui_internal--Group_padding_size`, которая используется для задания отступов в режиме `card`. Тем не менее удалось встроить её в схему с основными переменными. Переменная теперь имеет более специфичное имя: `--vkui_internal--Group_card_mode_padding_size`. --- .../components/Group/Group.e2e-playground.tsx | 35 ++++++++++++- .../vkui/src/components/Group/Group.e2e.tsx | 11 +++- .../src/components/Group/Group.module.css | 52 +++++++++++++++---- .../src/components/Group/Group.stories.tsx | 18 +++++++ packages/vkui/src/components/Group/Group.tsx | 4 ++ .../Group/GroupExpandedContent.test.tsx | 26 ++++++++++ .../components/Group/GroupExpandedContent.tsx | 27 ++++++++++ packages/vkui/src/components/Group/Readme.md | 38 ++++++++++++++ ...edcontent-android-chromium-dark-1-snap.png | 3 ++ ...dcontent-android-chromium-light-1-snap.png | 3 ++ ...expandedcontent-ios-webkit-dark-1-snap.png | 3 ++ ...xpandedcontent-ios-webkit-light-1-snap.png | 3 ++ ...ndedcontent-vkcom-chromium-dark-1-snap.png | 3 ++ ...dedcontent-vkcom-chromium-light-1-snap.png | 3 ++ ...andedcontent-vkcom-firefox-dark-1-snap.png | 3 ++ ...ndedcontent-vkcom-firefox-light-1-snap.png | 3 ++ ...pandedcontent-vkcom-webkit-dark-1-snap.png | 3 ++ ...andedcontent-vkcom-webkit-light-1-snap.png | 3 ++ 18 files changed, 229 insertions(+), 12 deletions(-) create mode 100644 packages/vkui/src/components/Group/GroupExpandedContent.test.tsx create mode 100644 packages/vkui/src/components/Group/GroupExpandedContent.tsx create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-dark-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-light-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-dark-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-light-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-dark-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-light-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-dark-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-light-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-dark-1-snap.png create mode 100644 packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-light-1-snap.png diff --git a/packages/vkui/src/components/Group/Group.e2e-playground.tsx b/packages/vkui/src/components/Group/Group.e2e-playground.tsx index 0b6401d4e2..d3539a72ef 100644 --- a/packages/vkui/src/components/Group/Group.e2e-playground.tsx +++ b/packages/vkui/src/components/Group/Group.e2e-playground.tsx @@ -1,7 +1,7 @@ import { ComponentPlayground, type ComponentPlaygroundProps } from '@vkui-e2e/playground-helpers'; import { Div } from '../Div/Div'; import { Header } from '../Header/Header'; -import { Group } from './Group'; +import { Group, type GroupProps } from './Group'; export const GroupPlayground = (props: ComponentPlaygroundProps) => { return ( @@ -24,3 +24,36 @@ export const GroupPlayground = (props: ComponentPlaygroundProps) => { ); }; + +export const GroupWithExpandedContentPlayground = (props: ComponentPlaygroundProps) => { + return ( + +
+ Expanded Inline +
+ , + +
+ Expanded Block +
+
, + ], + }, + ]} + > + {(props: GroupProps) => ( +
+ +
+ )} +
+ ); +}; diff --git a/packages/vkui/src/components/Group/Group.e2e.tsx b/packages/vkui/src/components/Group/Group.e2e.tsx index f3af10b1df..db8f20db95 100644 --- a/packages/vkui/src/components/Group/Group.e2e.tsx +++ b/packages/vkui/src/components/Group/Group.e2e.tsx @@ -1,7 +1,16 @@ import { test } from '@vkui-e2e/test'; -import { GroupPlayground } from './Group.e2e-playground'; +import { GroupPlayground, GroupWithExpandedContentPlayground } from './Group.e2e-playground'; test('Group', async ({ mount, expectScreenshotClippedToContent, componentPlaygroundProps }) => { await mount(); await expectScreenshotClippedToContent(); }); + +test('Group.ExpandedContent', async ({ + mount, + expectScreenshotClippedToContent, + componentPlaygroundProps, +}) => { + await mount(); + await expectScreenshotClippedToContent(); +}); diff --git a/packages/vkui/src/components/Group/Group.module.css b/packages/vkui/src/components/Group/Group.module.css index 92e85a3626..383c491aea 100644 --- a/packages/vkui/src/components/Group/Group.module.css +++ b/packages/vkui/src/components/Group/Group.module.css @@ -7,24 +7,29 @@ * - sizeX="regular" (desktop) -> mode="card" */ .Group { - --vkui_internal--Group_padding_size: 0; + --vkui_internal--Group_padding_inline: 0; + --vkui_internal--Group_padding_block: var(--vkui--spacing_size_m); + --vkui_internal--Group_card_mode_padding_size: 0; color: var(--vkui--color_text_primary); - padding-block: var(--vkui--spacing_size_m); + padding-block: var(--vkui_internal--Group_padding_block); + padding-inline: var(--vkui_internal--Group_padding_inline); } .Group--padding-s { - --vkui_internal--Group_padding_size: var(--vkui--spacing_size_xs); + --vkui_internal--Group_card_mode_padding_size: var(--vkui--spacing_size_xs); } .Group--padding-m { - --vkui_internal--Group_padding_size: var(--vkui--spacing_size_m); + --vkui_internal--Group_card_mode_padding_size: var(--vkui--spacing_size_m); } /* разделитель при mode="card" */ .Group--mode-card, .Group--sizeX-regular.Group--mode-none { - padding: var(--vkui_internal--Group_padding_size); + --vkui_internal--Group_padding_inline: var(--vkui_internal--Group_card_mode_padding_size); + --vkui_internal--Group_padding_block: var(--vkui_internal--Group_card_mode_padding_size); + position: relative; background: var(--vkui--color_background_content); border-radius: var(--vkui--size_border_radius_paper--regular); @@ -32,7 +37,9 @@ @media (--sizeX-regular) { .Group--sizeX-none.Group--mode-none { - padding: var(--vkui_internal--Group_padding_size); + --vkui_internal--Group_padding_inline: var(--vkui_internal--Group_card_mode_padding_size); + --vkui_internal--Group_padding_block: var(--vkui_internal--Group_card_mode_padding_size); + position: relative; background: var(--vkui--color_background_content); border-radius: var(--vkui--size_border_radius_paper--regular); @@ -40,13 +47,15 @@ } .Group--sizeX-compact.Group--mode-card { - padding-inline: 0; + --vkui_internal--Group_padding_inline: 0; + border-radius: var(--vkui--size_border_radius_promo--regular); } @media (--sizeX-compact) { .Group--sizeX-none.Group--mode-card { - padding-inline: 0; + --vkui_internal--Group_padding_inline: 0; + border-radius: var(--vkui--size_border_radius_promo--regular); } } @@ -231,7 +240,8 @@ */ @media (--sizeX-regular) { .Group--mode-plain-inside-modal { - padding: var(--vkui--spacing_size_m); + --vkui_internal--Group_padding_inline: var(--vkui--spacing_size_m); + --vkui_internal--Group_padding_block: var(--vkui--spacing_size_m); } .Group--mode-plain-inside-modal + .Group__separator-sibling { @@ -245,7 +255,7 @@ * Group вложенный в Group */ .Group .Group { - padding-inline: 0; + --vkui_internal--Group_padding_inline: 0; } .Group .Group + .Group__separator-sibling { @@ -260,6 +270,28 @@ padding-block-end: 0; } +/* + * Group.ExpandedContent + * компенсирующий отступы Group в зависимости + * от режима: inline / block + */ + +.Group__expanded-content--inline { + margin-inline: calc(-1 * var(--vkui_internal--Group_padding_inline)); +} + +.Group__expanded-content--block { + margin-block: calc(-1 * var(--vkui_internal--Group_padding_block)); +} + +.Group .Group:first-of-type .Group__expanded-content--block { + margin-inline-start: 0; +} + +.Group .Group:last-of-type .Group__expanded-content--block { + margin-inline-start: 0; +} + /* * CMP: * PanelHeader diff --git a/packages/vkui/src/components/Group/Group.stories.tsx b/packages/vkui/src/components/Group/Group.stories.tsx index 114e38ac8e..8f168772ab 100644 --- a/packages/vkui/src/components/Group/Group.stories.tsx +++ b/packages/vkui/src/components/Group/Group.stories.tsx @@ -67,6 +67,24 @@ export const Example: Story = { Добавить домашний адрес Добавить рабочий адрес + + +
Подкомпонентный подход: Адреса
+
+ Добавить домашний адрес + Добавить рабочий адрес + + Для использования в мини-приложениях, Delivery Club, VK Taxi и других сервисах + ВКонтакте. Эти адреса видны только Вам. + +
+ +
Контент игнорирует боковые отступы Group
+ + Добавить домашний адрес + Добавить рабочий адрес + +
), withSinglePanel, diff --git a/packages/vkui/src/components/Group/Group.tsx b/packages/vkui/src/components/Group/Group.tsx index 76a6656a2e..2963c11534 100644 --- a/packages/vkui/src/components/Group/Group.tsx +++ b/packages/vkui/src/components/Group/Group.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { hasReactNode } from '@vkontakte/vkjs'; import { GroupContainer, type GroupContainerProps } from './GroupContainer'; import { GroupDescription } from './GroupDescription'; +import { GroupExpandedContent } from './GroupExpandedContent'; import { GroupHeader } from './GroupHeader'; export interface GroupProps extends GroupContainerProps { @@ -16,6 +17,7 @@ export const Group: React.FC & { Container: typeof GroupContainer; Header: typeof GroupHeader; Description: typeof GroupDescription; + ExpandedContent: typeof GroupExpandedContent; } = ({ header, description, children, ...restProps }: GroupProps): React.ReactNode => { return ( @@ -33,3 +35,5 @@ Group.Header = GroupHeader; Group.Header.displayName = 'Group.Header'; Group.Description = GroupDescription; Group.Description.displayName = 'Group.Description'; +Group.ExpandedContent = GroupExpandedContent; +Group.ExpandedContent.displayName = 'Group.ExpandedContent'; diff --git a/packages/vkui/src/components/Group/GroupExpandedContent.test.tsx b/packages/vkui/src/components/Group/GroupExpandedContent.test.tsx new file mode 100644 index 0000000000..d62aff282a --- /dev/null +++ b/packages/vkui/src/components/Group/GroupExpandedContent.test.tsx @@ -0,0 +1,26 @@ +import { render, screen } from '@testing-library/react'; +import { GroupExpandedContent, type GroupExpandedContentProps } from './GroupExpandedContent'; +import styles from './Group.module.css'; + +describe('GroupExpandedContent', () => { + it.each<{ direction: GroupExpandedContentProps['direction']; className: string }>([ + { + direction: undefined, + className: styles['Group__expanded-content--inline'], + }, + { + direction: 'inline', + className: styles['Group__expanded-content--inline'], + }, + { + direction: 'block', + className: styles['Group__expanded-content--block'], + }, + ])( + 'should have className "$className" with direction "$direction"', + async ({ direction, className }) => { + render(Content); + expect(screen.getByText('Content')).toHaveClass(className); + }, + ); +}); diff --git a/packages/vkui/src/components/Group/GroupExpandedContent.tsx b/packages/vkui/src/components/Group/GroupExpandedContent.tsx new file mode 100644 index 0000000000..30fef559c5 --- /dev/null +++ b/packages/vkui/src/components/Group/GroupExpandedContent.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import { classNames } from '@vkontakte/vkjs'; +import type { HasComponent, HTMLAttributesWithRootRef } from '../../types'; +import { RootComponent } from '../RootComponent/RootComponent'; +import styles from './Group.module.css'; + +const stylesDirection = { + inline: styles['Group__expanded-content--inline'], + block: styles['Group__expanded-content--block'], +}; + +export type GroupExpandedContentProps = HTMLAttributesWithRootRef & + HasComponent & { + direction?: 'inline' | 'block'; + }; +export const GroupExpandedContent: React.FC = ({ + direction = 'inline', + ...restProps +}: GroupExpandedContentProps) => { + return ( + + ); +}; diff --git a/packages/vkui/src/components/Group/Readme.md b/packages/vkui/src/components/Group/Readme.md index 3c138b4e00..3e87cf4388 100644 --- a/packages/vkui/src/components/Group/Readme.md +++ b/packages/vkui/src/components/Group/Readme.md @@ -169,3 +169,41 @@ const SharedContent = () => { ``` + +
+ +## + +Компенсирует внутренние отступы `Group` по горизонтали `direction="inline"` или по вертикали `direction="block"`. +Позволяет вложить внутрь `Group` контент, игнорируя внутренние отступы `Group`. + +```jsx +const recentFriends = getRandomUsers(20); + +Недавние}> +
HorizontalScroll не учитывает отступы Group по горизонтали
+ + + + {recentFriends.map((item) => { + return ( + {}} key={item.id} header={item.first_name}> + + + ); + })} + + + +
Здесь контент учитывает отступы Group по горизонтали
+ + {recentFriends.map((item) => { + return ( + {}} key={item.id} header={item.first_name}> + + + ); + })} + +
; +``` diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-dark-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-dark-1-snap.png new file mode 100644 index 0000000000..a94e86f227 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-dark-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:481df6bdaf315b553d539993c6a379db20b4fd0a42de7a2d851bce355f060327 +size 96894 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-light-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-light-1-snap.png new file mode 100644 index 0000000000..121adacda7 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-android-chromium-light-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd65983229a250175068a599652b475cc31b2996d4be47cb6c86553ce7d4426a +size 100535 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-dark-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-dark-1-snap.png new file mode 100644 index 0000000000..77a75164dc --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-dark-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4db9c42cafa4288f19354e1c5eaf09cb5e52b4465ec5d425323093bae99e89e9 +size 100661 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-light-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-light-1-snap.png new file mode 100644 index 0000000000..2710f0e239 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-ios-webkit-light-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee51265360ff8c139dac1b0e3e1c504c132c4b97cebfd30e44c0df764d25ad81 +size 102779 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-dark-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-dark-1-snap.png new file mode 100644 index 0000000000..dab1b7cd62 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-dark-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db760d3fdb5a159d85dd09fe583bad25d8fde113e70158f08ecc6418aea79e13 +size 40825 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-light-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-light-1-snap.png new file mode 100644 index 0000000000..03c2df51e2 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-chromium-light-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61c918dcfce7c9f4a6792b425fc199b6b2153d7dbd7e664a0e9fabca457b852d +size 42172 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-dark-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-dark-1-snap.png new file mode 100644 index 0000000000..468bc3b94a --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-dark-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9104e79dea4d1bd86f7ad87c82e5335c2bd774b4e6eece95ee694edd56a0550 +size 56379 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-light-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-light-1-snap.png new file mode 100644 index 0000000000..6f41e91c2c --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-firefox-light-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59b5a1fe349c051e0b7e22d8fc336408281524ab4730703683ea2dcb72479515 +size 57679 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-dark-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-dark-1-snap.png new file mode 100644 index 0000000000..0605a7c584 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-dark-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0385007d9b7ab7c636b7802f1c18155c9f30d1aad938b3b88e9639ce3d138eb +size 41668 diff --git a/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-light-1-snap.png b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-light-1-snap.png new file mode 100644 index 0000000000..ecc256e7a9 --- /dev/null +++ b/packages/vkui/src/components/Group/__image_snapshots__/group-expandedcontent-vkcom-webkit-light-1-snap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a70a7e8d40fce6f663c5be3cee7dca65c8eca4c5aaf1ccdf22f12ed3ab17c6ad +size 42797