Browse Source

chore: upgrade to React 18 (#5450)

* chore: upgrade to React 18

* better type

* use React.FC to fix type

Co-authored-by: dwelle <luzar.david@gmail.com>
Aakansha Doshi 2 years ago
parent
commit
15d79f8fee

+ 4 - 4
package.json

@@ -26,8 +26,8 @@
     "@tldraw/vec": "1.7.1",
     "@types/jest": "27.4.0",
     "@types/pica": "5.1.3",
-    "@types/react": "17.0.39",
-    "@types/react-dom": "17.0.11",
+    "@types/react": "18.0.15",
+    "@types/react-dom": "18.0.6",
     "@types/socket.io-client": "1.4.36",
     "browser-fs-access": "0.29.1",
     "clsx": "1.1.1",
@@ -47,8 +47,8 @@
     "png-chunks-extract": "1.0.0",
     "points-on-curve": "0.2.0",
     "pwacompat": "2.0.17",
-    "react": "17.0.2",
-    "react-dom": "17.0.2",
+    "react": "18.2.0",
+    "react-dom": "18.2.0",
     "react-scripts": "4.0.3",
     "roughjs": "4.5.2",
     "sass": "1.51.0",

+ 1 - 0
src/components/Card.tsx

@@ -4,6 +4,7 @@ import "./Card.scss";
 
 export const Card: React.FC<{
   color: keyof OpenColor | "primary";
+  children?: React.ReactNode;
 }> = ({ children, color }) => {
   return (
     <div

+ 1 - 0
src/components/CheckboxItem.tsx

@@ -8,6 +8,7 @@ export const CheckboxItem: React.FC<{
   checked: boolean;
   onChange: (checked: boolean, event: React.MouseEvent) => void;
   className?: string;
+  children?: React.ReactNode;
 }> = ({ children, checked, onChange, className }) => {
   return (
     <div

+ 1 - 0
src/components/ImageExportDialog.tsx

@@ -58,6 +58,7 @@ const ExportButton: React.FC<{
   onClick: () => void;
   title: string;
   shade?: number;
+  children?: React.ReactNode;
 }> = ({ children, title, onClick, color, shade = 6 }) => {
   return (
     <button

+ 1 - 1
src/components/LayerUI.tsx

@@ -308,7 +308,7 @@ const LayerUI = ({
           </Stack.Col>
           {!appState.viewModeEnabled && (
             <Section heading="shapes">
-              {(heading) => (
+              {(heading: React.ReactNode) => (
                 <Stack.Col gap={4} align="start">
                   <Stack.Row
                     gap={1}

+ 1 - 1
src/components/LibraryMenu.tsx

@@ -224,7 +224,7 @@ export const LibraryMenu = ({
   }, [setPublishLibSuccess, publishLibSuccess]);
 
   const onPublishLibSuccess = useCallback(
-    (data, libraryItems: LibraryItems) => {
+    (data: { url: string; authorName: string }, libraryItems: LibraryItems) => {
       setShowPublishLibraryDialog(false);
       setPublishLibSuccess({ url: data.url, authorName: data.authorName });
       const nextLibItems = libraryItems.slice();

+ 1 - 1
src/components/MobileMenu.tsx

@@ -68,7 +68,7 @@ export const MobileMenu = ({
     return (
       <FixedSideContainer side="top" className="App-top-bar">
         <Section heading="shapes">
-          {(heading) => (
+          {(heading: React.ReactNode) => (
             <Stack.Col gap={4} align="center">
               <Stack.Row gap={1} className="App-toolbar-container">
                 <Island padding={1} className="App-toolbar">

+ 4 - 5
src/components/Section.tsx

@@ -2,12 +2,11 @@ import React from "react";
 import { t } from "../i18n";
 import { useExcalidrawContainer } from "./App";
 
-interface SectionProps extends React.HTMLProps<HTMLElement> {
+export const Section: React.FC<{
   heading: string;
-  children: React.ReactNode | ((header: React.ReactNode) => React.ReactNode);
-}
-
-export const Section = ({ heading, children, ...props }: SectionProps) => {
+  children?: React.ReactNode | ((heading: React.ReactNode) => React.ReactNode);
+  className?: string;
+}> = ({ heading, children, ...props }) => {
   const { id } = useExcalidrawContainer();
   const header = (
     <h2 className="visually-hidden" id={`${id}-${heading}-title`}>

+ 9 - 3
src/index.tsx

@@ -1,8 +1,14 @@
-import ReactDOM from "react-dom";
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
 import ExcalidrawApp from "./excalidraw-app";
 
 import "./excalidraw-app/pwa";
 import "./excalidraw-app/sentry";
 window.__EXCALIDRAW_SHA__ = process.env.REACT_APP_GIT_SHA;
-
-ReactDOM.render(<ExcalidrawApp />, document.getElementById("root"));
+const rootElement = document.getElementById("root")!;
+const root = createRoot(rootElement);
+root.render(
+  <StrictMode>
+    <ExcalidrawApp />
+  </StrictMode>,
+);

+ 26 - 15
src/packages/excalidraw/example/App.tsx

@@ -24,7 +24,10 @@ import {
   LibraryItems,
   PointerDownState as ExcalidrawPointerDownState,
 } from "../../../types";
-import { ExcalidrawElement } from "../../../element/types";
+import {
+  ExcalidrawElement,
+  NonDeletedExcalidrawElement,
+} from "../../../element/types";
 import { ImportedLibraryData } from "../../../data/types";
 
 declare global {
@@ -249,20 +252,28 @@ export default function App() {
     excalidrawAPI?.updateScene(sceneData);
   };
 
-  const onLinkOpen = useCallback((element, event) => {
-    const link = element.link;
-    const { nativeEvent } = event.detail;
-    const isNewTab = nativeEvent.ctrlKey || nativeEvent.metaKey;
-    const isNewWindow = nativeEvent.shiftKey;
-    const isInternalLink =
-      link.startsWith("/") || link.includes(window.location.origin);
-    if (isInternalLink && !isNewTab && !isNewWindow) {
-      // signal that we're handling the redirect ourselves
-      event.preventDefault();
-      // do a custom redirect, such as passing to react-router
-      // ...
-    }
-  }, []);
+  const onLinkOpen = useCallback(
+    (
+      element: NonDeletedExcalidrawElement,
+      event: CustomEvent<{
+        nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
+      }>,
+    ) => {
+      const link = element.link!;
+      const { nativeEvent } = event.detail;
+      const isNewTab = nativeEvent.ctrlKey || nativeEvent.metaKey;
+      const isNewWindow = nativeEvent.shiftKey;
+      const isInternalLink =
+        link.startsWith("/") || link.includes(window.location.origin);
+      if (isInternalLink && !isNewTab && !isNewWindow) {
+        // signal that we're handling the redirect ourselves
+        event.preventDefault();
+        // do a custom redirect, such as passing to react-router
+        // ...
+      }
+    },
+    [],
+  );
 
   const onCopy = async (type: string) => {
     await exportToClipboard({

+ 27 - 21
yarn.lock

@@ -2227,10 +2227,10 @@
   resolved "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz"
   integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
 
-"@types/react-dom@17.0.11":
-  version "17.0.11"
-  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.11.tgz#e1eadc3c5e86bdb5f7684e00274ae228e7bcc466"
-  integrity sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==
+"@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" "*"
 
@@ -2241,7 +2241,7 @@
   dependencies:
     "@types/react" "^17"
 
-"@types/react@*", "@types/react@17.0.39":
+"@types/react@*":
   version "17.0.39"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce"
   integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==
@@ -2250,6 +2250,15 @@
     "@types/scheduler" "*"
     csstype "^3.0.2"
 
+"@types/react@18.0.15":
+  version "18.0.15"
+  resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.15.tgz#d355644c26832dc27f3e6cbf0c4f4603fc4ab7fe"
+  integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==
+  dependencies:
+    "@types/prop-types" "*"
+    "@types/scheduler" "*"
+    csstype "^3.0.2"
+
 "@types/react@^17":
   version "17.0.44"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7"
@@ -10161,14 +10170,13 @@ react-dev-utils@^11.0.3:
     strip-ansi "6.0.0"
     text-table "0.2.0"
 
-react-dom@17.0.2:
-  version "17.0.2"
-  resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
-  integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
+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"
-    scheduler "^0.20.2"
+    scheduler "^0.23.0"
 
 react-error-overlay@^6.0.9:
   version "6.0.9"
@@ -10256,13 +10264,12 @@ react-scripts@4.0.3:
   optionalDependencies:
     fsevents "^2.1.3"
 
-react@17.0.2:
-  version "17.0.2"
-  resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
-  integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
+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"
 
 read-pkg-up@^2.0.0:
   version "2.0.0"
@@ -10800,13 +10807,12 @@ saxes@^5.0.1:
   dependencies:
     xmlchars "^2.2.0"
 
-scheduler@^0.20.2:
-  version "0.20.2"
-  resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz"
-  integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
+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"
 
 schema-utils@^1.0.0:
   version "1.0.0"