From e8df593785b014a812811570122ccd891cbedcc6 Mon Sep 17 00:00:00 2001 From: Luke Reddick Date: Wed, 7 Sep 2022 17:47:50 -0600 Subject: [PATCH] [React 18] Update to be compatible. --- package.json | 12 +++--- src/core.js | 15 ++++--- src/react.js | 24 +++++------ src/strategies/custom_elements.js | 12 +++--- src/types.d.ts | 13 +++--- yarn.lock | 72 +++++++++++++++++-------------- 6 files changed, 79 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index f4b8222..8b3f0b9 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "@babel/preset-react": "^7.0.0", "@types/jest": "^24.0.5", "@types/puppeteer": "^1.12.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.2", + "@types/react": "^18.0.18", + "@types/react-dom": "^18.0.6", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^23.6.0", "expect-puppeteer": "3.5.1", @@ -22,8 +22,8 @@ "npm-run-all": "^4.1.5", "prettier": "^1.15.3", "puppeteer": "^1.12.2", - "react": "^16.7.0", - "react-dom": "^16.7.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "rollup": "^1.1.2", "rollup-plugin-babel": "^4.3.2", "rollup-plugin-babel-minify": "^7.0.0", @@ -64,8 +64,8 @@ "main": "dist/remount.es5.js", "module": "dist/remount.js", "peerDependencies": { - "react": ">= 15.0.0", - "react-dom": ">= 15.0.0" + "react": ">= 18.0.0", + "react-dom": ">= 18.0.0" }, "repository": { "type": "git", diff --git a/src/core.js b/src/core.js index 3bdd49b..f6a0d92 100644 --- a/src/core.js +++ b/src/core.js @@ -6,6 +6,7 @@ /** @typedef { import('./types').ElementSpec } ElementSpec */ /** @typedef { import('./types').PropertyMap } PropertyMap */ /** @typedef { import('./types').Strategy } Strategy */ +/** @typedef { import('react-dom/client').Root } Root */ import * as CustomElementsStrategy from './strategies/custom_elements' import * as MutationObserverStrategy from './strategies/mutation_observer' @@ -80,22 +81,22 @@ export function define(components, defaults) { // Define a custom element. Strategy.defineElement(elSpec, name, { - onMount(element, mountPoint) { + onMount(element, root) { const props = getProps(element, elSpec.attributes) if (elSpec.shadow && elSpec.retarget) { - adapter.mount(elSpec, mountPoint, props, element) + adapter.mount(elSpec, root, props, element) } else { - adapter.mount(elSpec, mountPoint, props, null) + adapter.mount(elSpec, root, props, null) } }, - onUpdate(element, mountPoint) { + onUpdate(element, root) { const props = getProps(element, elSpec.attributes) - adapter.update(elSpec, mountPoint, props, null) + adapter.update(elSpec, root, props, null) }, - onUnmount(element, mountPoint) { - adapter.unmount(elSpec, mountPoint) + onUnmount(_element, root) { + adapter.unmount(elSpec, root) } }) }) diff --git a/src/react.js b/src/react.js index 8f70101..8d0d4ca 100644 --- a/src/react.js +++ b/src/react.js @@ -1,35 +1,35 @@ // @ts-check /** @typedef { import('./types').ElementSpec } ElementSpec */ +/** @typedef { import('react-dom/client').Root } Root */ import * as React from 'react' -import * as ReactDOM from 'react-dom' import retargetEvents from 'react-shadow-dom-retarget-events' /** * @param {ElementSpec} elSpec - * @param {HTMLElement} mountPoint + * @param {Root} root * @param {object} props * @param {HTMLElement | null} element */ -export function mount(elSpec, mountPoint, props, element) { - return update(elSpec, mountPoint, props, element) +export function mount(elSpec, root, props, element) { + return update(elSpec, root, props, element) } /** - * Updates a custom element by calling `ReactDOM.render()`. + * Updates a custom element by calling `createRoot().render()`. * @private * * @param {ElementSpec} elSpec - * @param {HTMLElement} mountPoint + * @param {Root} root * @param {object} props * @param {HTMLElement | null} element */ -export function update(elSpec, mountPoint, props, element) { +export function update(elSpec, root, props, element) { const { component } = elSpec const reactElement = React.createElement(component, props) - ReactDOM.render(reactElement, mountPoint) + root.render(reactElement); if (element) { retargetEvents(element.shadowRoot) } @@ -39,10 +39,10 @@ export function update(elSpec, mountPoint, props, element) { * Unmounts a component. * @private * - * @param {ElementSpec} elSpec - * @param {HTMLElement} mountPoint + * @param {ElementSpec} _elSpec + * @param {Root} root */ -export function unmount(elSpec, mountPoint) { - ReactDOM.unmountComponentAtNode(mountPoint) +export function unmount(_elSpec, root) { + root.unmount(); } diff --git a/src/strategies/custom_elements.js b/src/strategies/custom_elements.js index f00b80e..a0222f3 100644 --- a/src/strategies/custom_elements.js +++ b/src/strategies/custom_elements.js @@ -9,6 +9,7 @@ /** @typedef { import('../types').PropertyMap } PropertyMap */ import { inject as enableBabelClasses } from '../helpers/babel_es5_adapter' +import { createRoot } from 'react-dom/client' /** * The name of this strategy. @@ -50,21 +51,22 @@ export function defineElement(elSpec, elName, events) { connectedCallback() { this._mountPoint = createMountPoint(this, elSpec) - onMount(this, this._mountPoint) + this._root = createRoot(this._mountPoint) + onMount(this, this._root) } disconnectedCallback() { - if (!this._mountPoint) { + if (!this._root) { return } - onUnmount(this, this._mountPoint) + onUnmount(this, this._root) } attributeChangedCallback() { - if (!this._mountPoint) { + if (!this._root) { return } - onUpdate(this, this._mountPoint) + onUpdate(this, this._root) } } diff --git a/src/types.d.ts b/src/types.d.ts index 64a2db9..ce860cf 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,4 +1,5 @@ import React from 'react' +import { Root } from 'react-dom/client' export type Component = | React.ComponentClass @@ -7,17 +8,17 @@ export type Component = export interface Adapter { mount: ( spec: ElementSpec, - mountPoint: HTMLElement, + root: Root, props: {}, element: HTMLElement | null ) => void update: ( spec: ElementSpec, - mountPoint: HTMLElement, + root: Root, props: {}, element: HTMLElement | null ) => void - unmount: (spec: ElementSpec, mountPoint: HTMLElement) => void + unmount: (spec: ElementSpec, root: Root) => void } export interface PropertyMap { @@ -47,9 +48,9 @@ export interface ElementSpec { export type ReactAdapter = Adapter export interface ElementEvents { - onMount: (source: HTMLElement, mountPoint: HTMLElement) => void - onUpdate: (source: HTMLElement, mountPoint: HTMLElement) => void - onUnmount: (source: HTMLElement, mountPoint: HTMLElement) => void + onMount: (source: HTMLElement, root: Root) => void + onUpdate: (source: HTMLElement, root: Root) => void + onUnmount: (source: HTMLElement, root: Root) => void } export interface Strategy { diff --git a/yarn.lock b/yarn.lock index 8112e38..08e92e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -722,14 +722,14 @@ dependencies: "@types/node" "*" -"@types/react-dom@^16.8.2": - version "16.8.2" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.2.tgz#9bd7d33f908b243ff0692846ef36c81d4941ad12" - integrity sha512-MX7n1wq3G/De15RGAAqnmidzhr2Y9O/ClxPxyqaNg96pGyeXUYPSvujgzEVpLo9oIP4Wn1UETl+rxTN02KEpBw== +"@types/react-dom@^18.0.6": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1" + integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.8.3": +"@types/react@*": version "16.8.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.3.tgz#7b67956f682bea30a5a09b3242c0784ff196c848" integrity sha512-PjPocAxL9SNLjYMP4dfOShW/rj9FDBJGu3JFRt0zEYf77xfihB6fq8zfDpMrV6s82KnAi7F1OEe5OsQX25Ybdw== @@ -737,6 +737,15 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/react@^18.0.18": + version "18.0.18" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.18.tgz#9f16f33d57bc5d9dca848d12c3572110ff9429ac" + integrity sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -744,6 +753,11 @@ dependencies: "@types/node" "*" +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -1618,6 +1632,11 @@ csstype@^2.2.0: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.2.tgz#3043d5e065454579afc7478a18de41909c8a2f01" integrity sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow== +csstype@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" + integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3219,7 +3238,7 @@ longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" dependencies: @@ -3550,7 +3569,7 @@ oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3826,13 +3845,6 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.6.2: - version "15.6.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - dependencies: - loose-envify "^1.3.1" - object-assign "^4.1.1" - proxy-from-env@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" @@ -3910,30 +3922,25 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^16.7.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" - integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg== +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.12.0" + scheduler "^0.23.0" react-shadow-dom-retarget-events@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/react-shadow-dom-retarget-events/-/react-shadow-dom-retarget-events-1.0.8.tgz#411fe79194d974d7d1944622508ac271cc3a4346" integrity sha1-QR/nkZTZdNfRlEYiUIrCccw6Q0Y= -react@^16.7.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" - integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.12.0" read-pkg-up@^1.0.1: version "1.0.1" @@ -4268,13 +4275,12 @@ sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -scheduler@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b" - integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0"