@hkdigital/lib-sveltekit 0.1.79 → 0.1.81
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/DragController.d.ts +40 -0
- package/dist/components/drag-drop/DragController.js +113 -0
- package/dist/components/drag-drop/Draggable.svelte +128 -44
- package/dist/components/drag-drop/Draggable.svelte.d.ts +11 -0
- package/dist/components/drag-drop/DropZone.svelte +47 -33
- package/dist/components/drag-drop/DropZone.svelte.d.ts +7 -21
- package/dist/components/layout/grid-layers/GridLayers.svelte +177 -158
- package/dist/components/layout/grid-layers/GridLayers.svelte.d.ts +2 -0
- package/dist/components/layout/grid-layers/GridLayers.svelte__ +167 -0
- package/dist/components/layout/grid-layers/util.d.ts +19 -0
- package/dist/components/layout/grid-layers/util.js +74 -0
- package/dist/components/rows/panel-grid-row/PanelGridRow.svelte.d.ts +2 -2
- package/dist/components/rows/panel-row-2/PanelRow2.svelte.d.ts +2 -2
- package/dist/themes/hkdev/components/drag-drop/draggable.css +4 -0
- package/dist/themes/hkdev/components/drag-drop/dropzone.css +32 -56
- package/package.json +1 -1
@@ -0,0 +1,40 @@
|
|
1
|
+
/**
|
2
|
+
* Controller for customizing drag
|
3
|
+
* E.g. set a custom preview image
|
4
|
+
*/
|
5
|
+
export class DragController {
|
6
|
+
/**
|
7
|
+
* @param {DragEvent} event - The drag event
|
8
|
+
*/
|
9
|
+
constructor(event: DragEvent);
|
10
|
+
event: DragEvent;
|
11
|
+
dataTransfer: DataTransfer;
|
12
|
+
targetElement: HTMLElement;
|
13
|
+
offsetX: number;
|
14
|
+
offsetY: number;
|
15
|
+
_previewSet: boolean;
|
16
|
+
/**
|
17
|
+
* Create a preview image from the current draggable element or a specific child element
|
18
|
+
* @param {string} [selector] - Optional CSS selector to target a specific child element
|
19
|
+
* @returns {HTMLElement} - The created preview element
|
20
|
+
*/
|
21
|
+
grabPreviewImage(selector?: string): HTMLElement;
|
22
|
+
/**
|
23
|
+
* Set a custom element as the drag preview image
|
24
|
+
* @param {HTMLElement} element - Element to use as drag preview
|
25
|
+
* @param {number} [offsetX] - Horizontal offset (uses natural offset if omitted)
|
26
|
+
* @param {number} [offsetY] - Vertical offset (uses natural offset if omitted)
|
27
|
+
* @returns {boolean} - Whether setting the preview was successful
|
28
|
+
*/
|
29
|
+
setPreviewImage(element: HTMLElement, offsetX?: number, offsetY?: number): boolean;
|
30
|
+
/**
|
31
|
+
* Check if a custom preview has been set
|
32
|
+
* @returns {boolean}
|
33
|
+
*/
|
34
|
+
hasCustomPreview(): boolean;
|
35
|
+
/**
|
36
|
+
* Apply the default preview (uses the draggable element itself)
|
37
|
+
* @returns {boolean}
|
38
|
+
*/
|
39
|
+
applyDefaultPreview(): boolean;
|
40
|
+
}
|
@@ -0,0 +1,113 @@
|
|
1
|
+
/**
|
2
|
+
* Controller for customizing drag
|
3
|
+
* E.g. set a custom preview image
|
4
|
+
*/
|
5
|
+
export class DragController {
|
6
|
+
/**
|
7
|
+
* @param {DragEvent} event - The drag event
|
8
|
+
*/
|
9
|
+
constructor(event) {
|
10
|
+
this.event = event;
|
11
|
+
this.dataTransfer = event.dataTransfer;
|
12
|
+
this.targetElement = /** @type {HTMLElement} */ (event.currentTarget);
|
13
|
+
|
14
|
+
// Calculate natural offsets by default (to prevent "jumping")
|
15
|
+
const rect = this.targetElement.getBoundingClientRect();
|
16
|
+
this.offsetX = event.clientX - rect.left;
|
17
|
+
this.offsetY = event.clientY - rect.top;
|
18
|
+
|
19
|
+
this._previewSet = false;
|
20
|
+
}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Create a preview image from the current draggable element or a specific child element
|
24
|
+
* @param {string} [selector] - Optional CSS selector to target a specific child element
|
25
|
+
* @returns {HTMLElement} - The created preview element
|
26
|
+
*/
|
27
|
+
grabPreviewImage(selector = null) {
|
28
|
+
// Find the source element (either the whole draggable or a specific child)
|
29
|
+
const sourceElement = selector
|
30
|
+
? this.targetElement.querySelector(selector)
|
31
|
+
: this.targetElement;
|
32
|
+
|
33
|
+
if (!sourceElement) {
|
34
|
+
console.error(`Element with selector "${selector}" not found`);
|
35
|
+
return this.grabPreviewImage(); // Fallback to the main element
|
36
|
+
}
|
37
|
+
|
38
|
+
// Clone the element to create the preview
|
39
|
+
const previewElement = /** @type {HTMLElement} */ (
|
40
|
+
sourceElement.cloneNode(true)
|
41
|
+
);
|
42
|
+
|
43
|
+
// Position off-screen (needed for setDragImage to work properly)
|
44
|
+
previewElement.style.position = 'absolute';
|
45
|
+
previewElement.style.top = '-9999px';
|
46
|
+
previewElement.style.left = '-9999px';
|
47
|
+
|
48
|
+
// Add to the document temporarily
|
49
|
+
document.body.appendChild(previewElement);
|
50
|
+
|
51
|
+
return previewElement;
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Set a custom element as the drag preview image
|
56
|
+
* @param {HTMLElement} element - Element to use as drag preview
|
57
|
+
* @param {number} [offsetX] - Horizontal offset (uses natural offset if omitted)
|
58
|
+
* @param {number} [offsetY] - Vertical offset (uses natural offset if omitted)
|
59
|
+
* @returns {boolean} - Whether setting the preview was successful
|
60
|
+
*/
|
61
|
+
setPreviewImage(element, offsetX, offsetY) {
|
62
|
+
if (!this.dataTransfer || !this.dataTransfer.setDragImage) {
|
63
|
+
return false;
|
64
|
+
}
|
65
|
+
|
66
|
+
// Use provided offsets or fall back to natural offsets
|
67
|
+
const finalOffsetX = offsetX !== undefined ? offsetX : this.offsetX;
|
68
|
+
const finalOffsetY = offsetY !== undefined ? offsetY : this.offsetY;
|
69
|
+
|
70
|
+
try {
|
71
|
+
this.dataTransfer.setDragImage(element, finalOffsetX, finalOffsetY);
|
72
|
+
this._previewSet = true;
|
73
|
+
return true;
|
74
|
+
} catch (err) {
|
75
|
+
console.error('Failed to set drag preview image:', err);
|
76
|
+
return false;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Check if a custom preview has been set
|
82
|
+
* @returns {boolean}
|
83
|
+
*/
|
84
|
+
hasCustomPreview() {
|
85
|
+
return this._previewSet;
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Apply the default preview (uses the draggable element itself)
|
90
|
+
* @returns {boolean}
|
91
|
+
*/
|
92
|
+
applyDefaultPreview() {
|
93
|
+
if (
|
94
|
+
!this.dataTransfer ||
|
95
|
+
!this.dataTransfer.setDragImage ||
|
96
|
+
this._previewSet
|
97
|
+
) {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
|
101
|
+
try {
|
102
|
+
this.dataTransfer.setDragImage(
|
103
|
+
this.targetElement,
|
104
|
+
this.offsetX,
|
105
|
+
this.offsetY
|
106
|
+
);
|
107
|
+
return true;
|
108
|
+
} catch (err) {
|
109
|
+
console.error('Failed to set default drag preview:', err);
|
110
|
+
return false;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
@@ -1,10 +1,9 @@
|
|
1
1
|
<script>
|
2
2
|
import { toStateClasses } from '../../util/design-system/index.js';
|
3
|
-
|
4
3
|
import { createOrGetDragState } from './drag-state.svelte.js';
|
5
|
-
|
4
|
+
import { DragController } from './DragController.js';
|
6
5
|
import { generateLocalId } from '../../util/unique';
|
7
|
-
|
6
|
+
import { onDestroy } from 'svelte';
|
8
7
|
import {
|
9
8
|
IDLE,
|
10
9
|
DRAGGING,
|
@@ -23,6 +22,10 @@
|
|
23
22
|
* base?: string,
|
24
23
|
* classes?: string,
|
25
24
|
* children: import('svelte').Snippet,
|
25
|
+
* draggingSnippet?: import('svelte').Snippet<[{
|
26
|
+
* element: HTMLElement,
|
27
|
+
* rect: DOMRect
|
28
|
+
* }]>,
|
26
29
|
* contextKey?: import('../../typedef').ContextKey,
|
27
30
|
* isDragging?: boolean,
|
28
31
|
* isDropping?: boolean,
|
@@ -31,7 +34,8 @@
|
|
31
34
|
* event: DragEvent,
|
32
35
|
* item: any,
|
33
36
|
* source: string,
|
34
|
-
* group: string
|
37
|
+
* group: string,
|
38
|
+
* getController: () => DragController
|
35
39
|
* }) => void,
|
36
40
|
* onDragging?: (detail: {
|
37
41
|
* event: DragEvent,
|
@@ -60,6 +64,7 @@
|
|
60
64
|
base = '',
|
61
65
|
classes = '',
|
62
66
|
children,
|
67
|
+
draggingSnippet,
|
63
68
|
contextKey,
|
64
69
|
isDragging = $bindable(false),
|
65
70
|
isDropping = $bindable(false),
|
@@ -76,11 +81,21 @@
|
|
76
81
|
|
77
82
|
const draggableId = generateLocalId();
|
78
83
|
|
79
|
-
//
|
84
|
+
// svelte-ignore non_reactive_update
|
85
|
+
let draggableElement;
|
80
86
|
|
81
87
|
let dragTimeout = null;
|
82
88
|
let currentState = $state(IDLE);
|
83
89
|
|
90
|
+
// Custom preview follower state
|
91
|
+
let showPreview = $state(false);
|
92
|
+
let previewX = $state(0);
|
93
|
+
let previewY = $state(0);
|
94
|
+
let dragOffsetX = $state(0);
|
95
|
+
let dragOffsetY = $state(0);
|
96
|
+
let customPreviewSet = $state(false);
|
97
|
+
let elementRect = $state(null);
|
98
|
+
|
84
99
|
// Computed state object for CSS classes
|
85
100
|
let stateObject = $derived({
|
86
101
|
idle: currentState === IDLE,
|
@@ -99,6 +114,28 @@
|
|
99
114
|
isDragPreview = currentState === DRAG_PREVIEW;
|
100
115
|
});
|
101
116
|
|
117
|
+
// Clean up on component destroy
|
118
|
+
onDestroy(() => {
|
119
|
+
if (showPreview) {
|
120
|
+
document.removeEventListener('dragover', handleDocumentDragOver);
|
121
|
+
}
|
122
|
+
});
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Handle document level dragover to ensure we get position updates
|
126
|
+
* @param {DragEvent} event
|
127
|
+
*/
|
128
|
+
function handleDocumentDragOver(event) {
|
129
|
+
if (showPreview && currentState === DRAGGING) {
|
130
|
+
// Update position for the custom preview
|
131
|
+
previewX = event.clientX - dragOffsetX;
|
132
|
+
previewY = event.clientY - dragOffsetY;
|
133
|
+
|
134
|
+
// Prevent default to allow drop
|
135
|
+
event.preventDefault();
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
102
139
|
/**
|
103
140
|
* Handle drag start
|
104
141
|
* @param {DragEvent} event
|
@@ -143,24 +180,51 @@
|
|
143
180
|
event.dataTransfer.effectAllowed = 'move';
|
144
181
|
event.dataTransfer.setData('application/json', JSON.stringify(dragData));
|
145
182
|
|
146
|
-
//
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
183
|
+
// Create the preview controller with natural offsets already calculated
|
184
|
+
const previewController = new DragController(event);
|
185
|
+
|
186
|
+
// Function to get the preview controller
|
187
|
+
const getController = () => previewController;
|
188
|
+
|
189
|
+
// Call onDragStart with the getController function
|
190
|
+
onDragStart?.({ event, item, source, group, getController });
|
191
|
+
|
192
|
+
// Check if we have a preview snippet and no custom preview was set by preview controller
|
193
|
+
if (draggingSnippet && !previewController.hasCustomPreview()) {
|
194
|
+
try {
|
195
|
+
// Get the element's bounding rectangle
|
196
|
+
const rect = draggableElement.getBoundingClientRect();
|
197
|
+
elementRect = rect;
|
198
|
+
|
199
|
+
// Calculate offsets - this is the natural position where the user grabbed
|
200
|
+
dragOffsetX = event.clientX - rect.left;
|
201
|
+
dragOffsetY = event.clientY - rect.top;
|
202
|
+
|
203
|
+
// Set initial position
|
204
|
+
previewX = event.clientX - dragOffsetX;
|
205
|
+
previewY = event.clientY - dragOffsetY;
|
206
|
+
|
207
|
+
// Set a transparent 1x1 pixel image as drag preview to hide browser preview
|
208
|
+
const emptyImg = new Image();
|
209
|
+
emptyImg.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
210
|
+
event.dataTransfer.setDragImage(emptyImg, 0, 0);
|
211
|
+
|
212
|
+
// Add document level event listener to catch all dragover events
|
213
|
+
document.addEventListener('dragover', handleDocumentDragOver);
|
214
|
+
|
215
|
+
// Show our custom preview
|
216
|
+
showPreview = true;
|
217
|
+
customPreviewSet = true;
|
218
|
+
} catch (err) {
|
219
|
+
console.error('Error setting up custom preview:', err);
|
220
|
+
// Fallback to default preview
|
221
|
+
previewController.applyDefaultPreview();
|
222
|
+
}
|
223
|
+
}
|
224
|
+
// Apply default preview if no custom preview was set and no snippet
|
225
|
+
else if (!previewController.hasCustomPreview() && !customPreviewSet) {
|
226
|
+
previewController.applyDefaultPreview();
|
161
227
|
}
|
162
|
-
|
163
|
-
onDragStart?.({ event, item, source, group });
|
164
228
|
}
|
165
229
|
|
166
230
|
/**
|
@@ -173,33 +237,41 @@
|
|
173
237
|
}
|
174
238
|
}
|
175
239
|
|
176
|
-
/**
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
function handleDragEnd(event) {
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
240
|
+
/**
|
241
|
+
* Handle drag end
|
242
|
+
* @param {DragEvent} event
|
243
|
+
*/
|
244
|
+
function handleDragEnd(event) {
|
245
|
+
clearTimeout(dragTimeout);
|
246
|
+
|
247
|
+
// Clear global drag state
|
248
|
+
dragState.end(draggableId);
|
249
|
+
|
250
|
+
// Clean up document event listener
|
251
|
+
if (customPreviewSet) {
|
252
|
+
document.removeEventListener('dragover', handleDocumentDragOver);
|
253
|
+
showPreview = false;
|
254
|
+
customPreviewSet = false;
|
255
|
+
elementRect = null;
|
256
|
+
}
|
185
257
|
|
186
|
-
|
187
|
-
|
258
|
+
// Check if drop was successful
|
259
|
+
const wasDropped = event.dataTransfer.dropEffect !== 'none';
|
188
260
|
|
189
|
-
|
190
|
-
|
191
|
-
|
261
|
+
if (wasDropped) {
|
262
|
+
currentState = DROPPING;
|
263
|
+
onDrop?.({ event, item, wasDropped: true });
|
192
264
|
|
193
|
-
|
194
|
-
|
265
|
+
// Brief dropping state before returning to idle
|
266
|
+
setTimeout(() => {
|
267
|
+
currentState = IDLE;
|
268
|
+
}, 100);
|
269
|
+
} else {
|
195
270
|
currentState = IDLE;
|
196
|
-
}
|
197
|
-
} else {
|
198
|
-
currentState = IDLE;
|
199
|
-
}
|
271
|
+
}
|
200
272
|
|
201
|
-
|
202
|
-
}
|
273
|
+
onDragEnd?.({ event, item, wasDropped });
|
274
|
+
}
|
203
275
|
|
204
276
|
/**
|
205
277
|
* Handle mouse down for drag delay
|
@@ -226,6 +298,7 @@ function handleDragEnd(event) {
|
|
226
298
|
<div
|
227
299
|
data-component="draggable"
|
228
300
|
data-id={draggableId}
|
301
|
+
bind:this={draggableElement}
|
229
302
|
draggable={!disabled && canDrag(item)}
|
230
303
|
ondragstart={handleDragStart}
|
231
304
|
ondrag={handleDrag}
|
@@ -237,3 +310,14 @@ function handleDragEnd(event) {
|
|
237
310
|
>
|
238
311
|
{@render children()}
|
239
312
|
</div>
|
313
|
+
|
314
|
+
{#if draggingSnippet && showPreview && elementRect}
|
315
|
+
<div
|
316
|
+
data-companion="drag-preview-follower"
|
317
|
+
style="position: fixed; z-index: 9999; pointer-events: none;"
|
318
|
+
style:left="{previewX}px"
|
319
|
+
style:top="{previewY}px"
|
320
|
+
>
|
321
|
+
{@render draggingSnippet({ element: draggableElement, rect: elementRect })}
|
322
|
+
</div>
|
323
|
+
{/if}
|
@@ -11,6 +11,10 @@ type Draggable = {
|
|
11
11
|
base?: string;
|
12
12
|
classes?: string;
|
13
13
|
children: Snippet<[]>;
|
14
|
+
draggingSnippet?: Snippet<[{
|
15
|
+
element: HTMLElement;
|
16
|
+
rect: DOMRect;
|
17
|
+
}]>;
|
14
18
|
contextKey?: ContextKey;
|
15
19
|
isDragging?: boolean;
|
16
20
|
isDropping?: boolean;
|
@@ -20,6 +24,7 @@ type Draggable = {
|
|
20
24
|
item: any;
|
21
25
|
source: string;
|
22
26
|
group: string;
|
27
|
+
getController: () => DragController;
|
23
28
|
}) => void;
|
24
29
|
onDragging?: (detail: {
|
25
30
|
event: DragEvent;
|
@@ -48,6 +53,10 @@ declare const Draggable: import("svelte").Component<{
|
|
48
53
|
base?: string;
|
49
54
|
classes?: string;
|
50
55
|
children: import("svelte").Snippet;
|
56
|
+
draggingSnippet?: import("svelte").Snippet<[{
|
57
|
+
element: HTMLElement;
|
58
|
+
rect: DOMRect;
|
59
|
+
}]>;
|
51
60
|
contextKey?: import("../../typedef").ContextKey;
|
52
61
|
isDragging?: boolean;
|
53
62
|
isDropping?: boolean;
|
@@ -57,6 +66,7 @@ declare const Draggable: import("svelte").Component<{
|
|
57
66
|
item: any;
|
58
67
|
source: string;
|
59
68
|
group: string;
|
69
|
+
getController: () => DragController;
|
60
70
|
}) => void;
|
61
71
|
onDragging?: (detail: {
|
62
72
|
event: DragEvent;
|
@@ -74,3 +84,4 @@ declare const Draggable: import("svelte").Component<{
|
|
74
84
|
}) => void;
|
75
85
|
canDrag?: (item: any) => boolean;
|
76
86
|
}, {}, "isDragging" | "isDropping" | "isDragPreview">;
|
87
|
+
import { DragController } from './DragController.js';
|
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
import { createOrGetDragState } from './drag-state.svelte.js';
|
6
6
|
|
7
|
+
import { GridLayers } from '../layout';
|
8
|
+
|
7
9
|
import {
|
8
10
|
findDraggableSource,
|
9
11
|
getDraggableIdFromEvent,
|
@@ -15,32 +17,26 @@
|
|
15
17
|
DRAG_OVER,
|
16
18
|
CAN_DROP,
|
17
19
|
CANNOT_DROP,
|
18
|
-
DROP_DISABLED
|
19
|
-
ACTIVE_DROP
|
20
|
+
DROP_DISABLED
|
20
21
|
} from '../../constants/state-labels/drop-states.js';
|
21
22
|
|
23
|
+
/** @typedef {import('../../typedef').DragData} DragData */
|
24
|
+
|
22
25
|
/**
|
23
26
|
* @type {{
|
24
27
|
* zone?: string,
|
25
28
|
* group?: string,
|
26
29
|
* disabled?: boolean,
|
27
30
|
* accepts?: (item: any) => boolean,
|
28
|
-
* maxItems?: number,
|
29
31
|
* base?: string,
|
30
32
|
* classes?: string,
|
33
|
+
* height?: string,
|
34
|
+
* autoHeight?: boolean,
|
31
35
|
* children?: import('svelte').Snippet,
|
32
36
|
* contextKey?: import('../../typedef').ContextKey,
|
33
|
-
*
|
34
|
-
* preview?: import('svelte').Snippet<[{
|
35
|
-
* item: any,
|
36
|
-
* source: string,
|
37
|
-
* group: string,
|
38
|
-
* metadata?: any
|
39
|
-
* }]>,
|
37
|
+
* dropPreviewSnippet?: import('svelte').Snippet<[DragData]>,
|
40
38
|
* isDragOver?: boolean,
|
41
39
|
* canDrop?: boolean,
|
42
|
-
* isDropping?: boolean,
|
43
|
-
* itemCount?: number,
|
44
40
|
* onDragEnter?: (detail: {
|
45
41
|
* event: DragEvent,
|
46
42
|
* zone: string,
|
@@ -81,17 +77,15 @@
|
|
81
77
|
group = 'default',
|
82
78
|
disabled = false,
|
83
79
|
accepts = () => true,
|
84
|
-
maxItems = Infinity,
|
85
80
|
base = '',
|
86
81
|
classes = '',
|
82
|
+
height = 'h-min',
|
83
|
+
autoHeight= false,
|
87
84
|
children,
|
88
85
|
contextKey,
|
89
|
-
|
90
|
-
preview,
|
86
|
+
dropPreviewSnippet,
|
91
87
|
isDragOver = $bindable(false),
|
92
88
|
canDrop = $bindable(false),
|
93
|
-
isDropping = $bindable(false),
|
94
|
-
itemCount = $bindable(0),
|
95
89
|
onDragEnter,
|
96
90
|
onDragOver,
|
97
91
|
onDragLeave,
|
@@ -140,8 +134,7 @@
|
|
140
134
|
'drag-over': currentState === DRAG_OVER,
|
141
135
|
'can-drop': currentState === CAN_DROP,
|
142
136
|
'cannot-drop': currentState === CANNOT_DROP,
|
143
|
-
'drop-disabled': disabled
|
144
|
-
'active-drop': currentState === ACTIVE_DROP
|
137
|
+
'drop-disabled': disabled
|
145
138
|
});
|
146
139
|
|
147
140
|
let stateClasses = $derived(toStateClasses(stateObject));
|
@@ -155,7 +148,6 @@
|
|
155
148
|
].includes(currentState);
|
156
149
|
|
157
150
|
canDrop = currentState === CAN_DROP;
|
158
|
-
isDropping = currentState === ACTIVE_DROP;
|
159
151
|
});
|
160
152
|
|
161
153
|
/**
|
@@ -172,7 +164,6 @@
|
|
172
164
|
if (!data) return false;
|
173
165
|
if (data.group !== group) return false;
|
174
166
|
if (!accepts(data.item)) return false;
|
175
|
-
if (itemCount >= maxItems) return false;
|
176
167
|
return true;
|
177
168
|
}
|
178
169
|
|
@@ -321,8 +312,7 @@ function handleDrop(event) {
|
|
321
312
|
|
322
313
|
// Check if we can accept this drop
|
323
314
|
if (dragData && canAcceptDrop(dragData)) {
|
324
|
-
//
|
325
|
-
currentState = ACTIVE_DROP;
|
315
|
+
// Notify listener
|
326
316
|
onDropStart?.({ event, zone, data: dragData });
|
327
317
|
|
328
318
|
// Call the onDrop handler and handle Promise resolution
|
@@ -361,17 +351,41 @@ function handleDrop(event) {
|
|
361
351
|
ondragover={handleDragOver}
|
362
352
|
ondragleave={handleDragLeave}
|
363
353
|
ondrop={handleDrop}
|
364
|
-
class="{base} {classes} {stateClasses}"
|
354
|
+
class="{base} {height} {classes} {stateClasses}"
|
365
355
|
data-zone={zone}
|
366
356
|
{...attrs}
|
367
357
|
>
|
368
|
-
{
|
369
|
-
{
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
{
|
374
|
-
|
375
|
-
|
376
|
-
|
358
|
+
<GridLayers heightFrom={autoHeight ? 'content' : null}>
|
359
|
+
{#if children}
|
360
|
+
<div data-layer="content" class:auto-height={autoHeight}>
|
361
|
+
{@render children()}
|
362
|
+
</div>
|
363
|
+
{/if}
|
364
|
+
|
365
|
+
{#if currentState === CAN_DROP && dropPreviewSnippet}
|
366
|
+
<div data-layer="preview">
|
367
|
+
{@render dropPreviewSnippet(dragState.current)}
|
368
|
+
</div>
|
369
|
+
{/if}
|
370
|
+
|
371
|
+
</GridLayers>
|
377
372
|
</div>
|
373
|
+
|
374
|
+
<style>
|
375
|
+
[data-layer='content']:not(.auto-height) {
|
376
|
+
position: absolute;
|
377
|
+
left: 0; right: 0; top: 0; bottom: 0;
|
378
|
+
}
|
379
|
+
|
380
|
+
[data-layer='content'].auto-height {
|
381
|
+
position: relative;
|
382
|
+
width: 100%;
|
383
|
+
}
|
384
|
+
|
385
|
+
[data-layer='preview']
|
386
|
+
{
|
387
|
+
position: absolute;
|
388
|
+
left: 0; right: 0; top: 0; bottom: 0;
|
389
|
+
pointer-events: none;
|
390
|
+
}
|
391
|
+
</style>
|
@@ -7,22 +7,15 @@ type DropZone = {
|
|
7
7
|
group?: string;
|
8
8
|
disabled?: boolean;
|
9
9
|
accepts?: (item: any) => boolean;
|
10
|
-
maxItems?: number;
|
11
10
|
base?: string;
|
12
11
|
classes?: string;
|
12
|
+
height?: string;
|
13
|
+
autoHeight?: boolean;
|
13
14
|
children?: Snippet<[]>;
|
14
15
|
contextKey?: ContextKey;
|
15
|
-
|
16
|
-
preview?: Snippet<[{
|
17
|
-
item: any;
|
18
|
-
source: string;
|
19
|
-
group: string;
|
20
|
-
metadata?: any;
|
21
|
-
}]>;
|
16
|
+
dropPreviewSnippet?: Snippet<[DragData]>;
|
22
17
|
isDragOver?: boolean;
|
23
18
|
canDrop?: boolean;
|
24
|
-
isDropping?: boolean;
|
25
|
-
itemCount?: number;
|
26
19
|
onDragEnter?: (detail: {
|
27
20
|
event: DragEvent;
|
28
21
|
zone: string;
|
@@ -63,22 +56,15 @@ declare const DropZone: import("svelte").Component<{
|
|
63
56
|
group?: string;
|
64
57
|
disabled?: boolean;
|
65
58
|
accepts?: (item: any) => boolean;
|
66
|
-
maxItems?: number;
|
67
59
|
base?: string;
|
68
60
|
classes?: string;
|
61
|
+
height?: string;
|
62
|
+
autoHeight?: boolean;
|
69
63
|
children?: import("svelte").Snippet;
|
70
64
|
contextKey?: import("../../typedef").ContextKey;
|
71
|
-
|
72
|
-
preview?: import("svelte").Snippet<[{
|
73
|
-
item: any;
|
74
|
-
source: string;
|
75
|
-
group: string;
|
76
|
-
metadata?: any;
|
77
|
-
}]>;
|
65
|
+
dropPreviewSnippet?: import("svelte").Snippet<[import("../../typedef").DragData]>;
|
78
66
|
isDragOver?: boolean;
|
79
67
|
canDrop?: boolean;
|
80
|
-
isDropping?: boolean;
|
81
|
-
itemCount?: number;
|
82
68
|
onDragEnter?: (detail: {
|
83
69
|
event: DragEvent;
|
84
70
|
zone: string;
|
@@ -111,4 +97,4 @@ declare const DropZone: import("svelte").Component<{
|
|
111
97
|
success: boolean;
|
112
98
|
error?: Error;
|
113
99
|
}) => void;
|
114
|
-
}, {}, "
|
100
|
+
}, {}, "isDragOver" | "canDrop">;
|