@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,328 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
/**
|
3
|
+
* GridRenderer Component
|
4
|
+
*
|
5
|
+
* Reusable component that renders a GridConfiguration using Half/Quarter components.
|
6
|
+
* Can be used in full-screen mode, embedded in other apps, or anywhere else.
|
7
|
+
*/
|
8
|
+
import { Half, Quarter, ResizeHandle, resizeStore } from '../index.js';
|
9
|
+
import type { GridConfiguration } from './gridLayouts.js';
|
10
|
+
|
11
|
+
// Props
|
12
|
+
export let grid: GridConfiguration;
|
13
|
+
export let componentMap: Record<string, any> = {};
|
14
|
+
export let fullscreen: boolean = false;
|
15
|
+
export let showEmptySlots: boolean = true;
|
16
|
+
export let enableResize: boolean = true;
|
17
|
+
|
18
|
+
// Resize state
|
19
|
+
let leftWidth = 50;
|
20
|
+
let rightWidth = 50;
|
21
|
+
let topHeight = 50;
|
22
|
+
let bottomHeight = 50;
|
23
|
+
|
24
|
+
// Subscribe to resize store changes
|
25
|
+
if (enableResize) {
|
26
|
+
resizeStore.subscribe((state: any) => {
|
27
|
+
leftWidth = state.leftWidth;
|
28
|
+
rightWidth = state.rightWidth;
|
29
|
+
topHeight = state.topHeight;
|
30
|
+
bottomHeight = state.bottomHeight;
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
// Handle resize events
|
35
|
+
function handleResize(event: CustomEvent) {
|
36
|
+
if (!enableResize) return;
|
37
|
+
|
38
|
+
const { horizontalSize, verticalSize } = event.detail;
|
39
|
+
if (horizontalSize !== undefined && verticalSize !== undefined) {
|
40
|
+
resizeStore.update2D(horizontalSize, verticalSize);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
// Get component for assignment
|
45
|
+
function getComponent(componentId: string) {
|
46
|
+
return componentMap[componentId];
|
47
|
+
}
|
48
|
+
|
49
|
+
// Get assigned component for a slot
|
50
|
+
function getAssignedComponent(slotId: string) {
|
51
|
+
if (!grid) return null;
|
52
|
+
|
53
|
+
const assignment = grid.componentAssignments.find(a => a.slotId === slotId);
|
54
|
+
if (!assignment) return null;
|
55
|
+
|
56
|
+
return getComponent(assignment.componentId);
|
57
|
+
}
|
58
|
+
|
59
|
+
// Render a slot with component or empty state
|
60
|
+
function renderSlot(slotId: string, slotName: string) {
|
61
|
+
const component = getAssignedComponent(slotId);
|
62
|
+
|
63
|
+
if (component) {
|
64
|
+
return {
|
65
|
+
hasComponent: true,
|
66
|
+
component: component
|
67
|
+
};
|
68
|
+
} else if (showEmptySlots) {
|
69
|
+
return {
|
70
|
+
hasComponent: false,
|
71
|
+
emptyMessage: `No component assigned to ${slotName} section`
|
72
|
+
};
|
73
|
+
}
|
74
|
+
|
75
|
+
return { hasComponent: false };
|
76
|
+
}
|
77
|
+
</script>
|
78
|
+
|
79
|
+
<!-- Slot rendering snippet -->
|
80
|
+
{#snippet slotContent(slotId, slotName)}
|
81
|
+
{@const slot = renderSlot(slotId, slotName)}
|
82
|
+
{#if slot.hasComponent}
|
83
|
+
<div class="component-wrapper">
|
84
|
+
<svelte:component this={slot.component} />
|
85
|
+
</div>
|
86
|
+
{:else if slot.emptyMessage}
|
87
|
+
<div class="empty-slot">
|
88
|
+
<p>{slot.emptyMessage}</p>
|
89
|
+
</div>
|
90
|
+
{/if}
|
91
|
+
{/snippet}
|
92
|
+
|
93
|
+
{#if grid}
|
94
|
+
<!-- Render the grid based on layout type -->
|
95
|
+
{#if grid.layoutId === 'half-horizontal'}
|
96
|
+
<div class="grid-container" class:fullscreen
|
97
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: 1fr;">
|
98
|
+
<!-- Left Half -->
|
99
|
+
<Half position="left">
|
100
|
+
{@render slotContent('left', 'left')}
|
101
|
+
</Half>
|
102
|
+
|
103
|
+
<!-- Right Half -->
|
104
|
+
<Half position="right">
|
105
|
+
{@render slotContent('right', 'right')}
|
106
|
+
</Half>
|
107
|
+
</div>
|
108
|
+
|
109
|
+
{:else if grid.layoutId === 'half-vertical'}
|
110
|
+
<div class="grid-container" class:fullscreen
|
111
|
+
style="grid-template-columns: 1fr; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
112
|
+
<!-- Top Half -->
|
113
|
+
<Half position="top">
|
114
|
+
{@render slotContent('top', 'top')}
|
115
|
+
</Half>
|
116
|
+
|
117
|
+
<!-- Bottom Half -->
|
118
|
+
<Half position="bottom">
|
119
|
+
{@render slotContent('bottom', 'bottom')}
|
120
|
+
</Half>
|
121
|
+
</div>
|
122
|
+
|
123
|
+
{:else if grid.layoutId === 'left-half-right-quarters'}
|
124
|
+
<div class="grid-container" class:fullscreen
|
125
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
126
|
+
<!-- Left Half -->
|
127
|
+
<Half position="left">
|
128
|
+
{@render slotContent('left', 'left')}
|
129
|
+
</Half>
|
130
|
+
|
131
|
+
<!-- Right side with quarters -->
|
132
|
+
<Quarter position="right" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
133
|
+
<div slot="top-or-left">
|
134
|
+
{@render slotContent('top-right', 'top-right')}
|
135
|
+
</div>
|
136
|
+
|
137
|
+
<div slot="bottom-or-right">
|
138
|
+
{@render slotContent('bottom-right', 'bottom-right')}
|
139
|
+
</div>
|
140
|
+
</Quarter>
|
141
|
+
</div>
|
142
|
+
|
143
|
+
{:else if grid.layoutId === 'right-half-left-quarters'}
|
144
|
+
<div class="grid-container" class:fullscreen
|
145
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
146
|
+
<!-- Left side with quarters -->
|
147
|
+
<Quarter position="left" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
148
|
+
<div slot="top-or-left">
|
149
|
+
{@render slotContent('top-left', 'top-left')}
|
150
|
+
</div>
|
151
|
+
|
152
|
+
<div slot="bottom-or-right">
|
153
|
+
{@render slotContent('bottom-left', 'bottom-left')}
|
154
|
+
</div>
|
155
|
+
</Quarter>
|
156
|
+
|
157
|
+
<!-- Right Half -->
|
158
|
+
<Half position="right">
|
159
|
+
{@render slotContent('right', 'right')}
|
160
|
+
</Half>
|
161
|
+
</div>
|
162
|
+
|
163
|
+
{:else if grid.layoutId === 'top-half-bottom-quarters'}
|
164
|
+
<div class="grid-container" class:fullscreen
|
165
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
166
|
+
<!-- Top Half -->
|
167
|
+
<Half position="top">
|
168
|
+
{@render slotContent('top', 'top')}
|
169
|
+
</Half>
|
170
|
+
|
171
|
+
<!-- Bottom side with quarters -->
|
172
|
+
<Quarter position="bottom" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
173
|
+
<div slot="top-or-left">
|
174
|
+
{@render slotContent('bottom-left', 'bottom-left')}
|
175
|
+
</div>
|
176
|
+
|
177
|
+
<div slot="bottom-or-right">
|
178
|
+
{@render slotContent('bottom-right', 'bottom-right')}
|
179
|
+
</div>
|
180
|
+
</Quarter>
|
181
|
+
</div>
|
182
|
+
|
183
|
+
{:else if grid.layoutId === 'bottom-half-top-quarters'}
|
184
|
+
<div class="grid-container" class:fullscreen
|
185
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
186
|
+
<!-- Top side with quarters -->
|
187
|
+
<Quarter position="top" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
188
|
+
<div slot="top-or-left">
|
189
|
+
{@render slotContent('top-left', 'top-left')}
|
190
|
+
</div>
|
191
|
+
|
192
|
+
<div slot="bottom-or-right">
|
193
|
+
{@render slotContent('top-right', 'top-right')}
|
194
|
+
</div>
|
195
|
+
</Quarter>
|
196
|
+
|
197
|
+
<!-- Bottom Half -->
|
198
|
+
<Half position="bottom">
|
199
|
+
{@render slotContent('bottom', 'bottom')}
|
200
|
+
</Half>
|
201
|
+
</div>
|
202
|
+
|
203
|
+
{:else if grid.layoutId === 'quarters'}
|
204
|
+
<div class="grid-container" class:fullscreen
|
205
|
+
style="grid-template-columns: {leftWidth}% {rightWidth}%; grid-template-rows: {topHeight}% {bottomHeight}%;">
|
206
|
+
<!-- Top quarters -->
|
207
|
+
<Quarter position="top" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
208
|
+
<div slot="top-or-left">
|
209
|
+
{@render slotContent('top-left', 'top-left')}
|
210
|
+
</div>
|
211
|
+
|
212
|
+
<div slot="bottom-or-right">
|
213
|
+
{@render slotContent('top-right', 'top-right')}
|
214
|
+
</div>
|
215
|
+
</Quarter>
|
216
|
+
|
217
|
+
<!-- Bottom quarters -->
|
218
|
+
<Quarter position="bottom" topHeight={topHeight} bottomHeight={bottomHeight} leftWidth={leftWidth} rightWidth={rightWidth}>
|
219
|
+
<div slot="top-or-left">
|
220
|
+
{@render slotContent('bottom-left', 'bottom-left')}
|
221
|
+
</div>
|
222
|
+
|
223
|
+
<div slot="bottom-or-right">
|
224
|
+
{@render slotContent('bottom-right', 'bottom-right')}
|
225
|
+
</div>
|
226
|
+
</Quarter>
|
227
|
+
</div>
|
228
|
+
|
229
|
+
{:else}
|
230
|
+
<div class="error-container">
|
231
|
+
<div class="error-content">
|
232
|
+
<div class="error-icon">🤷</div>
|
233
|
+
<h3>Unsupported Layout</h3>
|
234
|
+
<p class="text-muted">Layout type "{grid.layoutId}" is not yet supported</p>
|
235
|
+
</div>
|
236
|
+
</div>
|
237
|
+
{/if}
|
238
|
+
|
239
|
+
<!-- Universal Resize Handle - applies to all valid layouts -->
|
240
|
+
{#if grid && enableResize}
|
241
|
+
<ResizeHandle
|
242
|
+
horizontalSize={leftWidth}
|
243
|
+
verticalSize={topHeight}
|
244
|
+
on:resize={handleResize}
|
245
|
+
/>
|
246
|
+
{/if}
|
247
|
+
{:else}
|
248
|
+
<div class="error-container">
|
249
|
+
<div class="error-content">
|
250
|
+
<div class="error-icon">⚠️</div>
|
251
|
+
<h3>No Grid Configuration</h3>
|
252
|
+
<p class="text-muted">No grid configuration provided</p>
|
253
|
+
</div>
|
254
|
+
</div>
|
255
|
+
{/if}
|
256
|
+
|
257
|
+
<style>
|
258
|
+
.grid-container {
|
259
|
+
height: 100%;
|
260
|
+
width: 100%;
|
261
|
+
display: grid;
|
262
|
+
position: relative;
|
263
|
+
background: #f0f0f0;
|
264
|
+
}
|
265
|
+
|
266
|
+
.grid-container.fullscreen {
|
267
|
+
height: 100vh;
|
268
|
+
width: 100vw;
|
269
|
+
}
|
270
|
+
|
271
|
+
.component-wrapper {
|
272
|
+
width: 100%;
|
273
|
+
height: 100%;
|
274
|
+
max-width: 100%;
|
275
|
+
max-height: 100%;
|
276
|
+
overflow: hidden;
|
277
|
+
display: flex;
|
278
|
+
flex-direction: column;
|
279
|
+
box-sizing: border-box;
|
280
|
+
}
|
281
|
+
|
282
|
+
.component-wrapper > :global(*) {
|
283
|
+
flex: 1;
|
284
|
+
min-height: 0;
|
285
|
+
min-width: 0;
|
286
|
+
max-width: 100%;
|
287
|
+
max-height: 100%;
|
288
|
+
box-sizing: border-box;
|
289
|
+
}
|
290
|
+
|
291
|
+
.empty-slot {
|
292
|
+
display: flex;
|
293
|
+
align-items: center;
|
294
|
+
justify-content: center;
|
295
|
+
background: #f8f9fa;
|
296
|
+
border: 2px dashed #dee2e6;
|
297
|
+
margin: 8px;
|
298
|
+
border-radius: 8px;
|
299
|
+
color: #6c757d;
|
300
|
+
min-height: 100px;
|
301
|
+
}
|
302
|
+
|
303
|
+
.empty-slot p {
|
304
|
+
margin: 0;
|
305
|
+
font-style: italic;
|
306
|
+
text-align: center;
|
307
|
+
padding: 1rem;
|
308
|
+
}
|
309
|
+
|
310
|
+
.error-container {
|
311
|
+
height: 100%;
|
312
|
+
display: flex;
|
313
|
+
align-items: center;
|
314
|
+
justify-content: center;
|
315
|
+
background: #f8f9fa;
|
316
|
+
}
|
317
|
+
|
318
|
+
.error-content {
|
319
|
+
text-align: center;
|
320
|
+
max-width: 400px;
|
321
|
+
padding: 2rem;
|
322
|
+
}
|
323
|
+
|
324
|
+
.error-icon {
|
325
|
+
font-size: 4rem;
|
326
|
+
margin-bottom: 1rem;
|
327
|
+
}
|
328
|
+
</style>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import type { GridConfiguration } from './gridLayouts.js';
|
2
|
+
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> {
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
4
|
+
$$bindings?: Bindings;
|
5
|
+
} & Exports;
|
6
|
+
(internal: unknown, props: Props & {
|
7
|
+
$$events?: Events;
|
8
|
+
$$slots?: Slots;
|
9
|
+
}): Exports & {
|
10
|
+
$set?: any;
|
11
|
+
$on?: any;
|
12
|
+
};
|
13
|
+
z_$$bindings?: Bindings;
|
14
|
+
}
|
15
|
+
declare const GridRenderer: $$__sveltets_2_IsomorphicComponent<{
|
16
|
+
grid: GridConfiguration;
|
17
|
+
componentMap?: Record<string, any>;
|
18
|
+
fullscreen?: boolean;
|
19
|
+
showEmptySlots?: boolean;
|
20
|
+
enableResize?: boolean;
|
21
|
+
}, {
|
22
|
+
[evt: string]: CustomEvent<any>;
|
23
|
+
}, {}, {}, string>;
|
24
|
+
type GridRenderer = InstanceType<typeof GridRenderer>;
|
25
|
+
export default GridRenderer;
|
@@ -0,0 +1,243 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
/**
|
3
|
+
* Component Info Panel
|
4
|
+
*
|
5
|
+
* Simple informational display of available components.
|
6
|
+
* No drag-and-drop needed since dropdowns handle selection.
|
7
|
+
*/
|
8
|
+
import type { ComponentConfig } from './GridSelector.svelte';
|
9
|
+
|
10
|
+
export let availableComponents: ComponentConfig[] = [];
|
11
|
+
|
12
|
+
// Group components by category if available
|
13
|
+
$: componentsByCategory = availableComponents.reduce((acc, component) => {
|
14
|
+
const category = component.category || 'General';
|
15
|
+
if (!acc[category]) acc[category] = [];
|
16
|
+
acc[category].push(component);
|
17
|
+
return acc;
|
18
|
+
}, {} as Record<string, ComponentConfig[]>);
|
19
|
+
|
20
|
+
$: categoryKeys = Object.keys(componentsByCategory).sort();
|
21
|
+
</script>
|
22
|
+
|
23
|
+
<div class="component-info p-3">
|
24
|
+
<div class="info-header mb-3">
|
25
|
+
<h6 class="mb-1">
|
26
|
+
<span class="step-number badge bg-info me-2">ℹ️</span>
|
27
|
+
Available Components
|
28
|
+
</h6>
|
29
|
+
<small class="text-muted">
|
30
|
+
{availableComponents.length} components ready to use
|
31
|
+
</small>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
{#if availableComponents.length === 0}
|
35
|
+
<div class="empty-state text-center py-4">
|
36
|
+
<div class="text-muted mb-2">
|
37
|
+
<i class="fas fa-cube" style="font-size: 2rem; opacity: 0.3;"></i>
|
38
|
+
</div>
|
39
|
+
<p class="text-muted mb-0">No components available</p>
|
40
|
+
</div>
|
41
|
+
{:else}
|
42
|
+
<div class="components-list">
|
43
|
+
{#each categoryKeys as category}
|
44
|
+
<div class="component-category mb-3">
|
45
|
+
{#if categoryKeys.length > 1}
|
46
|
+
<div class="category-title mb-2">
|
47
|
+
<small class="text-muted fw-bold">{category}</small>
|
48
|
+
</div>
|
49
|
+
{/if}
|
50
|
+
|
51
|
+
<div class="component-items">
|
52
|
+
{#each componentsByCategory[category] as component}
|
53
|
+
<div class="component-item-info">
|
54
|
+
<div class="component-icon">
|
55
|
+
{#if component.icon}
|
56
|
+
{#if component.icon.startsWith('http') || component.icon.startsWith('/') || component.icon.startsWith('.')}
|
57
|
+
<img src={component.icon} alt={component.name} />
|
58
|
+
{:else}
|
59
|
+
<span class="icon-emoji">{component.icon}</span>
|
60
|
+
{/if}
|
61
|
+
{:else}
|
62
|
+
<span class="icon-default">📦</span>
|
63
|
+
{/if}
|
64
|
+
</div>
|
65
|
+
|
66
|
+
<div class="component-info">
|
67
|
+
<div class="component-name">{component.name}</div>
|
68
|
+
{#if component.description}
|
69
|
+
<div class="component-description">{component.description}</div>
|
70
|
+
{/if}
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
{/each}
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
{/each}
|
77
|
+
</div>
|
78
|
+
|
79
|
+
<div class="usage-instructions mt-3 p-2 bg-light rounded">
|
80
|
+
<small class="text-muted">
|
81
|
+
<i class="fas fa-info-circle me-1"></i>
|
82
|
+
Use the dropdowns in the preview area to assign components
|
83
|
+
</small>
|
84
|
+
</div>
|
85
|
+
{/if}
|
86
|
+
</div>
|
87
|
+
|
88
|
+
|
89
|
+
<style>
|
90
|
+
.component-info {
|
91
|
+
height: 100%;
|
92
|
+
overflow-y: auto;
|
93
|
+
}
|
94
|
+
|
95
|
+
.empty-state {
|
96
|
+
display: flex;
|
97
|
+
flex-direction: column;
|
98
|
+
align-items: center;
|
99
|
+
justify-content: center;
|
100
|
+
min-height: 200px;
|
101
|
+
}
|
102
|
+
|
103
|
+
.component-item-info {
|
104
|
+
display: flex;
|
105
|
+
align-items: center;
|
106
|
+
gap: 12px;
|
107
|
+
padding: 8px;
|
108
|
+
border: 1px solid #e9ecef;
|
109
|
+
border-radius: 6px;
|
110
|
+
background: #fff;
|
111
|
+
margin-bottom: 6px;
|
112
|
+
transition: all 0.2s ease;
|
113
|
+
}
|
114
|
+
|
115
|
+
.component-item-info:hover {
|
116
|
+
border-color: #007bff;
|
117
|
+
background: #f8f9fa;
|
118
|
+
}
|
119
|
+
|
120
|
+
.component-icon {
|
121
|
+
flex-shrink: 0;
|
122
|
+
width: 28px;
|
123
|
+
height: 28px;
|
124
|
+
display: flex;
|
125
|
+
align-items: center;
|
126
|
+
justify-content: center;
|
127
|
+
background: #f8f9fa;
|
128
|
+
border-radius: 4px;
|
129
|
+
border: 1px solid #dee2e6;
|
130
|
+
}
|
131
|
+
|
132
|
+
.component-icon img {
|
133
|
+
width: 20px;
|
134
|
+
height: 20px;
|
135
|
+
object-fit: contain;
|
136
|
+
}
|
137
|
+
|
138
|
+
.icon-emoji,
|
139
|
+
.icon-default {
|
140
|
+
font-size: 16px;
|
141
|
+
line-height: 1;
|
142
|
+
}
|
143
|
+
|
144
|
+
.component-info {
|
145
|
+
flex: 1;
|
146
|
+
min-width: 0;
|
147
|
+
}
|
148
|
+
|
149
|
+
.component-name {
|
150
|
+
font-weight: 500;
|
151
|
+
font-size: 13px;
|
152
|
+
color: #333;
|
153
|
+
margin-bottom: 2px;
|
154
|
+
white-space: nowrap;
|
155
|
+
overflow: hidden;
|
156
|
+
text-overflow: ellipsis;
|
157
|
+
}
|
158
|
+
|
159
|
+
.component-description {
|
160
|
+
font-size: 11px;
|
161
|
+
color: #666;
|
162
|
+
line-height: 1.3;
|
163
|
+
display: -webkit-box;
|
164
|
+
-webkit-line-clamp: 2;
|
165
|
+
line-clamp: 2;
|
166
|
+
-webkit-box-orient: vertical;
|
167
|
+
overflow: hidden;
|
168
|
+
}
|
169
|
+
|
170
|
+
.category-title {
|
171
|
+
border-bottom: 1px solid #dee2e6;
|
172
|
+
padding-bottom: 4px;
|
173
|
+
}
|
174
|
+
|
175
|
+
.usage-instructions {
|
176
|
+
position: sticky;
|
177
|
+
bottom: 0;
|
178
|
+
background: #f8f9fa !important;
|
179
|
+
border: 1px solid #dee2e6;
|
180
|
+
}
|
181
|
+
|
182
|
+
.step-number {
|
183
|
+
font-size: 12px;
|
184
|
+
width: 20px;
|
185
|
+
height: 20px;
|
186
|
+
display: inline-flex;
|
187
|
+
align-items: center;
|
188
|
+
justify-content: center;
|
189
|
+
border-radius: 50%;
|
190
|
+
}
|
191
|
+
|
192
|
+
/* Dark theme support */
|
193
|
+
:global(.theme-dark) .component-item-info {
|
194
|
+
background: #3d3d3d;
|
195
|
+
border-color: #555;
|
196
|
+
color: #fff;
|
197
|
+
}
|
198
|
+
|
199
|
+
:global(.theme-dark) .component-item-info:hover {
|
200
|
+
border-color: #4dabf7;
|
201
|
+
background: #404040;
|
202
|
+
}
|
203
|
+
|
204
|
+
:global(.theme-dark) .component-icon {
|
205
|
+
background: #2d2d2d;
|
206
|
+
border-color: #555;
|
207
|
+
}
|
208
|
+
|
209
|
+
:global(.theme-dark) .component-name {
|
210
|
+
color: #fff;
|
211
|
+
}
|
212
|
+
|
213
|
+
:global(.theme-dark) .component-description {
|
214
|
+
color: #ccc;
|
215
|
+
}
|
216
|
+
|
217
|
+
:global(.theme-dark) .usage-instructions {
|
218
|
+
background: #2d2d2d !important;
|
219
|
+
border-color: #555;
|
220
|
+
}
|
221
|
+
|
222
|
+
:global(.theme-dark) .category-title {
|
223
|
+
border-color: #555;
|
224
|
+
}
|
225
|
+
|
226
|
+
/* Scrollbar styling */
|
227
|
+
.component-info::-webkit-scrollbar {
|
228
|
+
width: 6px;
|
229
|
+
}
|
230
|
+
|
231
|
+
.component-info::-webkit-scrollbar-track {
|
232
|
+
background: #f1f1f1;
|
233
|
+
}
|
234
|
+
|
235
|
+
.component-info::-webkit-scrollbar-thumb {
|
236
|
+
background: #c1c1c1;
|
237
|
+
border-radius: 3px;
|
238
|
+
}
|
239
|
+
|
240
|
+
.component-info::-webkit-scrollbar-thumb:hover {
|
241
|
+
background: #a8a8a8;
|
242
|
+
}
|
243
|
+
</style>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
/**
|
2
|
+
* Component Info Panel
|
3
|
+
*
|
4
|
+
* Simple informational display of available components.
|
5
|
+
* No drag-and-drop needed since dropdowns handle selection.
|
6
|
+
*/
|
7
|
+
import type { ComponentConfig } from './GridSelector.svelte';
|
8
|
+
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> {
|
9
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
10
|
+
$$bindings?: Bindings;
|
11
|
+
} & Exports;
|
12
|
+
(internal: unknown, props: Props & {
|
13
|
+
$$events?: Events;
|
14
|
+
$$slots?: Slots;
|
15
|
+
}): Exports & {
|
16
|
+
$set?: any;
|
17
|
+
$on?: any;
|
18
|
+
};
|
19
|
+
z_$$bindings?: Bindings;
|
20
|
+
}
|
21
|
+
declare const ComponentPalette: $$__sveltets_2_IsomorphicComponent<{
|
22
|
+
availableComponents?: ComponentConfig[];
|
23
|
+
}, {
|
24
|
+
[evt: string]: CustomEvent<any>;
|
25
|
+
}, {}, {}, string>;
|
26
|
+
type ComponentPalette = InstanceType<typeof ComponentPalette>;
|
27
|
+
export default ComponentPalette;
|