@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
package/dist/styles/base.css
CHANGED
|
@@ -8,6 +8,36 @@
|
|
|
8
8
|
box-sizing: border-box;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/* Drop the UA default margin on paragraphs so block text sits on the grid;
|
|
12
|
+
contexts that want spacing (e.g. .markdown-display p) opt back in. */
|
|
13
|
+
p {
|
|
14
|
+
margin: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* ───────────────────────────────────────────────────────────────────────────
|
|
18
|
+
Standardized focus ring — THE single source of truth.
|
|
19
|
+
|
|
20
|
+
The entire library draws ONE focus ring: a solid outline in --fd-ring, sized
|
|
21
|
+
by --fd-ring-width / --fd-ring-offset. Components must NOT declare their own
|
|
22
|
+
focus rings (no per-element :focus outline/box-shadow). :focus-visible keeps
|
|
23
|
+
it to keyboard navigation; browsers still surface it for text fields on
|
|
24
|
+
click. Scoped to the library roots so it never leaks into the host app.
|
|
25
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
26
|
+
.flowdrop-root :focus-visible,
|
|
27
|
+
.svelte-flow :focus-visible {
|
|
28
|
+
outline: var(--fd-ring-width) solid var(--fd-ring);
|
|
29
|
+
outline-offset: var(--fd-ring-offset);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* xyflow hard-disables the node wrapper outline
|
|
33
|
+
(.svelte-flow__node.selectable:focus-visible { outline: none }). That wrapper
|
|
34
|
+
is our single focusable node element, so re-assert the standard ring at
|
|
35
|
+
matching specificity. */
|
|
36
|
+
.svelte-flow .svelte-flow__node.selectable:focus-visible {
|
|
37
|
+
outline: var(--fd-ring-width) solid var(--fd-ring);
|
|
38
|
+
outline-offset: var(--fd-ring-offset);
|
|
39
|
+
}
|
|
40
|
+
|
|
11
41
|
/* Layout utilities */
|
|
12
42
|
.flowdrop-layout {
|
|
13
43
|
display: flex;
|
|
@@ -93,9 +123,11 @@
|
|
|
93
123
|
background-color: var(--fd-primary);
|
|
94
124
|
}
|
|
95
125
|
|
|
126
|
+
/* Handles are tabindex="-1" (programmatic focus only, so :focus-visible won't
|
|
127
|
+
fire) — keep a :focus ring, but draw it from the same tokens. */
|
|
96
128
|
.svelte-flow .svelte-flow__handle:focus {
|
|
97
|
-
outline:
|
|
98
|
-
outline-offset:
|
|
129
|
+
outline: var(--fd-ring-width) solid var(--fd-ring);
|
|
130
|
+
outline-offset: var(--fd-ring-offset);
|
|
99
131
|
}
|
|
100
132
|
|
|
101
133
|
/* Centralized handle edge positioning — offset derived from --fd-handle-size */
|
|
@@ -117,6 +149,7 @@
|
|
|
117
149
|
display: inline-flex;
|
|
118
150
|
align-items: center;
|
|
119
151
|
justify-content: center;
|
|
152
|
+
gap: var(--fd-space-xs);
|
|
120
153
|
padding: var(--fd-space-xs) var(--fd-space-xl);
|
|
121
154
|
border: 1px solid transparent;
|
|
122
155
|
border-radius: var(--fd-radius-md);
|
|
@@ -135,10 +168,7 @@
|
|
|
135
168
|
border-color: var(--fd-border);
|
|
136
169
|
}
|
|
137
170
|
|
|
138
|
-
.
|
|
139
|
-
outline: 2px solid var(--fd-ring);
|
|
140
|
-
outline-offset: 2px;
|
|
141
|
-
}
|
|
171
|
+
/* Focus ring is centralized (see top of file). */
|
|
142
172
|
|
|
143
173
|
.flowdrop-btn--primary {
|
|
144
174
|
background-color: var(--fd-primary);
|
|
@@ -195,38 +225,278 @@
|
|
|
195
225
|
min-height: var(--fd-space-6xl);
|
|
196
226
|
}
|
|
197
227
|
|
|
198
|
-
/*
|
|
228
|
+
/* ───────────────────────────────────────────────────────────────────────────
|
|
229
|
+
Icon buttons — square, icon-only. The typed primitive IconButton.svelte
|
|
230
|
+
routes here (the same way Button.svelte routes through .flowdrop-btn). It
|
|
231
|
+
composes onto .flowdrop-btn, then overrides geometry to a fixed square and
|
|
232
|
+
layers a tint variant. Corners follow --fd-control-radius so the Drafter
|
|
233
|
+
theme gets crisp icon buttons alongside its form controls.
|
|
234
|
+
|
|
235
|
+
Sizes: md (default) is 32px with a 16px glyph — the dominant size across the
|
|
236
|
+
library (form-array actions, modal closes, toolbars). sm maps to the
|
|
237
|
+
canonical --fd-size-icon-btn token (28px); lg is 36px (canvas-scale). */
|
|
238
|
+
.flowdrop-btn--icon {
|
|
239
|
+
width: 2rem;
|
|
240
|
+
height: 2rem;
|
|
241
|
+
min-height: 0;
|
|
242
|
+
padding: 0;
|
|
243
|
+
border-radius: var(--fd-control-radius);
|
|
244
|
+
color: var(--fd-muted-foreground);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.flowdrop-btn--icon svg {
|
|
248
|
+
width: 1rem;
|
|
249
|
+
height: 1rem;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.flowdrop-btn--icon.flowdrop-btn--sm {
|
|
253
|
+
width: var(--fd-size-icon-btn);
|
|
254
|
+
height: var(--fd-size-icon-btn);
|
|
255
|
+
padding: 0;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.flowdrop-btn--icon.flowdrop-btn--sm svg {
|
|
259
|
+
width: 0.875rem;
|
|
260
|
+
height: 0.875rem;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.flowdrop-btn--icon.flowdrop-btn--lg {
|
|
264
|
+
width: 2.25rem;
|
|
265
|
+
height: 2.25rem;
|
|
266
|
+
padding: 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.flowdrop-btn--icon.flowdrop-btn--lg svg {
|
|
270
|
+
width: 1.125rem;
|
|
271
|
+
height: 1.125rem;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Ghost (default for icon buttons) — transparent until hover. */
|
|
275
|
+
.flowdrop-btn--icon.flowdrop-btn--ghost:hover:not(:disabled) {
|
|
276
|
+
background-color: var(--fd-muted);
|
|
277
|
+
color: var(--fd-foreground);
|
|
278
|
+
border-color: transparent;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Default — flat --fd-background surface with a resting border. */
|
|
282
|
+
.flowdrop-btn--icon-default {
|
|
283
|
+
background-color: var(--fd-background);
|
|
284
|
+
border-color: var(--fd-border);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.flowdrop-btn--icon-default:hover:not(:disabled) {
|
|
288
|
+
background-color: var(--fd-muted);
|
|
289
|
+
color: var(--fd-foreground);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Tinted semantic variants — muted fill + semantic border/text, solid on press.
|
|
293
|
+
Unlike the solid text-button --primary, the icon flavour stays a quiet tint
|
|
294
|
+
so a row of action buttons reads as a group, not a wall of colour. */
|
|
295
|
+
.flowdrop-btn--icon-primary {
|
|
296
|
+
background-color: var(--fd-primary-muted);
|
|
297
|
+
border-color: var(--fd-primary);
|
|
298
|
+
color: var(--fd-primary-hover);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.flowdrop-btn--icon-primary:hover:not(:disabled) {
|
|
302
|
+
border-color: var(--fd-primary-hover);
|
|
303
|
+
color: var(--fd-primary-hover);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.flowdrop-btn--icon-primary:active:not(:disabled) {
|
|
307
|
+
background-color: var(--fd-primary);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.flowdrop-btn--icon-danger {
|
|
311
|
+
background-color: var(--fd-error-muted);
|
|
312
|
+
border-color: var(--fd-error);
|
|
313
|
+
color: var(--fd-error);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.flowdrop-btn--icon-danger:hover:not(:disabled) {
|
|
317
|
+
border-color: var(--fd-error-hover);
|
|
318
|
+
color: var(--fd-error-hover);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.flowdrop-btn--icon-danger:active:not(:disabled) {
|
|
322
|
+
background-color: var(--fd-error);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.flowdrop-btn--icon-success {
|
|
326
|
+
background-color: var(--fd-success-muted);
|
|
327
|
+
border-color: var(--fd-success);
|
|
328
|
+
color: var(--fd-success);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.flowdrop-btn--icon-success:hover:not(:disabled) {
|
|
332
|
+
border-color: var(--fd-success-hover);
|
|
333
|
+
color: var(--fd-success-hover);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.flowdrop-btn--icon-success:active:not(:disabled) {
|
|
337
|
+
background-color: var(--fd-success);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* Active / toggled state (e.g. a pressed canvas control) — primary tint. */
|
|
341
|
+
.flowdrop-btn--icon.is-active {
|
|
342
|
+
color: var(--fd-primary);
|
|
343
|
+
background-color: var(--fd-primary-muted);
|
|
344
|
+
border-color: var(--fd-primary);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.flowdrop-btn--icon:disabled {
|
|
348
|
+
opacity: 0.35;
|
|
349
|
+
cursor: not-allowed;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* ───────────────────────────────────────────────────────────────────────────
|
|
353
|
+
Form controls — THE single source of truth for input/select/textarea look.
|
|
354
|
+
|
|
355
|
+
The typed primitives Input.svelte / Select.svelte / Textarea.svelte route
|
|
356
|
+
here (the same way Button.svelte routes through .flowdrop-btn) so every field
|
|
357
|
+
across the library — config form, sidebar search, playground, prompts —
|
|
358
|
+
renders identically. Resting fields are ALWAYS the flat --fd-background
|
|
359
|
+
surface; `:disabled` is the ONLY muted state. Components must not re-declare
|
|
360
|
+
control backgrounds/borders locally. */
|
|
199
361
|
.flowdrop-input {
|
|
200
362
|
display: block;
|
|
201
363
|
width: 100%;
|
|
202
|
-
padding:
|
|
364
|
+
padding: 0.625rem 0.875rem;
|
|
203
365
|
border: 1px solid var(--fd-border);
|
|
204
|
-
border-radius: var(--fd-radius
|
|
366
|
+
border-radius: var(--fd-control-radius);
|
|
205
367
|
font-size: var(--fd-text-sm);
|
|
368
|
+
font-family: inherit;
|
|
206
369
|
line-height: 1.25rem;
|
|
207
370
|
color: var(--fd-foreground);
|
|
208
371
|
background-color: var(--fd-background);
|
|
372
|
+
box-shadow: var(--fd-shadow-sm);
|
|
209
373
|
transition:
|
|
210
374
|
border-color var(--fd-transition-normal),
|
|
211
375
|
box-shadow var(--fd-transition-normal);
|
|
212
376
|
}
|
|
213
377
|
|
|
378
|
+
.flowdrop-input::placeholder {
|
|
379
|
+
color: var(--fd-muted-foreground);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* Active-field hint only; the focus ring itself is centralized (top of file). */
|
|
383
|
+
.flowdrop-input:hover:not(:disabled):not(:focus) {
|
|
384
|
+
border-color: var(--fd-border-strong);
|
|
385
|
+
}
|
|
386
|
+
|
|
214
387
|
.flowdrop-input:focus {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
388
|
+
border-color: var(--fd-ring);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.flowdrop-input:disabled {
|
|
392
|
+
background-color: var(--fd-muted);
|
|
393
|
+
border-color: var(--fd-border-muted);
|
|
394
|
+
color: var(--fd-muted-foreground);
|
|
395
|
+
cursor: not-allowed;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Invalid keeps its error border even on hover. */
|
|
399
|
+
.flowdrop-input--invalid,
|
|
400
|
+
.flowdrop-input--invalid:hover:not(:disabled) {
|
|
401
|
+
border-color: var(--fd-error);
|
|
218
402
|
}
|
|
219
403
|
|
|
404
|
+
/* Sizes */
|
|
220
405
|
.flowdrop-input--sm {
|
|
221
|
-
padding:
|
|
406
|
+
padding: 0.375rem 0.625rem;
|
|
222
407
|
font-size: var(--fd-text-xs);
|
|
223
408
|
}
|
|
224
409
|
|
|
225
410
|
.flowdrop-input--lg {
|
|
226
|
-
padding:
|
|
411
|
+
padding: 0.75rem 1rem;
|
|
227
412
|
font-size: var(--fd-text-base);
|
|
228
413
|
}
|
|
229
414
|
|
|
415
|
+
/* Tabular figures for numeric entry (aligned digits). */
|
|
416
|
+
.flowdrop-input--numeric {
|
|
417
|
+
font-variant-numeric: tabular-nums;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* Multiline */
|
|
421
|
+
.flowdrop-input--textarea {
|
|
422
|
+
min-height: 5rem;
|
|
423
|
+
line-height: 1.5;
|
|
424
|
+
resize: vertical;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/* Select: room for the chevron overlay; native arrow removed. */
|
|
428
|
+
.flowdrop-input--select {
|
|
429
|
+
padding-right: 2.5rem;
|
|
430
|
+
cursor: pointer;
|
|
431
|
+
appearance: none;
|
|
432
|
+
-webkit-appearance: none;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Select shell carries the chevron; the <select> keeps the field look. */
|
|
436
|
+
.flowdrop-select-wrap {
|
|
437
|
+
position: relative;
|
|
438
|
+
width: 100%;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.flowdrop-select-wrap__icon {
|
|
442
|
+
position: absolute;
|
|
443
|
+
right: 0.75rem;
|
|
444
|
+
top: 50%;
|
|
445
|
+
transform: translateY(-50%);
|
|
446
|
+
display: flex;
|
|
447
|
+
pointer-events: none;
|
|
448
|
+
color: var(--fd-muted-foreground);
|
|
449
|
+
transition: color var(--fd-transition-fast);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.flowdrop-select-wrap:focus-within .flowdrop-select-wrap__icon {
|
|
453
|
+
color: var(--fd-primary);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.flowdrop-select-wrap__icon svg {
|
|
457
|
+
width: 1rem;
|
|
458
|
+
height: 1rem;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* Input with a leading/trailing affordance (e.g. a search magnifier). */
|
|
462
|
+
.flowdrop-input-wrap {
|
|
463
|
+
position: relative;
|
|
464
|
+
width: 100%;
|
|
465
|
+
display: flex;
|
|
466
|
+
align-items: center;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.flowdrop-input-wrap__icon {
|
|
470
|
+
position: absolute;
|
|
471
|
+
top: 50%;
|
|
472
|
+
transform: translateY(-50%);
|
|
473
|
+
display: flex;
|
|
474
|
+
align-items: center;
|
|
475
|
+
pointer-events: none;
|
|
476
|
+
color: var(--fd-muted-foreground);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.flowdrop-input-wrap__icon--leading {
|
|
480
|
+
left: 0.75rem;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.flowdrop-input-wrap__icon--trailing {
|
|
484
|
+
right: 0.75rem;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.flowdrop-input-wrap__icon svg {
|
|
488
|
+
width: 1rem;
|
|
489
|
+
height: 1rem;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.flowdrop-input--has-leading {
|
|
493
|
+
padding-left: 2.25rem;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.flowdrop-input--has-trailing {
|
|
497
|
+
padding-right: 2.25rem;
|
|
498
|
+
}
|
|
499
|
+
|
|
230
500
|
/* Card styles */
|
|
231
501
|
.flowdrop-card {
|
|
232
502
|
background-color: var(--fd-card);
|
|
@@ -1092,6 +1362,7 @@
|
|
|
1092
1362
|
--fd-notes-node-width: 500px;
|
|
1093
1363
|
--fd-notes-node-min-width: 250px;
|
|
1094
1364
|
--fd-notes-node-max-width: 500px;
|
|
1365
|
+
--fd-notes-node-min-height: 200px;
|
|
1095
1366
|
--fd-notes-node-backdrop-filter: blur(8px);
|
|
1096
1367
|
}
|
|
1097
1368
|
|
package/dist/styles/tokens.css
CHANGED
|
@@ -127,6 +127,13 @@
|
|
|
127
127
|
--fd-card: #ffffff; /* @public */
|
|
128
128
|
--fd-card-foreground: var(--_gray-9); /* @public */
|
|
129
129
|
|
|
130
|
+
/* ----- CHROME PANELS (sidebar + config/inspector panel) -----
|
|
131
|
+
Large editor-shell panels read from these so a theme can make them
|
|
132
|
+
glassy/translucent without touching every other surface. Default to the
|
|
133
|
+
opaque app background + no blur, so existing themes are unchanged. */
|
|
134
|
+
--fd-panel-bg: var(--fd-background); /* @public sidebar + config panel surface */
|
|
135
|
+
--fd-panel-backdrop-filter: none; /* @public glass/frost behind translucent panels; e.g. blur(14px) */
|
|
136
|
+
|
|
130
137
|
/* ----- HEADER (Distinct header styling) ----- */
|
|
131
138
|
--fd-header: #f5f7fa; /* @public */
|
|
132
139
|
--fd-header-foreground: var(--_gray-8); /* @public */
|
|
@@ -140,10 +147,45 @@
|
|
|
140
147
|
--fd-border-muted: var(--_gray-3); /* @public */
|
|
141
148
|
--fd-border-strong: var(--_gray-5); /* @public */
|
|
142
149
|
--fd-ring: var(--_blue-2); /* @public */
|
|
150
|
+
/* Focus-ring geometry. The whole library draws ONE focus ring from these
|
|
151
|
+
(see base.css). Color is theme-aware (--fd-ring); width/offset are not, so
|
|
152
|
+
they live only here. */
|
|
153
|
+
--fd-ring-width: 2px; /* @public */
|
|
154
|
+
--fd-ring-offset: 2px; /* @public */
|
|
155
|
+
|
|
156
|
+
/* ----- EDITOR CANVAS & NODE SURFACES -----
|
|
157
|
+
Scoped surfaces for the graph editor, kept separate from the general app
|
|
158
|
+
"chrome" (navbar, sidebars, panels) so a theme can restyle the canvas/nodes
|
|
159
|
+
without tinting the rest of the UI. Each defaults to its chrome equivalent,
|
|
160
|
+
so overriding the base token (e.g. --fd-card) still cascades here. */
|
|
161
|
+
--fd-canvas-bg: var(--fd-background); /* @public editor canvas (grid) background */
|
|
162
|
+
--fd-node-bg: var(--fd-card); /* @public node body surface */
|
|
163
|
+
--fd-node-header-bg: var(--fd-header); /* @public node header surface */
|
|
164
|
+
--fd-node-radius: var(
|
|
165
|
+
--fd-radius-xl
|
|
166
|
+
); /* @public node card corner radius; lower for sharper corners */
|
|
167
|
+
--fd-node-shadow: var(
|
|
168
|
+
--fd-shadow-md
|
|
169
|
+
); /* @public node resting elevation; 'none' for a flat look */
|
|
170
|
+
--fd-node-shadow-hover: var(
|
|
171
|
+
--fd-shadow-lg
|
|
172
|
+
); /* @public node hover/selected elevation; 'none' for a flat look */
|
|
173
|
+
--fd-node-backdrop-filter: none; /* @public glass/frost effect behind translucent node bodies; e.g. blur(10px) */
|
|
143
174
|
|
|
144
175
|
/* ----- NODE BORDERS (Higher contrast for visibility when zoomed out) ----- */
|
|
145
176
|
--fd-node-border: var(--_gray-5); /* @public */
|
|
146
177
|
--fd-node-border-hover: var(--_gray-6); /* @public */
|
|
178
|
+
--fd-node-border-width: 1.5px; /* @public node outline thickness; lower for a thinner look */
|
|
179
|
+
/* Note nodes can carry their own outline so themes can read them as
|
|
180
|
+
informational/annotation rather than a process node. Defaults to the
|
|
181
|
+
shared node border so existing themes are unchanged. */
|
|
182
|
+
--fd-note-border: var(--fd-node-border); /* @public notes-node outline */
|
|
183
|
+
--fd-note-border-hover: var(--fd-node-border-hover); /* @public notes-node outline (hover) */
|
|
184
|
+
|
|
185
|
+
/* ----- CANVAS GRID (pattern color for the editor background grid; any theme
|
|
186
|
+
can recolor whichever grid variant it picks via config.canvas.grid).
|
|
187
|
+
Default matches xyflow's dot-grid color so the default theme is unchanged. */
|
|
188
|
+
--fd-grid-pattern-color: #91919a; /* @public */
|
|
147
189
|
|
|
148
190
|
/* ----- PRIMARY (Interactive/Brand) ----- */
|
|
149
191
|
--fd-primary: var(--_blue-2); /* @public */
|
|
@@ -211,6 +253,12 @@
|
|
|
211
253
|
--fd-radius-2xl: 1rem; /* @public 16px */
|
|
212
254
|
--fd-radius-full: 9999px; /* @public */
|
|
213
255
|
|
|
256
|
+
/* Corner radius shared by form controls (input/select/textarea) and their
|
|
257
|
+
group containers (array item boxes, fieldsets, checkbox groups, config
|
|
258
|
+
sections). Defaults to --fd-radius-lg; themes can tighten it independently
|
|
259
|
+
of cards/panels — e.g. Drafter sets 2px for crisp drafting corners. */
|
|
260
|
+
--fd-control-radius: var(--fd-radius-lg); /* @public */
|
|
261
|
+
|
|
214
262
|
/* ----- SHADOWS (Refined layered shadows for modern depth) ----- */
|
|
215
263
|
--fd-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.04), 0 1px 3px rgb(0 0 0 / 0.06); /* @public */
|
|
216
264
|
--fd-shadow-md: 0 4px 8px rgb(0 0 0 / 0.06), 0 2px 4px rgb(0 0 0 / 0.04); /* @public */
|
|
@@ -307,6 +355,7 @@
|
|
|
307
355
|
--fd-scrollbar-thumb: var(--_gray-4); /* @internal */
|
|
308
356
|
--fd-scrollbar-thumb-hover: var(--_gray-5); /* @internal */
|
|
309
357
|
--fd-scrollbar-track: var(--_gray-2); /* @internal */
|
|
358
|
+
--fd-scrollbar-radius: 4px; /* @public scrollbar thumb/track corner radius; 0 for square */
|
|
310
359
|
|
|
311
360
|
/* ----- BACKDROP/OVERLAY ----- */
|
|
312
361
|
--fd-backdrop: rgba(255, 255, 255, 0.8); /* @internal */
|
|
@@ -324,11 +373,17 @@
|
|
|
324
373
|
|
|
325
374
|
/* ----- NODE LAYOUT (Dimensions and port alignment; multiples of 10 for grid) ----- */
|
|
326
375
|
--fd-node-grid-step: 10; /* @internal — layout algorithm detail */
|
|
327
|
-
--fd-node-default-width:
|
|
376
|
+
--fd-node-default-width: 280px; /* @public */
|
|
328
377
|
--fd-node-header-height: 60px; /* @public */
|
|
329
|
-
--fd-node-header-title-height: 40px; /* @internal */
|
|
378
|
+
--fd-node-header-title-height: 40px; /* @internal — fits icon + up to 2 text lines */
|
|
330
379
|
--fd-node-header-desc-line: 20px; /* @internal */
|
|
331
380
|
--fd-node-header-gap: 10px; /* @internal */
|
|
381
|
+
/* Divider absorbed into header bottom padding so header height stays on the
|
|
382
|
+
20px grid regardless of border thickness. */
|
|
383
|
+
--fd-node-header-divider-width: 1px; /* @public */
|
|
384
|
+
--fd-node-header-divider-color: var(
|
|
385
|
+
--fd-border-muted
|
|
386
|
+
); /* @public — header bottom divider color */
|
|
332
387
|
--fd-node-port-row-height: 20px; /* @internal */
|
|
333
388
|
--fd-node-terminal-size: 80px; /* @public */
|
|
334
389
|
--fd-node-square-size: 80px; /* @public */
|
|
@@ -395,6 +450,9 @@
|
|
|
395
450
|
--fd-node-border: #4a4a52;
|
|
396
451
|
--fd-node-border-hover: #5a5a62;
|
|
397
452
|
|
|
453
|
+
/* ----- CANVAS GRID (matches xyflow's dark dot-grid color) ----- */
|
|
454
|
+
--fd-grid-pattern-color: #777;
|
|
455
|
+
|
|
398
456
|
/* ----- NODE COLORS (port type labels/badges - lighter for readability on dark surfaces) ----- */
|
|
399
457
|
--fd-node-emerald: #34d399;
|
|
400
458
|
--fd-node-blue: #60a5fa;
|
package/dist/svelte-app.d.ts
CHANGED
|
@@ -204,6 +204,12 @@ export declare function mountWorkflowEditor(container: HTMLElement, options?: {
|
|
|
204
204
|
authProvider?: AuthProvider;
|
|
205
205
|
/** Instance identifier — see {@link FlowDropMountOptions.instanceId}. */
|
|
206
206
|
instanceId?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Register the built-in markdown/code/template editors. Batteries-included
|
|
209
|
+
* by default (chunks load lazily). See {@link FlowDropFeatures.builtinEditors}.
|
|
210
|
+
* @default true
|
|
211
|
+
*/
|
|
212
|
+
builtinEditors?: boolean;
|
|
207
213
|
}): Promise<MountedFlowDropApp>;
|
|
208
214
|
/**
|
|
209
215
|
* Unmount a FlowDrop app
|
package/dist/svelte-app.js
CHANGED
|
@@ -55,6 +55,58 @@ function releaseInstance(fd, isDefault) {
|
|
|
55
55
|
fd.destroy();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve endpoint config, port config and categories from mount options and
|
|
60
|
+
* apply them to the given instance (API context, port-compatibility checker,
|
|
61
|
+
* categories). Shared by `mountFlowDropApp` and `mountWorkflowEditor`.
|
|
62
|
+
*
|
|
63
|
+
* @returns the resolved {@link EndpointConfig} (merged with defaults), which the
|
|
64
|
+
* callers forward to their mounted component.
|
|
65
|
+
*/
|
|
66
|
+
async function configureInstance(fd, options) {
|
|
67
|
+
const { endpointConfig, portConfig, categories, authProvider } = options;
|
|
68
|
+
// Create endpoint configuration, merging with defaults so all required
|
|
69
|
+
// endpoints are present.
|
|
70
|
+
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
71
|
+
const config = endpointConfig
|
|
72
|
+
? {
|
|
73
|
+
...defaultEndpointConfig,
|
|
74
|
+
...endpointConfig,
|
|
75
|
+
endpoints: {
|
|
76
|
+
...defaultEndpointConfig.endpoints,
|
|
77
|
+
...endpointConfig.endpoints
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
: defaultEndpointConfig;
|
|
81
|
+
// Initialize port configuration (fetch from API when not supplied).
|
|
82
|
+
let finalPortConfig = portConfig;
|
|
83
|
+
if (!finalPortConfig) {
|
|
84
|
+
try {
|
|
85
|
+
finalPortConfig = await fetchPortConfig(config, authProvider);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
logger.warn('Failed to fetch port config from API, using default:', error);
|
|
89
|
+
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Configure this instance's API context and port compatibility checker.
|
|
93
|
+
fd.api.configure(config, authProvider);
|
|
94
|
+
fd.portCompatibility.reinitialize(finalPortConfig);
|
|
95
|
+
// Initialize this instance's categories (fetch from API when not supplied).
|
|
96
|
+
if (categories) {
|
|
97
|
+
fd.categories.initialize(categories);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
try {
|
|
101
|
+
const fetchedCategories = await fetchCategories(config, authProvider);
|
|
102
|
+
fd.categories.initialize(fetchedCategories);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
logger.warn('Failed to fetch categories from API, using defaults:', error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return config;
|
|
109
|
+
}
|
|
58
110
|
/**
|
|
59
111
|
* Mount the full FlowDrop App with navbar, sidebars, and workflow editor
|
|
60
112
|
*
|
|
@@ -103,61 +155,14 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
103
155
|
await initializeSettings({
|
|
104
156
|
defaults: initialSettings
|
|
105
157
|
});
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
endpoints: {
|
|
115
|
-
...defaultEndpointConfig.endpoints,
|
|
116
|
-
...endpointConfig.endpoints
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
// Use default configuration if none provided
|
|
122
|
-
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
123
|
-
config = defaultEndpointConfig;
|
|
124
|
-
}
|
|
125
|
-
// Initialize port configuration
|
|
126
|
-
let finalPortConfig = portConfig;
|
|
127
|
-
if (!finalPortConfig && config) {
|
|
128
|
-
// Try to fetch port configuration from API
|
|
129
|
-
try {
|
|
130
|
-
finalPortConfig = await fetchPortConfig(config, authProvider);
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
logger.warn('Failed to fetch port config from API, using default:', error);
|
|
134
|
-
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
else if (!finalPortConfig) {
|
|
138
|
-
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
139
|
-
}
|
|
140
|
-
// Configure this instance's API context (endpoints + auth provider) so
|
|
141
|
-
// <App> and services resolve it via getInstance().api.
|
|
142
|
-
if (config) {
|
|
143
|
-
fd.api.configure(config, authProvider);
|
|
144
|
-
}
|
|
145
|
-
// Re-initialize this instance's port compatibility checker with the resolved
|
|
146
|
-
// config (it was seeded with DEFAULT_PORT_CONFIG at construction).
|
|
147
|
-
fd.portCompatibility.reinitialize(finalPortConfig);
|
|
148
|
-
// Initialize this instance's categories
|
|
149
|
-
if (categories) {
|
|
150
|
-
fd.categories.initialize(categories);
|
|
151
|
-
}
|
|
152
|
-
else if (config) {
|
|
153
|
-
try {
|
|
154
|
-
const fetchedCategories = await fetchCategories(config, authProvider);
|
|
155
|
-
fd.categories.initialize(fetchedCategories);
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
logger.warn('Failed to fetch categories from API, using defaults:', error);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
158
|
+
// Resolve and apply endpoint config, port config and categories to this
|
|
159
|
+
// instance (see configureInstance).
|
|
160
|
+
const config = await configureInstance(fd, {
|
|
161
|
+
endpointConfig,
|
|
162
|
+
portConfig,
|
|
163
|
+
categories,
|
|
164
|
+
authProvider
|
|
165
|
+
});
|
|
161
166
|
// Set up event handler callbacks in this instance's store
|
|
162
167
|
if (eventHandlers?.onDirtyStateChange) {
|
|
163
168
|
fd.workflow.setOnDirtyStateChange(eventHandlers.onDirtyStateChange);
|
|
@@ -335,61 +340,17 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
335
340
|
* @returns Promise resolving to a MountedFlowDropApp instance
|
|
336
341
|
*/
|
|
337
342
|
export async function mountWorkflowEditor(container, options = {}) {
|
|
338
|
-
const { workflow, endpointConfig, portConfig, categories, authProvider, instanceId } = options;
|
|
343
|
+
const { workflow, endpointConfig, portConfig, categories, authProvider, instanceId, builtinEditors } = options;
|
|
339
344
|
// Per-instance state container (see mountFlowDropApp)
|
|
340
345
|
const { fd, isDefault } = acquireInstance(instanceId);
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
endpoints: {
|
|
350
|
-
...defaultEndpointConfig.endpoints,
|
|
351
|
-
...endpointConfig.endpoints
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
// Use default configuration if none provided
|
|
357
|
-
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
358
|
-
config = defaultEndpointConfig;
|
|
359
|
-
}
|
|
360
|
-
// Initialize port configuration
|
|
361
|
-
let finalPortConfig = portConfig;
|
|
362
|
-
if (!finalPortConfig && config) {
|
|
363
|
-
// Try to fetch port configuration from API
|
|
364
|
-
try {
|
|
365
|
-
finalPortConfig = await fetchPortConfig(config, authProvider);
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
logger.warn('Failed to fetch port config from API, using default:', error);
|
|
369
|
-
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else if (!finalPortConfig) {
|
|
373
|
-
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
374
|
-
}
|
|
375
|
-
// Configure this instance's API context and port compatibility checker.
|
|
376
|
-
if (config) {
|
|
377
|
-
fd.api.configure(config, authProvider);
|
|
378
|
-
}
|
|
379
|
-
fd.portCompatibility.reinitialize(finalPortConfig);
|
|
380
|
-
// Initialize this instance's categories
|
|
381
|
-
if (categories) {
|
|
382
|
-
fd.categories.initialize(categories);
|
|
383
|
-
}
|
|
384
|
-
else if (config) {
|
|
385
|
-
try {
|
|
386
|
-
const fetchedCategories = await fetchCategories(config, authProvider);
|
|
387
|
-
fd.categories.initialize(fetchedCategories);
|
|
388
|
-
}
|
|
389
|
-
catch (error) {
|
|
390
|
-
logger.warn('Failed to fetch categories from API, using defaults:', error);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
346
|
+
// Resolve and apply endpoint config, port config and categories to this
|
|
347
|
+
// instance (see configureInstance).
|
|
348
|
+
const config = await configureInstance(fd, {
|
|
349
|
+
endpointConfig,
|
|
350
|
+
portConfig,
|
|
351
|
+
categories,
|
|
352
|
+
authProvider
|
|
353
|
+
});
|
|
393
354
|
// Seed the instance's workflow before mounting so the editor renders it
|
|
394
355
|
// immediately. (1.x accepted this option but silently ignored it.)
|
|
395
356
|
if (workflow) {
|
|
@@ -401,7 +362,8 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
401
362
|
props: {
|
|
402
363
|
instance: fd,
|
|
403
364
|
endpointConfig: config,
|
|
404
|
-
authProvider
|
|
365
|
+
authProvider,
|
|
366
|
+
builtinEditors
|
|
405
367
|
}
|
|
406
368
|
});
|
|
407
369
|
// Create the mounted app interface (simpler version)
|