@flowdrop/flowdrop 2.0.0-beta.2 → 2.0.0-beta.4
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/CHANGELOG.md +59 -0
- package/MIGRATION-2.0.md +13 -0
- package/README.md +5 -5
- package/dist/components/App.svelte +36 -191
- package/dist/components/App.svelte.d.ts +2 -7
- package/dist/components/Button.stories.svelte +65 -0
- package/dist/components/Button.stories.svelte.d.ts +19 -0
- package/dist/components/Button.svelte +62 -0
- package/dist/components/Button.svelte.d.ts +24 -0
- package/dist/components/CanvasIconButton.svelte +76 -0
- package/dist/components/CanvasIconButton.svelte.d.ts +18 -0
- package/dist/components/ConfigForm.svelte +4 -23
- package/dist/components/ConfigPanel.svelte +4 -3
- package/dist/components/EditorStatusBar.stories.svelte +44 -0
- package/dist/components/EditorStatusBar.stories.svelte.d.ts +27 -0
- package/dist/components/EditorStatusBar.svelte +99 -0
- package/dist/components/EditorStatusBar.svelte.d.ts +15 -0
- package/dist/components/IconButton.svelte +80 -0
- package/dist/components/IconButton.svelte.d.ts +30 -0
- package/dist/components/Input.svelte +74 -0
- package/dist/components/Input.svelte.d.ts +17 -0
- package/dist/components/LogoWordmark.svelte +113 -0
- package/dist/components/LogoWordmark.svelte.d.ts +26 -0
- package/dist/components/Navbar.svelte +17 -63
- package/dist/components/Navbar.svelte.d.ts +3 -0
- package/dist/components/NodeSidebar.svelte +17 -122
- package/dist/components/NodeSwapPicker.svelte +10 -28
- package/dist/components/PortMappingRow.svelte +0 -2
- package/dist/components/SchemaForm.svelte +0 -12
- package/dist/components/Select.svelte +53 -0
- package/dist/components/Select.svelte.d.ts +15 -0
- package/dist/components/SettingsModal.svelte +0 -5
- package/dist/components/SettingsPanel.svelte +2 -6
- package/dist/components/Textarea.svelte +39 -0
- package/dist/components/Textarea.svelte.d.ts +12 -0
- package/dist/components/ThemeToggle.svelte +15 -94
- package/dist/components/UniversalNode.svelte +32 -1
- package/dist/components/WorkflowEditor.svelte +62 -51
- package/dist/components/WorkflowEditor.svelte.d.ts +18 -0
- package/dist/components/chat/AIChatPanel.svelte +1 -1
- package/dist/components/console/ConsoleAutocomplete.svelte +1 -1
- package/dist/components/console/ConsoleOutput.svelte +2 -2
- package/dist/components/form/FormArray.svelte +37 -173
- package/dist/components/form/FormAutocomplete.svelte +10 -6
- package/dist/components/form/FormCheckboxGroup.svelte +1 -5
- package/dist/components/form/FormCodeEditor.svelte +9 -7
- package/dist/components/form/FormField.svelte +5 -44
- package/dist/components/form/FormFieldLight.svelte +8 -47
- package/dist/components/form/FormFieldset.svelte +1 -1
- package/dist/components/form/FormMarkdownEditor.svelte +8 -5
- package/dist/components/form/FormNumberField.svelte +4 -36
- package/dist/components/form/FormRangeField.svelte +18 -27
- package/dist/components/form/FormSelect.svelte +13 -75
- package/dist/components/form/FormTemplateEditor.svelte +6 -4
- package/dist/components/form/FormTextField.svelte +3 -35
- package/dist/components/form/FormTextarea.svelte +4 -39
- package/dist/components/form/FormToggle.svelte +0 -4
- package/dist/components/form/resolveFieldType.d.ts +24 -0
- package/dist/components/form/resolveFieldType.js +55 -0
- package/dist/components/icons/CloseIcon.svelte +6 -0
- package/dist/components/icons/CloseIcon.svelte.d.ts +26 -0
- package/dist/components/icons/CommandLineIcon.svelte +15 -0
- package/dist/components/icons/CommandLineIcon.svelte.d.ts +26 -0
- package/dist/components/icons/MenuIcon.svelte +4 -0
- package/dist/components/icons/MenuIcon.svelte.d.ts +26 -0
- package/dist/components/icons/MenuOpenIcon.svelte +6 -0
- package/dist/components/icons/MenuOpenIcon.svelte.d.ts +26 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +0 -10
- package/dist/components/interrupt/ConfirmationPrompt.svelte +0 -5
- package/dist/components/interrupt/InterruptBubble.svelte +0 -10
- package/dist/components/interrupt/ReviewPrompt.svelte +0 -20
- package/dist/components/interrupt/TextInputPrompt.svelte +0 -6
- package/dist/components/layouts/MainLayout.svelte +4 -5
- package/dist/components/nodes/AtomNode.svelte +46 -34
- package/dist/components/nodes/GatewayNode.svelte +91 -99
- package/dist/components/nodes/IdeaNode.svelte +62 -90
- package/dist/components/nodes/NodeConfigButton.svelte +86 -0
- package/dist/components/nodes/NodeConfigButton.svelte.d.ts +15 -0
- package/dist/components/nodes/NotesNode.svelte +70 -81
- package/dist/components/nodes/SimpleNode.svelte +28 -78
- package/dist/components/nodes/SquareNode.svelte +79 -109
- package/dist/components/nodes/TerminalNode.svelte +28 -86
- package/dist/components/nodes/ToolNode.svelte +82 -95
- package/dist/components/nodes/WorkflowNode.svelte +91 -100
- package/dist/components/playground/ChatInput.svelte +0 -1
- package/dist/components/playground/InputCollector.svelte +11 -48
- package/dist/components/playground/PlaygroundApp.svelte +1 -1
- package/dist/components/playground/PlaygroundStudio.svelte +0 -5
- package/dist/messages/index.d.ts +1 -1
- package/dist/messages/index.js +1 -1
- package/dist/openapi/v1/openapi.yaml +2 -2
- package/dist/playground/mount.d.ts +9 -5
- package/dist/playground/mount.js +9 -5
- package/dist/skins/drafter.d.ts +30 -0
- package/dist/skins/drafter.js +198 -0
- package/dist/skins/index.d.ts +2 -1
- package/dist/skins/index.js +4 -2
- package/dist/styles/base.css +285 -14
- package/dist/styles/tokens.css +60 -2
- package/dist/svelte-app.d.ts +6 -0
- package/dist/svelte-app.js +71 -109
- package/dist/themes/drafter.d.ts +2 -0
- package/dist/themes/drafter.js +15 -0
- package/dist/themes/index.d.ts +2 -1
- package/dist/themes/index.js +8 -2
- package/dist/types/events.d.ts +18 -0
- package/dist/types/events.js +2 -1
- package/dist/types/settings.d.ts +1 -1
- package/dist/types/settings.js +1 -1
- package/dist/types/skin.d.ts +1 -1
- package/dist/types/theme.d.ts +16 -2
- package/dist/utils/connections.js +14 -50
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ConfigValues, NodeMetadata } from '../../types/index.js';
|
|
3
3
|
import Icon from '@iconify/svelte';
|
|
4
|
+
import NodeConfigButton from './NodeConfigButton.svelte';
|
|
4
5
|
import MarkdownDisplay from '../MarkdownDisplay.svelte';
|
|
5
6
|
import { m } from '../../messages/index.js';
|
|
6
7
|
|
|
@@ -88,28 +89,17 @@
|
|
|
88
89
|
function handleDoubleClick(): void {
|
|
89
90
|
openConfigSidebar();
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Handles keyboard events for accessibility
|
|
94
|
-
* @param event - The keyboard event
|
|
95
|
-
*/
|
|
96
|
-
function handleKeydown(event: KeyboardEvent): void {
|
|
97
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
98
|
-
event.preventDefault();
|
|
99
|
-
handleDoubleClick();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
92
|
</script>
|
|
103
93
|
|
|
94
|
+
<!-- Presentational: focus, keyboard and selection live on xyflow's node
|
|
95
|
+
wrapper (see UniversalNode). double-click is a mouse convenience. -->
|
|
96
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
104
97
|
<div
|
|
105
98
|
class="flowdrop-notes-node {currentType.typeClass}"
|
|
106
99
|
class:flowdrop-notes-node--selected={props.selected}
|
|
107
100
|
class:flowdrop-notes-node--processing={props.isProcessing}
|
|
108
101
|
class:flowdrop-notes-node--has-error={props.isError}
|
|
109
102
|
ondblclick={handleDoubleClick}
|
|
110
|
-
onkeydown={handleKeydown}
|
|
111
|
-
role="button"
|
|
112
|
-
tabindex="0"
|
|
113
103
|
>
|
|
114
104
|
<!-- Display Mode -->
|
|
115
105
|
<div class="flowdrop-notes-node__content">
|
|
@@ -146,35 +136,34 @@
|
|
|
146
136
|
</div>
|
|
147
137
|
|
|
148
138
|
<!-- Config button -->
|
|
149
|
-
<
|
|
150
|
-
class="flowdrop-notes-node__config-btn"
|
|
151
|
-
onclick={openConfigSidebar}
|
|
152
|
-
title={notes.configure}
|
|
153
|
-
>
|
|
154
|
-
<Icon icon="mdi:cog" />
|
|
155
|
-
</button>
|
|
139
|
+
<NodeConfigButton onclick={openConfigSidebar} title={notes.configure} />
|
|
156
140
|
</div>
|
|
157
141
|
|
|
158
142
|
<style>
|
|
159
143
|
.flowdrop-notes-node {
|
|
144
|
+
box-sizing: border-box;
|
|
160
145
|
min-width: var(--fd-notes-node-min-width);
|
|
161
146
|
max-width: var(--fd-notes-node-max-width);
|
|
162
147
|
width: var(--fd-notes-node-width);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
148
|
+
/* Grid-aligned floor; grows in 20px steps via the chrome + body below. */
|
|
149
|
+
min-height: var(--fd-notes-node-min-height);
|
|
150
|
+
border-radius: var(--fd-node-radius);
|
|
151
|
+
border: var(--fd-node-border-width) solid var(--fd-note-border);
|
|
152
|
+
background: var(--fd-node-bg);
|
|
166
153
|
backdrop-filter: var(--fd-notes-node-backdrop-filter);
|
|
167
|
-
box-shadow: var(--fd-shadow
|
|
154
|
+
box-shadow: var(--fd-node-shadow);
|
|
168
155
|
color: var(--fd-foreground);
|
|
169
156
|
transition: all var(--fd-transition-fast);
|
|
170
157
|
overflow: hidden;
|
|
171
158
|
z-index: 5;
|
|
172
159
|
}
|
|
173
160
|
|
|
174
|
-
/* Note type: Info (blue) - subtle background tint, neutral border
|
|
161
|
+
/* Note type: Info (blue) - subtle background tint, neutral border.
|
|
162
|
+
Uses the info accent (not primary) so an info note never reads as a
|
|
163
|
+
primary/success action — primary stays reserved for interactive intent. */
|
|
175
164
|
.flowdrop-notes-node--info {
|
|
176
165
|
background-color: var(--fd-info-muted);
|
|
177
|
-
--_notes-icon: var(--fd-
|
|
166
|
+
--_notes-icon: var(--fd-info);
|
|
178
167
|
}
|
|
179
168
|
|
|
180
169
|
/* Note type: Warning (yellow/amber) - subtle background tint */
|
|
@@ -202,29 +191,27 @@
|
|
|
202
191
|
}
|
|
203
192
|
|
|
204
193
|
.flowdrop-notes-node:hover {
|
|
205
|
-
box-shadow: var(--fd-shadow-
|
|
206
|
-
border-color: var(--fd-
|
|
194
|
+
box-shadow: var(--fd-node-shadow-hover);
|
|
195
|
+
border-color: var(--fd-note-border-hover);
|
|
207
196
|
}
|
|
208
197
|
|
|
209
198
|
/* Selected state - matches other node components */
|
|
210
199
|
.flowdrop-notes-node--selected {
|
|
211
200
|
box-shadow:
|
|
212
201
|
0 0 0 2px var(--fd-primary-muted),
|
|
213
|
-
var(--fd-shadow-
|
|
202
|
+
var(--fd-node-shadow-hover);
|
|
214
203
|
border-color: var(--fd-primary);
|
|
215
204
|
}
|
|
216
205
|
|
|
217
206
|
.flowdrop-notes-node--selected:hover {
|
|
218
207
|
box-shadow:
|
|
219
208
|
0 0 0 2px var(--fd-primary-muted),
|
|
220
|
-
var(--fd-shadow-
|
|
209
|
+
var(--fd-node-shadow-hover);
|
|
221
210
|
border-color: var(--fd-primary);
|
|
222
211
|
}
|
|
223
212
|
|
|
224
|
-
.
|
|
225
|
-
|
|
226
|
-
outline-offset: 2px;
|
|
227
|
-
}
|
|
213
|
+
/* Focus ring is centralized in base.css (drawn on the .svelte-flow__node
|
|
214
|
+
wrapper, which is the focusable element). */
|
|
228
215
|
|
|
229
216
|
.flowdrop-notes-node--processing {
|
|
230
217
|
opacity: 0.7;
|
|
@@ -237,7 +224,11 @@
|
|
|
237
224
|
|
|
238
225
|
/* Display Mode Styles */
|
|
239
226
|
.flowdrop-notes-node__content {
|
|
240
|
-
|
|
227
|
+
box-sizing: border-box;
|
|
228
|
+
/* px on the 20px grid; bottom padding absorbs both node borders so the
|
|
229
|
+
chrome (padding + 40px header + 20px gap) sums to 100px and the outer
|
|
230
|
+
node height stays a 20px multiple as the body grows. */
|
|
231
|
+
padding: 20px 20px calc(20px - var(--fd-node-border-width) * 2);
|
|
241
232
|
height: 100%;
|
|
242
233
|
display: flex;
|
|
243
234
|
flex-direction: column;
|
|
@@ -247,14 +238,16 @@
|
|
|
247
238
|
display: flex;
|
|
248
239
|
align-items: center;
|
|
249
240
|
justify-content: space-between;
|
|
250
|
-
|
|
241
|
+
/* one 40px grid block for the icon row + a 20px gap before the body */
|
|
242
|
+
min-height: 40px;
|
|
243
|
+
margin-bottom: 20px;
|
|
251
244
|
flex-shrink: 0;
|
|
252
245
|
}
|
|
253
246
|
|
|
254
247
|
.flowdrop-notes-node__header-left {
|
|
255
248
|
display: flex;
|
|
256
249
|
align-items: center;
|
|
257
|
-
gap:
|
|
250
|
+
gap: 12px;
|
|
258
251
|
}
|
|
259
252
|
|
|
260
253
|
/* Squircle icon wrapper - Apple-style rounded square background */
|
|
@@ -262,9 +255,10 @@
|
|
|
262
255
|
display: flex;
|
|
263
256
|
align-items: center;
|
|
264
257
|
justify-content: center;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
258
|
+
/* px (not rem) so the icon stays grid-locked regardless of root font-size */
|
|
259
|
+
width: 36px;
|
|
260
|
+
height: 36px;
|
|
261
|
+
border-radius: 8px;
|
|
268
262
|
background: color-mix(in srgb, var(--_notes-icon) var(--fd-node-icon-bg-opacity), transparent);
|
|
269
263
|
flex-shrink: 0;
|
|
270
264
|
transition: all var(--fd-transition-normal);
|
|
@@ -280,8 +274,8 @@
|
|
|
280
274
|
}
|
|
281
275
|
|
|
282
276
|
.flowdrop-notes-node__icon-wrapper :global(.flowdrop-notes-node__icon) {
|
|
283
|
-
width:
|
|
284
|
-
height:
|
|
277
|
+
width: 20px;
|
|
278
|
+
height: 20px;
|
|
285
279
|
color: var(--fd-node-icon);
|
|
286
280
|
}
|
|
287
281
|
|
|
@@ -292,10 +286,12 @@
|
|
|
292
286
|
}
|
|
293
287
|
|
|
294
288
|
.flowdrop-notes-node__body {
|
|
295
|
-
margin-bottom: var(--fd-space-xs);
|
|
296
289
|
flex: 1;
|
|
297
290
|
overflow-y: auto;
|
|
298
291
|
color: var(--fd-muted-foreground);
|
|
292
|
+
/* 20px line rows so plain-text notes grow on the grid (rich markdown with
|
|
293
|
+
headings/lists may not snap exactly) */
|
|
294
|
+
line-height: 20px;
|
|
299
295
|
}
|
|
300
296
|
|
|
301
297
|
/* Markdown content inherits foreground color for better readability */
|
|
@@ -303,17 +299,36 @@
|
|
|
303
299
|
color: var(--fd-foreground);
|
|
304
300
|
}
|
|
305
301
|
|
|
302
|
+
/* Put markdown blocks on a 20px baseline so the note grows in clean 20px steps:
|
|
303
|
+
each block bottom-margins one grid row (browser em-margins would land off-grid),
|
|
304
|
+
and every line is a 20px row. */
|
|
305
|
+
.flowdrop-notes-node__body
|
|
306
|
+
:global(:is(h1, h2, h3, h4, h5, h6, p, ul, ol, pre, blockquote, table)) {
|
|
307
|
+
margin: 0 0 20px;
|
|
308
|
+
line-height: 20px;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.flowdrop-notes-node__body
|
|
312
|
+
:global(:is(h1, h2, h3, h4, h5, h6, p, ul, ol, pre, blockquote, table):last-child) {
|
|
313
|
+
margin-bottom: 0;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.flowdrop-notes-node__body :global(li) {
|
|
317
|
+
margin: 0;
|
|
318
|
+
line-height: 20px;
|
|
319
|
+
}
|
|
320
|
+
|
|
306
321
|
.flowdrop-notes-node__processing {
|
|
307
322
|
display: flex;
|
|
308
323
|
align-items: center;
|
|
309
|
-
gap:
|
|
324
|
+
gap: 8px;
|
|
310
325
|
font-size: var(--fd-text-xs);
|
|
311
326
|
color: var(--fd-muted-foreground);
|
|
312
327
|
}
|
|
313
328
|
|
|
314
329
|
.flowdrop-notes-node__spinner {
|
|
315
|
-
width:
|
|
316
|
-
height:
|
|
330
|
+
width: 12px;
|
|
331
|
+
height: 12px;
|
|
317
332
|
border: 1px solid color-mix(in srgb, var(--fd-foreground) 30%, transparent);
|
|
318
333
|
border-top-color: var(--fd-foreground);
|
|
319
334
|
border-radius: 50%;
|
|
@@ -323,14 +338,14 @@
|
|
|
323
338
|
.flowdrop-notes-node__error-indicator {
|
|
324
339
|
display: flex;
|
|
325
340
|
align-items: center;
|
|
326
|
-
gap:
|
|
341
|
+
gap: 8px;
|
|
327
342
|
font-size: var(--fd-text-xs);
|
|
328
343
|
color: var(--fd-error);
|
|
329
344
|
}
|
|
330
345
|
|
|
331
346
|
:global(.flowdrop-notes-node__error-icon) {
|
|
332
|
-
width:
|
|
333
|
-
height:
|
|
347
|
+
width: 12px;
|
|
348
|
+
height: 12px;
|
|
334
349
|
}
|
|
335
350
|
|
|
336
351
|
@keyframes spin {
|
|
@@ -339,46 +354,20 @@
|
|
|
339
354
|
}
|
|
340
355
|
}
|
|
341
356
|
|
|
342
|
-
.
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
right: var(--fd-space-xs);
|
|
346
|
-
width: 1.5rem;
|
|
347
|
-
height: 1.5rem;
|
|
348
|
-
background-color: var(--fd-backdrop);
|
|
349
|
-
border: 1px solid var(--fd-border);
|
|
350
|
-
border-radius: var(--fd-radius-sm);
|
|
351
|
-
color: var(--fd-muted-foreground);
|
|
352
|
-
cursor: pointer;
|
|
353
|
-
display: flex;
|
|
354
|
-
align-items: center;
|
|
355
|
-
justify-content: center;
|
|
356
|
-
opacity: 0;
|
|
357
|
-
transition: all var(--fd-transition-normal);
|
|
358
|
-
backdrop-filter: var(--fd-backdrop-blur);
|
|
359
|
-
z-index: 15;
|
|
360
|
-
font-size: var(--fd-text-sm);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
.flowdrop-notes-node:hover .flowdrop-notes-node__config-btn {
|
|
364
|
-
opacity: 1;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
.flowdrop-notes-node__config-btn:hover {
|
|
368
|
-
background-color: var(--fd-muted);
|
|
369
|
-
border-color: var(--fd-border-strong);
|
|
370
|
-
color: var(--fd-foreground);
|
|
357
|
+
/* Reveal the NodeConfigButton (gear) when the node is hovered. */
|
|
358
|
+
.flowdrop-notes-node:hover {
|
|
359
|
+
--fd-config-btn-opacity: 1;
|
|
371
360
|
}
|
|
372
361
|
|
|
373
362
|
/* Responsive design */
|
|
374
363
|
@media (max-width: 640px) {
|
|
375
364
|
.flowdrop-notes-node {
|
|
376
365
|
min-width: 200px;
|
|
377
|
-
max-width:
|
|
366
|
+
max-width: 360px;
|
|
378
367
|
}
|
|
379
368
|
|
|
380
369
|
.flowdrop-notes-node__content {
|
|
381
|
-
padding:
|
|
370
|
+
padding: 12px;
|
|
382
371
|
}
|
|
383
372
|
}
|
|
384
373
|
</style>
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { getDataTypeColor, getCategoryColorToken } from '../../utils/colors.js';
|
|
24
24
|
import { getInstance } from '../../stores/getInstance.svelte.js';
|
|
25
25
|
import { applyPortOrder, getPortTop, isPortVisible } from '../../utils/portUtils.js';
|
|
26
|
-
import
|
|
26
|
+
import NodeConfigButton from './NodeConfigButton.svelte';
|
|
27
27
|
import AlertCircleIcon from '../icons/AlertCircleIcon.svelte';
|
|
28
28
|
|
|
29
29
|
const props = $props<{
|
|
@@ -106,19 +106,6 @@
|
|
|
106
106
|
openConfigSidebar();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// Handle single click - only handle selection, no config opening
|
|
110
|
-
function handleClick(): void {
|
|
111
|
-
// Node selection is handled by Svelte Flow
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Handle keyboard events
|
|
115
|
-
function handleKeydown(event: KeyboardEvent): void {
|
|
116
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
117
|
-
event.preventDefault();
|
|
118
|
-
handleDoubleClick();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
109
|
const dynamicInputs = $derived(
|
|
123
110
|
((props.data.config?.dynamicInputs as DynamicPort[]) || []).map((port) =>
|
|
124
111
|
dynamicPortToNodePort(port, 'input')
|
|
@@ -175,7 +162,7 @@
|
|
|
175
162
|
const nodeMinHeight = $derived(
|
|
176
163
|
(() => {
|
|
177
164
|
const maxPorts = Math.max(visibleInputPorts.length, visibleOutputPorts.length, 1);
|
|
178
|
-
return maxPorts <= 1 ? 80 :
|
|
165
|
+
return maxPorts <= 1 ? 80 : maxPorts * 40;
|
|
179
166
|
})()
|
|
180
167
|
);
|
|
181
168
|
</script>
|
|
@@ -197,17 +184,16 @@
|
|
|
197
184
|
{/each}
|
|
198
185
|
|
|
199
186
|
<!-- Simple Node -->
|
|
187
|
+
<!-- Presentational: focus, keyboard and selection live on xyflow's node
|
|
188
|
+
wrapper (see UniversalNode). double-click is a mouse convenience. -->
|
|
189
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
200
190
|
<div
|
|
201
191
|
class="flowdrop-simple-node flowdrop-simple-node--normal"
|
|
202
192
|
class:flowdrop-simple-node--selected={props.selected}
|
|
203
193
|
class:flowdrop-simple-node--processing={props.isProcessing}
|
|
204
194
|
class:flowdrop-simple-node--error={props.isError}
|
|
205
195
|
style="min-height: {nodeMinHeight}px"
|
|
206
|
-
onclick={handleClick}
|
|
207
196
|
ondblclick={handleDoubleClick}
|
|
208
|
-
onkeydown={handleKeydown}
|
|
209
|
-
role="button"
|
|
210
|
-
tabindex="0"
|
|
211
197
|
>
|
|
212
198
|
<div class="flowdrop-simple-node__header">
|
|
213
199
|
<div class="flowdrop-simple-node__header-content">
|
|
@@ -250,13 +236,7 @@
|
|
|
250
236
|
{/if}
|
|
251
237
|
|
|
252
238
|
<!-- Config button -->
|
|
253
|
-
<
|
|
254
|
-
class="flowdrop-simple-node__config-btn"
|
|
255
|
-
onclick={openConfigSidebar}
|
|
256
|
-
title="Configure node"
|
|
257
|
-
>
|
|
258
|
-
<CogIcon />
|
|
259
|
-
</button>
|
|
239
|
+
<NodeConfigButton onclick={openConfigSidebar} title="Configure node" />
|
|
260
240
|
</div>
|
|
261
241
|
|
|
262
242
|
<!-- Output Handles: 1 port centered at 40px; N ports at 20px start, 40px gap -->
|
|
@@ -278,14 +258,15 @@
|
|
|
278
258
|
<style>
|
|
279
259
|
.flowdrop-simple-node {
|
|
280
260
|
position: relative;
|
|
281
|
-
background-color: var(--fd-
|
|
282
|
-
|
|
283
|
-
border
|
|
261
|
+
background-color: var(--fd-node-bg);
|
|
262
|
+
backdrop-filter: var(--fd-node-backdrop-filter);
|
|
263
|
+
border: var(--fd-node-border-width) solid var(--fd-node-border);
|
|
264
|
+
border-radius: var(--fd-node-radius);
|
|
284
265
|
display: flex;
|
|
285
266
|
flex-direction: column;
|
|
286
267
|
cursor: pointer;
|
|
287
268
|
transition: all var(--fd-transition-fast);
|
|
288
|
-
box-shadow: var(--fd-shadow
|
|
269
|
+
box-shadow: var(--fd-node-shadow);
|
|
289
270
|
overflow: hidden;
|
|
290
271
|
z-index: 10;
|
|
291
272
|
color: var(--fd-foreground);
|
|
@@ -298,28 +279,26 @@
|
|
|
298
279
|
}
|
|
299
280
|
|
|
300
281
|
.flowdrop-simple-node:hover {
|
|
301
|
-
box-shadow: var(--fd-shadow-
|
|
282
|
+
box-shadow: var(--fd-node-shadow-hover);
|
|
302
283
|
border-color: var(--fd-node-border-hover);
|
|
303
284
|
}
|
|
304
285
|
|
|
305
286
|
.flowdrop-simple-node--selected {
|
|
306
287
|
box-shadow:
|
|
307
288
|
0 0 0 2px var(--fd-primary-muted),
|
|
308
|
-
var(--fd-shadow-
|
|
289
|
+
var(--fd-node-shadow-hover);
|
|
309
290
|
border-color: var(--fd-primary);
|
|
310
291
|
}
|
|
311
292
|
|
|
312
293
|
.flowdrop-simple-node--selected:hover {
|
|
313
294
|
box-shadow:
|
|
314
295
|
0 0 0 2px var(--fd-primary-muted),
|
|
315
|
-
var(--fd-shadow-
|
|
296
|
+
var(--fd-node-shadow-hover);
|
|
316
297
|
border-color: var(--fd-primary);
|
|
317
298
|
}
|
|
318
299
|
|
|
319
|
-
.
|
|
320
|
-
|
|
321
|
-
outline-offset: 2px;
|
|
322
|
-
}
|
|
300
|
+
/* Focus ring is centralized in base.css (drawn on the .svelte-flow__node
|
|
301
|
+
wrapper, which is the focusable element). */
|
|
323
302
|
|
|
324
303
|
.flowdrop-simple-node--processing {
|
|
325
304
|
opacity: 0.7;
|
|
@@ -331,8 +310,9 @@
|
|
|
331
310
|
}
|
|
332
311
|
|
|
333
312
|
.flowdrop-simple-node__header {
|
|
334
|
-
|
|
335
|
-
|
|
313
|
+
/* px (not rem) on the 20px grid: 10px vertical, 20px horizontal. */
|
|
314
|
+
padding: 10px 20px;
|
|
315
|
+
background: var(--fd-node-header-bg);
|
|
336
316
|
flex: 1;
|
|
337
317
|
}
|
|
338
318
|
|
|
@@ -347,9 +327,10 @@
|
|
|
347
327
|
display: var(--fd-node-icon-display, flex);
|
|
348
328
|
align-items: center;
|
|
349
329
|
justify-content: center;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
330
|
+
/* px (not rem) so the icon stays grid-locked regardless of root font-size */
|
|
331
|
+
width: 36px;
|
|
332
|
+
height: 36px;
|
|
333
|
+
border-radius: 8px;
|
|
353
334
|
background: color-mix(in srgb, var(--_icon-color) var(--fd-node-icon-bg-opacity), transparent);
|
|
354
335
|
flex-shrink: 0;
|
|
355
336
|
transition: all var(--fd-transition-normal);
|
|
@@ -382,8 +363,8 @@
|
|
|
382
363
|
}
|
|
383
364
|
|
|
384
365
|
.flowdrop-simple-node__icon-wrapper :global(.flowdrop-simple-node__icon) {
|
|
385
|
-
width:
|
|
386
|
-
height:
|
|
366
|
+
width: 20px;
|
|
367
|
+
height: 20px;
|
|
387
368
|
color: var(--fd-node-icon);
|
|
388
369
|
}
|
|
389
370
|
|
|
@@ -414,40 +395,9 @@
|
|
|
414
395
|
height: 12px;
|
|
415
396
|
}
|
|
416
397
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
.flowdrop-simple-node__config-btn {
|
|
423
|
-
position: absolute;
|
|
424
|
-
top: var(--fd-space-xs);
|
|
425
|
-
right: var(--fd-space-xs);
|
|
426
|
-
width: 1.5rem;
|
|
427
|
-
height: 1.5rem;
|
|
428
|
-
background-color: var(--fd-backdrop);
|
|
429
|
-
border: 1px solid var(--fd-border);
|
|
430
|
-
border-radius: var(--fd-radius-sm);
|
|
431
|
-
color: var(--fd-muted-foreground);
|
|
432
|
-
cursor: pointer;
|
|
433
|
-
display: flex;
|
|
434
|
-
align-items: center;
|
|
435
|
-
justify-content: center;
|
|
436
|
-
opacity: 0;
|
|
437
|
-
transition: all var(--fd-transition-normal);
|
|
438
|
-
backdrop-filter: blur(4px);
|
|
439
|
-
z-index: 15;
|
|
440
|
-
font-size: var(--fd-text-sm);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
.flowdrop-simple-node:hover .flowdrop-simple-node__config-btn {
|
|
444
|
-
opacity: 1;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
.flowdrop-simple-node__config-btn:hover {
|
|
448
|
-
background-color: var(--fd-muted);
|
|
449
|
-
border-color: var(--fd-border-strong);
|
|
450
|
-
color: var(--fd-foreground);
|
|
398
|
+
/* Reveal the NodeConfigButton (gear) when the node is hovered. */
|
|
399
|
+
.flowdrop-simple-node:hover {
|
|
400
|
+
--fd-config-btn-opacity: 1;
|
|
451
401
|
}
|
|
452
402
|
|
|
453
403
|
@keyframes spin {
|