Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: deprecate vk-bridge #5496

Merged
merged 12 commits into from
Aug 16, 2023
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<a href="https://npmjs.com/package/@vkontakte/vkui"><img src="https://img.shields.io/npm/v/@vkontakte/vkui/latest.svg?maxAge=3600" alt="open latest version"></a>
</p>
<p align="center">
VKUI — это библиотека адаптивных React-компонентов, <br> для создания веб-приложений и <a href="https://dev.vk.com/mini-apps/overview">VK Mini Apps</a> в экосистеме ВКонтакте.<br>
VKUI — это библиотека адаптивных React-компонентов<br> для создания веб-приложений.<br>
Библиотека основана на <a href="https://www.figma.com/@vk">дизайн-системе ВКонтакте</a> и реализует её интерфейсы для различных платформ.<br>
Релизы: <a href="https://github.com/VKCOM/VKUI/releases">https://github.com/VKCOM/VKUI/releases</a>.<br>
Гайд по миграции <a href="https://vkcom.github.io/VKUI/#/Migration">на версию 5</a>.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import { useGlobals } from '@storybook/manager-api';
import { IconButton, Icons } from '@storybook/components';
import { PARAM_KEY } from './constants';

export const HasCustomPanelHeaderAfter = () => {
const [globals, updateGlobals] = useGlobals();
const active = globals[PARAM_KEY];

const toggle = React.useCallback(() => {
updateGlobals({ [PARAM_KEY]: !active });
}, [updateGlobals, active]);

return (
<IconButton active={active} key="customPanelHeaderAfter" onClick={toggle}>
<Icons icon="browser" />
&nbsp; hasCustomPanelHeaderAfter
</IconButton>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const ADDON_ID = 'storybook/customPanelHeaderAfter';
export const PARAM_KEY = 'hasCustomPanelHeaderAfter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function managerEntries(entry = []) {
return [...entry, require.resolve('./register.ts')];
}

module.exports = {
managerEntries,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { addons, types } from '@storybook/manager-api';
import { HasCustomPanelHeaderAfter } from './HasCustomPanelHeaderAfter';
import { ADDON_ID } from './constants';

addons.register(ADDON_ID, () => {
addons.add(ADDON_ID, {
title: 'CustomPanelHeaderAfter',
type: types.TOOL,
match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
render: HasCustomPanelHeaderAfter,
});
});
1 change: 1 addition & 0 deletions packages/vkui/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const config: StorybookConfig = {
'@project-tools/storybook-addon-cartesian',
'./addons/appearance',
'./addons/pointer',
'./addons/customPanelHeaderAfter',
'storybook-addon-swc',
],
framework: {
Expand Down
14 changes: 4 additions & 10 deletions packages/vkui/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '../src/styles/adaptivity.module.css';

import { Preview } from '@storybook/react';
import { BREAKPOINTS } from '../src/lib/adaptivity';
import { Platform, Appearance, WebviewType } from '../src';
import { Platform, Appearance } from '../src';
import { withVKUIWrapper } from '../src/storybook/VKUIDecorators';

interface CustomViewPortItem {
Expand Down Expand Up @@ -66,15 +66,9 @@ const preview: Preview = {
dynamicTitle: true,
},
},
webviewType: {
name: 'WebviewType',
defaultValue: WebviewType.INTERNAL,
toolbar: {
icon: 'component',
items: [WebviewType.INTERNAL, WebviewType.VKAPPS],
title: 'WebviewType',
dynamicTitle: true,
},
hasCustomPanelHeaderAfter: {
description: 'Hide "after" prop of PanelHeader for custom floating "after" element',
defaultValue: false,
},
},
argTypes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import { hasMouse as _hasPointer } from '@vkontakte/vkjs';
import { BridgeAdaptivity, useBridgeAdaptivity } from '../../hooks/useBridgeAdaptivity';
import { BREAKPOINTS, SizeType, ViewHeight, ViewWidth } from '../../lib/adaptivity';
import { warnOnce } from '../../lib/warnOnce';
import { HasChildren } from '../../types';
import { AdaptivityContext, type AdaptivityProps } from './AdaptivityContext';

const warn = warnOnce('AdaptivityProvider');

export interface AdaptivityProviderProps extends AdaptivityProps, HasChildren {}

/**
Expand All @@ -19,7 +22,24 @@
hasHover,
children,
}: AdaptivityProviderProps) => {
const bridge = useBridgeAdaptivity();
// TODO [>=6]: удалить использование хука (#5049)
/* eslint-disable @typescript-eslint/naming-convention */
const LEGACY_isPerhapsPropsByBridgeTypeAdaptive =
viewWidth !== undefined && viewHeight !== undefined;
const LEGACY_isPerhapsPropsByBridgeTypeForceMobile =
viewWidth !== undefined && sizeX !== undefined && sizeY !== undefined;
const LEGACY_disableInternalUseBridgeAdaptivity =
LEGACY_isPerhapsPropsByBridgeTypeAdaptive || LEGACY_isPerhapsPropsByBridgeTypeForceMobile;
const LEGACY_bridge = useBridgeAdaptivity(LEGACY_disableInternalUseBridgeAdaptivity);
/* eslint-enable @typescript-eslint/naming-convention */

if (process.env.NODE_ENVIRONMENT === 'development') {
// TODO [>=6]: удалить warn
if (!LEGACY_disableInternalUseBridgeAdaptivity) {
warn("[@vkontakte/vk-bridge] Интеграция VKUI с @vkontakte/vk-bridge устарела и будет удалена в v6. Используйте хук `useAdaptivity()` из @vkontakte/vk-bridge-react и результат передайте в компонент (см. https://github.com/VKCOM/VKUI/issues/5049)"); // prettier-ignore

Check warning on line 39 in packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx

View check run for this annotation

Codecov / codecov/patch

packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx#L38-L39

Added lines #L38 - L39 were not covered by tests
}
}

const adaptivity = React.useMemo(
() =>
calculateAdaptivity(
Expand All @@ -31,20 +51,22 @@
hasPointer,
hasHover,
},
bridge,
LEGACY_bridge,
),
[viewWidth, viewHeight, sizeX, sizeY, hasPointer, hasHover, bridge],
[viewWidth, viewHeight, sizeX, sizeY, hasPointer, hasHover, LEGACY_bridge],
);

return <AdaptivityContext.Provider value={adaptivity}>{children}</AdaptivityContext.Provider>;
};

function calculateAdaptivity(
{ viewWidth, viewHeight, sizeX, sizeY, hasPointer, hasHover }: AdaptivityProps,
bridge: BridgeAdaptivity,
LEGACY_bridge: BridgeAdaptivity, // eslint-disable-line @typescript-eslint/naming-convention
) {
if (bridge.type === 'adaptive') {
const { viewportWidth, viewportHeight } = bridge;
// TODO [>=6]: удалить блок кода c использованием LEGACY_bridge (#5049)
// https://github.com/VKCOM/VKUI/blob/v5.5.5/packages/vkui/src/components/AdaptivityProvider/AdaptivityProvider.tsx#L46-L92
if (LEGACY_bridge.type === 'adaptive') {
const { viewportWidth, viewportHeight } = LEGACY_bridge;

if (viewportWidth >= BREAKPOINTS.DESKTOP) {
viewWidth = ViewWidth.DESKTOP;
Expand Down Expand Up @@ -80,11 +102,14 @@
} else {
sizeY = SizeType.REGULAR;
}
} else if (bridge.type === 'force_mobile' || bridge.type === 'force_mobile_compact') {
} else if (
LEGACY_bridge.type === 'force_mobile' ||
LEGACY_bridge.type === 'force_mobile_compact'
) {
viewWidth = ViewWidth.MOBILE;
sizeX = SizeType.COMPACT;

if (bridge.type === 'force_mobile_compact') {
if (LEGACY_bridge.type === 'force_mobile_compact') {
sizeY = SizeType.COMPACT;
} else {
sizeY = SizeType.REGULAR;
Expand Down
27 changes: 23 additions & 4 deletions packages/vkui/src/components/AppRoot/AppRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { IconSettingsProvider } from '@vkontakte/icons';
import { Insets } from '@vkontakte/vk-bridge';
import { classNames, noop } from '@vkontakte/vkjs';
import { useAdaptivity } from '../../hooks/useAdaptivity';
import { useAppearance } from '../../hooks/useAppearance';
Expand All @@ -10,10 +9,20 @@
import { useDOM } from '../../lib/dom';
import { isRefObject } from '../../lib/isRefObject';
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
import { warnOnce } from '../../lib/warnOnce';
import { AppRootContext } from './AppRootContext';
import { ElementScrollController, GlobalScrollController } from './ScrollContext';
import styles from './AppRoot.module.css';

const warn = warnOnce('AppRoot');

export type SafeAreaInsets = {
top?: number;
right?: number;
bottom?: number;
left?: number;
};

const vkuiSizeXClassNames = {
none: 'vkui--sizeX-none',
[SizeType.REGULAR]: 'vkui--sizeX-regular',
Expand All @@ -29,6 +38,7 @@
mode?: 'partial' | 'embedded' | 'full';
window?: Window;
scroll?: 'global' | 'contain';
safeAreaInsets?: SafeAreaInsets;
/**
* Кастомный root-элемент портала
*/
Expand All @@ -47,17 +57,26 @@
portalRoot: portalRootProp = null,
disablePortal,
className,
safeAreaInsets,
...props
}: AppRootProps) => {
const isKeyboardInputActive = useKeyboardInputTracker();
const rootRef = React.useRef<HTMLDivElement | null>(null);
const [portalRoot, setPortalRoot] = React.useState<HTMLElement | null>(null);
const { document } = useDOM();
const insets = useInsets();
const deprecatedInsets = useInsets(!safeAreaInsets);
const insets = safeAreaInsets ? safeAreaInsets : deprecatedInsets;
const appearance = useAppearance();

const { hasPointer, sizeX = 'none' } = useAdaptivity();

if (process.env.NODE_ENVIRONMENT === 'development') {
if (!safeAreaInsets) {

Check warning on line 74 in packages/vkui/src/components/AppRoot/AppRoot.tsx

View check run for this annotation

Codecov / codecov/patch

packages/vkui/src/components/AppRoot/AppRoot.tsx#L74

Added line #L74 was not covered by tests
// TODO [>=6]: удалить warn
warn("[@vkontakte/vk-bridge] Интеграция VKUI с @vkontakte/vk-bridge устарела и будет удалена в v6. Используйте хук `useInsets()` из @vkontakte/vk-bridge-react и результат передайте в параметр `safeAreaInsets` (см. https://github.com/VKCOM/VKUI/issues/5049)"); // prettier-ignore

Check warning on line 76 in packages/vkui/src/components/AppRoot/AppRoot.tsx

View check run for this annotation

Codecov / codecov/patch

packages/vkui/src/components/AppRoot/AppRoot.tsx#L76

Added line #L76 was not covered by tests
}
}

// setup portal
useIsomorphicLayoutEffect(() => {
let portal: HTMLElement | null = null;
Expand Down Expand Up @@ -115,7 +134,7 @@

const parent = rootRef.current.parentElement;

let key: keyof Insets;
let key: keyof SafeAreaInsets;
for (key in insets) {
if (insets.hasOwnProperty(key) && typeof insets[key] === 'number') {
const inset = insets[key];
Expand All @@ -126,7 +145,7 @@
}

return () => {
let key: keyof Insets;
let key: keyof SafeAreaInsets;
for (key in insets) {
if (insets.hasOwnProperty(key)) {
parent.style.removeProperty(INSET_CUSTOM_PROPERTY_PREFIX + key);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppearanceType } from '@vkontakte/vk-bridge';
import { usePlatform } from '../../hooks/usePlatform';
import type { AppearanceType } from '../../lib/appearance';
import { TokensClassProvider } from '../../lib/tokensClassProvider';
import { ConfigProviderOverride } from '../ConfigProvider/ConfigProviderOverride';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('ConfigProvider', () => {
it('provides config context', () => {
const config = {
appearance: Appearance.LIGHT,
webviewType: WebviewType.INTERNAL,
hasCustomPanelHeaderAfter: false,
transitionMotionEnabled: false,
};
const ConfigUser = () => {
Expand All @@ -24,7 +24,8 @@ describe('ConfigProvider', () => {
isWebView: false,
locale: 'ru',
appearance: Appearance.LIGHT,
webviewType: WebviewType.INTERNAL,
hasCustomPanelHeaderAfter: false,
customPanelHeaderAfterMinWidth: 90,
transitionMotionEnabled: false,
});
return null;
Expand All @@ -35,6 +36,59 @@ describe('ConfigProvider', () => {
</ConfigProvider>,
);
});
// TODO [>=6] Удалить этот тест на бэкпорт
describe('[deprecated] test webviewType backport', () => {
it('convert WebviewType.INTERNAL to hasCustomPanelHeaderAfter={false}', () => {
const config = {
appearance: Appearance.LIGHT,
webviewType: WebviewType.INTERNAL,
transitionMotionEnabled: false,
};
const ConfigUser = () => {
expect(useContext(ConfigProviderContext)).toEqual({
platform: Platform.ANDROID,
isWebView: false,
locale: 'ru',
appearance: Appearance.LIGHT,
webviewType: WebviewType.INTERNAL,
hasCustomPanelHeaderAfter: false,
customPanelHeaderAfterMinWidth: 90,
transitionMotionEnabled: false,
});
return null;
};
render(
<ConfigProvider {...config}>
<ConfigUser />
</ConfigProvider>,
);
});
it('convert WebviewType.VKAPPS to hasCustomPanelHeaderAfter={true}', () => {
const config = {
appearance: Appearance.LIGHT,
webviewType: WebviewType.VKAPPS,
transitionMotionEnabled: false,
};
const ConfigUser = () => {
expect(useContext(ConfigProviderContext)).toEqual({
platform: Platform.ANDROID,
isWebView: false,
locale: 'ru',
appearance: Appearance.LIGHT,
webviewType: WebviewType.VKAPPS,
hasCustomPanelHeaderAfter: true,
customPanelHeaderAfterMinWidth: 90,
transitionMotionEnabled: false,
});
return null;
};
render(
<ConfigProvider {...config}>
<ConfigUser />
</ConfigProvider>,
);
});
});
describe('inherits properties from parent ConfigProvider context', () => {
let config: ConfigProviderContextInterface | undefined;
const ReadConfig = () => {
Expand All @@ -45,14 +99,20 @@ describe('ConfigProvider', () => {
const defaultConfig: ConfigProviderContextInterface = {
platform: Platform.VKCOM,
appearance: Appearance.DARK,
// TODO [>=6] Удалить webviewType
webviewType: WebviewType.INTERNAL,
hasCustomPanelHeaderAfter: true,
customPanelHeaderAfterMinWidth: 90,
transitionMotionEnabled: false,
isWebView: true,
locale: 'en',
};
it.each([
['platform', Platform.ANDROID],
// TODO [>=6] Удалить webviewType
['webviewType', WebviewType.VKAPPS],
['hasCustomPanelHeaderAfter', false],
['customPanelHeaderAfterMinWidth', 100],
['transitionMotionEnabled', true],
['isWebView', false],
['platform', Appearance.LIGHT],
Expand Down
Loading
Loading