Skip to content

Commit

Permalink
Add debounce to user search field
Browse files Browse the repository at this point in the history
  • Loading branch information
myieye committed Oct 19, 2023
1 parent 1b4618d commit 39981ff
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
22 changes: 16 additions & 6 deletions frontend/src/lib/forms/Input.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { randomFieldId } from './utils';
import FormField from './FormField.svelte';
import { debounce as _debounce } from '$lib/util/time';
export let id = randomFieldId();
export let label: string;
Expand All @@ -14,20 +15,29 @@
// Despite the compatibility table, 'new-password' seems to work well in Chrome, Edge & Firefox
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#browser_compatibility
export let autocomplete: 'new-password' | undefined = undefined;
export let debounce: number | boolean = false;
const DEFAULT_DEBOUNCE_TIME = 400;
$: debounceTime = typeof debounce === 'number' ? debounce : DEFAULT_DEBOUNCE_TIME;
$: valueSetter = debounce
? _debounce((newValue: string) => value = newValue, debounceTime)
: (newValue: string) => value = newValue;
function onInput(event: Event): void {
const newValue = (event.target as HTMLInputElement).value;
valueSetter(newValue);
}
</script>

<!-- https://daisyui.com/components/input -->
<FormField {id} {error} {label} {autofocus} {description}>
<!-- svelte-ignore a11y-autofocus -->
<!--
{...{type}} prevents a Svelte compile error (https://github.com/sveltejs/svelte/issues/3921)
and is perfectly safe, because we limit the type to string values
-->
<input
{id}
{...{ type }}
bind:value
{type}
{value}
class:input-error={error}
on:input={onInput}
{placeholder}
class="input input-bordered"
{readonly}
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/lib/util/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ export const enum Duration {
export async function delay<T>(ms = Duration.Default): Promise<T> {
return new Promise<T>(resolve => setTimeout(resolve, ms));
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function debounce<P extends any[]>(fn: (...args: P) => void, debounceTime: number): (...args: P) => void {
let timeout: ReturnType<typeof setTimeout>;
return (...args: P) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), debounceTime);
};
}
2 changes: 1 addition & 1 deletion frontend/src/routes/(authenticated)/admin/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
</span>
</Badge>
</span>
<Input label="" placeholder={$t('admin_dashboard.filter_placeholder')} bind:value={$queryParamValues.userSearch} />
<Input label="" placeholder={$t('admin_dashboard.filter_placeholder')} bind:value={$queryParamValues.userSearch} debounce />

<div class="divider" />
<div class="overflow-x-auto">
Expand Down

0 comments on commit 39981ff

Please sign in to comment.