@@ -36,6 +36,7 @@ import {
3636 getCellRangeValue ,
3737 getCellValue ,
3838 shouldHandleClipboardEvent ,
39+ isFocusedWithin ,
3940} from "./util" ;
4041import reducer , { INITIAL_STATE , hasKeyDownHandler } from "./reducer" ;
4142import context from "./context" ;
@@ -105,6 +106,8 @@ export type Props<CellType extends Types.CellBase> = {
105106 onSelect ?: ( selected : Point . Point [ ] ) => void ;
106107 /** Callback called when Spreadsheet's active cell changes. */
107108 onActivate ?: ( active : Point . Point ) => void ;
109+ /** Callback called when the Spreadsheet loses focus */
110+ onBlur ?: ( ) => void ;
108111 onCellCommit ?: (
109112 prevCell : null | CellType ,
110113 nextCell : null | CellType ,
@@ -137,6 +140,7 @@ const Spreadsheet = <CellType extends Types.CellBase>(
137140 onModeChange = ( ) => { } ,
138141 onSelect = ( ) => { } ,
139142 onActivate = ( ) => { } ,
143+ onBlur = ( ) => { } ,
140144 onCellCommit = ( ) => { } ,
141145 } = props ;
142146 const initialState = React . useMemo (
@@ -195,6 +199,7 @@ const Spreadsheet = <CellType extends Types.CellBase>(
195199 ( data ) => dispatch ( Actions . setData ( data ) ) ,
196200 [ dispatch ]
197201 ) ;
202+ const blur = React . useCallback ( ( ) => dispatch ( Actions . blur ( ) ) , [ dispatch ] ) ;
198203
199204 React . useEffect ( ( ) => {
200205 const prevState = prevStateRef . current ;
@@ -222,15 +227,24 @@ const Spreadsheet = <CellType extends Types.CellBase>(
222227 onSelect ( points ) ;
223228 }
224229
225- if ( state . active !== prevState . active && state . active ) {
226- onActivate ( state . active ) ;
230+ if ( state . active !== prevState . active ) {
231+ if ( state . active ) {
232+ onActivate ( state . active ) ;
233+ } else {
234+ const root = rootRef . current ;
235+ if ( root && isFocusedWithin ( root ) && document . activeElement ) {
236+ ( document . activeElement as HTMLElement ) . blur ( ) ;
237+ }
238+ onBlur ( ) ;
239+ }
227240 }
228241
229242 prevStateRef . current = state ;
230243 } , [
231244 props . data ,
232245 state ,
233246 onActivate ,
247+ onBlur ,
234248 onCellCommit ,
235249 onChange ,
236250 onModeChange ,
@@ -325,6 +339,18 @@ const Spreadsheet = <CellType extends Types.CellBase>(
325339 [ state , onDragStart , handleMouseUp ]
326340 ) ;
327341
342+ const handleBlur = React . useCallback (
343+ ( event ) => {
344+ const { currentTarget } = event ;
345+ setTimeout ( ( ) => {
346+ if ( ! isFocusedWithin ( currentTarget ) ) {
347+ blur ( ) ;
348+ }
349+ } , 0 ) ;
350+ } ,
351+ [ blur ]
352+ ) ;
353+
328354 const formulaParser = React . useMemo ( ( ) => {
329355 return props . formulaParser || new FormulaParser ( ) ;
330356 } , [ props . formulaParser ] ) ;
@@ -460,6 +486,7 @@ const Spreadsheet = <CellType extends Types.CellBase>(
460486 onKeyPress = { onKeyPress }
461487 onKeyDown = { handleKeyDown }
462488 onMouseMove = { handleMouseMove }
489+ onBlur = { handleBlur }
463490 >
464491 { tableNode }
465492 { activeCellNode }
@@ -472,6 +499,7 @@ const Spreadsheet = <CellType extends Types.CellBase>(
472499 onKeyPress ,
473500 handleKeyDown ,
474501 handleMouseMove ,
502+ handleBlur ,
475503 tableNode ,
476504 activeCellNode ,
477505 ]
0 commit comments