@cloudparker/moldex.js 0.0.123 → 4.1.0

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.
Files changed (72) hide show
  1. package/dist/types.d.ts +6 -0
  2. package/dist/types.js +7 -0
  3. package/dist/views/core/button/components/button/button.svelte +135 -83
  4. package/dist/views/core/button/components/button-back/button-back.svelte +28 -15
  5. package/dist/views/core/button/components/button-close/button-close.svelte +4 -2
  6. package/dist/views/core/button/components/button-close-icon/button-close-icon.svelte +29 -15
  7. package/dist/views/core/button/components/button-dropdown/button-dropdown.svelte +96 -72
  8. package/dist/views/core/button/components/button-dropdown/button-dropdown.svelte.d.ts +1 -1
  9. package/dist/views/core/button/components/button-list-item/button-list-item.svelte +98 -52
  10. package/dist/views/core/button/components/button-menu/button-menu.svelte +79 -43
  11. package/dist/views/core/button/components/button-ok/button-ok.svelte +4 -2
  12. package/dist/views/core/button/components/button-search/button-search.svelte +45 -21
  13. package/dist/views/core/button/components/switch/switch.svelte +70 -0
  14. package/dist/views/core/button/components/switch/switch.svelte.d.ts +11 -0
  15. package/dist/views/core/button/index.d.ts +4 -2
  16. package/dist/views/core/button/index.js +2 -1
  17. package/dist/views/core/common/components/content-area/content-area.svelte +40 -27
  18. package/dist/views/core/common/components/loading/loading.svelte +9 -2
  19. package/dist/views/core/common/components/virtual-scrolling/virtual-scrolling-list.svelte +37 -20
  20. package/dist/views/core/dialog/components/cropper-dialog/cropper-dialog.svelte +52 -36
  21. package/dist/views/core/dialog/components/dialog/dialog.svelte +298 -177
  22. package/dist/views/core/dialog/components/loading-dialog/loading-dialog.svelte +30 -18
  23. package/dist/views/core/dialog/components/msg-dialog/msg-dialog.svelte +17 -7
  24. package/dist/views/core/dialog/components/number-field-dialog/number-field-dialog.svelte +41 -26
  25. package/dist/views/core/dialog/components/picker-dialog/picker-dialog.svelte +150 -105
  26. package/dist/views/core/dialog/components/text-field-dialog/text-field-dialog.svelte +40 -25
  27. package/dist/views/core/dialog/components/textarea-field-dialog/textarea-field-dialog.svelte +40 -25
  28. package/dist/views/core/drawer/components/drawer/drawer.svelte +58 -36
  29. package/dist/views/core/icon/components/icon/icon.svelte +24 -12
  30. package/dist/views/core/icon/components/icon-circle/icon-circle.svelte +10 -2
  31. package/dist/views/core/input/components/checkbox-field/checkbox-field.svelte +44 -25
  32. package/dist/views/core/input/components/color-field/color-field.svelte +81 -69
  33. package/dist/views/core/input/components/combobox-field/combobox-field.svelte +359 -269
  34. package/dist/views/core/input/components/date-field/date-field.svelte +39 -30
  35. package/dist/views/core/input/components/datetime-field/datetime-field.svelte +18 -12
  36. package/dist/views/core/input/components/email-field/email-field.svelte +17 -12
  37. package/dist/views/core/input/components/file-field/file-field.svelte +78 -64
  38. package/dist/views/core/input/components/input-field/input-field.svelte +267 -164
  39. package/dist/views/core/input/components/label/label.svelte +24 -10
  40. package/dist/views/core/input/components/number-field/number-field.svelte +18 -12
  41. package/dist/views/core/input/components/password-field/password-field.svelte +70 -57
  42. package/dist/views/core/input/components/phone-field/phone-field.svelte +155 -104
  43. package/dist/views/core/input/components/radio-field/radio-field.svelte +83 -52
  44. package/dist/views/core/input/components/range-field/range-field.svelte +67 -44
  45. package/dist/views/core/input/components/search-field/search-field.svelte +62 -45
  46. package/dist/views/core/input/components/text-field/text-field.svelte +21 -16
  47. package/dist/views/core/input/components/textarea-field/textarea-field.svelte +17 -12
  48. package/dist/views/core/input/components/time-field/time-field.svelte +17 -12
  49. package/dist/views/core/navbar/components/navbar/navbar.svelte +76 -38
  50. package/dist/views/core/no-data/components/no-data/no-data.svelte +36 -19
  51. package/dist/views/core/pagination/components/pagination/pagination.svelte +90 -66
  52. package/dist/views/core/progressbar/components/progressbar/progressbar.svelte +36 -22
  53. package/dist/views/core/ruler/components/vertical-ruler/verticcal-ruler.svelte +5 -1
  54. package/dist/views/core/screen-detector/components/screen-detector.svelte +13 -9
  55. package/dist/views/core/sidebar/components/sidebar.svelte +36 -23
  56. package/dist/views/core/spinner/components/spinner/spinner.svelte +6 -1
  57. package/dist/views/core/text/components/text-await/text-await.svelte +9 -1
  58. package/dist/views/core/text/components/text-copy/text-copy.svelte +27 -16
  59. package/dist/views/core/text/components/text-currency/text-currency.svelte +13 -2
  60. package/dist/views/core/text/components/text-date/text-date.svelte +32 -20
  61. package/dist/views/core/text/components/text-email/text-email.svelte +12 -3
  62. package/dist/views/core/text/components/text-html/text-html.svelte +2 -1
  63. package/dist/views/core/text/components/text-phone/text-phone.svelte +12 -3
  64. package/dist/views/core/toast/components/toast/toast.svelte +43 -20
  65. package/dist/views/extra/fields/country-combobox-field.svelte +23 -15
  66. package/dist/views/extra/loaders/country-loader.svelte +33 -15
  67. package/dist/views/extra/texts/text-country-state.svelte +36 -28
  68. package/dist/views/extra/texts/text-country.svelte +16 -8
  69. package/package.json +3 -12
  70. package/readme.md +57 -2
  71. package/dist/tailwind.css +0 -1
  72. package/dist/theme.css +0 -27
