mertani-web-toolkit 0.1.54 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,6 +57,8 @@
57
57
  emptyMessage?: string;
58
58
  closeOnSelect?: boolean;
59
59
  loadingSuggestions?: boolean;
60
+ /** Jika false, suggestions tidak difilter di client (untuk data dari API yang sudah difilter) */
61
+ filterSuggestionsClientSide?: boolean;
60
62
 
61
63
  // Events
62
64
  onSelectSuggestion?: (value: string, option: SuggestionOption) => void;
@@ -126,6 +128,7 @@
126
128
  emptyMessage = 'Tidak ada hasil',
127
129
  closeOnSelect = true,
128
130
  loadingSuggestions = false,
131
+ filterSuggestionsClientSide = true,
129
132
 
130
133
  // Events
131
134
  onSelectSuggestion,
@@ -155,15 +158,15 @@
155
158
  ...props
156
159
  }: Props = $props();
157
160
 
158
- let inputValue = $state(value);
159
- let errorMessage = $state('');
160
- let isFocused = $state(false);
161
- let showList = $state(false);
162
- let activeIndex = $state(-1);
163
- let wrapperEl: HTMLDivElement | null = $state(null);
164
- let inputEl: HTMLInputElement | null = $state(null);
165
- let searchByValue = $state(searchBy);
166
- let searchByOpen = $state(false);
161
+ let inputValue = $derived(value);
162
+ let errorMessage = $derived('');
163
+ let isFocused = $derived(false);
164
+ let showList = $derived(false);
165
+ let activeIndex = $derived(-1);
166
+ let wrapperEl: HTMLDivElement | null = $derived(null);
167
+ let inputEl: HTMLInputElement | null = $derived(null);
168
+ let searchByValue = $derived(searchBy);
169
+ let searchByOpen = $derived(false);
167
170
 
168
171
  $effect(() => {
169
172
  inputValue = value;
@@ -180,6 +183,11 @@
180
183
  }
181
184
  });
182
185
 
186
+ $effect(() => {
187
+ suggestions = suggestions;
188
+ activeIndex = -1;
189
+ });
190
+
183
191
  const sizeConfig = $derived(() => {
184
192
  switch (size) {
185
193
  case 48:
@@ -309,12 +317,17 @@
309
317
  return classes.join(' ');
310
318
  });
311
319
 
312
- function normalizeSuggestion(option: SuggestionOption) {
320
+ function normalizeSuggestion(option: SuggestionOption): {
321
+ label: string;
322
+ value: string;
323
+ raw: SuggestionOption;
324
+ } {
313
325
  if (typeof option === 'string') {
314
326
  return { label: option, value: option, raw: option };
315
327
  }
316
- const val = option.value ?? option.label;
317
- return { label: option.label, value: val, raw: option };
328
+ const val = String(option.value ?? option.id ?? option.label ?? '');
329
+ const lbl = String(option.label ?? option.value ?? option.id ?? '');
330
+ return { label: lbl, value: val, raw: option };
318
331
  }
319
332
 
320
333
  const filteredSuggestions = $derived(() => {
@@ -325,9 +338,10 @@
325
338
  return [];
326
339
  }
327
340
 
328
- const result = query
329
- ? normalized.filter((item) => item.label.toLowerCase().includes(query))
330
- : normalized;
341
+ const result =
342
+ filterSuggestionsClientSide && query
343
+ ? normalized.filter((item) => item.label.toLowerCase().includes(query))
344
+ : normalized;
331
345
  return result.slice(0, maxSuggestions);
332
346
  });
333
347
 
@@ -388,12 +402,6 @@
388
402
  oninput?.(e);
389
403
  }
390
404
 
391
- function handleSearchByChange(e: Event) {
392
- const target = e.target as HTMLSelectElement;
393
- searchByValue = target.value;
394
- searchBy = target.value;
395
- }
396
-
397
405
  function selectSearchBy(option: SearchByOption) {
398
406
  searchByValue = option.value;
399
407
  searchBy = option.value;
@@ -469,12 +477,15 @@
469
477
  }
470
478
 
471
479
  $effect(() => {
472
- if (showList) {
473
- setTimeout(() => document.addEventListener('click', handleClickOutside), 10);
474
- } else {
480
+ if (!showList) {
475
481
  document.removeEventListener('click', handleClickOutside);
482
+ return;
476
483
  }
477
- return () => document.removeEventListener('click', handleClickOutside);
484
+ const tid = setTimeout(() => document.addEventListener('click', handleClickOutside), 10);
485
+ return () => {
486
+ clearTimeout(tid);
487
+ document.removeEventListener('click', handleClickOutside);
488
+ };
478
489
  });
479
490
  </script>
480
491
 
@@ -42,6 +42,8 @@ interface Props extends HTMLInputAttributes {
42
42
  emptyMessage?: string;
43
43
  closeOnSelect?: boolean;
44
44
  loadingSuggestions?: boolean;
45
+ /** Jika false, suggestions tidak difilter di client (untuk data dari API yang sudah difilter) */
46
+ filterSuggestionsClientSide?: boolean;
45
47
  onSelectSuggestion?: (value: string, option: SuggestionOption) => void;
46
48
  onclick?: (event: MouseEvent) => void;
47
49
  oninput?: (event: Event) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mertani-web-toolkit",
3
- "version": "0.1.54",
3
+ "version": "0.1.55",
4
4
  "homepage": "https://storybook.mertani.com/",
5
5
  "scripts": {
6
6
  "dev": "vite dev",