@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
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
<script lang="ts">
|
|
21
21
|
import Icon from '@iconify/svelte';
|
|
22
|
+
import Input from '../Input.svelte';
|
|
23
|
+
import Select from '../Select.svelte';
|
|
24
|
+
import Textarea from '../Textarea.svelte';
|
|
25
|
+
import IconButton from '../IconButton.svelte';
|
|
22
26
|
import type { FieldSchema } from './types.js';
|
|
23
27
|
import { m } from '../../messages/index.js';
|
|
24
28
|
|
|
@@ -284,40 +288,37 @@
|
|
|
284
288
|
<!-- Action buttons group -->
|
|
285
289
|
<div class="form-array__actions">
|
|
286
290
|
<!-- Move Up button -->
|
|
287
|
-
<
|
|
288
|
-
|
|
289
|
-
class="form-array__action-btn form-array__action-btn--move"
|
|
291
|
+
<IconButton
|
|
292
|
+
variant="primary"
|
|
290
293
|
onclick={() => moveItemUp(index)}
|
|
291
294
|
disabled={index === 0 || disabled}
|
|
292
|
-
|
|
295
|
+
ariaLabel={t.moveItemUp({ n: index + 1 })}
|
|
293
296
|
title={t.moveUp}
|
|
294
297
|
>
|
|
295
298
|
<Icon icon="heroicons:arrow-up" />
|
|
296
|
-
</
|
|
299
|
+
</IconButton>
|
|
297
300
|
|
|
298
301
|
<!-- Move Down button -->
|
|
299
|
-
<
|
|
300
|
-
|
|
301
|
-
class="form-array__action-btn form-array__action-btn--move"
|
|
302
|
+
<IconButton
|
|
303
|
+
variant="primary"
|
|
302
304
|
onclick={() => moveItemDown(index)}
|
|
303
305
|
disabled={index === items.length - 1 || disabled}
|
|
304
|
-
|
|
306
|
+
ariaLabel={t.moveItemDown({ n: index + 1 })}
|
|
305
307
|
title={t.moveDown}
|
|
306
308
|
>
|
|
307
309
|
<Icon icon="heroicons:arrow-down" />
|
|
308
|
-
</
|
|
310
|
+
</IconButton>
|
|
309
311
|
|
|
310
312
|
<!-- Delete button -->
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
class="form-array__action-btn form-array__action-btn--delete"
|
|
313
|
+
<IconButton
|
|
314
|
+
variant="danger"
|
|
314
315
|
onclick={() => removeItem(index)}
|
|
315
316
|
disabled={!canRemoveItem || disabled}
|
|
316
|
-
|
|
317
|
+
ariaLabel={t.deleteItem({ n: index + 1 })}
|
|
317
318
|
title={t.delete}
|
|
318
319
|
>
|
|
319
320
|
<Icon icon="heroicons:trash" />
|
|
320
|
-
</
|
|
321
|
+
</IconButton>
|
|
321
322
|
</div>
|
|
322
323
|
</div>
|
|
323
324
|
|
|
@@ -330,18 +331,16 @@
|
|
|
330
331
|
<!-- Simple type: render inline input -->
|
|
331
332
|
{#if itemSchema.type === 'string'}
|
|
332
333
|
{#if itemSchema.format === 'multiline'}
|
|
333
|
-
<
|
|
334
|
-
class="form-array__input form-array__textarea"
|
|
334
|
+
<Textarea
|
|
335
335
|
value={String(item ?? '')}
|
|
336
336
|
placeholder={itemSchema.placeholder ?? ''}
|
|
337
337
|
rows={3}
|
|
338
338
|
oninput={(e) => updateItem(index, e.currentTarget.value)}
|
|
339
339
|
{disabled}
|
|
340
|
-
|
|
340
|
+
/>
|
|
341
341
|
{:else}
|
|
342
|
-
<
|
|
342
|
+
<Input
|
|
343
343
|
type="text"
|
|
344
|
-
class="form-array__input"
|
|
345
344
|
value={String(item ?? '')}
|
|
346
345
|
placeholder={itemSchema.placeholder ?? ''}
|
|
347
346
|
oninput={(e) => updateItem(index, e.currentTarget.value)}
|
|
@@ -349,9 +348,9 @@
|
|
|
349
348
|
/>
|
|
350
349
|
{/if}
|
|
351
350
|
{:else if itemSchema.type === 'number' || itemSchema.type === 'integer'}
|
|
352
|
-
<
|
|
351
|
+
<Input
|
|
353
352
|
type="number"
|
|
354
|
-
class="
|
|
353
|
+
class="flowdrop-input--numeric"
|
|
355
354
|
value={item as number}
|
|
356
355
|
placeholder={itemSchema.placeholder ?? ''}
|
|
357
356
|
min={itemSchema.minimum}
|
|
@@ -380,8 +379,7 @@
|
|
|
380
379
|
</label>
|
|
381
380
|
{:else if itemSchema.enum}
|
|
382
381
|
<!-- Enum: render select -->
|
|
383
|
-
<
|
|
384
|
-
class="form-array__select"
|
|
382
|
+
<Select
|
|
385
383
|
value={String(item ?? '')}
|
|
386
384
|
onchange={(e) => updateItem(index, e.currentTarget.value)}
|
|
387
385
|
{disabled}
|
|
@@ -389,12 +387,11 @@
|
|
|
389
387
|
{#each itemSchema.enum as option (option)}
|
|
390
388
|
<option value={String(option)}>{String(option)}</option>
|
|
391
389
|
{/each}
|
|
392
|
-
</
|
|
390
|
+
</Select>
|
|
393
391
|
{:else}
|
|
394
392
|
<!-- Fallback to text -->
|
|
395
|
-
<
|
|
393
|
+
<Input
|
|
396
394
|
type="text"
|
|
397
|
-
class="form-array__input"
|
|
398
395
|
value={String(item ?? '')}
|
|
399
396
|
placeholder={itemSchema.placeholder ?? ''}
|
|
400
397
|
oninput={(e) => updateItem(index, e.currentTarget.value)}
|
|
@@ -425,9 +422,8 @@
|
|
|
425
422
|
|
|
426
423
|
<div class="form-array__subform-input">
|
|
427
424
|
{#if propFieldSchema.enum}
|
|
428
|
-
<
|
|
425
|
+
<Select
|
|
429
426
|
id="{id}-{index}-{propKey}"
|
|
430
|
-
class="form-array__select"
|
|
431
427
|
value={String(propValue ?? '')}
|
|
432
428
|
onchange={(e) =>
|
|
433
429
|
updateObjectProperty(index, propKey, e.currentTarget.value)}
|
|
@@ -436,23 +432,21 @@
|
|
|
436
432
|
{#each propFieldSchema.enum as option (option)}
|
|
437
433
|
<option value={String(option)}>{String(option)}</option>
|
|
438
434
|
{/each}
|
|
439
|
-
</
|
|
435
|
+
</Select>
|
|
440
436
|
{:else if propFieldSchema.type === 'string' && propFieldSchema.format === 'multiline'}
|
|
441
|
-
<
|
|
437
|
+
<Textarea
|
|
442
438
|
id="{id}-{index}-{propKey}"
|
|
443
|
-
class="form-array__input form-array__textarea"
|
|
444
439
|
value={String(propValue ?? '')}
|
|
445
440
|
placeholder={propFieldSchema.placeholder ?? ''}
|
|
446
441
|
rows={3}
|
|
447
442
|
oninput={(e) =>
|
|
448
443
|
updateObjectProperty(index, propKey, e.currentTarget.value)}
|
|
449
444
|
{disabled}
|
|
450
|
-
|
|
445
|
+
/>
|
|
451
446
|
{:else if propFieldSchema.type === 'string'}
|
|
452
|
-
<
|
|
447
|
+
<Input
|
|
453
448
|
id="{id}-{index}-{propKey}"
|
|
454
449
|
type="text"
|
|
455
|
-
class="form-array__input"
|
|
456
450
|
value={String(propValue ?? '')}
|
|
457
451
|
placeholder={propFieldSchema.placeholder ?? ''}
|
|
458
452
|
oninput={(e) =>
|
|
@@ -460,10 +454,10 @@
|
|
|
460
454
|
{disabled}
|
|
461
455
|
/>
|
|
462
456
|
{:else if propFieldSchema.type === 'number' || propFieldSchema.type === 'integer'}
|
|
463
|
-
<
|
|
457
|
+
<Input
|
|
464
458
|
id="{id}-{index}-{propKey}"
|
|
465
459
|
type="number"
|
|
466
|
-
class="
|
|
460
|
+
class="flowdrop-input--numeric"
|
|
467
461
|
value={propValue as number}
|
|
468
462
|
placeholder={propFieldSchema.placeholder ?? ''}
|
|
469
463
|
min={propFieldSchema.minimum}
|
|
@@ -493,10 +487,9 @@
|
|
|
493
487
|
</span>
|
|
494
488
|
</label>
|
|
495
489
|
{:else}
|
|
496
|
-
<
|
|
490
|
+
<Input
|
|
497
491
|
id="{id}-{index}-{propKey}"
|
|
498
492
|
type="text"
|
|
499
|
-
class="form-array__input"
|
|
500
493
|
value={String(propValue ?? '')}
|
|
501
494
|
placeholder={propFieldSchema.placeholder ?? ''}
|
|
502
495
|
oninput={(e) =>
|
|
@@ -596,7 +589,7 @@
|
|
|
596
589
|
flex-direction: column;
|
|
597
590
|
background-color: var(--fd-muted);
|
|
598
591
|
border: 1px solid var(--fd-border);
|
|
599
|
-
border-radius: var(--fd-radius
|
|
592
|
+
border-radius: var(--fd-control-radius);
|
|
600
593
|
overflow: hidden;
|
|
601
594
|
animation: itemFadeIn 0.25s ease-out forwards;
|
|
602
595
|
opacity: 0;
|
|
@@ -670,9 +663,7 @@
|
|
|
670
663
|
}
|
|
671
664
|
|
|
672
665
|
.form-array__item-toggle:focus-visible {
|
|
673
|
-
outline: none;
|
|
674
666
|
border-color: var(--fd-primary);
|
|
675
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
676
667
|
}
|
|
677
668
|
|
|
678
669
|
.form-array__item-toggle :global(svg) {
|
|
@@ -699,67 +690,8 @@
|
|
|
699
690
|
margin-left: auto;
|
|
700
691
|
}
|
|
701
692
|
|
|
702
|
-
.
|
|
703
|
-
|
|
704
|
-
align-items: center;
|
|
705
|
-
justify-content: center;
|
|
706
|
-
width: 2rem;
|
|
707
|
-
height: 2rem;
|
|
708
|
-
padding: 0;
|
|
709
|
-
border: 1px solid transparent;
|
|
710
|
-
border-radius: 0.375rem;
|
|
711
|
-
cursor: pointer;
|
|
712
|
-
transition: all 0.15s;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
.form-array__action-btn :global(svg) {
|
|
716
|
-
width: 1rem;
|
|
717
|
-
height: 1rem;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
.form-array__action-btn:focus-visible {
|
|
721
|
-
outline: none;
|
|
722
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
.form-array__action-btn:disabled {
|
|
726
|
-
opacity: 0.35;
|
|
727
|
-
cursor: not-allowed;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
/* Move Up/Down buttons - Blue semantic color */
|
|
731
|
-
.form-array__action-btn--move {
|
|
732
|
-
background-color: var(--fd-primary-muted);
|
|
733
|
-
border-color: var(--fd-primary);
|
|
734
|
-
color: var(--fd-primary-hover);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
.form-array__action-btn--move:hover:not(:disabled) {
|
|
738
|
-
background-color: var(--fd-primary-muted);
|
|
739
|
-
border-color: var(--fd-primary-hover);
|
|
740
|
-
color: var(--fd-primary-hover);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
.form-array__action-btn--move:active:not(:disabled) {
|
|
744
|
-
background-color: var(--fd-primary);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
/* Delete button - Red/Warning semantic color */
|
|
748
|
-
.form-array__action-btn--delete {
|
|
749
|
-
background-color: var(--fd-error-muted);
|
|
750
|
-
border-color: var(--fd-error);
|
|
751
|
-
color: var(--fd-error);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
.form-array__action-btn--delete:hover:not(:disabled) {
|
|
755
|
-
background-color: var(--fd-error-muted);
|
|
756
|
-
border-color: var(--fd-error-hover);
|
|
757
|
-
color: var(--fd-error-hover);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
.form-array__action-btn--delete:active:not(:disabled) {
|
|
761
|
-
background-color: var(--fd-error);
|
|
762
|
-
}
|
|
693
|
+
/* Action buttons (move/delete) now render through IconButton.svelte —
|
|
694
|
+
geometry + semantic tints live in base.css (.flowdrop-btn--icon*). */
|
|
763
695
|
|
|
764
696
|
/* ============================================
|
|
765
697
|
ITEM CONTENT
|
|
@@ -779,69 +711,6 @@
|
|
|
779
711
|
INPUTS (Simple Types)
|
|
780
712
|
============================================ */
|
|
781
713
|
|
|
782
|
-
.form-array__input {
|
|
783
|
-
width: 100%;
|
|
784
|
-
padding: 0.5rem 0.75rem;
|
|
785
|
-
border: 1px solid var(--fd-border);
|
|
786
|
-
border-radius: var(--fd-radius-md);
|
|
787
|
-
font-size: var(--fd-text-sm);
|
|
788
|
-
font-family: inherit;
|
|
789
|
-
color: var(--fd-foreground);
|
|
790
|
-
background-color: var(--fd-background);
|
|
791
|
-
transition: all var(--fd-transition-normal);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
.form-array__input::placeholder {
|
|
795
|
-
color: var(--fd-muted-foreground);
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
.form-array__input:hover {
|
|
799
|
-
border-color: var(--fd-border-strong);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
.form-array__input:focus {
|
|
803
|
-
outline: none;
|
|
804
|
-
border-color: var(--fd-primary);
|
|
805
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
.form-array__input--number {
|
|
809
|
-
font-variant-numeric: tabular-nums;
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
.form-array__textarea {
|
|
813
|
-
resize: vertical;
|
|
814
|
-
min-height: 4rem;
|
|
815
|
-
line-height: 1.5;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
.form-array__select {
|
|
819
|
-
width: 100%;
|
|
820
|
-
padding: 0.5rem 2rem 0.5rem 0.75rem;
|
|
821
|
-
border: 1px solid var(--fd-border);
|
|
822
|
-
border-radius: var(--fd-radius-md);
|
|
823
|
-
font-size: var(--fd-text-sm);
|
|
824
|
-
font-family: inherit;
|
|
825
|
-
color: var(--fd-foreground);
|
|
826
|
-
background-color: var(--fd-background);
|
|
827
|
-
cursor: pointer;
|
|
828
|
-
appearance: none;
|
|
829
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
|
|
830
|
-
background-repeat: no-repeat;
|
|
831
|
-
background-position: right 0.5rem center;
|
|
832
|
-
background-size: 1rem;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
.form-array__select:hover {
|
|
836
|
-
border-color: var(--fd-border-strong);
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
.form-array__select:focus {
|
|
840
|
-
outline: none;
|
|
841
|
-
border-color: var(--fd-primary);
|
|
842
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
843
|
-
}
|
|
844
|
-
|
|
845
714
|
/* ============================================
|
|
846
715
|
TOGGLE (Boolean in Array)
|
|
847
716
|
============================================ */
|
|
@@ -958,7 +827,7 @@
|
|
|
958
827
|
padding: 2rem 1rem;
|
|
959
828
|
background-color: var(--fd-muted);
|
|
960
829
|
border: 2px dashed var(--fd-border-strong);
|
|
961
|
-
border-radius: var(--fd-radius
|
|
830
|
+
border-radius: var(--fd-control-radius);
|
|
962
831
|
}
|
|
963
832
|
|
|
964
833
|
.form-array__empty :global(svg) {
|
|
@@ -986,7 +855,7 @@
|
|
|
986
855
|
gap: 0.5rem;
|
|
987
856
|
padding: 0.625rem 1rem;
|
|
988
857
|
border: 1px solid var(--fd-success);
|
|
989
|
-
border-radius: var(--fd-radius
|
|
858
|
+
border-radius: var(--fd-control-radius);
|
|
990
859
|
background-color: var(--fd-success-muted);
|
|
991
860
|
color: var(--fd-success-hover);
|
|
992
861
|
font-size: 0.8125rem;
|
|
@@ -1002,11 +871,6 @@
|
|
|
1002
871
|
color: var(--fd-success-hover);
|
|
1003
872
|
}
|
|
1004
873
|
|
|
1005
|
-
.form-array__add-btn:focus-visible {
|
|
1006
|
-
outline: none;
|
|
1007
|
-
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.3);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
874
|
.form-array__add-btn:active:not(:disabled) {
|
|
1011
875
|
background-color: var(--fd-success);
|
|
1012
876
|
}
|
|
@@ -787,7 +787,6 @@
|
|
|
787
787
|
}
|
|
788
788
|
|
|
789
789
|
.form-autocomplete--disabled {
|
|
790
|
-
opacity: 0.6;
|
|
791
790
|
pointer-events: none;
|
|
792
791
|
}
|
|
793
792
|
|
|
@@ -804,7 +803,7 @@
|
|
|
804
803
|
font-size: var(--fd-text-sm);
|
|
805
804
|
font-family: inherit;
|
|
806
805
|
color: var(--fd-foreground);
|
|
807
|
-
background-color: var(--fd-
|
|
806
|
+
background-color: var(--fd-background);
|
|
808
807
|
transition: all var(--fd-transition-normal);
|
|
809
808
|
box-shadow: var(--fd-shadow-sm);
|
|
810
809
|
cursor: text;
|
|
@@ -817,11 +816,16 @@
|
|
|
817
816
|
}
|
|
818
817
|
|
|
819
818
|
.form-autocomplete__field--focused {
|
|
820
|
-
border-color: var(--fd-
|
|
819
|
+
border-color: var(--fd-ring);
|
|
821
820
|
background-color: var(--fd-background);
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
.form-autocomplete--disabled .form-autocomplete__field {
|
|
824
|
+
background-color: var(--fd-muted);
|
|
825
|
+
border-color: var(--fd-border-muted);
|
|
826
|
+
color: var(--fd-muted-foreground);
|
|
827
|
+
cursor: not-allowed;
|
|
828
|
+
opacity: 1;
|
|
825
829
|
}
|
|
826
830
|
|
|
827
831
|
/* Multiple mode - textarea-like styling */
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
padding: 0.75rem;
|
|
87
87
|
background-color: var(--fd-muted);
|
|
88
88
|
border: 1px solid var(--fd-border);
|
|
89
|
-
border-radius: var(--fd-radius
|
|
89
|
+
border-radius: var(--fd-control-radius);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
.form-checkbox-item {
|
|
@@ -143,10 +143,6 @@
|
|
|
143
143
|
transform: scale(1);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
.form-checkbox__input:focus-visible + .form-checkbox__custom {
|
|
147
|
-
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
146
|
.form-checkbox__label {
|
|
151
147
|
font-size: var(--fd-text-sm);
|
|
152
148
|
color: var(--fd-foreground);
|
|
@@ -364,7 +364,9 @@
|
|
|
364
364
|
border: 1px solid var(--fd-border);
|
|
365
365
|
border-radius: var(--fd-radius-lg);
|
|
366
366
|
overflow: hidden;
|
|
367
|
-
|
|
367
|
+
/* Match plain form fields (FormTextField/Textarea/Select): rest on the
|
|
368
|
+
input surface, not the recessed --fd-muted. */
|
|
369
|
+
background-color: var(--fd-background);
|
|
368
370
|
transition: all var(--fd-transition-normal);
|
|
369
371
|
box-shadow: var(--fd-shadow-sm);
|
|
370
372
|
}
|
|
@@ -374,12 +376,15 @@
|
|
|
374
376
|
background-color: var(--fd-background);
|
|
375
377
|
}
|
|
376
378
|
|
|
379
|
+
/* Compound widget: the focusable CodeMirror lives inside this container, so
|
|
380
|
+
the standard ring (centralized for simple elements) is drawn here via
|
|
381
|
+
:focus-within using the same --fd-ring tokens. Outline paints outside the
|
|
382
|
+
container's overflow, so it isn't clipped. */
|
|
377
383
|
.form-code-editor__container:focus-within {
|
|
378
384
|
border-color: var(--fd-primary);
|
|
379
385
|
background-color: var(--fd-background);
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
var(--fd-shadow-sm);
|
|
386
|
+
outline: var(--fd-ring-width) solid var(--fd-ring);
|
|
387
|
+
outline-offset: var(--fd-ring-offset);
|
|
383
388
|
}
|
|
384
389
|
|
|
385
390
|
.form-code-editor--error .form-code-editor__container {
|
|
@@ -388,9 +393,6 @@
|
|
|
388
393
|
|
|
389
394
|
.form-code-editor--error .form-code-editor__container:focus-within {
|
|
390
395
|
border-color: var(--fd-error);
|
|
391
|
-
box-shadow:
|
|
392
|
-
0 0 0 3px rgba(239, 68, 68, 0.12),
|
|
393
|
-
var(--fd-shadow-sm);
|
|
394
396
|
}
|
|
395
397
|
|
|
396
398
|
/* Dark theme overrides */
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
import FormAutocomplete from './FormAutocomplete.svelte';
|
|
44
44
|
import type { FieldSchema } from './types.js';
|
|
45
45
|
import { getSchemaOptions } from './types.js';
|
|
46
|
+
import { resolveBaseFieldType } from './resolveFieldType.js';
|
|
46
47
|
import type { WorkflowNode, WorkflowEdge, AuthProvider } from '../../types/index.js';
|
|
47
48
|
import { getResolvedTheme } from '../../stores/settingsStore.svelte.js';
|
|
48
49
|
import { getInstance } from '../../stores/getInstance.svelte.js';
|
|
@@ -139,50 +140,10 @@
|
|
|
139
140
|
return 'template-editor';
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// Enum with single selection -> select
|
|
148
|
-
if (schema.enum) {
|
|
149
|
-
return 'select-enum';
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// oneOf with labeled options (standard JSON Schema) -> select
|
|
153
|
-
// Must be checked before basic type checks since oneOf schemas often have type: 'string'
|
|
154
|
-
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
155
|
-
return 'select-options';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Multiline string -> textarea
|
|
159
|
-
if (schema.type === 'string' && schema.format === 'multiline') {
|
|
160
|
-
return 'textarea';
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Range slider for number/integer with format: "range"
|
|
164
|
-
if ((schema.type === 'number' || schema.type === 'integer') && schema.format === 'range') {
|
|
165
|
-
return 'range';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// String -> text field
|
|
169
|
-
if (schema.type === 'string') {
|
|
170
|
-
return 'text';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Number or integer -> number field
|
|
174
|
-
if (schema.type === 'number' || schema.type === 'integer') {
|
|
175
|
-
return 'number';
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Boolean -> toggle
|
|
179
|
-
if (schema.type === 'boolean') {
|
|
180
|
-
return 'toggle';
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Future: Array type support
|
|
184
|
-
if (schema.type === 'array') {
|
|
185
|
-
return 'array';
|
|
143
|
+
// Shared basic field resolution (enum/oneOf/primitive types).
|
|
144
|
+
const base = resolveBaseFieldType(schema);
|
|
145
|
+
if (base) {
|
|
146
|
+
return base;
|
|
186
147
|
}
|
|
187
148
|
|
|
188
149
|
// Object type without specific format -> CodeMirror JSON editor
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
const fd = getInstance();
|
|
49
49
|
import type { FieldSchema } from './types.js';
|
|
50
50
|
import { getSchemaOptions } from './types.js';
|
|
51
|
+
import { resolveBaseFieldType } from './resolveFieldType.js';
|
|
51
52
|
import type { WorkflowNode, WorkflowEdge } from '../../types/index.js';
|
|
52
53
|
import type { AuthProvider } from '../../types/auth.js';
|
|
53
54
|
|
|
@@ -144,50 +145,10 @@
|
|
|
144
145
|
return 'code-editor-fallback';
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// Enum with single selection -> select
|
|
153
|
-
if (schema.enum) {
|
|
154
|
-
return 'select-enum';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// oneOf with labeled options (standard JSON Schema) -> select
|
|
158
|
-
// Must be checked before basic type checks since oneOf schemas often have type: 'string'
|
|
159
|
-
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
160
|
-
return 'select-options';
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Multiline string -> textarea
|
|
164
|
-
if (schema.type === 'string' && schema.format === 'multiline') {
|
|
165
|
-
return 'textarea';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Range slider for number/integer with format: "range"
|
|
169
|
-
if ((schema.type === 'number' || schema.type === 'integer') && schema.format === 'range') {
|
|
170
|
-
return 'range';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// String -> text field
|
|
174
|
-
if (schema.type === 'string') {
|
|
175
|
-
return 'text';
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Number or integer -> number field
|
|
179
|
-
if (schema.type === 'number' || schema.type === 'integer') {
|
|
180
|
-
return 'number';
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Boolean -> toggle
|
|
184
|
-
if (schema.type === 'boolean') {
|
|
185
|
-
return 'toggle';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Array type
|
|
189
|
-
if (schema.type === 'array') {
|
|
190
|
-
return 'array';
|
|
148
|
+
// Shared basic field resolution (enum/oneOf/primitive types).
|
|
149
|
+
const base = resolveBaseFieldType(schema);
|
|
150
|
+
if (base) {
|
|
151
|
+
return base;
|
|
191
152
|
}
|
|
192
153
|
|
|
193
154
|
// Fallback to text
|
|
@@ -233,11 +194,11 @@
|
|
|
233
194
|
function getEditorHint(editorType: string): string {
|
|
234
195
|
switch (editorType) {
|
|
235
196
|
case 'code-editor-fallback':
|
|
236
|
-
return "Code editor
|
|
197
|
+
return "Code editor not registered. Register it on the instance's field registry: import { registerCodeEditorField } from '@flowdrop/flowdrop/form/code'; registerCodeEditorField(instance.fields);";
|
|
237
198
|
case 'markdown-editor-fallback':
|
|
238
|
-
return "Markdown editor
|
|
199
|
+
return "Markdown editor not registered. Register it on the instance's field registry: import { registerMarkdownEditorField } from '@flowdrop/flowdrop/form/markdown'; registerMarkdownEditorField(instance.fields);";
|
|
239
200
|
case 'template-editor-fallback':
|
|
240
|
-
return "Template editor
|
|
201
|
+
return "Template editor not registered. Register it on the instance's field registry: import { registerTemplateEditorField } from '@flowdrop/flowdrop/form/code'; registerTemplateEditorField(instance.fields);";
|
|
241
202
|
default:
|
|
242
203
|
return 'This field type requires additional registration.';
|
|
243
204
|
}
|
|
@@ -641,7 +641,8 @@
|
|
|
641
641
|
border: 1px solid var(--fd-border);
|
|
642
642
|
border-radius: var(--fd-radius-lg);
|
|
643
643
|
overflow: hidden;
|
|
644
|
-
|
|
644
|
+
/* Match plain form fields: rest on the input surface, not --fd-muted. */
|
|
645
|
+
background-color: var(--fd-background);
|
|
645
646
|
transition: border-color var(--fd-transition-normal);
|
|
646
647
|
}
|
|
647
648
|
|
|
@@ -655,12 +656,13 @@
|
|
|
655
656
|
border-color: var(--fd-border-strong);
|
|
656
657
|
}
|
|
657
658
|
|
|
659
|
+
/* Compound widget: ring drawn on the body via :focus-within, using the
|
|
660
|
+
standard --fd-ring tokens (outline isn't clipped by the container overflow). */
|
|
658
661
|
.form-markdown-editor__body:focus-within {
|
|
659
662
|
border-color: var(--fd-primary);
|
|
660
663
|
background-color: var(--fd-background);
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
var(--fd-shadow-sm);
|
|
664
|
+
outline: var(--fd-ring-width) solid var(--fd-ring);
|
|
665
|
+
outline-offset: var(--fd-ring-offset);
|
|
664
666
|
}
|
|
665
667
|
|
|
666
668
|
/* ── Status bar ────────────────────────────────── */
|
|
@@ -702,7 +704,8 @@
|
|
|
702
704
|
|
|
703
705
|
.form-markdown-editor__body :global(.cm-editor) {
|
|
704
706
|
height: var(--editor-height, 300px);
|
|
705
|
-
|
|
707
|
+
/* Match plain form fields: white input surface (overrides oneDark in dark mode). */
|
|
708
|
+
background-color: var(--fd-background) !important;
|
|
706
709
|
color: var(--fd-foreground) !important;
|
|
707
710
|
}
|
|
708
711
|
|