From a902d20a7413016a662e1f7b3f7a5241213ce354 Mon Sep 17 00:00:00 2001
From: Steve 'Cutter' Blades <no.junk@cutterscrossing.com>
Date: Fri, 1 Jul 2022 07:20:24 -0500
Subject: [PATCH] fix: replace findDOMNode with refs

#2193
---
 src/BackgroundCells.js  | 12 ++++++------
 src/DateContentRow.js   | 39 +++++++++++++++++++--------------------
 src/DayColumn.js        | 13 +++++++------
 src/DayColumnWrapper.js |  8 +++++---
 src/Month.js            | 16 +++++++++-------
 src/TimeGrid.js         |  8 ++------
 6 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/src/BackgroundCells.js b/src/BackgroundCells.js
index eed1ea7ce2..8a6ecd043f 100644
--- a/src/BackgroundCells.js
+++ b/src/BackgroundCells.js
@@ -1,6 +1,5 @@
+import React, { createRef } from 'react'
 import PropTypes from 'prop-types'
-import React from 'react'
-import { findDOMNode } from 'react-dom'
 import clsx from 'clsx'
 
 import { notify } from './utils/helpers'
@@ -14,6 +13,7 @@ class BackgroundCells extends React.Component {
     this.state = {
       selecting: false,
     }
+    this.containerRef = createRef()
   }
 
   componentDidMount() {
@@ -44,7 +44,7 @@ class BackgroundCells extends React.Component {
     let current = getNow()
 
     return (
-      <div className="rbc-row-bg">
+      <div className="rbc-row-bg" ref={this.containerRef}>
         {range.map((date, index) => {
           let selected = selecting && index >= startIdx && index <= endIdx
           const { className, style } = getters.dayProp(date)
@@ -71,13 +71,13 @@ class BackgroundCells extends React.Component {
   }
 
   _selectable() {
-    let node = findDOMNode(this)
+    let node = this.containerRef.current
     let selector = (this._selector = new Selection(this.props.container, {
       longPressThreshold: this.props.longPressThreshold,
     }))
 
     let selectorClicksHandler = (point, actionType) => {
-      if (!isEvent(findDOMNode(this), point)) {
+      if (!isEvent(node, point)) {
         let rowBox = getBoundsForNode(node)
         let { range, rtl } = this.props
 
@@ -128,7 +128,7 @@ class BackgroundCells extends React.Component {
     selector.on('beforeSelect', (box) => {
       if (this.props.selectable !== 'ignoreEvents') return
 
-      return !isEvent(findDOMNode(this), box)
+      return !isEvent(this.containerRef.current, box)
     })
 
     selector.on('click', (point) => selectorClicksHandler(point, 'click'))
diff --git a/src/DateContentRow.js b/src/DateContentRow.js
index dfee9d4703..0342dd7dd8 100644
--- a/src/DateContentRow.js
+++ b/src/DateContentRow.js
@@ -1,9 +1,8 @@
+import React, { createRef } from 'react'
 import clsx from 'clsx'
 import getHeight from 'dom-helpers/height'
 import qsa from 'dom-helpers/querySelectorAll'
 import PropTypes from 'prop-types'
-import React from 'react'
-import { findDOMNode } from 'react-dom'
 
 import BackgroundCells from './BackgroundCells'
 import EventRow from './EventRow'
@@ -16,6 +15,10 @@ class DateContentRow extends React.Component {
   constructor(...args) {
     super(...args)
 
+    this.containerRef = createRef()
+    this.headingRowRef = createRef()
+    this.eventRowRef = createRef()
+
     this.slotMetrics = DateSlotMetrics.getSlotMetrics()
   }
 
@@ -28,7 +31,7 @@ class DateContentRow extends React.Component {
   handleShowMore = (slot, target) => {
     const { range, onShowMore } = this.props
     let metrics = this.slotMetrics(this.props)
-    let row = qsa(findDOMNode(this), '.rbc-row-bg')[0]
+    let row = qsa(this.containerRef.current, '.rbc-row-bg')[0]
 
     let cell
     if (row) cell = row.children[slot - 1]
@@ -37,23 +40,19 @@ class DateContentRow extends React.Component {
     onShowMore(events, range[slot - 1], cell, slot, target)
   }
 
-  createHeadingRef = (r) => {
-    this.headingRow = r
-  }
-
-  createEventRef = (r) => {
-    this.eventRow = r
-  }
-
   getContainer = () => {
     const { container } = this.props
-    return container ? container() : findDOMNode(this)
+    return container ? container() : this.containerRef.current
   }
 
   getRowLimit() {
-    let eventHeight = getHeight(this.eventRow)
-    let headingHeight = this.headingRow ? getHeight(this.headingRow) : 0
-    let eventSpace = getHeight(findDOMNode(this)) - headingHeight
+    /* Guessing this only gets called on the dummyRow */
+    const eventHeight = getHeight(this.eventRowRef.current)
+    const headingHeight =
+      this.headingRowRef && this.headingRowRef.current
+        ? getHeight(this.headingRowRef.current)
+        : 0
+    const eventSpace = getHeight(this.containerRef.current) - headingHeight
 
     return Math.max(Math.floor(eventSpace / eventHeight), 1)
   }
@@ -74,7 +73,7 @@ class DateContentRow extends React.Component {
   renderDummy = () => {
     let { className, range, renderHeader, showAllEvents } = this.props
     return (
-      <div className={className}>
+      <div className={className} ref={this.containerRef}>
         <div
           className={clsx(
             'rbc-row-content',
@@ -82,11 +81,11 @@ class DateContentRow extends React.Component {
           )}
         >
           {renderHeader && (
-            <div className="rbc-row" ref={this.createHeadingRef}>
+            <div className="rbc-row" ref={this.headingRowRef}>
               {range.map(this.renderHeadingCell)}
             </div>
           )}
-          <div className="rbc-row" ref={this.createEventRef}>
+          <div className="rbc-row" ref={this.eventRowRef}>
             <div className="rbc-row-segment">
               <div className="rbc-event">
                 <div className="rbc-event-content">&nbsp;</div>
@@ -152,7 +151,7 @@ class DateContentRow extends React.Component {
     }
 
     return (
-      <div className={className} role="rowgroup">
+      <div className={className} role="rowgroup" ref={this.containerRef}>
         <BackgroundCells
           localizer={localizer}
           date={date}
@@ -178,7 +177,7 @@ class DateContentRow extends React.Component {
           role="row"
         >
           {renderHeader && (
-            <div className="rbc-row " ref={this.createHeadingRef}>
+            <div className="rbc-row " ref={this.headingRowRef}>
               {range.map(this.renderHeadingCell)}
             </div>
           )}
diff --git a/src/DayColumn.js b/src/DayColumn.js
index 910a6c7f62..f02dde7af2 100644
--- a/src/DayColumn.js
+++ b/src/DayColumn.js
@@ -1,6 +1,5 @@
+import React, { createRef } from 'react'
 import PropTypes from 'prop-types'
-import React from 'react'
-import { findDOMNode } from 'react-dom'
 import clsx from 'clsx'
 
 import Selection, { getBoundsForNode, isEvent } from './Selection'
@@ -23,6 +22,7 @@ class DayColumn extends React.Component {
     super(...args)
 
     this.slotMetrics = TimeSlotUtils.getSlotMetrics(this.props)
+    this.containerRef = createRef()
   }
 
   componentDidMount() {
@@ -129,6 +129,7 @@ class DayColumn extends React.Component {
 
     return (
       <DayColumnWrapperComponent
+        ref={this.containerRef}
         date={date}
         style={style}
         className={clsx(
@@ -249,9 +250,9 @@ class DayColumn extends React.Component {
   }
 
   _selectable = () => {
-    let node = findDOMNode(this)
+    let node = this.containerRef.current
     const { longPressThreshold, localizer } = this.props
-    let selector = (this._selector = new Selection(() => findDOMNode(this), {
+    let selector = (this._selector = new Selection(() => node, {
       longPressThreshold: longPressThreshold,
     }))
 
@@ -311,7 +312,7 @@ class DayColumn extends React.Component {
     }
 
     let selectorClicksHandler = (box, actionType) => {
-      if (!isEvent(findDOMNode(this), box)) {
+      if (!isEvent(this.containerRef.current, box)) {
         const { startDate, endDate } = selectionState(box)
         this._selectSlot({
           startDate,
@@ -329,7 +330,7 @@ class DayColumn extends React.Component {
     selector.on('beforeSelect', (box) => {
       if (this.props.selectable !== 'ignoreEvents') return
 
-      return !isEvent(findDOMNode(this), box)
+      return !isEvent(this.containerRef.current, box)
     })
 
     selector.on('click', (box) => selectorClicksHandler(box, 'click'))
diff --git a/src/DayColumnWrapper.js b/src/DayColumnWrapper.js
index 2d8ca9f189..120b8931d1 100644
--- a/src/DayColumnWrapper.js
+++ b/src/DayColumnWrapper.js
@@ -1,11 +1,13 @@
 import React from 'react'
 
-const DayColumnWrapper = ({ children, className, style }) => {
+const DayColumnWrapper = ({ children, className, style, innerRef }) => {
   return (
-    <div className={className} style={style}>
+    <div className={className} style={style} ref={innerRef}>
       {children}
     </div>
   )
 }
 
-export default DayColumnWrapper
+export default React.forwardRef((props, ref) => (
+  <DayColumnWrapper {...props} innerRef={ref} />
+))
diff --git a/src/Month.js b/src/Month.js
index 38ee63732e..9407618335 100644
--- a/src/Month.js
+++ b/src/Month.js
@@ -1,6 +1,5 @@
+import React, { createRef } from 'react'
 import PropTypes from 'prop-types'
-import React from 'react'
-import { findDOMNode } from 'react-dom'
 import clsx from 'clsx'
 
 import chunk from 'lodash/chunk'
@@ -25,13 +24,15 @@ class MonthView extends React.Component {
   constructor(...args) {
     super(...args)
 
-    this._bgRows = []
-    this._pendingSelection = []
-    this.slotRowRef = React.createRef()
     this.state = {
       rowLimit: 5,
       needLimitMeasure: true,
     }
+    this.containerRef = createRef()
+    this.slotRowRef = createRef()
+
+    this._bgRows = []
+    this._pendingSelection = []
   }
 
   UNSAFE_componentWillReceiveProps({ date }) {
@@ -69,7 +70,7 @@ class MonthView extends React.Component {
   }
 
   getContainer = () => {
-    return findDOMNode(this)
+    return this.containerRef.current
   }
 
   render() {
@@ -84,6 +85,7 @@ class MonthView extends React.Component {
         className={clsx('rbc-month-view', className)}
         role="table"
         aria-label="Month View"
+        ref={this.containerRef}
       >
         <div className="rbc-row rbc-month-header" role="row">
           {this.renderHeaders(weeks[0])}
@@ -284,7 +286,7 @@ class MonthView extends React.Component {
     this.clearSelection()
 
     if (popup) {
-      let position = getPosition(cell, findDOMNode(this))
+      let position = getPosition(cell, this.containerRef.current)
 
       this.setState({
         overlay: { date, events, position, target },
diff --git a/src/TimeGrid.js b/src/TimeGrid.js
index 96e3a5d484..122c1d8134 100644
--- a/src/TimeGrid.js
+++ b/src/TimeGrid.js
@@ -1,8 +1,7 @@
+import React, { Component, createRef } from 'react'
 import PropTypes from 'prop-types'
 import clsx from 'clsx'
 import * as animationFrame from 'dom-helpers/animationFrame'
-import React, { Component } from 'react'
-import { findDOMNode } from 'react-dom'
 import memoize from 'memoize-one'
 
 import DayColumn from './DayColumn'
@@ -24,6 +23,7 @@ export default class TimeGrid extends Component {
     this.scrollRef = React.createRef()
     this.contentRef = React.createRef()
     this._scrollRatio = null
+    this.gutterRef = createRef()
   }
 
   UNSAFE_componentWillMount() {
@@ -83,10 +83,6 @@ export default class TimeGrid extends Component {
     }
   }
 
-  gutterRef = (ref) => {
-    this.gutter = ref && findDOMNode(ref)
-  }
-
   handleSelectAlldayEvent = (...args) => {
     //cancel any pending selections so only the event click goes through.
     this.clearSelection()