1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- import type {TraceTree, TraceTreeNode} from './traceTree';
- export interface RovingTabIndexState {
- index: number | null;
- items: number | null;
- node: TraceTreeNode<TraceTree.NodeValue> | null;
- }
- export type RovingTabIndexAction =
- | {
- index: number | null;
- items: number;
- node: TraceTreeNode<TraceTree.NodeValue> | null;
- type: 'initialize';
- }
- | {index: number; node: TraceTreeNode<TraceTree.NodeValue>; type: 'set index'}
- | {type: 'clear index'};
- export type RovingTabIndexUserActions = 'next' | 'previous' | 'last' | 'first';
- export function rovingTabIndexReducer(
- state: RovingTabIndexState,
- action: RovingTabIndexAction
- ): RovingTabIndexState {
- switch (action.type) {
- case 'initialize': {
- return {index: action.index, items: action.items, node: action.node};
- }
- case 'set index':
- return {...state, node: action.node, index: action.index};
- case 'clear index':
- return {...state, index: null, node: null};
- default:
- throw new Error('Invalid action');
- }
- }
- export function getRovingIndexActionFromEvent(
- event: React.KeyboardEvent
- ): RovingTabIndexUserActions | null {
- // @TODO it would be trivial to extend this and support
- // things like j/k vim-like navigation or add modifiers
- // so that users could jump to parent or sibling nodes.
- // I would need to put some thought into this, but shift+cmd+up
- // seems like a good candidate for jumping to parent node and
- // shift+cmd+down for jumping to the next sibling node.
- switch (event.key) {
- case 'ArrowDown':
- if (event.shiftKey) {
- return 'last';
- }
- return 'next';
- case 'ArrowUp':
- if (event.shiftKey) {
- return 'first';
- }
- return 'previous';
- case 'Home':
- return 'first';
- case 'End':
- return 'last';
- case 'Tab':
- if (event.shiftKey) {
- return 'previous';
- }
- return 'next';
- default:
- return null;
- }
- }
|