@warkypublic/svelix 0.1.14 → 0.1.15
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.
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
let popupWidth = $state(0);
|
|
91
91
|
let backdropZ = $state(1090);
|
|
92
92
|
let dropdownZ = $state(1100);
|
|
93
|
+
let pointerInteractingWithDropdown = $state(false);
|
|
93
94
|
// Plain variable — NOT $state to avoid deep proxy on the complex virtualizer object.
|
|
94
95
|
let rawVirtualizer: SvelteVirtualizer<
|
|
95
96
|
HTMLDivElement,
|
|
@@ -334,6 +335,13 @@
|
|
|
334
335
|
);
|
|
335
336
|
}
|
|
336
337
|
|
|
338
|
+
function markDropdownPointerInteraction() {
|
|
339
|
+
pointerInteractingWithDropdown = true;
|
|
340
|
+
setTimeout(() => {
|
|
341
|
+
pointerInteractingWithDropdown = false;
|
|
342
|
+
}, 0);
|
|
343
|
+
}
|
|
344
|
+
|
|
337
345
|
// Public API via bind:this
|
|
338
346
|
export function clear() {
|
|
339
347
|
onClear();
|
|
@@ -403,6 +411,7 @@
|
|
|
403
411
|
class="relative w-full"
|
|
404
412
|
bind:this={anchorEl}
|
|
405
413
|
onfocusout={(e) => {
|
|
414
|
+
if (pointerInteractingWithDropdown) return;
|
|
406
415
|
const currentTarget = e.currentTarget as HTMLElement;
|
|
407
416
|
const relatedTarget = e.relatedTarget as Node | null;
|
|
408
417
|
const insideDropdown = !!(relatedTarget && dropdownEl?.contains(relatedTarget));
|
|
@@ -452,6 +461,7 @@
|
|
|
452
461
|
: "fixed"} card bg-surface-50-950 shadow-lg border border-surface-300-700 overflow-hidden`}
|
|
453
462
|
role="listbox"
|
|
454
463
|
aria-label={label ?? "Options"}
|
|
464
|
+
onpointerdown={markDropdownPointerInteraction}
|
|
455
465
|
style:z-index={dropdownZ}
|
|
456
466
|
style:top={!disablePortal ? `${popupTop}px` : undefined}
|
|
457
467
|
style:left={!disablePortal ? `${popupLeft}px` : undefined}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import NativeSelectCtrl from '../FormerControllers/NativeSelectCtrl.svelte';
|
|
9
9
|
import TextAreaCtrl from '../FormerControllers/TextAreaCtrl.svelte';
|
|
10
10
|
import SwitchCtrl from '../FormerControllers/SwitchCtrl.svelte';
|
|
11
|
+
import Boxer from '../Boxer/Boxer.svelte';
|
|
11
12
|
|
|
12
13
|
interface UserForm {
|
|
13
14
|
id?: number;
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
age?: number;
|
|
19
20
|
role: string;
|
|
20
21
|
department: string;
|
|
22
|
+
skills: string[];
|
|
21
23
|
bio: string;
|
|
22
24
|
website: string;
|
|
23
25
|
emailNotifications: boolean;
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
age: undefined,
|
|
39
41
|
role: '',
|
|
40
42
|
department: '',
|
|
43
|
+
skills: [],
|
|
41
44
|
bio: '',
|
|
42
45
|
website: '',
|
|
43
46
|
emailNotifications: true,
|
|
@@ -53,6 +56,7 @@
|
|
|
53
56
|
age: 32,
|
|
54
57
|
role: 'admin',
|
|
55
58
|
department: 'engineering',
|
|
59
|
+
skills: ['typescript', 'svelte'],
|
|
56
60
|
bio: 'Senior software engineer with 10 years of experience building scalable systems.',
|
|
57
61
|
website: 'https://janesmith.dev',
|
|
58
62
|
emailNotifications: true,
|
|
@@ -73,6 +77,14 @@
|
|
|
73
77
|
{ label: 'Operations', value: 'operations' },
|
|
74
78
|
];
|
|
75
79
|
|
|
80
|
+
const skillOptions = [
|
|
81
|
+
{ label: 'Svelte', value: 'svelte' },
|
|
82
|
+
{ label: 'TypeScript', value: 'typescript' },
|
|
83
|
+
{ label: 'Node.js', value: 'nodejs' },
|
|
84
|
+
{ label: 'Testing', value: 'testing' },
|
|
85
|
+
{ label: 'UX', value: 'ux' },
|
|
86
|
+
];
|
|
87
|
+
|
|
76
88
|
let values = $state<UserForm>(request === 'insert' ? { ...emptyUser } : { ...filledUser });
|
|
77
89
|
let lastSaved = $state<UserForm | undefined>(undefined);
|
|
78
90
|
let opened = $state(false);
|
|
@@ -194,6 +206,25 @@
|
|
|
194
206
|
/>
|
|
195
207
|
</div>
|
|
196
208
|
|
|
209
|
+
<Boxer
|
|
210
|
+
label="Skills"
|
|
211
|
+
name="skills"
|
|
212
|
+
data={skillOptions}
|
|
213
|
+
dataSource="local"
|
|
214
|
+
disablePortal
|
|
215
|
+
multiSelect
|
|
216
|
+
searchable
|
|
217
|
+
clearable
|
|
218
|
+
placeholder="Search skills..."
|
|
219
|
+
disabled={isReadonly}
|
|
220
|
+
value={state.values?.skills ?? []}
|
|
221
|
+
onChange={(v) =>
|
|
222
|
+
state.setState('values', {
|
|
223
|
+
...state.values,
|
|
224
|
+
skills: Array.isArray(v) ? v : v ? [v] : [],
|
|
225
|
+
})}
|
|
226
|
+
/>
|
|
227
|
+
|
|
197
228
|
<TextAreaCtrl
|
|
198
229
|
label="Bio"
|
|
199
230
|
name="bio"
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import NativeSelectCtrl from '../FormerControllers/NativeSelectCtrl.svelte';
|
|
9
9
|
import TextAreaCtrl from '../FormerControllers/TextAreaCtrl.svelte';
|
|
10
10
|
import SwitchCtrl from '../FormerControllers/SwitchCtrl.svelte';
|
|
11
|
+
import Boxer from '../Boxer/Boxer.svelte';
|
|
11
12
|
|
|
12
13
|
interface UserForm {
|
|
13
14
|
id?: number;
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
age?: number;
|
|
19
20
|
role: string;
|
|
20
21
|
department: string;
|
|
22
|
+
skills: string[];
|
|
21
23
|
bio: string;
|
|
22
24
|
website: string;
|
|
23
25
|
emailNotifications: boolean;
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
age: undefined,
|
|
39
41
|
role: '',
|
|
40
42
|
department: '',
|
|
43
|
+
skills: [],
|
|
41
44
|
bio: '',
|
|
42
45
|
website: '',
|
|
43
46
|
emailNotifications: true,
|
|
@@ -53,6 +56,7 @@
|
|
|
53
56
|
age: 32,
|
|
54
57
|
role: 'admin',
|
|
55
58
|
department: 'engineering',
|
|
59
|
+
skills: ['typescript', 'svelte'],
|
|
56
60
|
bio: 'Senior software engineer with 10 years of experience building scalable systems.',
|
|
57
61
|
website: 'https://janesmith.dev',
|
|
58
62
|
emailNotifications: true,
|
|
@@ -73,6 +77,14 @@
|
|
|
73
77
|
{ label: 'Operations', value: 'operations' },
|
|
74
78
|
];
|
|
75
79
|
|
|
80
|
+
const skillOptions = [
|
|
81
|
+
{ label: 'Svelte', value: 'svelte' },
|
|
82
|
+
{ label: 'TypeScript', value: 'typescript' },
|
|
83
|
+
{ label: 'Node.js', value: 'nodejs' },
|
|
84
|
+
{ label: 'Testing', value: 'testing' },
|
|
85
|
+
{ label: 'UX', value: 'ux' },
|
|
86
|
+
];
|
|
87
|
+
|
|
76
88
|
let values = $state<UserForm>(request === 'insert' ? { ...emptyUser } : { ...filledUser });
|
|
77
89
|
let lastSaved = $state<UserForm | undefined>(undefined);
|
|
78
90
|
let opened = $state(false);
|
|
@@ -194,6 +206,24 @@
|
|
|
194
206
|
/>
|
|
195
207
|
</div>
|
|
196
208
|
|
|
209
|
+
<Boxer
|
|
210
|
+
label="Skills"
|
|
211
|
+
name="skills"
|
|
212
|
+
data={skillOptions}
|
|
213
|
+
dataSource="local"
|
|
214
|
+
multiSelect
|
|
215
|
+
searchable
|
|
216
|
+
clearable
|
|
217
|
+
placeholder="Search skills..."
|
|
218
|
+
disabled={isReadonly}
|
|
219
|
+
value={state.values?.skills ?? []}
|
|
220
|
+
onChange={(v) =>
|
|
221
|
+
state.setState('values', {
|
|
222
|
+
...state.values,
|
|
223
|
+
skills: Array.isArray(v) ? v : v ? [v] : [],
|
|
224
|
+
})}
|
|
225
|
+
/>
|
|
226
|
+
|
|
197
227
|
<TextAreaCtrl
|
|
198
228
|
label="Bio"
|
|
199
229
|
name="bio"
|