mertani-web-toolkit 0.1.53 → 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;
@@ -0,0 +1,16 @@
1
+ <svg
2
+ width="16"
3
+ height="16"
4
+ viewBox="0 0 16 16"
5
+ fill="currentColor"
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ >
8
+ <path
9
+ d="M5.884 6.68C5.84256 6.62777 5.79109 6.58436 5.73263 6.55232C5.67416 6.52027 5.60988 6.50025 5.54356 6.49341C5.47724 6.48658 5.41022 6.49308 5.34645 6.51253C5.28268 6.53198 5.22344 6.56399 5.17223 6.60667C5.12101 6.64935 5.07884 6.70185 5.04821 6.76106C5.01758 6.82028 4.9991 6.88503 4.99386 6.95149C4.98863 7.01796 4.99673 7.0848 5.01771 7.14808C5.03868 7.21137 5.0721 7.26982 5.116 7.32L7.349 10L5.116 12.68C5.03487 12.7823 4.99694 12.9122 5.01032 13.042C5.02369 13.1719 5.08731 13.2913 5.18759 13.3749C5.28787 13.4585 5.41684 13.4995 5.54697 13.4892C5.6771 13.479 5.79805 13.4182 5.884 13.32L8 10.781L10.116 13.321C10.201 13.4228 10.323 13.4867 10.4551 13.4987C10.5205 13.5046 10.5865 13.4975 10.6492 13.4779C10.7118 13.4583 10.7701 13.4266 10.8205 13.3845C10.8709 13.3424 10.9126 13.2908 10.9431 13.2326C10.9735 13.1744 10.9923 13.1108 10.9982 13.0454C11.0041 12.98 10.997 12.914 10.9774 12.8513C10.9578 12.7887 10.9261 12.7304 10.884 12.68L8.651 10L10.884 7.32C10.9651 7.21775 11.0031 7.08782 10.9897 6.95798C10.9763 6.82814 10.9127 6.70867 10.8124 6.62511C10.7121 6.54154 10.5832 6.50051 10.453 6.51076C10.3229 6.52102 10.2019 6.58176 10.116 6.68L8 9.219L5.884 6.68Z"
10
+ fill="currentColor"
11
+ />
12
+ <path
13
+ d="M14 14V4.5L9.5 0H4C3.46957 0 2.96086 0.210714 2.58579 0.585786C2.21071 0.960859 2 1.46957 2 2V14C2 14.5304 2.21071 15.0391 2.58579 15.4142C2.96086 15.7893 3.46957 16 4 16H12C12.5304 16 13.0391 15.7893 13.4142 15.4142C13.7893 15.0391 14 14.5304 14 14ZM9.5 3C9.5 3.39782 9.65804 3.77936 9.93934 4.06066C10.2206 4.34196 10.6022 4.5 11 4.5H13V14C13 14.2652 12.8946 14.5196 12.7071 14.7071C12.5196 14.8946 12.2652 15 12 15H4C3.73478 15 3.48043 14.8946 3.29289 14.7071C3.10536 14.5196 3 14.2652 3 14V2C3 1.73478 3.10536 1.48043 3.29289 1.29289C3.48043 1.10536 3.73478 1 4 1H9.5V3Z"
14
+ fill="currentColor"
15
+ />
16
+ </svg>
@@ -0,0 +1,26 @@
1
+ export default BsFileEarmarkExcel;
2
+ type BsFileEarmarkExcel = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const BsFileEarmarkExcel: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -142,6 +142,7 @@ import BSCalendar2Date from './BSCalendar2Date.svelte';
142
142
  import BsDiagram3 from './BsDiagram3.svelte';
143
143
  import BsNodePlus from './BsNodePlus.svelte';
144
144
  import BSBuildingLock from './BSBuildingLock.svelte';
145
+ import BsFileEarmarkExcel from './BsFileEarmarkExcel.svelte';
145
146
  // Icon component map dengan nama custom
146
147
  export const iconMap = {
147
148
  'bs-activity': BsActivity,
@@ -287,7 +288,8 @@ export const iconMap = {
287
288
  'bs-calendar2-date': BSCalendar2Date,
288
289
  'bs-diagram3': BsDiagram3,
289
290
  'bs-node-plus': BsNodePlus,
290
- 'bs-building-lock': BSBuildingLock
291
+ 'bs-building-lock': BSBuildingLock,
292
+ 'bs-file-earmark-excel': BsFileEarmarkExcel
291
293
  };
292
294
  // Export icon names untuk type safety
293
295
  export const IconNames = Object.keys(iconMap);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mertani-web-toolkit",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "homepage": "https://storybook.mertani.com/",
5
5
  "scripts": {
6
6
  "dev": "vite dev",