@hkdigital/lib-sveltekit 0.2.5 → 0.2.7
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/classes/logging/Logger.js +1 -1
- package/dist/components/drag-drop/DragController.d.ts +0 -20
- package/dist/components/drag-drop/DragController.js +1 -70
- package/dist/components/drag-drop/DragDropContext.svelte +14 -7
- package/dist/components/drag-drop/Draggable.svelte +40 -20
- package/dist/components/drag-drop/Draggable.svelte.d.ts +8 -2
- package/dist/components/drag-drop/drag-state.svelte.js +23 -27
- package/dist/components/drag-drop/drag-state.svelte.js__ +323 -0
- package/dist/components/layout/grid-layers/GridLayers.svelte +16 -140
- package/dist/components/layout/grid-layers/GridLayers.svelte.d.ts +2 -22
- package/dist/components/layout/grid-layers/GridLayers.svelte__heightFrom__ +372 -0
- package/dist/features/presenter/ImageSlide.svelte +2 -2
- package/dist/features/presenter/ImageSlide.svelte.d.ts +2 -2
- package/dist/features/presenter/Presenter.svelte +4 -2
- package/package.json +1 -1
- package/dist/components/layout/grid-layers/GridLayers.svelte__ +0 -167
@@ -0,0 +1,323 @@
|
|
1
|
+
// drag-state.svelte.js
|
2
|
+
import { defineStateContext } from '$lib/util/svelte/state-context/index.js';
|
3
|
+
|
4
|
+
/** @typedef {import('$lib/typedef').SimulatedDragEvent} SimulatedDragEvent */
|
5
|
+
|
6
|
+
class DragState {
|
7
|
+
// Existing draggables map
|
8
|
+
draggables = $state(new Map());
|
9
|
+
|
10
|
+
// New: Registry for dropzones
|
11
|
+
dropZones = $state(new Map());
|
12
|
+
|
13
|
+
// Track which dropzone is currently active
|
14
|
+
activeDropZone = $state(null);
|
15
|
+
|
16
|
+
// Track the last active drop zone
|
17
|
+
// - activeDropZone gets cleared by dragLeavr
|
18
|
+
// - but we need it in 'end'
|
19
|
+
lastActiveDropZone = null;
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Register a dropzone
|
23
|
+
* @param {string} zoneId
|
24
|
+
* @param {Object} config
|
25
|
+
* @param {string} config.zone
|
26
|
+
* @param {string} config.group
|
27
|
+
* @param {Function} config.accepts
|
28
|
+
* @param {Function} config.onDragEnter
|
29
|
+
* @param {Function} config.onDragOver
|
30
|
+
* @param {Function} config.onDragLeave
|
31
|
+
* @param {(DropData) => void} config.onDrop
|
32
|
+
* @param {HTMLElement} config.element
|
33
|
+
*/
|
34
|
+
registerDropZone(zoneId, config) {
|
35
|
+
if (this.dropZones.has(zoneId)) {
|
36
|
+
throw new Error(`Zone [${zoneId}] is already registered`);
|
37
|
+
}
|
38
|
+
|
39
|
+
this.dropZones.set(zoneId, {
|
40
|
+
...config,
|
41
|
+
isOver: false,
|
42
|
+
canDrop: false
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Unregister a dropzone
|
48
|
+
* @param {string} zoneId
|
49
|
+
*/
|
50
|
+
unregisterDropZone(zoneId) {
|
51
|
+
if (this.activeDropZone === zoneId) {
|
52
|
+
this.activeDropZone = null;
|
53
|
+
}
|
54
|
+
this.dropZones.delete(zoneId);
|
55
|
+
}
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Get dropzone at coordinates
|
59
|
+
* @param {number} x
|
60
|
+
* @param {number} y
|
61
|
+
* @returns {Object|null}
|
62
|
+
*/
|
63
|
+
getDropZoneAtPoint(x, y) {
|
64
|
+
// Check all registered dropzones
|
65
|
+
for (const [zoneId, config] of this.dropZones) {
|
66
|
+
const rect = config.element.getBoundingClientRect();
|
67
|
+
|
68
|
+
if (
|
69
|
+
x >= rect.left &&
|
70
|
+
x <= rect.right &&
|
71
|
+
y >= rect.top &&
|
72
|
+
y <= rect.bottom
|
73
|
+
) {
|
74
|
+
// Found a dropzone at this point
|
75
|
+
// Check if it's the deepest one (for nested zones)
|
76
|
+
let deepestZone = { zoneId, config, depth: 0 };
|
77
|
+
|
78
|
+
// Check for nested dropzones
|
79
|
+
for (const [otherId, otherConfig] of this.dropZones) {
|
80
|
+
if (otherId === zoneId) continue;
|
81
|
+
|
82
|
+
const otherRect = otherConfig.element.getBoundingClientRect();
|
83
|
+
if (
|
84
|
+
x >= otherRect.left &&
|
85
|
+
x <= otherRect.right &&
|
86
|
+
y >= otherRect.top &&
|
87
|
+
y <= otherRect.bottom
|
88
|
+
) {
|
89
|
+
// Check if this zone is nested inside our current zone
|
90
|
+
if (config.element.contains(otherConfig.element)) {
|
91
|
+
deepestZone = {
|
92
|
+
zoneId: otherId,
|
93
|
+
config: otherConfig,
|
94
|
+
depth: deepestZone.depth + 1
|
95
|
+
};
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
return { zoneId: deepestZone.zoneId, config: deepestZone.config };
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
return null;
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Update active dropzone based on coordinates
|
109
|
+
*
|
110
|
+
* @param {number} x
|
111
|
+
* @param {number} y
|
112
|
+
* @param {DragEvent|SimulatedDragEvent} event
|
113
|
+
*/
|
114
|
+
updateActiveDropZone(x, y, event) {
|
115
|
+
const dropZone = this.getDropZoneAtPoint(x, y);
|
116
|
+
const newActiveId = dropZone?.zoneId || null;
|
117
|
+
|
118
|
+
// Handle leave/enter transitions
|
119
|
+
if (this.activeDropZone !== newActiveId) {
|
120
|
+
// Leave previous zone
|
121
|
+
if (this.activeDropZone) {
|
122
|
+
this.lastActiveDropZone = this.activeDropZone;
|
123
|
+
|
124
|
+
const prevConfig = this.dropZones.get(this.activeDropZone);
|
125
|
+
if (prevConfig) {
|
126
|
+
prevConfig.isOver = false;
|
127
|
+
prevConfig.canDrop = false;
|
128
|
+
prevConfig.onDragLeave?.({ event, zone: prevConfig.zone });
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
// Enter new zone
|
133
|
+
if (newActiveId && dropZone) {
|
134
|
+
const dragData = this.getDraggable(event);
|
135
|
+
const canDrop = dragData && dropZone.config.accepts(dragData);
|
136
|
+
|
137
|
+
dropZone.config.isOver = true;
|
138
|
+
dropZone.config.canDrop = canDrop;
|
139
|
+
dropZone.config.onDragEnter?.({
|
140
|
+
event,
|
141
|
+
zone: dropZone.config.zone,
|
142
|
+
canDrop
|
143
|
+
});
|
144
|
+
}
|
145
|
+
|
146
|
+
this.activeDropZone = newActiveId;
|
147
|
+
} else if (newActiveId) {
|
148
|
+
// Still in the same zone, just send dragOver
|
149
|
+
dropZone.config.onDragOver?.({ event, zone: dropZone.config.zone });
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Handle drop at coordinates
|
155
|
+
* @param {number} x
|
156
|
+
* @param {number} y
|
157
|
+
* @param {DragEvent|SimulatedDragEvent} event
|
158
|
+
*/
|
159
|
+
handleDropAtPoint(x, y, event) {
|
160
|
+
const dropZone = this.getDropZoneAtPoint(x, y);
|
161
|
+
|
162
|
+
if (dropZone && dropZone.config.canDrop) {
|
163
|
+
const dragData = this.getDraggable(event);
|
164
|
+
|
165
|
+
if (dragData && dropZone.config.element) {
|
166
|
+
// Calculate drop position relative to dropzone
|
167
|
+
const rect = dropZone.config.element.getBoundingClientRect();
|
168
|
+
|
169
|
+
const style = window.getComputedStyle(dropZone.config.element);
|
170
|
+
|
171
|
+
const borderLeftWidth = parseInt(style.borderLeftWidth, 10) || 0;
|
172
|
+
const borderTopWidth = parseInt(style.borderTopWidth, 10) || 0;
|
173
|
+
|
174
|
+
const dropOffsetX = x - rect.left - borderLeftWidth;
|
175
|
+
const dropOffsetY = y - rect.top - borderTopWidth;
|
176
|
+
|
177
|
+
const dropX = dropOffsetX - (dragData.offsetX ?? 0);
|
178
|
+
const dropY = dropOffsetY - (dragData.offsetY ?? 0);
|
179
|
+
|
180
|
+
// Call the dropzone's drop handler
|
181
|
+
dropZone.config.onDrop?.({
|
182
|
+
zone: dropZone.config.zone,
|
183
|
+
source: dragData.source,
|
184
|
+
item: dragData.item,
|
185
|
+
x: dropX,
|
186
|
+
y: dropY,
|
187
|
+
drag: dragData,
|
188
|
+
drop: {
|
189
|
+
offsetX: dropOffsetX,
|
190
|
+
offsetY: dropOffsetY,
|
191
|
+
target: dropZone.config.element
|
192
|
+
}
|
193
|
+
});
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
// Ensure we notify the active dropzone that drag ended
|
198
|
+
if (this.activeDropZone) {
|
199
|
+
const config = this.dropZones.get(this.activeDropZone);
|
200
|
+
if (config) {
|
201
|
+
config.isOver = false;
|
202
|
+
config.canDrop = false;
|
203
|
+
config.onDragLeave?.({ event, zone: config.zone });
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
// Reset active dropzone
|
208
|
+
this.activeDropZone = null;
|
209
|
+
}
|
210
|
+
|
211
|
+
/**
|
212
|
+
* @param {string} draggableId
|
213
|
+
* @param {import('$lib/typedef/drag.js').DragData} dragData
|
214
|
+
*/
|
215
|
+
start(draggableId, dragData) {
|
216
|
+
this.draggables.set(draggableId, dragData);
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* @param {string} draggableId
|
221
|
+
*/
|
222
|
+
end(draggableId) {
|
223
|
+
this.draggables.delete(draggableId);
|
224
|
+
|
225
|
+
// Check both current AND last active dropzone
|
226
|
+
const zoneToNotify = this.activeDropZone || this.lastActiveDropZone;
|
227
|
+
|
228
|
+
if (zoneToNotify) {
|
229
|
+
const config = this.dropZones.get(zoneToNotify);
|
230
|
+
if (config && (config.isOver || config.canDrop)) {
|
231
|
+
config.isOver = false;
|
232
|
+
config.canDrop = false;
|
233
|
+
config.onDragLeave?.({
|
234
|
+
event: new DragEvent('dragend'),
|
235
|
+
zone: config.zone
|
236
|
+
});
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
this.activeDropZone = null;
|
241
|
+
this.lastActiveDropZone = null;
|
242
|
+
}
|
243
|
+
|
244
|
+
/**
|
245
|
+
* Get a drag data by draggable id
|
246
|
+
*
|
247
|
+
* @param {string} draggableId
|
248
|
+
* @returns {import('$lib/typedef/drag.js').DragData|undefined}
|
249
|
+
*/
|
250
|
+
getDraggableById(draggableId) {
|
251
|
+
return this.draggables.get(draggableId);
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Get a drag data. Extracts draggable id from the supplied DragEvent
|
256
|
+
*
|
257
|
+
* @param {DragEvent|SimulatedDragEvent} event
|
258
|
+
*
|
259
|
+
* @returns {Object|null} The drag data, or null for file drops
|
260
|
+
*/
|
261
|
+
getDraggable(event) {
|
262
|
+
// Check if this is a touch-simulated event
|
263
|
+
if (event.dataTransfer && !event.dataTransfer.files) {
|
264
|
+
try {
|
265
|
+
const jsonData = event.dataTransfer.getData('application/json');
|
266
|
+
if (jsonData) {
|
267
|
+
const transferData = JSON.parse(jsonData);
|
268
|
+
const draggableId = transferData.draggableId;
|
269
|
+
|
270
|
+
if (draggableId) {
|
271
|
+
return this.getDraggableById(draggableId);
|
272
|
+
}
|
273
|
+
}
|
274
|
+
} catch (error) {
|
275
|
+
console.error('Error getting drag data:', error);
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
// Check if this is a file drop
|
280
|
+
if (event.dataTransfer.types.includes('Files')) {
|
281
|
+
return null;
|
282
|
+
}
|
283
|
+
|
284
|
+
// Handle internal drag operations
|
285
|
+
try {
|
286
|
+
const jsonData = event.dataTransfer.getData('application/json');
|
287
|
+
if (jsonData) {
|
288
|
+
const transferData = JSON.parse(jsonData);
|
289
|
+
const draggableId = transferData.draggableId;
|
290
|
+
|
291
|
+
if (draggableId) {
|
292
|
+
const dragData = this.getDraggableById(draggableId);
|
293
|
+
if (dragData) {
|
294
|
+
return dragData;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
} catch (error) {
|
299
|
+
console.error('Error getting drag data:', error);
|
300
|
+
}
|
301
|
+
|
302
|
+
return null;
|
303
|
+
}
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Get the most recently started drag operation (convenience method)
|
307
|
+
* @returns {import('$lib/typedef/drag.js').DragData|undefined}
|
308
|
+
*/
|
309
|
+
get current() {
|
310
|
+
const entries = Array.from(this.draggables.entries());
|
311
|
+
return entries.length > 0 ? entries[entries.length - 1][1] : undefined;
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* @returns {boolean}
|
316
|
+
*/
|
317
|
+
isDragging() {
|
318
|
+
return this.draggables.size > 0;
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
export const [createOrGetDragState, createDragState, getDragState] =
|
323
|
+
defineStateContext(DragState);
|
@@ -1,187 +1,63 @@
|
|
1
1
|
<script>
|
2
|
-
import { onMount, onDestroy } from 'svelte';
|
3
|
-
import { setupLayerObserver, measureTargetLayer } from './util.js';
|
4
|
-
|
5
2
|
/**
|
3
|
+
* GridLayers Component
|
4
|
+
*
|
5
|
+
* Creates a single-cell grid where all children occupy the same space,
|
6
|
+
* enabling layered layouts with natural height behavior.
|
7
|
+
*
|
6
8
|
* @type {{
|
7
9
|
* base?: string,
|
8
10
|
* bg?: string,
|
9
11
|
* padding?: string,
|
10
12
|
* margin?: string,
|
11
|
-
* height?: string,
|
12
13
|
* classes?: string,
|
13
14
|
* style?: string,
|
14
|
-
*
|
15
|
-
* cellBg?: string,
|
16
|
-
* cellPadding?: string,
|
17
|
-
* cellMargin?: string,
|
18
|
-
* cellClasses?: string,
|
19
|
-
* cellStyle?: string,
|
20
|
-
* heightFrom?: string|null,
|
15
|
+
* overflow?: string,
|
21
16
|
* children: import('svelte').Snippet,
|
22
|
-
* cellAttrs?: { [attr: string]: any },
|
23
17
|
* [attr: string]: any
|
24
18
|
* }}
|
25
19
|
*/
|
26
20
|
const {
|
27
|
-
//
|
21
|
+
// Container styles
|
28
22
|
base = '',
|
29
23
|
bg = '',
|
30
24
|
padding = '',
|
31
25
|
margin = '',
|
32
|
-
height = 'h-full',
|
33
26
|
classes = '',
|
34
27
|
style = '',
|
35
|
-
|
36
|
-
cellBg = '',
|
37
|
-
cellPadding = '',
|
38
|
-
cellMargin = '',
|
39
|
-
cellClasses = '',
|
40
|
-
cellStyle = '',
|
41
|
-
|
42
|
-
// Behavior
|
43
|
-
heightFrom = null,
|
28
|
+
overflow = '',
|
44
29
|
|
45
|
-
//
|
46
|
-
cellAttrs = {},
|
30
|
+
// Content
|
47
31
|
children,
|
48
32
|
|
49
33
|
// Attributes
|
50
34
|
...attrs
|
51
35
|
} = $props();
|
52
36
|
|
53
|
-
//
|
54
|
-
let gridContainer = $state(null);
|
55
|
-
let gridContent = $state(null);
|
56
|
-
let calculatedHeight = $state(0);
|
57
|
-
let observer = $state(null);
|
58
|
-
let targetLayer = $state(null);
|
59
|
-
let isFirstRender = $state(heightFrom !== null); // Start with true if heightFrom is provided
|
60
|
-
let preCalculatedHeight = $state(0);
|
61
|
-
|
62
|
-
// Derived container style that updates reactively when dependencies change
|
37
|
+
// Build the inline style
|
63
38
|
let containerStyle = $derived.by(() => {
|
64
|
-
const styles = [];
|
39
|
+
const styles = ['grid-template: 1fr / 1fr;'];
|
65
40
|
|
66
41
|
if (style) {
|
67
42
|
styles.push(style);
|
68
43
|
}
|
69
44
|
|
70
|
-
if (heightFrom && calculatedHeight > 0) {
|
71
|
-
styles.push(`height: ${calculatedHeight}px;`);
|
72
|
-
}
|
73
|
-
|
74
45
|
return styles.join(' ');
|
75
46
|
});
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Handler for height changes detected by the observer
|
79
|
-
* @param {number} newHeight - The new calculated height
|
80
|
-
*/
|
81
|
-
function handleHeightChange(newHeight) {
|
82
|
-
calculatedHeight = newHeight;
|
83
|
-
}
|
84
|
-
|
85
|
-
/**
|
86
|
-
* Initialize height measurement and observation
|
87
|
-
*/
|
88
|
-
function initializeHeightTracking() {
|
89
|
-
if (!heightFrom || !gridContent) return;
|
90
|
-
|
91
|
-
// Measure the layer initially
|
92
|
-
const { element, height } = measureTargetLayer(gridContent, heightFrom);
|
93
|
-
|
94
|
-
if (element) {
|
95
|
-
targetLayer = element;
|
96
|
-
calculatedHeight = height;
|
97
|
-
|
98
|
-
// Setup observer for future changes
|
99
|
-
observer = setupLayerObserver(element, handleHeightChange);
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
// Initialize on mount with the two-pass rendering approach
|
104
|
-
onMount(() => {
|
105
|
-
if (heightFrom) {
|
106
|
-
// First render: measure invisibly
|
107
|
-
requestAnimationFrame(() => {
|
108
|
-
if (gridContent) {
|
109
|
-
const { element, height } = measureTargetLayer(gridContent, heightFrom);
|
110
|
-
|
111
|
-
if (element) {
|
112
|
-
targetLayer = element;
|
113
|
-
preCalculatedHeight = height;
|
114
|
-
|
115
|
-
// Second render: show with correct height
|
116
|
-
requestAnimationFrame(() => {
|
117
|
-
calculatedHeight = preCalculatedHeight;
|
118
|
-
isFirstRender = false;
|
119
|
-
|
120
|
-
// Setup observer for future changes
|
121
|
-
observer = setupLayerObserver(element, handleHeightChange);
|
122
|
-
});
|
123
|
-
} else {
|
124
|
-
// No target layer found, just show the component
|
125
|
-
isFirstRender = false;
|
126
|
-
}
|
127
|
-
} else {
|
128
|
-
// No grid content, just show the component
|
129
|
-
isFirstRender = false;
|
130
|
-
}
|
131
|
-
});
|
132
|
-
} else {
|
133
|
-
// No heightFrom, no need for measurement
|
134
|
-
isFirstRender = false;
|
135
|
-
}
|
136
|
-
});
|
137
|
-
|
138
|
-
// Effect to re-setup observer when either the target layer or heightFrom changes
|
139
|
-
$effect(() => {
|
140
|
-
// Only handle changes after initial setup
|
141
|
-
if (!isFirstRender && heightFrom && gridContent && !observer) {
|
142
|
-
initializeHeightTracking();
|
143
|
-
}
|
144
|
-
});
|
145
|
-
|
146
|
-
// Clean up on destroy
|
147
|
-
onDestroy(() => {
|
148
|
-
if (observer) {
|
149
|
-
observer.disconnect();
|
150
|
-
observer = null;
|
151
|
-
}
|
152
|
-
});
|
153
|
-
|
154
47
|
</script>
|
155
48
|
|
156
49
|
<div
|
157
50
|
data-component="grid-layers"
|
158
|
-
|
159
|
-
class="relative {isFirstRender ? 'invisible' : ''} {base} {bg} {heightFrom ? '' : height} {classes} {margin} {padding}"
|
51
|
+
class="grid {base} {bg} {classes} {margin} {padding} {overflow}"
|
160
52
|
style={containerStyle}
|
161
53
|
{...attrs}
|
162
54
|
>
|
163
|
-
|
164
|
-
data-section="grid"
|
165
|
-
bind:this={gridContent}
|
166
|
-
class="absolute inset-0 grid {cellBase} {cellBg} {cellPadding} {cellMargin} {cellClasses}"
|
167
|
-
style={cellStyle}
|
168
|
-
{...cellAttrs}
|
169
|
-
>
|
170
|
-
{@render children()}
|
171
|
-
</div>
|
55
|
+
{@render children()}
|
172
56
|
</div>
|
173
57
|
|
174
58
|
<style>
|
175
|
-
/* All children
|
176
|
-
|
177
|
-
|
178
|
-
grid-template-columns: 1fr;
|
179
|
-
grid-template-rows: 1fr;
|
180
|
-
}
|
181
|
-
|
182
|
-
[data-section='grid'] > :global(*) {
|
183
|
-
grid-column: 1;
|
184
|
-
grid-row: 1;
|
185
|
-
z-index: 0; /* Base z-index to allow explicit stacking order */
|
59
|
+
/* All direct children occupy the same grid area */
|
60
|
+
div > :global(*) {
|
61
|
+
grid-area: 1 / 1;
|
186
62
|
}
|
187
63
|
</style>
|
@@ -7,20 +7,10 @@ type GridLayers = {
|
|
7
7
|
bg?: string;
|
8
8
|
padding?: string;
|
9
9
|
margin?: string;
|
10
|
-
height?: string;
|
11
10
|
classes?: string;
|
12
11
|
style?: string;
|
13
|
-
|
14
|
-
cellBg?: string;
|
15
|
-
cellPadding?: string;
|
16
|
-
cellMargin?: string;
|
17
|
-
cellClasses?: string;
|
18
|
-
cellStyle?: string;
|
19
|
-
heightFrom?: string;
|
12
|
+
overflow?: string;
|
20
13
|
children: Snippet<[]>;
|
21
|
-
cellAttrs?: {
|
22
|
-
[attr: string]: any;
|
23
|
-
};
|
24
14
|
}>): void;
|
25
15
|
};
|
26
16
|
declare const GridLayers: import("svelte").Component<{
|
@@ -29,18 +19,8 @@ declare const GridLayers: import("svelte").Component<{
|
|
29
19
|
bg?: string;
|
30
20
|
padding?: string;
|
31
21
|
margin?: string;
|
32
|
-
height?: string;
|
33
22
|
classes?: string;
|
34
23
|
style?: string;
|
35
|
-
|
36
|
-
cellBg?: string;
|
37
|
-
cellPadding?: string;
|
38
|
-
cellMargin?: string;
|
39
|
-
cellClasses?: string;
|
40
|
-
cellStyle?: string;
|
41
|
-
heightFrom?: string | null;
|
24
|
+
overflow?: string;
|
42
25
|
children: import("svelte").Snippet;
|
43
|
-
cellAttrs?: {
|
44
|
-
[attr: string]: any;
|
45
|
-
};
|
46
26
|
}, {}, "">;
|