11/* eslint react/no-did-update-set-state: "off" */
2- import React , { CSSProperties , PureComponent , ReactNode } from 'react' ;
2+ import React , {
3+ CSSProperties ,
4+ PureComponent ,
5+ ReactNode ,
6+ RefObject ,
7+ } from 'react' ;
38import classNames from 'classnames' ;
49import memoize from 'memoize-one' ;
510import clamp from 'lodash.clamp' ;
@@ -69,6 +74,9 @@ type LegacyCanvasRenderingContext2D = CanvasRenderingContext2D & {
6974} ;
7075
7176export type GridProps = typeof Grid . defaultProps & {
77+ // Children to render in the grid
78+ children ?: ReactNode ;
79+
7280 // Options to set on the canvas
7381 canvasOptions ?: CanvasRenderingContext2DSettings ;
7482
@@ -295,6 +303,12 @@ class Grid extends PureComponent<GridProps, GridState> {
295303
296304 canvasContext : CanvasRenderingContext2D | null ;
297305
306+ // The wrapper element for the canvas, used for sizing
307+ canvasWrapper : RefObject < HTMLDivElement > ;
308+
309+ // Listen for resizing of the element and update the canvas appropriately
310+ resizeObserver : ResizeObserver ;
311+
298312 // We draw the canvas on the next animation frame, keep track of the next one
299313 animationFrame : number | null ;
300314
@@ -351,6 +365,8 @@ class Grid extends PureComponent<GridProps, GridState> {
351365
352366 this . canvas = null ;
353367 this . canvasContext = null ;
368+ this . canvasWrapper = React . createRef ( ) ;
369+ this . resizeObserver = new window . ResizeObserver ( this . handleResize ) ;
354370 this . animationFrame = null ;
355371
356372 this . prevMetrics = null ;
@@ -457,7 +473,9 @@ class Grid extends PureComponent<GridProps, GridState> {
457473 this . canvas ?. addEventListener ( 'wheel' , this . handleWheel , {
458474 passive : false ,
459475 } ) ;
460- window . addEventListener ( 'resize' , this . handleResize ) ;
476+ if ( this . canvasWrapper . current != null ) {
477+ this . resizeObserver . observe ( this . canvasWrapper . current ) ;
478+ }
461479
462480 this . updateCanvas ( ) ;
463481
@@ -561,7 +579,7 @@ class Grid extends PureComponent<GridProps, GridState> {
561579 this . handleMouseUp as unknown as EventListenerOrEventListenerObject ,
562580 true
563581 ) ;
564- window . removeEventListener ( 'resize' , this . handleResize ) ;
582+ this . resizeObserver . disconnect ( ) ;
565583
566584 this . stopDragTimer ( ) ;
567585 }
@@ -801,17 +819,17 @@ class Grid extends PureComponent<GridProps, GridState> {
801819 }
802820
803821 private updateCanvasScale ( ) : void {
804- const { canvas, canvasContext } = this ;
822+ const { canvas, canvasContext, canvasWrapper } = this ;
805823 if ( ! canvas ) throw new Error ( 'canvas not set' ) ;
806824 if ( ! canvasContext ) throw new Error ( 'canvasContext not set' ) ;
807- if ( ! canvas . parentElement ) throw new Error ( 'Canvas has no parent element ' ) ;
825+ if ( ! canvasWrapper . current ) throw new Error ( 'canvasWrapper not set ' ) ;
808826
809827 const scale = Grid . getScale ( canvasContext ) ;
810828 // the parent wrapper has 100% width/height, and is used for determining size
811829 // we don't want to stretch the canvas to 100%, to avoid fractional pixels.
812830 // A wrapper element must be used for sizing, and canvas size must be
813831 // set manually to a floored value in css and a scaled value in width/height
814- const rect = canvas . parentElement . getBoundingClientRect ( ) ;
832+ const rect = canvasWrapper . current . getBoundingClientRect ( ) ;
815833 const width = Math . floor ( rect . width ) ;
816834 const height = Math . floor ( rect . height ) ;
817835 canvas . style . width = `${ width } px` ;
@@ -2177,10 +2195,11 @@ class Grid extends PureComponent<GridProps, GridState> {
21772195 }
21782196
21792197 render ( ) : ReactNode {
2198+ const { children } = this . props ;
21802199 const { cursor } = this . state ;
21812200
21822201 return (
2183- < >
2202+ < div className = "grid-wrapper" ref = { this . canvasWrapper } >
21842203 < canvas
21852204 className = { classNames ( 'grid-canvas' , Grid . getCursorClassName ( cursor ) ) }
21862205 ref = { canvas => {
@@ -2198,7 +2217,8 @@ class Grid extends PureComponent<GridProps, GridState> {
21982217 Your browser does not support HTML canvas. Update your browser?
21992218 </ canvas >
22002219 { this . renderInputField ( ) }
2201- </ >
2220+ { children }
2221+ </ div >
22022222 ) ;
22032223 }
22042224}
0 commit comments