From f662902c94d907a64469651b8dc36b88fbc17c19 Mon Sep 17 00:00:00 2001 From: Andrey Medvedev Date: Fri, 16 Feb 2024 14:17:09 +0300 Subject: [PATCH] Applying changes from v6 to AdaptiveProvider (#6536) (#6585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Это черри пик merge коммита bf26ee0145f26a1ea622d079b6349f06dc474812 из #6489 Попытка перенести исправления в подсчёте `sizeY` у `AdoptivityProvider` из v6 в v5. https://github.com/VKCOM/VKUI/issues/6476) был именно для v5. - в целом мы полностью переносим логику затрагивающую работу `AdoptivityProvider` без `bridge`. В то же время логику c `bridge` мы не трогаем. В том числе оставляем *неявное* использование `_hasPointer` из `vkjs` и игнорирование `hasPointer` свойства `AdoptivityProvider`. Сделано специально, чтобы никак не затронуть пользователей bridge, ведь на них баг не распространяется. https://github.com/VKCOM/VKUI/blob/f361335092b365360b3b8ee65c145fb6b621a414/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx#L105-L112 https://github.com/VKCOM/VKUI/blob/f361335092b365360b3b8ee65c145fb6b621a414/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx#L2 ```js export const hasMouse = /*#__PURE__*/ (() => detect.hasMouse)(); ``` [hasMouse source](https://github.com/VKCOM/vkjs/blob/3ab9216c6c9f7f48998176e9403eaba7450b9a31/src/InputUtils.ts#L48) Также я заметил, что есть специльный тест, котороый реагирует именно на `_hasPointer` проверку, так что оставил, в v6 мы всё равно это убираем. https://github.com/VKCOM/VKUI/blob/f361335092b365360b3b8ee65c145fb6b621a414/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.test.tsx#L300-L308 --- .../AdaptivityProvider.test.tsx | 477 +++++++++++++++--- .../AdaptivityProvider/AdaptivityProvider.tsx | 26 +- packages/vkui/src/lib/adaptivity/functions.ts | 10 +- 3 files changed, 440 insertions(+), 73 deletions(-) diff --git a/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.test.tsx b/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.test.tsx index d31faea755..8b2ac4486b 100644 --- a/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.test.tsx +++ b/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.test.tsx @@ -1,58 +1,111 @@ import * as React from 'react'; -import { render, screen } from '@testing-library/react'; -import { type BridgeAdaptivity, useBridgeAdaptivity } from '../../hooks/useBridgeAdaptivity'; +import { render } from '@testing-library/react'; +import { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries'; +import { type BridgeAdaptivity } from '../../hooks/useBridgeAdaptivity'; import { SizeType, ViewHeight, ViewWidth } from '../../lib/adaptivity'; import { baselineComponent } from '../../testing/utils'; import { AdaptivityContext, type AdaptivityProps } from './AdaptivityContext'; import { AdaptivityProvider, type AdaptivityProviderProps } from './AdaptivityProvider'; +const bridgeMock = jest.fn(() => { + return { + type: '', + viewportWidth: 0, + viewportHeight: 0, + }; +}); jest.mock('../../hooks/useBridgeAdaptivity', () => { - const bridgeMock = jest.fn(() => { - return { - type: '', - viewportWidth: 0, - viewportHeight: 0, - }; - }); + return { + useBridgeAdaptivity: () => bridgeMock(), + }; +}); +const hasPointerStub = jest.fn().mockReturnValue(true); +jest.mock('@vkontakte/vkjs', () => ({ + get canUseDOM() { + return true; + }, + detectIOS: () => false, + get hasMouse() { + return hasPointerStub(); + }, +})); +jest.mock('../../hooks/useMediaQueries', () => ({ + useMediaQueries: () => ({ + desktopPlus: () => jest.fn(), + smallTabletPlus: () => jest.fn(), + tablet: () => jest.fn(), + smallTablet: () => jest.fn(), + mobile: () => jest.fn(), + mediumHeight: () => jest.fn(), + mobileLandscapeHeight: () => jest.fn(), + }), +})); +jest.mock('../../lib/matchMedia', () => ({ + matchMediaListAddListener: () => jest.fn(), + matchMediaListRemoveListener: () => jest.fn(), +})); + +const getViewWidthByMediaQueriesStub = jest.fn().mockReturnValue(ViewWidth.SMALL_MOBILE); +const getViewHeightByMediaQueriesStub = jest.fn().mockReturnValue(ViewHeight.SMALL); +jest.mock('../../lib/adaptivity', () => { return { - useBridgeAdaptivity: bridgeMock, + ...jest.requireActual('../../lib/adaptivity'), + getViewWidthByMediaQueries: () => getViewWidthByMediaQueriesStub(), + getViewHeightByMediaQueries: () => getViewHeightByMediaQueriesStub(), }; }); -function CatchAdaptivityProviderContext() { - const { sizeX, sizeY, viewWidth, viewHeight } = React.useContext(AdaptivityContext); - - return ( -
- ); +jest.mock('../../lib/platform', () => { + return { + ...jest.requireActual('../../lib/platform'), + platform: () => 'vkcom', + }; +}); +jest.mock('../../hooks/usePlatform', () => { + return { + usePlatform: () => 'vkcom', + }; +}); + +interface AdaptivityResultsRef { + adaptivityProviderResults: AdaptivityProps; + adaptivityWithJsMediaQueriesHookResults: AdaptivityProps; } -function renderAdaptiveProvider(props?: AdaptivityProviderProps): AdaptivityProps { - render( - - - , +const CatchAdaptivityProviderContext = React.forwardRef((_, ref) => { + const adaptivityProviderResults = React.useContext(AdaptivityContext); + const adaptivityWithJsMediaQueriesHookResults = useAdaptivityWithJSMediaQueries(); + + React.useImperativeHandle( + ref, + () => ({ + adaptivityProviderResults, + adaptivityWithJsMediaQueriesHookResults, + }), + [adaptivityProviderResults, adaptivityWithJsMediaQueriesHookResults], ); - const elWithContextData = screen.getByTestId('adaptivity-provider-context'); + return null; +}); - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return { - sizeX: elWithContextData.dataset.sizeX, - sizeY: elWithContextData.dataset.sizeY, - viewWidth: elWithContextData.dataset.viewWidth - ? Number(elWithContextData.dataset.viewWidth) - : undefined, - viewHeight: elWithContextData.dataset.viewHeight - ? Number(elWithContextData.dataset.viewHeight) - : undefined, - } as AdaptivityProps; +const TestAdaptiveProvider = React.forwardRef( + (props, ref) => ( + + + + ), +); + +function renderAdaptiveProvider(props?: AdaptivityProviderProps): AdaptivityProps { + const adaptivityProviderResultsRef = React.createRef(); + + render(); + + if (!adaptivityProviderResultsRef.current) { + throw new Error('adaptivityProviderResultsRef.current is not defined'); + } + + return adaptivityProviderResultsRef.current?.adaptivityProviderResults; } function renderAdaptiveProviderWithBridge( @@ -61,7 +114,7 @@ function renderAdaptiveProviderWithBridge( viewportHeight = 0, hasPointer?: boolean, ) { - (useBridgeAdaptivity as jest.Mock).mockReturnValue({ + bridgeMock.mockReturnValue({ type, viewportWidth, viewportHeight, @@ -72,7 +125,7 @@ function renderAdaptiveProviderWithBridge( describe('AdaptivityProvider', () => { beforeEach(() => { - (useBridgeAdaptivity as jest.Mock).mockReturnValue({ + bridgeMock.mockReturnValue({ type: '', viewportWidth: 0, viewportHeight: 0, @@ -83,8 +136,11 @@ describe('AdaptivityProvider', () => { describe('without bridge', () => { it('should return undefined adaptivity props', () => { - const result = renderAdaptiveProvider(); - expect(result).toEqual({ + const adaptivityProviderResultsRef = React.createRef(); + + render(); + + expect(adaptivityProviderResultsRef.current?.adaptivityProviderResults).toMatchObject({ sizeX: undefined, sizeY: undefined, viewWidth: undefined, @@ -93,11 +149,25 @@ describe('AdaptivityProvider', () => { }); it('should define sizeX and sizeY adaptivity props', () => { - const result = renderAdaptiveProvider({ + expect( + renderAdaptiveProvider({ + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + }), + ).toMatchObject({ + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, viewWidth: ViewWidth.DESKTOP, viewHeight: ViewHeight.MEDIUM, }); - expect(result).toEqual({ + + expect( + renderAdaptiveProvider({ + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + hasPointer: true, + }), + ).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.DESKTOP, @@ -109,7 +179,7 @@ describe('AdaptivityProvider', () => { describe('with bridge', () => { it('should apply bridge adaptivity [viewWidth] SMALL_MOBILE', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 300, 420); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.REGULAR, viewWidth: ViewWidth.SMALL_MOBILE, @@ -119,7 +189,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewWidth] MOBILE', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 320, 420); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.REGULAR, viewWidth: ViewWidth.MOBILE, @@ -129,7 +199,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewWidth] SMALL_TABLET', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 768, 420); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.SMALL_TABLET, @@ -139,7 +209,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewWidth] TABLET', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 1024, 420); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.TABLET, @@ -149,7 +219,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewWidth] DESKTOP', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 1280, 420); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.DESKTOP, @@ -159,7 +229,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewHeight] EXTRA_SMALL', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 320, 340); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.MOBILE, @@ -169,7 +239,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewHeight] SMALL', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 320, 415); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.REGULAR, viewWidth: ViewWidth.MOBILE, @@ -179,7 +249,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [viewHeight] MEDIUM', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 320, 720); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.REGULAR, viewWidth: ViewWidth.MOBILE, @@ -189,7 +259,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [both] SMALL_MOBILE / EXTRA_SMALL', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 300, 340); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.SMALL_MOBILE, @@ -199,7 +269,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [both] SMALL_TABLET / SMALL', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 768, 415); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.SMALL_TABLET, @@ -209,7 +279,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [both] TABLET / MEDIUM', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 1024, 720); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.TABLET, @@ -219,7 +289,7 @@ describe('AdaptivityProvider', () => { it('should apply bridge adaptivity [both] DESKTOP / MEDIUM', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 1280, 720); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.DESKTOP, @@ -229,7 +299,7 @@ describe('AdaptivityProvider', () => { it('should ignore custom mouse with bridge [viewWidth] SMALL_TABLET', () => { const result = renderAdaptiveProviderWithBridge('adaptive', 768, 420, false); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.REGULAR, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.SMALL_TABLET, @@ -239,7 +309,7 @@ describe('AdaptivityProvider', () => { it('should use bridge force_mobile preset', () => { const result = renderAdaptiveProviderWithBridge('force_mobile'); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.REGULAR, viewWidth: ViewWidth.MOBILE, @@ -249,7 +319,7 @@ describe('AdaptivityProvider', () => { it('should use bridge force_mobile_compact preset', () => { const result = renderAdaptiveProviderWithBridge('force_mobile_compact'); - expect(result).toEqual({ + expect(result).toMatchObject({ sizeX: SizeType.COMPACT, sizeY: SizeType.COMPACT, viewWidth: ViewWidth.MOBILE, @@ -258,3 +328,290 @@ describe('AdaptivityProvider', () => { }); }); }); + +interface TestSuite { + inProps: AdaptivityProviderProps & { + runOnlyThisSuite?: boolean; + }; + outProps: AdaptivityProps; +} + +const testSuites: TestSuite[] = [ + { + inProps: { + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.COMPACT, + viewWidth: ViewWidth.DESKTOP, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + viewWidth: ViewWidth.MOBILE, + viewHeight: ViewHeight.EXTRA_SMALL, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.COMPACT, + viewWidth: ViewWidth.MOBILE, + viewHeight: ViewHeight.EXTRA_SMALL, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.COMPACT, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + sizeX: SizeType.COMPACT as const, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.REGULAR, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + sizeX: SizeType.COMPACT as const, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.COMPACT, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + sizeY: SizeType.REGULAR as const, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + sizeX: SizeType.REGULAR as const, + sizeY: SizeType.REGULAR as const, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + viewWidth: ViewWidth.SMALL_TABLET, + viewHeight: ViewHeight.MEDIUM, + }, + }, + { + inProps: { + sizeX: SizeType.REGULAR as const, + sizeY: SizeType.REGULAR as const, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_MOBILE, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_MOBILE, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.MOBILE, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.MOBILE, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.COMPACT, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_TABLET, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.SMALL_TABLET, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.COMPACT, + }, + }, + { + inProps: { + viewWidth: ViewWidth.TABLET, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.TABLET, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.COMPACT, + }, + }, + { + inProps: { + viewWidth: ViewWidth.DESKTOP, + hasPointer: false, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.REGULAR, + }, + }, + { + inProps: { + viewWidth: ViewWidth.DESKTOP, + hasPointer: true, + }, + outProps: { + sizeX: SizeType.REGULAR, + sizeY: SizeType.COMPACT, + }, + }, +]; + +describe('AdaptiveProvider without bridge and useAdaptivityWithJSMediaQueries should return similar results', () => { + beforeAll(() => { + bridgeMock.mockReturnValue({ + type: '', + viewportWidth: 0, + viewportHeight: 0, + }); + }); + testSuites.map((testOptions) => { + const { inProps, outProps } = testOptions; + + describe(`should define sizeX and sizeY adaptivity props for input: \n${JSON.stringify( + inProps, + null, + '\t', + )}\n`, () => { + beforeEach(() => { + hasPointerStub.mockReturnValue(false); + getViewWidthByMediaQueriesStub.mockReturnValue(() => inProps.viewWidth); + getViewHeightByMediaQueriesStub.mockReturnValue(() => inProps.viewHeight); + }); + + const test = inProps.runOnlyThisSuite ? it.only : it; + test('AdaptiveProvider', () => { + const adaptivityProviderResultsRef = React.createRef(); + + render(); + + // AdaptivityProvider results + expect(adaptivityProviderResultsRef.current?.adaptivityProviderResults).toMatchObject( + outProps, + ); + }); + + test('useAdaptivityWithJSMediaQueries', () => { + const adaptivityProviderResultsRef = React.createRef(); + + render(); + + // useAdaptivityWithJSMediaQueries results + expect( + adaptivityProviderResultsRef.current?.adaptivityWithJsMediaQueriesHookResults, + ).toMatchObject(outProps); + }); + }); + }); +}); diff --git a/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx b/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx index 421d6b78dc..12f4e0cdf3 100644 --- a/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx +++ b/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx @@ -1,7 +1,15 @@ import * as React from 'react'; import { hasMouse as _hasPointer } from '@vkontakte/vkjs'; import { BridgeAdaptivity, useBridgeAdaptivity } from '../../hooks/useBridgeAdaptivity'; -import { BREAKPOINTS, SizeType, ViewHeight, ViewWidth } from '../../lib/adaptivity'; +import { + BREAKPOINTS, + getSizeX, + isCompactByViewHeight, + isCompactByViewWidth, + SizeType, + ViewHeight, + ViewWidth, +} from '../../lib/adaptivity'; import { warnOnce } from '../../lib/warnOnce'; import { HasChildren } from '../../types'; import { AdaptivityContext, type AdaptivityProps } from './AdaptivityContext'; @@ -116,19 +124,13 @@ function calculateAdaptivity( } } else { if (sizeX === undefined && viewWidth !== undefined) { - if (viewWidth <= ViewWidth.MOBILE) { - sizeX = SizeType.COMPACT; - } else { - sizeX = SizeType.REGULAR; - } + sizeX = getSizeX(viewWidth); } - if (sizeY === undefined && viewWidth !== undefined && viewHeight !== undefined) { - if ( - (viewWidth >= ViewWidth.SMALL_TABLET && _hasPointer) || - viewHeight <= ViewHeight.EXTRA_SMALL - ) { + + if (sizeY === undefined) { + if (isCompactByViewWidth(viewWidth, hasPointer) || isCompactByViewHeight(viewHeight)) { sizeY = SizeType.COMPACT; - } else { + } else if (viewWidth !== undefined || viewHeight !== undefined) { sizeY = SizeType.REGULAR; } } diff --git a/packages/vkui/src/lib/adaptivity/functions.ts b/packages/vkui/src/lib/adaptivity/functions.ts index a2e6875fa2..a9940cce2e 100644 --- a/packages/vkui/src/lib/adaptivity/functions.ts +++ b/packages/vkui/src/lib/adaptivity/functions.ts @@ -75,12 +75,20 @@ export function getSizeX(viewWidth: ViewWidth): SizeType { return viewWidth <= ViewWidth.MOBILE ? SizeType.COMPACT : SizeType.REGULAR; } +export function isCompactByViewWidth(viewWidth: ViewWidth | undefined, hasPointer?: boolean) { + return viewWidth !== undefined && viewWidth >= ViewWidth.SMALL_TABLET && hasPointer; +} + +export function isCompactByViewHeight(viewHeight: ViewHeight | undefined) { + return viewHeight !== undefined && viewHeight <= ViewHeight.EXTRA_SMALL; +} + export function getSizeY( viewWidth: ViewWidth, viewHeight: ViewHeight, hasPointer: boolean, ): SizeType { - if ((viewWidth >= ViewWidth.SMALL_TABLET && hasPointer) || viewHeight <= ViewHeight.EXTRA_SMALL) { + if (isCompactByViewWidth(viewWidth, hasPointer) || isCompactByViewHeight(viewHeight)) { return SizeType.COMPACT; } return SizeType.REGULAR;