@@ -1,272 +1,362 @@
1
- <script module lang="ts"></script>
2
-
3
- <script lang="ts">import ButtonListItem from "../../../button/components/button-list-item/button-list-item.svelte";
4
- import Button from "../../../button/components/button/button.svelte";
5
- import {
6
- mdiCheckCircle,
7
- mdiCheckCircleOutline,
8
- mdiUnfoldMoreHorizontal
9
- } from "../../../icon";
10
- import Icon from "../../../icon/components/icon/icon.svelte";
11
- import NoData from "../../../no-data/components/no-data/no-data.svelte";
12
- import InputField, {} from "../input-field/input-field.svelte";
13
- import SearchField from "../search-field/search-field.svelte";
14
- import { SvelteSet } from "svelte/reactivity";
15
- import VirtualScrollingList from "../../../common/components/virtual-scrolling/virtual-scrolling-list.svelte";
16
- let {
17
- appearance,
18
- chipClassName,
19
- className,
20
- comboboxIconClassName,
21
- comboboxIconPath = mdiUnfoldMoreHorizontal,
22
- contentSnippet,
23
- createButtonClassName,
24
- createButtonLabel = "Add",
25
- displayClassName,
26
- displayFieldName = "name",
27
- displayItemsCount,
28
- dropdownBodyClassName,
29
- dropdownBodySnippet,
30
- dropdownClassName,
31
- dropdownFooterClassName,
32
- dropdownFooterSnippet,
33
- dropdownHeaderClassName,
34
- dropdownHeaderSnippet,
35
- emptyMessage = "No items exists!",
36
- emptyMessageSnippet,
37
- hasComboboxIcon = true,
38
- hasDropdownFooter,
39
- hasDropdownFooterCreateButton,
40
- hasDropdownHeader,
41
- hasDropdownHeaderSearch,
42
- hasCheckbox,
43
- iconClassName,
44
- iconPathFieldName,
45
- id,
46
- identityFieldName = "_id",
47
- itemClassName,
48
- items,
49
- multiple,
50
- name,
51
- onCreateButtonClick,
52
- onSearch,
53
- searchClassName,
54
- searchFieldName = "name",
55
- searchPlaceholder = "Search...",
56
- showChip,
57
- size,
58
- subtitleClassName,
59
- subtitleFieldName,
60
- titleClassName,
61
- titleFieldName = "name",
62
- value = $bindable(null),
63
- checkboxIconPath = mdiCheckCircle,
64
- uncheckboxIconPath = mdiCheckCircleOutline,
65
- checkboxIconClassName = "",
66
- uncheckboxIconClassName = "",
67
- checkboxClassName = "",
68
- dropPosition = "bottom",
69
- itemTileSnippet,
70
- onChange,
71
- ...props
72
- } = $props();
73
- let searchFieldRef = $state(null);
74
- let isPlaced = $state(false);
75
- let searchText = $state("");
76
- let dropdownHeight = $state(0);
77
- let windowScrollY = $state(0);
78
- let bodyHeight = $state(0);
79
- let placementClassName = $derived.by(() => {
80
- if (!isPlaced) return "mt-1";
81
- const rect = inputFieldRef.getBoundingClientRect();
82
- const spaceBelow = window.innerHeight - rect.bottom;
83
- const spaceAbove = rect.top;
84
- let placement;
85
- switch (dropPosition) {
86
- case "top":
87
- placement = "bottom-full mb-1";
88
- break;
89
- case "middle":
90
- placement = "-translate-y-1/2 top-1/2";
91
- break;
92
- default:
93
- placement = "mt-1";
94
- }
95
- if (dropPosition === "bottom" && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight) {
96
- placement = "bottom-full mb-1";
97
- } else if (dropPosition === "top" && spaceAbove < dropdownHeight && spaceBelow > dropdownHeight) {
98
- placement = "mt-1";
99
- } else if (dropPosition === "middle") {
100
- const spaceNeeded = dropdownHeight / 2;
101
- if (spaceAbove < spaceNeeded || spaceBelow < spaceNeeded) {
102
- placement = spaceAbove > spaceBelow ? "bottom-full mb-1" : "mt-1";
103
- }
104
- }
105
- return placement;
106
- });
107
- let selectedItemsSet = $derived(
108
- value ? new SvelteSet(Array.isArray(value) ? value : [value]) : new SvelteSet()
109
- );
110
- let comboboxIconSizeClassName = $derived.by(() => {
111
- if (size) {
112
- switch (size) {
113
- case "lg":
114
- return "!h-7 !w-7";
115
- case "md":
116
- return "!h-6 !w-6";
117
- case "sm":
118
- return "!h-5 !w-5";
119
- case "xs":
120
- return "!h-4 !w-4";
121
- }
122
- }
123
- });
124
- let hasPrimitiveItemsData = $derived.by(() => {
125
- if (items) {
126
- let firstItem = items[0];
127
- return typeof firstItem == "string" || typeof firstItem == "number" || firstItem instanceof Date;
128
- }
129
- return false;
130
- });
131
- let _value = $derived.by(() => {
132
- return selectedItemsSet?.size ? "&nbsp;" : "";
133
- });
134
- let displayItems = $derived.by(() => {
135
- let array = Array.from(selectedItemsSet);
136
- let results = array.map((id2) => {
137
- if (hasPrimitiveItemsData) {
138
- return id2;
139
- } else {
140
- let item = itemsIdentityMap[id2];
141
- if (item) {
142
- if (displayFieldName && item.hasOwnProperty(displayFieldName)) {
143
- return item[displayFieldName];
144
- }
145
- }
146
- }
147
- });
148
- return results;
149
- });
150
- let displayItemsTitle = $derived(displayItems.join(", "));
151
- let displayText = $derived.by(() => {
152
- let results = displayItems;
153
- if (!showChip) {
154
- if (results?.length) {
155
- if (multiple) {
156
- let res = results.join(", ");
157
- if (displayItemsCount != null && displayItemsCount > 1) {
158
- res = results.slice(0, displayItemsCount).join(", ");
159
- if (results.length > displayItemsCount) {
160
- res += `<span class="text-gray-400 px-2">+ ${results.length - displayItemsCount} </span>`;
161
- }
162
- }
163
- return res;
164
- } else {
165
- return results[0] || "";
166
- }
167
- }
168
- }
169
- return "";
170
- });
171
- let preparedItems = $derived.by(() => {
172
- return (items || []).map((item, index) => {
173
- let res = {};
174
- if (hasPrimitiveItemsData) {
175
- res[identityFieldName] = item;
176
- res[titleFieldName] = item;
177
- res[searchFieldName] = item;
178
- } else {
179
- res = item;
180
- }
181
- return res;
182
- });
183
- });
184
- let itemsIdentityMap = $derived.by(() => {
185
- return preparedItems.reduce((acc, val) => {
186
- acc[val[identityFieldName]] = val;
187
- return acc;
188
- }, {});
189
- });
190
- let filteredItems = $derived.by(() => {
191
- if (searchText) {
192
- return preparedItems.filter((item) => {
193
- return (item[searchFieldName] || "").toLowerCase().indexOf(searchText) >= 0;
194
- });
195
- } else {
196
- return [...preparedItems];
197
- }
198
- });
199
- let inputFieldRef = $state(null);
200
- export function focus() {
201
- inputFieldRef?.focus();
202
- }
203
- function toggleDropdown() {
204
- if (isPlaced) {
205
- closeDropdown();
206
- } else {
207
- openDropdown();
208
- }
209
- }
210
- function closeDropdown() {
211
- searchText = "";
212
- isPlaced = false;
213
- focus();
214
- }
215
- function openDropdown() {
216
- isPlaced = true;
217
- }
218
- function handleInputClick() {
219
- toggleDropdown();
220
- }
221
- function handleBackdropClick() {
222
- toggleDropdown();
223
- }
224
- function handleKeyDown(event) {
225
- if (event.key === "Escape") {
226
- closeDropdown();
227
- } else if (event.key === "Enter" || event.key === " ") {
228
- event.preventDefault();
229
- toggleDropdown();
230
- } else if (/^[a-zA-Z0-9]$/.test(event.key)) {
231
- searchFieldRef && searchFieldRef.focus();
232
- } else if (event.key === "Backspace" || event.key === "Delete") {
233
- event.preventDefault();
234
- selectedItemsSet.clear();
235
- value = null;
236
- }
237
- }
238
- function handleDropdownKeyDown(event) {
239
- if (event.key === "Escape") {
240
- closeDropdown();
241
- }
242
- }
243
- function handleSearch(value2) {
244
- searchText = value2;
245
- }
246
- function handleItemClick(ev, item, index) {
247
- let id2 = item[identityFieldName];
248
- if (multiple) {
249
- if (selectedItemsSet.has(id2)) {
250
- selectedItemsSet.delete(id2);
251
- } else {
252
- selectedItemsSet.add(id2);
253
- }
254
- } else {
255
- selectedItemsSet.clear();
256
- selectedItemsSet.add(id2);
257
- }
258
- items = [...items || []];
259
- let array = Array.from(selectedItemsSet);
260
- if (array.length) {
261
- value = multiple ? array : array[0];
262
- } else {
263
- value = null;
264
- }
265
- if (!multiple) {
266
- closeDropdown();
267
- }
268
- onChange && onChange(value);
269
- }
1
+ <script module lang="ts">
2
+ export type ComboboxFieldProps = {
3
+ chipClassName?: string;
4
+ comboboxIconClassName?: string;
5
+ comboboxIconPath?: string;
6
+ createButtonClassName?: string;
7
+ createButtonLabel?: string;
8
+ displayClassName?: string;
9
+ displayFieldName?: string;
10
+ displayItemsCount?: number;
11
+ dropdownBodyClassName?: string;
12
+ dropdownBodySnippet?: Snippet;
13
+ dropdownClassName?: string;
14
+ dropdownFooterClassName?: string;
15
+ dropdownFooterSnippet?: Snippet;
16
+ dropdownHeaderClassName?: string;
17
+ dropdownHeaderSnippet?: Snippet;
18
+ emptyMessage?: string;
19
+ emptyMessageSnippet?: Snippet;
20
+ hasComboboxIcon?: boolean;
21
+ hasDropdownFooter?: boolean;
22
+ hasDropdownFooterCreateButton?: boolean;
23
+ hasDropdownHeader?: boolean;
24
+ hasDropdownHeaderSearch?: boolean;
25
+ hasCheckbox?: boolean;
26
+ iconClassName?: string;
27
+ iconPathFieldName?: string;
28
+ identityFieldName?: string;
29
+ itemClassName?: string;
30
+ items?: any[];
31
+ multiple?: boolean;
32
+ onCreateButtonClick?: (ev: MouseEvent) => void;
33
+ onSearch?: (value: string) => void;
34
+ searchClassName?: string;
35
+ searchFieldName?: string;
36
+ searchPlaceholder?: string;
37
+ showChip?: boolean;
38
+ subtitleClassName?: string;
39
+ subtitleFieldName?: string;
40
+ titleClassName?: string;
41
+ titleFieldName?: string;
42
+ checkboxIconPath?: string;
43
+ uncheckboxIconPath?: string;
44
+ checkboxIconClassName?: string;
45
+ uncheckboxIconClassName?: string;
46
+ checkboxClassName?: string;
47
+ dropPosition?: 'top' | 'bottom' | 'middle';
48
+ itemTileSnippet?: Snippet<[item: any, index: any]>;
49
+ };
50
+ </script>
51
+
52
+ <script lang="ts">
53
+ import ButtonListItem from '../../../button/components/button-list-item/button-list-item.svelte';
54
+ import Button from '../../../button/components/button/button.svelte';
55
+ import {
56
+ mdiCheckCircle,
57
+ mdiCheckCircleOutline,
58
+ mdiUnfoldMoreHorizontal
59
+ } from '../../../icon';
60
+ import Icon from '../../../icon/components/icon/icon.svelte';
61
+ import NoData from '../../../no-data/components/no-data/no-data.svelte';
62
+ import type { Snippet } from 'svelte';
63
+ import InputField, { type InputFieldProps } from '../input-field/input-field.svelte';
64
+ import SearchField from '../search-field/search-field.svelte';
65
+ import { SvelteSet } from 'svelte/reactivity';
66
+ import VirtualScrollingList from '../../../common/components/virtual-scrolling/virtual-scrolling-list.svelte';
67
+
68
+ let {
69
+ appearance,
70
+ chipClassName,
71
+ className,
72
+ comboboxIconClassName,
73
+ comboboxIconPath = mdiUnfoldMoreHorizontal,
74
+ contentSnippet,
75
+ createButtonClassName,
76
+ createButtonLabel = 'Add',
77
+ displayClassName,
78
+ displayFieldName = 'name',
79
+ displayItemsCount,
80
+ dropdownBodyClassName,
81
+ dropdownBodySnippet,
82
+ dropdownClassName,
83
+ dropdownFooterClassName,
84
+ dropdownFooterSnippet,
85
+ dropdownHeaderClassName,
86
+ dropdownHeaderSnippet,
87
+ emptyMessage = 'No items exists!',
88
+ emptyMessageSnippet,
89
+ hasComboboxIcon = true,
90
+ hasDropdownFooter,
91
+ hasDropdownFooterCreateButton,
92
+ hasDropdownHeader,
93
+ hasDropdownHeaderSearch,
94
+ hasCheckbox,
95
+ iconClassName,
96
+ iconPathFieldName,
97
+ id,
98
+ identityFieldName = '_id',
99
+ itemClassName,
100
+ items,
101
+ multiple,
102
+ name,
103
+ onCreateButtonClick,
104
+ onSearch,
105
+ searchClassName,
106
+ searchFieldName = 'name',
107
+ searchPlaceholder = 'Search...',
108
+ showChip,
109
+ size,
110
+ subtitleClassName,
111
+ subtitleFieldName,
112
+ titleClassName,
113
+ titleFieldName = 'name',
114
+ value = $bindable(null),
115
+ checkboxIconPath = mdiCheckCircle,
116
+ uncheckboxIconPath = mdiCheckCircleOutline,
117
+ checkboxIconClassName = '',
118
+ uncheckboxIconClassName = '',
119
+ checkboxClassName = '',
120
+ dropPosition = 'bottom',
121
+ itemTileSnippet,
122
+ onChange,
123
+ ...props
124
+ }: InputFieldProps & ComboboxFieldProps = $props();
125
+
126
+ let searchFieldRef: any | null = $state(null);
127
+
128
+ let isPlaced = $state(false);
129
+ let searchText: string = $state('');
130
+ let dropdownHeight = $state(0);
131
+ let windowScrollY = $state(0);
132
+ let bodyHeight: number = $state(0);
133
+
134
+ let placementClassName = $derived.by(() => {
135
+ if (!isPlaced) return 'mt-1';
136
+
137
+ const rect = inputFieldRef.getBoundingClientRect();
138
+ const spaceBelow = window.innerHeight - rect.bottom;
139
+ const spaceAbove = rect.top;
140
+
141
+ let placement;
142
+
143
+ switch (dropPosition) {
144
+ case 'top':
145
+ placement = 'bottom-full mb-1';
146
+ break;
147
+ case 'middle':
148
+ placement = '-translate-y-1/2 top-1/2';
149
+ break;
150
+ default:
151
+ placement = 'mt-1';
152
+ }
153
+
154
+ if (dropPosition === 'bottom' && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight) {
155
+ placement = 'bottom-full mb-1';
156
+ } else if (dropPosition === 'top' && spaceAbove < dropdownHeight && spaceBelow > dropdownHeight) {
157
+ placement = 'mt-1';
158
+ } else if (dropPosition === 'middle') {
159
+ const spaceNeeded = dropdownHeight / 2;
160
+ if (spaceAbove < spaceNeeded || spaceBelow < spaceNeeded) {
161
+ placement = spaceAbove > spaceBelow ? 'bottom-full mb-1' : 'mt-1';
162
+ }
163
+ }
164
+
165
+ return placement;
166
+ });
167
+
168
+ let selectedItemsSet: SvelteSet<any> = $derived(
169
+ value ? new SvelteSet<any>(Array.isArray(value) ? value : [value]) : new SvelteSet<any>()
170
+ );
171
+
172
+ let comboboxIconSizeClassName = $derived.by(() => {
173
+ if (size) {
174
+ switch (size) {
175
+ case 'lg':
176
+ return '!h-7 !w-7';
177
+ case 'md':
178
+ return '!h-6 !w-6';
179
+ case 'sm':
180
+ return '!h-5 !w-5';
181
+ case 'xs':
182
+ return '!h-4 !w-4';
183
+ }
184
+ }
185
+ });
186
+
187
+ let hasPrimitiveItemsData = $derived.by(() => {
188
+ if (items) {
189
+ let firstItem = items[0];
190
+ return (
191
+ typeof firstItem == 'string' || typeof firstItem == 'number' || firstItem instanceof Date
192
+ );
193
+ }
194
+ return false;
195
+ });
196
+
197
+ let _value = $derived.by(() => {
198
+ return selectedItemsSet?.size ? '&nbsp;' : '';
199
+ });
200
+
201
+ let displayItems: string[] = $derived.by(() => {
202
+ let array = Array.from(selectedItemsSet);
203
+ let results = array.map((id) => {
204
+ if (hasPrimitiveItemsData) {
205
+ return id;
206
+ } else {
207
+ let item = itemsIdentityMap[id];
208
+ if (item) {
209
+ if (displayFieldName && item.hasOwnProperty(displayFieldName)) {
210
+ return item[displayFieldName];
211
+ }
212
+ }
213
+ }
214
+ });
215
+ return results;
216
+ });
217
+
218
+ let displayItemsTitle = $derived(displayItems.join(', '));
219
+
220
+ let displayText: string = $derived.by(() => {
221
+ let results: string[] = displayItems;
222
+ if (!showChip) {
223
+ if (results?.length) {
224
+ if (multiple) {
225
+ let res: string = results.join(', ');
226
+ if (displayItemsCount != null && displayItemsCount > 1) {
227
+ res = results.slice(0, displayItemsCount).join(', ');
228
+ if (results.length > displayItemsCount) {
229
+ res += `<span class="text-gray-400 px-2">+ ${results.length - displayItemsCount} </span>`;
230
+ }
231
+ }
232
+ return res;
233
+ } else {
234
+ return results[0] || '';
235
+ }
236
+ }
237
+ }
238
+
239
+ return '';
240
+ });
241
+
242
+ let preparedItems = $derived.by(() => {
243
+ return (items || []).map((item, index) => {
244
+ let res: any = {};
245
+ if (hasPrimitiveItemsData) {
246
+ res[identityFieldName] = item;
247
+ res[titleFieldName] = item;
248
+ res[searchFieldName] = item;
249
+ } else {
250
+ res = item;
251
+ }
252
+ return res;
253
+ });
254
+ });
255
+
256
+ let itemsIdentityMap: any = $derived.by(() => {
257
+ return preparedItems.reduce((acc, val) => {
258
+ acc[val[identityFieldName]] = val;
259
+ return acc;
260
+ }, {});
261
+ });
262
+
263
+ let filteredItems = $derived.by(() => {
264
+ if (searchText) {
265
+ return preparedItems.filter((item: any) => {
266
+ return (item[searchFieldName] || '').toLowerCase().indexOf(searchText) >= 0;
267
+ });
268
+ } else {
269
+ return [...preparedItems];
270
+ }
271
+ });
272
+
273
+ let inputFieldRef: any | null = $state(null);
274
+
275
+ export function focus() {
276
+ inputFieldRef?.focus();
277
+ }
278
+
279
+ function toggleDropdown() {
280
+ if (isPlaced) {
281
+ closeDropdown();
282
+ } else {
283
+ openDropdown();
284
+ }
285
+ }
286
+
287
+ function closeDropdown() {
288
+ searchText = '';
289
+ isPlaced = false;
290
+ focus();
291
+ }
292
+
293
+ function openDropdown() {
294
+ isPlaced = true;
295
+ }
296
+
297
+ function handleInputClick() {
298
+ toggleDropdown();
299
+ }
300
+
301
+ function handleBackdropClick() {
302
+ toggleDropdown();
303
+ }
304
+
305
+ function handleKeyDown(event: KeyboardEvent) {
306
+ if (event.key === 'Escape') {
307
+ closeDropdown();
308
+ } else if (event.key === 'Enter' || event.key === ' ') {
309
+ event.preventDefault(); // Prevent default action for spacebar to avoid scrolling
310
+ toggleDropdown();
311
+ } else if (/^[a-zA-Z0-9]$/.test(event.key)) {
312
+ searchFieldRef && searchFieldRef.focus();
313
+ } else if (event.key === 'Backspace' || event.key === 'Delete') {
314
+ event.preventDefault(); // Prevent default action for these keys if necessary
315
+ selectedItemsSet.clear();
316
+ value = null;
317
+ }
318
+ }
319
+
320
+ function handleDropdownKeyDown(event: KeyboardEvent) {
321
+ if (event.key === 'Escape') {
322
+ closeDropdown();
323
+ }
324
+ }
325
+
326
+ function handleSearch(value: string) {
327
+ searchText = value;
328
+ }
329
+
330
+ function handleItemClick(ev: MouseEvent, item: any, index: number) {
331
+ let id = item[identityFieldName];
332
+ if (multiple) {
333
+ if (selectedItemsSet.has(id)) {
334
+ selectedItemsSet.delete(id);
335
+ } else {
336
+ selectedItemsSet.add(id);
337
+ }
338
+ } else {
339
+ selectedItemsSet.clear();
340
+ selectedItemsSet.add(id);
341
+ }
342
+
343
+ items = [...(items || [])];
344
+
345
+ let array = Array.from(selectedItemsSet);
346
+ if (array.length) {
347
+ value = multiple ? array : array[0];
348
+ } else {
349
+ value = null;
350
+ }
351
+
352
+ if (!multiple) {
353
+ closeDropdown();
354
+ }
355
+
356
+ onChange && onChange(value);
357
+
358
+ // console.log('handleItemClick', selectedItemsSet, value);
359
+ }
270
360
  </script>
271
361
 
272
362
  {#snippet rightIcon()}