From f09c2e2c311c15f633db8dc45930d8e58a4b362d Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 19 Apr 2025 13:33:07 -0700 Subject: [PATCH] fix(toolbar-search): re-filter rows if `DataTable` rows change (#2154) Fixes #2143 Make `ToolbarSearch` filtering reactive to `DataTable` rows. Previously, `ToolbarSearch` did not update when `DataTable` rows changed. Now it subscribes to the context rows and re-runs `filterRows` in `afterUpdate` to prevent infinite loops. --- src/DataTable/ToolbarSearch.svelte | 28 +++++++++++++++++++++++-- tests/DataTable/DataTableSearch.test.ts | 3 +-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/DataTable/ToolbarSearch.svelte b/src/DataTable/ToolbarSearch.svelte index d9f33bcc..acde487b 100644 --- a/src/DataTable/ToolbarSearch.svelte +++ b/src/DataTable/ToolbarSearch.svelte @@ -46,15 +46,39 @@ */ export let ref = null; - import { tick, getContext } from "svelte"; + import { tick, getContext, afterUpdate, onMount } from "svelte"; import Search from "../Search/Search.svelte"; const ctx = getContext("DataTable") ?? {}; + let rows = null; + let unsubscribe = null; + $: if (shouldFilterRows) { - filteredRowIds = ctx?.filterRows(value, shouldFilterRows); + unsubscribe = ctx?.tableRows.subscribe((tableRows) => { + // Only update if the rows have actually changed. + // This approach works in both Svelte 4 and Svelte 5. + if (JSON.stringify(tableRows) !== JSON.stringify(rows)) { + rows = tableRows; + } + }); + } else { + rows = null; } + onMount(() => { + return () => { + unsubscribe?.(); + }; + }); + + afterUpdate(() => { + // Only filter rows in a callback to avoid an infinite update loop. + if (rows !== null) { + filteredRowIds = ctx?.filterRows(value, shouldFilterRows); + } + }); + async function expandSearch() { await tick(); if (disabled || persistent || expanded) return; diff --git a/tests/DataTable/DataTableSearch.test.ts b/tests/DataTable/DataTableSearch.test.ts index 71758718..2a721bd8 100644 --- a/tests/DataTable/DataTableSearch.test.ts +++ b/tests/DataTable/DataTableSearch.test.ts @@ -182,8 +182,7 @@ describe("DataTableSearch", () => { }); }); - // TODO: fix reactivity - it.skip("re-filters rows when toggled", async () => { + it("re-filters rows when toggled", async () => { render(DataTableSearch); allRowsRendered();