@smartnet360/svelte-components 0.0.1-beta.2
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/Desktop/Desktop.svelte +423 -0
- package/dist/Desktop/Desktop.svelte.d.ts +26 -0
- package/dist/Desktop/Grid/Half.svelte +50 -0
- package/dist/Desktop/Grid/Half.svelte.d.ts +29 -0
- package/dist/Desktop/Grid/Quarter.svelte +103 -0
- package/dist/Desktop/Grid/Quarter.svelte.d.ts +27 -0
- package/dist/Desktop/Grid/README.md +331 -0
- package/dist/Desktop/Grid/ResizeHandle.svelte +118 -0
- package/dist/Desktop/Grid/ResizeHandle.svelte.d.ts +23 -0
- package/dist/Desktop/Grid/index.d.ts +4 -0
- package/dist/Desktop/Grid/index.js +4 -0
- package/dist/Desktop/Grid/resizeStore.d.ts +16 -0
- package/dist/Desktop/Grid/resizeStore.js +39 -0
- package/dist/Desktop/GridRenderer.svelte +328 -0
- package/dist/Desktop/GridRenderer.svelte.d.ts +25 -0
- package/dist/Desktop/GridSelector/ComponentPalette.svelte +243 -0
- package/dist/Desktop/GridSelector/ComponentPalette.svelte.d.ts +27 -0
- package/dist/Desktop/GridSelector/ConfigurationPanel.svelte +242 -0
- package/dist/Desktop/GridSelector/ConfigurationPanel.svelte.d.ts +28 -0
- package/dist/Desktop/GridSelector/GridSelector.svelte +232 -0
- package/dist/Desktop/GridSelector/GridSelector.svelte.d.ts +43 -0
- package/dist/Desktop/GridSelector/LayoutPicker.svelte +241 -0
- package/dist/Desktop/GridSelector/LayoutPicker.svelte.d.ts +28 -0
- package/dist/Desktop/GridSelector/LayoutPreview.svelte +309 -0
- package/dist/Desktop/GridSelector/LayoutPreview.svelte.d.ts +32 -0
- package/dist/Desktop/GridSelector/index.d.ts +4 -0
- package/dist/Desktop/GridSelector/index.js +4 -0
- package/dist/Desktop/GridViewer.svelte +125 -0
- package/dist/Desktop/GridViewer.svelte.d.ts +21 -0
- package/dist/Desktop/README.md +279 -0
- package/dist/Desktop/gridLayouts.d.ts +76 -0
- package/dist/Desktop/gridLayouts.js +351 -0
- package/dist/Desktop/index.d.ts +7 -0
- package/dist/Desktop/index.js +7 -0
- package/dist/Desktop/launchHelpers.d.ts +25 -0
- package/dist/Desktop/launchHelpers.js +77 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +65 -0
@@ -0,0 +1,423 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<script lang="ts">
|
4
|
+
/**
|
5
|
+
* Desktop Component - Main Orchestrator
|
6
|
+
*
|
7
|
+
* Manages multiple grid configurations and provides a launcher interface.
|
8
|
+
* Users can create new grids, switch between existing ones, and manage their workspace.
|
9
|
+
*/
|
10
|
+
import { onMount } from 'svelte';
|
11
|
+
import { GridSelector, type ComponentConfig } from './GridSelector/index.js';
|
12
|
+
import { GridRenderer } from './index.js';
|
13
|
+
import type { GridConfiguration } from './gridLayouts.js';
|
14
|
+
|
15
|
+
// Props
|
16
|
+
export let availableComponents: ComponentConfig[] = [];
|
17
|
+
export let namespace: string = 'default-desktop';
|
18
|
+
export let theme: 'light' | 'dark' = 'light';
|
19
|
+
export let maxGrids: number = 10;
|
20
|
+
export let onLaunch: ((grid: GridConfiguration) => void) | null = null;
|
21
|
+
|
22
|
+
// State
|
23
|
+
let savedGrids: GridConfiguration[] = [];
|
24
|
+
let showGridSelector: boolean = false;
|
25
|
+
let isLoading: boolean = true;
|
26
|
+
let showFullscreenGrid: boolean = false;
|
27
|
+
let currentGrid: GridConfiguration | null = null;
|
28
|
+
let editingGrid: GridConfiguration | null = null;
|
29
|
+
|
30
|
+
// Storage keys
|
31
|
+
const STORAGE_KEY = `${namespace}:grids`;
|
32
|
+
|
33
|
+
// Load saved grids from localStorage
|
34
|
+
function loadSavedGrids() {
|
35
|
+
try {
|
36
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
37
|
+
if (stored) {
|
38
|
+
savedGrids = JSON.parse(stored);
|
39
|
+
}
|
40
|
+
} catch (error) {
|
41
|
+
console.error('Failed to load saved grids:', error);
|
42
|
+
savedGrids = [];
|
43
|
+
}
|
44
|
+
isLoading = false;
|
45
|
+
}
|
46
|
+
|
47
|
+
// Save grids to localStorage
|
48
|
+
function savePersistentData() {
|
49
|
+
try {
|
50
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(savedGrids));
|
51
|
+
} catch (error) {
|
52
|
+
console.error('Failed to save grids:', error);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
// Handle new grid creation or editing
|
57
|
+
function handleGridCreated(event: CustomEvent<GridConfiguration>) {
|
58
|
+
const gridData = event.detail;
|
59
|
+
|
60
|
+
if (editingGrid) {
|
61
|
+
// Update existing grid
|
62
|
+
const updatedGrid: GridConfiguration = {
|
63
|
+
...gridData,
|
64
|
+
id: editingGrid.id, // Keep the original ID
|
65
|
+
created: editingGrid.created, // Keep original creation date
|
66
|
+
modified: new Date().toISOString() // Update modification date
|
67
|
+
};
|
68
|
+
|
69
|
+
savedGrids = savedGrids.map(g => g.id === editingGrid!.id ? updatedGrid : g);
|
70
|
+
editingGrid = null;
|
71
|
+
} else {
|
72
|
+
// Create new grid
|
73
|
+
if (savedGrids.length >= maxGrids) {
|
74
|
+
alert(`Maximum of ${maxGrids} grids allowed. Please delete a grid first.`);
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
savedGrids = [...savedGrids, gridData];
|
78
|
+
}
|
79
|
+
|
80
|
+
showGridSelector = false;
|
81
|
+
savePersistentData();
|
82
|
+
}
|
83
|
+
|
84
|
+
// Handle grid selector cancel
|
85
|
+
function handleGridSelectorCancel() {
|
86
|
+
showGridSelector = false;
|
87
|
+
editingGrid = null;
|
88
|
+
}
|
89
|
+
|
90
|
+
// Show grid selector
|
91
|
+
function openGridSelector() {
|
92
|
+
editingGrid = null; // Clear any editing state
|
93
|
+
showGridSelector = true;
|
94
|
+
}
|
95
|
+
|
96
|
+
// Edit an existing grid
|
97
|
+
function editGrid(grid: GridConfiguration) {
|
98
|
+
editingGrid = grid;
|
99
|
+
showGridSelector = true;
|
100
|
+
}
|
101
|
+
|
102
|
+
// Switch to a specific grid - now opens in fullscreen view
|
103
|
+
function switchToGrid(gridId: string) {
|
104
|
+
if (gridId === '') {
|
105
|
+
// Back to launcher
|
106
|
+
showFullscreenGrid = false;
|
107
|
+
currentGrid = null;
|
108
|
+
return;
|
109
|
+
} else {
|
110
|
+
// Find the grid and open in fullscreen view
|
111
|
+
const grid = savedGrids.find(g => g.id === gridId);
|
112
|
+
if (grid) {
|
113
|
+
currentGrid = grid;
|
114
|
+
showFullscreenGrid = true;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
// Launch grid using callback
|
120
|
+
function launchGrid(gridId: string) {
|
121
|
+
const grid = savedGrids.find(g => g.id === gridId);
|
122
|
+
if (!grid) return;
|
123
|
+
|
124
|
+
// If no launch callback provided, do nothing
|
125
|
+
if (!onLaunch) {
|
126
|
+
console.warn('No onLaunch callback provided - grid launch ignored');
|
127
|
+
return;
|
128
|
+
}
|
129
|
+
|
130
|
+
// Call the parent's launch handler with the grid configuration
|
131
|
+
onLaunch(grid);
|
132
|
+
}
|
133
|
+
|
134
|
+
// Delete a grid
|
135
|
+
function deleteGrid(gridId: string) {
|
136
|
+
if (confirm('Are you sure you want to delete this grid? This action cannot be undone.')) {
|
137
|
+
savedGrids = savedGrids.filter(g => g.id !== gridId);
|
138
|
+
savePersistentData();
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
// Export grid configuration
|
145
|
+
function exportGrid(grid: GridConfiguration) {
|
146
|
+
const dataStr = JSON.stringify(grid, null, 2);
|
147
|
+
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
148
|
+
const url = URL.createObjectURL(dataBlob);
|
149
|
+
|
150
|
+
const link = document.createElement('a');
|
151
|
+
link.href = url;
|
152
|
+
link.download = `${grid.name.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_grid.json`;
|
153
|
+
link.click();
|
154
|
+
|
155
|
+
URL.revokeObjectURL(url);
|
156
|
+
}
|
157
|
+
|
158
|
+
// Close fullscreen grid view
|
159
|
+
function closeFullscreenGrid() {
|
160
|
+
showFullscreenGrid = false;
|
161
|
+
currentGrid = null;
|
162
|
+
}
|
163
|
+
|
164
|
+
// Load data on mount
|
165
|
+
onMount(() => {
|
166
|
+
loadSavedGrids();
|
167
|
+
|
168
|
+
// Add keyboard event listener
|
169
|
+
const handleKeydown = (event: KeyboardEvent) => {
|
170
|
+
if (showFullscreenGrid && event.key === 'Escape') {
|
171
|
+
closeFullscreenGrid();
|
172
|
+
}
|
173
|
+
};
|
174
|
+
|
175
|
+
document.addEventListener('keydown', handleKeydown);
|
176
|
+
|
177
|
+
// Cleanup
|
178
|
+
return () => {
|
179
|
+
document.removeEventListener('keydown', handleKeydown);
|
180
|
+
};
|
181
|
+
});
|
182
|
+
</script>
|
183
|
+
|
184
|
+
<div class="desktop-orchestrator" class:theme-dark={theme === 'dark'}>
|
185
|
+
{#if isLoading}
|
186
|
+
<div class="loading-screen">
|
187
|
+
<div class="loading-content">
|
188
|
+
<div class="spinner-border text-primary" role="status">
|
189
|
+
<span class="visually-hidden">Loading...</span>
|
190
|
+
</div>
|
191
|
+
<p class="mt-3">Loading Desktop...</p>
|
192
|
+
</div>
|
193
|
+
</div>
|
194
|
+
{:else if showFullscreenGrid && currentGrid}
|
195
|
+
<!-- Fullscreen Grid View -->
|
196
|
+
<div class="fullscreen-grid">
|
197
|
+
<div class="fullscreen-header">
|
198
|
+
<div class="d-flex justify-content-between align-items-center p-3 border-bottom">
|
199
|
+
<div class="d-flex align-items-center">
|
200
|
+
<button
|
201
|
+
class="btn btn-outline-secondary btn-sm me-3"
|
202
|
+
on:click={closeFullscreenGrid}
|
203
|
+
title="Back to launcher"
|
204
|
+
>
|
205
|
+
<i class="bi bi-arrow-left me-2" aria-hidden="true"></i>
|
206
|
+
Back
|
207
|
+
</button>
|
208
|
+
<h4 class="mb-0">{currentGrid.name}</h4>
|
209
|
+
</div>
|
210
|
+
<div class="text-muted small">
|
211
|
+
Press ESC to exit fullscreen
|
212
|
+
</div>
|
213
|
+
</div>
|
214
|
+
</div>
|
215
|
+
<div class="fullscreen-content">
|
216
|
+
<GridRenderer
|
217
|
+
grid={currentGrid}
|
218
|
+
componentMap={availableComponents.reduce((map, comp) => {
|
219
|
+
map[comp.id] = comp.component;
|
220
|
+
return map;
|
221
|
+
}, {} as Record<string, any>)}
|
222
|
+
fullscreen={true}
|
223
|
+
/>
|
224
|
+
</div>
|
225
|
+
</div>
|
226
|
+
{:else if showGridSelector}
|
227
|
+
<GridSelector
|
228
|
+
{availableComponents}
|
229
|
+
{theme}
|
230
|
+
existingGrid={editingGrid}
|
231
|
+
on:gridCreated={handleGridCreated}
|
232
|
+
on:cancel={handleGridSelectorCancel}
|
233
|
+
/>
|
234
|
+
{:else}
|
235
|
+
<!-- Launcher View -->
|
236
|
+
<div class="launcher-view">
|
237
|
+
<div class="launcher-header p-4 border-bottom">
|
238
|
+
<div class="d-flex justify-content-between align-items-center">
|
239
|
+
<div>
|
240
|
+
<h2 class="mb-1">Desktop Launcher</h2>
|
241
|
+
</div>
|
242
|
+
<button
|
243
|
+
class="btn btn-primary"
|
244
|
+
on:click={openGridSelector}
|
245
|
+
disabled={savedGrids.length >= maxGrids}
|
246
|
+
>
|
247
|
+
<i class="bi bi-plus me-2" aria-hidden="true"></i>
|
248
|
+
Create New Grid
|
249
|
+
</button>
|
250
|
+
</div>
|
251
|
+
</div>
|
252
|
+
|
253
|
+
<div class="launcher-content p-4">
|
254
|
+
{#if savedGrids.length === 0}
|
255
|
+
<div class="empty-state">
|
256
|
+
<div class="empty-content">
|
257
|
+
|
258
|
+
<button class="btn btn-primary btn-lg" on:click={openGridSelector}>
|
259
|
+
<i class="bi bi-plus me-2" aria-hidden="true"></i>
|
260
|
+
Create New Grid
|
261
|
+
</button>
|
262
|
+
</div>
|
263
|
+
</div>
|
264
|
+
{:else}
|
265
|
+
<div class="grids-container">
|
266
|
+
<div class="row">
|
267
|
+
{#each savedGrids as grid}
|
268
|
+
<div class="col-md-6 col-lg-4 mb-4">
|
269
|
+
<div class="grid-card card h-100">
|
270
|
+
<div class="card-body">
|
271
|
+
<h5 class="card-title">{grid.name}</h5>
|
272
|
+
<p class="card-text text-muted">
|
273
|
+
Layout: {grid.layoutId}<br>
|
274
|
+
Components: {grid.componentAssignments.length}<br>
|
275
|
+
Created: {new Date(grid.created).toLocaleDateString()}
|
276
|
+
</p>
|
277
|
+
</div>
|
278
|
+
<div class="card-footer bg-transparent">
|
279
|
+
<div class="d-flex gap-2">
|
280
|
+
<button
|
281
|
+
class="btn btn-primary btn-sm"
|
282
|
+
on:click={() => switchToGrid(grid.id)}
|
283
|
+
>
|
284
|
+
Open
|
285
|
+
</button>
|
286
|
+
<button
|
287
|
+
class="btn btn-outline-secondary btn-sm"
|
288
|
+
on:click={() => editGrid(grid)}
|
289
|
+
aria-label="Edit grid"
|
290
|
+
title="Edit grid"
|
291
|
+
>
|
292
|
+
<i class="bi bi-pencil" aria-hidden="true"></i>
|
293
|
+
</button>
|
294
|
+
<button
|
295
|
+
class="btn btn-outline-primary btn-sm"
|
296
|
+
on:click={() => launchGrid(grid.id)}
|
297
|
+
aria-label="Launch in new window"
|
298
|
+
title="Launch in new window"
|
299
|
+
>
|
300
|
+
<i class="bi bi-box-arrow-up-right" aria-hidden="true"></i>
|
301
|
+
</button>
|
302
|
+
<button
|
303
|
+
class="btn btn-outline-danger btn-sm"
|
304
|
+
on:click={() => deleteGrid(grid.id)}
|
305
|
+
aria-label="Delete grid"
|
306
|
+
title="Delete grid"
|
307
|
+
>
|
308
|
+
<i class="bi bi-trash" aria-hidden="true"></i>
|
309
|
+
</button>
|
310
|
+
</div>
|
311
|
+
</div>
|
312
|
+
</div>
|
313
|
+
</div>
|
314
|
+
{/each}
|
315
|
+
</div>
|
316
|
+
|
317
|
+
{#if savedGrids.length >= maxGrids}
|
318
|
+
<div class="alert alert-warning">
|
319
|
+
<i class="bi bi-exclamation-triangle me-2" aria-hidden="true"></i>
|
320
|
+
Maximum number of grids ({maxGrids}) reached. Delete a grid to create a new one.
|
321
|
+
</div>
|
322
|
+
{/if}
|
323
|
+
</div>
|
324
|
+
{/if}
|
325
|
+
</div>
|
326
|
+
</div>
|
327
|
+
{/if}
|
328
|
+
</div>
|
329
|
+
|
330
|
+
<style>
|
331
|
+
.desktop-orchestrator {
|
332
|
+
height: 100vh;
|
333
|
+
background: #fff;
|
334
|
+
display: flex;
|
335
|
+
flex-direction: column;
|
336
|
+
}
|
337
|
+
|
338
|
+
.loading-screen {
|
339
|
+
height: 100vh;
|
340
|
+
display: flex;
|
341
|
+
align-items: center;
|
342
|
+
justify-content: center;
|
343
|
+
}
|
344
|
+
|
345
|
+
.loading-content {
|
346
|
+
text-align: center;
|
347
|
+
}
|
348
|
+
|
349
|
+
.launcher-view {
|
350
|
+
height: 100vh;
|
351
|
+
display: flex;
|
352
|
+
flex-direction: column;
|
353
|
+
}
|
354
|
+
|
355
|
+
.launcher-content {
|
356
|
+
flex: 1;
|
357
|
+
overflow-y: auto;
|
358
|
+
}
|
359
|
+
|
360
|
+
.fullscreen-grid {
|
361
|
+
height: 100vh;
|
362
|
+
display: flex;
|
363
|
+
flex-direction: column;
|
364
|
+
}
|
365
|
+
|
366
|
+
.fullscreen-content {
|
367
|
+
flex: 1;
|
368
|
+
overflow: hidden;
|
369
|
+
}
|
370
|
+
|
371
|
+
.empty-state {
|
372
|
+
display: flex;
|
373
|
+
align-items: center;
|
374
|
+
justify-content: center;
|
375
|
+
min-height: 400px;
|
376
|
+
}
|
377
|
+
|
378
|
+
.empty-content {
|
379
|
+
text-align: center;
|
380
|
+
max-width: 500px;
|
381
|
+
}
|
382
|
+
|
383
|
+
.grid-card {
|
384
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
385
|
+
cursor: pointer;
|
386
|
+
}
|
387
|
+
|
388
|
+
.grid-card:hover {
|
389
|
+
transform: translateY(-2px);
|
390
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
391
|
+
}
|
392
|
+
|
393
|
+
/* Dark theme */
|
394
|
+
.theme-dark {
|
395
|
+
background: #1a1a1a;
|
396
|
+
color: #fff;
|
397
|
+
}
|
398
|
+
|
399
|
+
.theme-dark .border-bottom {
|
400
|
+
border-color: #404040 !important;
|
401
|
+
}
|
402
|
+
|
403
|
+
.theme-dark .card {
|
404
|
+
background: #2d2d2d;
|
405
|
+
border-color: #404040;
|
406
|
+
}
|
407
|
+
|
408
|
+
.theme-dark .card-footer {
|
409
|
+
border-color: #404040;
|
410
|
+
}
|
411
|
+
|
412
|
+
.theme-dark .text-muted {
|
413
|
+
color: #999 !important;
|
414
|
+
}
|
415
|
+
|
416
|
+
/* Responsive adjustments */
|
417
|
+
@media (max-width: 768px) {
|
418
|
+
.launcher-header .d-flex {
|
419
|
+
flex-direction: column;
|
420
|
+
gap: 1rem;
|
421
|
+
}
|
422
|
+
}
|
423
|
+
</style>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { type ComponentConfig } from './GridSelector/index.js';
|
2
|
+
import type { GridConfiguration } from './gridLayouts.js';
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
5
|
+
$$bindings?: Bindings;
|
6
|
+
} & Exports;
|
7
|
+
(internal: unknown, props: Props & {
|
8
|
+
$$events?: Events;
|
9
|
+
$$slots?: Slots;
|
10
|
+
}): Exports & {
|
11
|
+
$set?: any;
|
12
|
+
$on?: any;
|
13
|
+
};
|
14
|
+
z_$$bindings?: Bindings;
|
15
|
+
}
|
16
|
+
declare const Desktop: $$__sveltets_2_IsomorphicComponent<{
|
17
|
+
availableComponents?: ComponentConfig[];
|
18
|
+
namespace?: string;
|
19
|
+
theme?: "light" | "dark";
|
20
|
+
maxGrids?: number;
|
21
|
+
onLaunch?: ((grid: GridConfiguration) => void) | null;
|
22
|
+
}, {
|
23
|
+
[evt: string]: CustomEvent<any>;
|
24
|
+
}, {}, {}, string>;
|
25
|
+
type Desktop = InstanceType<typeof Desktop>;
|
26
|
+
export default Desktop;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
export let position: 'left' | 'right' | 'top' | 'bottom' = 'left';
|
3
|
+
</script>
|
4
|
+
|
5
|
+
<div class="half {position}">
|
6
|
+
<slot />
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<style>
|
10
|
+
.half {
|
11
|
+
display: flex;
|
12
|
+
align-items: stretch;
|
13
|
+
justify-content: stretch;
|
14
|
+
border: 1px solid #ccc;
|
15
|
+
overflow: hidden;
|
16
|
+
width: 100%;
|
17
|
+
height: 100%;
|
18
|
+
min-height: 0; /* Important for flex children */
|
19
|
+
min-width: 0; /* Important for flex children */
|
20
|
+
}
|
21
|
+
|
22
|
+
.half > :global(*) {
|
23
|
+
width: 100%;
|
24
|
+
height: 100%;
|
25
|
+
max-width: 100%;
|
26
|
+
max-height: 100%;
|
27
|
+
box-sizing: border-box;
|
28
|
+
}
|
29
|
+
|
30
|
+
/* Positions */
|
31
|
+
.left {
|
32
|
+
grid-column: 1 / 2;
|
33
|
+
grid-row: 1 / -1;
|
34
|
+
}
|
35
|
+
|
36
|
+
.right {
|
37
|
+
grid-column: 2 / 3;
|
38
|
+
grid-row: 1 / -1;
|
39
|
+
}
|
40
|
+
|
41
|
+
.top {
|
42
|
+
grid-row: 1 / 2;
|
43
|
+
grid-column: 1 / -1;
|
44
|
+
}
|
45
|
+
|
46
|
+
.bottom {
|
47
|
+
grid-row: 2 / 3;
|
48
|
+
grid-column: 1 / -1;
|
49
|
+
}
|
50
|
+
</style>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
3
|
+
$$bindings?: Bindings;
|
4
|
+
} & Exports;
|
5
|
+
(internal: unknown, props: Props & {
|
6
|
+
$$events?: Events;
|
7
|
+
$$slots?: Slots;
|
8
|
+
}): Exports & {
|
9
|
+
$set?: any;
|
10
|
+
$on?: any;
|
11
|
+
};
|
12
|
+
z_$$bindings?: Bindings;
|
13
|
+
}
|
14
|
+
type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
|
15
|
+
default: any;
|
16
|
+
} ? Props extends Record<string, never> ? any : {
|
17
|
+
children?: any;
|
18
|
+
} : {});
|
19
|
+
declare const Half: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
|
20
|
+
position?: "left" | "right" | "top" | "bottom";
|
21
|
+
}, {
|
22
|
+
default: {};
|
23
|
+
}>, {
|
24
|
+
[evt: string]: CustomEvent<any>;
|
25
|
+
}, {
|
26
|
+
default: {};
|
27
|
+
}, {}, string>;
|
28
|
+
type Half = InstanceType<typeof Half>;
|
29
|
+
export default Half;
|
@@ -0,0 +1,103 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
export let position: 'left' | 'right' | 'top' | 'bottom';
|
3
|
+
export let topHeight: number = 50;
|
4
|
+
export let bottomHeight: number = 50;
|
5
|
+
export let leftWidth: number = 50;
|
6
|
+
export let rightWidth: number = 50;
|
7
|
+
</script>
|
8
|
+
|
9
|
+
<div class="quarters {position}"
|
10
|
+
style="--top-height: {topHeight}%; --bottom-height: {bottomHeight}%; --left-width: {leftWidth}%; --right-width: {rightWidth}%">
|
11
|
+
<div class="quarter top-or-left">
|
12
|
+
<slot name="top-or-left" />
|
13
|
+
</div>
|
14
|
+
<div class="quarter bottom-or-right">
|
15
|
+
<slot name="bottom-or-right" />
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<style>
|
20
|
+
.quarters {
|
21
|
+
border: 1px solid #aaa;
|
22
|
+
display: grid;
|
23
|
+
overflow: hidden;
|
24
|
+
width: 100%;
|
25
|
+
height: 100%;
|
26
|
+
}
|
27
|
+
|
28
|
+
/* Position the quarters container within the parent grid */
|
29
|
+
.quarters.left {
|
30
|
+
grid-column: 1 / 2;
|
31
|
+
grid-row: 1 / -1; /* Span all rows within the column */
|
32
|
+
}
|
33
|
+
|
34
|
+
.quarters.right {
|
35
|
+
grid-column: 2 / 3;
|
36
|
+
grid-row: 1 / -1; /* Span all rows within the column */
|
37
|
+
}
|
38
|
+
|
39
|
+
.quarters.top {
|
40
|
+
grid-row: 1 / 2;
|
41
|
+
grid-column: 1 / -1;
|
42
|
+
}
|
43
|
+
|
44
|
+
.quarters.bottom {
|
45
|
+
grid-row: 2 / 3;
|
46
|
+
grid-column: 1 / -1;
|
47
|
+
}
|
48
|
+
|
49
|
+
/* Left and Right quarters are stacked (vertical split) */
|
50
|
+
.quarters.left,
|
51
|
+
.quarters.right {
|
52
|
+
grid-template-rows: var(--top-height) var(--bottom-height);
|
53
|
+
grid-template-columns: 1fr;
|
54
|
+
}
|
55
|
+
|
56
|
+
/* Top and Bottom quarters are side-by-side (horizontal split) */
|
57
|
+
.quarters.top,
|
58
|
+
.quarters.bottom {
|
59
|
+
grid-template-columns: var(--left-width) var(--right-width);
|
60
|
+
grid-template-rows: 1fr;
|
61
|
+
}
|
62
|
+
|
63
|
+
.quarter {
|
64
|
+
border: 1px solid #ddd;
|
65
|
+
display: flex;
|
66
|
+
align-items: stretch;
|
67
|
+
justify-content: stretch;
|
68
|
+
overflow: hidden;
|
69
|
+
width: 100%;
|
70
|
+
height: 100%;
|
71
|
+
min-height: 0; /* Important for flex children */
|
72
|
+
min-width: 0; /* Important for flex children */
|
73
|
+
}
|
74
|
+
|
75
|
+
.quarter > :global(*) {
|
76
|
+
width: 100%;
|
77
|
+
height: 100%;
|
78
|
+
max-width: 100%;
|
79
|
+
max-height: 100%;
|
80
|
+
box-sizing: border-box;
|
81
|
+
}
|
82
|
+
|
83
|
+
/* Position within the grid */
|
84
|
+
.quarters.left .top-or-left,
|
85
|
+
.quarters.right .top-or-left {
|
86
|
+
grid-row: 1;
|
87
|
+
}
|
88
|
+
|
89
|
+
.quarters.left .bottom-or-right,
|
90
|
+
.quarters.right .bottom-or-right {
|
91
|
+
grid-row: 2;
|
92
|
+
}
|
93
|
+
|
94
|
+
.quarters.top .top-or-left,
|
95
|
+
.quarters.bottom .top-or-left {
|
96
|
+
grid-column: 1;
|
97
|
+
}
|
98
|
+
|
99
|
+
.quarters.top .bottom-or-right,
|
100
|
+
.quarters.bottom .bottom-or-right {
|
101
|
+
grid-column: 2;
|
102
|
+
}
|
103
|
+
</style>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
3
|
+
$$bindings?: Bindings;
|
4
|
+
} & Exports;
|
5
|
+
(internal: unknown, props: Props & {
|
6
|
+
$$events?: Events;
|
7
|
+
$$slots?: Slots;
|
8
|
+
}): Exports & {
|
9
|
+
$set?: any;
|
10
|
+
$on?: any;
|
11
|
+
};
|
12
|
+
z_$$bindings?: Bindings;
|
13
|
+
}
|
14
|
+
declare const Quarter: $$__sveltets_2_IsomorphicComponent<{
|
15
|
+
position: "left" | "right" | "top" | "bottom";
|
16
|
+
topHeight?: number;
|
17
|
+
bottomHeight?: number;
|
18
|
+
leftWidth?: number;
|
19
|
+
rightWidth?: number;
|
20
|
+
}, {
|
21
|
+
[evt: string]: CustomEvent<any>;
|
22
|
+
}, {
|
23
|
+
'top-or-left': {};
|
24
|
+
'bottom-or-right': {};
|
25
|
+
}, {}, string>;
|
26
|
+
type Quarter = InstanceType<typeof Quarter>;
|
27
|
+
export default Quarter;
|