Skip to content

Commit cb6cdf7

Browse files
authored
Merge pull request #4834 from gitbutlerapp/clean-up-select-component
Clean-up: Remove anti-pattern from the Select component
2 parents 2b508c6 + 057df19 commit cb6cdf7

File tree

2 files changed

+11
-32
lines changed

2 files changed

+11
-32
lines changed

apps/desktop/src/lib/select/SearchItem.svelte

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,27 @@
11
<script lang="ts">
2-
import { type SelectItem } from './Select.svelte';
32
import Icon from '@gitbutler/ui/Icon.svelte';
43
54
interface Props {
5+
searchValue: string;
66
placeholder?: string;
7-
items: SelectItem[];
8-
onSort?: (items: SelectItem[]) => void;
97
}
108
11-
const { placeholder = 'Search…', items, onSort }: Props = $props();
12-
13-
let value = $state('');
14-
let filteredItems = $state(items);
9+
let { placeholder = 'Search…', searchValue = $bindable() }: Props = $props();
1510
1611
let inputEl: HTMLInputElement;
1712
18-
function handleFilter() {
19-
filteredItems = items.filter((item) => item.label.toLowerCase().includes(value.toLowerCase()));
20-
}
21-
2213
function resetFilter() {
23-
value = '';
24-
handleFilter();
14+
searchValue = '';
2515
inputEl.focus();
2616
}
2717
2818
function handleInput(event: Event) {
29-
value = (event.target as HTMLInputElement).value;
30-
handleFilter();
19+
searchValue = (event.target as HTMLInputElement).value;
3120
}
32-
33-
$effect(() => {
34-
onSort?.(filteredItems);
35-
});
3621
</script>
3722

3823
<div class="container">
39-
{#if !value}
24+
{#if !searchValue}
4025
<i class="icon search-icon">
4126
<Icon name="search" />
4227
</i>
@@ -51,7 +36,7 @@
5136
class="text-13 search-input"
5237
type="text"
5338
{placeholder}
54-
bind:value
39+
bind:value={searchValue}
5540
oninput={handleInput}
5641
autocorrect="off"
5742
autocomplete="off"

apps/desktop/src/lib/select/Select.svelte

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,14 @@
5050
let selectWrapperEl: HTMLElement;
5151
5252
let highlightedIndex: number | undefined = $state(undefined);
53-
let filteredOptions = $state(options);
53+
let searchValue = $state('');
54+
let filteredOptions = $derived(
55+
options.filter((item) => item.label.toLowerCase().includes(searchValue.toLowerCase()))
56+
);
5457
let maxHeightState = $state(maxHeight);
5558
let listOpen = $state(false);
5659
let inputBoundingRect = $state<DOMRect>();
5760
58-
$effect(() => {
59-
filteredOptions = options;
60-
});
61-
6261
const maxBottomPadding = 20;
6362
6463
function setMaxHeight() {
@@ -187,12 +186,7 @@
187186
>
188187
<ScrollableContainer initiallyVisible>
189188
{#if searchable && options.length > 5}
190-
<SearchItem
191-
items={options}
192-
onSort={(filtered) => {
193-
filteredOptions = filtered;
194-
}}
195-
/>
189+
<SearchItem bind:searchValue />
196190
{/if}
197191
<OptionsGroup>
198192
{#if filteredOptions.length === 0}

0 commit comments

Comments
 (0)