11import React from 'react' ;
22
3- import PropTypes from 'prop-types' ;
4-
53import { FOCUSED_CLASS_NAME } from '../../constants' ;
64import { DashKitContext } from '../../context' ;
5+ import type { ConfigItem , ConfigLayout } from '../../shared' ;
6+ import type { PluginRef , ReactGridLayoutProps } from '../../typings' ;
77import { cn } from '../../utils/cn' ;
88import Item from '../Item/Item' ;
99import OverlayControls from '../OverlayControls/OverlayControls' ;
@@ -13,28 +13,28 @@ import './GridItem.scss';
1313const b = cn ( 'dashkit-grid-item' ) ;
1414
1515class WindowFocusObserver {
16- constructor ( ) {
17- this . subscribers = 0 ;
18- this . isFocused = ! document . hidden ;
16+ subscribers = 0 ;
17+ isFocused = ! document . hidden ;
1918
19+ constructor ( ) {
2020 window . addEventListener ( 'blur' , this . blurHandler , true ) ;
2121 window . addEventListener ( 'focus' , this . focusHandler , true ) ;
2222 }
2323
24- blurHandler = ( e ) => {
24+ blurHandler = ( e : FocusEvent ) => {
2525 if ( e . target === window ) {
2626 this . isFocused = false ;
2727 }
2828 } ;
2929
30- focusHandler = ( e ) => {
30+ focusHandler = ( e : FocusEvent ) => {
3131 if ( e . target === window ) {
3232 this . isFocused = true ;
3333 }
3434 } ;
3535
3636 // Method to get state after all blur\focus events in document are triggered
37- async getFocusedState ( ) {
37+ async getFocusedState ( ) : Promise < boolean > {
3838 return new Promise ( ( resolve ) => {
3939 requestAnimationFrame ( ( ) => {
4040 resolve ( this . isFocused ) ;
@@ -45,43 +45,53 @@ class WindowFocusObserver {
4545
4646const windowFocusObserver = new WindowFocusObserver ( ) ;
4747
48- class GridItem extends React . PureComponent {
49- static propTypes = {
50- adjustWidgetLayout : PropTypes . func . isRequired ,
51- gridLayout : PropTypes . object ,
52- id : PropTypes . string ,
53- item : PropTypes . object ,
54- isDragging : PropTypes . bool ,
55- isDraggedOut : PropTypes . bool ,
56- layout : PropTypes . array ,
57-
58- forwardedRef : PropTypes . any ,
59- forwardedPluginRef : PropTypes . any ,
60- isPlaceholder : PropTypes . bool ,
61-
62- onItemMountChange : PropTypes . func ,
63- onItemRender : PropTypes . func ,
64-
65- // from react-grid-layout:
66- children : PropTypes . node ,
67- className : PropTypes . string ,
68- style : PropTypes . object ,
69- noOverlay : PropTypes . bool ,
70- focusable : PropTypes . bool ,
71- withCustomHandle : PropTypes . bool ,
72- onMouseDown : PropTypes . func ,
73- onMouseUp : PropTypes . func ,
74- onTouchEnd : PropTypes . func ,
75- onTouchStart : PropTypes . func ,
76- onItemFocus : PropTypes . func ,
77- onItemBlur : PropTypes . func ,
78- } ;
79-
48+ type GridItemProps = {
49+ adjustWidgetLayout : ( data : {
50+ widgetId : string ;
51+ needSetDefault ?: boolean ;
52+ adjustedWidgetLayout ?: ConfigLayout ;
53+ } ) => void ;
54+ gridLayout ?: ReactGridLayoutProps ;
55+ id ?: string ;
56+ item : ConfigItem ;
57+ isDragging ?: boolean ;
58+ isDraggedOut ?: boolean ;
59+ layout ?: ConfigLayout [ ] ;
60+
61+ forwardedRef ?: React . Ref < HTMLDivElement > ;
62+ forwardedPluginRef ?: ( pluginRef : PluginRef ) => void ;
63+ isPlaceholder ?: boolean ;
64+
65+ onItemMountChange ?: ( item : ConfigItem , meta : { isAsync : boolean ; isMounted : boolean } ) => void ;
66+ onItemRender ?: ( item : ConfigItem ) => void ;
67+
68+ // from react-grid-layout:
69+ children ?: React . ReactNode ;
70+ className ?: string ;
71+ style ?: React . CSSProperties ;
72+ noOverlay ?: boolean ;
73+ focusable ?: boolean ;
74+ withCustomHandle ?: boolean ;
75+ onMouseDown ?: ( e : React . MouseEvent < HTMLDivElement > ) => void ;
76+ onMouseUp ?: ( e : React . MouseEvent < HTMLDivElement > ) => void ;
77+ onTouchEnd ?: ( e : React . TouchEvent < HTMLDivElement > ) => void ;
78+ onTouchStart ?: ( e : React . TouchEvent < HTMLDivElement > ) => void ;
79+ onItemFocus ?: ( item : ConfigItem ) => void ;
80+ onItemBlur ?: ( item : ConfigItem ) => void ;
81+ } ;
82+
83+ type GridItemState = {
84+ isFocused : boolean ;
85+ } ;
86+
87+ class GridItem extends React . PureComponent < GridItemProps , GridItemState > {
8088 static contextType = DashKitContext ;
89+ context ! : React . ContextType < typeof DashKitContext > ;
8190
8291 _isAsyncItem = false ;
92+ controller : AbortController | null = null ;
8393
84- state = {
94+ state : GridItemState = {
8595 isFocused : false ,
8696 } ;
8797
@@ -105,7 +115,7 @@ class GridItem extends React.PureComponent {
105115 < div className = { b ( 'overlay' ) } />
106116 < OverlayControls
107117 configItem = { item }
108- onItemClick = { focusable ? this . onOverlayItemClick : null }
118+ onItemClick = { focusable ? this . onOverlayItemClick : undefined }
109119 />
110120 </ React . Fragment >
111121 ) ;
@@ -114,17 +124,13 @@ class GridItem extends React.PureComponent {
114124 onOverlayItemClick = ( ) => {
115125 // Creating button element to trigger focus out
116126 const focusDummy = document . createElement ( 'button' ) ;
117- const styles = {
127+ Object . assign ( focusDummy . style , {
118128 width : '0' ,
119129 height : '0' ,
120130 opacity : '0' ,
121131 position : 'fixed' ,
122132 top : '0' ,
123133 left : '0' ,
124- } ;
125-
126- Object . entries ( styles ) . forEach ( ( [ key , value ] ) => {
127- focusDummy . style [ key ] = value ;
128134 } ) ;
129135
130136 // requestAnimationFrame to make call after alert() or confirm()
@@ -187,14 +193,16 @@ class GridItem extends React.PureComponent {
187193 const { editMode} = this . context ;
188194 const { isFocused} = this . state ;
189195
190- const width = Number . parseInt ( style . width , 10 ) ;
191- const height = Number . parseInt ( style . height , 10 ) ;
192- const transform = style . transform ;
196+ const width =
197+ style ?. width === undefined ? undefined : Number . parseInt ( String ( style . width ) , 10 ) ;
198+ const height =
199+ style ?. height === undefined ? undefined : Number . parseInt ( String ( style . height ) , 10 ) ;
200+ const transform = style ?. transform ;
193201 const preparedClassName =
194202 ( editMode
195203 ? className
196204 : className
197- . replace ( 'react-resizable' , '' )
205+ ? .replace ( 'react-resizable' , '' )
198206 . replace ( 'react-draggable' , '' )
199207 . replace ( FOCUSED_CLASS_NAME , '' ) ) +
200208 ( isFocused ? ` ${ FOCUSED_CLASS_NAME } ` : '' ) ;
@@ -254,9 +262,11 @@ class GridItem extends React.PureComponent {
254262 }
255263}
256264
257- const GridItemForwarderRef = React . forwardRef ( ( props , ref ) => {
258- return < GridItem { ...props } forwardedRef = { ref } /> ;
259- } ) ;
265+ const GridItemForwarderRef = React . forwardRef < HTMLDivElement , Omit < GridItemProps , 'forwardedRef' > > (
266+ ( props , ref ) => {
267+ return < GridItem { ...props } forwardedRef = { ref } /> ;
268+ } ,
269+ ) ;
260270
261271GridItemForwarderRef . displayName = 'forwardRef(GridItem)' ;
262272
0 commit comments