From be5ef3ec08c5b70ac54c17df18290c2844988874 Mon Sep 17 00:00:00 2001 From: EldarMuhamethanov <61377022+EldarMuhamethanov@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:47:27 +0300 Subject: [PATCH] [BREAKING CHANGE] feat: rename appearance to colorScheme (#7728) * feat: rename AppearanceType to ColorSchemeType, Appearance to ColorScheme * feat: rename useAppearance to useColorScheme, useAutoDetectAppearance to useAutoDetectColorScheme * feat: rename appearance props to colorScheme props in styleguide and storybook * feat: rename useAppearanceProvider to useColorSchemeProvider * feat: add codemod to renaming Appearance, AppearanceType to ColorScheme, ColorSchemeType * feat: add codemod to renaming AppearanceProvider, AppearanceProviderProps to ColorSchemeProvider, ColorSchemeTypeProps * feat: add codemod to renaming useAppearance to useColorScheme * feat: add codemod to renaming ConfigProvider prop appearance to colorScheme * feat: rename identifier * Update styleguide/pages/integrations_vk_mini_apps.md revert renaming Co-authored-by: Inomdzhon Mirdzhamolov * Update styleguide/pages/platforms_and_themes.md Co-authored-by: Inomdzhon Mirdzhamolov * fix: revert change link * fix: rename appearance to colorScheme in storybook theme addon --------- Co-authored-by: Inomdzhon Mirdzhamolov --- docs/TESTING.md | 2 +- packages/codemods/src/codemod-helpers.ts | 47 ++++ .../appearance-provider/alias.input.tsx | 15 ++ .../appearance-provider/basic.input.tsx | 26 +++ .../appearance/alias.input.tsx | 20 ++ .../appearance/basic.input.tsx | 24 +++ .../config-provider/basic.input.tsx | 33 +++ .../__snapshots__/appearance-provider.ts.snap | 48 +++++ .../__snapshots__/appearance.ts.snap | 51 +++++ .../__snapshots__/config-provider.ts.snap | 33 +++ .../v7/__tests__/appearance-provider.ts | 12 ++ .../src/transforms/v7/__tests__/appearance.ts | 12 ++ .../v7/__tests__/config-provider.ts | 12 ++ .../src/transforms/v7/appearance-provider.ts | 54 +++++ .../codemods/src/transforms/v7/appearance.ts | 77 +++++++ .../src/transforms/v7/config-provider.ts | 204 ++++++++++++++++++ packages/vkui/.env.development.local | 2 +- .../.storybook/addons/appearance/constants.ts | 2 - .../ColorSchemeSwitch.tsx} | 2 +- .../addons/colorScheme/constants.ts | 2 + .../{appearance => colorScheme}/preset.js | 0 .../{appearance => colorScheme}/register.ts | 6 +- .../addons/storybook-theme/StorybookTheme.tsx | 2 +- packages/vkui/.storybook/main.ts | 2 +- packages/vkui/.storybook/preview.ts | 2 +- packages/vkui/playwright-ct.config.ts | 28 +-- .../vkui/src/components/Alert/Alert.e2e.tsx | 2 +- .../src/components/AppRoot/AppRoot.test.tsx | 37 ++-- .../src/components/AppRoot/AppRootPortal.tsx | 8 +- .../vkui/src/components/Button/Button.e2e.tsx | 2 +- .../ColorSchemeProvider.stories.tsx} | 16 +- .../ColorSchemeProvider.tsx} | 14 +- .../ConfigProvider/ConfigProvider.test.tsx | 8 +- .../ConfigProvider/ConfigProvider.tsx | 10 +- .../ConfigProvider/ConfigProviderContext.tsx | 6 +- .../src/components/ConfigProvider/Readme.md | 2 +- .../CustomSelect/CustomSelect.e2e.tsx | 6 +- .../vkui/src/components/Flex/Flex.e2e.tsx | 2 +- .../HorizontalScroll.e2e-playground.tsx | 8 +- .../vkui/src/components/Image/Image.e2e.tsx | 2 +- .../ImageBase/ImageBase.e2e-playground.tsx | 6 +- .../components/ImageBase/ImageBase.e2e.tsx | 2 +- .../ImageBaseOverlay/ImageBaseOverlay.tsx | 6 +- .../vkui/src/components/Link/Link.e2e.tsx | 2 +- .../PanelHeader/PanelHeader.e2e.tsx | 2 +- .../PullToRefresh/PullToRefresh.e2e.tsx | 2 +- .../Search/Search.e2e-playground.tsx | 4 +- .../components/SimpleGrid/SimpleGrid.e2e.tsx | 2 +- .../Slider/Slider.e2e-playground.tsx | 8 +- .../vkui/src/components/Slider/Slider.e2e.tsx | 2 +- .../src/components/Spacing/Spacing.e2e.tsx | 2 +- .../vkui/src/components/Switch/Switch.e2e.tsx | 2 +- .../vkui/src/components/Tabs/Tabs.e2e.tsx | 4 +- .../src/components/Tappable/Tappable.e2e.tsx | 2 +- .../Textarea/Textarea.e2e-playground.tsx | 8 +- .../src/components/Textarea/Textarea.e2e.tsx | 2 +- packages/vkui/src/hooks/useAppearance.ts | 8 - .../src/hooks/useAutoDetectAppearance.test.ts | 40 ++-- ...earance.ts => useAutoDetectColorScheme.ts} | 18 +- packages/vkui/src/hooks/useColorScheme.ts | 8 + packages/vkui/src/index.ts | 10 +- packages/vkui/src/lib/appearance/index.ts | 8 - packages/vkui/src/lib/appearance/types.ts | 1 - packages/vkui/src/lib/colorScheme/index.ts | 8 + packages/vkui/src/lib/colorScheme/types.ts | 1 + .../src/lib/tokens/useTokenClassName.test.tsx | 12 +- .../vkui/src/lib/tokens/useTokenClassName.ts | 14 +- .../vkui/src/storybook/VKUIDecorators.tsx | 4 +- .../src/testing/e2e/ComponentPlayground.tsx | 10 +- .../vkui/src/testing/e2e/index.playwright.ts | 20 +- packages/vkui/src/testing/e2e/types.ts | 6 +- packages/vkui/src/testing/e2e/utils.tsx | 6 +- styleguide/Components/Frame/Frame.js | 8 +- styleguide/Components/Modals/Themes.js | 6 +- styleguide/Components/Preview.js | 20 +- ...pearanceSelect.js => ColorSchemeSelect.js} | 4 +- styleguide/Components/Settings/Settings.js | 10 +- styleguide/Components/Settings/ThemeName.js | 6 +- .../StyleGuide/StyleGuideDesktop.js | 4 +- .../Components/StyleGuide/StyleGuideHeader.js | 10 +- .../Components/StyleGuide/StyleGuideMobile.js | 14 +- .../StyleGuide/StyleGuideRenderer.js | 62 +++--- styleguide/Components/Table/TableRenderer.js | 6 +- styleguide/config.js | 2 +- styleguide/lib/theme/constants.js | 2 +- styleguide/lib/theme/functions.js | 52 ++--- styleguide/lib/theme/useLoadThemeNames.js | 4 +- styleguide/lib/theme/useLoadThemeTokens.js | 8 +- styleguide/pages/integrations_vk_mini_apps.md | 4 +- styleguide/pages/platforms_and_themes.md | 26 +-- 90 files changed, 997 insertions(+), 322 deletions(-) create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/alias.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/appearance/alias.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/appearance/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/config-provider/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance-provider.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/config-provider.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/appearance-provider.ts create mode 100644 packages/codemods/src/transforms/v7/__tests__/appearance.ts create mode 100644 packages/codemods/src/transforms/v7/__tests__/config-provider.ts create mode 100644 packages/codemods/src/transforms/v7/appearance-provider.ts create mode 100644 packages/codemods/src/transforms/v7/appearance.ts create mode 100644 packages/codemods/src/transforms/v7/config-provider.ts delete mode 100644 packages/vkui/.storybook/addons/appearance/constants.ts rename packages/vkui/.storybook/addons/{appearance/AppearanceSwitch.tsx => colorScheme/ColorSchemeSwitch.tsx} (94%) create mode 100644 packages/vkui/.storybook/addons/colorScheme/constants.ts rename packages/vkui/.storybook/addons/{appearance => colorScheme}/preset.js (100%) rename packages/vkui/.storybook/addons/{appearance => colorScheme}/register.ts (70%) rename packages/vkui/src/components/{AppearanceProvider/AppearanceProvider.stories.tsx => ColorSchemeProvider/ColorSchemeProvider.stories.tsx} (55%) rename packages/vkui/src/components/{AppearanceProvider/AppearanceProvider.tsx => ColorSchemeProvider/ColorSchemeProvider.tsx} (59%) delete mode 100644 packages/vkui/src/hooks/useAppearance.ts rename packages/vkui/src/hooks/{useAutoDetectAppearance.ts => useAutoDetectColorScheme.ts} (63%) create mode 100644 packages/vkui/src/hooks/useColorScheme.ts delete mode 100644 packages/vkui/src/lib/appearance/index.ts delete mode 100644 packages/vkui/src/lib/appearance/types.ts create mode 100644 packages/vkui/src/lib/colorScheme/index.ts create mode 100644 packages/vkui/src/lib/colorScheme/types.ts rename styleguide/Components/Settings/{AppearanceSelect.js => ColorSchemeSelect.js} (78%) diff --git a/docs/TESTING.md b/docs/TESTING.md index a665004f15..ae2142d6ff 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -65,7 +65,7 @@ - platform: 'android' - browserName: 'chromium' -- appearance: 'light' +- colorScheme: 'light' ```tsx test('Example', async ({ expectScreenshotClippedToContent }) => { diff --git a/packages/codemods/src/codemod-helpers.ts b/packages/codemods/src/codemod-helpers.ts index df831acc86..7bb059ca89 100644 --- a/packages/codemods/src/codemod-helpers.ts +++ b/packages/codemods/src/codemod-helpers.ts @@ -31,6 +31,53 @@ export function getImportInfo( return { localName: localImportName }; } +export function renameImportName( + j: JSCodeshift, + source: Collection, + componentName: string, + newName: string, + alias: string, + renameOnlyImportedName: boolean, +) { + source + .find(j.ImportDeclaration, { source: { value: alias } }) + .find(j.ImportSpecifier, { local: { name: componentName } }) + .forEach((path) => { + const newSpecifier = j.importSpecifier( + j.identifier(newName), + renameOnlyImportedName ? j.identifier(componentName) : j.identifier(newName), + ); + (newSpecifier as any).importKind = (path.value as any).importKind; + j(path).replaceWith(newSpecifier); + }); +} + +export function renameIdentifier( + j: JSCodeshift, + source: Collection, + oldName: string, + newName: string, +) { + source.find(j.Identifier, { name: oldName }).forEach((path) => { + j(path).replaceWith(j.identifier(newName)); + }); +} + +export function renameTypeIdentifier( + j: JSCodeshift, + source: Collection, + oldName: string, + newName: string, +) { + source + .find(j.TSTypeReference, { typeName: { type: 'Identifier', name: oldName } }) + .forEach((path) => { + if (path.node.typeName.type === 'Identifier') { + path.node.typeName.name = newName; + } + }); +} + export function renameProp( j: JSCodeshift, source: Collection, diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/alias.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/alias.input.tsx new file mode 100644 index 0000000000..c5da0f73e4 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/alias.input.tsx @@ -0,0 +1,15 @@ +import { AppearanceProvider as AppearanceProviderAlias, type AppearanceProviderProps as AppearanceProviderPropsAlias, Snackbar } from '@vkontakte/vkui'; +import React from 'react'; + +const App = () => { + const props: AppearanceProviderPropsAlias = { + value: 'dark', + children: (Поделиться) + }; + + return ( + + + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/basic.input.tsx new file mode 100644 index 0000000000..e8ab71bebd --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/appearance-provider/basic.input.tsx @@ -0,0 +1,26 @@ +import { AppearanceProvider, type AppearanceProviderProps, Snackbar } from '@vkontakte/vkui'; +import React from 'react'; + +type Props = AppearanceProviderProps & { + additionalProp: string, +} + +const App = () => { + const props: AppearanceProviderProps = { + value: 'dark', + children: (Поделиться) + }; + + const getAdditionalProvider = () => ( + + Поделиться + + ) + + return ( + + + {getAdditionalProvider()} + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/appearance/alias.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/appearance/alias.input.tsx new file mode 100644 index 0000000000..62759ed761 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/appearance/alias.input.tsx @@ -0,0 +1,20 @@ +import { Appearance as AppearanceAlias, type AppearanceType as AppearanceTypeAlias } from '@vkontakte/vkui'; +import React from 'react'; + +const Component: React.FC<{ + appearance: AppearanceTypeAlias; +}> = () => { + return ( +
+ ) +} + +const App = () => { + const appearance: AppearanceTypeAlias = AppearanceAlias.LIGHT; + + return ( + + + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/appearance/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/appearance/basic.input.tsx new file mode 100644 index 0000000000..7d416cab05 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/appearance/basic.input.tsx @@ -0,0 +1,24 @@ +import { Appearance, type AppearanceType, useAppearance } from '@vkontakte/vkui'; +import React from 'react'; + +const Component: React.FC<{ + appearance: AppearanceType; +}> = ({ + appearance, +}) => { + return ( +
+ ) +} + +const App = () => { + const appearance: AppearanceType = Appearance.LIGHT; + + const fromHookAppearance = useAppearance(); + + return ( + + + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/config-provider/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/config-provider/basic.input.tsx new file mode 100644 index 0000000000..926365ed9d --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/config-provider/basic.input.tsx @@ -0,0 +1,33 @@ +import { ConfigProvider, ConfigProviderContext } from '@vkontakte/vkui'; +import React, {createContext} from 'react'; + +const OtherContext = createContext({}); + + +const App = () => { + const contextValue = {} + return ( + <> + +
+
+ + +
+
+ + +
+
+ + ); +}; diff --git a/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance-provider.ts.snap b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance-provider.ts.snap new file mode 100644 index 0000000000..86f923fb92 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance-provider.ts.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`appearance-provider transforms correctly 1`] = ` +"import { ColorSchemeProvider, type ColorSchemeProviderProps, Snackbar } from '@vkontakte/vkui'; +import React from 'react'; + +type Props = ColorSchemeProviderProps & { + additionalProp: string, +} + +const App = () => { + const props: ColorSchemeProviderProps = { + value: 'dark', + children: (Поделиться) + }; + + const getAdditionalProvider = () => ( + + Поделиться + + ) + + return ( + ( + + {getAdditionalProvider()} + ) + ); +};" +`; + +exports[`appearance-provider transforms correctly 2`] = ` +"import { ColorSchemeProvider as AppearanceProviderAlias, type ColorSchemeProviderProps as AppearanceProviderPropsAlias, Snackbar } from '@vkontakte/vkui'; +import React from 'react'; + +const App = () => { + const props: AppearanceProviderPropsAlias = { + value: 'dark', + children: (Поделиться) + }; + + return ( + + + + ); +};" +`; diff --git a/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance.ts.snap b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance.ts.snap new file mode 100644 index 0000000000..60b257bb58 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/appearance.ts.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`appearance transforms correctly 1`] = ` +"import { ColorScheme, type ColorSchemeType, useColorScheme } from '@vkontakte/vkui'; +import React from 'react'; + +const Component: React.FC<{ + appearance: ColorSchemeType; +}> = ({ + appearance, +}) => { + return ( +
+ ) +} + +const App = () => { + const appearance: ColorSchemeType = ColorScheme.LIGHT; + + const fromHookAppearance = useColorScheme(); + + return ( + ( + + ) + ); +};" +`; + +exports[`appearance transforms correctly 2`] = ` +"import { ColorScheme as AppearanceAlias, type ColorSchemeType as AppearanceTypeAlias } from '@vkontakte/vkui'; +import React from 'react'; + +const Component: React.FC<{ + appearance: AppearanceTypeAlias; +}> = () => { + return ( +
+ ) +} + +const App = () => { + const appearance: AppearanceTypeAlias = AppearanceAlias.LIGHT; + + return ( + + + + ); +};" +`; diff --git a/packages/codemods/src/transforms/v7/__tests__/__snapshots__/config-provider.ts.snap b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/config-provider.ts.snap new file mode 100644 index 0000000000..4e066ccd6e --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/config-provider.ts.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`config-provider transforms correctly 1`] = ` +"import { ConfigProvider, ConfigProviderContext } from '@vkontakte/vkui'; +import React, {createContext} from 'react'; + +const OtherContext = createContext({}); + + +const App = () => { + const contextValue = {} + return (<> + +
+
+ +
+
+ +
+
+ ); +};" +`; diff --git a/packages/codemods/src/transforms/v7/__tests__/appearance-provider.ts b/packages/codemods/src/transforms/v7/__tests__/appearance-provider.ts new file mode 100644 index 0000000000..eb78df1133 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/appearance-provider.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'appearance-provider'; +const fixtures = ['basic', 'alias'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/__tests__/appearance.ts b/packages/codemods/src/transforms/v7/__tests__/appearance.ts new file mode 100644 index 0000000000..560cce86e4 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/appearance.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'appearance'; +const fixtures = ['basic', 'alias'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/__tests__/config-provider.ts b/packages/codemods/src/transforms/v7/__tests__/config-provider.ts new file mode 100644 index 0000000000..f57da4c581 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/config-provider.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'config-provider'; +const fixtures = ['basic'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/appearance-provider.ts b/packages/codemods/src/transforms/v7/appearance-provider.ts new file mode 100644 index 0000000000..9008a29349 --- /dev/null +++ b/packages/codemods/src/transforms/v7/appearance-provider.ts @@ -0,0 +1,54 @@ +import { API, FileInfo } from 'jscodeshift'; +import { + getImportInfo, + renameIdentifier, + renameImportName, + renameTypeIdentifier, +} from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const OLD_PROVIDER_NAME = 'AppearanceProvider'; +const OLD_PROVIDER_PROPS_NAME = 'AppearanceProviderProps'; + +const NEW_PROVIDER_NAME = 'ColorSchemeProvider'; +const NEW_PROVIDER_PROPS_NAME = 'ColorSchemeProviderProps'; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName: providerLocalName } = getImportInfo(j, file, OLD_PROVIDER_NAME, alias); + const { localName: providerPropsLocalName } = getImportInfo( + j, + file, + OLD_PROVIDER_PROPS_NAME, + alias, + ); + if (!providerLocalName && !providerPropsLocalName) { + return source.toSource(); + } + if (providerLocalName) { + const isAliasUsed = providerLocalName !== OLD_PROVIDER_NAME; + renameImportName(j, source, providerLocalName, NEW_PROVIDER_NAME, alias, isAliasUsed); + if (!isAliasUsed) { + renameIdentifier(j, source, providerLocalName, NEW_PROVIDER_NAME); + } + } + if (providerPropsLocalName) { + const isAliasUsed = providerPropsLocalName !== OLD_PROVIDER_PROPS_NAME; + renameImportName( + j, + source, + providerPropsLocalName, + NEW_PROVIDER_PROPS_NAME, + alias, + isAliasUsed, + ); + if (!isAliasUsed) { + renameTypeIdentifier(j, source, providerPropsLocalName, NEW_PROVIDER_PROPS_NAME); + } + } + return source.toSource(); +} diff --git a/packages/codemods/src/transforms/v7/appearance.ts b/packages/codemods/src/transforms/v7/appearance.ts new file mode 100644 index 0000000000..e9d2d39f88 --- /dev/null +++ b/packages/codemods/src/transforms/v7/appearance.ts @@ -0,0 +1,77 @@ +import { API, FileInfo } from 'jscodeshift'; +import { + getImportInfo, + renameIdentifier, + renameImportName, + renameTypeIdentifier, +} from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const OLD_APPEARANCE_NAME = 'Appearance'; +const OLD_APPEARANCE_TYPE_NAME = 'AppearanceType'; +const OLD_HOOK_APPEARANCE_NAME = 'useAppearance'; + +const NEW_APPEARANCE_NAME = 'ColorScheme'; +const NEW_APPEARANCE_TYPE_NAME = 'ColorSchemeType'; +const NEW_HOOK_APPEARANCE_NAME = 'useColorScheme'; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName: appearanceLocalName } = getImportInfo(j, file, OLD_APPEARANCE_NAME, alias); + const { localName: appearanceTypeLocalName } = getImportInfo( + j, + file, + OLD_APPEARANCE_TYPE_NAME, + alias, + ); + const { localName: useAppearanceLocalName } = getImportInfo( + j, + file, + OLD_HOOK_APPEARANCE_NAME, + alias, + ); + + if (!appearanceLocalName && !appearanceTypeLocalName && !useAppearanceLocalName) { + return source.toSource(); + } + if (appearanceLocalName) { + const isAliasUsed = appearanceLocalName !== OLD_APPEARANCE_NAME; + renameImportName(j, source, appearanceLocalName, NEW_APPEARANCE_NAME, alias, isAliasUsed); + if (!isAliasUsed) { + renameIdentifier(j, source, appearanceLocalName, NEW_APPEARANCE_NAME); + } + } + if (appearanceTypeLocalName) { + const isAliasUsed = appearanceTypeLocalName !== OLD_APPEARANCE_TYPE_NAME; + renameImportName( + j, + source, + appearanceTypeLocalName, + NEW_APPEARANCE_TYPE_NAME, + alias, + isAliasUsed, + ); + if (!isAliasUsed) { + renameTypeIdentifier(j, source, appearanceTypeLocalName, NEW_APPEARANCE_TYPE_NAME); + } + } + if (useAppearanceLocalName) { + const isAliasUsed = useAppearanceLocalName !== OLD_HOOK_APPEARANCE_NAME; + renameImportName( + j, + source, + useAppearanceLocalName, + NEW_HOOK_APPEARANCE_NAME, + alias, + isAliasUsed, + ); + if (!isAliasUsed) { + renameIdentifier(j, source, useAppearanceLocalName, NEW_HOOK_APPEARANCE_NAME); + } + } + return source.toSource(); +} diff --git a/packages/codemods/src/transforms/v7/config-provider.ts b/packages/codemods/src/transforms/v7/config-provider.ts new file mode 100644 index 0000000000..0502739c05 --- /dev/null +++ b/packages/codemods/src/transforms/v7/config-provider.ts @@ -0,0 +1,204 @@ +import { + API, + Collection, + FileInfo, + JSCodeshift, + JSXAttribute, + JSXSpreadAttribute, + ObjectProperty, +} from 'jscodeshift'; +import { getImportInfo } from '../../codemod-helpers'; +import { report } from '../../report'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const CONFIG_PROVIDER_NAME = 'ConfigProvider'; +const CONFIG_PROVIDER_PROPS_NAME = 'ConfigProviderProps'; +const CONFIG_PROVIDER_CONTEXT_NAME = 'ConfigProviderContext'; +const USE_CONFIG_PROVIDER_NAME = 'useConfigProvider'; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName: configProviderName } = getImportInfo(j, file, CONFIG_PROVIDER_NAME, alias); + const { localName: configProviderPropsName } = getImportInfo( + j, + file, + CONFIG_PROVIDER_PROPS_NAME, + alias, + ); + const { localName: configProviderContextName } = getImportInfo( + j, + file, + CONFIG_PROVIDER_CONTEXT_NAME, + alias, + ); + const { localName: useConfigProviderName } = getImportInfo( + j, + file, + USE_CONFIG_PROVIDER_NAME, + alias, + ); + if ( + !configProviderName && + !configProviderPropsName && + !configProviderContextName && + !useConfigProviderName + ) { + return source.toSource(); + } + + if (configProviderName) { + handleConfigProvider(j, api, source, configProviderName); + } + if (configProviderContextName) { + handleConfigProviderContext(j, api, source, configProviderContextName); + } + if (useConfigProviderName) { + handleUseConfigProvider(j, api, source, useConfigProviderName); + } + if (configProviderPropsName) { + handleConfigProviderProps(j, api, source, configProviderPropsName); + } + + return source.toSource(); +} + +function handleConfigProviderProps( + j: JSCodeshift, + api: API, + source: Collection, + localName: string, +) { + const showReport = () => { + report( + api, + `: "${localName}" has been changed. Manual changes required: need to rename "appearance" field to "colorScheme" in object if it need`, + ); + }; + const types = source.find(j.TSTypeReference, { + typeName: { type: 'Identifier', name: localName }, + }); + if (types.length) { + showReport(); + } +} + +function handleUseConfigProvider(j: JSCodeshift, api: API, source: Collection, localName: string) { + const showReport = () => { + report( + api, + `: "${localName}" has been changed. Manual changes required: need to rename "appearance" field to "colorScheme" in result of hook if it need`, + ); + }; + const identifiers = source.find(j.Identifier, { + name: localName, + }); + if (identifiers.length) { + showReport(); + } +} + +function handleConfigProvider(j: JSCodeshift, api: API, source: Collection, localName: string) { + const showReport = () => { + report( + api, + `: "${localName}" has been changed. Manual changes required: need to rename "appearance" field to "colorScheme" if it need`, + ); + }; + source + .find(j.JSXElement, { + openingElement: { + name: { + name: localName, + }, + }, + }) + .forEach((path) => { + const appearanceAttribute = path.node.openingElement.attributes?.find( + (attr) => attr.type === 'JSXAttribute' && attr.name && attr.name.name === 'appearance', + ) as JSXAttribute; + + if (appearanceAttribute) { + appearanceAttribute.name = j.jsxIdentifier('colorScheme'); + return; + } + const spreadAttribute = path.node.openingElement.attributes?.find( + (attr) => attr.type === 'JSXSpreadAttribute', + ) as JSXSpreadAttribute; + if (spreadAttribute) { + showReport(); + return; + } + return; + }); +} + +function handleConfigProviderContext( + j: JSCodeshift, + api: API, + source: Collection, + localName: string, +) { + const showReport = () => { + report( + api, + `: "${localName}" has been changed. Manual changes required: need to rename "appearance" field to "colorScheme" if it need`, + ); + }; + + source + .find(j.JSXElement, { + openingElement: { + name: { + object: { name: localName }, + property: { name: 'Provider' }, + }, + }, + }) + .forEach((path) => { + const valueAttribute = path.node.openingElement.attributes?.find( + (attr) => attr.type === 'JSXAttribute' && attr.name && attr.name.name === 'value', + ) as JSXAttribute; + + if (!valueAttribute) { + showReport(); + return; + } + + const valueExpression = + valueAttribute.value?.type === 'JSXExpressionContainer' + ? valueAttribute.value.expression + : undefined; + + if (!valueExpression) { + showReport(); + return; + } + + if (valueExpression.type === 'Identifier') { + showReport(); + return; + } + + if (valueExpression.type === 'ObjectExpression') { + const appearanceProp = valueExpression.properties.find( + (prop) => + prop.type === 'ObjectProperty' && + prop.key.type === 'Identifier' && + prop.key.name === 'appearance', + ) as ObjectProperty; + if (!appearanceProp) { + showReport(); + return; + } + + appearanceProp.key = j.identifier('colorScheme'); + return; + } + showReport(); + return; + }); +} diff --git a/packages/vkui/.env.development.local b/packages/vkui/.env.development.local index 4e9507351b..6362010f7e 100644 --- a/packages/vkui/.env.development.local +++ b/packages/vkui/.env.development.local @@ -6,7 +6,7 @@ # Используется для запуска Playwright только для конкретных проектов. # Доступные проекты ищи в файле `playwright-ct.config.ts`. # -# @type JSONArray – используйте шаблон `${platform} (${browser_engine}) • ${appearance}`. +# @type JSONArray – используйте шаблон `${platform} (${browser_engine}) • ${colorScheme}`. PLAYWRIGHT_FORCE_PROJECTS='[ "android (chromium) • dark" ]' diff --git a/packages/vkui/.storybook/addons/appearance/constants.ts b/packages/vkui/.storybook/addons/appearance/constants.ts deleted file mode 100644 index 48e74d9cfb..0000000000 --- a/packages/vkui/.storybook/addons/appearance/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const ADDON_ID = 'storybook/appearance'; -export const PARAM_KEY = 'appearance'; diff --git a/packages/vkui/.storybook/addons/appearance/AppearanceSwitch.tsx b/packages/vkui/.storybook/addons/colorScheme/ColorSchemeSwitch.tsx similarity index 94% rename from packages/vkui/.storybook/addons/appearance/AppearanceSwitch.tsx rename to packages/vkui/.storybook/addons/colorScheme/ColorSchemeSwitch.tsx index cd136eacb4..a273e6ec3c 100644 --- a/packages/vkui/.storybook/addons/appearance/AppearanceSwitch.tsx +++ b/packages/vkui/.storybook/addons/colorScheme/ColorSchemeSwitch.tsx @@ -4,7 +4,7 @@ import { useGlobals } from '@storybook/manager-api'; import { IconButton } from '@storybook/components'; import { PARAM_KEY } from './constants'; -export const AppearanceSwitch = () => { +export const ColorSchemeSwitch = () => { const [globals, updateGlobals] = useGlobals(); const isDarkTheme = globals[PARAM_KEY] === 'dark'; diff --git a/packages/vkui/.storybook/addons/colorScheme/constants.ts b/packages/vkui/.storybook/addons/colorScheme/constants.ts new file mode 100644 index 0000000000..ce183712cd --- /dev/null +++ b/packages/vkui/.storybook/addons/colorScheme/constants.ts @@ -0,0 +1,2 @@ +export const ADDON_ID = 'storybook/colorScheme'; +export const PARAM_KEY = 'colorScheme'; diff --git a/packages/vkui/.storybook/addons/appearance/preset.js b/packages/vkui/.storybook/addons/colorScheme/preset.js similarity index 100% rename from packages/vkui/.storybook/addons/appearance/preset.js rename to packages/vkui/.storybook/addons/colorScheme/preset.js diff --git a/packages/vkui/.storybook/addons/appearance/register.ts b/packages/vkui/.storybook/addons/colorScheme/register.ts similarity index 70% rename from packages/vkui/.storybook/addons/appearance/register.ts rename to packages/vkui/.storybook/addons/colorScheme/register.ts index 06ab8ee95b..77ae8e97b3 100644 --- a/packages/vkui/.storybook/addons/appearance/register.ts +++ b/packages/vkui/.storybook/addons/colorScheme/register.ts @@ -1,12 +1,12 @@ import { addons, types } from '@storybook/manager-api'; -import { AppearanceSwitch } from './AppearanceSwitch'; +import { ColorSchemeSwitch } from './ColorSchemeSwitch'; import { ADDON_ID } from './constants'; addons.register(ADDON_ID, () => { addons.add(ADDON_ID, { - title: 'Appearance', + title: 'ColorScheme', type: types.TOOL, match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), - render: AppearanceSwitch, + render: ColorSchemeSwitch, }); }); diff --git a/packages/vkui/.storybook/addons/storybook-theme/StorybookTheme.tsx b/packages/vkui/.storybook/addons/storybook-theme/StorybookTheme.tsx index fcae85068b..5ed23354dd 100644 --- a/packages/vkui/.storybook/addons/storybook-theme/StorybookTheme.tsx +++ b/packages/vkui/.storybook/addons/storybook-theme/StorybookTheme.tsx @@ -36,7 +36,7 @@ export const StorybookTheme = () => { const updateTheme = (themeProp: 'light' | 'dark') => { channel.emit(SET_STORYBOOK_THEME, themeProp); - updateGlobals({ [PARAM_KEY]: themeProp, appearance: themeProp }); + updateGlobals({ [PARAM_KEY]: themeProp, colorScheme: themeProp }); updateLocalStorageValue(themeProp); }; diff --git a/packages/vkui/.storybook/main.ts b/packages/vkui/.storybook/main.ts index 5c81b27e0d..047f06768c 100644 --- a/packages/vkui/.storybook/main.ts +++ b/packages/vkui/.storybook/main.ts @@ -28,7 +28,7 @@ const config: StorybookConfig = { getAbsolutePath('@storybook/addon-interactions'), getAbsolutePath('@storybook/addon-a11y'), getAbsolutePath('@project-tools/storybook-addon-cartesian'), - './addons/appearance', + './addons/colorScheme', './addons/pointer', './addons/customPanelHeaderAfter', './addons/storybook-theme', diff --git a/packages/vkui/.storybook/preview.ts b/packages/vkui/.storybook/preview.ts index a895489fe9..0fa176aded 100644 --- a/packages/vkui/.storybook/preview.ts +++ b/packages/vkui/.storybook/preview.ts @@ -53,7 +53,7 @@ const preview: Preview = { cartesian: { disabled: true }, }, globalTypes: { - appearance: { + colorScheme: { defaultValue: 'light', }, hasPointer: { diff --git a/packages/vkui/playwright-ct.config.ts b/packages/vkui/playwright-ct.config.ts index 09d6717d3c..36229669e6 100644 --- a/packages/vkui/playwright-ct.config.ts +++ b/packages/vkui/playwright-ct.config.ts @@ -1,7 +1,7 @@ /* eslint no-console: 0 */ import path from 'path'; import { - Appearance, + ColorScheme, defineConfig, type DeviceKey, devices, @@ -124,50 +124,50 @@ function generateProjects(): TestProject { return restProps; }; - const appearances = [Appearance.LIGHT, Appearance.DARK]; - const projects = appearances - .map((appearance) => [ + const colorSchemes = [ColorScheme.LIGHT, ColorScheme.DARK]; + const projects = colorSchemes + .map((colorScheme) => [ { - name: `android (chromium) • ${appearance}`, + name: `android (chromium) • ${colorScheme}`, use: { ...getDeviceDescriptorWithoutScaleFactor('Pixel 5'), - appearance, + colorScheme, platform: Platform.ANDROID, }, }, { - name: `ios (webkit) • ${appearance}`, + name: `ios (webkit) • ${colorScheme}`, use: { ...getDeviceDescriptorWithoutScaleFactor('iPhone XR'), - appearance, + colorScheme, platform: Platform.IOS, }, }, { - name: `vkcom (chromium) • ${appearance}`, + name: `vkcom (chromium) • ${colorScheme}`, use: { ...getDeviceDescriptorWithoutScaleFactor('Desktop Chrome'), - appearance, + colorScheme, platform: Platform.VKCOM, }, }, { - name: `vkcom (firefox) • ${appearance}`, + name: `vkcom (firefox) • ${colorScheme}`, use: { ...getDeviceDescriptorWithoutScaleFactor('Desktop Firefox'), - appearance, + colorScheme, platform: Platform.VKCOM, }, }, { - name: `vkcom (webkit) • ${appearance}`, + name: `vkcom (webkit) • ${colorScheme}`, use: { ...getDeviceDescriptorWithoutScaleFactor('Desktop Safari'), - appearance, + colorScheme, platform: Platform.VKCOM, }, }, diff --git a/packages/vkui/src/components/Alert/Alert.e2e.tsx b/packages/vkui/src/components/Alert/Alert.e2e.tsx index a6aaeb2437..84cfd713a1 100644 --- a/packages/vkui/src/components/Alert/Alert.e2e.tsx +++ b/packages/vkui/src/components/Alert/Alert.e2e.tsx @@ -28,7 +28,7 @@ test.describe('Alert', () => { test.describe('Alert', () => { test.use({ - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('long word', async ({ mount, diff --git a/packages/vkui/src/components/AppRoot/AppRoot.test.tsx b/packages/vkui/src/components/AppRoot/AppRoot.test.tsx index d4b220830f..e16aed6db4 100644 --- a/packages/vkui/src/components/AppRoot/AppRoot.test.tsx +++ b/packages/vkui/src/components/AppRoot/AppRoot.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; import { noop } from '@vkontakte/vkjs'; -import { Appearance } from '../../lib/appearance'; +import { ColorScheme } from '../../lib/colorScheme'; import { Platform } from '../../lib/platform'; import { DEFAULT_TOKENS_CLASS_NAMES } from '../../lib/tokens'; import { baselineComponent } from '../../testing/utils'; @@ -327,20 +327,25 @@ describe('AppRoot', () => { const CUSTOM_TOKEN_CLASS_NAME = 'myClassName'; it.each([ - ['default', Platform.IOS, Appearance.LIGHT, undefined], - ['default', Platform.IOS, Appearance.LIGHT, {}], - ['default', Platform.IOS, Appearance.DARK, DEFAULT_TOKENS_CLASS_NAMES], - ['default', Platform.IOS, Appearance.LIGHT, { dark: CUSTOM_TOKEN_CLASS_NAME }], - ['default', Platform.IOS, Appearance.LIGHT, { android: { dark: CUSTOM_TOKEN_CLASS_NAME } }], - ['custom', Platform.IOS, Appearance.DARK, { dark: CUSTOM_TOKEN_CLASS_NAME }], - ['custom', Platform.ANDROID, Appearance.DARK, { android: { dark: CUSTOM_TOKEN_CLASS_NAME } }], + ['default', Platform.IOS, ColorScheme.LIGHT, undefined], + ['default', Platform.IOS, ColorScheme.LIGHT, {}], + ['default', Platform.IOS, ColorScheme.DARK, DEFAULT_TOKENS_CLASS_NAMES], + ['default', Platform.IOS, ColorScheme.LIGHT, { dark: CUSTOM_TOKEN_CLASS_NAME }], + ['default', Platform.IOS, ColorScheme.LIGHT, { android: { dark: CUSTOM_TOKEN_CLASS_NAME } }], + ['custom', Platform.IOS, ColorScheme.DARK, { dark: CUSTOM_TOKEN_CLASS_NAME }], + [ + 'custom', + Platform.ANDROID, + ColorScheme.DARK, + { android: { dark: CUSTOM_TOKEN_CLASS_NAME } }, + ], ])( - 'should use %s tokensClassName if platform="%s" appearance="%s" tokensClassNames={%o}', - (type, platform, appearance, tokensClassNames) => { + 'should use %s tokensClassName if platform="%s" colorScheme="%s" tokensClassNames={%o}', + (type, platform, colorScheme, tokensClassNames) => { const { unmount } = render( @@ -348,7 +353,7 @@ describe('AppRoot', () => { ); const tokensClassName = type === 'default' - ? DEFAULT_TOKENS_CLASS_NAMES[platform][appearance] + ? DEFAULT_TOKENS_CLASS_NAMES[platform][colorScheme] : CUSTOM_TOKEN_CLASS_NAME; expect(document.documentElement).toHaveClass(tokensClassName); unmount(); @@ -358,13 +363,13 @@ describe('AppRoot', () => { }); it('should add tokensClassName to embedded element of AppRoot inner full AppRoot and removes on unmount', async () => { - const configForFullMode = { appearance: Appearance.LIGHT, platform: Platform.VKCOM }; + const configForFullMode = { colorScheme: ColorScheme.LIGHT, platform: Platform.VKCOM }; const vkuiTokenModeClassNameForFullMode = - DEFAULT_TOKENS_CLASS_NAMES[configForFullMode.platform][configForFullMode.appearance]; + DEFAULT_TOKENS_CLASS_NAMES[configForFullMode.platform][configForFullMode.colorScheme]; - const configForEmbeddedMode = { appearance: Appearance.DARK, platform: Platform.VKCOM }; + const configForEmbeddedMode = { colorScheme: ColorScheme.DARK, platform: Platform.VKCOM }; const vkuiTokenModeClassNameForEmbeddedMode = - DEFAULT_TOKENS_CLASS_NAMES[configForEmbeddedMode.platform][configForEmbeddedMode.appearance]; + DEFAULT_TOKENS_CLASS_NAMES[configForEmbeddedMode.platform][configForEmbeddedMode.colorScheme]; const ConfigUserWithOwnProvider = () => { return ( diff --git a/packages/vkui/src/components/AppRoot/AppRootPortal.tsx b/packages/vkui/src/components/AppRoot/AppRootPortal.tsx index fd3415456e..f703ab6136 100644 --- a/packages/vkui/src/components/AppRoot/AppRootPortal.tsx +++ b/packages/vkui/src/components/AppRoot/AppRootPortal.tsx @@ -1,12 +1,12 @@ 'use client'; import * as React from 'react'; -import { useAppearance } from '../../hooks/useAppearance'; +import { useColorScheme } from '../../hooks/useColorScheme'; import { useIsClient } from '../../hooks/useIsClient'; import { createPortal } from '../../lib/createPortal'; import { isRefObject } from '../../lib/isRefObject'; import type { HasChildren } from '../../types'; -import { AppearanceProvider } from '../AppearanceProvider/AppearanceProvider'; +import { ColorSchemeProvider } from '../ColorSchemeProvider/ColorSchemeProvider'; import { AppRootContext, type AppRootContextInterface } from './AppRootContext'; export interface AppRootPortalProps extends HasChildren { @@ -19,7 +19,7 @@ export interface AppRootPortalProps extends HasChildren { export const AppRootPortal = ({ children, usePortal }: AppRootPortalProps): React.ReactNode => { const { portalRoot, mode, disablePortal } = React.useContext(AppRootContext); - const appearance = useAppearance(); + const colorScheme = useColorScheme(); const isClient = useIsClient(); if (!isClient) { @@ -32,7 +32,7 @@ export const AppRootPortal = ({ children, usePortal }: AppRootPortalProps): Reac } return createPortal( - {children}, + {children}, portalContainer, ); }; diff --git a/packages/vkui/src/components/Button/Button.e2e.tsx b/packages/vkui/src/components/Button/Button.e2e.tsx index 5c57e4c717..b650ef34d7 100644 --- a/packages/vkui/src/components/Button/Button.e2e.tsx +++ b/packages/vkui/src/components/Button/Button.e2e.tsx @@ -20,7 +20,7 @@ test.describe('Button', () => { }); test.describe('Button', () => { - test.use({ onlyForAppearances: ['light'] }); + test.use({ onlyForColorSchemes: ['light'] }); test('paddings', async ({ mount, expectScreenshotClippedToContent, diff --git a/packages/vkui/src/components/AppearanceProvider/AppearanceProvider.stories.tsx b/packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.stories.tsx similarity index 55% rename from packages/vkui/src/components/AppearanceProvider/AppearanceProvider.stories.tsx rename to packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.stories.tsx index fdb123abcd..5f3d43f2ba 100644 --- a/packages/vkui/src/components/AppearanceProvider/AppearanceProvider.stories.tsx +++ b/packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.stories.tsx @@ -1,18 +1,18 @@ import type { Meta, StoryObj } from '@storybook/react'; import { CanvasFullLayout, DisableCartesianParam } from '../../storybook/constants'; -import { AppearanceProvider, type AppearanceProviderProps } from './AppearanceProvider'; +import { ColorSchemeProvider, type ColorSchemeProviderProps } from './ColorSchemeProvider'; -const story: Meta = { - title: 'Service/AppearanceProvider', - component: AppearanceProvider, +const story: Meta = { + title: 'Service/ColorSchemeProvider', + component: ColorSchemeProvider, parameters: { ...CanvasFullLayout, ...DisableCartesianParam }, }; export default story; -export const Playground: StoryObj = { +export const Playground: StoryObj = { render: (args) => ( - +
= { color: 'var(--vkui--color_text_primary)', }} > - AppearanceProvider + ColorSchemeProvider
-
+ ), }; diff --git a/packages/vkui/src/components/AppearanceProvider/AppearanceProvider.tsx b/packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.tsx similarity index 59% rename from packages/vkui/src/components/AppearanceProvider/AppearanceProvider.tsx rename to packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.tsx index 55d524eeda..5d5c73adce 100644 --- a/packages/vkui/src/components/AppearanceProvider/AppearanceProvider.tsx +++ b/packages/vkui/src/components/ColorSchemeProvider/ColorSchemeProvider.tsx @@ -1,23 +1,23 @@ import * as React from 'react'; import { IconAppearanceProvider } from '@vkontakte/icons'; -import type { AppearanceType } from '../../lib/appearance'; +import type { ColorSchemeType } from '../../lib/colorScheme'; import { TokensClassProvider } from '../../lib/tokens'; import { ConfigProviderOverride } from '../ConfigProvider/ConfigProviderOverride'; -export interface AppearanceProviderProps { - value: AppearanceType; +export interface ColorSchemeProviderProps { + value: ColorSchemeType; children: React.ReactNode; } /** - * @see https://vkcom.github.io/VKUI/#/AppearanceProvider + * @see https://vkcom.github.io/VKUI/#/ColorSchemeProvider */ -export const AppearanceProvider = ({ +export const ColorSchemeProvider = ({ value, children, -}: AppearanceProviderProps): React.ReactNode => { +}: ColorSchemeProviderProps): React.ReactNode => { return ( - + {children} diff --git a/packages/vkui/src/components/ConfigProvider/ConfigProvider.test.tsx b/packages/vkui/src/components/ConfigProvider/ConfigProvider.test.tsx index 507037dbfd..69b03d4f7e 100644 --- a/packages/vkui/src/components/ConfigProvider/ConfigProvider.test.tsx +++ b/packages/vkui/src/components/ConfigProvider/ConfigProvider.test.tsx @@ -20,7 +20,7 @@ describe(ConfigProvider, () => { platform: 'android', isWebView: false, locale: 'ru', - appearance: 'light', + colorScheme: 'light', hasCustomPanelHeaderAfter: false, customPanelHeaderAfterMinWidth: 90, tokensClassNames: DEFAULT_TOKENS_CLASS_NAMES, @@ -30,7 +30,7 @@ describe(ConfigProvider, () => { }; render( @@ -48,7 +48,7 @@ describe(ConfigProvider, () => { const defaultConfig: ConfigProviderContextInterface = { platform: 'vkcom', - appearance: 'dark', + colorScheme: 'dark', hasCustomPanelHeaderAfter: true, customPanelHeaderAfterMinWidth: 90, transitionMotionEnabled: false, @@ -89,7 +89,7 @@ describe(ConfigProviderOverride, () => { const defaultConfig: ConfigProviderContextInterface = { platform: 'vkcom', - appearance: 'dark', + colorScheme: 'dark', hasCustomPanelHeaderAfter: true, customPanelHeaderAfterMinWidth: 90, transitionMotionEnabled: false, diff --git a/packages/vkui/src/components/ConfigProvider/ConfigProvider.tsx b/packages/vkui/src/components/ConfigProvider/ConfigProvider.tsx index 663b9fc46a..34b6e5ff13 100644 --- a/packages/vkui/src/components/ConfigProvider/ConfigProvider.tsx +++ b/packages/vkui/src/components/ConfigProvider/ConfigProvider.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { IconAppearanceProvider } from '@vkontakte/icons'; -import { useAutoDetectAppearance } from '../../hooks/useAutoDetectAppearance'; +import { useAutoDetectColorScheme } from '../../hooks/useAutoDetectColorScheme'; import { useObjectMemo } from '../../hooks/useObjectMemo'; import { TokensClassProvider } from '../../lib/tokens'; import { excludeKeysWithUndefined } from '../../lib/utils'; @@ -31,14 +31,14 @@ export const ConfigProvider = (propsRaw: ConfigProviderProps): React.ReactNode = transitionMotionEnabled, platform, locale, - appearance: appearanceProp, + colorScheme: colorSchemeProp, tokensClassNames, } = { ...parentConfig, ...props, }; - const appearance = useAutoDetectAppearance(appearanceProp); + const colorScheme = useAutoDetectColorScheme(colorSchemeProp); const configContext = useObjectMemo({ hasCustomPanelHeaderAfter, @@ -48,12 +48,12 @@ export const ConfigProvider = (propsRaw: ConfigProviderProps): React.ReactNode = platform, locale, tokensClassNames, - appearance, + colorScheme, }); return ( - + {children} diff --git a/packages/vkui/src/components/ConfigProvider/ConfigProviderContext.tsx b/packages/vkui/src/components/ConfigProvider/ConfigProviderContext.tsx index d520039151..fb2f609a0c 100644 --- a/packages/vkui/src/components/ConfigProvider/ConfigProviderContext.tsx +++ b/packages/vkui/src/components/ConfigProvider/ConfigProviderContext.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { AppearanceType } from '../../lib/appearance'; +import type { ColorSchemeType } from '../../lib/colorScheme'; import { platform, type PlatformType } from '../../lib/platform'; import { DEFAULT_TOKENS_CLASS_NAMES, type TokensClassNames } from '../../lib/tokens'; @@ -34,7 +34,7 @@ export interface ConfigProviderContextInterface { /** * Тип цветовой схемы – `light` или `dark` */ - appearance: AppearanceType | undefined; + colorScheme: ColorSchemeType | undefined; /** * Включена ли анимация переходов между экранами в `Root` и `View` */ @@ -79,7 +79,7 @@ export const ConfigProviderContext: React.Context > Обратите внимание, что в вашем приложении должен быть только один `ConfigProvider`. Если вам необходимо > переопределить какой-то из параметров, то это можно сделать с помощью [`PlatformProvider`](#/PlatformProvider), -> [`AppearanceProvider`](#/AppearanceProvider) или [`LocaleProvider`](#/LocaleProvider) +> [`ColorSchemeProvider`](#/ColorSchemeProvider) или [`LocaleProvider`](#/LocaleProvider) diff --git a/packages/vkui/src/components/CustomSelect/CustomSelect.e2e.tsx b/packages/vkui/src/components/CustomSelect/CustomSelect.e2e.tsx index 0ac66618ca..68af237403 100644 --- a/packages/vkui/src/components/CustomSelect/CustomSelect.e2e.tsx +++ b/packages/vkui/src/components/CustomSelect/CustomSelect.e2e.tsx @@ -1,5 +1,5 @@ import { test } from '@vkui-e2e/test'; -import { Appearance } from '../../lib/appearance'; +import { ColorScheme } from '../../lib/colorScheme'; import { CustomSelectNoMaxHeightPlayground, CustomSelectOptionScrollPlayground, @@ -17,7 +17,7 @@ test('CustomSelect', async ({ test.describe('CustomSelect', () => { test.use({ - onlyForAppearances: [Appearance.LIGHT], + onlyForColorSchemes: [ColorScheme.LIGHT], }); test('no max height', async ({ mount, @@ -41,7 +41,7 @@ test.describe('CustomSelect', () => { test.describe('CustomSelect', () => { test.use({ - onlyForAppearances: [Appearance.LIGHT], + onlyForColorSchemes: [ColorScheme.LIGHT], onlyForPlatforms: ['android'], onlyForBrowsers: ['chromium'], }); diff --git a/packages/vkui/src/components/Flex/Flex.e2e.tsx b/packages/vkui/src/components/Flex/Flex.e2e.tsx index 0980c28bfd..a610042f0c 100644 --- a/packages/vkui/src/components/Flex/Flex.e2e.tsx +++ b/packages/vkui/src/components/Flex/Flex.e2e.tsx @@ -3,7 +3,7 @@ import { FlexPlayground } from './Flex.e2e-playground'; test.describe('Flex', () => { test.use({ - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('Rendering', async ({ mount, diff --git a/packages/vkui/src/components/HorizontalScroll/HorizontalScroll.e2e-playground.tsx b/packages/vkui/src/components/HorizontalScroll/HorizontalScroll.e2e-playground.tsx index a4a0595519..0669a9515c 100644 --- a/packages/vkui/src/components/HorizontalScroll/HorizontalScroll.e2e-playground.tsx +++ b/packages/vkui/src/components/HorizontalScroll/HorizontalScroll.e2e-playground.tsx @@ -52,11 +52,11 @@ export const HorizontalScrollSmallTabletPlayground = (props: ComponentPlayground }; export const HorizontalScrollWithHasMousePlayground = ({ - appearance, + colorScheme, ...restProps }: ComponentPlaygroundProps) => { return ( - + { return ( - + { test.use({ onlyForPlatforms: [Platform.ANDROID], - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('State: Focus Visible', async ({ diff --git a/packages/vkui/src/components/ImageBase/ImageBase.e2e-playground.tsx b/packages/vkui/src/components/ImageBase/ImageBase.e2e-playground.tsx index 4b2ae50c38..9306bced02 100644 --- a/packages/vkui/src/components/ImageBase/ImageBase.e2e-playground.tsx +++ b/packages/vkui/src/components/ImageBase/ImageBase.e2e-playground.tsx @@ -1,5 +1,5 @@ import { ComponentPlayground, type ComponentPlaygroundProps } from '@vkui-e2e/playground-helpers'; -import { AppearanceProvider } from '../AppearanceProvider/AppearanceProvider'; +import { ColorSchemeProvider } from '../ColorSchemeProvider/ColorSchemeProvider'; import { ImageBase, type ImageBaseProps } from './ImageBase'; const base64Image = @@ -33,12 +33,12 @@ export const ImageWithParentWithBorderRadius = (props: ComponentPlaygroundProps) {/* Специально оборачиваем в провайдер, чтобы фон ImageBase бы темныи и выглядывал /* из-за img если img не полностью перекрывает ImageBase */} - + - + )} diff --git a/packages/vkui/src/components/ImageBase/ImageBase.e2e.tsx b/packages/vkui/src/components/ImageBase/ImageBase.e2e.tsx index 753847dcf5..efd3723010 100644 --- a/packages/vkui/src/components/ImageBase/ImageBase.e2e.tsx +++ b/packages/vkui/src/components/ImageBase/ImageBase.e2e.tsx @@ -5,7 +5,7 @@ import { ImageWithParentWithBorderRadius } from './ImageBase.e2e-playground'; test.describe('ImageBase', () => { test.use({ onlyForPlatforms: [Platform.ANDROID], - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('Parent with border-radius: Image does not have visible corners from Image background', async ({ diff --git a/packages/vkui/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx b/packages/vkui/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx index 5599cde1d1..9f8a4ea53a 100644 --- a/packages/vkui/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx +++ b/packages/vkui/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { classNames } from '@vkontakte/vkjs'; import { useAdaptivityHasPointer } from '../../../hooks/useAdaptivityHasPointer'; -import { useAppearance } from '../../../hooks/useAppearance'; +import { useColorScheme } from '../../../hooks/useColorScheme'; import { useExternRef } from '../../../hooks/useExternRef'; import { useFocusVisible } from '../../../hooks/useFocusVisible'; import { useFocusVisibleClassName } from '../../../hooks/useFocusVisibleClassName'; @@ -94,9 +94,9 @@ export const ImageBaseOverlay: React.FC = ({ visibility: visibilityProp, ...restProps }: ImageBaseOverlayProps) => { - const appearance = useAppearance(); + const colorScheme = useColorScheme(); const hasPointer = useAdaptivityHasPointer(); - const theme = themeProp ?? appearance; + const theme = themeProp ?? colorScheme; const visibility = visibilityProp ?? (hasPointer ? 'on-hover' : 'always'); const commonClassNames = classNames( diff --git a/packages/vkui/src/components/Link/Link.e2e.tsx b/packages/vkui/src/components/Link/Link.e2e.tsx index 008cba3a15..66f599d286 100644 --- a/packages/vkui/src/components/Link/Link.e2e.tsx +++ b/packages/vkui/src/components/Link/Link.e2e.tsx @@ -5,7 +5,7 @@ import { LinkFocusVisiblePlayground } from './Link.e2e-playground'; test.describe('Link', () => { test.use({ onlyForPlatforms: [Platform.ANDROID], - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('State: Focus Visible', async ({ diff --git a/packages/vkui/src/components/PanelHeader/PanelHeader.e2e.tsx b/packages/vkui/src/components/PanelHeader/PanelHeader.e2e.tsx index 2ffc9380de..d93529ac59 100644 --- a/packages/vkui/src/components/PanelHeader/PanelHeader.e2e.tsx +++ b/packages/vkui/src/components/PanelHeader/PanelHeader.e2e.tsx @@ -2,7 +2,7 @@ import { test } from '@vkui-e2e/test'; import { PanelHeaderPlayground } from './PanelHeader.e2e-playground'; test.use({ - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('PanelHeader', async ({ diff --git a/packages/vkui/src/components/PullToRefresh/PullToRefresh.e2e.tsx b/packages/vkui/src/components/PullToRefresh/PullToRefresh.e2e.tsx index a6830a5d45..0c8c28fc3e 100644 --- a/packages/vkui/src/components/PullToRefresh/PullToRefresh.e2e.tsx +++ b/packages/vkui/src/components/PullToRefresh/PullToRefresh.e2e.tsx @@ -7,7 +7,7 @@ import { test.describe('PullToRefresh', () => { // we are interested in VKCOM only as we need to test here mostly // whether the spinner is positioned properly - test.use({ onlyForPlatforms: ['vkcom'], onlyForAppearances: ['light'] }); + test.use({ onlyForPlatforms: ['vkcom'], onlyForColorSchemes: ['light'] }); test('renders spinner properly in default environment', async ({ page, diff --git a/packages/vkui/src/components/Search/Search.e2e-playground.tsx b/packages/vkui/src/components/Search/Search.e2e-playground.tsx index 1f5c71c0bc..e464364aad 100644 --- a/packages/vkui/src/components/Search/Search.e2e-playground.tsx +++ b/packages/vkui/src/components/Search/Search.e2e-playground.tsx @@ -40,9 +40,9 @@ export const SearchPlayground = (props: ComponentPlaygroundProps) => { ); }; -export const SearchTestFocusOnIOSPlayground = ({ appearance }: ComponentPlaygroundProps) => { +export const SearchTestFocusOnIOSPlayground = ({ colorScheme }: ComponentPlaygroundProps) => { return ( - + { test.use({ - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('Rendering', async ({ mount, diff --git a/packages/vkui/src/components/Slider/Slider.e2e-playground.tsx b/packages/vkui/src/components/Slider/Slider.e2e-playground.tsx index 00df8d0011..61e0e479c6 100644 --- a/packages/vkui/src/components/Slider/Slider.e2e-playground.tsx +++ b/packages/vkui/src/components/Slider/Slider.e2e-playground.tsx @@ -42,11 +42,11 @@ export const SliderPlayground = (props: ComponentPlaygroundProps) => { }; export const SliderPlaygroundForKeyboardTest = ({ - appearance, + colorScheme, ...restProps }: ComponentPlaygroundProps & (SliderProps | SliderMultipleProps)) => { return ( - + @@ -57,11 +57,11 @@ export const SliderPlaygroundForKeyboardTest = ({ }; export const SliderPlaygroundForTooltipTest = ({ - appearance, + colorScheme, ...restProps }: ComponentPlaygroundProps & (SliderProps | SliderMultipleProps)) => { return ( - + { * см. https://github.com/testing-library/user-event/issues/871 */ test.describe('keyboard events', () => { - test.use({ onlyForPlatforms: ['android'], onlyForAppearances: ['light'] }); + test.use({ onlyForPlatforms: ['android'], onlyForColorSchemes: ['light'] }); test('should be focused with Tab button', async ({ page, mount, componentPlaygroundProps }) => { const result = await mount( diff --git a/packages/vkui/src/components/Spacing/Spacing.e2e.tsx b/packages/vkui/src/components/Spacing/Spacing.e2e.tsx index c45ae9b351..47d510b264 100644 --- a/packages/vkui/src/components/Spacing/Spacing.e2e.tsx +++ b/packages/vkui/src/components/Spacing/Spacing.e2e.tsx @@ -1,7 +1,7 @@ import { test } from '@vkui-e2e/test'; import { SpacingPlayground } from './Spacing.e2e-playground'; -test.use({ onlyForPlatforms: ['vkcom'], onlyForAppearances: ['light'] }); +test.use({ onlyForPlatforms: ['vkcom'], onlyForColorSchemes: ['light'] }); test('Spacing', async ({ mount, expectScreenshotClippedToContent, componentPlaygroundProps }) => { await mount(); diff --git a/packages/vkui/src/components/Switch/Switch.e2e.tsx b/packages/vkui/src/components/Switch/Switch.e2e.tsx index a0cd9321b7..8751ee8476 100644 --- a/packages/vkui/src/components/Switch/Switch.e2e.tsx +++ b/packages/vkui/src/components/Switch/Switch.e2e.tsx @@ -10,7 +10,7 @@ test('Switch', async ({ mount, expectScreenshotClippedToContent, componentPlaygr test.describe('Switch', () => { test.use({ onlyForPlatforms: [Platform.ANDROID], - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); test('State: Focus Visible', async ({ diff --git a/packages/vkui/src/components/Tabs/Tabs.e2e.tsx b/packages/vkui/src/components/Tabs/Tabs.e2e.tsx index b673fe1de8..26e609514a 100644 --- a/packages/vkui/src/components/Tabs/Tabs.e2e.tsx +++ b/packages/vkui/src/components/Tabs/Tabs.e2e.tsx @@ -1,5 +1,5 @@ import { test } from '@vkui-e2e/test'; -import { Appearance } from '../../lib/appearance'; +import { ColorScheme } from '../../lib/colorScheme'; import { TabsItemsFlexModePlayground, TabsPlayground } from './Tabs.e2e-playground'; test('Tabs', async ({ mount, expectScreenshotClippedToContent, componentPlaygroundProps }) => { @@ -9,7 +9,7 @@ test('Tabs', async ({ mount, expectScreenshotClippedToContent, componentPlaygrou test.describe('Tabs', () => { test.use({ - onlyForAppearances: [Appearance.LIGHT], + onlyForColorSchemes: [ColorScheme.LIGHT], }); test('layout fill mode', async ({ mount, diff --git a/packages/vkui/src/components/Tappable/Tappable.e2e.tsx b/packages/vkui/src/components/Tappable/Tappable.e2e.tsx index f064c2ca57..b87905e1eb 100644 --- a/packages/vkui/src/components/Tappable/Tappable.e2e.tsx +++ b/packages/vkui/src/components/Tappable/Tappable.e2e.tsx @@ -11,7 +11,7 @@ test.describe('Tappable', () => { test.describe('State: Focus Visible', () => { test.use({ onlyForPlatforms: [Platform.ANDROID], - onlyForAppearances: ['light'], + onlyForColorSchemes: ['light'], }); ['inside', 'outside'].forEach((mode) => { diff --git a/packages/vkui/src/components/Textarea/Textarea.e2e-playground.tsx b/packages/vkui/src/components/Textarea/Textarea.e2e-playground.tsx index 73c204b95b..2262fc2aa7 100644 --- a/packages/vkui/src/components/Textarea/Textarea.e2e-playground.tsx +++ b/packages/vkui/src/components/Textarea/Textarea.e2e-playground.tsx @@ -3,7 +3,7 @@ import { ComponentPlayground, type ComponentPlaygroundProps } from '@vkui-e2e/pl import { BREAKPOINTS } from '../../lib/adaptivity'; import { AdaptivityProvider } from '../AdaptivityProvider/AdaptivityProvider'; import { AppRoot } from '../AppRoot/AppRoot'; -import { AppearanceProvider } from '../AppearanceProvider/AppearanceProvider'; +import { ColorSchemeProvider } from '../ColorSchemeProvider/ColorSchemeProvider'; import { Div } from '../Div/Div'; import { Flex } from '../Flex/Flex'; import { IconButton } from '../IconButton/IconButton'; @@ -69,7 +69,7 @@ export const TextareaPlayground = (props: ComponentPlaygroundProps) => { ); }; -export const TextareaStatePlayground = ({ appearance }: ComponentPlaygroundProps) => { +export const TextareaStatePlayground = ({ colorScheme }: ComponentPlaygroundProps) => { return ( - +