@flowdrop/flowdrop 1.4.0 → 1.5.0
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/README.md +68 -24
- package/dist/adapters/WorkflowAdapter.js +2 -22
- package/dist/adapters/agentspec/autoLayout.d.ts +51 -5
- package/dist/adapters/agentspec/autoLayout.js +120 -23
- package/dist/chat/commandClassifier.d.ts +19 -0
- package/dist/chat/commandClassifier.js +30 -0
- package/dist/chat/index.d.ts +27 -0
- package/dist/chat/index.js +32 -0
- package/dist/chat/responseParser.d.ts +21 -0
- package/dist/chat/responseParser.js +87 -0
- package/dist/commands/batch.d.ts +18 -0
- package/dist/commands/batch.js +56 -0
- package/dist/commands/executor.d.ts +37 -0
- package/dist/commands/executor.js +1044 -0
- package/dist/commands/index.d.ts +14 -0
- package/dist/commands/index.js +17 -0
- package/dist/commands/parser.d.ts +16 -0
- package/dist/commands/parser.js +278 -0
- package/dist/commands/positioner.d.ts +19 -0
- package/dist/commands/positioner.js +33 -0
- package/dist/commands/storeIntegration.svelte.d.ts +16 -0
- package/dist/commands/storeIntegration.svelte.js +67 -0
- package/dist/commands/types.d.ts +343 -0
- package/dist/commands/types.js +45 -0
- package/dist/components/App.svelte +351 -12
- package/dist/components/App.svelte.d.ts +3 -0
- package/dist/components/CanvasController.svelte +38 -0
- package/dist/components/CanvasController.svelte.d.ts +32 -0
- package/dist/components/ConfigMappingRow.svelte +130 -0
- package/dist/components/ConfigMappingRow.svelte.d.ts +8 -0
- package/dist/components/ConfigPanel.svelte +56 -7
- package/dist/components/ConfigPanel.svelte.d.ts +2 -0
- package/dist/components/FlowDropEdge.svelte +2 -10
- package/dist/components/LogsSidebar.svelte +5 -5
- package/dist/components/NodeSidebar.svelte +15 -49
- package/dist/components/NodeSwapPicker.svelte +537 -0
- package/dist/components/NodeSwapPicker.svelte.d.ts +16 -0
- package/dist/components/PortMappingRow.svelte +209 -0
- package/dist/components/PortMappingRow.svelte.d.ts +12 -0
- package/dist/components/SwapMappingEditor.svelte +550 -0
- package/dist/components/SwapMappingEditor.svelte.d.ts +12 -0
- package/dist/components/WorkflowEditor.svelte +99 -4
- package/dist/components/WorkflowEditor.svelte.d.ts +8 -0
- package/dist/components/chat/AIChatPanel.svelte +658 -0
- package/dist/components/chat/AIChatPanel.svelte.d.ts +13 -0
- package/dist/components/chat/CommandPreview.svelte +184 -0
- package/dist/components/chat/CommandPreview.svelte.d.ts +9 -0
- package/dist/components/console/CommandConsole.stories.svelte +93 -0
- package/dist/components/console/CommandConsole.stories.svelte.d.ts +27 -0
- package/dist/components/console/CommandConsole.svelte +259 -0
- package/dist/components/console/CommandConsole.svelte.d.ts +11 -0
- package/dist/components/console/ConsoleAutocomplete.svelte +139 -0
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +21 -0
- package/dist/components/console/ConsoleInput.svelte +712 -0
- package/dist/components/console/ConsoleInput.svelte.d.ts +16 -0
- package/dist/components/console/ConsoleOutput.svelte +121 -0
- package/dist/components/console/ConsoleOutput.svelte.d.ts +11 -0
- package/dist/components/console/formatters.d.ts +26 -0
- package/dist/components/console/formatters.js +118 -0
- package/dist/components/interrupt/index.d.ts +1 -0
- package/dist/components/interrupt/index.js +1 -0
- package/dist/config/endpoints.d.ts +8 -0
- package/dist/config/endpoints.js +5 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +9 -0
- package/dist/editor/index.d.ts +3 -1
- package/dist/editor/index.js +4 -2
- package/dist/helpers/proximityConnect.js +8 -1
- package/dist/helpers/workflowEditorHelper.d.ts +3 -53
- package/dist/helpers/workflowEditorHelper.js +13 -228
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +1 -1
- package/dist/schemas/v1/workflow.schema.json +107 -22
- package/dist/services/chatService.d.ts +65 -0
- package/dist/services/chatService.js +131 -0
- package/dist/services/historyService.d.ts +6 -4
- package/dist/services/historyService.js +21 -6
- package/dist/stores/interruptStore.svelte.js +6 -1
- package/dist/stores/playgroundStore.svelte.d.ts +1 -1
- package/dist/stores/playgroundStore.svelte.js +11 -2
- package/dist/stores/portCoordinateStore.svelte.d.ts +4 -0
- package/dist/stores/portCoordinateStore.svelte.js +20 -26
- package/dist/stores/workflowStore.svelte.d.ts +31 -2
- package/dist/stores/workflowStore.svelte.js +84 -64
- package/dist/types/chat.d.ts +63 -0
- package/dist/types/chat.js +9 -0
- package/dist/types/events.d.ts +28 -2
- package/dist/types/events.js +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/settings.d.ts +6 -0
- package/dist/types/settings.js +3 -0
- package/dist/utils/edgeStyling.d.ts +42 -0
- package/dist/utils/edgeStyling.js +176 -0
- package/dist/utils/nodeIds.d.ts +31 -0
- package/dist/utils/nodeIds.js +42 -0
- package/dist/utils/nodeSwap.d.ts +221 -0
- package/dist/utils/nodeSwap.js +686 -0
- package/package.json +6 -1
- package/dist/helpers/nodeLayoutHelper.d.ts +0 -14
- package/dist/helpers/nodeLayoutHelper.js +0 -19
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
NodeSwapPicker Component
|
|
3
|
+
Displays available node types for swapping, with search/filter and version upgrade badge.
|
|
4
|
+
Reuses patterns from NodeSidebar.
|
|
5
|
+
Styled with BEM syntax.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import type {
|
|
10
|
+
NodeMetadata,
|
|
11
|
+
NodeCategory,
|
|
12
|
+
WorkflowFormat,
|
|
13
|
+
WorkflowNode,
|
|
14
|
+
} from "../types/index.js";
|
|
15
|
+
import Icon from "@iconify/svelte";
|
|
16
|
+
import { getNodeIcon, getCategoryIcon } from "../utils/icons.js";
|
|
17
|
+
import { getCategoryColorToken } from "../utils/colors.js";
|
|
18
|
+
import { getCategoryLabel } from "../stores/categoriesStore.svelte.js";
|
|
19
|
+
import { getVersionUpgrade } from "../utils/nodeSwap.js";
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
/** The node being swapped */
|
|
24
|
+
currentNode: WorkflowNode;
|
|
25
|
+
/** All available node types */
|
|
26
|
+
availableNodes: NodeMetadata[];
|
|
27
|
+
/** Active workflow format for filtering */
|
|
28
|
+
activeFormat?: WorkflowFormat;
|
|
29
|
+
/** Callback when a node type is selected */
|
|
30
|
+
onSelect: (metadata: NodeMetadata) => void;
|
|
31
|
+
/** Callback to cancel swap */
|
|
32
|
+
onCancel: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
currentNode,
|
|
37
|
+
availableNodes,
|
|
38
|
+
activeFormat,
|
|
39
|
+
onSelect,
|
|
40
|
+
onCancel,
|
|
41
|
+
}: Props = $props();
|
|
42
|
+
|
|
43
|
+
let searchInput = $state("");
|
|
44
|
+
|
|
45
|
+
/** Check version upgrade availability */
|
|
46
|
+
let versionUpgrade = $derived(
|
|
47
|
+
getVersionUpgrade(currentNode.data.metadata, availableNodes),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
/** Filter nodes compatible with active format */
|
|
51
|
+
function isNodeCompatibleWithFormat(node: NodeMetadata): boolean {
|
|
52
|
+
if (!activeFormat) return true;
|
|
53
|
+
if (!node.formats || node.formats.length === 0) return true;
|
|
54
|
+
return node.formats.includes(activeFormat);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Nodes filtered by format compatibility */
|
|
58
|
+
let formatCompatibleNodes = $derived(
|
|
59
|
+
availableNodes.filter((n) => isNodeCompatibleWithFormat(n)),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
/** Apply search filter */
|
|
63
|
+
let filteredNodes = $derived.by(() => {
|
|
64
|
+
let nodes = formatCompatibleNodes;
|
|
65
|
+
if (searchInput.trim()) {
|
|
66
|
+
const query = searchInput.toLowerCase();
|
|
67
|
+
nodes = nodes.filter(
|
|
68
|
+
(node) =>
|
|
69
|
+
node.name.toLowerCase().includes(query) ||
|
|
70
|
+
node.description.toLowerCase().includes(query) ||
|
|
71
|
+
node.tags?.some((tag) => tag.toLowerCase().includes(query)),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return nodes;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
/** Get unique categories preserving API order */
|
|
78
|
+
let categories = $derived.by(() => {
|
|
79
|
+
const seen = new Set<NodeCategory>();
|
|
80
|
+
const ordered: NodeCategory[] = [];
|
|
81
|
+
for (const node of filteredNodes) {
|
|
82
|
+
if (!seen.has(node.category)) {
|
|
83
|
+
seen.add(node.category);
|
|
84
|
+
ordered.push(node.category);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return ordered;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/** Get filtered nodes for a specific category */
|
|
91
|
+
function getNodesForCategory(category: NodeCategory): NodeMetadata[] {
|
|
92
|
+
return filteredNodes.filter((n) => n.category === category);
|
|
93
|
+
}
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<div class="swap-picker">
|
|
97
|
+
<!-- Header -->
|
|
98
|
+
<div class="swap-picker__header">
|
|
99
|
+
<button
|
|
100
|
+
class="swap-picker__back"
|
|
101
|
+
onclick={onCancel}
|
|
102
|
+
aria-label="Back to configuration"
|
|
103
|
+
>
|
|
104
|
+
<Icon icon="heroicons:arrow-left" />
|
|
105
|
+
</button>
|
|
106
|
+
<h2 class="swap-picker__title">Swap Node</h2>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<!-- Current node info -->
|
|
110
|
+
<div class="swap-picker__current">
|
|
111
|
+
<span class="swap-picker__current-label">Current:</span>
|
|
112
|
+
<span class="swap-picker__current-name">{currentNode.data.label}</span>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<!-- Version upgrade banner -->
|
|
116
|
+
{#if versionUpgrade}
|
|
117
|
+
<button
|
|
118
|
+
class="swap-picker__upgrade"
|
|
119
|
+
onclick={() => onSelect(versionUpgrade!)}
|
|
120
|
+
>
|
|
121
|
+
<Icon icon="heroicons:arrow-up-circle" />
|
|
122
|
+
<div class="swap-picker__upgrade-info">
|
|
123
|
+
<span class="swap-picker__upgrade-title">Upgrade Available</span>
|
|
124
|
+
<span class="swap-picker__upgrade-detail">
|
|
125
|
+
v{currentNode.data.metadata.version} → v{versionUpgrade.version}
|
|
126
|
+
</span>
|
|
127
|
+
</div>
|
|
128
|
+
<Icon icon="heroicons:chevron-right" />
|
|
129
|
+
</button>
|
|
130
|
+
{/if}
|
|
131
|
+
|
|
132
|
+
<!-- Search (hidden in minimal via --fd-sidebar-search-display) -->
|
|
133
|
+
<div class="swap-picker__search">
|
|
134
|
+
<input
|
|
135
|
+
type="text"
|
|
136
|
+
placeholder="Search node types..."
|
|
137
|
+
class="swap-picker__input"
|
|
138
|
+
bind:value={searchInput}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<!-- Node list -->
|
|
143
|
+
<div class="swap-picker__list">
|
|
144
|
+
{#if filteredNodes.length === 0}
|
|
145
|
+
<div class="swap-picker__empty">
|
|
146
|
+
<p>No matching node types found</p>
|
|
147
|
+
</div>
|
|
148
|
+
{:else}
|
|
149
|
+
{#each categories as category (category)}
|
|
150
|
+
{@const categoryNodes = getNodesForCategory(category)}
|
|
151
|
+
{#if categoryNodes.length > 0}
|
|
152
|
+
<!-- Flat style: dot + name rows (shown in minimal skin) -->
|
|
153
|
+
<div class="swap-picker__flat-section">
|
|
154
|
+
<div class="swap-picker__flat-category">
|
|
155
|
+
{getCategoryLabel(category).toUpperCase()}
|
|
156
|
+
</div>
|
|
157
|
+
<div class="swap-picker__flat-list">
|
|
158
|
+
{#each categoryNodes as nodeType (nodeType.id)}
|
|
159
|
+
<button
|
|
160
|
+
class="swap-picker__flat-item"
|
|
161
|
+
onclick={() => onSelect(nodeType)}
|
|
162
|
+
>
|
|
163
|
+
<span
|
|
164
|
+
class="swap-picker__flat-dot"
|
|
165
|
+
style="background: {getCategoryColorToken(nodeType.category)}"
|
|
166
|
+
></span>
|
|
167
|
+
<span class="swap-picker__flat-name">{nodeType.name}</span>
|
|
168
|
+
</button>
|
|
169
|
+
{/each}
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<!-- Card style: icon + name + desc rows (shown in default skin) -->
|
|
174
|
+
<div class="swap-picker__card-section">
|
|
175
|
+
<div class="swap-picker__category-header">
|
|
176
|
+
<span
|
|
177
|
+
class="swap-picker__category-icon"
|
|
178
|
+
style="--_icon-color: {getCategoryColorToken(category)}"
|
|
179
|
+
>
|
|
180
|
+
<Icon icon={getCategoryIcon(category)} />
|
|
181
|
+
</span>
|
|
182
|
+
<span class="swap-picker__category-name">
|
|
183
|
+
{getCategoryLabel(category)}
|
|
184
|
+
</span>
|
|
185
|
+
<span class="swap-picker__category-count">
|
|
186
|
+
{categoryNodes.length}
|
|
187
|
+
</span>
|
|
188
|
+
</div>
|
|
189
|
+
<div class="swap-picker__category-items">
|
|
190
|
+
{#each categoryNodes as nodeType (nodeType.id)}
|
|
191
|
+
<button
|
|
192
|
+
class="swap-picker__item"
|
|
193
|
+
onclick={() => onSelect(nodeType)}
|
|
194
|
+
>
|
|
195
|
+
<span
|
|
196
|
+
class="swap-picker__item-icon"
|
|
197
|
+
style="--_icon-color: {getCategoryColorToken(
|
|
198
|
+
nodeType.category,
|
|
199
|
+
)}"
|
|
200
|
+
>
|
|
201
|
+
<Icon
|
|
202
|
+
icon={getNodeIcon(nodeType.icon, nodeType.category)}
|
|
203
|
+
/>
|
|
204
|
+
</span>
|
|
205
|
+
<div class="swap-picker__item-info">
|
|
206
|
+
<span class="swap-picker__item-name">{nodeType.name}</span>
|
|
207
|
+
<span class="swap-picker__item-desc">
|
|
208
|
+
{nodeType.description}
|
|
209
|
+
</span>
|
|
210
|
+
</div>
|
|
211
|
+
<Icon
|
|
212
|
+
icon="heroicons:chevron-right"
|
|
213
|
+
class="swap-picker__item-arrow"
|
|
214
|
+
/>
|
|
215
|
+
</button>
|
|
216
|
+
{/each}
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
{/if}
|
|
220
|
+
{/each}
|
|
221
|
+
{/if}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<style>
|
|
226
|
+
.swap-picker {
|
|
227
|
+
height: 100%;
|
|
228
|
+
display: flex;
|
|
229
|
+
flex-direction: column;
|
|
230
|
+
background-color: var(--fd-background);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.swap-picker__header {
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
gap: 0.5rem;
|
|
237
|
+
padding: 0.875rem 1rem;
|
|
238
|
+
border-bottom: 1px solid var(--fd-border);
|
|
239
|
+
background-color: var(--fd-muted);
|
|
240
|
+
flex-shrink: 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.swap-picker__back {
|
|
244
|
+
background: none;
|
|
245
|
+
border: none;
|
|
246
|
+
cursor: pointer;
|
|
247
|
+
color: var(--fd-muted-foreground);
|
|
248
|
+
padding: 0.25rem;
|
|
249
|
+
border-radius: var(--fd-radius-sm);
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: center;
|
|
252
|
+
transition:
|
|
253
|
+
color var(--fd-transition-fast),
|
|
254
|
+
background-color var(--fd-transition-fast);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.swap-picker__back:hover {
|
|
258
|
+
color: var(--fd-foreground);
|
|
259
|
+
background-color: var(--fd-subtle);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.swap-picker__title {
|
|
263
|
+
margin: 0;
|
|
264
|
+
font-size: 1rem;
|
|
265
|
+
font-weight: 600;
|
|
266
|
+
color: var(--fd-foreground);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.swap-picker__current {
|
|
270
|
+
padding: 0.5rem 1rem;
|
|
271
|
+
border-bottom: 1px solid var(--fd-border-muted);
|
|
272
|
+
background-color: var(--fd-muted);
|
|
273
|
+
font-size: var(--fd-text-xs);
|
|
274
|
+
display: flex;
|
|
275
|
+
gap: 0.375rem;
|
|
276
|
+
align-items: center;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.swap-picker__current-label {
|
|
280
|
+
color: var(--fd-muted-foreground);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.swap-picker__current-name {
|
|
284
|
+
color: var(--fd-foreground);
|
|
285
|
+
font-weight: 500;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.swap-picker__upgrade {
|
|
289
|
+
display: flex;
|
|
290
|
+
align-items: center;
|
|
291
|
+
gap: 0.5rem;
|
|
292
|
+
padding: 0.625rem 1rem;
|
|
293
|
+
border: none;
|
|
294
|
+
border-bottom: 1px solid var(--fd-border-muted);
|
|
295
|
+
background-color: color-mix(in srgb, var(--fd-primary) 8%, transparent);
|
|
296
|
+
color: var(--fd-primary);
|
|
297
|
+
cursor: pointer;
|
|
298
|
+
width: 100%;
|
|
299
|
+
text-align: left;
|
|
300
|
+
transition: background-color var(--fd-transition-fast);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.swap-picker__upgrade:hover {
|
|
304
|
+
background-color: color-mix(in srgb, var(--fd-primary) 15%, transparent);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.swap-picker__upgrade-info {
|
|
308
|
+
flex: 1;
|
|
309
|
+
display: flex;
|
|
310
|
+
flex-direction: column;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.swap-picker__upgrade-title {
|
|
314
|
+
font-size: var(--fd-text-sm);
|
|
315
|
+
font-weight: 600;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.swap-picker__upgrade-detail {
|
|
319
|
+
font-size: var(--fd-text-xs);
|
|
320
|
+
opacity: 0.8;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.swap-picker__search {
|
|
324
|
+
display: var(--fd-sidebar-search-display, flex);
|
|
325
|
+
padding: 0.75rem 1rem;
|
|
326
|
+
border-bottom: 1px solid var(--fd-border);
|
|
327
|
+
flex-shrink: 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.swap-picker__input {
|
|
331
|
+
width: 100%;
|
|
332
|
+
padding: 0.5rem 0.75rem;
|
|
333
|
+
border: 1px solid var(--fd-border-strong);
|
|
334
|
+
border-radius: var(--fd-radius-md);
|
|
335
|
+
font-size: var(--fd-text-sm);
|
|
336
|
+
color: var(--fd-foreground);
|
|
337
|
+
background-color: var(--fd-background);
|
|
338
|
+
box-sizing: border-box;
|
|
339
|
+
transition:
|
|
340
|
+
border-color var(--fd-transition-normal),
|
|
341
|
+
box-shadow var(--fd-transition-normal);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.swap-picker__input:focus {
|
|
345
|
+
outline: none;
|
|
346
|
+
border-color: var(--fd-ring);
|
|
347
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fd-ring) 20%, transparent);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.swap-picker__input::placeholder {
|
|
351
|
+
color: var(--fd-muted-foreground);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.swap-picker__list {
|
|
355
|
+
flex: 1;
|
|
356
|
+
overflow-y: auto;
|
|
357
|
+
padding: 0.75rem;
|
|
358
|
+
scrollbar-width: thin;
|
|
359
|
+
scrollbar-color: var(--fd-scrollbar-thumb) var(--fd-scrollbar-track);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.swap-picker__empty {
|
|
363
|
+
padding: 2rem 1rem;
|
|
364
|
+
text-align: center;
|
|
365
|
+
color: var(--fd-muted-foreground);
|
|
366
|
+
font-size: var(--fd-text-sm);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* Display-control token wiring for skin variants */
|
|
370
|
+
.swap-picker__flat-section {
|
|
371
|
+
display: var(--fd-sidebar-flat-display, none);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.swap-picker__card-section {
|
|
375
|
+
display: var(--fd-sidebar-card-display, block);
|
|
376
|
+
margin-bottom: 0.75rem;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* Flat style (minimal skin) */
|
|
380
|
+
.swap-picker__flat-category {
|
|
381
|
+
font-size: var(--fd-text-xs);
|
|
382
|
+
font-weight: 600;
|
|
383
|
+
color: var(--fd-sidebar-category-color, var(--fd-muted-foreground));
|
|
384
|
+
letter-spacing: 0.08em;
|
|
385
|
+
padding: 1.25rem 0.75rem 0.375rem 0.75rem;
|
|
386
|
+
text-transform: uppercase;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.swap-picker__flat-list {
|
|
390
|
+
display: flex;
|
|
391
|
+
flex-direction: column;
|
|
392
|
+
gap: 1px;
|
|
393
|
+
margin-bottom: 0.25rem;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.swap-picker__flat-item {
|
|
397
|
+
display: flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
gap: 0.625rem;
|
|
400
|
+
padding: 0.5rem 0.75rem;
|
|
401
|
+
border: none;
|
|
402
|
+
border-radius: var(--fd-radius-sm);
|
|
403
|
+
background: none;
|
|
404
|
+
cursor: pointer;
|
|
405
|
+
width: 100%;
|
|
406
|
+
text-align: left;
|
|
407
|
+
transition: background-color var(--fd-transition-fast);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.swap-picker__flat-item:hover {
|
|
411
|
+
background-color: var(--fd-muted);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.swap-picker__flat-dot {
|
|
415
|
+
width: 8px;
|
|
416
|
+
height: 8px;
|
|
417
|
+
border-radius: 50%;
|
|
418
|
+
flex-shrink: 0;
|
|
419
|
+
display: inline-block;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.swap-picker__flat-name {
|
|
423
|
+
font-size: var(--fd-text-sm);
|
|
424
|
+
color: var(--fd-sidebar-flat-item-color, var(--fd-foreground));
|
|
425
|
+
white-space: nowrap;
|
|
426
|
+
overflow: hidden;
|
|
427
|
+
text-overflow: ellipsis;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.swap-picker__category-header {
|
|
431
|
+
display: flex;
|
|
432
|
+
align-items: center;
|
|
433
|
+
gap: 0.5rem;
|
|
434
|
+
padding: 0.375rem 0.25rem;
|
|
435
|
+
margin-bottom: 0.25rem;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.swap-picker__category-icon {
|
|
439
|
+
width: 1.25rem;
|
|
440
|
+
height: 1.25rem;
|
|
441
|
+
border-radius: 0.25rem;
|
|
442
|
+
background: color-mix(
|
|
443
|
+
in srgb,
|
|
444
|
+
var(--_icon-color) var(--fd-node-icon-bg-opacity),
|
|
445
|
+
transparent
|
|
446
|
+
);
|
|
447
|
+
color: var(--fd-node-icon);
|
|
448
|
+
font-size: 0.625rem;
|
|
449
|
+
display: flex;
|
|
450
|
+
align-items: center;
|
|
451
|
+
justify-content: center;
|
|
452
|
+
flex-shrink: 0;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.swap-picker__category-name {
|
|
456
|
+
font-size: var(--fd-text-xs);
|
|
457
|
+
font-weight: 600;
|
|
458
|
+
color: var(--fd-muted-foreground);
|
|
459
|
+
text-transform: uppercase;
|
|
460
|
+
letter-spacing: 0.05em;
|
|
461
|
+
flex: 1;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.swap-picker__category-count {
|
|
465
|
+
font-size: var(--fd-text-xs);
|
|
466
|
+
color: var(--fd-muted-foreground);
|
|
467
|
+
background-color: var(--fd-subtle);
|
|
468
|
+
padding: 0.125rem 0.375rem;
|
|
469
|
+
border-radius: var(--fd-radius-sm);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.swap-picker__category-items {
|
|
473
|
+
display: flex;
|
|
474
|
+
flex-direction: column;
|
|
475
|
+
gap: 2px;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.swap-picker__item {
|
|
479
|
+
display: flex;
|
|
480
|
+
align-items: center;
|
|
481
|
+
gap: 0.5rem;
|
|
482
|
+
padding: 0.5rem;
|
|
483
|
+
border: 1px solid transparent;
|
|
484
|
+
border-radius: var(--fd-radius-md);
|
|
485
|
+
background: none;
|
|
486
|
+
cursor: pointer;
|
|
487
|
+
width: 100%;
|
|
488
|
+
text-align: left;
|
|
489
|
+
transition: all var(--fd-transition-fast);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.swap-picker__item:hover {
|
|
493
|
+
background-color: var(--fd-muted);
|
|
494
|
+
border-color: var(--fd-border);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.swap-picker__item-icon {
|
|
498
|
+
width: 1.75rem;
|
|
499
|
+
height: 1.75rem;
|
|
500
|
+
border-radius: 0.375rem;
|
|
501
|
+
background: color-mix(
|
|
502
|
+
in srgb,
|
|
503
|
+
var(--_icon-color) var(--fd-node-icon-bg-opacity),
|
|
504
|
+
transparent
|
|
505
|
+
);
|
|
506
|
+
color: var(--fd-node-icon);
|
|
507
|
+
font-size: var(--fd-text-xs);
|
|
508
|
+
display: flex;
|
|
509
|
+
align-items: center;
|
|
510
|
+
justify-content: center;
|
|
511
|
+
flex-shrink: 0;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.swap-picker__item-info {
|
|
515
|
+
flex: 1;
|
|
516
|
+
min-width: 0;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.swap-picker__item-name {
|
|
520
|
+
display: block;
|
|
521
|
+
font-size: var(--fd-text-sm);
|
|
522
|
+
font-weight: 500;
|
|
523
|
+
color: var(--fd-foreground);
|
|
524
|
+
overflow: hidden;
|
|
525
|
+
text-overflow: ellipsis;
|
|
526
|
+
white-space: nowrap;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.swap-picker__item-desc {
|
|
530
|
+
display: block;
|
|
531
|
+
font-size: var(--fd-text-xs);
|
|
532
|
+
color: var(--fd-muted-foreground);
|
|
533
|
+
overflow: hidden;
|
|
534
|
+
text-overflow: ellipsis;
|
|
535
|
+
white-space: nowrap;
|
|
536
|
+
}
|
|
537
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NodeMetadata, WorkflowFormat, WorkflowNode } from "../types/index.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The node being swapped */
|
|
4
|
+
currentNode: WorkflowNode;
|
|
5
|
+
/** All available node types */
|
|
6
|
+
availableNodes: NodeMetadata[];
|
|
7
|
+
/** Active workflow format for filtering */
|
|
8
|
+
activeFormat?: WorkflowFormat;
|
|
9
|
+
/** Callback when a node type is selected */
|
|
10
|
+
onSelect: (metadata: NodeMetadata) => void;
|
|
11
|
+
/** Callback to cancel swap */
|
|
12
|
+
onCancel: () => void;
|
|
13
|
+
}
|
|
14
|
+
declare const NodeSwapPicker: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type NodeSwapPicker = ReturnType<typeof NodeSwapPicker>;
|
|
16
|
+
export default NodeSwapPicker;
|