From 28e9c50791005464ea3e57b7e058f910793c52ca Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 3 Dec 2025 14:54:38 -0800 Subject: [PATCH 1/2] fix(toolbar): omit `inert` when batch actions are not present Fixes #2404 Track batch actions visibility state instead of selection state to prevent toolbar content from being inert when rows are selected without the batch actions component present. --- docs/src/COMPONENT_API.json | 6 +++ src/DataTable/Toolbar.svelte | 6 +++ src/DataTable/ToolbarBatchActions.svelte | 4 ++ src/DataTable/ToolbarContent.svelte | 13 +++--- .../DataTableToolbarNoBatch.test.svelte | 32 +++++++++++++ .../DataTable/DataTableToolbarNoBatch.test.ts | 45 +++++++++++++++++++ types/DataTable/Toolbar.svelte.d.ts | 1 + 7 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 tests/DataTable/DataTableToolbarNoBatch.test.svelte create mode 100644 tests/DataTable/DataTableToolbarNoBatch.test.ts diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index 75e806f54a..1af3a2986e 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -18479,6 +18479,12 @@ "type": "(visible: boolean) => void", "description": "", "optional": false + }, + { + "name": "batchActionsActive", + "type": "import(\"svelte/store\").Writable", + "description": "", + "optional": false } ] } diff --git a/src/DataTable/Toolbar.svelte b/src/DataTable/Toolbar.svelte index 1af52c7031..7e0b769bac 100644 --- a/src/DataTable/Toolbar.svelte +++ b/src/DataTable/Toolbar.svelte @@ -15,6 +15,11 @@ */ const overflowVisible = writable(false); + /** + * @type {import("svelte/store").Writable} + */ + const batchActionsActive = writable(false); + /** * @type {(visible: boolean) => void} */ @@ -26,6 +31,7 @@ setContext("Toolbar", { overflowVisible, setOverflowVisible, + batchActionsActive, }); diff --git a/src/DataTable/ToolbarBatchActions.svelte b/src/DataTable/ToolbarBatchActions.svelte index a6872d4391..57b39037a4 100644 --- a/src/DataTable/ToolbarBatchActions.svelte +++ b/src/DataTable/ToolbarBatchActions.svelte @@ -82,6 +82,10 @@ }); } + $: if (ctxToolbar?.batchActionsActive) { + ctxToolbar.batchActionsActive.set(showActions); + } + onMount(() => { return () => { unsubscribe?.(); diff --git a/src/DataTable/ToolbarContent.svelte b/src/DataTable/ToolbarContent.svelte index 310b1d903d..21be1812c9 100644 --- a/src/DataTable/ToolbarContent.svelte +++ b/src/DataTable/ToolbarContent.svelte @@ -1,18 +1,17 @@
diff --git a/tests/DataTable/DataTableToolbarNoBatch.test.svelte b/tests/DataTable/DataTableToolbarNoBatch.test.svelte new file mode 100644 index 0000000000..e6e1d36624 --- /dev/null +++ b/tests/DataTable/DataTableToolbarNoBatch.test.svelte @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/tests/DataTable/DataTableToolbarNoBatch.test.ts b/tests/DataTable/DataTableToolbarNoBatch.test.ts new file mode 100644 index 0000000000..f86e1d8e43 --- /dev/null +++ b/tests/DataTable/DataTableToolbarNoBatch.test.ts @@ -0,0 +1,45 @@ +import { render, screen } from "@testing-library/svelte"; +import { user } from "../setup-tests"; +import DataTableToolbarNoBatch from "./DataTableToolbarNoBatch.test.svelte"; + +// Regression test for https://github.com/carbon-design-system/carbon-components-svelte/issues/2404 +describe("DataTable toolbar without batch actions", () => { + it("toolbar content should not be inert when rows are selected without batch actions", () => { + const { container } = render(DataTableToolbarNoBatch, { + props: { + selectedRowIds: ["a"], + }, + }); + + const toolbarContent = container.querySelector(".bx--toolbar-content"); + expect(toolbarContent).not.toHaveAttribute("inert"); + }); + + it("toolbar button should be clickable when rows are selected without batch actions", async () => { + const clickHandler = vi.fn(); + render(DataTableToolbarNoBatch, { + props: { + selectedRowIds: ["a"], + }, + }); + + const button = screen.getByText("Action"); + button.addEventListener("click", clickHandler); + await user.click(button); + + expect(clickHandler).toHaveBeenCalled(); + }); + + it("toolbar search should be focusable when rows are selected without batch actions", async () => { + render(DataTableToolbarNoBatch, { + props: { + selectedRowIds: ["a"], + }, + }); + + const searchInput = screen.getByRole("searchbox"); + await user.click(searchInput); + + expect(searchInput).toHaveFocus(); + }); +}); diff --git a/types/DataTable/Toolbar.svelte.d.ts b/types/DataTable/Toolbar.svelte.d.ts index ce8eebadae..e15c537ef2 100644 --- a/types/DataTable/Toolbar.svelte.d.ts +++ b/types/DataTable/Toolbar.svelte.d.ts @@ -4,6 +4,7 @@ import type { SvelteHTMLElements } from "svelte/elements"; export type ToolbarContext = { overflowVisible: import("svelte/store").Writable; setOverflowVisible: (visible: boolean) => void; + batchActionsActive: import("svelte/store").Writable; }; type $RestProps = SvelteHTMLElements["section"]; From b03d2f952fa626be80be598d6d117835e84f93f0 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 4 Dec 2025 06:44:46 -0800 Subject: [PATCH 2/2] docs(data-table): add "With toolbar and selectable rows" example --- docs/src/pages/components/DataTable.svx | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/docs/src/pages/components/DataTable.svx b/docs/src/pages/components/DataTable.svx index b6759c2056..ed8c50c351 100644 --- a/docs/src/pages/components/DataTable.svx +++ b/docs/src/pages/components/DataTable.svx @@ -502,6 +502,70 @@ Use `size="short"` to create a more compact table with a small toolbar. +## With toolbar and selectable rows + +Set `selectable` to `true` to enable selectable rows. Here, the toolbar is used standalone. For batch actions for selected rows, see the [batch selection with toolbar](#batch-selection-with-batch-actions-toolbar) example. + + + + + + + + + + ## Filterable Set `shouldFilterRows` to `true` to enable client-side filtering. The default filter performs string comparisons on cell values.