diff --git a/packages/react-ui-smoke-test/cra-template-react-ui/template/src/index.tsx b/packages/react-ui-smoke-test/cra-template-react-ui/template/src/index.tsx
index 6090560dec0..5d90d531ec6 100644
--- a/packages/react-ui-smoke-test/cra-template-react-ui/template/src/index.tsx
+++ b/packages/react-ui-smoke-test/cra-template-react-ui/template/src/index.tsx
@@ -1,13 +1,30 @@
-import React from 'react';
-import { createRoot } from 'react-dom/client';
+import React, {StrictMode} from 'react';
+import { render } from 'react-dom';
import { App } from './App';
import * as serviceWorker from './serviceWorker';
const container = document.getElementById('root');
+
+let strictMode = false;
+if (process.env.STRICT_MODE === "true") {
+ strictMode = true;
+}
+
+function StrictModeWrapper(props: {children: React.ReactElement}) {
+ return strictMode
+ ?
+ {props.children}
+
+ : props.children
+}
+
if (container) {
- const root = createRoot(container);
- root.render();
+ render(
+
+
+ ,
+ container);
}
// If you want your app to work offline and load faster, you can change
diff --git a/packages/react-ui-smoke-test/smoke.test.ts b/packages/react-ui-smoke-test/smoke.test.ts
index fe053382f23..e89bad5e9b3 100644
--- a/packages/react-ui-smoke-test/smoke.test.ts
+++ b/packages/react-ui-smoke-test/smoke.test.ts
@@ -51,14 +51,14 @@ describe('React-ui smoke test', () => {
serveProcess = serveApplication(appDirectory);
await openPageOnBrowser(screenshotPath);
- expect(console.error).not.toBeCalled();
+ expect(console.error).not.toHaveBeenCalled();
},
TIMEOUT,
);
it('Render all controls and validations on server side (SSR)', async () => {
execSync(`yarn install && yarn server`, { stdio: 'inherit', cwd: path.join(__dirname, 'react-ui-ssr') });
- expect(console.error).not.toBeCalled();
+ expect(console.error).not.toHaveBeenCalled();
});
});
diff --git a/packages/react-ui-testing/TestPages/src/ReactTestApplication.jsx b/packages/react-ui-testing/TestPages/src/ReactTestApplication.jsx
index 811458f685c..81bda75c3be 100644
--- a/packages/react-ui-testing/TestPages/src/ReactTestApplication.jsx
+++ b/packages/react-ui-testing/TestPages/src/ReactTestApplication.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { StrictMode } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
@@ -30,6 +30,9 @@ let SidePageTestPage;
if (process.env.hasSidePage) SidePageTestPage = require('./components/TestPages/SidePageTestPage').default;
else SidePageTestPage = () =>
Does not work
;
+let strictMode = false;
+if (process.env.strictMode === "true") strictMode = true;
+
import './styles/reset.less';
import './styles/typography.less';
import AutocompleteTestPage from './components/TestPages/AutocompleteTestPage';
@@ -37,36 +40,46 @@ import ToastTestPage from './components/TestPages/ToastTestPage';
import ToggleTestPage from './components/TestPages/ToggleTestPage';
import SwitcherTestPage from './components/TestPages/SwitcherTestPage';
+function StrictModeWrapper(props) {
+ return strictMode
+ ?
+ {props.children}
+
+ : props.children
+}
+
// eslint-disable-next-line import/no-default-export
export default function ReactTestApplication() {
return (
-
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
-
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
);
}
diff --git a/packages/react-ui-testing/TestPages/versions.js b/packages/react-ui-testing/TestPages/versions.js
index dc4ca0bb543..f59a367ffb4 100644
--- a/packages/react-ui-testing/TestPages/versions.js
+++ b/packages/react-ui-testing/TestPages/versions.js
@@ -1,13 +1,14 @@
const shell = require('shelljs');
const semver = require('semver');
const reactUiLocalVersionStub = '9.9.9';
+let reactVersion;
const versionsInfo = [
{
- react: '17.0.2',
+ react: reactVersion ?? '17.0.2',
'@skbkontur/react-ui': [reactUiLocalVersionStub],
dependencies: {
- 'react-dom': '17.0.2',
+ 'react-dom': reactVersion ?? '17.0.2',
},
},
];
diff --git a/packages/react-ui-testing/TestPages/webpack.config.js b/packages/react-ui-testing/TestPages/webpack.config.js
index 65ed71dd372..4d7884af083 100644
--- a/packages/react-ui-testing/TestPages/webpack.config.js
+++ b/packages/react-ui-testing/TestPages/webpack.config.js
@@ -83,6 +83,7 @@ function createConfig(reactVersion, reactUIVersion) {
'process.env.newCombobox': JSON.stringify(semver.satisfies(reactUIVersion, '>=0.7.0')),
'process.env.reactUIVersion': JSON.stringify(reactUIVersion),
'process.env.baseUrl': JSON.stringify(`/${reactVersion}/${reactUIVersion}`),
+ 'process.env.strictMode': process.env.STRICT_MODE,
}),
new HtmlWebpackPlugin({
filename: `${reactVersion}/${reactUIVersion}/index.html`,
diff --git a/packages/react-ui-validations/.storybook/main.ts b/packages/react-ui-validations/.storybook/main.ts
index 90184cd1cca..41ddcbda4f1 100644
--- a/packages/react-ui-validations/.storybook/main.ts
+++ b/packages/react-ui-validations/.storybook/main.ts
@@ -8,7 +8,7 @@ const config: StorybookConfig = {
name: '@storybook/react-webpack5',
options: {
fastRefresh: !isTestEnv,
- strictMode: true,
+ strictMode: process?.env?.STRICT_MODE === 'true',
},
},
core: {
diff --git a/packages/react-ui-validations/package.json b/packages/react-ui-validations/package.json
index 913e9c25d4e..acf0fa8b4f2 100644
--- a/packages/react-ui-validations/package.json
+++ b/packages/react-ui-validations/package.json
@@ -75,10 +75,10 @@
"@skbkontur/storybook-addon-live-examples": "0.0.17",
"@storybook/addon-a11y": "7.6.18",
"@storybook/addon-controls": "7.6.18",
+ "@storybook/addon-docs": "7.6.18",
"@storybook/addon-essentials": "7.6.18",
"@storybook/addon-interactions": "^7.6.18",
"@storybook/addon-links": "7.6.18",
- "@storybook/addon-docs": "7.6.18",
"@storybook/blocks": "7.6.18",
"@storybook/react": "7.6.18",
"@storybook/react-webpack5": "7.6.18",
diff --git a/packages/react-ui-validations/tests/test-setup.js b/packages/react-ui-validations/tests/test-setup.js
index 444960649cb..331823cc049 100644
--- a/packages/react-ui-validations/tests/test-setup.js
+++ b/packages/react-ui-validations/tests/test-setup.js
@@ -1,7 +1,7 @@
import { configure } from '@testing-library/react';
import '@testing-library/jest-dom';
-configure({ testIdAttribute: 'data-tid' });
+configure({ testIdAttribute: 'data-tid', reactStrictMode: process?.env?.STRICT_MODE === 'true' });
jest.mock('../src/smoothScrollIntoView', () => {
const originalModule = jest.requireActual('../src/smoothScrollIntoView');
diff --git a/packages/react-ui/.storybook/config-stories.ts b/packages/react-ui/.storybook/config-stories.ts
index 850492db17f..6890b67b499 100644
--- a/packages/react-ui/.storybook/config-stories.ts
+++ b/packages/react-ui/.storybook/config-stories.ts
@@ -19,9 +19,8 @@ const config: StorybookConfig = {
framework: {
name: '@storybook/react-webpack5',
options: {
- legacyRootApi: true,
fastRefresh: true,
- strictMode: true,
+ strictMode: process?.env?.STRICT_MODE === 'true',
},
},
core: {
diff --git a/packages/react-ui/.storybook/preview.tsx b/packages/react-ui/.storybook/preview.tsx
index 81cff15c677..80aaa47957f 100644
--- a/packages/react-ui/.storybook/preview.tsx
+++ b/packages/react-ui/.storybook/preview.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { StrictMode } from 'react';
import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';
import { Preview } from '@storybook/react';
import { addons } from '@storybook/manager-api';
diff --git a/packages/react-ui/internal/PerformanceMetrics/PerformanceMetrics.tsx b/packages/react-ui/internal/PerformanceMetrics/PerformanceMetrics.tsx
deleted file mode 100644
index d210aef5bd1..00000000000
--- a/packages/react-ui/internal/PerformanceMetrics/PerformanceMetrics.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import React from 'react';
-import { createRoot } from 'react-dom/client';
-
-import { Button } from '../../components/Button';
-import { Nullable } from '../../typings/utility-types';
-import { Spinner } from '../../components/Spinner';
-
-const PANEL_WRAPPER_STYLES = { width: '45%', display: 'inline-block', verticalAlign: 'top' };
-
-interface PerformanceMetricsProps {
- componentsA: React.ReactElement;
- componentsB: React.ReactElement;
-}
-
-export function PerformanceMetrics(props: PerformanceMetricsProps) {
- return (
-
- );
-}
-
-interface PerformanceMetricsPanelProps {
- title: string;
- component: React.ReactElement;
-}
-interface PerformanceMetricsPanelState {
- mounted: boolean;
-}
-
-class PerformanceMetricsPanel extends React.Component {
- public state: PerformanceMetricsPanelState = {
- mounted: false,
- };
- private container: Nullable;
-
- public render() {
- return (
-
-
{this.props.title}
-
-
-
-
-
- );
- }
-
- public componentDidMount() {
- if (this.state.mounted && this.container) {
- const root = createRoot(this.container);
- root.render(this.props.component);
- }
- }
-
- public componentDidUpdate(): void {
- if (!this.container) {
- return;
- }
- if (this.state.mounted) {
- const root = createRoot(this.container);
- root.render(this.props.component);
- } else {
- const root = createRoot(this.container);
- root.unmount();
- }
- }
-
- private setContainerRef = (element: Nullable) => {
- this.container = element;
- };
-
- private toggleMountedState = () => {
- this.setState({
- mounted: !this.state.mounted,
- });
- };
-}
diff --git a/packages/react-ui/internal/PerformanceMetrics/__stories__/PerformanceMetrics.stories.tsx b/packages/react-ui/internal/PerformanceMetrics/__stories__/PerformanceMetrics.stories.tsx
deleted file mode 100644
index f4a76e78cd8..00000000000
--- a/packages/react-ui/internal/PerformanceMetrics/__stories__/PerformanceMetrics.stories.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import React from 'react';
-
-import { PerformanceMetrics } from '../PerformanceMetrics';
-import { Input } from '../../../components/Input';
-import { Tooltip } from '../../../components/Tooltip';
-
-function getTooltipContent() {
- return 'Tooltip content';
-}
-const INPUTS_COUNT = 150;
-const INPUT_WIDTH = 50;
-const DUMMY = new Array(INPUTS_COUNT).fill('');
-const WRAPPER_STYLES = { marginRight: 10, marginBottom: 10, display: 'inline-block' };
-
-const inputs = (
-
- {DUMMY.map((i, index) => (
-
-
-
- ))}
-
-);
-
-const inputsWithTooltip = (
-
- {DUMMY.map((i, index) => (
-
-
-
-
-
- ))}
-
-);
-
-export default { title: 'PerformanceMetrics', parameters: { creevey: { skip: true } } };
-
-export const BareInputsVsTooltipInput = () => {
- return (
-
- );
-};
-BareInputsVsTooltipInput.storyName = 'Bare Inputs vs Tooltip+Input';
diff --git a/packages/react-ui/package.json b/packages/react-ui/package.json
index 35a87cdc761..5c58a197866 100644
--- a/packages/react-ui/package.json
+++ b/packages/react-ui/package.json
@@ -151,8 +151,8 @@
"selenium-webdriver": "^4.27.0",
"semver": "^7.6.2",
"serve": "^13.0.2",
- "string-replace-loader": "3.1.0",
"storybook": "7.6.18",
+ "string-replace-loader": "3.1.0",
"style-loader": "^4.0.0",
"stylelint": "^16.6.0",
"stylelint-config-standard": "^36.0.0",
diff --git a/packages/react-ui/test-setup.js b/packages/react-ui/test-setup.js
index 0dc2e0b52fa..1c2d91bbd84 100644
--- a/packages/react-ui/test-setup.js
+++ b/packages/react-ui/test-setup.js
@@ -9,6 +9,7 @@ Enzyme.configure({ adapter: new Adapter() });
configure({
testIdAttribute: 'data-tid',
+ reactStrictMode: process?.env?.STRICT_MODE === 'true',
});
jest.mock('react-focus-lock', () => (props) => {props.children}
);
diff --git a/scripts/testing/package-versions.json b/scripts/testing/package-versions.json
new file mode 100644
index 00000000000..7ba3e96416f
--- /dev/null
+++ b/scripts/testing/package-versions.json
@@ -0,0 +1,33 @@
+{
+ "react": {
+ "16": {
+ "react": "^16.0.0",
+ "react-dom": "^16.0.0",
+ "@testing-library/react": "^12.1.5"
+ },
+ "17": {
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "@testing-library/react": "12.1.5"
+ },
+ "18": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "@testing-library/react": "15.0.7"
+ },
+ "19": {
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "@testing-library/react": "16.2.0",
+ "@testing-library/dom": "^10.4.0"
+ }
+ },
+ "typescript": {
+ "4": {
+ "typescript": "^4.9.4"
+ },
+ "5": {
+ "typescript": "^5.8.2"
+ }
+ }
+}
diff --git a/scripts/testing/set-package-versions.js b/scripts/testing/set-package-versions.js
new file mode 100644
index 00000000000..50022b23cdd
--- /dev/null
+++ b/scripts/testing/set-package-versions.js
@@ -0,0 +1,63 @@
+const path = require('path');
+const fs = require('fs');
+
+const reactVersion = process?.env?.REACT_VERSION;
+const tsVersion = process?.env?.TYPESCRIPT_VERSION;
+
+// эти 2 команды в самом конце закинуть в package.json, чтобы весь механизм завелся
+//"preinstall": "node scripts/testing/set-package-versions.js", -- для ci
+//"set-testing-package-versions-local": "cross-env REACT_VERSION=17 TYPESCRIPT_VERSION=4 node scripts/testing/set-package-versions.js" -- для Local
+
+if (!(reactVersion && tsVersion)) {
+ return;
+}
+
+const packagesPath = path.resolve(__dirname, "..", "..", "packages");
+const {react, typescript} = getJsonFile(path.resolve(__dirname, "package-versions.json"));
+
+const packagesForReact = react[reactVersion];
+const packagesForTypescript = typescript[tsVersion];
+
+const allPackages = {...packagesForReact, ...packagesForTypescript};
+
+try {
+ patchSmokeTestPackage();
+ patchSeleniumTestsPackage();
+ patchPackageJsons();
+} catch (e) {
+ //log
+}
+
+function patchPackageJsons() {
+ const pathToReactUi = path.resolve(packagesPath, "react-ui", "package.json");
+ const pathToReactUiValidation = path.resolve(packagesPath, "react-ui-validations", "package.json");
+ [pathToReactUi, pathToReactUiValidation].forEach(packagePath => {
+ const json = getJsonFile(packagePath);
+ json.devDependencies = {...json.devDependencies, ...allPackages}
+ writeJsonFile(packagePath, json);
+ })
+}
+
+function patchSeleniumTestsPackage() {
+ const pathToConfig = path.resolve(packagesPath, "react-ui-testing", "TestPages", "versions.js");
+ const config = fs.readFileSync(pathToConfig, 'utf8');
+ const patchedConfig = config.replace("let reactVersion;", `let reactVersion = ${packagesForReact?.react.replaceAll('^', '')};`)
+ fs.writeFileSync(pathToConfig, patchedConfig);
+ console.log(pathToConfig, "patched");
+}
+
+function patchSmokeTestPackage() {
+ const pathToConfig = path.resolve(packagesPath, "react-ui-smoke-test", "cra-template-react-ui", "template.json");
+ const package = getJsonFile(pathToConfig);
+ package.package.dependencies = {...package.package.dependencies, ...packagesForReact};
+ writeJsonFile(pathToConfig, package);
+ console.log(pathToConfig, "patched");
+}
+
+function getJsonFile(path) {
+ return JSON.parse(fs.readFileSync(path, 'utf8'));
+}
+
+function writeJsonFile(path, content) {
+ fs.writeFileSync(path, JSON.stringify(content, null, 2) + "\n");
+}
diff --git a/yarn.lock b/yarn.lock
index a53aea53f62..35da755e8e3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -19983,7 +19983,7 @@ string-replace-loader@3.1.0, string-replace-loader@^3.1.0:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
-"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -20001,6 +20001,15 @@ string-width@^1.0.1:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -20127,7 +20136,7 @@ stringify-object@^3.2.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -20148,6 +20157,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-ansi@^7.0.1, strip-ansi@^7.1.0:
version "7.1.0"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -22015,7 +22031,7 @@ wordwrap@^1.0.0:
resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -22033,6 +22049,15 @@ wrap-ansi@^5.1.0:
string-width "^3.0.0"
strip-ansi "^5.0.0"
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"