react-konva-grid
Advanced tools
Comparing version 2.7.4 to 2.7.5
@@ -75,2 +75,9 @@ import { ItemSizer, InstanceInterface, AreaProps, CellInterface, CellMetaData, SelectionArea } from "./Grid"; | ||
export declare const prepareClipboardData: (rows: string[][]) => [string, string]; | ||
/** | ||
* Cycles active cell within selecton bounds | ||
* @param activeCellBounds | ||
* @param selectionBounds | ||
* @param direction | ||
*/ | ||
export declare const findNextCellWithinBounds: (activeCellBounds: AreaProps, selectionBounds: AreaProps, direction?: string) => CellInterface | null; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.prepareClipboardData = exports.selectionFromActiveCell = exports.requestTimeout = exports.cancelTimeout = exports.getOffsetForRowAndAlignment = exports.getOffsetForColumnAndAlignment = exports.getOffsetForIndexAndAlignment = exports.rafThrottle = exports.debounce = exports.throttle = exports.cellIndentifier = exports.getEstimatedTotalWidth = exports.getEstimatedTotalHeight = exports.getItemMetadata = exports.getColumnWidth = exports.getRowHeight = exports.getColumnOffset = exports.getRowOffset = exports.itemKey = exports.getBoundedCells = exports.getColumnStopIndexForStartIndex = exports.getColumnStartIndexForOffset = exports.getRowStopIndexForStartIndex = exports.getRowStartIndexForOffset = void 0; | ||
exports.findNextCellWithinBounds = exports.prepareClipboardData = exports.selectionFromActiveCell = exports.requestTimeout = exports.cancelTimeout = exports.getOffsetForRowAndAlignment = exports.getOffsetForColumnAndAlignment = exports.getOffsetForIndexAndAlignment = exports.rafThrottle = exports.debounce = exports.throttle = exports.cellIndentifier = exports.getEstimatedTotalWidth = exports.getEstimatedTotalHeight = exports.getItemMetadata = exports.getColumnWidth = exports.getRowHeight = exports.getColumnOffset = exports.getRowOffset = exports.itemKey = exports.getBoundedCells = exports.getColumnStopIndexForStartIndex = exports.getColumnStartIndexForOffset = exports.getRowStopIndexForStartIndex = exports.getRowStartIndexForOffset = void 0; | ||
const types_1 = require("./types"); | ||
var Align; | ||
@@ -450,2 +451,49 @@ (function (Align) { | ||
}; | ||
/** | ||
* Cycles active cell within selecton bounds | ||
* @param activeCellBounds | ||
* @param selectionBounds | ||
* @param direction | ||
*/ | ||
exports.findNextCellWithinBounds = (activeCellBounds, selectionBounds, direction = types_1.Movement.forwards) => { | ||
let rowIndex, columnIndex; | ||
let nextActiveCell = null; | ||
if (direction === types_1.Movement.forwards) { | ||
rowIndex = activeCellBounds.top; | ||
columnIndex = activeCellBounds.left + 1; | ||
if (columnIndex > selectionBounds.right) { | ||
rowIndex = rowIndex + 1; | ||
columnIndex = selectionBounds.left; | ||
if (rowIndex > selectionBounds.bottom) { | ||
rowIndex = selectionBounds.top; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
if (direction === types_1.Movement.backwards) { | ||
rowIndex = activeCellBounds.bottom; | ||
columnIndex = activeCellBounds.left - 1; | ||
if (columnIndex < selectionBounds.left) { | ||
rowIndex = rowIndex - 1; | ||
columnIndex = selectionBounds.right; | ||
if (rowIndex < selectionBounds.top) { | ||
rowIndex = selectionBounds.bottom; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
if (direction === types_1.Movement.downwards) { | ||
rowIndex = activeCellBounds.bottom + 1; | ||
columnIndex = activeCellBounds.left; | ||
if (rowIndex > selectionBounds.bottom) { | ||
columnIndex = activeCellBounds.left + 1; | ||
rowIndex = selectionBounds.top; | ||
if (columnIndex > selectionBounds.right) { | ||
columnIndex = selectionBounds.left; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
return nextActiveCell; | ||
}; | ||
//# sourceMappingURL=helpers.js.map |
@@ -20,2 +20,3 @@ import React from "react"; | ||
onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void; | ||
onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void; | ||
} | ||
@@ -26,3 +27,3 @@ export interface EditorProps extends CellInterface { | ||
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void; | ||
onEscape?: (e: React.KeyboardEvent<HTMLInputElement>) => void; | ||
onCancel?: (e: React.KeyboardEvent<HTMLInputElement>) => void; | ||
scrollPosition: ScrollCoords; | ||
@@ -29,0 +30,0 @@ position: CellPosition; |
@@ -35,2 +35,3 @@ "use strict"; | ||
const types_1 = require("./../types"); | ||
const helpers_1 = require("../helpers"); | ||
/** | ||
@@ -41,5 +42,4 @@ * Default cell editor | ||
const DefaultEditor = (props) => { | ||
const { rowIndex, columnIndex, onChange, onSubmit, onBlur, onEscape, scrollPosition, position } = props, rest = __rest(props, ["rowIndex", "columnIndex", "onChange", "onSubmit", "onBlur", "onEscape", "scrollPosition", "position"]); | ||
const { rowIndex, columnIndex, onChange, onSubmit, onBlur, onCancel, scrollPosition, position } = props, rest = __rest(props, ["rowIndex", "columnIndex", "onChange", "onSubmit", "onBlur", "onCancel", "scrollPosition", "position"]); | ||
const inputRef = react_1.useRef(null); | ||
const escapePressedRef = react_1.useRef(false); | ||
react_1.useEffect(() => { | ||
@@ -64,3 +64,2 @@ if (!inputRef.current) | ||
}, onChange: (e) => onChange(e.target.value), onKeyDown: (e) => { | ||
escapePressedRef.current = false; | ||
// Enter key | ||
@@ -71,4 +70,3 @@ if (e.which === types_1.KeyCodes.Enter) { | ||
if (e.which === types_1.KeyCodes.Escape) { | ||
escapePressedRef.current = true; | ||
onEscape && onEscape(e); | ||
onCancel && onCancel(e); | ||
} | ||
@@ -79,10 +77,3 @@ if (e.which === types_1.KeyCodes.Tab) { | ||
} | ||
}, onBlur: (e) => { | ||
/* If the user has pressed Escape key, do not call onBlur, | ||
Since we are any hiding the input | ||
*/ | ||
if (escapePressedRef.current) | ||
return; | ||
onBlur && onBlur(e); | ||
} }, rest))); | ||
}, onBlur: onBlur }, rest))); | ||
}; | ||
@@ -104,2 +95,3 @@ const getDefaultEditor = (cell) => DefaultEditor; | ||
const currentActiveCellRef = react_1.useRef(null); | ||
const initialActiveCell = react_1.useRef(); | ||
const [scrollPosition, setScrollPosition] = react_1.useState({ | ||
@@ -114,2 +106,15 @@ scrollLeft: 0, | ||
}; | ||
react_1.useEffect(() => { | ||
if (!currentActiveCellRef.current) | ||
return; | ||
/** | ||
* Active cell has changed, but submit has not been clicked - currentActiveCellRef | ||
*/ | ||
onSubmit && onSubmit(value, currentActiveCellRef.current); | ||
}, [activeCell]); | ||
/** | ||
* Make a cell editable | ||
* @param coords | ||
* @param initialValue | ||
*/ | ||
const makeEditable = (coords, initialValue) => { | ||
@@ -169,2 +174,3 @@ if (!gridRef.current) | ||
const handleSubmit = react_1.useCallback((e) => { | ||
var _a, _b; | ||
if (!activeCell) | ||
@@ -175,3 +181,3 @@ return; | ||
const nextIndex = shiftKey ? -1 : 1; | ||
const nextActiveCell = isTabKeyPressed | ||
let nextActiveCell = isTabKeyPressed | ||
? { | ||
@@ -182,5 +188,22 @@ rowIndex: activeCell.rowIndex, | ||
: { | ||
rowIndex: activeCell.rowIndex + 1, | ||
columnIndex: activeCell.columnIndex, | ||
rowIndex: (((_a = initialActiveCell.current) === null || _a === void 0 ? void 0 : _a.rowIndex) || activeCell.rowIndex) + 1, | ||
columnIndex: ((_b = initialActiveCell.current) === null || _b === void 0 ? void 0 : _b.columnIndex) || activeCell.columnIndex, | ||
}; | ||
/* Set previous key */ | ||
if (isTabKeyPressed && !initialActiveCell.current) { | ||
initialActiveCell.current = activeCell; | ||
} | ||
if (e.which === types_1.KeyCodes.Enter) { | ||
/* Move to the next row + cell */ | ||
initialActiveCell.current = undefined; | ||
/* If user has selected some cells and active cell is within this selection */ | ||
if (selections.length && activeCell && gridRef) { | ||
const { bounds } = selections[0]; | ||
const activeCellBounds = gridRef.current.getCellBounds(activeCell); | ||
const nextCell = helpers_1.findNextCellWithinBounds(activeCellBounds, bounds, types_1.Movement.downwards); | ||
if (nextCell) | ||
nextActiveCell = nextCell; | ||
} | ||
} | ||
/* Save the new value */ | ||
onSubmit && onSubmit(value, activeCell, nextActiveCell); | ||
@@ -191,3 +214,6 @@ /* Show editor */ | ||
gridRef.current.focus(); | ||
}, [value, activeCell]); | ||
}, [value, selections, activeCell]); | ||
const handleMouseDown = react_1.useCallback(() => { | ||
initialActiveCell.current = undefined; | ||
}, []); | ||
const handleChange = react_1.useCallback((value) => { | ||
@@ -209,18 +235,5 @@ if (!activeCell) | ||
}, []); | ||
/* Update value onBlur */ | ||
const handleBlur = react_1.useCallback((e) => { | ||
if (!currentActiveCellRef.current) | ||
return; | ||
/** | ||
* Event callstack | ||
* mouseDown => sets the activeCell | ||
* onBlur => reads the new activeCell, which is wrong. | ||
* Thats the reason by storing the active cell in Ref internally | ||
*/ | ||
onSubmit && onSubmit(value, currentActiveCellRef.current); | ||
hideEditor(); | ||
}, [value]); | ||
/* Editor */ | ||
const Editor = react_1.useMemo(() => getEditor(activeCell), [activeCell]); | ||
const editorComponent = isEditorShown ? (react_1.default.createElement(Editor, { value: value, onChange: handleChange, onSubmit: handleSubmit, onBlur: handleBlur, onEscape: handleHide, position: position, scrollPosition: scrollPosition })) : null; | ||
const editorComponent = isEditorShown ? (react_1.default.createElement(Editor, { value: value, onChange: handleChange, onSubmit: handleSubmit, onBlur: hideEditor, onCancel: handleHide, position: position, scrollPosition: scrollPosition })) : null; | ||
return { | ||
@@ -231,2 +244,3 @@ editorComponent, | ||
onKeyDown: handleKeyDown, | ||
onMouseDown: handleMouseDown, | ||
}; | ||
@@ -233,0 +247,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const helpers_1 = require("./../helpers"); | ||
const types_1 = require("./../types"); | ||
const EMPTY_SELECTION = []; | ||
/** | ||
@@ -24,3 +26,3 @@ * useSelection hook to enable selection in datagrid | ||
setActiveCell({ rowIndex: bounds.top, columnIndex: bounds.left }); | ||
setSelections([]); | ||
setSelections(EMPTY_SELECTION); | ||
}; | ||
@@ -259,8 +261,20 @@ /* selection object from start, end */ | ||
case types_1.KeyCodes.Tab: | ||
/* TODO Cycle through the selections if selections.length > 0 */ | ||
if (isShiftKey) { | ||
keyNavigate(types_1.Direction.Left); | ||
/* Cycle through the selections if selections.length > 0 */ | ||
if (selections.length && activeCell && gridRef) { | ||
const { bounds } = selections[0]; | ||
const activeCellBounds = gridRef.current.getCellBounds(activeCell); | ||
const direction = isShiftKey | ||
? types_1.Movement.backwards | ||
: types_1.Movement.forwards; | ||
const nextCell = helpers_1.findNextCellWithinBounds(activeCellBounds, bounds, direction); | ||
if (nextCell) | ||
setActiveCell(nextCell); | ||
} | ||
else { | ||
keyNavigate(types_1.Direction.Right); | ||
if (isShiftKey) { | ||
keyNavigate(types_1.Direction.Left); | ||
} | ||
else { | ||
keyNavigate(types_1.Direction.Right); | ||
} | ||
} | ||
@@ -267,0 +281,0 @@ e.preventDefault(); |
@@ -23,1 +23,6 @@ export declare enum KeyCodes { | ||
} | ||
export declare enum Movement { | ||
forwards = "forwards", | ||
backwards = "backwards", | ||
downwards = "downwards" | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Direction = exports.KeyCodes = void 0; | ||
exports.Movement = exports.Direction = exports.KeyCodes = void 0; | ||
var KeyCodes; | ||
@@ -28,2 +28,8 @@ (function (KeyCodes) { | ||
})(Direction = exports.Direction || (exports.Direction = {})); | ||
var Movement; | ||
(function (Movement) { | ||
Movement["forwards"] = "forwards"; | ||
Movement["backwards"] = "backwards"; | ||
Movement["downwards"] = "downwards"; | ||
})(Movement = exports.Movement || (exports.Movement = {})); | ||
//# sourceMappingURL=types.js.map |
{ | ||
"name": "react-konva-grid", | ||
"description": "Declarative React Canvas Grid primitive for Data table, Pivot table, Excel Worksheets", | ||
"version": "2.7.4", | ||
"version": "2.7.5", | ||
"main": "dist/index.js", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -10,2 +10,3 @@ // Utilities extracted from https://github.com/bvaughn/react-window | ||
} from "./Grid"; | ||
import { Movement } from "./types"; | ||
@@ -669,1 +670,55 @@ enum Align { | ||
}; | ||
/** | ||
* Cycles active cell within selecton bounds | ||
* @param activeCellBounds | ||
* @param selectionBounds | ||
* @param direction | ||
*/ | ||
export const findNextCellWithinBounds = ( | ||
activeCellBounds: AreaProps, | ||
selectionBounds: AreaProps, | ||
direction: string = Movement.forwards | ||
): CellInterface | null => { | ||
let rowIndex, columnIndex; | ||
let nextActiveCell: CellInterface | null = null; | ||
if (direction === Movement.forwards) { | ||
rowIndex = activeCellBounds.top; | ||
columnIndex = activeCellBounds.left + 1; | ||
if (columnIndex > selectionBounds.right) { | ||
rowIndex = rowIndex + 1; | ||
columnIndex = selectionBounds.left; | ||
if (rowIndex > selectionBounds.bottom) { | ||
rowIndex = selectionBounds.top; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
if (direction === Movement.backwards) { | ||
rowIndex = activeCellBounds.bottom; | ||
columnIndex = activeCellBounds.left - 1; | ||
if (columnIndex < selectionBounds.left) { | ||
rowIndex = rowIndex - 1; | ||
columnIndex = selectionBounds.right; | ||
if (rowIndex < selectionBounds.top) { | ||
rowIndex = selectionBounds.bottom; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
if (direction === Movement.downwards) { | ||
rowIndex = activeCellBounds.bottom + 1; | ||
columnIndex = activeCellBounds.left; | ||
if (rowIndex > selectionBounds.bottom) { | ||
columnIndex = activeCellBounds.left + 1; | ||
rowIndex = selectionBounds.top; | ||
if (columnIndex > selectionBounds.right) { | ||
columnIndex = selectionBounds.left; | ||
} | ||
} | ||
nextActiveCell = { rowIndex, columnIndex }; | ||
} | ||
return nextActiveCell; | ||
}; |
import React, { useState, useCallback, useRef } from "react"; | ||
import { SelectionArea, AreaProps, CellInterface, GridRef } from "./../Grid"; | ||
import { KeyCodes, Direction } from "./../types"; | ||
import { SelectionArea, CellInterface, GridRef } from "./../Grid"; | ||
import { findNextCellWithinBounds } from "./../helpers"; | ||
import { KeyCodes, Direction, Movement } from "./../types"; | ||
@@ -25,2 +26,4 @@ export interface UseSelectionOptions { | ||
const EMPTY_SELECTION: SelectionArea[] = []; | ||
/** | ||
@@ -55,3 +58,3 @@ * useSelection hook to enable selection in datagrid | ||
setActiveCell({ rowIndex: bounds.top, columnIndex: bounds.left }); | ||
setSelections([]); | ||
setSelections(EMPTY_SELECTION); | ||
}; | ||
@@ -334,7 +337,21 @@ | ||
case KeyCodes.Tab: | ||
/* TODO Cycle through the selections if selections.length > 0 */ | ||
if (isShiftKey) { | ||
keyNavigate(Direction.Left); | ||
/* Cycle through the selections if selections.length > 0 */ | ||
if (selections.length && activeCell && gridRef) { | ||
const { bounds } = selections[0]; | ||
const activeCellBounds = gridRef.current.getCellBounds(activeCell); | ||
const direction = isShiftKey | ||
? Movement.backwards | ||
: Movement.forwards; | ||
const nextCell = findNextCellWithinBounds( | ||
activeCellBounds, | ||
bounds, | ||
direction | ||
); | ||
if (nextCell) setActiveCell(nextCell); | ||
} else { | ||
keyNavigate(Direction.Right); | ||
if (isShiftKey) { | ||
keyNavigate(Direction.Left); | ||
} else { | ||
keyNavigate(Direction.Right); | ||
} | ||
} | ||
@@ -341,0 +358,0 @@ e.preventDefault(); |
@@ -24,1 +24,7 @@ export enum KeyCodes { | ||
} | ||
export enum Movement { | ||
forwards = "forwards", | ||
backwards = "backwards", | ||
downwards = "downwards", | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14813261
21934