diff --git a/src/DataSheet.js b/src/DataSheet.js index 4036229..1f489dc 100644 --- a/src/DataSheet.js +++ b/src/DataSheet.js @@ -270,9 +270,11 @@ export default class DataSheet extends PureComponent { handleKeyboardCellMovement(e, commit = false) { const { start, editing } = this.getState(); - const { data } = this.props; + const { data, customNavigate } = this.props; const isEditing = editing && !isEmpty(editing); const currentCell = data[start.i] && data[start.i][start.j]; + let defaultOffset = { i: 1, j: 0 }; + let jumpRow = false; if (isEditing && !commit) { return false; @@ -287,17 +289,34 @@ export default class DataSheet extends PureComponent { } if (keyCode === TAB_KEY) { - this.handleNavigate(e, { i: 0, j: e.shiftKey ? -1 : 1 }, true); + defaultOffset = { i: 0, j: e.shiftKey ? -1 : 1 }; + jumpRow = true; } else if (keyCode === RIGHT_KEY) { - this.handleNavigate(e, { i: 0, j: 1 }); + defaultOffset = { i: 0, j: 1 }; } else if (keyCode === LEFT_KEY) { - this.handleNavigate(e, { i: 0, j: -1 }); + defaultOffset = { i: 0, j: -1 }; } else if (keyCode === UP_KEY) { - this.handleNavigate(e, { i: -1, j: 0 }); + defaultOffset = { i: -1, j: 0 }; } else if (keyCode === DOWN_KEY) { - this.handleNavigate(e, { i: 1, j: 0 }); + defaultOffset = { i: 1, j: 0 }; } else if (commit && keyCode === ENTER_KEY) { - this.handleNavigate(e, { i: e.shiftKey ? -1 : 1, j: 0 }); + defaultOffset = { i: e.shiftKey ? -1 : 1, j: 0 }; + } + if ( + [TAB_KEY, RIGHT_KEY, LEFT_KEY, UP_KEY, DOWN_KEY, ENTER_KEY].includes( + keyCode, + ) + ) { + const [newOffset, newJumpRow] = customNavigate + ? customNavigate(currentCell, keyCode, e) || [defaultOffset, jumpRow] + : [defaultOffset, jumpRow]; + if (keyCode === ENTER_KEY) { + if (commit) { + this.handleNavigate(e, newOffset, newJumpRow); + } + } else { + this.handleNavigate(e, newOffset, newJumpRow); + } } } @@ -745,6 +764,7 @@ DataSheet.propTypes = { parsePaste: PropTypes.func, attributesRenderer: PropTypes.func, keyFn: PropTypes.func, + customNavigate: PropTypes.func, handleCopy: PropTypes.func, }; diff --git a/types/react-datasheet.d.ts b/types/react-datasheet.d.ts index 0c12617..e65ff21 100644 --- a/types/react-datasheet.d.ts +++ b/types/react-datasheet.d.ts @@ -79,6 +79,8 @@ declare namespace ReactDataSheet { keyFn?: (row: number) => string | number; /** Optional: Function that can decide whether navigating to the indicated cell is possible. */ isCellNavigable?: (cell: T, row: number, col: number, jumpNext: boolean) => boolean; + + customNavigate?: (cell: T, keyCode: number, e: object) => T[]; } /** A function to process the raw clipboard data. It should return an array of arrays of strings. This is useful for when the clipboard may have data with irregular field or line delimiters. If not set, rows will be split with line breaks and cells with tabs. To wire it up pass your function to the parsePaste property of the ReactDataSheet component. */