Skip to content

Commit

Permalink
feat(table): add isKeyboardNavigationDisabled prop to the table
Browse files Browse the repository at this point in the history
  • Loading branch information
Maharshi Alpesh authored and macci001 committed Nov 5, 2024
1 parent 1091377 commit 40a6706
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-icons-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nextui-org/table": patch
---

Currently, whenever any arrow-key keypress is triggered it navigates the focus to other cell/row. This creates an issue when the table cell contains a component which requires this keys for specific purpose (eg. if a table cell contains input component, it might need arrow keys for editing. But it is not possible because whenever the keypress triggers navigation). The PR adds an `isKeyboardNavigationDisabled` prop to disable the navigation.
2 changes: 1 addition & 1 deletion apps/docs/content/docs/components/table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ You can customize the `Table` component by passing custom Tailwind CSS classes t
| disableAnimation | `boolean` | Whether to disable the table and checkbox animations. | `false` |
| checkboxesProps | [CheckboxProps](/docs/components/checkbox/#checkbox-props) | Props to be passed to the checkboxes. | - |
| classNames | `Record<"base" | "table" | "thead" | "tbody" | "tfoot" | "emptyWrapper" | "loadingWrapper" | "wrapper" | "tr" | "th" | "td" | "sortIcon", string>` | Allows to set custom class names for the dropdown item slots. | - |

| isKeyboardNavigationDisabled | `boolean` | Whether to disable keyboard navigations or not. | `false` |
### Table Events

| Attribute | Type | Description |
Expand Down
40 changes: 39 additions & 1 deletion packages/components/table/__tests__/table.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as React from "react";
import {act, render} from "@testing-library/react";
import {act, render, fireEvent} from "@testing-library/react";
import userEvent, {UserEvent} from "@testing-library/user-event";


Check warning on line 5 in packages/components/table/__tests__/table.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint

Delete `⏎`
import {Table, TableHeader, TableCell, TableColumn, TableBody, TableRow} from "../src";
import {keyCodes} from "../../../utilities/test-utils/src";

const columns = [
{name: "Foo", key: "foo"},
Expand Down Expand Up @@ -101,6 +103,42 @@ describe("Table", () => {
expect(wrapper.getAllByRole("gridcell")).toHaveLength(2);
});

it("should disable key navigations when isKeyboardNavigationDisabled is enabled", async () => {
const wrapper = render(
<Table isKeyboardNavigationDisabled={true} selectionMode="single">
<TableHeader>
<TableColumn>Foo</TableColumn>
<TableColumn>Bar</TableColumn>
<TableColumn>Baz</TableColumn>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Foo 1</TableCell>
<TableCell>Bar 1</TableCell>
<TableCell>Baz 1</TableCell>
</TableRow>
<TableRow>
<TableCell>Foo 2</TableCell>
<TableCell>Bar 2</TableCell>
<TableCell>Baz 2</TableCell>
</TableRow>
</TableBody>
</Table>,
);

const row1 = wrapper.getAllByRole("row")[1];

// selecting the row1
await act(async () => {
await userEvent.click(row1);
});
expect(row1).toHaveFocus();

// triggering the arrow down on row1 should not shift the focus to row2
fireEvent.keyDown(row1, {key: "ArrowDown", keyCode: keyCodes.ArrowDown});
expect(row1).toHaveFocus();
});

it("should render dynamic table", () => {
const wrapper = render(
<Table aria-label="Dynamic Table">
Expand Down
10 changes: 10 additions & 0 deletions packages/components/table/src/use-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ interface Props<T> extends HTMLNextUIProps<"table"> {
* @default false
*/
disableAnimation?: boolean;
/**
* Whether to disable the keyboard navigation functionality.
* @default false
*/
isKeyboardNavigationDisabled?: boolean;
/**
* Props to be passed to the checkboxes.
*/
Expand Down Expand Up @@ -158,6 +163,7 @@ export function useTable<T extends object>(originalProps: UseTableProps<T>) {
classNames,
removeWrapper = false,
disableAnimation = globalContext?.disableAnimation ?? false,
isKeyboardNavigationDisabled = false,
selectionMode = "none",
topContentPlacement = "inside",
bottomContentPlacement = "inside",
Expand Down Expand Up @@ -185,6 +191,10 @@ export function useTable<T extends object>(originalProps: UseTableProps<T>) {
showSelectionCheckboxes,
});

if (isKeyboardNavigationDisabled && !state.isKeyboardNavigationDisabled) {
state.setKeyboardNavigationDisabled(true);
}

const {collection} = state;

// Exclude the layout prop because it has a name conflict and is deprecated in useTable.
Expand Down

0 comments on commit 40a6706

Please sign in to comment.