Skip to content

Commit

Permalink
Add basic React 18 support (#6827)
Browse files Browse the repository at this point in the history
* build(deps): Bump react and react-dom to v18

* refactor(docs): update docs site initialization to use createRoot API

* build(babel): enforce classic react runtime and allow declare fields in babel config

* refactor(*): update children prop types to use React 18 PropsWithChildren

* build(*): bump react and react-dom versions

* style(EuiForm): replace React.FC with FunctionComponent usage

* style(*): reorder PropsWithChildren usage to be from least to most specific
  • Loading branch information
tkajtoch committed Jul 31, 2023
1 parent 35b3358 commit 1c672b1
Show file tree
Hide file tree
Showing 38 changed files with 371 additions and 337 deletions.
4 changes: 2 additions & 2 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ module.exports = {
"corejs": !process.env.NO_COREJS_POLYFILL ? '3.6' : undefined,
"modules": process.env.BABEL_MODULES ? process.env.BABEL_MODULES === 'false' ? false : process.env.BABEL_MODULES : "commonjs" // babel's default is commonjs
}],
["@babel/typescript", { isTSX: true, allExtensions: true }],
"@babel/react",
["@babel/react", { runtime: 'classic' }],
["@babel/typescript", { isTSX: true, allExtensions: true, allowDeclareFields: true }],
[
"@emotion/babel-preset-css-prop",
{
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
},
"resolutions": {
"**/prismjs": "1.27.0",
"**/react": "^17.0.0",
"**/react": "^18",
"**/@types/react": "^18",
"react-focus-lock": "^2.9.5"
},
"pre-commit": [
Expand Down Expand Up @@ -147,8 +148,8 @@
"@types/enzyme": "^3.10.5",
"@types/jest": "^24.0.6",
"@types/node": "^10.17.5",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@types/react-is": "^17.0.3",
"@types/react-router-dom": "^5.3.3",
"@types/tabbable": "^3.1.2",
Expand Down Expand Up @@ -224,9 +225,9 @@
"prop-types": "^15.6.0",
"puppeteer": "^5.5.0",
"raw-loader": "^4.0.1",
"react": "^17.0.2",
"react": "^18.2.0",
"react-docgen-typescript": "^2.2.2",
"react-dom": "^17.0.2",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-redux": "^7.2.1",
"react-refresh": "^0.11.0",
Expand Down Expand Up @@ -260,12 +261,12 @@
"@elastic/datemath": "^5.0.2",
"@emotion/css": "11.x",
"@emotion/react": "11.x",
"@types/react": "^16.9 || ^17.0",
"@types/react-dom": "^16.9 || ^17.0",
"@types/react": "^16.9 || ^17.0 || ^18.0",
"@types/react-dom": "^16.9 || ^17.0 || ^18.0",
"moment": "^2.13.0",
"prop-types": "^15.5.0",
"react": "^16.12 || ^17.0",
"react-dom": "^16.12 || ^17.0",
"react": "^16.12 || ^17.0 || ^18.0",
"react-dom": "^16.12 || ^17.0 || ^18.0",
"typescript": "~4.5.3"
},
"files": [
Expand Down
4 changes: 2 additions & 2 deletions src-docs/src/components/with_theme/theme_context.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { EUI_THEMES, EUI_THEME } from '../../../../src/themes';
// @ts-ignore importing from a JS file
import { applyTheme } from '../../services';
Expand Down Expand Up @@ -45,7 +45,7 @@ interface State {

export const ThemeContext = React.createContext(defaultState);

export class ThemeProvider extends React.Component<object, State> {
export class ThemeProvider extends React.Component<PropsWithChildren, State> {
constructor(props: object) {
super(props);

Expand Down
241 changes: 122 additions & 119 deletions src-docs/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { createElement } from 'react';
import ReactDOM from 'react-dom';
import React, { createElement, StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { HashRouter, Switch, Route, Redirect } from 'react-router-dom';
import { Helmet } from 'react-helmet';
Expand Down Expand Up @@ -40,130 +40,133 @@ const routes = [
...childRoutes,
];

ReactDOM.render(
<Provider store={store}>
<ThemeProvider>
<AppContext>
<HashRouter>
<Switch>
{routes.map(
({
name,
path,
sections,
isBeta,
isNew,
component,
from,
to,
}) => {
const meta = (
<Helmet>
<title>{`${name} - Elastic UI Framework`}</title>
</Helmet>
);
const mainComponent = (
<Route
key={path}
path={`/${path}`}
render={(props) => {
const { location } = props;
// prevents encoded urls with a section id to fail
if (location.pathname.includes('%23')) {
const url = decodeURIComponent(location.pathname);
return <Redirect push to={url} />;
} else {
return (
<AppView
currentRoute={{
name,
path,
sections,
isBeta,
isNew,
}}
>
{({ theme }) => (
<>
{meta}
{createElement(component, {
selectedTheme: theme,
title: name,
})}
</>
)}
</AppView>
);
}
}}
/>
);
const root = createRoot(document.getElementById('guide'));

const standaloneSections = [];
(sections || []).forEach(
({ id, fullScreen, sections: subSections }) => {
if (fullScreen) {
const { slug, demo } = fullScreen;
standaloneSections.push(
<Route
key={`/${path}/${slug}`}
path={`/${path}/${slug}`}
render={() => (
<ExampleContext.Provider
value={{ parentPath: `/${path}#${id}` }}
root.render(
<StrictMode>
<Provider store={store}>
<ThemeProvider>
<AppContext>
<HashRouter>
<Switch>
{routes.map(
({
name,
path,
sections,
isBeta,
isNew,
component,
from,
to,
}) => {
const meta = (
<Helmet>
<title>{`${name} - Elastic UI Framework`}</title>
</Helmet>
);
const mainComponent = (
<Route
key={path}
path={`/${path}`}
render={(props) => {
const { location } = props;
// prevents encoded urls with a section id to fail
if (location.pathname.includes('%23')) {
const url = decodeURIComponent(location.pathname);
return <Redirect push to={url} />;
} else {
return (
<AppView
currentRoute={{
name,
path,
sections,
isBeta,
isNew,
}}
>
{meta}
{demo}
</ExampleContext.Provider>
)}
/>
);
}
if (subSections) {
subSections.forEach(({ fullScreen, id: sectionId }) => {
if (fullScreen) {
const { slug, demo } = fullScreen;
standaloneSections.push(
<Route
key={`/${path}/${id}/${slug}`}
path={`/${path}/${id}/${slug}`}
render={() => (
<ExampleContext.Provider
value={{
parentPath: `/${path}/${id}#${sectionId}`,
}}
>
{({ theme }) => (
<>
{meta}
{demo}
</ExampleContext.Provider>
{createElement(component, {
selectedTheme: theme,
title: name,
})}
</>
)}
/>
</AppView>
);
}
});
}}
/>
);

const standaloneSections = [];
(sections || []).forEach(
({ id, fullScreen, sections: subSections }) => {
if (fullScreen) {
const { slug, demo } = fullScreen;
standaloneSections.push(
<Route
key={`/${path}/${slug}`}
path={`/${path}/${slug}`}
render={() => (
<ExampleContext.Provider
value={{ parentPath: `/${path}#${id}` }}
>
{meta}
{demo}
</ExampleContext.Provider>
)}
/>
);
}
if (subSections) {
subSections.forEach(({ fullScreen, id: sectionId }) => {
if (fullScreen) {
const { slug, demo } = fullScreen;
standaloneSections.push(
<Route
key={`/${path}/${id}/${slug}`}
path={`/${path}/${id}/${slug}`}
render={() => (
<ExampleContext.Provider
value={{
parentPath: `/${path}/${id}#${sectionId}`,
}}
>
{meta}
{demo}
</ExampleContext.Provider>
)}
/>
);
}
});
}
}
}
);
standaloneSections.filter((x) => !!x);
);
standaloneSections.filter((x) => !!x);

// place standaloneSections before mainComponent so their routes take precedent
const routes = [...standaloneSections, mainComponent];
// place standaloneSections before mainComponent so their routes take precedent
const routes = [...standaloneSections, mainComponent];

if (from)
return [
...routes,
<Route exact path={`/${from}`}>
<Redirect to={`/${to}`} />
</Route>,
];
else if (component) return routes;
return null;
}
)}
</Switch>
</HashRouter>
</AppContext>
</ThemeProvider>
</Provider>,
document.getElementById('guide')
if (from)
return [
...routes,
<Route exact path={`/${from}`}>
<Redirect to={`/${to}`} />
</Route>,
];
else if (component) return routes;
return null;
}
)}
</Switch>
</HashRouter>
</AppContext>
</ThemeProvider>
</Provider>
</StrictMode>
);
6 changes: 4 additions & 2 deletions src-docs/src/views/flex/wrapper_styles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { css } from '@emotion/react';
import {
useEuiTheme,
Expand All @@ -18,7 +18,9 @@ export const flexItemHiglightStyles = ({ euiTheme }: UseEuiTheme) => {
`;
};

export const FlexItemHighlightWrapper: React.FC = ({ children }) => {
export const FlexItemHighlightWrapper: React.FC<PropsWithChildren> = ({
children,
}) => {
const euiTheme = useEuiTheme();
return <div css={flexItemHiglightStyles(euiTheme)}>{children}</div>;
};
14 changes: 9 additions & 5 deletions src-docs/src/views/theme/color_mode/inverse.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import React, { useState, FC } from 'react';
import React, {
useState,
FC,
PropsWithChildren,
} from 'react';
import {
EuiThemeProvider,
useEuiTheme,
Expand Down Expand Up @@ -66,7 +70,7 @@ export default () => {
);
};

const ThemedChildren: FC = ({ children, ...rest }) => {
const ThemedChildren: FC<PropsWithChildren> = ({ children, ...rest }) => {
const { colorMode: _colorMode } = useEuiTheme();
const colorMode = _colorMode.toLowerCase();
return (
Expand Down Expand Up @@ -101,7 +105,7 @@ const ThemedChildren: FC = ({ children, ...rest }) => {
);
};

const Popover: FC = ({ children }) => {
const Popover: FC<PropsWithChildren> = ({ children }) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
return (
<EuiPopover
Expand All @@ -123,7 +127,7 @@ const Popover: FC = ({ children }) => {
);
};

const Modal: FC = ({ children }) => {
const Modal: FC<PropsWithChildren> = ({ children }) => {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<>
Expand Down Expand Up @@ -151,7 +155,7 @@ const Modal: FC = ({ children }) => {
);
};

const Flyout: FC = ({ children }) => {
const Flyout: FC<PropsWithChildren> = ({ children }) => {
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
return (
<>
Expand Down
Loading

0 comments on commit 1c672b1

Please sign in to comment.