@hkdigital/lib-sveltekit 0.1.90 → 0.1.92
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.
- package/dist/components/drag-drop/DropZone.svelte +168 -28
- package/dist/components/drag-drop/DropZone.svelte.d.ts +6 -4
- package/dist/components/drag-drop/DropZoneArea.svelte +119 -0
- package/dist/components/drag-drop/DropZoneArea.svelte.d.ts +90 -0
- package/dist/components/drag-drop/DropZoneList.svelte +125 -0
- package/dist/components/drag-drop/DropZoneList.svelte.d.ts +92 -0
- package/dist/components/drag-drop/index.d.ts +2 -0
- package/dist/components/drag-drop/index.js +2 -0
- package/dist/themes/hkdev/components/drag-drop/drop-zone.css +0 -1
- package/dist/util/design-system/css/root-design-vars.js +5 -3
- package/package.json +1 -1
@@ -24,8 +24,9 @@
|
|
24
24
|
* accepts?: (item: any) => boolean,
|
25
25
|
* base?: string,
|
26
26
|
* classes?: string,
|
27
|
-
*
|
28
|
-
*
|
27
|
+
* minHeight?: string,
|
28
|
+
* maxHeight?: string,
|
29
|
+
* heightMode?: 'fixed' | 'flexible' | 'fill',
|
29
30
|
* children?: import('svelte').Snippet,
|
30
31
|
* contextKey?: import('../../typedef').ContextKey,
|
31
32
|
* dropPreviewSnippet?: import('svelte').Snippet<[DragData]>,
|
@@ -67,8 +68,9 @@
|
|
67
68
|
accepts = () => true,
|
68
69
|
base = '',
|
69
70
|
classes = '',
|
70
|
-
|
71
|
-
|
71
|
+
minHeight = '',
|
72
|
+
maxHeight = '',
|
73
|
+
heightMode = 'fixed',
|
72
74
|
children,
|
73
75
|
contextKey,
|
74
76
|
dropPreviewSnippet,
|
@@ -83,15 +85,24 @@
|
|
83
85
|
...attrs
|
84
86
|
} = $props();
|
85
87
|
|
88
|
+
// let debugEvents = [];
|
89
|
+
|
86
90
|
const dragState = createOrGetDragState(contextKey);
|
87
91
|
|
88
92
|
let currentState = $state(READY);
|
89
|
-
let dropZoneElement; // Reference to the drop zone DOM element
|
90
93
|
|
91
|
-
|
92
|
-
|
94
|
+
let dropZoneElement = $state(null);
|
95
|
+
|
96
|
+
// $effect( () => {
|
97
|
+
// if(dropZoneElement) {
|
98
|
+
// console.debug(dropZoneElement);
|
99
|
+
// }
|
100
|
+
// } )
|
101
|
+
|
93
102
|
let isCurrentlyOver = $state(false);
|
94
103
|
|
104
|
+
// $inspect({ zone, isCurrentlyOver });
|
105
|
+
|
95
106
|
// Cleanup function
|
96
107
|
let cleanup;
|
97
108
|
|
@@ -104,13 +115,41 @@
|
|
104
115
|
|
105
116
|
document.addEventListener('dragend', handleGlobalDragEnd);
|
106
117
|
|
118
|
+
// console.debug(`DropZone ${zone} mounted`);
|
119
|
+
|
107
120
|
cleanup = () => {
|
108
121
|
document.removeEventListener('dragend', handleGlobalDragEnd);
|
109
122
|
};
|
123
|
+
|
124
|
+
return cleanup;
|
110
125
|
});
|
111
126
|
|
112
|
-
|
113
|
-
|
127
|
+
// Computed height classes based on mode
|
128
|
+
let heightClasses = $derived.by(() => {
|
129
|
+
const classes = [];
|
130
|
+
|
131
|
+
switch (heightMode) {
|
132
|
+
case 'flexible':
|
133
|
+
// Flexible height with optional min/max constraints
|
134
|
+
if (minHeight) classes.push(minHeight);
|
135
|
+
else classes.push('min-h-[100px]'); // Default minimum
|
136
|
+
if (maxHeight) {
|
137
|
+
classes.push(maxHeight);
|
138
|
+
classes.push('overflow-y-auto');
|
139
|
+
}
|
140
|
+
break;
|
141
|
+
case 'fill':
|
142
|
+
// Fill the parent container
|
143
|
+
classes.push('h-full');
|
144
|
+
break;
|
145
|
+
case 'fixed':
|
146
|
+
default:
|
147
|
+
// Fixed height (default to min-height if not filling)
|
148
|
+
classes.push('h-min');
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
|
152
|
+
return classes.join(' ');
|
114
153
|
});
|
115
154
|
|
116
155
|
// Computed state object for CSS classes
|
@@ -185,13 +224,46 @@
|
|
185
224
|
* @param {DragEvent} event
|
186
225
|
*/
|
187
226
|
function handleDragEnter(event) {
|
227
|
+
// debugEvents.push({
|
228
|
+
// event: 'dragEnter',
|
229
|
+
// target: event.target,
|
230
|
+
// currentTarget: event.currentTarget,
|
231
|
+
// isCurrentlyOver
|
232
|
+
// });
|
233
|
+
|
234
|
+
// console.log('dragEnter:', { zone });
|
235
|
+
|
188
236
|
// Prevent default to allow drop
|
189
237
|
event.preventDefault();
|
190
238
|
|
191
|
-
//
|
192
|
-
|
239
|
+
// Check if mouse is actually within drop zone boundaries
|
240
|
+
const rect = dropZoneElement.getBoundingClientRect();
|
241
|
+
const x = event.clientX;
|
242
|
+
const y = event.clientY;
|
243
|
+
|
244
|
+
const isWithinBounds =
|
245
|
+
x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
246
|
+
|
247
|
+
if (!isWithinBounds) {
|
248
|
+
// Don't enter if mouse is outside bounds
|
249
|
+
// console.debug('Mouse outside bounds', {
|
250
|
+
// x,
|
251
|
+
// y,
|
252
|
+
// top: rect.top,
|
253
|
+
// bottom: rect.bottom,
|
254
|
+
// left: rect.left,
|
255
|
+
// right: rect.right
|
256
|
+
// });
|
257
|
+
|
258
|
+
dropZoneElement.style.border = "solid 10px purple";
|
259
|
+
return;
|
260
|
+
}
|
261
|
+
|
262
|
+
if (isCurrentlyOver) {
|
263
|
+
// console.debug('Already over');
|
264
|
+
return;
|
265
|
+
}
|
193
266
|
|
194
|
-
// Now we're over this drop zone
|
195
267
|
isCurrentlyOver = true;
|
196
268
|
|
197
269
|
// Get the drag data
|
@@ -213,11 +285,56 @@
|
|
213
285
|
* @param {DragEvent} event
|
214
286
|
*/
|
215
287
|
function handleDragOver(event) {
|
288
|
+
// console.log('dragOver', {zone}, event );
|
289
|
+
// console.log('dragOver', {
|
290
|
+
// zone,
|
291
|
+
// eventTarget: event.target.closest('[data-zone]')?.dataset?.zone,
|
292
|
+
// currentTarget: event.currentTarget.dataset?.zone,
|
293
|
+
// path: event.composedPath().map(el => el.dataset?.zone || el.tagName)
|
294
|
+
// });
|
295
|
+
|
296
|
+
// debugEvents.push({
|
297
|
+
// event: 'handleDragOver',
|
298
|
+
// target: event.target,
|
299
|
+
// currentTarget: event.currentTarget,
|
300
|
+
// isCurrentlyOver,
|
301
|
+
// contains: dropZoneElement.contains(event.target),
|
302
|
+
// mouseX: event.clientX,
|
303
|
+
// mouseY: event.clientY,
|
304
|
+
// dropZoneBounds: dropZoneElement.getBoundingClientRect()
|
305
|
+
// });
|
306
|
+
|
307
|
+
// console.log('dragOver:', {
|
308
|
+
// target: event.target,
|
309
|
+
// currentTarget: event.currentTarget,
|
310
|
+
// isCurrentlyOver,
|
311
|
+
// contains: dropZoneElement.contains(event.target)
|
312
|
+
// });
|
313
|
+
|
314
|
+
// Check if mouse is actually within drop zone boundaries
|
315
|
+
const rect = dropZoneElement.getBoundingClientRect();
|
316
|
+
const x = event.clientX;
|
317
|
+
const y = event.clientY;
|
318
|
+
|
319
|
+
const isWithinBounds =
|
320
|
+
x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
321
|
+
|
322
|
+
if (!isWithinBounds) {
|
323
|
+
// Mouse is outside bounds, treat as leave
|
324
|
+
if (isCurrentlyOver) {
|
325
|
+
isCurrentlyOver = false;
|
326
|
+
currentState = READY;
|
327
|
+
onDragLeave?.({ event, zone });
|
328
|
+
}
|
329
|
+
return;
|
330
|
+
}
|
331
|
+
|
332
|
+
// console.log('dragOver (accepted)', {zone});
|
333
|
+
|
216
334
|
// Prevent default to allow drop
|
217
335
|
event.preventDefault();
|
218
336
|
|
219
|
-
// If we're not currently over this drop zone
|
220
|
-
// treat it as an enter event
|
337
|
+
// If we're not currently over this drop zone, treat it as an enter
|
221
338
|
if (!isCurrentlyOver) {
|
222
339
|
handleDragEnter(event);
|
223
340
|
return;
|
@@ -247,6 +364,23 @@
|
|
247
364
|
* @param {DragEvent} event
|
248
365
|
*/
|
249
366
|
function handleDragLeave(event) {
|
367
|
+
// debugEvents.push({
|
368
|
+
// event: 'handleDragLeave',
|
369
|
+
// target: event.target,
|
370
|
+
// currentTarget: event.currentTarget,
|
371
|
+
// relatedTarget: event.relatedTarget,
|
372
|
+
// isCurrentlyOver,
|
373
|
+
// isActuallyLeaving: !event.relatedTarget || !dropZoneElement.contains(event.relatedTarget)
|
374
|
+
// });
|
375
|
+
|
376
|
+
// console.log('dragLeave:', {
|
377
|
+
// target: event.target,
|
378
|
+
// currentTarget: event.currentTarget,
|
379
|
+
// relatedTarget: event.relatedTarget,
|
380
|
+
// isCurrentlyOver,
|
381
|
+
// isActuallyLeaving: !event.relatedTarget || !dropZoneElement.contains(event.relatedTarget)
|
382
|
+
// });
|
383
|
+
|
250
384
|
// We need to check if we're actually leaving the drop zone or just
|
251
385
|
// entering a child element within the drop zone
|
252
386
|
|
@@ -269,9 +403,16 @@
|
|
269
403
|
* @param {DragEvent} event
|
270
404
|
*/
|
271
405
|
function handleDrop(event) {
|
406
|
+
// console.debug( JSON.stringify(debugEvents, null, 2));
|
407
|
+
|
272
408
|
// Prevent default browser actions
|
273
409
|
event.preventDefault();
|
274
410
|
|
411
|
+
if (!isCurrentlyOver) {
|
412
|
+
// Prevent drop if not currently over
|
413
|
+
return;
|
414
|
+
}
|
415
|
+
|
275
416
|
// Reset our tracking state
|
276
417
|
isCurrentlyOver = false;
|
277
418
|
|
@@ -306,15 +447,9 @@
|
|
306
447
|
const dropZoneRect = dropZoneElement.getBoundingClientRect();
|
307
448
|
|
308
449
|
// Calculate position with both dragData.offsetX/Y adjustment and border adjustment
|
309
|
-
const dropOffsetX =
|
310
|
-
event.clientX -
|
311
|
-
dropZoneRect.left -
|
312
|
-
borderLeftWidth;
|
450
|
+
const dropOffsetX = event.clientX - dropZoneRect.left - borderLeftWidth;
|
313
451
|
|
314
|
-
const dropOffsetY =
|
315
|
-
event.clientY -
|
316
|
-
dropZoneRect.top -
|
317
|
-
borderTopWidth;
|
452
|
+
const dropOffsetY = event.clientY - dropZoneRect.top - borderTopWidth;
|
318
453
|
|
319
454
|
const x = dropOffsetX - (dragData.offsetX ?? 0);
|
320
455
|
const y = dropOffsetY - (dragData.offsetY ?? 0);
|
@@ -353,8 +488,9 @@
|
|
353
488
|
currentState = READY;
|
354
489
|
}
|
355
490
|
}
|
356
|
-
</script>
|
357
491
|
|
492
|
+
// console.log(`DropZone ${zone} script run`);
|
493
|
+
</script>
|
358
494
|
<div
|
359
495
|
data-component="drop-zone"
|
360
496
|
bind:this={dropZoneElement}
|
@@ -362,13 +498,17 @@
|
|
362
498
|
ondragover={handleDragOver}
|
363
499
|
ondragleave={handleDragLeave}
|
364
500
|
ondrop={handleDrop}
|
365
|
-
class="{base} {
|
501
|
+
class="{base} {heightClasses} {classes} {stateClasses}"
|
366
502
|
data-zone={zone}
|
367
503
|
{...attrs}
|
368
504
|
>
|
369
|
-
<GridLayers heightFrom={
|
505
|
+
<GridLayers heightFrom={heightMode === 'flexible' ? 'content' : null}>
|
370
506
|
{#if children}
|
371
|
-
<div
|
507
|
+
<div
|
508
|
+
data-layer="content"
|
509
|
+
class:relative={heightMode === 'flexible'}
|
510
|
+
class:w-full={heightMode === 'flexible'}
|
511
|
+
>
|
372
512
|
{@render children()}
|
373
513
|
</div>
|
374
514
|
{/if}
|
@@ -382,7 +522,7 @@
|
|
382
522
|
</div>
|
383
523
|
|
384
524
|
<style>
|
385
|
-
[data-layer='content']:not(.
|
525
|
+
[data-layer='content']:not(.relative) {
|
386
526
|
position: absolute;
|
387
527
|
left: 0;
|
388
528
|
right: 0;
|
@@ -390,7 +530,7 @@
|
|
390
530
|
bottom: 0;
|
391
531
|
}
|
392
532
|
|
393
|
-
[data-layer='content'].
|
533
|
+
[data-layer='content'].relative {
|
394
534
|
position: relative;
|
395
535
|
width: 100%;
|
396
536
|
}
|
@@ -9,8 +9,9 @@ type DropZone = {
|
|
9
9
|
accepts?: (item: any) => boolean;
|
10
10
|
base?: string;
|
11
11
|
classes?: string;
|
12
|
-
|
13
|
-
|
12
|
+
minHeight?: string;
|
13
|
+
maxHeight?: string;
|
14
|
+
heightMode?: "fill" | "fixed" | "flexible";
|
14
15
|
children?: Snippet<[]>;
|
15
16
|
contextKey?: ContextKey;
|
16
17
|
dropPreviewSnippet?: Snippet<[DragData]>;
|
@@ -52,8 +53,9 @@ declare const DropZone: import("svelte").Component<{
|
|
52
53
|
accepts?: (item: any) => boolean;
|
53
54
|
base?: string;
|
54
55
|
classes?: string;
|
55
|
-
|
56
|
-
|
56
|
+
minHeight?: string;
|
57
|
+
maxHeight?: string;
|
58
|
+
heightMode?: "fixed" | "flexible" | "fill";
|
57
59
|
children?: import("svelte").Snippet;
|
58
60
|
contextKey?: import("../../typedef").ContextKey;
|
59
61
|
dropPreviewSnippet?: import("svelte").Snippet<[import("../../typedef").DragData]>;
|
@@ -0,0 +1,119 @@
|
|
1
|
+
<script>
|
2
|
+
import { DropZone } from './index.js';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @type {{
|
6
|
+
* zone?: string,
|
7
|
+
* group?: string,
|
8
|
+
* disabled?: boolean,
|
9
|
+
* accepts?: (item: any) => boolean,
|
10
|
+
* fillContainer?: boolean,
|
11
|
+
* aspectRatio?: string,
|
12
|
+
* overflow?: 'auto' | 'hidden' | 'visible' | 'scroll',
|
13
|
+
* base?: string,
|
14
|
+
* classes?: string,
|
15
|
+
* children?: import('svelte').Snippet,
|
16
|
+
* contextKey?: import('../../typedef').ContextKey,
|
17
|
+
* dropPreviewSnippet?: import('svelte').Snippet<[import('../../typedef').DragData]>,
|
18
|
+
* isDragOver?: boolean,
|
19
|
+
* canDrop?: boolean,
|
20
|
+
* onDragEnter?: (detail: {
|
21
|
+
* event: DragEvent,
|
22
|
+
* zone: string,
|
23
|
+
* canDrop: boolean
|
24
|
+
* }) => void,
|
25
|
+
* onDragOver?: (detail: {
|
26
|
+
* event: DragEvent,
|
27
|
+
* zone: string
|
28
|
+
* }) => void,
|
29
|
+
* onDragLeave?: (detail: {
|
30
|
+
* event: DragEvent,
|
31
|
+
* zone: string
|
32
|
+
* }) => void,
|
33
|
+
* onDrop?: (detail: import('../../typedef').DropData) => any | Promise<any>,
|
34
|
+
* onDropStart?: (detail: {
|
35
|
+
* event: DragEvent,
|
36
|
+
* zone: string,
|
37
|
+
* data: any
|
38
|
+
* }) => void,
|
39
|
+
* onDropEnd?: (detail: {
|
40
|
+
* event: DragEvent,
|
41
|
+
* zone: string,
|
42
|
+
* data: any,
|
43
|
+
* success: boolean,
|
44
|
+
* error?: Error
|
45
|
+
* }) => void,
|
46
|
+
* [key: string]: any
|
47
|
+
* }}
|
48
|
+
*/
|
49
|
+
let {
|
50
|
+
zone = 'default',
|
51
|
+
group = 'default',
|
52
|
+
disabled = false,
|
53
|
+
accepts = () => true,
|
54
|
+
fillContainer = true,
|
55
|
+
aspectRatio = '',
|
56
|
+
overflow = 'hidden',
|
57
|
+
base = '',
|
58
|
+
classes = '',
|
59
|
+
children,
|
60
|
+
contextKey,
|
61
|
+
dropPreviewSnippet,
|
62
|
+
isDragOver = $bindable(false),
|
63
|
+
canDrop = $bindable(false),
|
64
|
+
onDragEnter,
|
65
|
+
onDragOver,
|
66
|
+
onDragLeave,
|
67
|
+
onDrop,
|
68
|
+
onDropStart,
|
69
|
+
onDropEnd,
|
70
|
+
...attrs
|
71
|
+
} = $props();
|
72
|
+
|
73
|
+
// Build overflow classes based on prop
|
74
|
+
let overflowClasses = $derived.by(() => {
|
75
|
+
switch (overflow) {
|
76
|
+
case 'auto':
|
77
|
+
return 'overflow-auto';
|
78
|
+
case 'scroll':
|
79
|
+
return 'overflow-scroll';
|
80
|
+
case 'visible':
|
81
|
+
return 'overflow-visible';
|
82
|
+
case 'hidden':
|
83
|
+
default:
|
84
|
+
return 'overflow-hidden';
|
85
|
+
}
|
86
|
+
});
|
87
|
+
|
88
|
+
// Combine all classes for the drop zone
|
89
|
+
let combinedClasses = $derived(
|
90
|
+
`${overflowClasses} ${aspectRatio} ${classes}`.trim()
|
91
|
+
);
|
92
|
+
</script>
|
93
|
+
|
94
|
+
<DropZone
|
95
|
+
data-component="drop-zone"
|
96
|
+
data-type="area"
|
97
|
+
{zone}
|
98
|
+
{group}
|
99
|
+
{disabled}
|
100
|
+
{accepts}
|
101
|
+
heightMode={fillContainer ? 'fill' : 'fixed'}
|
102
|
+
{base}
|
103
|
+
classes={combinedClasses}
|
104
|
+
{contextKey}
|
105
|
+
{dropPreviewSnippet}
|
106
|
+
bind:isDragOver
|
107
|
+
bind:canDrop
|
108
|
+
{onDragEnter}
|
109
|
+
{onDragOver}
|
110
|
+
{onDragLeave}
|
111
|
+
{onDrop}
|
112
|
+
{onDropStart}
|
113
|
+
{onDropEnd}
|
114
|
+
{...attrs}
|
115
|
+
>
|
116
|
+
{#if children}
|
117
|
+
{@render children()}
|
118
|
+
{/if}
|
119
|
+
</DropZone>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
export default DropZoneArea;
|
2
|
+
type DropZoneArea = {
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
4
|
+
$set?(props: Partial<{
|
5
|
+
[key: string]: any;
|
6
|
+
zone?: string;
|
7
|
+
group?: string;
|
8
|
+
disabled?: boolean;
|
9
|
+
accepts?: (item: any) => boolean;
|
10
|
+
fillContainer?: boolean;
|
11
|
+
aspectRatio?: string;
|
12
|
+
overflow?: "scroll" | "auto" | "hidden" | "visible";
|
13
|
+
base?: string;
|
14
|
+
classes?: string;
|
15
|
+
children?: Snippet<[]>;
|
16
|
+
contextKey?: ContextKey;
|
17
|
+
dropPreviewSnippet?: Snippet<[DragData]>;
|
18
|
+
isDragOver?: boolean;
|
19
|
+
canDrop?: boolean;
|
20
|
+
onDragEnter?: (detail: {
|
21
|
+
event: DragEvent;
|
22
|
+
zone: string;
|
23
|
+
canDrop: boolean;
|
24
|
+
}) => void;
|
25
|
+
onDragOver?: (detail: {
|
26
|
+
event: DragEvent;
|
27
|
+
zone: string;
|
28
|
+
}) => void;
|
29
|
+
onDragLeave?: (detail: {
|
30
|
+
event: DragEvent;
|
31
|
+
zone: string;
|
32
|
+
}) => void;
|
33
|
+
onDrop?: (detail: DropData) => any;
|
34
|
+
onDropStart?: (detail: {
|
35
|
+
event: DragEvent;
|
36
|
+
zone: string;
|
37
|
+
data: any;
|
38
|
+
}) => void;
|
39
|
+
onDropEnd?: (detail: {
|
40
|
+
event: DragEvent;
|
41
|
+
zone: string;
|
42
|
+
data: any;
|
43
|
+
success: boolean;
|
44
|
+
error?: Error;
|
45
|
+
}) => void;
|
46
|
+
}>): void;
|
47
|
+
};
|
48
|
+
declare const DropZoneArea: import("svelte").Component<{
|
49
|
+
[key: string]: any;
|
50
|
+
zone?: string;
|
51
|
+
group?: string;
|
52
|
+
disabled?: boolean;
|
53
|
+
accepts?: (item: any) => boolean;
|
54
|
+
fillContainer?: boolean;
|
55
|
+
aspectRatio?: string;
|
56
|
+
overflow?: "auto" | "hidden" | "visible" | "scroll";
|
57
|
+
base?: string;
|
58
|
+
classes?: string;
|
59
|
+
children?: import("svelte").Snippet;
|
60
|
+
contextKey?: import("../../typedef").ContextKey;
|
61
|
+
dropPreviewSnippet?: import("svelte").Snippet<[import("../../typedef").DragData]>;
|
62
|
+
isDragOver?: boolean;
|
63
|
+
canDrop?: boolean;
|
64
|
+
onDragEnter?: (detail: {
|
65
|
+
event: DragEvent;
|
66
|
+
zone: string;
|
67
|
+
canDrop: boolean;
|
68
|
+
}) => void;
|
69
|
+
onDragOver?: (detail: {
|
70
|
+
event: DragEvent;
|
71
|
+
zone: string;
|
72
|
+
}) => void;
|
73
|
+
onDragLeave?: (detail: {
|
74
|
+
event: DragEvent;
|
75
|
+
zone: string;
|
76
|
+
}) => void;
|
77
|
+
onDrop?: (detail: import("../../typedef").DropData) => any | Promise<any>;
|
78
|
+
onDropStart?: (detail: {
|
79
|
+
event: DragEvent;
|
80
|
+
zone: string;
|
81
|
+
data: any;
|
82
|
+
}) => void;
|
83
|
+
onDropEnd?: (detail: {
|
84
|
+
event: DragEvent;
|
85
|
+
zone: string;
|
86
|
+
data: any;
|
87
|
+
success: boolean;
|
88
|
+
error?: Error;
|
89
|
+
}) => void;
|
90
|
+
}, {}, "isDragOver" | "canDrop">;
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<script>
|
2
|
+
import { DropZone } from './index.js';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @type {{
|
6
|
+
* zone?: string,
|
7
|
+
* group?: string,
|
8
|
+
* disabled?: boolean,
|
9
|
+
* accepts?: (item: any) => boolean,
|
10
|
+
* minHeight?: string,
|
11
|
+
* maxHeight?: string,
|
12
|
+
* gap?: string,
|
13
|
+
* direction?: 'vertical' | 'horizontal',
|
14
|
+
* base?: string,
|
15
|
+
* classes?: string,
|
16
|
+
* children?: import('svelte').Snippet,
|
17
|
+
* contextKey?: import('../../typedef').ContextKey,
|
18
|
+
* dropPreviewSnippet?: import('svelte').Snippet<[import('../../typedef').DragData]>,
|
19
|
+
* isDragOver?: boolean,
|
20
|
+
* canDrop?: boolean,
|
21
|
+
* onDragEnter?: (detail: {
|
22
|
+
* event: DragEvent,
|
23
|
+
* zone: string,
|
24
|
+
* canDrop: boolean
|
25
|
+
* }) => void,
|
26
|
+
* onDragOver?: (detail: {
|
27
|
+
* event: DragEvent,
|
28
|
+
* zone: string
|
29
|
+
* }) => void,
|
30
|
+
* onDragLeave?: (detail: {
|
31
|
+
* event: DragEvent,
|
32
|
+
* zone: string
|
33
|
+
* }) => void,
|
34
|
+
* onDrop?: (detail: import('../../typedef').DropData) => any | Promise<any>,
|
35
|
+
* onDropStart?: (detail: {
|
36
|
+
* event: DragEvent,
|
37
|
+
* zone: string,
|
38
|
+
* data: any
|
39
|
+
* }) => void,
|
40
|
+
* onDropEnd?: (detail: {
|
41
|
+
* event: DragEvent,
|
42
|
+
* zone: string,
|
43
|
+
* data: any,
|
44
|
+
* success: boolean,
|
45
|
+
* error?: Error
|
46
|
+
* }) => void,
|
47
|
+
* [key: string]: any
|
48
|
+
* }}
|
49
|
+
*/
|
50
|
+
let {
|
51
|
+
zone = 'default',
|
52
|
+
group = 'default',
|
53
|
+
disabled = false,
|
54
|
+
accepts = () => true,
|
55
|
+
minHeight = 'min-h-[200px]',
|
56
|
+
maxHeight = '',
|
57
|
+
gap = 'gap-2',
|
58
|
+
direction = 'vertical',
|
59
|
+
base = '',
|
60
|
+
classes = '',
|
61
|
+
children,
|
62
|
+
contextKey,
|
63
|
+
dropPreviewSnippet,
|
64
|
+
isDragOver = $bindable(false),
|
65
|
+
canDrop = $bindable(false),
|
66
|
+
onDragEnter,
|
67
|
+
onDragOver,
|
68
|
+
onDragLeave,
|
69
|
+
onDrop,
|
70
|
+
onDropStart,
|
71
|
+
onDropEnd,
|
72
|
+
...attrs
|
73
|
+
} = $props();
|
74
|
+
|
75
|
+
// Build flex layout classes based on direction
|
76
|
+
let layoutClasses = $derived.by(() => {
|
77
|
+
const layoutParts = ['flex'];
|
78
|
+
|
79
|
+
if (direction === 'vertical') {
|
80
|
+
layoutParts.push('flex-col');
|
81
|
+
} else {
|
82
|
+
layoutParts.push('flex-row', 'flex-wrap');
|
83
|
+
}
|
84
|
+
|
85
|
+
if (gap) {
|
86
|
+
layoutParts.push(gap);
|
87
|
+
}
|
88
|
+
|
89
|
+
return layoutParts.join(' ');
|
90
|
+
});
|
91
|
+
|
92
|
+
// Combine all classes for the drop zone
|
93
|
+
let combinedClasses = $derived(
|
94
|
+
`${layoutClasses} ${classes}`.trim()
|
95
|
+
);
|
96
|
+
</script>
|
97
|
+
|
98
|
+
<DropZone
|
99
|
+
data-component="drop-zone"
|
100
|
+
data-type="list"
|
101
|
+
{zone}
|
102
|
+
{group}
|
103
|
+
{disabled}
|
104
|
+
{accepts}
|
105
|
+
{minHeight}
|
106
|
+
{maxHeight}
|
107
|
+
heightMode="flexible"
|
108
|
+
{base}
|
109
|
+
classes={combinedClasses}
|
110
|
+
{contextKey}
|
111
|
+
{dropPreviewSnippet}
|
112
|
+
bind:isDragOver
|
113
|
+
bind:canDrop
|
114
|
+
{onDragEnter}
|
115
|
+
{onDragOver}
|
116
|
+
{onDragLeave}
|
117
|
+
{onDrop}
|
118
|
+
{onDropStart}
|
119
|
+
{onDropEnd}
|
120
|
+
{...attrs}
|
121
|
+
>
|
122
|
+
{#if children}
|
123
|
+
{@render children()}
|
124
|
+
{/if}
|
125
|
+
</DropZone>
|
@@ -0,0 +1,92 @@
|
|
1
|
+
export default DropZoneList;
|
2
|
+
type DropZoneList = {
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
4
|
+
$set?(props: Partial<{
|
5
|
+
[key: string]: any;
|
6
|
+
zone?: string;
|
7
|
+
group?: string;
|
8
|
+
disabled?: boolean;
|
9
|
+
accepts?: (item: any) => boolean;
|
10
|
+
minHeight?: string;
|
11
|
+
maxHeight?: string;
|
12
|
+
gap?: string;
|
13
|
+
direction?: "vertical" | "horizontal";
|
14
|
+
base?: string;
|
15
|
+
classes?: string;
|
16
|
+
children?: Snippet<[]>;
|
17
|
+
contextKey?: ContextKey;
|
18
|
+
dropPreviewSnippet?: Snippet<[DragData]>;
|
19
|
+
isDragOver?: boolean;
|
20
|
+
canDrop?: boolean;
|
21
|
+
onDragEnter?: (detail: {
|
22
|
+
event: DragEvent;
|
23
|
+
zone: string;
|
24
|
+
canDrop: boolean;
|
25
|
+
}) => void;
|
26
|
+
onDragOver?: (detail: {
|
27
|
+
event: DragEvent;
|
28
|
+
zone: string;
|
29
|
+
}) => void;
|
30
|
+
onDragLeave?: (detail: {
|
31
|
+
event: DragEvent;
|
32
|
+
zone: string;
|
33
|
+
}) => void;
|
34
|
+
onDrop?: (detail: DropData) => any;
|
35
|
+
onDropStart?: (detail: {
|
36
|
+
event: DragEvent;
|
37
|
+
zone: string;
|
38
|
+
data: any;
|
39
|
+
}) => void;
|
40
|
+
onDropEnd?: (detail: {
|
41
|
+
event: DragEvent;
|
42
|
+
zone: string;
|
43
|
+
data: any;
|
44
|
+
success: boolean;
|
45
|
+
error?: Error;
|
46
|
+
}) => void;
|
47
|
+
}>): void;
|
48
|
+
};
|
49
|
+
declare const DropZoneList: import("svelte").Component<{
|
50
|
+
[key: string]: any;
|
51
|
+
zone?: string;
|
52
|
+
group?: string;
|
53
|
+
disabled?: boolean;
|
54
|
+
accepts?: (item: any) => boolean;
|
55
|
+
minHeight?: string;
|
56
|
+
maxHeight?: string;
|
57
|
+
gap?: string;
|
58
|
+
direction?: "vertical" | "horizontal";
|
59
|
+
base?: string;
|
60
|
+
classes?: string;
|
61
|
+
children?: import("svelte").Snippet;
|
62
|
+
contextKey?: import("../../typedef").ContextKey;
|
63
|
+
dropPreviewSnippet?: import("svelte").Snippet<[import("../../typedef").DragData]>;
|
64
|
+
isDragOver?: boolean;
|
65
|
+
canDrop?: boolean;
|
66
|
+
onDragEnter?: (detail: {
|
67
|
+
event: DragEvent;
|
68
|
+
zone: string;
|
69
|
+
canDrop: boolean;
|
70
|
+
}) => void;
|
71
|
+
onDragOver?: (detail: {
|
72
|
+
event: DragEvent;
|
73
|
+
zone: string;
|
74
|
+
}) => void;
|
75
|
+
onDragLeave?: (detail: {
|
76
|
+
event: DragEvent;
|
77
|
+
zone: string;
|
78
|
+
}) => void;
|
79
|
+
onDrop?: (detail: import("../../typedef").DropData) => any | Promise<any>;
|
80
|
+
onDropStart?: (detail: {
|
81
|
+
event: DragEvent;
|
82
|
+
zone: string;
|
83
|
+
data: any;
|
84
|
+
}) => void;
|
85
|
+
onDropEnd?: (detail: {
|
86
|
+
event: DragEvent;
|
87
|
+
zone: string;
|
88
|
+
data: any;
|
89
|
+
success: boolean;
|
90
|
+
error?: Error;
|
91
|
+
}) => void;
|
92
|
+
}, {}, "isDragOver" | "canDrop">;
|
@@ -1,4 +1,6 @@
|
|
1
1
|
export { default as Draggable } from "./Draggable.svelte";
|
2
2
|
export { default as DropZone } from "./DropZone.svelte";
|
3
|
+
export { default as DropZoneList } from "./DropZoneList.svelte";
|
4
|
+
export { default as DropZoneArea } from "./DropZoneArea.svelte";
|
3
5
|
export { default as DragDropContext } from "./DragDropContext.svelte";
|
4
6
|
export * from "./drag-state.svelte.js";
|
@@ -1,5 +1,7 @@
|
|
1
1
|
export { default as Draggable } from './Draggable.svelte';
|
2
2
|
export { default as DropZone } from './DropZone.svelte';
|
3
|
+
export { default as DropZoneList } from './DropZoneList.svelte';
|
4
|
+
export { default as DropZoneArea } from './DropZoneArea.svelte';
|
3
5
|
export { default as DragDropContext } from './DragDropContext.svelte';
|
4
6
|
|
5
7
|
export * from './drag-state.svelte.js';
|
@@ -44,12 +44,14 @@ export function rootDesignVarsHTML(design, clamping) {
|
|
44
44
|
--design-width: ${design.width};
|
45
45
|
--design-height: ${design.height};
|
46
46
|
|
47
|
-
/*
|
47
|
+
/* Scaling factors */
|
48
48
|
--scale-w: 1;
|
49
49
|
--scale-h: 1;
|
50
|
-
--scale-viewport: min(var(--scale-w), var(--scale-h));
|
51
50
|
|
52
|
-
/*
|
51
|
+
/* --scale-viewport: min(var(--scale-w), var(--scale-h)); */
|
52
|
+
--scale-viewport: 1;
|
53
|
+
|
54
|
+
/* Base clamping units */
|
53
55
|
--scale-ui: clamp(${clamping.ui.min}, var(--scale-viewport), ${clamping.ui.max});
|
54
56
|
--scale-text-base: clamp(${clamping.textBase.min}, var(--scale-viewport), ${clamping.textBase.max});
|
55
57
|
--scale-text-heading: clamp(${clamping.textHeading.min}, var(--scale-viewport), ${clamping.textHeading.max});
|