Skip to content

Commit d4351f6

Browse files
committed
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.
1 parent d5eaef6 commit d4351f6

File tree

7 files changed

+102
-7
lines changed

7 files changed

+102
-7
lines changed

docs/src/COMPONENT_API.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18479,6 +18479,12 @@
1847918479
"type": "(visible: boolean) => void",
1848018480
"description": "",
1848118481
"optional": false
18482+
},
18483+
{
18484+
"name": "batchActionsActive",
18485+
"type": "import(\"svelte/store\").Writable<boolean>",
18486+
"description": "",
18487+
"optional": false
1848218488
}
1848318489
]
1848418490
}

src/DataTable/Toolbar.svelte

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
*/
1616
const overflowVisible = writable(false);
1717
18+
/**
19+
* @type {import("svelte/store").Writable<boolean>}
20+
*/
21+
const batchActionsActive = writable(false);
22+
1823
/**
1924
* @type {(visible: boolean) => void}
2025
*/
@@ -26,6 +31,7 @@
2631
setContext("Toolbar", {
2732
overflowVisible,
2833
setOverflowVisible,
34+
batchActionsActive,
2935
});
3036
</script>
3137

src/DataTable/ToolbarBatchActions.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
});
8383
}
8484
85+
$: if (ctxToolbar?.batchActionsActive) {
86+
ctxToolbar.batchActionsActive.set(showActions);
87+
}
88+
8589
onMount(() => {
8690
return () => {
8791
unsubscribe?.();

src/DataTable/ToolbarContent.svelte

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
<script>
22
import { getContext } from "svelte";
33
4-
const ctx = getContext("DataTable") ?? {};
4+
const ctx = getContext("Toolbar") ?? {};
55
6-
let batchSelectedIds = [];
6+
let batchActionsActive = false;
77
8-
if (ctx?.batchSelectedIds) {
9-
ctx.batchSelectedIds.subscribe((value) => {
10-
batchSelectedIds = value;
8+
if (ctx?.batchActionsActive) {
9+
ctx.batchActionsActive.subscribe((value) => {
10+
batchActionsActive = value;
1111
});
1212
}
1313
14-
$: hasBatchSelection = batchSelectedIds.length > 0;
15-
$: inertProps = hasBatchSelection ? { inert: true } : {};
14+
$: inertProps = batchActionsActive ? { inert: true } : {};
1615
</script>
1716
1817
<div class:bx--toolbar-content={true} {...inertProps}>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script lang="ts">
2+
import {
3+
Button,
4+
DataTable,
5+
Toolbar,
6+
ToolbarContent,
7+
ToolbarSearch,
8+
} from "carbon-components-svelte";
9+
10+
const headers = [
11+
{ key: "name", value: "Name" },
12+
{ key: "port", value: "Port" },
13+
{ key: "rule", value: "Rule" },
14+
] as const;
15+
16+
const rows = [
17+
{ id: "a", name: "Load Balancer 3", port: 3000, rule: "Round robin" },
18+
{ id: "b", name: "Load Balancer 1", port: 443, rule: "Round robin" },
19+
{ id: "c", name: "Load Balancer 2", port: 80, rule: "DNS delegation" },
20+
];
21+
22+
export let selectedRowIds: string[] = [];
23+
</script>
24+
25+
<div data-testid="selected-ids">{JSON.stringify(selectedRowIds)}</div>
26+
27+
<DataTable {headers} {rows} bind:selectedRowIds>
28+
<Toolbar size="sm">
29+
<ToolbarContent>
30+
<ToolbarSearch persistent />
31+
<Button data-testid="toolbar-button">Action</Button>
32+
</ToolbarContent>
33+
</Toolbar>
34+
</DataTable>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { render, screen } from "@testing-library/svelte";
2+
import { user } from "../setup-tests";
3+
import DataTableToolbarNoBatch from "./DataTableToolbarNoBatch.test.svelte";
4+
5+
// Regression test for https://github.com/carbon-design-system/carbon-components-svelte/issues/2404
6+
describe("DataTable toolbar without batch actions", () => {
7+
it("toolbar content should not be inert when rows are selected without batch actions", () => {
8+
const { container } = render(DataTableToolbarNoBatch, {
9+
props: {
10+
selectedRowIds: ["a"],
11+
},
12+
});
13+
14+
const toolbarContent = container.querySelector(".bx--toolbar-content");
15+
expect(toolbarContent).not.toHaveAttribute("inert");
16+
});
17+
18+
it("toolbar button should be clickable when rows are selected without batch actions", async () => {
19+
const clickHandler = vi.fn();
20+
render(DataTableToolbarNoBatch, {
21+
props: {
22+
selectedRowIds: ["a"],
23+
},
24+
});
25+
26+
const button = screen.getByTestId("toolbar-button");
27+
button.addEventListener("click", clickHandler);
28+
await user.click(button);
29+
30+
expect(clickHandler).toHaveBeenCalled();
31+
});
32+
33+
it("toolbar search should be focusable when rows are selected without batch actions", async () => {
34+
render(DataTableToolbarNoBatch, {
35+
props: {
36+
selectedRowIds: ["a"],
37+
},
38+
});
39+
40+
const searchInput = screen.getByRole("searchbox");
41+
await user.click(searchInput);
42+
43+
expect(searchInput).toHaveFocus();
44+
});
45+
});

types/DataTable/Toolbar.svelte.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { SvelteHTMLElements } from "svelte/elements";
44
export type ToolbarContext = {
55
overflowVisible: import("svelte/store").Writable<boolean>;
66
setOverflowVisible: (visible: boolean) => void;
7+
batchActionsActive: import("svelte/store").Writable<boolean>;
78
};
89

910
type $RestProps = SvelteHTMLElements["section"];

0 commit comments

Comments
 (0)