@flowdrop/flowdrop 2.0.0-beta.2 → 2.0.0-beta.3
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 +34 -0
- package/MIGRATION-2.0.md +13 -0
- package/dist/components/App.svelte +21 -45
- package/dist/components/App.svelte.d.ts +2 -7
- package/dist/components/CanvasIconButton.svelte +76 -0
- package/dist/components/CanvasIconButton.svelte.d.ts +18 -0
- package/dist/components/ConfigForm.svelte +0 -19
- package/dist/components/ConfigPanel.svelte +4 -3
- package/dist/components/LogoWordmark.svelte +113 -0
- package/dist/components/LogoWordmark.svelte.d.ts +26 -0
- package/dist/components/Navbar.svelte +8 -59
- package/dist/components/NodeSidebar.svelte +4 -11
- package/dist/components/NodeSwapPicker.svelte +0 -2
- package/dist/components/PortMappingRow.svelte +0 -2
- package/dist/components/SchemaForm.svelte +0 -12
- package/dist/components/SettingsModal.svelte +0 -5
- package/dist/components/SettingsPanel.svelte +2 -6
- package/dist/components/ThemeToggle.svelte +0 -5
- 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 +0 -16
- package/dist/components/form/FormAutocomplete.svelte +10 -6
- package/dist/components/form/FormCheckboxGroup.svelte +0 -4
- package/dist/components/form/FormCodeEditor.svelte +9 -7
- package/dist/components/form/FormFieldLight.svelte +3 -3
- package/dist/components/form/FormMarkdownEditor.svelte +8 -5
- package/dist/components/form/FormNumberField.svelte +0 -4
- package/dist/components/form/FormRangeField.svelte +1 -20
- package/dist/components/form/FormSelect.svelte +10 -6
- package/dist/components/form/FormTemplateEditor.svelte +6 -4
- package/dist/components/form/FormTextField.svelte +10 -6
- package/dist/components/form/FormTextarea.svelte +10 -6
- package/dist/components/form/FormToggle.svelte +0 -4
- 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 +0 -2
- package/dist/components/playground/PlaygroundApp.svelte +1 -1
- package/dist/components/playground/PlaygroundStudio.svelte +0 -5
- 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 +185 -0
- package/dist/skins/index.d.ts +2 -1
- package/dist/skins/index.js +4 -2
- package/dist/styles/base.css +38 -9
- package/dist/styles/tokens.css +54 -2
- package/dist/svelte-app.d.ts +6 -0
- package/dist/svelte-app.js +3 -2
- 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/package.json +1 -1
|
@@ -473,11 +473,6 @@
|
|
|
473
473
|
color: var(--fd-foreground);
|
|
474
474
|
}
|
|
475
475
|
|
|
476
|
-
.schema-form__button--secondary:focus-visible {
|
|
477
|
-
outline: none;
|
|
478
|
-
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
476
|
.schema-form__button--primary {
|
|
482
477
|
background: linear-gradient(135deg, var(--fd-primary) 0%, var(--fd-primary-hover) 100%);
|
|
483
478
|
color: var(--fd-primary-foreground);
|
|
@@ -498,13 +493,6 @@
|
|
|
498
493
|
transform: translateY(0);
|
|
499
494
|
}
|
|
500
495
|
|
|
501
|
-
.schema-form__button--primary:focus-visible {
|
|
502
|
-
outline: none;
|
|
503
|
-
box-shadow:
|
|
504
|
-
0 0 0 3px rgba(59, 130, 246, 0.4),
|
|
505
|
-
0 4px 12px rgba(59, 130, 246, 0.35);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
496
|
.schema-form__button-spinner {
|
|
509
497
|
width: 1rem;
|
|
510
498
|
height: 1rem;
|
|
@@ -198,7 +198,8 @@
|
|
|
198
198
|
description: 'Visual style and layout of the editor',
|
|
199
199
|
oneOf: [
|
|
200
200
|
{ const: 'default', title: 'Default' },
|
|
201
|
-
{ const: 'minimal', title: 'Minimal' }
|
|
201
|
+
{ const: 'minimal', title: 'Minimal' },
|
|
202
|
+
{ const: 'drafter', title: 'Drafter' }
|
|
202
203
|
],
|
|
203
204
|
default: 'default'
|
|
204
205
|
}
|
|
@@ -538,11 +539,6 @@
|
|
|
538
539
|
color: var(--fd-primary-foreground);
|
|
539
540
|
}
|
|
540
541
|
|
|
541
|
-
.flowdrop-settings-panel__tab:focus {
|
|
542
|
-
outline: none;
|
|
543
|
-
box-shadow: 0 0 0 2px var(--fd-ring);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
542
|
:global(.flowdrop-settings-panel__tab-icon) {
|
|
547
543
|
font-size: var(--fd-text-base);
|
|
548
544
|
}
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
const fd = getInstance();
|
|
19
19
|
|
|
20
|
+
// Element ref used only to reach xyflow's node wrapper (our ancestor).
|
|
21
|
+
let universalNodeEl: HTMLDivElement;
|
|
22
|
+
|
|
20
23
|
let {
|
|
21
24
|
data,
|
|
22
25
|
selected = false
|
|
@@ -61,6 +64,34 @@
|
|
|
61
64
|
shouldShowNodeStatus(executionInfo) && resolvedComponentName !== 'note'
|
|
62
65
|
);
|
|
63
66
|
|
|
67
|
+
// Keyboard activation lives on xyflow's node wrapper — the single focusable,
|
|
68
|
+
// arrow-movable element SvelteFlow manages. Because the wrapper is our
|
|
69
|
+
// ancestor, its keydown events never bubble down into our markup, so we bind
|
|
70
|
+
// directly to it. Enter/Space opens the node's config, mirroring the
|
|
71
|
+
// double-click (and single-click for square/atom) mouse paths. Node selection
|
|
72
|
+
// and arrow-key movement remain SvelteFlow's job.
|
|
73
|
+
$effect(() => {
|
|
74
|
+
const wrapper = universalNodeEl?.closest<HTMLElement>('.svelte-flow__node');
|
|
75
|
+
if (!wrapper) return;
|
|
76
|
+
|
|
77
|
+
function onWrapperKeydown(event: KeyboardEvent): void {
|
|
78
|
+
// Only when the node itself is focused — not an inner field (e.g. an
|
|
79
|
+
// editable note) — so we don't hijack typing.
|
|
80
|
+
if (event.target !== wrapper) return;
|
|
81
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
82
|
+
event.preventDefault();
|
|
83
|
+
data.onConfigOpen?.({
|
|
84
|
+
id: data.nodeId ?? 'unknown',
|
|
85
|
+
type: resolvedComponentName,
|
|
86
|
+
data
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
wrapper.addEventListener('keydown', onWrapperKeydown);
|
|
92
|
+
return () => wrapper.removeEventListener('keydown', onWrapperKeydown);
|
|
93
|
+
});
|
|
94
|
+
|
|
64
95
|
/**
|
|
65
96
|
* Get the node component for the given type from the registry.
|
|
66
97
|
*
|
|
@@ -129,7 +160,7 @@
|
|
|
129
160
|
}
|
|
130
161
|
</script>
|
|
131
162
|
|
|
132
|
-
<div class="universal-node">
|
|
163
|
+
<div class="universal-node" bind:this={universalNodeEl}>
|
|
133
164
|
<!-- Render the node component dynamically (Svelte 5 dynamic component syntax) -->
|
|
134
165
|
{#if nodeComponent}
|
|
135
166
|
<!-- Svelte 5 dynamic component limitation; reactivity maintained via $derived -->
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
import CanvasController from './CanvasController.svelte';
|
|
27
27
|
import FlowDropZone from './FlowDropZone.svelte';
|
|
28
28
|
import EdgeRefresher from './EdgeRefresher.svelte';
|
|
29
|
-
import { tick, untrack } from 'svelte';
|
|
29
|
+
import { tick, untrack, onMount } from 'svelte';
|
|
30
30
|
import type { EndpointConfig } from '../config/endpoints.js';
|
|
31
31
|
import type { AuthProvider } from '../types/auth.js';
|
|
32
32
|
import ConnectionLine from './ConnectionLine.svelte';
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
import { m } from '../messages/index.js';
|
|
35
35
|
import { provideInstance } from '../stores/getInstance.svelte.js';
|
|
36
36
|
import type { FlowDropInstance } from '../stores/instanceContainer.svelte.js';
|
|
37
|
+
import type { FlowDropGridVariant } from '../types/theme.js';
|
|
37
38
|
import UniversalNode from './UniversalNode.svelte';
|
|
38
39
|
import {
|
|
39
40
|
EdgeStylingHelper,
|
|
@@ -56,7 +57,8 @@
|
|
|
56
57
|
import { logger } from '../utils/logger.js';
|
|
57
58
|
import { validateWorkflowData } from '../utils/validation.js';
|
|
58
59
|
import { createEditorStateMachine } from '../stores/editorStateMachine.svelte.js';
|
|
59
|
-
import
|
|
60
|
+
import CanvasIconButton from './CanvasIconButton.svelte';
|
|
61
|
+
import CommandLineIcon from './icons/CommandLineIcon.svelte';
|
|
60
62
|
import { DEV } from 'esm-env';
|
|
61
63
|
|
|
62
64
|
interface Props {
|
|
@@ -85,6 +87,23 @@
|
|
|
85
87
|
onToggleConsole?: () => void;
|
|
86
88
|
/** Per-instance state container (created by mount functions). Defaults to the page-default instance. */
|
|
87
89
|
instance?: FlowDropInstance;
|
|
90
|
+
/**
|
|
91
|
+
* Canvas background grid pattern. Supplied by App from the active theme's
|
|
92
|
+
* `config.canvas.grid` default; any theme can opt into 'lines' / 'cross'.
|
|
93
|
+
* Color is driven separately by the `--fd-grid-pattern-color` token.
|
|
94
|
+
* @default 'dots'
|
|
95
|
+
*/
|
|
96
|
+
gridVariant?: FlowDropGridVariant;
|
|
97
|
+
/**
|
|
98
|
+
* Register the built-in heavy form editors (markdown / code / template)
|
|
99
|
+
* on this instance's field registry. Batteries-included by default — node
|
|
100
|
+
* config fields with `format: 'markdown' | 'code' | 'template'` render real
|
|
101
|
+
* CodeMirror editors. The chunks are code-split (loaded lazily here), so
|
|
102
|
+
* the `/editor` static bundle stays light. Set `false` to keep the textarea
|
|
103
|
+
* fallback or register your own field components. See `features.builtinEditors`.
|
|
104
|
+
* @default true
|
|
105
|
+
*/
|
|
106
|
+
builtinEditors?: boolean;
|
|
88
107
|
}
|
|
89
108
|
|
|
90
109
|
let props: Props = $props();
|
|
@@ -95,10 +114,36 @@
|
|
|
95
114
|
// svelte-ignore state_referenced_locally
|
|
96
115
|
const fd = provideInstance(props.instance);
|
|
97
116
|
|
|
117
|
+
// Batteries-included: register the built-in heavy form editors (markdown /
|
|
118
|
+
// code / template) on this instance's field registry so node config fields
|
|
119
|
+
// render real editors out of the box. Dynamic import is deliberate — the
|
|
120
|
+
// bundle guard only inspects *static* imports, and `form/markdown`/`form/code`
|
|
121
|
+
// statically re-export their CodeMirror components, so a static import here
|
|
122
|
+
// would leak CodeMirror into the light `/editor` entry. Importing lazily on
|
|
123
|
+
// mount keeps the static graph clean while the chunks load on demand.
|
|
124
|
+
// register*Field is idempotent per registry, so re-mounts are safe.
|
|
125
|
+
onMount(() => {
|
|
126
|
+
if (props.builtinEditors === false) return;
|
|
127
|
+
void (async () => {
|
|
128
|
+
const [code, markdown] = await Promise.all([
|
|
129
|
+
import('../form/code.js'),
|
|
130
|
+
import('../form/markdown.js')
|
|
131
|
+
]);
|
|
132
|
+
code.registerCodeEditorField(fd.fields);
|
|
133
|
+
code.registerTemplateEditorField(fd.fields);
|
|
134
|
+
markdown.registerMarkdownEditorField(fd.fields);
|
|
135
|
+
})();
|
|
136
|
+
});
|
|
137
|
+
|
|
98
138
|
// `mode` is the public API; the canvas only needs to know whether editing is
|
|
99
139
|
// enabled. 'readonly' and 'locked' both disable interaction identically.
|
|
100
140
|
const canvasEditable = $derived((props.mode ?? 'edit') === 'edit');
|
|
101
141
|
|
|
142
|
+
// Canvas grid pattern, supplied by the active theme's config.canvas.grid
|
|
143
|
+
// (App passes it down). BackgroundVariant's enum values are the same strings
|
|
144
|
+
// ('dots' | 'lines' | 'cross'), so the theme config maps straight through.
|
|
145
|
+
const gridVariant = $derived((props.gridVariant ?? 'dots') as BackgroundVariant);
|
|
146
|
+
|
|
102
147
|
// ---------------------------------------------------------------------------
|
|
103
148
|
// Editor State Machine
|
|
104
149
|
// Centralizes reactive guards — replaces scattered boolean flags
|
|
@@ -875,23 +920,26 @@
|
|
|
875
920
|
>
|
|
876
921
|
<Controls />
|
|
877
922
|
{#if canvasEditable && props.onToggleConsole}
|
|
878
|
-
<
|
|
923
|
+
<CanvasIconButton
|
|
879
924
|
class="flowdrop-console-toggle"
|
|
880
|
-
|
|
925
|
+
label={m().layout.commandConsole}
|
|
926
|
+
active={props.consoleOpen}
|
|
881
927
|
onclick={props.onToggleConsole}
|
|
882
|
-
aria-label={m().layout.commandConsole}
|
|
883
|
-
title={m().layout.commandConsole}
|
|
884
|
-
type="button"
|
|
885
928
|
>
|
|
886
|
-
|
|
887
|
-
|
|
929
|
+
{#snippet icon()}
|
|
930
|
+
<CommandLineIcon />
|
|
931
|
+
{/snippet}
|
|
932
|
+
</CanvasIconButton>
|
|
888
933
|
{/if}
|
|
889
934
|
<!-- Always render Background for consistent bg color in dark/light mode -->
|
|
890
935
|
<Background
|
|
891
936
|
gap={getEditorSettings().gridSize}
|
|
892
|
-
bgColor="var(--fd-
|
|
893
|
-
variant={
|
|
894
|
-
|
|
937
|
+
bgColor="var(--fd-canvas-bg)"
|
|
938
|
+
variant={gridVariant}
|
|
939
|
+
lineWidth={1}
|
|
940
|
+
patternColor={getEditorSettings().showGrid
|
|
941
|
+
? 'var(--fd-grid-pattern-color)'
|
|
942
|
+
: 'transparent'}
|
|
895
943
|
/>
|
|
896
944
|
{#if getEditorSettings().showMinimap}
|
|
897
945
|
<MiniMap />
|
|
@@ -1006,48 +1054,11 @@
|
|
|
1006
1054
|
justify-content: space-between;
|
|
1007
1055
|
}
|
|
1008
1056
|
|
|
1009
|
-
|
|
1010
|
-
|
|
1057
|
+
/* Console toggle — placement only; visuals live in CanvasIconButton */
|
|
1058
|
+
:global(.flowdrop-console-toggle) {
|
|
1011
1059
|
bottom: 140px;
|
|
1012
1060
|
left: 12px;
|
|
1013
1061
|
z-index: 5;
|
|
1014
|
-
display: flex;
|
|
1015
|
-
align-items: center;
|
|
1016
|
-
justify-content: center;
|
|
1017
|
-
width: 2rem;
|
|
1018
|
-
height: 2rem;
|
|
1019
|
-
border: 1px solid var(--fd-border);
|
|
1020
|
-
border-radius: var(--fd-radius-md);
|
|
1021
|
-
background-color: var(--fd-background);
|
|
1022
|
-
color: var(--fd-muted-foreground);
|
|
1023
|
-
cursor: pointer;
|
|
1024
|
-
box-shadow: var(--fd-shadow-sm);
|
|
1025
|
-
transition:
|
|
1026
|
-
color var(--fd-transition-fast),
|
|
1027
|
-
background-color var(--fd-transition-fast),
|
|
1028
|
-
box-shadow var(--fd-transition-fast);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
.flowdrop-console-toggle:hover {
|
|
1032
|
-
color: var(--fd-foreground);
|
|
1033
|
-
background-color: var(--fd-subtle);
|
|
1034
|
-
box-shadow: var(--fd-shadow-md);
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
.flowdrop-console-toggle:focus {
|
|
1038
|
-
outline: none;
|
|
1039
|
-
box-shadow: 0 0 0 2px var(--fd-ring);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
.flowdrop-console-toggle--active {
|
|
1043
|
-
color: var(--fd-primary);
|
|
1044
|
-
background-color: var(--fd-primary-muted);
|
|
1045
|
-
border-color: var(--fd-primary);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
.flowdrop-console-toggle--active:hover {
|
|
1049
|
-
color: var(--fd-primary);
|
|
1050
|
-
background-color: var(--fd-primary-muted);
|
|
1051
1062
|
}
|
|
1052
1063
|
|
|
1053
1064
|
:global(.flowdrop-workflow-editor .svelte-flow__node:hover) {
|
|
@@ -3,6 +3,7 @@ import type { WorkflowNode as WorkflowNodeType } from '../types/index.js';
|
|
|
3
3
|
import type { EndpointConfig } from '../config/endpoints.js';
|
|
4
4
|
import type { AuthProvider } from '../types/auth.js';
|
|
5
5
|
import type { FlowDropInstance } from '../stores/instanceContainer.svelte.js';
|
|
6
|
+
import type { FlowDropGridVariant } from '../types/theme.js';
|
|
6
7
|
interface Props {
|
|
7
8
|
endpointConfig?: EndpointConfig;
|
|
8
9
|
/** Auth provider applied to this instance's API requests. */
|
|
@@ -27,6 +28,23 @@ interface Props {
|
|
|
27
28
|
onToggleConsole?: () => void;
|
|
28
29
|
/** Per-instance state container (created by mount functions). Defaults to the page-default instance. */
|
|
29
30
|
instance?: FlowDropInstance;
|
|
31
|
+
/**
|
|
32
|
+
* Canvas background grid pattern. Supplied by App from the active theme's
|
|
33
|
+
* `config.canvas.grid` default; any theme can opt into 'lines' / 'cross'.
|
|
34
|
+
* Color is driven separately by the `--fd-grid-pattern-color` token.
|
|
35
|
+
* @default 'dots'
|
|
36
|
+
*/
|
|
37
|
+
gridVariant?: FlowDropGridVariant;
|
|
38
|
+
/**
|
|
39
|
+
* Register the built-in heavy form editors (markdown / code / template)
|
|
40
|
+
* on this instance's field registry. Batteries-included by default — node
|
|
41
|
+
* config fields with `format: 'markdown' | 'code' | 'template'` render real
|
|
42
|
+
* CodeMirror editors. The chunks are code-split (loaded lazily here), so
|
|
43
|
+
* the `/editor` static bundle stays light. Set `false` to keep the textarea
|
|
44
|
+
* fallback or register your own field components. See `features.builtinEditors`.
|
|
45
|
+
* @default true
|
|
46
|
+
*/
|
|
47
|
+
builtinEditors?: boolean;
|
|
30
48
|
}
|
|
31
49
|
declare const WorkflowEditor: import("svelte").Component<Props, {
|
|
32
50
|
updateNodeData: (nodeId: string, dataUpdates: Partial<WorkflowNodeType["data"]>) => void;
|
|
@@ -68,12 +68,12 @@
|
|
|
68
68
|
|
|
69
69
|
.console-output::-webkit-scrollbar-track {
|
|
70
70
|
background: var(--fd-scrollbar-track);
|
|
71
|
-
border-radius:
|
|
71
|
+
border-radius: var(--fd-scrollbar-radius);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
.console-output::-webkit-scrollbar-thumb {
|
|
75
75
|
background: var(--fd-scrollbar-thumb);
|
|
76
|
-
border-radius:
|
|
76
|
+
border-radius: var(--fd-scrollbar-radius);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
.console-output::-webkit-scrollbar-thumb:hover {
|
|
@@ -670,9 +670,7 @@
|
|
|
670
670
|
}
|
|
671
671
|
|
|
672
672
|
.form-array__item-toggle:focus-visible {
|
|
673
|
-
outline: none;
|
|
674
673
|
border-color: var(--fd-primary);
|
|
675
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
676
674
|
}
|
|
677
675
|
|
|
678
676
|
.form-array__item-toggle :global(svg) {
|
|
@@ -717,11 +715,6 @@
|
|
|
717
715
|
height: 1rem;
|
|
718
716
|
}
|
|
719
717
|
|
|
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
718
|
.form-array__action-btn:disabled {
|
|
726
719
|
opacity: 0.35;
|
|
727
720
|
cursor: not-allowed;
|
|
@@ -800,9 +793,7 @@
|
|
|
800
793
|
}
|
|
801
794
|
|
|
802
795
|
.form-array__input:focus {
|
|
803
|
-
outline: none;
|
|
804
796
|
border-color: var(--fd-primary);
|
|
805
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
806
797
|
}
|
|
807
798
|
|
|
808
799
|
.form-array__input--number {
|
|
@@ -837,9 +828,7 @@
|
|
|
837
828
|
}
|
|
838
829
|
|
|
839
830
|
.form-array__select:focus {
|
|
840
|
-
outline: none;
|
|
841
831
|
border-color: var(--fd-primary);
|
|
842
|
-
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
843
832
|
}
|
|
844
833
|
|
|
845
834
|
/* ============================================
|
|
@@ -1002,11 +991,6 @@
|
|
|
1002
991
|
color: var(--fd-success-hover);
|
|
1003
992
|
}
|
|
1004
993
|
|
|
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
994
|
.form-array__add-btn:active:not(:disabled) {
|
|
1011
995
|
background-color: var(--fd-success);
|
|
1012
996
|
}
|
|
@@ -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 */
|
|
@@ -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 */
|
|
@@ -233,11 +233,11 @@
|
|
|
233
233
|
function getEditorHint(editorType: string): string {
|
|
234
234
|
switch (editorType) {
|
|
235
235
|
case 'code-editor-fallback':
|
|
236
|
-
return "Code editor
|
|
236
|
+
return "Code editor not registered. Register it on the instance's field registry: import { registerCodeEditorField } from '@flowdrop/flowdrop/form/code'; registerCodeEditorField(instance.fields);";
|
|
237
237
|
case 'markdown-editor-fallback':
|
|
238
|
-
return "Markdown editor
|
|
238
|
+
return "Markdown editor not registered. Register it on the instance's field registry: import { registerMarkdownEditorField } from '@flowdrop/flowdrop/form/markdown'; registerMarkdownEditorField(instance.fields);";
|
|
239
239
|
case 'template-editor-fallback':
|
|
240
|
-
return "Template editor
|
|
240
|
+
return "Template editor not registered. Register it on the instance's field registry: import { registerTemplateEditorField } from '@flowdrop/flowdrop/form/code'; registerTemplateEditorField(instance.fields);";
|
|
241
241
|
default:
|
|
242
242
|
return 'This field type requires additional registration.';
|
|
243
243
|
}
|
|
@@ -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
|
|
|
@@ -165,12 +165,6 @@
|
|
|
165
165
|
0 2px 4px rgba(0, 0, 0, 0.1);
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
.form-range-field:focus::-webkit-slider-thumb {
|
|
169
|
-
box-shadow:
|
|
170
|
-
0 0 0 3px rgba(59, 130, 246, 0.2),
|
|
171
|
-
0 4px 12px rgba(59, 130, 246, 0.35);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
168
|
/* Firefox - Track */
|
|
175
169
|
.form-range-field::-moz-range-track {
|
|
176
170
|
height: 6px;
|
|
@@ -205,20 +199,7 @@
|
|
|
205
199
|
0 2px 4px rgba(0, 0, 0, 0.1);
|
|
206
200
|
}
|
|
207
201
|
|
|
208
|
-
.
|
|
209
|
-
box-shadow:
|
|
210
|
-
0 0 0 3px rgba(59, 130, 246, 0.2),
|
|
211
|
-
0 4px 12px rgba(59, 130, 246, 0.35);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/* Focus styles */
|
|
215
|
-
.form-range-field:focus {
|
|
216
|
-
outline: none;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.form-range-field:focus-visible {
|
|
220
|
-
outline: none;
|
|
221
|
-
}
|
|
202
|
+
/* Focus ring is centralized in base.css (outline on the range input). */
|
|
222
203
|
|
|
223
204
|
/* Value display row */
|
|
224
205
|
.form-range-values {
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
font-size: var(--fd-text-sm);
|
|
86
86
|
font-family: inherit;
|
|
87
87
|
color: var(--fd-foreground);
|
|
88
|
-
background-color: var(--fd-
|
|
88
|
+
background-color: var(--fd-background);
|
|
89
89
|
transition: all var(--fd-transition-normal);
|
|
90
90
|
box-shadow: var(--fd-shadow-sm);
|
|
91
91
|
cursor: pointer;
|
|
@@ -98,12 +98,16 @@
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
.form-select:focus {
|
|
101
|
-
|
|
102
|
-
border-color: var(--fd-primary);
|
|
101
|
+
border-color: var(--fd-ring);
|
|
103
102
|
background-color: var(--fd-background);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.form-select:disabled {
|
|
106
|
+
background-color: var(--fd-muted);
|
|
107
|
+
border-color: var(--fd-border-muted);
|
|
108
|
+
color: var(--fd-muted-foreground);
|
|
109
|
+
cursor: not-allowed;
|
|
110
|
+
opacity: 1;
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
.form-select__icon {
|