Skip to content

Commit e453652

Browse files
authored
Merge pull request #170 from iddan/fix/blur
Fix Blur
2 parents 7103cd7 + 79a64a5 commit e453652

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

src/Spreadsheet.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
getCellRangeValue,
3737
getCellValue,
3838
shouldHandleClipboardEvent,
39+
isFocusedWithin,
3940
} from "./util";
4041
import reducer, { INITIAL_STATE, hasKeyDownHandler } from "./reducer";
4142
import 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
]

src/reducer.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ describe("reducer", () => {
101101
["view", EDIT_STATE, Actions.view(), INITIAL_STATE],
102102
[
103103
"blur",
104-
{ ...INITIAL_STATE, active: Point.ORIGIN },
104+
{
105+
...INITIAL_STATE,
106+
active: Point.ORIGIN,
107+
selected: PointRange.create(Point.ORIGIN, Point.ORIGIN),
108+
},
105109
Actions.blur(),
106110
INITIAL_STATE,
107111
],

src/reducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ function clear(state: Types.StoreState): Types.StoreState | void {
267267
}
268268

269269
function blur(state: Types.StoreState): Types.StoreState {
270-
return { ...state, active: null };
270+
return { ...state, active: null, selected: null };
271271
}
272272

273273
function view(state: Types.StoreState): Types.StoreState {

0 commit comments

Comments
 (0)