@flowdrop/flowdrop 2.0.0-beta.1 → 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 +67 -0
- package/MIGRATION-2.0.md +173 -3
- package/dist/api/enhanced-client.js +6 -11
- package/dist/components/App.svelte +22 -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 +6 -21
- 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/PipelineStatus.svelte +6 -1
- package/dist/components/PipelineStatus.svelte.d.ts +3 -0
- package/dist/components/PortMappingRow.svelte +0 -2
- package/dist/components/SchemaForm.svelte +4 -14
- 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 +66 -52
- package/dist/components/WorkflowEditor.svelte.d.ts +21 -0
- package/dist/components/chat/AIChatPanel.svelte +7 -2
- 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 +18 -15
- package/dist/components/form/FormCheckboxGroup.svelte +0 -4
- package/dist/components/form/FormCodeEditor.svelte +9 -7
- package/dist/components/form/FormFieldLight.svelte +33 -4
- package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
- 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/form/FormUISchemaRenderer.svelte +3 -1
- 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 +11 -12
- 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/PipelineKanbanView.svelte +4 -2
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
- package/dist/components/playground/PipelinePanel.svelte +20 -3
- package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
- package/dist/components/playground/PipelineTableView.svelte +4 -2
- package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
- package/dist/components/playground/Playground.svelte +76 -25
- package/dist/components/playground/Playground.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundApp.svelte +6 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +5 -0
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +7 -6
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +2 -1
- package/dist/components/playground/pipelineViewUtils.svelte.js +2 -2
- package/dist/config/endpoints.d.ts +23 -0
- package/dist/config/endpoints.js +28 -0
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.js +2 -6
- package/dist/display/index.d.ts +6 -1
- package/dist/display/index.js +9 -1
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/form/full.d.ts +2 -1
- package/dist/form/full.js +4 -1
- package/dist/form/index.d.ts +0 -1
- package/dist/form/index.js +3 -2
- package/dist/helpers/workflowEditorHelper.d.ts +4 -2
- package/dist/helpers/workflowEditorHelper.js +4 -3
- package/dist/playground/index.d.ts +2 -2
- package/dist/playground/index.js +2 -2
- package/dist/playground/mount.d.ts +19 -5
- package/dist/playground/mount.js +16 -8
- package/dist/registry/builtinNodeTypes.d.ts +53 -0
- package/dist/registry/builtinNodeTypes.js +67 -0
- package/dist/registry/builtinNodes.d.ts +2 -39
- package/dist/registry/builtinNodes.js +6 -53
- package/dist/services/agentSpecExecutionService.d.ts +0 -2
- package/dist/services/agentSpecExecutionService.js +0 -2
- package/dist/services/apiVariableService.js +12 -26
- package/dist/services/categoriesApi.js +3 -6
- package/dist/services/chatService.d.ts +4 -3
- package/dist/services/chatService.js +13 -18
- package/dist/services/interruptService.d.ts +7 -6
- package/dist/services/interruptService.js +19 -21
- package/dist/services/playgroundService.d.ts +9 -8
- package/dist/services/playgroundService.js +23 -25
- package/dist/services/portConfigApi.js +3 -6
- package/dist/services/settingsService.d.ts +9 -4
- package/dist/services/settingsService.js +23 -12
- 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/stores/apiContext.d.ts +11 -0
- package/dist/stores/apiContext.js +15 -0
- package/dist/stores/categoriesStore.svelte.js +0 -1
- package/dist/stores/playgroundStore.svelte.js +0 -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 +4 -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/auth.d.ts +9 -51
- package/dist/types/auth.js +4 -54
- package/dist/types/events.d.ts +18 -0
- package/dist/types/events.js +2 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +0 -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/edgeStyling.js +9 -5
- package/dist/utils/fetchWithAuth.d.ts +36 -15
- package/dist/utils/fetchWithAuth.js +53 -23
- package/dist/utils/nodeTypes.js +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,73 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.0.0-beta.3] - 2026-06-12
|
|
11
|
+
|
|
12
|
+
Third 2.0 beta, published under the npm `beta` dist-tag (`npm install @flowdrop/flowdrop@beta`). `latest` remains 1.15.0 until 2.0.0 GA. This release finishes the navbar/theme defaults pass started in beta.2 (navbar opt-in everywhere, light as the default theme, the FlowDrop wordmark in the header), adds the **Drafter** blueprint theme with per-theme canvas grids, and lands a keyboard-navigation and focus-ring overhaul alongside the 20px node-grid alignment.
|
|
13
|
+
|
|
14
|
+
### Breaking Changes
|
|
15
|
+
|
|
16
|
+
- **`mountPlaygroundApp` / `<PlaygroundApp>` no longer render the navbar by default.** `showNavbar` now defaults to `false`, matching `mountFlowDropApp` / `<App>` — so every mount path is navbar-off by default and embedding FlowDrop into a page that already has its own header never double-stacks a header. Pass `showNavbar: true` to opt back into the FlowDrop navbar (logo, branding, settings modal) when FlowDrop owns the whole page.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Drafter blueprint theme.** A third built-in editor theme (`'drafter'`), shipping light + dark variants: a blueprint aesthetic with a soft mint canvas, a subtle emerald line grid, and translucent green-tinted flat nodes. Data-type port colors and category icon colors are left untouched so they keep popping against the muted draft surface. Selectable from the Settings → UI Theme picker; the `FlowDropSkinName` / theme / skin name unions gain `'drafter'`.
|
|
21
|
+
- **Per-theme canvas grid.** A new `FlowDropGridVariant` type (`'dots' | 'lines' | 'cross'`) and `themeConfig.canvas.grid` config let any theme drive the editor's background grid (previously hardcoded to dots). The grid pattern color is the `--fd-grid-pattern-color` token, whose default matches xyflow's dot color, so the default/minimal themes render unchanged. `resolveTheme` now merges `config.canvas` alongside `config.sidebar`.
|
|
22
|
+
- **`features.builtinEditors` opt-out.** The built-in markdown/code/template editors are batteries-included in the full editor by default. Pass `features: { builtinEditors: false }` to `mountFlowDropApp` (or `builtinEditors: false` to `mountWorkflowEditor` / `<WorkflowEditor>`) to skip registering them — keeping the textarea fallback or leaving room to register your own field components via `instance.fields.register(...)`. The corrected fallback hint now points at the registry-scoped API (`registerMarkdownEditorField(instance.fields)`).
|
|
23
|
+
- **FlowDrop wordmark logo in the navbar.** The header now renders the FlowDrop wordmark in place of the plain text title.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **The default theme preference is now `'light'` (was `'dark'`).** `DEFAULT_THEME_SETTINGS.preference` was hardcoded to `'dark'`, so any embed with no persisted theme choice rendered dark. Embeds now default to light; hosts that want dark by default should set the preference explicitly.
|
|
28
|
+
- **Editor / node / chrome surface tokens are scoped per surface,** refining how themes (including Drafter) tint the canvas, nodes, and surrounding chrome independently.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **Nodes are a single tab stop again.** The node config (gear) button sat in the tab order, so leaving a node required a second `Tab` press. The gear button is removed from the tab order (it stays mouse/Enter-activatable), and node focus defers to xyflow's own node focus — Tab now moves one node per press. `nodesFocusable` redundancy was removed to eliminate the duplicate stop.
|
|
33
|
+
- **The full editor renders markdown/code/config editors out of the box again.** The beta.2 light-entry split made the heavy form editors opt-in everywhere, which inadvertently left `<WorkflowEditor>` / `<App>` / the playground showing the "Editor component not registered" textarea fallback for node config fields with `format: 'markdown' | 'code' | 'template'`. The full editor now registers the built-in editors on its own instance's field registry on mount. Registration uses a dynamic `import()`, so the chunks stay code-split (loaded lazily) and the light `/editor` static bundle is unaffected — the bundle guard still passes. The standalone `@flowdrop/flowdrop/form` primitive is unchanged and remains opt-in.
|
|
34
|
+
- **`<App navbarActions>` accepts the full `NavbarAction` shape.** The component prop was typed with an inline subset that silently dropped `external` and `group`, even though the underlying `<Navbar>` (and the `mountFlowDropApp` option) already supported them. It now uses the canonical `NavbarAction` type, so external-link and grouped actions type-check through the component as they always did through the mount API.
|
|
35
|
+
- **The node header no longer shows a top-accent line.**
|
|
36
|
+
|
|
37
|
+
### Changed (internal — no API change)
|
|
38
|
+
|
|
39
|
+
- **One centralized focus ring across the whole component library.** New `--fd-ring-width` / `--fd-ring-offset` tokens and a single `.flowdrop-root :focus-visible` rule in `base.css` replace ~200 lines of component-local focus CSS (mismatched outlines, hardcoded `rgba(59,130,246)` box-shadow glows, `color-mix` rings) removed across 41 files. CodeMirror editors in `overflow:hidden` containers use a `:focus-within` ring (outline paints outside the box and would clip); range-input thumbs ring on the parent.
|
|
40
|
+
- **Extracted shared `NodeConfigButton` and `CanvasIconButton` components,** replacing per-node config-button and per-canvas floating-button duplication (including an inline-SVG cog) with one keyboard-correct implementation each.
|
|
41
|
+
- **Node geometry converted from `rem` to `px` and snapped to a 20px grid** across all eight node types — header, port rows (fixed 60px), icon sizes, paddings, gaps, and font sizes — so nodes stay aligned to the canvas coordinate grid regardless of the host's root font-size.
|
|
42
|
+
- **The code / markdown / template editors now rest on the shared input surface** instead of carrying their own background.
|
|
43
|
+
|
|
44
|
+
## [2.0.0-beta.2] - 2026-06-09
|
|
45
|
+
|
|
46
|
+
Second 2.0 beta, published under the npm `beta` dist-tag (`npm install @flowdrop/flowdrop@beta`). This release tightens the 2.0 package boundaries, finishes `AuthProvider` propagation across the editor and playground runtime surfaces, and adds a regression guard for light-entry bundle size.
|
|
47
|
+
|
|
48
|
+
### Breaking Changes
|
|
49
|
+
|
|
50
|
+
- **Heavy dependencies no longer leak into the light entries.** Three exports moved so that `@flowdrop/flowdrop/core` and the light `@flowdrop/flowdrop/form` never statically pull CodeMirror, `marked`, DOMPurify, or `@xyflow/svelte` (enforced by a new CI bundle guard, see below):
|
|
51
|
+
- `sanitizeHtml` moved from `@flowdrop/flowdrop/core` to `@flowdrop/flowdrop/display` (it is DOMPurify-backed; `/core` is the zero-heavy-dep entry).
|
|
52
|
+
- `FormFieldFull` moved from `@flowdrop/flowdrop/form` to `@flowdrop/flowdrop/form/full` — it statically bundles every editor (CodeMirror), so keeping it in the light `/form` entry pulled CodeMirror into every `SchemaForm` import. The `FormField` exported from `/form` remains the registry-based light factory.
|
|
53
|
+
- Service singleton _instances_ (`playgroundService`, `interruptService` from `/playground`; `nodeExecutionService` from `/editor`; `agentSpecExecutionService` from `/core`) are no longer exported — they were constructed eagerly at import time, pulling the service and its dependencies into the entry's static graph. The classes (`PlaygroundService`, `InterruptService`, `NodeExecutionService`, `AgentSpecExecutionService`) remain; call `getInstance()` for the shared instance. See [MIGRATION-2.0.md section 4](./MIGRATION-2.0.md#keeping-heavy-dependencies-out-of-the-light-entries).
|
|
54
|
+
|
|
55
|
+
### Changed (internal — no API change)
|
|
56
|
+
|
|
57
|
+
- `SchemaForm`, `ConfigForm`, and the UISchema renderer now use the registry-based light `FormFieldLight` internally, so importing `SchemaForm` no longer statically pulls CodeMirror (heavy editors stay opt-in via `/form/code` and `/form/markdown`).
|
|
58
|
+
- Built-in node **type metadata** (aliases, `resolveBuiltinAlias`, `isBuiltinType`) split into a component-free `registry/builtinNodeTypes` module so `/core`'s node-type utilities no longer drag in the node components (and transitively `marked`/DOMPurify).
|
|
59
|
+
- `utils/edgeStyling` and the `ConnectionLineType` reference in `types/index.ts` use type-only imports of `@xyflow/svelte`, removing the runtime `@xyflow/svelte` dependency from the headless command DSL reachable from `/core`.
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- **Bundle-size guard (`pnpm run check:bundle`)** and a CI workflow that walk each published entry's static import graph and fail if a heavy dependency (CodeMirror, `@xyflow/svelte`, `marked`, DOMPurify) becomes statically reachable from a light entry (`/core`, `/form`, `/editor`). Dynamic `import()` — how `/form/code` lazy-loads CodeMirror — is intentionally ignored.
|
|
64
|
+
- **500-node editor render benchmark.** The e2e performance suite now includes a large trigger-chain workflow fixture so regressions in large-canvas rendering show up before release.
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- **`AuthProvider` now reaches all documented runtime surfaces.** Playground, chat, interrupt, settings, editor, and pipeline requests now consistently route through the configured provider, including standalone playground mounts and the editor/pipeline views that previously dropped auth headers on secondary requests.
|
|
69
|
+
- **Theme skin tokens clear when switching back to the default skin.** Returning from a custom/base skin to the default theme no longer leaves stale CSS custom properties behind.
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
|
|
73
|
+
- **`AuthProvider` request handling is centralized.** Services now share the `fetchWithAuth` path, and the public provider interface is slimmer while preserving bearer, API-key, custom-header, and callback authentication behavior.
|
|
74
|
+
|
|
8
75
|
## [2.0.0-beta.1] - 2026-06-07
|
|
9
76
|
|
|
10
77
|
Pre-release of 2.0.0, published under the npm `beta` dist-tag (`npm install @flowdrop/flowdrop@beta`). `latest` remains 1.15.0 until 2.0.0 GA. See [MIGRATION-2.0.md](./MIGRATION-2.0.md) for the upgrade guide.
|
package/MIGRATION-2.0.md
CHANGED
|
@@ -80,6 +80,52 @@ authProvider)` for you. Services that previously read the singleton (playground,
|
|
|
80
80
|
interrupt, chat, node-execution, dynamic-schema, variable) now take the endpoint
|
|
81
81
|
config as their first argument — pass `fd.api.config`.
|
|
82
82
|
|
|
83
|
+
These services also accept the instance's `AuthProvider` as an **optional
|
|
84
|
+
trailing argument** so every request they make is authenticated consistently
|
|
85
|
+
with `fd.api.client` (the typed workflow/node API). The built-in components and
|
|
86
|
+
mount helpers pass `fd.api.authProvider` for you — no action is needed for the
|
|
87
|
+
normal mounted flow. Only direct callers of the service singletons need to
|
|
88
|
+
forward it:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
import { playgroundService } from '@flowdrop/flowdrop/playground';
|
|
92
|
+
|
|
93
|
+
// 2.0 — authenticate playground requests by forwarding the provider
|
|
94
|
+
await playgroundService.listSessions(fd.api.config, workflowId, undefined, fd.api.authProvider);
|
|
95
|
+
await playgroundService.sendMessage(fd.api.config, sessionId, text, undefined, fd.api.authProvider);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The settings-sync entry points gained the same optional provider:
|
|
99
|
+
`setSettingsEndpointConfig(config, authProvider?)` and
|
|
100
|
+
`createSettingsService(config, authProvider?)` — pass an `AuthProvider` if your
|
|
101
|
+
backend's preferences endpoint requires auth.
|
|
102
|
+
|
|
103
|
+
The standalone playground mounts — `mountPlayground`, `mountPlaygroundStudio`,
|
|
104
|
+
and `mountPlaygroundApp` — accept an `authProvider` option that they wire into
|
|
105
|
+
`fd.api` for you (the editor's built-in playground already inherits the
|
|
106
|
+
provider from `mountFlowDropApp`). Pass it so playground requests (sessions,
|
|
107
|
+
messages, polling, interrupts) carry your auth/CSRF headers:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
mountPlayground(el, {
|
|
111
|
+
workflowId,
|
|
112
|
+
endpointConfig: createEndpointConfig('/api/flowdrop'),
|
|
113
|
+
authProvider: new CallbackAuthProvider({ getToken: () => session.getCsrfToken() })
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The same plumbing was extended to the editor and pipeline surfaces, which
|
|
118
|
+
previously built unauthenticated API clients from `endpointConfig` alone:
|
|
119
|
+
|
|
120
|
+
- The exported `<WorkflowEditor>` component accepts an `authProvider` prop
|
|
121
|
+
(threaded for you by `mountFlowDropApp` / `mountWorkflowEditor` / `<App>`).
|
|
122
|
+
Pass it when using `<WorkflowEditor>` directly.
|
|
123
|
+
- `<PipelineStatus>` accepts an `authProvider` prop (used when it builds its own
|
|
124
|
+
client from `endpointConfig` / `baseUrl`; ignored when you pass `apiClient`).
|
|
125
|
+
- `PipelineViewProps` — the contract for custom pipeline views registered via
|
|
126
|
+
`pipelineViews` — gained an optional `authProvider`, so custom views can build
|
|
127
|
+
authenticated clients the same way the built-in graph/kanban/table views do.
|
|
128
|
+
|
|
83
129
|
### `EndpointConfig.auth` is removed — use an `AuthProvider`
|
|
84
130
|
|
|
85
131
|
The `auth` block on `EndpointConfig` (and its header-injection branch) is gone.
|
|
@@ -108,6 +154,65 @@ mountFlowDropApp(el, {
|
|
|
108
154
|
| `{ type: 'api_key', apiKey }` | `new StaticAuthProvider({ type: 'api_key', apiKey })` |
|
|
109
155
|
| `{ type: 'custom', headers }` | `new StaticAuthProvider({ type: 'custom', headers })` |
|
|
110
156
|
|
|
157
|
+
`StaticAuthProvider`'s `api_key` type now accepts an optional `apiKeyHeader` to
|
|
158
|
+
override the header name (defaults to `X-API-Key`):
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
new StaticAuthProvider({ type: 'api_key', apiKey: KEY, apiKeyHeader: 'X-Tenant-Key' });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `AuthProvider.isAuthenticated()` is removed
|
|
165
|
+
|
|
166
|
+
The `isAuthenticated()` method has been dropped from the `AuthProvider`
|
|
167
|
+
interface and all built-in providers. It was never consulted by the library —
|
|
168
|
+
request authentication is driven entirely by `getAuthHeaders()` and the optional
|
|
169
|
+
`onUnauthorized()` / `onForbidden()` hooks. If you implemented a **custom**
|
|
170
|
+
`AuthProvider`, you can delete the method; no replacement is needed.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
// 1.x — required
|
|
174
|
+
const provider: AuthProvider = {
|
|
175
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` }),
|
|
176
|
+
isAuthenticated: () => Boolean(token) // ← remove this
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 2.0
|
|
180
|
+
const provider: AuthProvider = {
|
|
181
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` })
|
|
182
|
+
};
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Auth refresh (`401`) now applies to every request
|
|
186
|
+
|
|
187
|
+
Previously only the typed workflow/node API (`fd.api.client`) refreshed and
|
|
188
|
+
retried on `401`. The per-instance services (playground, chat, interrupt,
|
|
189
|
+
settings, port config, categories) and form autocomplete attached auth headers
|
|
190
|
+
but did **not** invoke `onUnauthorized()`. They now all route through one
|
|
191
|
+
authenticated-fetch path, so a configured `onUnauthorized()` fires — and the
|
|
192
|
+
request retries once with a refreshed token — uniformly across the library.
|
|
193
|
+
|
|
194
|
+
This is not a source change for consumers, but if your `onUnauthorized()` had
|
|
195
|
+
side effects (analytics, redirects) it may now be called from request paths
|
|
196
|
+
where it previously was not. Make it idempotent.
|
|
197
|
+
|
|
198
|
+
### Swap the auth provider at runtime — `fd.api.setAuthProvider()`
|
|
199
|
+
|
|
200
|
+
The `AuthProvider` is still supplied at mount time, but you no longer have to
|
|
201
|
+
remount to change it (e.g. on login/logout). `ApiContext` gained
|
|
202
|
+
`setAuthProvider()`, which updates the live client and is picked up by services
|
|
203
|
+
on their next request:
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
207
|
+
const fd = getInstance();
|
|
208
|
+
|
|
209
|
+
// after the user logs in / refreshes their session
|
|
210
|
+
fd.api.setAuthProvider(new StaticAuthProvider({ type: 'bearer', token: newToken }));
|
|
211
|
+
|
|
212
|
+
// on logout
|
|
213
|
+
fd.api.setAuthProvider(new NoAuthProvider());
|
|
214
|
+
```
|
|
215
|
+
|
|
111
216
|
### Instance-scoped port compatibility
|
|
112
217
|
|
|
113
218
|
`initializePortCompatibility()`, `getPortCompatibilityChecker()`, and
|
|
@@ -190,6 +295,19 @@ import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
|
190
295
|
registerCodeEditorField(getInstance().fields);
|
|
191
296
|
```
|
|
192
297
|
|
|
298
|
+
**You only need this for the standalone `@flowdrop/flowdrop/form` primitive.**
|
|
299
|
+
The full editor is batteries-included: `<WorkflowEditor>` / `<App>` and the
|
|
300
|
+
playground register the built-in markdown, code, and template editors on their
|
|
301
|
+
own instance's `fields` registry on mount, so node config fields with
|
|
302
|
+
`format: 'markdown' | 'code' | 'template'` render real editors out of the box —
|
|
303
|
+
no host call required. Registration is a dynamic `import()`, so the CodeMirror /
|
|
304
|
+
`marked` chunks stay code-split (the light `/editor` static bundle is
|
|
305
|
+
unaffected) and load lazily on first use. To strip them, pass
|
|
306
|
+
`features: { builtinEditors: false }` to `mountFlowDropApp` (or
|
|
307
|
+
`builtinEditors: false` to `mountWorkflowEditor` / `<WorkflowEditor>`) and either
|
|
308
|
+
accept the textarea fallback or register your own field components via
|
|
309
|
+
`instance.fields.register(...)`.
|
|
310
|
+
|
|
193
311
|
Category color/icon helpers likewise take a `CategoriesStore` as an explicit
|
|
194
312
|
parameter — the last global-instance fallback in `utils` is gone.
|
|
195
313
|
|
|
@@ -206,16 +324,16 @@ barrel no longer re-exports `marked`.
|
|
|
206
324
|
|
|
207
325
|
- **Playground exports** (`Playground`, `PlaygroundModal`, `ChatPanel`,
|
|
208
326
|
`SessionManager`, `InputCollector`, `ExecutionLogs`, `MessageBubble`,
|
|
209
|
-
`PlaygroundService`, `
|
|
327
|
+
`PlaygroundService`, `PlaygroundStore`) are removed from
|
|
210
328
|
`@flowdrop/flowdrop/editor`. Import them from `@flowdrop/flowdrop/playground`
|
|
211
329
|
instead.
|
|
212
330
|
|
|
213
331
|
```js
|
|
214
332
|
// 1.x
|
|
215
|
-
import { Playground,
|
|
333
|
+
import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/editor';
|
|
216
334
|
|
|
217
335
|
// 2.0
|
|
218
|
-
import { Playground,
|
|
336
|
+
import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/playground';
|
|
219
337
|
```
|
|
220
338
|
|
|
221
339
|
- **`marked`** is no longer re-exported from `@flowdrop/flowdrop/display`. If you
|
|
@@ -284,6 +402,58 @@ This also tightens tree-shaking: importing `App` and a couple of types from the
|
|
|
284
402
|
main entry no longer pulls the form, display, playground, and settings barrels
|
|
285
403
|
into your bundle.
|
|
286
404
|
|
|
405
|
+
### Keeping heavy dependencies out of the light entries
|
|
406
|
+
|
|
407
|
+
A few more exports moved so that the lightweight entries (`/core`, the light
|
|
408
|
+
`/form`) never statically pull a heavy dependency (CodeMirror, `marked`,
|
|
409
|
+
DOMPurify, `@xyflow/svelte`). These are enforced by a bundle guard in CI, so
|
|
410
|
+
they cannot silently regress.
|
|
411
|
+
|
|
412
|
+
- **`sanitizeHtml` moved from `@flowdrop/flowdrop/core` to
|
|
413
|
+
`@flowdrop/flowdrop/display`.** It is DOMPurify-backed, and `/core` is the
|
|
414
|
+
"zero heavy dependencies" entry, so it now lives alongside `MarkdownDisplay`.
|
|
415
|
+
|
|
416
|
+
```js
|
|
417
|
+
// before
|
|
418
|
+
import { sanitizeHtml } from '@flowdrop/flowdrop/core';
|
|
419
|
+
// 2.0
|
|
420
|
+
import { sanitizeHtml } from '@flowdrop/flowdrop/display';
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
- **`FormFieldFull` moved from `@flowdrop/flowdrop/form` to
|
|
424
|
+
`@flowdrop/flowdrop/form/full`.** `FormFieldFull` statically bundles every
|
|
425
|
+
editor (including CodeMirror); keeping it in the light `/form` entry pulled
|
|
426
|
+
CodeMirror into every `SchemaForm` import. The default `FormField` exported
|
|
427
|
+
from `/form` is the registry-based light field factory — register heavy
|
|
428
|
+
editors via `/form/code` / `/form/markdown` (unchanged). Use `/form/full`
|
|
429
|
+
only if you specifically want every editor statically bundled.
|
|
430
|
+
|
|
431
|
+
```js
|
|
432
|
+
// before
|
|
433
|
+
import { FormFieldFull } from '@flowdrop/flowdrop/form';
|
|
434
|
+
// 2.0
|
|
435
|
+
import { FormFieldFull } from '@flowdrop/flowdrop/form/full';
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
- **Service singleton _instances_ are no longer exported.**
|
|
439
|
+
`playgroundService` and `interruptService` (`@flowdrop/flowdrop/playground`),
|
|
440
|
+
`nodeExecutionService` (`@flowdrop/flowdrop/editor`), and
|
|
441
|
+
`agentSpecExecutionService` (`@flowdrop/flowdrop/core`) are removed. They were
|
|
442
|
+
module-level instances constructed at import time, which forced the service
|
|
443
|
+
(and its dependencies) to be built the moment the entry was imported. The
|
|
444
|
+
**classes** remain exported (`PlaygroundService`, `InterruptService`,
|
|
445
|
+
`NodeExecutionService`, `AgentSpecExecutionService`). Most apps never touched
|
|
446
|
+
these directly (use `fd.playground` / `fd.interrupts`); if you did, call
|
|
447
|
+
`getInstance()` to obtain the shared instance:
|
|
448
|
+
|
|
449
|
+
```js
|
|
450
|
+
// before
|
|
451
|
+
import { playgroundService } from '@flowdrop/flowdrop/playground';
|
|
452
|
+
// 2.0
|
|
453
|
+
import { PlaygroundService } from '@flowdrop/flowdrop/playground';
|
|
454
|
+
const playgroundService = PlaygroundService.getInstance();
|
|
455
|
+
```
|
|
456
|
+
|
|
287
457
|
## 5. Workflow `metadata` is required and `version` → `schemaVersion`
|
|
288
458
|
|
|
289
459
|
The workflow document's `metadata` object is now **required** on the `Workflow`
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module api/enhanced-client
|
|
7
7
|
*/
|
|
8
|
-
import { buildEndpointUrl, getEndpointMethod,
|
|
8
|
+
import { buildEndpointUrl, getEndpointMethod, getRequestHeaders } from '../config/endpoints.js';
|
|
9
9
|
import { NoAuthProvider } from '../types/auth.js';
|
|
10
10
|
import { getApiSettings } from '../stores/settingsStore.svelte.js';
|
|
11
11
|
import { logger } from '../utils/logger.js';
|
|
@@ -56,15 +56,12 @@ export class EnhancedFlowDropApiClient {
|
|
|
56
56
|
async request(endpointKey, endpointPath, params, options = {}, operation = 'API request') {
|
|
57
57
|
const url = buildEndpointUrl(this.config, endpointPath, params);
|
|
58
58
|
const method = options.method ?? getEndpointMethod(this.config, endpointKey);
|
|
59
|
-
const configHeaders = getEndpointHeaders(this.config, endpointKey);
|
|
60
59
|
// Get user settings for timeout and retry
|
|
61
60
|
const userApiSettings = getApiSettings();
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
// Merge headers: config headers < auth headers < request-specific headers
|
|
61
|
+
// Merge headers via the shared path: static endpoint headers < auth headers
|
|
62
|
+
// < request-specific headers.
|
|
65
63
|
const headers = {
|
|
66
|
-
...
|
|
67
|
-
...authHeaders,
|
|
64
|
+
...(await getRequestHeaders(this.config, endpointKey, this.authProvider)),
|
|
68
65
|
...options.headers
|
|
69
66
|
};
|
|
70
67
|
// Create AbortController for timeout
|
|
@@ -93,11 +90,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
93
90
|
if (this.authProvider.onUnauthorized) {
|
|
94
91
|
const refreshed = await this.authProvider.onUnauthorized();
|
|
95
92
|
if (refreshed && attempt < maxAttempts) {
|
|
96
|
-
//
|
|
97
|
-
const newAuthHeaders = await this.authProvider.getAuthHeaders();
|
|
93
|
+
// Rebuild headers via the shared path to pick up the fresh token.
|
|
98
94
|
fetchConfig.headers = {
|
|
99
|
-
...
|
|
100
|
-
...newAuthHeaders,
|
|
95
|
+
...(await getRequestHeaders(this.config, endpointKey, this.authProvider)),
|
|
101
96
|
...options.headers
|
|
102
97
|
};
|
|
103
98
|
continue; // Retry with new headers
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
import MainLayout from './layouts/MainLayout.svelte';
|
|
10
10
|
import WorkflowEditor from './WorkflowEditor.svelte';
|
|
11
11
|
import NodeSidebar from './NodeSidebar.svelte';
|
|
12
|
-
import
|
|
12
|
+
import CanvasIconButton from './CanvasIconButton.svelte';
|
|
13
|
+
import MenuIcon from './icons/MenuIcon.svelte';
|
|
14
|
+
import MenuOpenIcon from './icons/MenuOpenIcon.svelte';
|
|
13
15
|
import ConfigForm from './ConfigForm.svelte';
|
|
14
16
|
import ConfigPanel from './ConfigPanel.svelte';
|
|
15
17
|
import CommandConsole from './console/CommandConsole.svelte';
|
|
@@ -18,6 +20,7 @@
|
|
|
18
20
|
import NodeSwapPicker from './NodeSwapPicker.svelte';
|
|
19
21
|
import SwapMappingEditor from './SwapMappingEditor.svelte';
|
|
20
22
|
import Navbar from './Navbar.svelte';
|
|
23
|
+
import type { NavbarAction } from '../types/navbar.js';
|
|
21
24
|
import type { NodeMetadata, Workflow, WorkflowNode, ConfigSchema } from '../types/index.js';
|
|
22
25
|
import type { InteractiveSwapState, SwapEventContext } from '../utils/nodeSwap.js';
|
|
23
26
|
import {
|
|
@@ -98,13 +101,7 @@
|
|
|
98
101
|
/** Custom navbar title */
|
|
99
102
|
navbarTitle?: string;
|
|
100
103
|
/** Custom navbar actions */
|
|
101
|
-
navbarActions?:
|
|
102
|
-
label: string;
|
|
103
|
-
href: string;
|
|
104
|
-
icon?: string;
|
|
105
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
106
|
-
onclick?: (event: Event) => void;
|
|
107
|
-
}>;
|
|
104
|
+
navbarActions?: NavbarAction[];
|
|
108
105
|
/** Show settings gear icon in navbar */
|
|
109
106
|
showSettings?: boolean;
|
|
110
107
|
/** Show the "Connected" status indicator in the navbar (default: true) */
|
|
@@ -1278,27 +1275,34 @@
|
|
|
1278
1275
|
>
|
|
1279
1276
|
<!-- Floating sidebar toggle — always visible on the canvas top-left -->
|
|
1280
1277
|
{#if !disableSidebar}
|
|
1281
|
-
<
|
|
1278
|
+
<CanvasIconButton
|
|
1282
1279
|
class="flowdrop-sidebar-fab"
|
|
1283
|
-
|
|
1284
|
-
aria-label={isSidebarCollapsed
|
|
1285
|
-
? mergedMessages.layout.expandSidebar
|
|
1286
|
-
: mergedMessages.layout.collapseSidebar}
|
|
1287
|
-
title={isSidebarCollapsed
|
|
1280
|
+
label={isSidebarCollapsed
|
|
1288
1281
|
? mergedMessages.layout.expandSidebar
|
|
1289
1282
|
: mergedMessages.layout.collapseSidebar}
|
|
1283
|
+
active={!isSidebarCollapsed}
|
|
1284
|
+
onclick={toggleSidebar}
|
|
1290
1285
|
>
|
|
1291
|
-
|
|
1292
|
-
|
|
1286
|
+
{#snippet icon()}
|
|
1287
|
+
{#if isSidebarCollapsed}
|
|
1288
|
+
<MenuIcon />
|
|
1289
|
+
{:else}
|
|
1290
|
+
<MenuOpenIcon />
|
|
1291
|
+
{/if}
|
|
1292
|
+
{/snippet}
|
|
1293
|
+
</CanvasIconButton>
|
|
1293
1294
|
{/if}
|
|
1294
1295
|
|
|
1295
1296
|
<WorkflowEditor
|
|
1296
1297
|
bind:this={workflowEditorRef}
|
|
1297
1298
|
endpointConfig={endpointConfig ?? undefined}
|
|
1299
|
+
{authProvider}
|
|
1298
1300
|
{openConfigSidebar}
|
|
1299
1301
|
{mode}
|
|
1300
1302
|
{pipelineId}
|
|
1301
1303
|
{refreshTrigger}
|
|
1304
|
+
builtinEditors={features.builtinEditors}
|
|
1305
|
+
gridVariant={themeConfig?.canvas?.grid ?? 'dots'}
|
|
1302
1306
|
consoleOpen={getUiSettings().consoleOpen}
|
|
1303
1307
|
onToggleConsole={toggleConsole}
|
|
1304
1308
|
/>
|
|
@@ -1411,38 +1415,11 @@
|
|
|
1411
1415
|
font-weight: 500;
|
|
1412
1416
|
}
|
|
1413
1417
|
|
|
1414
|
-
/* Floating sidebar toggle button */
|
|
1415
|
-
.flowdrop-sidebar-fab {
|
|
1416
|
-
position: absolute;
|
|
1418
|
+
/* Floating sidebar toggle button — placement only; visuals live in CanvasIconButton */
|
|
1419
|
+
:global(.flowdrop-sidebar-fab) {
|
|
1417
1420
|
top: 12px;
|
|
1418
1421
|
left: 12px;
|
|
1419
1422
|
z-index: 50;
|
|
1420
|
-
display: flex;
|
|
1421
|
-
align-items: center;
|
|
1422
|
-
justify-content: center;
|
|
1423
|
-
width: 2.25rem;
|
|
1424
|
-
height: 2.25rem;
|
|
1425
|
-
border: 1px solid var(--fd-border);
|
|
1426
|
-
border-radius: var(--fd-radius-md);
|
|
1427
|
-
background-color: var(--fd-background);
|
|
1428
|
-
color: var(--fd-muted-foreground);
|
|
1429
|
-
cursor: pointer;
|
|
1430
|
-
box-shadow: var(--fd-shadow-md);
|
|
1431
|
-
transition:
|
|
1432
|
-
color var(--fd-transition-fast),
|
|
1433
|
-
background-color var(--fd-transition-fast),
|
|
1434
|
-
box-shadow var(--fd-transition-fast);
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
.flowdrop-sidebar-fab:hover {
|
|
1438
|
-
color: var(--fd-foreground);
|
|
1439
|
-
background-color: var(--fd-subtle);
|
|
1440
|
-
box-shadow: var(--fd-shadow-lg);
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
.flowdrop-sidebar-fab:focus {
|
|
1444
|
-
outline: none;
|
|
1445
|
-
box-shadow: 0 0 0 2px var(--fd-ring);
|
|
1446
1423
|
}
|
|
1447
1424
|
|
|
1448
1425
|
/* Main editor area */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NavbarAction } from '../types/navbar.js';
|
|
1
2
|
import type { NodeMetadata, Workflow, ConfigSchema } from '../types/index.js';
|
|
2
3
|
import type { SwapStrategy } from '../utils/nodeSwap.js';
|
|
3
4
|
import type { EndpointConfig } from '../config/endpoints.js';
|
|
@@ -53,13 +54,7 @@ interface Props {
|
|
|
53
54
|
/** Custom navbar title */
|
|
54
55
|
navbarTitle?: string;
|
|
55
56
|
/** Custom navbar actions */
|
|
56
|
-
navbarActions?:
|
|
57
|
-
label: string;
|
|
58
|
-
href: string;
|
|
59
|
-
icon?: string;
|
|
60
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
61
|
-
onclick?: (event: Event) => void;
|
|
62
|
-
}>;
|
|
57
|
+
navbarActions?: NavbarAction[];
|
|
63
58
|
/** Show settings gear icon in navbar */
|
|
64
59
|
showSettings?: boolean;
|
|
65
60
|
/** Show the "Connected" status indicator in the navbar (default: true) */
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
/**
|
|
6
|
+
* The icon to render — an inline-SVG snippet (offline-safe). Pass a local
|
|
7
|
+
* icon component from `$lib/components/icons/`, not a network-fetched one.
|
|
8
|
+
*/
|
|
9
|
+
icon: Snippet;
|
|
10
|
+
/** Accessible label — drives both aria-label and the hover title. */
|
|
11
|
+
label: string;
|
|
12
|
+
/** Renders the active/toggled-on visual state (e.g. the panel it controls is open). */
|
|
13
|
+
active?: boolean;
|
|
14
|
+
onclick: () => void;
|
|
15
|
+
/** Caller-supplied class for positioning (top/left/bottom/z-index). */
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { icon, label, active = false, onclick, class: klass = '' }: Props = $props();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<button
|
|
23
|
+
class="flowdrop-canvas-btn {klass}"
|
|
24
|
+
class:flowdrop-canvas-btn--active={active}
|
|
25
|
+
{onclick}
|
|
26
|
+
aria-label={label}
|
|
27
|
+
title={label}
|
|
28
|
+
type="button"
|
|
29
|
+
>
|
|
30
|
+
{@render icon()}
|
|
31
|
+
</button>
|
|
32
|
+
|
|
33
|
+
<style>
|
|
34
|
+
.flowdrop-canvas-btn {
|
|
35
|
+
position: absolute;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
width: 2.25rem;
|
|
40
|
+
height: 2.25rem;
|
|
41
|
+
border: 1px solid var(--fd-border);
|
|
42
|
+
border-radius: var(--fd-radius-md);
|
|
43
|
+
background-color: var(--fd-background);
|
|
44
|
+
color: var(--fd-muted-foreground);
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
box-shadow: var(--fd-shadow-md);
|
|
47
|
+
transition:
|
|
48
|
+
color var(--fd-transition-fast),
|
|
49
|
+
background-color var(--fd-transition-fast),
|
|
50
|
+
box-shadow var(--fd-transition-fast),
|
|
51
|
+
border-color var(--fd-transition-fast);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Size whatever inline SVG the caller renders. */
|
|
55
|
+
.flowdrop-canvas-btn :global(svg) {
|
|
56
|
+
width: 18px;
|
|
57
|
+
height: 18px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.flowdrop-canvas-btn:hover {
|
|
61
|
+
color: var(--fd-foreground);
|
|
62
|
+
background-color: var(--fd-subtle);
|
|
63
|
+
box-shadow: var(--fd-shadow-lg);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.flowdrop-canvas-btn--active {
|
|
67
|
+
color: var(--fd-primary);
|
|
68
|
+
background-color: var(--fd-primary-muted);
|
|
69
|
+
border-color: var(--fd-primary);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.flowdrop-canvas-btn--active:hover {
|
|
73
|
+
color: var(--fd-primary);
|
|
74
|
+
background-color: var(--fd-primary-muted);
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/**
|
|
4
|
+
* The icon to render — an inline-SVG snippet (offline-safe). Pass a local
|
|
5
|
+
* icon component from `$lib/components/icons/`, not a network-fetched one.
|
|
6
|
+
*/
|
|
7
|
+
icon: Snippet;
|
|
8
|
+
/** Accessible label — drives both aria-label and the hover title. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Renders the active/toggled-on visual state (e.g. the panel it controls is open). */
|
|
11
|
+
active?: boolean;
|
|
12
|
+
onclick: () => void;
|
|
13
|
+
/** Caller-supplied class for positioning (top/left/bottom/z-index). */
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
declare const CanvasIconButton: import("svelte").Component<Props, {}, "">;
|
|
17
|
+
type CanvasIconButton = ReturnType<typeof CanvasIconButton>;
|
|
18
|
+
export default CanvasIconButton;
|
|
@@ -32,9 +32,13 @@
|
|
|
32
32
|
} from '../types/index.js';
|
|
33
33
|
import { dynamicPortToNodePort } from '../types/index.js';
|
|
34
34
|
import type { UISchemaElement } from '../types/uischema.js';
|
|
35
|
-
|
|
35
|
+
// Import the light, registry-based field factory and light fields directly
|
|
36
|
+
// (not via the form barrel, which aggregates the heavy CodeMirror editors).
|
|
37
|
+
import FormField from './form/FormFieldLight.svelte';
|
|
38
|
+
import FormFieldWrapper from './form/FormFieldWrapper.svelte';
|
|
39
|
+
import FormToggle from './form/FormToggle.svelte';
|
|
36
40
|
import FormUISchemaRenderer from './form/FormUISchemaRenderer.svelte';
|
|
37
|
-
import type { FieldSchema } from './form/
|
|
41
|
+
import type { FieldSchema } from './form/types.js';
|
|
38
42
|
import {
|
|
39
43
|
getEffectiveConfigEditOptions,
|
|
40
44
|
fetchDynamicSchema,
|
|
@@ -1069,11 +1073,6 @@
|
|
|
1069
1073
|
color: var(--fd-foreground);
|
|
1070
1074
|
}
|
|
1071
1075
|
|
|
1072
|
-
.config-form__button--secondary:focus-visible {
|
|
1073
|
-
outline: none;
|
|
1074
|
-
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
1076
|
.config-form__button--primary {
|
|
1078
1077
|
background: linear-gradient(135deg, var(--fd-primary) 0%, var(--fd-primary-hover) 100%);
|
|
1079
1078
|
color: var(--fd-primary-foreground);
|
|
@@ -1094,13 +1093,6 @@
|
|
|
1094
1093
|
transform: translateY(0);
|
|
1095
1094
|
}
|
|
1096
1095
|
|
|
1097
|
-
.config-form__button--primary:focus-visible {
|
|
1098
|
-
outline: none;
|
|
1099
|
-
box-shadow:
|
|
1100
|
-
0 0 0 3px rgba(59, 130, 246, 0.4),
|
|
1101
|
-
0 4px 12px rgba(59, 130, 246, 0.35);
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
1096
|
/* ============================================
|
|
1105
1097
|
UI EXTENSIONS SECTION
|
|
1106
1098
|
============================================ */
|
|
@@ -1555,11 +1547,4 @@
|
|
|
1555
1547
|
.config-form__button--external:active {
|
|
1556
1548
|
transform: translateY(0);
|
|
1557
1549
|
}
|
|
1558
|
-
|
|
1559
|
-
.config-form__button--external:focus-visible {
|
|
1560
|
-
outline: none;
|
|
1561
|
-
box-shadow:
|
|
1562
|
-
0 0 0 3px rgba(99, 102, 241, 0.4),
|
|
1563
|
-
0 4px 12px rgba(99, 102, 241, 0.35);
|
|
1564
|
-
}
|
|
1565
1550
|
</style>
|
|
@@ -110,7 +110,8 @@
|
|
|
110
110
|
height: 100%;
|
|
111
111
|
display: flex;
|
|
112
112
|
flex-direction: column;
|
|
113
|
-
background-color: var(--fd-
|
|
113
|
+
background-color: var(--fd-panel-bg);
|
|
114
|
+
backdrop-filter: var(--fd-panel-backdrop-filter);
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
.config-panel__header {
|
|
@@ -119,7 +120,7 @@
|
|
|
119
120
|
align-items: center;
|
|
120
121
|
padding: 0.875rem 1rem;
|
|
121
122
|
border-bottom: 1px solid var(--fd-border);
|
|
122
|
-
background-color: var(--fd-
|
|
123
|
+
background-color: var(--fd-card);
|
|
123
124
|
flex-shrink: 0;
|
|
124
125
|
}
|
|
125
126
|
|
|
@@ -180,7 +181,7 @@
|
|
|
180
181
|
.config-panel__details {
|
|
181
182
|
padding: 0.75rem 1rem;
|
|
182
183
|
border-bottom: 1px solid var(--fd-border-muted);
|
|
183
|
-
background-color: var(--fd-
|
|
184
|
+
background-color: var(--fd-card);
|
|
184
185
|
flex-shrink: 0;
|
|
185
186
|
}
|
|
186
187
|
|