1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
"use client"
import * as React from "react"
import { useQueryState } from "nuqs"
import { Input } from "@/components/ui/input"
import { useDebouncedCallback } from "@/hooks/use-debounced-callback"
/**
* A generic "Global Filter" input that syncs its value with `?search=...` in the URL (shallow).
* Uses a custom `useDebouncedCallback` to reduce rapid updates.
*/
export function DataTableGlobalFilter() {
// The actual "search" state is still read/written from URL
const [searchValue, setSearchValue] = useQueryState("search", {
parse: (str) => str,
serialize: (val) => val,
eq: (a, b) => a === b,
clearOnDefault: true,
shallow: false,
})
// Local tempValue to update instantly on user keystroke
const [tempValue, setTempValue] = React.useState(searchValue ?? "")
// Debounced callback that sets the URL param after `delay` ms
const debouncedSetSearch = useDebouncedCallback((value: string) => {
if (value !== searchValue) setSearchValue(value.trim() === "" ? null : value);
}, 300)
// When user types, update local `tempValue` immediately,
// then call the debounced function to update the query param
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const val = e.target.value
setTempValue(val)
debouncedSetSearch(val)
}
// Debug
console.log("tempValue:", tempValue, "searchValue:", searchValue)
return (
<Input
value={tempValue}
onChange={handleChange}
placeholder="Search..."
className="h-8 w-24 sm:w-40"
/>
)
}
|