From 77aca493dbb00b9e065abf775a69c2dcb2c8ef35 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Fri, 11 Jun 2021 21:49:43 +0100
Subject: [PATCH 01/21] Add support for React 18

---
 package.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/package.json b/package.json
index 2861c7a1e7..d8471d63ff 100644
--- a/package.json
+++ b/package.json
@@ -94,11 +94,11 @@
     "mini-css-extract-plugin": "^1.6.0",
     "postcss": "^8.3.2",
     "prettier": "2.3.1",
-    "react": "^17.0.2",
+    "react": "alpha",
     "react-contextmenu": "^2.14.0",
     "react-dnd": "^14.0.2",
     "react-dnd-html5-backend": "^14.0.0",
-    "react-dom": "^17.0.2",
+    "react-dom": "alpha",
     "react-popper": "^2.2.5",
     "rollup": "^2.51.2",
     "rollup-plugin-postcss": "^4.0.0",
@@ -106,7 +106,7 @@
     "xlsx": "^0.17.0"
   },
   "peerDependencies": {
-    "react": "^16.14 || ^17.0",
-    "react-dom": "^16.14 || ^17.0"
+    "react": "^16.14 || ^17.0 || ^18.0",
+    "react-dom": "^16.14 || ^17.0 || ^18.0"
   }
 }

From fffcd9aeaa47530ef57bda5d98277963ba732741 Mon Sep 17 00:00:00 2001
From: Aman Mahajan <amahajan@freewheel.com>
Date: Fri, 11 Jun 2021 16:47:32 -0500
Subject: [PATCH 02/21] Usse the new createRoot api to render storybook

---
 .storybook/preview.tsx | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 5395d3b38f..77b356527b 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,5 +1,6 @@
 import 'core-js/stable';
 import { css } from '@linaria/core';
