# Infinite Table Keyboard Navigation API

Canonical page: https://infinite-table.com/docs/reference/keyboard-navigation-api/

Available starting with version `6.1.1`.

See the [Keyboard Navigation](https://infinite-table.com/docs/learn/keyboard-navigation/navigating-cells.md) page for more details.

```tsx title="Configuring the keyboard navigation to be 'cell'"
<InfiniteTable keyboardNavigation="cell" />

// can be "cell" (default), "row" or false
```

You can retrieve the keyboard navigation api by reading it from the `api.keyboardNavigationApi` property.

```tsx {4}

const onReady = ({api}: {api:InfiniteTableApi<DATA_TYPE>}) => {
  // do something with it
  api.keyboardNavigationApi.gotoCell({direction: 'top'})
}

<InfiniteTable<DATA_TYPE>
  columns={[...]}
  onReady={onReady}
/>
```

See the [Infinite Table API page](https://infinite-table.com/docs/reference/api/index.md) for the main API.
See the [Infinite Table Cell Selection API page](https://infinite-table.com/docs/reference/cell-selection-api/index.md) for the row selection API.
See the [Infinite Table Row Selection API page](https://infinite-table.com/docs/reference/row-selection-api/index.md) for the row selection API.
See the [Infinite Table Column API page](https://infinite-table.com/docs/reference/column-api/index.md) for the column API.

### setKeyboardNavigation (`(keyboardNavigation: 'cell'|'row'|false) => void`)

> Sets the keyboard navigation mode. See [`keyboardNavigation`](https://infinite-table.com/docs/reference/infinite-table-props.md#keyboardNavigation)

The sole argument is of the same type as the [`keyboardNavigation`](https://infinite-table.com/docs/reference/infinite-table-props.md#keyboardNavigation)

See the [Keyboard Navigation](https://infinite-table.com/docs/learn/keyboard-navigation/navigating-cells.md) page for more details.

If you are using controlled [`activeCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeCellIndex) or [`activeRowIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeRowIndex), make sure you update the values by using the [`onActiveCellIndexChange`](https://infinite-table.com/docs/reference/infinite-table-props.md#onActiveCellIndexChange) and [`onActiveRowIndexChange`](https://infinite-table.com/docs/reference/infinite-table-props.md#onActiveRowIndexChange) callbacks respectively.

### setActiveCellIndex (`(activeCellIndex: [number, number]) => void`)

> Sets the value for [`defaultActiveCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#defaultActiveCellIndex)/[`activeCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeCellIndex)
See related [`gotoCell`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#gotoCell)

If you are using controlled [`activeCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeCellIndex) make sure you update the controlled value by using the [`onActiveCellIndexChange`](https://infinite-table.com/docs/reference/infinite-table-props.md#onActiveCellIndexChange) callback prop.

### setActiveRowIndex (`(activeRowIndex: number) => void`)

> Sets the value for [`defaultActiveRowIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#defaultActiveRowIndex)/[`activeRowIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeRowIndex)

If you are using controlled [`activeRow`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeRow), make sure you update the values by using the [`onActiveRowIndexChange`](https://infinite-table.com/docs/reference/infinite-table-props.md#onActiveRowIndexChange) callback prop.

### gotoNextRow (`()=> number | false`)

> Changes the active row index to the next row. See related [`gotoPreviousRow`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#gotoPreviousRow), [`setActiveRowIndex`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#setActiveRowIndex)

Returns `false` if the action was not successful (eg: already at the last row), otherwise the new active row index.

This sets the value for [`activeCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeCellIndex)

### gotoPreviousRow (`()=> number | false`)

> Changes the active row index to the prev row. See related [`gotoNextRow`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#gotoNextRow), [`setActiveRowIndex`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#setActiveRowIndex)

Returns `false` if the action was not successful (eg: already at the first row), otherwise the new active row index.

This sets the value for [`activeCellIndex`](https://infinite-table.com/docs/reference/infinite-table-props.md#activeCellIndex)

### gotoCell (`({direction: 'top' | 'bottom' | 'left' | 'right' }) => [number, number] | false`)

> Changes the active cell index, by navigating to the specified direction (equivalent to pressing the arrow keys).
See related [`setActiveCellIndex`](https://infinite-table.com/docs/reference/keyboard-navigation-api/index.md#setActiveCellIndex)

**Example: Using KeyboardNavigationApi.gotoCell**

```tsx
import {
  InfiniteTable,
  DataSource,
  DataSourceData,
  InfiniteTableKeyboardNavigationApi,
} from '@infinite-table/infinite-react';
import type { InfiniteTablePropColumns } from '@infinite-table/infinite-react';
import * as React from 'react';
import { useState } from 'react';

type Developer = {
  id: number;
  firstName: string;
  lastName: string;
  country: string;
  city: string;
  currency: string;
  preferredLanguage: string;
  stack: string;
  canDesign: 'yes' | 'no';
  hobby: string;
  salary: number;
  age: number;
};

const dataSource: DataSourceData<Developer> = () => {
  return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`)
    .then((r) => r.json())
    .then((data: Developer[]) => data);
};

const columns: InfiniteTablePropColumns<Developer> = {
  preferredLanguage: { field: 'preferredLanguage' },
  country: { field: 'country' },
  salary: {
    field: 'salary',
    type: 'number',
  },
  age: { field: 'age' },
  canDesign: { field: 'canDesign' },
  firstName: { field: 'firstName' },
  stack: { field: 'stack' },
  id: { field: 'id' },
  hobby: { field: 'hobby' },
  city: { field: 'city' },
  currency: { field: 'currency' },
};

export default function App() {
  const [keyboardNavigationApi, setKeyboardNavigationApi] = useState<
    InfiniteTableKeyboardNavigationApi<Developer> | undefined
  >(undefined);

  return (
    <>
      <DataSource<Developer> primaryKey="id" data={dataSource}>
        <div>
          <button
            onClick={() => {
              keyboardNavigationApi?.gotoCell({ direction: 'top' });
            }}
          >
            Go to top
          </button>
          <div>
            <button
              onClick={() => {
                keyboardNavigationApi?.gotoCell({ direction: 'left' });
              }}
            >
              Go to left
            </button>
            <button
              onClick={() => {
                keyboardNavigationApi?.gotoCell({ direction: 'right' });
              }}
            >
              Go to right
            </button>
          </div>
          <button
            onClick={() => {
              keyboardNavigationApi?.gotoCell({ direction: 'bottom' });
            }}
          >
            Go to bottom
          </button>
        </div>
        <InfiniteTable<Developer>
          debugId="goto-cell-example"
          // keyboardNavigation="cell" is the default, so no need to specify it
          columns={columns}
          defaultActiveCellIndex={[0, 0]}
          onReady={({ api }) => {
            setKeyboardNavigationApi(api.keyboardNavigationApi);
          }}
        />
      </DataSource>
    </>
  );
}
```
