Skip to content

Commit

Permalink
Add support for HOME and END keys
Browse files Browse the repository at this point in the history
  • Loading branch information
talldan committed Aug 9, 2019
1 parent 78b8619 commit f874a33
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 36 deletions.
26 changes: 21 additions & 5 deletions packages/block-library/src/table/navigable-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
placeCaretAtHorizontalEdge,
} from '@wordpress/dom';
import { useRef } from '@wordpress/element';
import { UP, DOWN, LEFT, RIGHT, isKeyboardModifierEvent } from '@wordpress/keycodes';
import { UP, DOWN, LEFT, RIGHT, HOME, END, isKeyboardModifierEvent } from '@wordpress/keycodes';

/**
* Internal dependencies
Expand All @@ -22,9 +22,11 @@ import {
getLastCellInColumn,
getFirstCellInRow,
getLastCellInRow,
getFirstCellInTable,
getLastCellInTable,
} from './state';

function getNextCellLocation( tableState, selectedCell, { isPrimary, isUp, isDown, isLeft, isRight } ) {
function getNextCellLocation( tableState, selectedCell, { isPrimary, isUp, isDown, isLeft, isRight, isHome, isEnd } ) {
if ( isUp ) {
if ( isPrimary ) {
return getFirstCellInColumn( tableState, selectedCell );
Expand Down Expand Up @@ -53,6 +55,18 @@ function getNextCellLocation( tableState, selectedCell, { isPrimary, isUp, isDow

return getCellToRight( tableState, selectedCell );
}
if ( isHome ) {
if ( isPrimary ) {
return getFirstCellInTable( tableState );
}
return getFirstCellInRow( selectedCell );
}
if ( isEnd ) {
if ( isPrimary ) {
return getLastCellInTable( tableState );
}
return getLastCellInRow( tableState, selectedCell );
}
}

function getCellContentEditableElement( tableElement, { sectionName, rowIndex, columnIndex } ) {
Expand Down Expand Up @@ -87,7 +101,9 @@ export default function NavigableTable( { children, className, tableState, selec
const isDown = keyCode === DOWN;
const isLeft = keyCode === LEFT;
const isRight = keyCode === RIGHT;
const isHorizontal = isLeft || isRight;
const isHome = keyCode === HOME;
const isEnd = keyCode === END;
const isHorizontal = isLeft || isRight || isHome || isEnd;
const isVertical = isUp || isDown;
const isNav = isHorizontal || isVertical;

Expand All @@ -103,7 +119,7 @@ export default function NavigableTable( { children, className, tableState, selec
}

const isAtEdge = isVertical ? isVerticalEdge : isHorizontalEdge;
const isReverse = isUp || isLeft;
const isReverse = isUp || isLeft || isHome;
const isCaretAtEdgeOfField = isAtEdge( target, isReverse );

if ( ! isCaretAtEdgeOfField ) {
Expand All @@ -114,7 +130,7 @@ export default function NavigableTable( { children, className, tableState, selec
event.preventDefault();

const isPrimary = isKeyboardModifierEvent.primary( event );
const nextCellLocation = getNextCellLocation( tableState, selectedCell, { isPrimary, isUp, isDown, isLeft, isRight } );
const nextCellLocation = getNextCellLocation( tableState, selectedCell, { isPrimary, isUp, isDown, isLeft, isRight, isHome, isEnd } );

if ( ! nextCellLocation ) {
return;
Expand Down
105 changes: 74 additions & 31 deletions packages/block-library/src/table/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,60 @@ export function createTable( {
};
}

export function getRow( state, { sectionName, rowIndex } ) {
return get( state, [ sectionName, rowIndex ] );
}

export function getCell( state, { sectionName, rowIndex, columnIndex } ) {
return get( state, [ sectionName, rowIndex, 'cells', columnIndex ] );
}

/**
* Returns the first row in the table.
*
* @param {Object} state Current table state.
*
* @return {Object} The first table row.
*/
export function getFirstRow( state ) {
export function getFirstRowLocation( state ) {
let firstSectionName;

if ( ! isEmptyTableSection( state.head ) ) {
return state.head[ 0 ];
}
if ( ! isEmptyTableSection( state.body ) ) {
return state.body[ 0 ];
firstSectionName = 'head';
} else if ( ! isEmptyTableSection( state.body ) ) {
firstSectionName = 'body';
} else if ( ! isEmptyTableSection( state.foot ) ) {
firstSectionName = 'foot';
}

return {
sectionName: firstSectionName,
rowIndex: 0,
};
}

/**
* Returns the first row in the table.
*
* @param {Object} state Current table state.
*
* @return {Object} The first table row.
*/
export function getLastRowLocation( state ) {
let lastSectionName;

if ( ! isEmptyTableSection( state.foot ) ) {
return state.foot[ 0 ];
lastSectionName = 'foot';
} else if ( ! isEmptyTableSection( state.body ) ) {
lastSectionName = 'body';
} else if ( ! isEmptyTableSection( state.head ) ) {
lastSectionName = 'head';
}

return {
sectionName: lastSectionName,
rowIndex: state[ lastSectionName ].length - 1,
};
}

/**
Expand Down Expand Up @@ -153,7 +190,7 @@ export function insertRow( state, {
rowIndex,
columnCount,
} ) {
const firstRow = getFirstRow( state );
const firstRow = getRow( state, getFirstRowLocation( state ) );
const cellCount = columnCount === undefined ? get( firstRow, [ 'cells', 'length' ] ) : columnCount;

// Bail early if the function cannot determine how many cells to add.
Expand Down Expand Up @@ -447,37 +484,23 @@ export function getCellToLeft( cellLocation ) {
} : undefined;
}

export function getFirstCellInColumn( state, cellLocation ) {
let firstSectionName;
if ( ! isEmptyTableSection( state.head ) ) {
firstSectionName = 'head';
} else if ( ! isEmptyTableSection( state.body ) ) {
firstSectionName = 'body';
} else if ( ! isEmptyTableSection( state.foot ) ) {
firstSectionName = 'foot';
}
export function getFirstCellInColumn( state, { columnIndex } ) {
const { sectionName, rowIndex } = getFirstRowLocation( state );

return {
...cellLocation,
sectionName: firstSectionName,
rowIndex: 0,
sectionName,
rowIndex,
columnIndex,
};
}

export function getLastCellInColumn( state, cellLocation ) {
let lastSectionName;
if ( ! isEmptyTableSection( state.foot ) ) {
lastSectionName = 'foot';
} else if ( ! isEmptyTableSection( state.body ) ) {
lastSectionName = 'body';
} else if ( ! isEmptyTableSection( state.head ) ) {
lastSectionName = 'head';
}
export function getLastCellInColumn( state, { columnIndex } ) {
const { sectionName, rowIndex } = getLastRowLocation( state );

return {
...cellLocation,
sectionName: lastSectionName,
rowIndex: state[ lastSectionName ].length - 1,
sectionName,
rowIndex,
columnIndex,
};
}

Expand All @@ -501,3 +524,23 @@ export function getLastCellInRow( state, cellLocation ) {
columnIndex: columnCount - 1,
} : undefined;
}

export function getFirstCellInTable( state ) {
const { sectionName, rowIndex } = getFirstRowLocation( state );

return {
sectionName,
rowIndex,
columnIndex: 0,
};
}

export function getLastCellInTable( state ) {
const { sectionName, rowIndex } = getLastRowLocation( state );

return {
sectionName,
rowIndex,
columnIndex: get( state, [ sectionName, rowIndex, 'cells', 'length' ] ) - 1,
};
}
Loading

0 comments on commit f874a33

Please sign in to comment.