+import ReactDOM, { Container } from 'react-dom';
 
 css`
   :global() {
@@ -49,3 +50,27 @@ css`
     }
   }
 `;
+
+// https://github.com/storybookjs/storybook/issues/10543#issuecomment-650646374
+const nodes = new Map();
+//@ts-expect-error
+ReactDOM.render = (element: React.ReactElement, container: Container) => {
+  let root = nodes.get(container);
+  if (!root) {
+    //@ts-expect-error
+    root = ReactDOM.createRoot(rootNode);
+    nodes.set(container, root);
+  }
+  root.render(element);
+};
+
+ReactDOM.unmountComponentAtNode = (container: Element | DocumentFragment) => {
+  const root = nodes.get(container);
+  if (root) {
+    root.unmount();
+    return true;
+  } else {
+    console.error("ReactDOM injection: can't unmount the given component");
+    return false;
+  }
+};

From 2f8327546c48684ebe557b2066d4ac4d1cd597cc Mon Sep 17 00:00:00 2001
From: Aman Mahajan <amahajan@freewheel.com>
Date: Fri, 11 Jun 2021 16:50:27 -0500
Subject: [PATCH 03/21] Fix variable

---
 .storybook/preview.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 77b356527b..47afd9bf30 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -58,7 +58,7 @@ ReactDOM.render = (element: React.ReactElement, container: Container) => {
   let root = nodes.get(container);
   if (!root) {
     //@ts-expect-error
-    root = ReactDOM.createRoot(rootNode);
+    root = ReactDOM.createRoot(container);
     nodes.set(container, root);
   }
   root.render(element);

From bc79f07bda760f5cec73f1d7652fd0c6bf26b347 Mon Sep 17 00:00:00 2001
From: Aman Mahajan <amahajan@freewheel.com>
Date: Tue, 15 Jun 2021 14:52:23 -0500
Subject: [PATCH 04/21] Use flushSync to prevent showing partially loaded grid

---
 src/hooks/useGridDimensions.ts | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/hooks/useGridDimensions.ts b/src/hooks/useGridDimensions.ts
index a7985cd2b2..3824234a40 100644
--- a/src/hooks/useGridDimensions.ts
+++ b/src/hooks/useGridDimensions.ts
@@ -1,4 +1,5 @@
 import { useRef, useState, useLayoutEffect } from 'react';
+import { flushSync } from 'react-dom';
 
 export function useGridDimensions(): [
   ref: React.RefObject<HTMLDivElement>,
@@ -20,11 +21,13 @@ export function useGridDimensions(): [
       // Get dimensions without scrollbars.
       // The dimensions given by the callback entries in Firefox do not substract the scrollbar sizes.
       const { clientWidth, clientHeight } = gridRef.current!;
-      // TODO: remove once fixed upstream
-      // we reduce width by 1px here to avoid layout issues in Chrome
-      // https://bugs.chromium.org/p/chromium/issues/detail?id=1206298
-      setGridWidth(clientWidth - (devicePixelRatio % 0.5 === 0 ? 0 : 1));
-      setGridHeight(clientHeight);
+      flushSync(() => {
+        // TODO: remove once fixed upstream
+        // we reduce width by 1px here to avoid layout issues in Chrome
+        // https://bugs.chromium.org/p/chromium/issues/detail?id=1206298
+        setGridWidth(clientWidth - (devicePixelRatio % 0.5 === 0 ? 0 : 1));
+        setGridHeight(clientHeight);
+      });
     });
 
     resizeObserver.observe(gridRef.current!);

From bbaa03ad071062ebc28fbd0e19f5855eeb865ca3 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Tue, 6 Jul 2021 13:54:44 +0100
Subject: [PATCH 05/21] Only flushSync on the initial render

---
 src/hooks/useGridDimensions.ts | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/hooks/useGridDimensions.ts b/src/hooks/useGridDimensions.ts
index 07c58996ca..f146bdf878 100644
--- a/src/hooks/useGridDimensions.ts
+++ b/src/hooks/useGridDimensions.ts
@@ -17,19 +17,19 @@ export function useGridDimensions(): [
     // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
     if (ResizeObserver == null) return;
 
-    const resizeObserver = new ResizeObserver(() => {
+    function saveDimensions() {
       // Get dimensions without scrollbars.
-      // The dimensions given by the callback entries in Firefox do not substract the scrollbar sizes.
+      // The dimensions given by the ResizeObserver callback entries in Firefox do not substract the scrollbar sizes.
       const { clientWidth, clientHeight } = gridRef.current!;
-      flushSync(() => {
-        // TODO: remove once fixed upstream
-        // we reduce width by 1px here to avoid layout issues in Chrome
-        // https://bugs.chromium.org/p/chromium/issues/detail?id=1206298
-        setGridWidth(clientWidth - (devicePixelRatio % 0.5 === 0 ? 0 : 1));
-        setGridHeight(clientHeight);
-      });
-    });
+      // TODO: remove once fixed upstream
+      // we reduce width by 1px here to avoid layout issues in Chrome
+      // https://bugs.chromium.org/p/chromium/issues/detail?id=1206298
+      setGridWidth(clientWidth - (devicePixelRatio % 0.5 === 0 ? 0 : 1));
+      setGridHeight(clientHeight);
+    }
 
+    flushSync(saveDimensions);
+    const resizeObserver = new ResizeObserver(saveDimensions);
     resizeObserver.observe(gridRef.current!);
 
     return () => {

From 64f35610c1e8cf1e5ba2df0026eb95946d61cf16 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Tue, 6 Jul 2021 14:27:34 +0100
Subject: [PATCH 06/21] Don't need flushSync

---
 src/hooks/useGridDimensions.ts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/hooks/useGridDimensions.ts b/src/hooks/useGridDimensions.ts
index f146bdf878..a01fe91964 100644
--- a/src/hooks/useGridDimensions.ts
+++ b/src/hooks/useGridDimensions.ts
@@ -1,5 +1,4 @@
 import { useRef, useState, useLayoutEffect } from 'react';
-import { flushSync } from 'react-dom';
 
 export function useGridDimensions(): [
   ref: React.RefObject<HTMLDivElement>,
@@ -28,7 +27,7 @@ export function useGridDimensions(): [
       setGridHeight(clientHeight);
     }
 
-    flushSync(saveDimensions);
+    saveDimensions();
     const resizeObserver = new ResizeObserver(saveDimensions);
     resizeObserver.observe(gridRef.current!);
 

From eeab342978522fcd1852fcf54dced3661caa6c88 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Mon, 13 Sep 2021 10:38:47 +0100
Subject: [PATCH 07/21] @testing-library/react@alpha

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 1bd0dcbc87..65a8ffa205 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
     "@storybook/manager-webpack5": "^6.3.8",
     "@storybook/react": "^6.3.8",
     "@testing-library/jest-dom": "^5.14.1",
-    "@testing-library/react": "^12.0.0",
+    "@testing-library/react": "alpha",
     "@testing-library/user-event": "^13.1.9",
     "@types/faker": "^5.5.6",
     "@types/hoist-non-react-statics": "^3.3.1",

From 17b232f9e71c3212121c9e00b115df4b5db0fced Mon Sep 17 00:00:00 2001
From: Aman Mahajan <amahajan@freewheel.com>
Date: Tue, 14 Dec 2021 14:40:34 -0600
Subject: [PATCH 08/21] Update react

---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 9913aeb080..21cb96001d 100644
--- a/package.json
+++ b/package.json
@@ -94,11 +94,11 @@
     "postcss-loader": "^6.1.1",
     "postcss-nested": "^5.0.6",
     "prettier": "2.4.1",
-    "react": "alpha",
+    "react": "^18.0.0-rc.0",
     "react-contextmenu": "^2.14.0",
     "react-dnd": "^14.0.2",
     "react-dnd-html5-backend": "^14.0.0",
-    "react-dom": "alpha",
+    "react-dom": "^18.0.0-rc.0",
     "react-refresh": "^0.10.0",
     "react-router-dom": "^5.3.0",
     "rollup": "^2.57.0",

From 17486565ba11e555dae4c9facd365434f9026c2c Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Tue, 29 Mar 2022 17:30:30 +0100
Subject: [PATCH 09/21] graduation from rc

---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 776eb5bdb1..4ec57e22b8 100644
--- a/package.json
+++ b/package.json
@@ -93,11 +93,11 @@
     "postcss-loader": "^6.2.1",
     "postcss-nested": "^5.0.6",
     "prettier": "2.5.1",
-    "react": "rc",
+    "react": "^18.0.0",
     "react-contextmenu": "^2.14.0",
     "react-dnd": "^15.1.0",
     "react-dnd-html5-backend": "^15.1.1",
-    "react-dom": "rc",
+    "react-dom": "^18.0.0",
     "react-refresh": "^0.11.0",
     "react-router-dom": "^6.2.1",
     "rollup": "^2.63.0",

From 6a9dec40084a9d71728f80bec5f3ccf567c0826a Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Tue, 29 Mar 2022 17:43:08 +0100
Subject: [PATCH 10/21] temporarily disable some website pages to fix the
 build, react-dnd has some incorret react imports

---
 website/root.tsx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/website/root.tsx b/website/root.tsx
index d55daac33a..e967c4103d 100644
--- a/website/root.tsx
+++ b/website/root.tsx
@@ -11,7 +11,7 @@ import CommonFeatures from './demos/CommonFeatures';
 import AllFeatures from './demos/AllFeatures';
 import CellNavigation from './demos/CellNavigation';
 import ColumnSpanning from './demos/ColumnSpanning';
-import ColumnsReordering from './demos/ColumnsReordering';
+// import ColumnsReordering from './demos/ColumnsReordering';
 import CustomizableComponents from './demos/CustomizableComponents';
 import ContextMenuDemo from './demos/ContextMenu';
 import Grouping from './demos/Grouping';
@@ -21,7 +21,7 @@ import MasterDetail from './demos/MasterDetail';
 import MillionCells from './demos/MillionCells';
 import NoRows from './demos/NoRows';
 import ResizableGrid from './demos/Resizable';
-import RowsReordering from './demos/RowsReordering';
+// import RowsReordering from './demos/RowsReordering';
 import ScrollToRow from './demos/ScrollToRow';
 import TreeView from './demos/TreeView';
 import VariableRowHeight from './demos/VariableRowHeight';
@@ -95,7 +95,7 @@ function Root() {
           <Route path="all-features" element={<AllFeatures direction={direction} />} />
           <Route path="cell-navigation" element={<CellNavigation direction={direction} />} />
           <Route path="column-spanning" element={<ColumnSpanning direction={direction} />} />
-          <Route path="columns-reordering" element={<ColumnsReordering direction={direction} />} />
+          {/* <Route path="columns-reordering" element={<ColumnsReordering direction={direction} />} /> */}
           <Route path="context-menu" element={<ContextMenuDemo direction={direction} />} />
           <Route
             path="customizable-components"
@@ -108,7 +108,7 @@ function Root() {
           <Route path="million-cells" element={<MillionCells direction={direction} />} />
           <Route path="no-rows" element={<NoRows direction={direction} />} />
           <Route path="resizable-grid" element={<ResizableGrid direction={direction} />} />
-          <Route path="rows-reordering" element={<RowsReordering direction={direction} />} />
+          {/* <Route path="rows-reordering" element={<RowsReordering direction={direction} />} /> */}
           <Route path="scroll-to-row" element={<ScrollToRow direction={direction} />} />
           <Route path="tree-view" element={<TreeView direction={direction} />} />
           <Route path="variable-row-height" element={<VariableRowHeight direction={direction} />} />

From 08064720b4f0034b16876e8b3767433193bf8fb7 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Tue, 29 Mar 2022 17:47:23 +0100
Subject: [PATCH 11/21] update react-refresh

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 3b8199252a..54e6087d79 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,7 @@
     "react-dnd": "^15.1.0",
     "react-dnd-html5-backend": "^15.1.1",
     "react-dom": "^18.0.0",
-    "react-refresh": "^0.11.0",
+    "react-refresh": "^0.12.0",
     "react-router-dom": "^6.2.1",
     "rollup": "^2.63.0",
     "rollup-plugin-postcss": "^4.0.2",

From dc8f410b92f81041b9bf65a10f321f142c8806a1 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 31 Mar 2022 13:34:08 +0100
Subject: [PATCH 12/21] @testing-library/react@13

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 54e6087d79..d168202250 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
     "@rollup/plugin-babel": "^5.3.0",
     "@rollup/plugin-node-resolve": "^13.1.3",
     "@testing-library/jest-dom": "^5.16.1",
-    "@testing-library/react": "alpha",
+    "@testing-library/react": "^13.0.0",
     "@testing-library/user-event": "^13.5.0",
     "@types/faker": "^5.5.9",
     "@types/hoist-non-react-statics": "^3.3.1",

From e62f201e2ad1a761cb7c5f4cd4efd11a77aa2c1e Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Mon, 4 Apr 2022 14:16:57 +0100
Subject: [PATCH 13/21] Update react-refresh-webpack-plugin

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 957d144bce..43520660fd 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,7 @@
     "@linaria/shaker": "^3.0.0-beta.17",
     "@linaria/webpack5-loader": "^3.0.0-beta.17",
     "@microsoft/api-extractor": "^7.19.4",
-    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
+    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
     "@rollup/plugin-babel": "^5.3.0",
     "@rollup/plugin-node-resolve": "^13.1.3",
     "@testing-library/jest-dom": "^5.16.1",

From 27ea8bca33146f941ab830ccdca997be8caf25e9 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Wed, 6 Apr 2022 13:05:22 +0100
Subject: [PATCH 14/21] react-dnd@16

---
 package.json     | 4 ++--
 website/root.tsx | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/package.json b/package.json
index 43520660fd..7207d9952a 100644
--- a/package.json
+++ b/package.json
@@ -93,8 +93,8 @@
     "prettier": "2.6.2",
     "react": "^18.0.0",
     "react-contextmenu": "^2.14.0",
-    "react-dnd": "^15.1.0",
-    "react-dnd-html5-backend": "^15.1.1",
+    "react-dnd": "^16.0.0",
+    "react-dnd-html5-backend": "^16.0.0",
     "react-dom": "^18.0.0",
     "react-refresh": "^0.12.0",
     "react-router-dom": "^6.2.1",
diff --git a/website/root.tsx b/website/root.tsx
index b8cdff90b0..e6dbb0a496 100644
--- a/website/root.tsx
+++ b/website/root.tsx
@@ -11,7 +11,7 @@ import CommonFeatures from './demos/CommonFeatures';
 import AllFeatures from './demos/AllFeatures';
 import CellNavigation from './demos/CellNavigation';
 import ColumnSpanning from './demos/ColumnSpanning';
-// import ColumnsReordering from './demos/ColumnsReordering';
+import ColumnsReordering from './demos/ColumnsReordering';
 import CustomizableComponents from './demos/CustomizableComponents';
 import ContextMenuDemo from './demos/ContextMenu';
 import Grouping from './demos/Grouping';
@@ -21,7 +21,7 @@ import MasterDetail from './demos/MasterDetail';
 import MillionCells from './demos/MillionCells';
 import NoRows from './demos/NoRows';
 import ResizableGrid from './demos/Resizable';
-// import RowsReordering from './demos/RowsReordering';
+import RowsReordering from './demos/RowsReordering';
 import ScrollToRow from './demos/ScrollToRow';
 import TreeView from './demos/TreeView';
 import VariableRowHeight from './demos/VariableRowHeight';
@@ -95,7 +95,7 @@ function Root() {
           <Route path="all-features" element={<AllFeatures direction={direction} />} />
           <Route path="cell-navigation" element={<CellNavigation direction={direction} />} />
           <Route path="column-spanning" element={<ColumnSpanning direction={direction} />} />
-          {/* <Route path="columns-reordering" element={<ColumnsReordering direction={direction} />} /> */}
+          <Route path="columns-reordering" element={<ColumnsReordering direction={direction} />} />
           <Route path="context-menu" element={<ContextMenuDemo direction={direction} />} />
           <Route
             path="customizable-components"
@@ -108,7 +108,7 @@ function Root() {
           <Route path="million-cells" element={<MillionCells direction={direction} />} />
           <Route path="no-rows" element={<NoRows direction={direction} />} />
           <Route path="resizable-grid" element={<ResizableGrid direction={direction} />} />
-          {/* <Route path="rows-reordering" element={<RowsReordering direction={direction} />} /> */}
+          <Route path="rows-reordering" element={<RowsReordering direction={direction} />} />
           <Route path="scroll-to-row" element={<ScrollToRow direction={direction} />} />
           <Route path="tree-view" element={<TreeView direction={direction} />} />
           <Route path="variable-row-height" element={<VariableRowHeight direction={direction} />} />

From f4eb37bcddecf77e6e04ba5b92a27df3ea08fae9 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Wed, 6 Apr 2022 23:12:40 +0100
Subject: [PATCH 15/21] use `react-dom/client`

---
 website/root.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/website/root.tsx b/website/root.tsx
index e6dbb0a496..884ce188b1 100644
--- a/website/root.tsx
+++ b/website/root.tsx
@@ -1,6 +1,5 @@
 import { StrictMode, useState } from 'react';
-// @ts-expect-error
-import { createRoot } from 'react-dom';
+import { createRoot } from 'react-dom/client';
 import { css } from '@linaria/core';
 import { HashRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
 

From a70d620c796840dcc3ff5fea2f290a4cf8363ba7 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Wed, 6 Apr 2022 23:16:13 +0100
Subject: [PATCH 16/21] fix type issue

---
 website/root.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/root.tsx b/website/root.tsx
index 884ce188b1..94fffd151f 100644
--- a/website/root.tsx
+++ b/website/root.tsx
@@ -118,7 +118,7 @@ function Root() {
   );
 }
 
-createRoot(document.getElementById('root')).render(
+createRoot(document.getElementById('root')!).render(
   <StrictMode>
     <Root />
   </StrictMode>

From 028abe5ed0de5fcf3fba11abf4b21e75caeafa75 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 7 Apr 2022 00:15:15 +0100
Subject: [PATCH 17/21] fix a couple test warnings

---
 src/hooks/useRovingCellRef.ts | 39 +++++++++++++++--------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/src/hooks/useRovingCellRef.ts b/src/hooks/useRovingCellRef.ts
index 00458f4667..acdaf93217 100644
--- a/src/hooks/useRovingCellRef.ts
+++ b/src/hooks/useRovingCellRef.ts
@@ -1,38 +1,33 @@
-import { useRef, useState } from 'react';
-import { useLayoutEffect } from './useLayoutEffect';
+import { useCallback, useState } from 'react';
 
 // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_roving_tabindex
 export function useRovingCellRef(isSelected: boolean) {
-  const ref = useRef<HTMLDivElement>(null);
   // https://www.w3.org/TR/wai-aria-practices-1.1/#gridNav_focus
-  const isChildFocused = useRef(false);
-  const [, forceRender] = useState<unknown>({});
+  const [isChildFocused, setIsChildFocused] = useState(false);
 
-  useLayoutEffect(() => {
-    if (!isSelected) {
-      isChildFocused.current = false;
-      return;
-    }
+  if (isChildFocused && !isSelected) {
+    setIsChildFocused(false);
+  }
 
-    if (isChildFocused.current) {
-      // When the child is focused, we need to rerender
-      // the cell again so tabIndex is updated to -1
-      forceRender({});
-      return;
-    }
-    ref.current?.focus({ preventScroll: true });
-  }, [isSelected]);
+  const refCallback = useCallback(
+    (cell: HTMLDivElement | null) => {
+      if (cell === null || !isSelected || cell.contains(document.activeElement)) return;
+
+      cell.focus({ preventScroll: true });
+    },
+    [isSelected]
+  );
 
   function onFocus(event: React.FocusEvent<HTMLDivElement>) {
-    if (event.target !== ref.current) {
-      isChildFocused.current = true;
+    if (event.target !== event.currentTarget) {
+      setIsChildFocused(true);
     }
   }
 
-  const isFocused = isSelected && !isChildFocused.current;
+  const isFocused = isSelected && !isChildFocused;
 
   return {
-    ref,
+    ref: refCallback,
     tabIndex: isFocused ? 0 : -1,
     onFocus
   };

From 457b375bd14c5d0dd808ad4f713befe20767b6f3 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 7 Apr 2022 00:15:57 +0100
Subject: [PATCH 18/21] name it ref

---
 src/hooks/useRovingCellRef.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/hooks/useRovingCellRef.ts b/src/hooks/useRovingCellRef.ts
index acdaf93217..e997f628c2 100644
--- a/src/hooks/useRovingCellRef.ts
+++ b/src/hooks/useRovingCellRef.ts
@@ -9,7 +9,7 @@ export function useRovingCellRef(isSelected: boolean) {
     setIsChildFocused(false);
   }
 
-  const refCallback = useCallback(
+  const ref = useCallback(
     (cell: HTMLDivElement | null) => {
       if (cell === null || !isSelected || cell.contains(document.activeElement)) return;
 
@@ -27,7 +27,7 @@ export function useRovingCellRef(isSelected: boolean) {
   const isFocused = isSelected && !isChildFocused;
 
   return {
-    ref: refCallback,
+    ref,
     tabIndex: isFocused ? 0 : -1,
     onFocus
   };

From 6b5a7f8e5dd0d6437e4fd89a84681ef192144d02 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 7 Apr 2022 00:28:23 +0100
Subject: [PATCH 19/21] fix last test warning

---
 test/components.test.tsx | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/test/components.test.tsx b/test/components.test.tsx
index 90716824ff..a08661c1dd 100644
--- a/test/components.test.tsx
+++ b/test/components.test.tsx
@@ -1,8 +1,8 @@
-import { StrictMode } from 'react';
+import { forwardRef, StrictMode } from 'react';
 import { render, screen } from '@testing-library/react';
 
 import DataGrid, { DataGridDefaultComponentsProvider, SelectColumn } from '../src';
-import type { Column, DataGridProps } from '../src';
+import type { Column, DataGridProps, CheckboxFormatterProps } from '../src';
 import { getRows, setup } from './utils';
 
 interface Row {
@@ -25,13 +25,16 @@ function GlobalNoRowsFallback() {
   return <div>Global no rows fallback</div>;
 }
 
-function Checkbox() {
-  return <div>Local checkbox</div>;
-}
+const Checkbox = forwardRef<HTMLDivElement, CheckboxFormatterProps>(function Checkbox(props, ref) {
+  return <div ref={ref}>Local checkbox</div>;
+});
 
-function GlobalCheckbox() {
-  return <div>Global checkbox</div>;
-}
+const GlobalCheckbox = forwardRef<HTMLDivElement, CheckboxFormatterProps>(function GlobalCheckbox(
+  props,
+  ref
+) {
+  return <div ref={ref}>Global checkbox</div>;
+});
 
 function setupProvider<R, SR, K extends React.Key>(props: DataGridProps<R, SR, K>) {
   return render(

From ba4230f846777a67a884eddda9aa4959ed8683a5 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 7 Apr 2022 00:32:38 +0100
Subject: [PATCH 20/21] update linaria

---
 package.json | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/package.json b/package.json
index 7207d9952a..9d8fa8e8d2 100644
--- a/package.json
+++ b/package.json
@@ -51,11 +51,11 @@
     "@babel/preset-typescript": "^7.16.7",
     "@babel/runtime": "^7.16.7",
     "@faker-js/faker": "^6.1.1",
-    "@linaria/babel-preset": "^3.0.0-beta.17",
-    "@linaria/core": "^3.0.0-beta.15",
-    "@linaria/rollup": "^3.0.0-beta.17",
-    "@linaria/shaker": "^3.0.0-beta.17",
-    "@linaria/webpack5-loader": "^3.0.0-beta.17",
+    "@linaria/babel-preset": "^3.0.0-beta.18",
+    "@linaria/core": "^3.0.0-beta.18",
+    "@linaria/rollup": "^3.0.0-beta.18",
+    "@linaria/shaker": "^3.0.0-beta.18",
+    "@linaria/webpack5-loader": "^3.0.0-beta.18",
     "@microsoft/api-extractor": "^7.19.4",
     "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
     "@rollup/plugin-babel": "^5.3.0",

From 87362b4421324b639646788e061f102a42e5fdc1 Mon Sep 17 00:00:00 2001
From: Nicolas Stepien <stepien.nicolas@gmail.com>
Date: Thu, 7 Apr 2022 15:54:53 +0100
Subject: [PATCH 21/21] mention React 18 in the README

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c68c0ed796..701eebe372 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
 
 ## Features
 
-- [React 16.14+ & 17.0+](package.json) support
+- [React 16.14+, 17.0+, and 18.0+](package.json) support
 - [Evergreen browsers and server-side rendering](browserslist) support
 - Tree-shaking support and only [one npm dependency](package.json) to keep your bundles slim
 - Great performance thanks to virtualization: columns and rows outside the viewport are not rendered