From f9c1d14d9396d2f84d0f67ceb5f76737b94ea5c3 Mon Sep 17 00:00:00 2001 From: Inomdzhon Mirdzhamolov Date: Mon, 2 Sep 2024 15:21:04 +0300 Subject: [PATCH] fix(Flex): refactor gaps (#7492) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Т.к. CSS св-во `gap` применяется только при наличии нескольких потомков, добавляем в наш фолбек такую же логику основываясь: - на передаче пропа `gap`; - на кол-ве элементов в пропе `children`; --- .../vkui/src/components/Flex/Flex.module.css | 31 ++++++++----- .../vkui/src/components/Flex/Flex.test.tsx | 14 +++++- packages/vkui/src/components/Flex/Flex.tsx | 44 +++++++++++++------ ...endering-android-chromium-light-1-snap.png | 4 +- 4 files changed, 66 insertions(+), 27 deletions(-) diff --git a/packages/vkui/src/components/Flex/Flex.module.css b/packages/vkui/src/components/Flex/Flex.module.css index 76f298e292..a3c9302411 100644 --- a/packages/vkui/src/components/Flex/Flex.module.css +++ b/packages/vkui/src/components/Flex/Flex.module.css @@ -3,19 +3,28 @@ --vkui_internal--flex_original_margin_block: 0px; display: flex; - margin-block: calc( - -1 * var(--vkui_internal--row_gap) + var(--vkui_internal--flex_original_margin_block) - ) - var(--vkui_internal--flex_original_margin_block); - margin-inline: calc( - -1 * var(--vkui_internal--column_gap) + var(--vkui_internal--flex_original_margin_inline) - ) - var(--vkui_internal--flex_original_margin_inline); } .Flex--margin-auto { --vkui_internal--flex_original_margin_inline: var(--vkui--size_base_padding_horizontal--regular); --vkui_internal--flex_original_margin_block: var(--vkui--size_base_padding_vertical--regular); + + margin-block: var(--vkui--size_base_padding_horizontal--regular); + margin-inline: var(--vkui--size_base_padding_vertical--regular); +} + +.Flex--withGaps { + margin-block-start: calc( + -1 * var(--vkui_internal--row_gap) + var(--vkui_internal--flex_original_margin_block) + ); + margin-inline-start: calc( + -1 * var(--vkui_internal--column_gap) + var(--vkui_internal--flex_original_margin_inline) + ); +} + +.Flex > .Flex--margin-auto { + margin-block: 0; + margin-inline: 0; } .Flex--direction-column { @@ -83,7 +92,7 @@ } /* stylelint-disable-next-line @project-tools/stylelint-atomic, selector-max-universal */ -.Flex > * { - margin-block: var(--vkui_internal--row_gap) 0; - margin-inline: var(--vkui_internal--column_gap) 0; +.Flex--withGaps > * { + margin-block-start: var(--vkui_internal--row_gap); + margin-inline-start: var(--vkui_internal--column_gap); } diff --git a/packages/vkui/src/components/Flex/Flex.test.tsx b/packages/vkui/src/components/Flex/Flex.test.tsx index 0d8849163a..a85b90f87c 100644 --- a/packages/vkui/src/components/Flex/Flex.test.tsx +++ b/packages/vkui/src/components/Flex/Flex.test.tsx @@ -7,16 +7,27 @@ import gapStyles from '../../styles/gaps.module.css'; describe(Flex, () => { baselineComponent(Flex); - it('should have css custom variable with gaps values', () => { + it('should have css custom variable with gaps values for several child', () => { render(
+
, ); expect(screen.getByTestId('flex')).toHaveStyle('--vkui_internal--row_gap: 20px'); expect(screen.getByTestId('flex')).toHaveStyle('--vkui_internal--column_gap: 15px'); }); + it('should not have css custom variable with gaps values for one child', () => { + render( + +
+
, + ); + expect(screen.getByTestId('flex')).not.toHaveStyle('--vkui_internal--row_gap: 20px'); + expect(screen.getByTestId('flex')).not.toHaveStyle('--vkui_internal--column_gap: 15px'); + }); + describe('check correct classNames', () => { it.each<{ props: Partial; className: string }>([ { @@ -71,6 +82,7 @@ describe(Flex, () => { render(
+
, ); expect(screen.getByTestId('flex')).toHaveClass(className); diff --git a/packages/vkui/src/components/Flex/Flex.tsx b/packages/vkui/src/components/Flex/Flex.tsx index 9deecc009d..b516e47e24 100644 --- a/packages/vkui/src/components/Flex/Flex.tsx +++ b/packages/vkui/src/components/Flex/Flex.tsx @@ -1,7 +1,9 @@ +import { Children } from 'react'; import { classNames } from '@vkontakte/vkjs'; import { calculateGap, columnGapClassNames, + type GapProp, type GapsProp, rowGapClassNames, } from '../../lib/layouts'; @@ -83,17 +85,11 @@ export const Flex: React.FC & { direction = 'row', style: styleProp, reverse = false, + children, ...props }: FlexProps) => { - const [columnGap, rowGap] = calculateGap(gap); - const style: CSSCustomProperties = {}; - - if (typeof rowGap === 'number') { - style['--vkui_internal--row_gap'] = `${rowGap}px`; - } - if (typeof columnGap === 'number') { - style['--vkui_internal--column_gap'] = `${columnGap}px`; - } + const withGaps = Children.count(children) > 1 && gap; + const [columnGap, rowGap] = calculateGap(withGaps ? gap : undefined); return ( & { reverse && styles['Flex--reverse'], direction !== 'row' && styles['Flex--direction-column'], margin !== 'none' && styles['Flex--margin-auto'], - typeof columnGap === 'string' && columnGapClassNames[columnGap], - typeof rowGap === 'string' && rowGapClassNames[rowGap], align && alignClassNames[align], justify && justifyClassNames[justify], + withGaps && styles['Flex--withGaps'], + withGaps && getGapsPresets(rowGap, columnGap), )} - style={{ ...styleProp, ...style }} - /> + style={withGaps ? { ...getGapsByUser(rowGap, columnGap), ...styleProp } : styleProp} + > + {children} + ); }; +function getGapsPresets(rowGap?: GapProp, columnGap?: GapProp) { + return classNames( + typeof rowGap === 'string' && rowGapClassNames[rowGap], + typeof columnGap === 'string' && columnGapClassNames[columnGap], + ); +} + +function getGapsByUser(rowGap?: GapProp, columnGap?: GapProp) { + const style: CSSCustomProperties = {}; + + if (typeof rowGap === 'number') { + style['--vkui_internal--row_gap'] = `${rowGap}px`; + } + if (typeof columnGap === 'number') { + style['--vkui_internal--column_gap'] = `${columnGap}px`; + } + + return style; +} + Flex.Item = FlexItem; diff --git a/packages/vkui/src/components/Flex/__image_snapshots__/flex-rendering-android-chromium-light-1-snap.png b/packages/vkui/src/components/Flex/__image_snapshots__/flex-rendering-android-chromium-light-1-snap.png index 86d2e6df29..14c96ebea6 100644 --- a/packages/vkui/src/components/Flex/__image_snapshots__/flex-rendering-android-chromium-light-1-snap.png +++ b/packages/vkui/src/components/Flex/__image_snapshots__/flex-rendering-android-chromium-light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:557bc49d99694b39e8d0e1eeb102d28dbc94ba779b3d297e6a1dd33d23eed859 -size 19413 +oid sha256:6f8a0e53261c30eeb2d5665dca115ec0e3c32a9237861bf054a43cef53041231 +size 19464