@d34dman/flowdrop 0.0.21 → 0.0.22
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/dist/components/App.svelte +48 -240
- package/dist/components/ConfigForm.svelte +707 -238
- package/dist/components/ConfigForm.svelte.d.ts +9 -2
- package/dist/components/ConfigPanel.svelte +160 -0
- package/dist/components/ConfigPanel.svelte.d.ts +32 -0
- package/dist/components/ReadOnlyDetails.svelte +168 -0
- package/dist/components/ReadOnlyDetails.svelte.d.ts +25 -0
- package/dist/components/WorkflowEditor.svelte +1 -1
- package/dist/components/nodes/NotesNode.svelte +89 -307
- package/dist/components/nodes/NotesNode.svelte.d.ts +3 -22
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +1 -1
- package/dist/components/ConfigSidebar.svelte +0 -916
- package/dist/components/ConfigSidebar.svelte.d.ts +0 -51
|
@@ -1,29 +1,46 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
ConfigForm Component
|
|
3
|
-
Handles dynamic form rendering for node configuration
|
|
3
|
+
Handles dynamic form rendering for node or entity configuration
|
|
4
|
+
Supports both node-based config and direct schema/values
|
|
4
5
|
Uses reactive $state for proper Svelte 5 reactivity
|
|
6
|
+
|
|
7
|
+
Accessibility features:
|
|
8
|
+
- Proper label associations with for/id attributes
|
|
9
|
+
- ARIA describedby for field descriptions
|
|
10
|
+
- Focus-visible states for keyboard navigation
|
|
11
|
+
- Required field indicators
|
|
5
12
|
-->
|
|
6
13
|
|
|
7
14
|
<script lang="ts">
|
|
15
|
+
import Icon from '@iconify/svelte';
|
|
8
16
|
import type { ConfigSchema, WorkflowNode } from '../types/index.js';
|
|
9
17
|
|
|
10
18
|
interface Props {
|
|
11
|
-
node
|
|
19
|
+
/** Optional workflow node (if provided, schema and values are derived from it) */
|
|
20
|
+
node?: WorkflowNode;
|
|
21
|
+
/** Direct config schema (used when node is not provided) */
|
|
22
|
+
schema?: ConfigSchema;
|
|
23
|
+
/** Direct config values (used when node is not provided) */
|
|
24
|
+
values?: Record<string, unknown>;
|
|
25
|
+
/** Callback when form is saved */
|
|
12
26
|
onSave: (config: Record<string, unknown>) => void;
|
|
27
|
+
/** Callback when form is cancelled */
|
|
13
28
|
onCancel: () => void;
|
|
14
29
|
}
|
|
15
30
|
|
|
16
|
-
let { node, onSave, onCancel }: Props = $props();
|
|
31
|
+
let { node, schema, values, onSave, onCancel }: Props = $props();
|
|
17
32
|
|
|
18
33
|
/**
|
|
19
|
-
* Get the configuration schema from node metadata
|
|
34
|
+
* Get the configuration schema from node metadata or direct prop
|
|
20
35
|
*/
|
|
21
|
-
const configSchema = $derived(
|
|
36
|
+
const configSchema = $derived(
|
|
37
|
+
schema ?? (node?.data.metadata?.configSchema as ConfigSchema | undefined)
|
|
38
|
+
);
|
|
22
39
|
|
|
23
40
|
/**
|
|
24
|
-
* Get the current node
|
|
41
|
+
* Get the current configuration from node or direct prop
|
|
25
42
|
*/
|
|
26
|
-
const
|
|
43
|
+
const initialConfig = $derived(values ?? node?.data.config ?? {});
|
|
27
44
|
|
|
28
45
|
/**
|
|
29
46
|
* Create reactive configuration values using $state
|
|
@@ -32,59 +49,71 @@
|
|
|
32
49
|
let configValues = $state<Record<string, unknown>>({});
|
|
33
50
|
|
|
34
51
|
/**
|
|
35
|
-
* Initialize config values when node
|
|
52
|
+
* Initialize config values when node/schema changes
|
|
36
53
|
*/
|
|
37
54
|
$effect(() => {
|
|
38
55
|
if (configSchema?.properties) {
|
|
39
56
|
const mergedConfig: Record<string, unknown> = {};
|
|
40
57
|
Object.entries(configSchema.properties).forEach(([key, field]) => {
|
|
41
|
-
const fieldConfig = field as
|
|
58
|
+
const fieldConfig = field as Record<string, unknown>;
|
|
42
59
|
// Use existing value if available, otherwise use default
|
|
43
|
-
mergedConfig[key] =
|
|
60
|
+
mergedConfig[key] =
|
|
61
|
+
initialConfig[key] !== undefined ? initialConfig[key] : fieldConfig.default;
|
|
44
62
|
});
|
|
45
63
|
configValues = mergedConfig;
|
|
46
64
|
}
|
|
47
65
|
});
|
|
48
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Check if a field is required based on schema
|
|
69
|
+
*/
|
|
70
|
+
function isFieldRequired(key: string): boolean {
|
|
71
|
+
if (!configSchema?.required) return false;
|
|
72
|
+
return configSchema.required.includes(key);
|
|
73
|
+
}
|
|
74
|
+
|
|
49
75
|
/**
|
|
50
76
|
* Handle form submission
|
|
51
77
|
*/
|
|
52
78
|
function handleSave(): void {
|
|
53
79
|
// Collect all form values including hidden fields
|
|
54
|
-
const form = document.querySelector('.
|
|
80
|
+
const form = document.querySelector('.config-form');
|
|
55
81
|
const updatedConfig: Record<string, unknown> = { ...configValues };
|
|
56
82
|
|
|
57
83
|
if (form) {
|
|
58
84
|
const inputs = form.querySelectorAll('input, select, textarea');
|
|
59
|
-
inputs.forEach((input:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
inputs.forEach((input: Element) => {
|
|
86
|
+
const inputEl = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
|
87
|
+
if (inputEl.id) {
|
|
88
|
+
if (inputEl instanceof HTMLInputElement && inputEl.type === 'checkbox') {
|
|
89
|
+
updatedConfig[inputEl.id] = inputEl.checked;
|
|
90
|
+
} else if (inputEl instanceof HTMLInputElement && inputEl.type === 'number') {
|
|
91
|
+
updatedConfig[inputEl.id] = inputEl.value ? Number(inputEl.value) : inputEl.value;
|
|
92
|
+
} else if (inputEl instanceof HTMLInputElement && inputEl.type === 'hidden') {
|
|
66
93
|
// Parse hidden field values that might be JSON
|
|
67
94
|
try {
|
|
68
|
-
const parsed = JSON.parse(
|
|
69
|
-
updatedConfig[
|
|
95
|
+
const parsed = JSON.parse(inputEl.value);
|
|
96
|
+
updatedConfig[inputEl.id] = parsed;
|
|
70
97
|
} catch {
|
|
71
98
|
// If not JSON, use raw value
|
|
72
|
-
updatedConfig[
|
|
99
|
+
updatedConfig[inputEl.id] = inputEl.value;
|
|
73
100
|
}
|
|
74
101
|
} else {
|
|
75
|
-
updatedConfig[
|
|
102
|
+
updatedConfig[inputEl.id] = inputEl.value;
|
|
76
103
|
}
|
|
77
104
|
}
|
|
78
105
|
});
|
|
79
106
|
}
|
|
80
107
|
|
|
81
108
|
// Preserve hidden field values from original config if not collected from form
|
|
82
|
-
if (
|
|
83
|
-
Object.entries(configSchema.properties).forEach(
|
|
84
|
-
|
|
85
|
-
updatedConfig
|
|
109
|
+
if (initialConfig && configSchema?.properties) {
|
|
110
|
+
Object.entries(configSchema.properties).forEach(
|
|
111
|
+
([key, property]: [string, Record<string, unknown>]) => {
|
|
112
|
+
if (property.format === 'hidden' && !(key in updatedConfig) && key in initialConfig) {
|
|
113
|
+
updatedConfig[key] = initialConfig[key];
|
|
114
|
+
}
|
|
86
115
|
}
|
|
87
|
-
|
|
116
|
+
);
|
|
88
117
|
}
|
|
89
118
|
|
|
90
119
|
onSave(updatedConfig);
|
|
@@ -92,301 +121,741 @@
|
|
|
92
121
|
</script>
|
|
93
122
|
|
|
94
123
|
{#if configSchema}
|
|
95
|
-
<
|
|
124
|
+
<form
|
|
125
|
+
class="config-form"
|
|
126
|
+
onsubmit={(e) => {
|
|
127
|
+
e.preventDefault();
|
|
128
|
+
handleSave();
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
96
131
|
{#if configSchema.properties}
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
<div class="config-form__fields">
|
|
133
|
+
{#each Object.entries(configSchema.properties) as [key, field], index (key)}
|
|
134
|
+
{@const fieldConfig = field as Record<string, unknown>}
|
|
135
|
+
{@const required = isFieldRequired(key)}
|
|
136
|
+
{@const hasDescription = Boolean(fieldConfig.description)}
|
|
137
|
+
{@const descriptionId = hasDescription ? `${key}-description` : undefined}
|
|
138
|
+
|
|
139
|
+
{#if fieldConfig.format !== 'hidden'}
|
|
140
|
+
<div class="config-form__field" style="animation-delay: {index * 30}ms">
|
|
141
|
+
<!-- Field Label -->
|
|
142
|
+
<label class="config-form__label" for={key}>
|
|
143
|
+
<span class="config-form__label-text">
|
|
144
|
+
{String(fieldConfig.title || fieldConfig.description || key)}
|
|
145
|
+
</span>
|
|
146
|
+
{#if required}
|
|
147
|
+
<span class="config-form__required" aria-label="required">*</span>
|
|
148
|
+
{/if}
|
|
149
|
+
</label>
|
|
150
|
+
|
|
151
|
+
<!-- Field Input Container -->
|
|
152
|
+
<div class="config-form__input-wrapper">
|
|
153
|
+
{#if fieldConfig.enum && fieldConfig.multiple}
|
|
154
|
+
<!-- Checkboxes for enum with multiple selection -->
|
|
155
|
+
{@const enumOptions = fieldConfig.enum as string[]}
|
|
156
|
+
<div
|
|
157
|
+
class="config-form__checkbox-group"
|
|
158
|
+
role="group"
|
|
159
|
+
aria-labelledby="{key}-label"
|
|
160
|
+
aria-describedby={descriptionId}
|
|
161
|
+
>
|
|
162
|
+
{#each enumOptions as option (String(option))}
|
|
163
|
+
{@const currentValue = configValues[key]}
|
|
164
|
+
{@const valueArray = Array.isArray(currentValue) ? currentValue : []}
|
|
165
|
+
<label class="config-form__checkbox-item">
|
|
166
|
+
<input
|
|
167
|
+
type="checkbox"
|
|
168
|
+
class="config-form__checkbox-input"
|
|
169
|
+
value={String(option)}
|
|
170
|
+
checked={valueArray.includes(String(option))}
|
|
171
|
+
onchange={(e) => {
|
|
172
|
+
const checked = e.currentTarget.checked;
|
|
173
|
+
const existingValue = configValues[key];
|
|
174
|
+
const currentValues: unknown[] = Array.isArray(existingValue)
|
|
175
|
+
? [...existingValue]
|
|
176
|
+
: [];
|
|
177
|
+
if (checked) {
|
|
178
|
+
if (!currentValues.includes(String(option))) {
|
|
179
|
+
configValues[key] = [...currentValues, String(option)];
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
configValues[key] = currentValues.filter((v) => v !== String(option));
|
|
183
|
+
}
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
<span class="config-form__checkbox-custom" aria-hidden="true">
|
|
187
|
+
<Icon icon="heroicons:check" />
|
|
188
|
+
</span>
|
|
189
|
+
<span class="config-form__checkbox-label">
|
|
190
|
+
{String(option)}
|
|
191
|
+
</span>
|
|
192
|
+
</label>
|
|
193
|
+
{/each}
|
|
194
|
+
</div>
|
|
195
|
+
{:else if fieldConfig.enum}
|
|
196
|
+
<!-- Select for enum with single selection -->
|
|
197
|
+
{@const enumOptions = fieldConfig.enum as string[]}
|
|
198
|
+
<div class="config-form__select-wrapper">
|
|
199
|
+
<select
|
|
200
|
+
id={key}
|
|
201
|
+
class="config-form__select"
|
|
202
|
+
bind:value={configValues[key]}
|
|
203
|
+
aria-describedby={descriptionId}
|
|
204
|
+
aria-required={required}
|
|
205
|
+
>
|
|
206
|
+
{#each enumOptions as option (String(option))}
|
|
207
|
+
<option value={String(option)}>{String(option)}</option>
|
|
208
|
+
{/each}
|
|
209
|
+
</select>
|
|
210
|
+
<span class="config-form__select-icon" aria-hidden="true">
|
|
211
|
+
<Icon icon="heroicons:chevron-down" />
|
|
212
|
+
</span>
|
|
213
|
+
</div>
|
|
214
|
+
{:else if fieldConfig.type === 'string' && fieldConfig.format === 'multiline'}
|
|
215
|
+
<!-- Textarea for multiline strings -->
|
|
216
|
+
<textarea
|
|
217
|
+
id={key}
|
|
218
|
+
class="config-form__textarea"
|
|
219
|
+
bind:value={configValues[key]}
|
|
220
|
+
placeholder={String(fieldConfig.placeholder || '')}
|
|
221
|
+
rows="4"
|
|
222
|
+
aria-describedby={descriptionId}
|
|
223
|
+
aria-required={required}
|
|
224
|
+
></textarea>
|
|
225
|
+
{:else if fieldConfig.type === 'string'}
|
|
226
|
+
<input
|
|
227
|
+
id={key}
|
|
228
|
+
type="text"
|
|
229
|
+
class="config-form__input"
|
|
230
|
+
bind:value={configValues[key]}
|
|
231
|
+
placeholder={String(fieldConfig.placeholder || '')}
|
|
232
|
+
aria-describedby={descriptionId}
|
|
233
|
+
aria-required={required}
|
|
234
|
+
/>
|
|
235
|
+
{:else if fieldConfig.type === 'number'}
|
|
236
|
+
<input
|
|
237
|
+
id={key}
|
|
238
|
+
type="number"
|
|
239
|
+
class="config-form__input config-form__input--number"
|
|
240
|
+
bind:value={configValues[key]}
|
|
241
|
+
placeholder={String(fieldConfig.placeholder || '')}
|
|
242
|
+
aria-describedby={descriptionId}
|
|
243
|
+
aria-required={required}
|
|
244
|
+
/>
|
|
245
|
+
{:else if fieldConfig.type === 'boolean'}
|
|
246
|
+
<!-- Toggle Switch for boolean -->
|
|
247
|
+
<label class="config-form__toggle">
|
|
109
248
|
<input
|
|
249
|
+
id={key}
|
|
110
250
|
type="checkbox"
|
|
111
|
-
class="
|
|
112
|
-
|
|
113
|
-
checked={Array.isArray(configValues[key]) &&
|
|
114
|
-
configValues[key].includes(String(option))}
|
|
251
|
+
class="config-form__toggle-input"
|
|
252
|
+
checked={Boolean(configValues[key] || fieldConfig.default || false)}
|
|
115
253
|
onchange={(e) => {
|
|
116
|
-
|
|
117
|
-
const currentValues = Array.isArray(configValues[key])
|
|
118
|
-
? [...(configValues[key] as unknown[])]
|
|
119
|
-
: [];
|
|
120
|
-
if (checked) {
|
|
121
|
-
if (!currentValues.includes(String(option))) {
|
|
122
|
-
configValues[key] = [...currentValues, String(option)];
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
configValues[key] = currentValues.filter((v) => v !== String(option));
|
|
126
|
-
}
|
|
254
|
+
configValues[key] = e.currentTarget.checked;
|
|
127
255
|
}}
|
|
256
|
+
aria-describedby={descriptionId}
|
|
128
257
|
/>
|
|
129
|
-
<span class="
|
|
130
|
-
|
|
258
|
+
<span class="config-form__toggle-track">
|
|
259
|
+
<span class="config-form__toggle-thumb"></span>
|
|
260
|
+
</span>
|
|
261
|
+
<span class="config-form__toggle-label">
|
|
262
|
+
{configValues[key] ? 'Enabled' : 'Disabled'}
|
|
131
263
|
</span>
|
|
132
264
|
</label>
|
|
133
|
-
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
<input
|
|
165
|
-
id={key}
|
|
166
|
-
type="number"
|
|
167
|
-
class="flowdrop-config-sidebar__input"
|
|
168
|
-
bind:value={configValues[key]}
|
|
169
|
-
placeholder={String(fieldConfig.placeholder || '')}
|
|
170
|
-
/>
|
|
171
|
-
{:else if fieldConfig.type === 'boolean'}
|
|
172
|
-
<input
|
|
173
|
-
id={key}
|
|
174
|
-
type="checkbox"
|
|
175
|
-
class="flowdrop-config-sidebar__checkbox"
|
|
176
|
-
checked={Boolean(configValues[key] || fieldConfig.default || false)}
|
|
177
|
-
onchange={(e) => {
|
|
178
|
-
configValues[key] = e.currentTarget.checked;
|
|
179
|
-
}}
|
|
180
|
-
/>
|
|
181
|
-
{:else if fieldConfig.type === 'select' || fieldConfig.options}
|
|
182
|
-
<select
|
|
183
|
-
id={key}
|
|
184
|
-
class="flowdrop-config-sidebar__select"
|
|
185
|
-
bind:value={configValues[key]}
|
|
186
|
-
>
|
|
187
|
-
{#if fieldConfig.options}
|
|
188
|
-
{#each fieldConfig.options as option (String(option.value))}
|
|
189
|
-
{@const optionConfig = option as any}
|
|
190
|
-
<option value={String(optionConfig.value)}>{String(optionConfig.label)}</option>
|
|
191
|
-
{/each}
|
|
265
|
+
{:else if fieldConfig.type === 'select' || fieldConfig.options}
|
|
266
|
+
{@const selectOptions = (fieldConfig.options ?? []) as Array<{
|
|
267
|
+
value: unknown;
|
|
268
|
+
label: unknown;
|
|
269
|
+
}>}
|
|
270
|
+
<div class="config-form__select-wrapper">
|
|
271
|
+
<select
|
|
272
|
+
id={key}
|
|
273
|
+
class="config-form__select"
|
|
274
|
+
bind:value={configValues[key]}
|
|
275
|
+
aria-describedby={descriptionId}
|
|
276
|
+
aria-required={required}
|
|
277
|
+
>
|
|
278
|
+
{#each selectOptions as option (String(option.value))}
|
|
279
|
+
<option value={String(option.value)}>{String(option.label)}</option>
|
|
280
|
+
{/each}
|
|
281
|
+
</select>
|
|
282
|
+
<span class="config-form__select-icon" aria-hidden="true">
|
|
283
|
+
<Icon icon="heroicons:chevron-down" />
|
|
284
|
+
</span>
|
|
285
|
+
</div>
|
|
286
|
+
{:else}
|
|
287
|
+
<!-- Fallback for unknown field types -->
|
|
288
|
+
<input
|
|
289
|
+
id={key}
|
|
290
|
+
type="text"
|
|
291
|
+
class="config-form__input"
|
|
292
|
+
bind:value={configValues[key]}
|
|
293
|
+
placeholder={String(fieldConfig.placeholder || '')}
|
|
294
|
+
aria-describedby={descriptionId}
|
|
295
|
+
/>
|
|
192
296
|
{/if}
|
|
193
|
-
</
|
|
194
|
-
|
|
195
|
-
<!--
|
|
196
|
-
|
|
197
|
-
id={
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<p class="flowdrop-config-sidebar__field-description">
|
|
206
|
-
{String(fieldConfig.description)}
|
|
207
|
-
</p>
|
|
208
|
-
{/if}
|
|
209
|
-
</div>
|
|
210
|
-
{/if}
|
|
211
|
-
{/each}
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<!-- Field Description -->
|
|
300
|
+
{#if hasDescription && fieldConfig.title}
|
|
301
|
+
<p id={descriptionId} class="config-form__description">
|
|
302
|
+
{String(fieldConfig.description)}
|
|
303
|
+
</p>
|
|
304
|
+
{/if}
|
|
305
|
+
</div>
|
|
306
|
+
{/if}
|
|
307
|
+
{/each}
|
|
308
|
+
</div>
|
|
212
309
|
{:else}
|
|
213
310
|
<!-- If no properties, show the raw schema for debugging -->
|
|
214
|
-
<div class="
|
|
215
|
-
<
|
|
216
|
-
|
|
311
|
+
<div class="config-form__debug">
|
|
312
|
+
<div class="config-form__debug-header">
|
|
313
|
+
<Icon icon="heroicons:bug-ant" class="config-form__debug-icon" />
|
|
314
|
+
<span>Debug - Config Schema</span>
|
|
315
|
+
</div>
|
|
316
|
+
<pre class="config-form__debug-content">{JSON.stringify(configSchema, null, 2)}</pre>
|
|
217
317
|
</div>
|
|
218
318
|
{/if}
|
|
219
|
-
</div>
|
|
220
319
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
320
|
+
<!-- Footer Actions -->
|
|
321
|
+
<div class="config-form__footer">
|
|
322
|
+
<button
|
|
323
|
+
type="button"
|
|
324
|
+
class="config-form__button config-form__button--secondary"
|
|
325
|
+
onclick={onCancel}
|
|
326
|
+
>
|
|
327
|
+
<Icon icon="heroicons:x-mark" class="config-form__button-icon" />
|
|
328
|
+
<span>Cancel</span>
|
|
329
|
+
</button>
|
|
330
|
+
<button type="submit" class="config-form__button config-form__button--primary">
|
|
331
|
+
<Icon icon="heroicons:check" class="config-form__button-icon" />
|
|
332
|
+
<span>Save Changes</span>
|
|
333
|
+
</button>
|
|
334
|
+
</div>
|
|
335
|
+
</form>
|
|
236
336
|
{:else}
|
|
237
|
-
<
|
|
238
|
-
|
|
239
|
-
|
|
337
|
+
<div class="config-form__empty">
|
|
338
|
+
<div class="config-form__empty-icon">
|
|
339
|
+
<Icon icon="heroicons:cog-6-tooth" />
|
|
340
|
+
</div>
|
|
341
|
+
<p class="config-form__empty-text">No configuration options available for this node.</p>
|
|
342
|
+
</div>
|
|
240
343
|
{/if}
|
|
241
344
|
|
|
242
345
|
<style>
|
|
243
|
-
|
|
346
|
+
/* ============================================
|
|
347
|
+
CONFIG FORM - Modern, Accessible Design
|
|
348
|
+
============================================ */
|
|
349
|
+
|
|
350
|
+
.config-form {
|
|
351
|
+
display: flex;
|
|
352
|
+
flex-direction: column;
|
|
353
|
+
gap: 1.5rem;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.config-form__fields {
|
|
244
357
|
display: flex;
|
|
245
358
|
flex-direction: column;
|
|
246
|
-
gap:
|
|
359
|
+
gap: 1.25rem;
|
|
247
360
|
}
|
|
248
361
|
|
|
249
|
-
|
|
362
|
+
/* ============================================
|
|
363
|
+
FIELD CONTAINER
|
|
364
|
+
============================================ */
|
|
365
|
+
|
|
366
|
+
.config-form__field {
|
|
250
367
|
display: flex;
|
|
251
368
|
flex-direction: column;
|
|
252
369
|
gap: 0.5rem;
|
|
370
|
+
animation: fieldFadeIn 0.3s ease-out forwards;
|
|
371
|
+
opacity: 0;
|
|
372
|
+
transform: translateY(4px);
|
|
253
373
|
}
|
|
254
374
|
|
|
255
|
-
|
|
256
|
-
|
|
375
|
+
@keyframes fieldFadeIn {
|
|
376
|
+
to {
|
|
377
|
+
opacity: 1;
|
|
378
|
+
transform: translateY(0);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* ============================================
|
|
383
|
+
LABELS
|
|
384
|
+
============================================ */
|
|
385
|
+
|
|
386
|
+
.config-form__label {
|
|
387
|
+
display: flex;
|
|
388
|
+
align-items: center;
|
|
389
|
+
gap: 0.25rem;
|
|
390
|
+
font-size: 0.8125rem;
|
|
391
|
+
font-weight: 600;
|
|
392
|
+
color: var(--color-ref-gray-700, #374151);
|
|
393
|
+
letter-spacing: -0.01em;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.config-form__label-text {
|
|
397
|
+
line-height: 1.4;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.config-form__required {
|
|
401
|
+
color: var(--color-ref-red-500, #ef4444);
|
|
257
402
|
font-weight: 500;
|
|
258
|
-
color: #374151;
|
|
259
403
|
}
|
|
260
404
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
405
|
+
/* ============================================
|
|
406
|
+
INPUT WRAPPER
|
|
407
|
+
============================================ */
|
|
408
|
+
|
|
409
|
+
.config-form__input-wrapper {
|
|
410
|
+
position: relative;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* ============================================
|
|
414
|
+
TEXT INPUTS
|
|
415
|
+
============================================ */
|
|
416
|
+
|
|
417
|
+
.config-form__input {
|
|
418
|
+
width: 100%;
|
|
419
|
+
padding: 0.625rem 0.875rem;
|
|
420
|
+
border: 1px solid var(--color-ref-gray-200, #e5e7eb);
|
|
421
|
+
border-radius: 0.5rem;
|
|
266
422
|
font-size: 0.875rem;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
423
|
+
font-family: inherit;
|
|
424
|
+
color: var(--color-ref-gray-900, #111827);
|
|
425
|
+
background-color: var(--color-ref-gray-50, #f9fafb);
|
|
426
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
427
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.config-form__input::placeholder {
|
|
431
|
+
color: var(--color-ref-gray-400, #9ca3af);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.config-form__input:hover {
|
|
435
|
+
border-color: var(--color-ref-gray-300, #d1d5db);
|
|
436
|
+
background-color: #ffffff;
|
|
270
437
|
}
|
|
271
438
|
|
|
272
|
-
.
|
|
273
|
-
.flowdrop-config-sidebar__select:focus {
|
|
439
|
+
.config-form__input:focus {
|
|
274
440
|
outline: none;
|
|
275
|
-
border-color: #3b82f6;
|
|
276
|
-
|
|
441
|
+
border-color: var(--color-ref-blue-500, #3b82f6);
|
|
442
|
+
background-color: #ffffff;
|
|
443
|
+
box-shadow:
|
|
444
|
+
0 0 0 3px rgba(59, 130, 246, 0.12),
|
|
445
|
+
0 1px 2px rgba(0, 0, 0, 0.04);
|
|
277
446
|
}
|
|
278
447
|
|
|
279
|
-
.
|
|
280
|
-
|
|
281
|
-
flex-direction: column;
|
|
282
|
-
gap: 0.5rem;
|
|
448
|
+
.config-form__input--number {
|
|
449
|
+
font-variant-numeric: tabular-nums;
|
|
283
450
|
}
|
|
284
451
|
|
|
285
|
-
|
|
452
|
+
/* ============================================
|
|
453
|
+
TEXTAREA
|
|
454
|
+
============================================ */
|
|
455
|
+
|
|
456
|
+
.config-form__textarea {
|
|
457
|
+
width: 100%;
|
|
458
|
+
padding: 0.625rem 0.875rem;
|
|
459
|
+
border: 1px solid var(--color-ref-gray-200, #e5e7eb);
|
|
460
|
+
border-radius: 0.5rem;
|
|
461
|
+
font-size: 0.875rem;
|
|
462
|
+
font-family: inherit;
|
|
463
|
+
color: var(--color-ref-gray-900, #111827);
|
|
464
|
+
background-color: var(--color-ref-gray-50, #f9fafb);
|
|
465
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
466
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
467
|
+
resize: vertical;
|
|
468
|
+
min-height: 5rem;
|
|
469
|
+
line-height: 1.5;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.config-form__textarea::placeholder {
|
|
473
|
+
color: var(--color-ref-gray-400, #9ca3af);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.config-form__textarea:hover {
|
|
477
|
+
border-color: var(--color-ref-gray-300, #d1d5db);
|
|
478
|
+
background-color: #ffffff;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.config-form__textarea:focus {
|
|
482
|
+
outline: none;
|
|
483
|
+
border-color: var(--color-ref-blue-500, #3b82f6);
|
|
484
|
+
background-color: #ffffff;
|
|
485
|
+
box-shadow:
|
|
486
|
+
0 0 0 3px rgba(59, 130, 246, 0.12),
|
|
487
|
+
0 1px 2px rgba(0, 0, 0, 0.04);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/* ============================================
|
|
491
|
+
SELECT DROPDOWN
|
|
492
|
+
============================================ */
|
|
493
|
+
|
|
494
|
+
.config-form__select-wrapper {
|
|
495
|
+
position: relative;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.config-form__select {
|
|
499
|
+
width: 100%;
|
|
500
|
+
padding: 0.625rem 2.5rem 0.625rem 0.875rem;
|
|
501
|
+
border: 1px solid var(--color-ref-gray-200, #e5e7eb);
|
|
502
|
+
border-radius: 0.5rem;
|
|
503
|
+
font-size: 0.875rem;
|
|
504
|
+
font-family: inherit;
|
|
505
|
+
color: var(--color-ref-gray-900, #111827);
|
|
506
|
+
background-color: var(--color-ref-gray-50, #f9fafb);
|
|
507
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
508
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
509
|
+
cursor: pointer;
|
|
510
|
+
appearance: none;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.config-form__select:hover {
|
|
514
|
+
border-color: var(--color-ref-gray-300, #d1d5db);
|
|
515
|
+
background-color: #ffffff;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.config-form__select:focus {
|
|
519
|
+
outline: none;
|
|
520
|
+
border-color: var(--color-ref-blue-500, #3b82f6);
|
|
521
|
+
background-color: #ffffff;
|
|
522
|
+
box-shadow:
|
|
523
|
+
0 0 0 3px rgba(59, 130, 246, 0.12),
|
|
524
|
+
0 1px 2px rgba(0, 0, 0, 0.04);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.config-form__select-icon {
|
|
528
|
+
position: absolute;
|
|
529
|
+
right: 0.75rem;
|
|
530
|
+
top: 50%;
|
|
531
|
+
transform: translateY(-50%);
|
|
532
|
+
pointer-events: none;
|
|
533
|
+
color: var(--color-ref-gray-400, #9ca3af);
|
|
286
534
|
display: flex;
|
|
287
535
|
align-items: center;
|
|
288
|
-
|
|
289
|
-
cursor: pointer;
|
|
536
|
+
transition: color 0.2s;
|
|
290
537
|
}
|
|
291
538
|
|
|
292
|
-
.
|
|
539
|
+
.config-form__select-icon :global(svg) {
|
|
293
540
|
width: 1rem;
|
|
294
541
|
height: 1rem;
|
|
295
|
-
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.config-form__select:focus + .config-form__select-icon {
|
|
545
|
+
color: var(--color-ref-blue-500, #3b82f6);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/* ============================================
|
|
549
|
+
CHECKBOX GROUP
|
|
550
|
+
============================================ */
|
|
551
|
+
|
|
552
|
+
.config-form__checkbox-group {
|
|
553
|
+
display: flex;
|
|
554
|
+
flex-direction: column;
|
|
555
|
+
gap: 0.625rem;
|
|
556
|
+
padding: 0.75rem;
|
|
557
|
+
background-color: var(--color-ref-gray-50, #f9fafb);
|
|
558
|
+
border: 1px solid var(--color-ref-gray-200, #e5e7eb);
|
|
559
|
+
border-radius: 0.5rem;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.config-form__checkbox-item {
|
|
563
|
+
display: flex;
|
|
564
|
+
align-items: center;
|
|
565
|
+
gap: 0.625rem;
|
|
296
566
|
cursor: pointer;
|
|
567
|
+
padding: 0.375rem;
|
|
568
|
+
margin: -0.375rem;
|
|
569
|
+
border-radius: 0.375rem;
|
|
570
|
+
transition: background-color 0.15s;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.config-form__checkbox-item:hover {
|
|
574
|
+
background-color: var(--color-ref-gray-100, #f3f4f6);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.config-form__checkbox-input {
|
|
578
|
+
position: absolute;
|
|
579
|
+
opacity: 0;
|
|
580
|
+
width: 0;
|
|
581
|
+
height: 0;
|
|
297
582
|
}
|
|
298
583
|
|
|
299
|
-
.
|
|
584
|
+
.config-form__checkbox-custom {
|
|
585
|
+
width: 1.125rem;
|
|
586
|
+
height: 1.125rem;
|
|
587
|
+
border: 1.5px solid var(--color-ref-gray-300, #d1d5db);
|
|
588
|
+
border-radius: 0.25rem;
|
|
589
|
+
background-color: #ffffff;
|
|
590
|
+
display: flex;
|
|
591
|
+
align-items: center;
|
|
592
|
+
justify-content: center;
|
|
593
|
+
transition: all 0.15s;
|
|
594
|
+
flex-shrink: 0;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.config-form__checkbox-custom :global(svg) {
|
|
598
|
+
width: 0.75rem;
|
|
599
|
+
height: 0.75rem;
|
|
600
|
+
color: #ffffff;
|
|
601
|
+
opacity: 0;
|
|
602
|
+
transform: scale(0.5);
|
|
603
|
+
transition: all 0.15s;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.config-form__checkbox-input:checked + .config-form__checkbox-custom {
|
|
607
|
+
background-color: var(--color-ref-blue-500, #3b82f6);
|
|
608
|
+
border-color: var(--color-ref-blue-500, #3b82f6);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.config-form__checkbox-input:checked + .config-form__checkbox-custom :global(svg) {
|
|
612
|
+
opacity: 1;
|
|
613
|
+
transform: scale(1);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.config-form__checkbox-input:focus-visible + .config-form__checkbox-custom {
|
|
617
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.config-form__checkbox-label {
|
|
300
621
|
font-size: 0.875rem;
|
|
301
|
-
color: #374151;
|
|
622
|
+
color: var(--color-ref-gray-700, #374151);
|
|
623
|
+
line-height: 1.4;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/* ============================================
|
|
627
|
+
TOGGLE SWITCH (Boolean)
|
|
628
|
+
============================================ */
|
|
629
|
+
|
|
630
|
+
.config-form__toggle {
|
|
631
|
+
display: flex;
|
|
632
|
+
align-items: center;
|
|
633
|
+
gap: 0.75rem;
|
|
302
634
|
cursor: pointer;
|
|
635
|
+
padding: 0.5rem 0;
|
|
303
636
|
}
|
|
304
637
|
|
|
305
|
-
.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
638
|
+
.config-form__toggle-input {
|
|
639
|
+
position: absolute;
|
|
640
|
+
opacity: 0;
|
|
641
|
+
width: 0;
|
|
642
|
+
height: 0;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.config-form__toggle-track {
|
|
646
|
+
position: relative;
|
|
647
|
+
width: 2.75rem;
|
|
648
|
+
height: 1.5rem;
|
|
649
|
+
background-color: var(--color-ref-gray-300, #d1d5db);
|
|
650
|
+
border-radius: 0.75rem;
|
|
651
|
+
transition: background-color 0.2s;
|
|
652
|
+
flex-shrink: 0;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.config-form__toggle-thumb {
|
|
656
|
+
position: absolute;
|
|
657
|
+
top: 0.125rem;
|
|
658
|
+
left: 0.125rem;
|
|
659
|
+
width: 1.25rem;
|
|
660
|
+
height: 1.25rem;
|
|
311
661
|
background-color: #ffffff;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
662
|
+
border-radius: 50%;
|
|
663
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
664
|
+
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
315
665
|
}
|
|
316
666
|
|
|
317
|
-
.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
667
|
+
.config-form__toggle-input:checked + .config-form__toggle-track {
|
|
668
|
+
background-color: var(--color-ref-blue-500, #3b82f6);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
.config-form__toggle-input:checked + .config-form__toggle-track .config-form__toggle-thumb {
|
|
672
|
+
transform: translateX(1.25rem);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
.config-form__toggle-input:focus-visible + .config-form__toggle-track {
|
|
676
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.config-form__toggle-label {
|
|
680
|
+
font-size: 0.875rem;
|
|
681
|
+
color: var(--color-ref-gray-600, #4b5563);
|
|
682
|
+
font-weight: 500;
|
|
683
|
+
min-width: 4.5rem;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.config-form__toggle-input:checked ~ .config-form__toggle-label {
|
|
687
|
+
color: var(--color-ref-blue-600, #2563eb);
|
|
321
688
|
}
|
|
322
689
|
|
|
323
|
-
|
|
690
|
+
/* ============================================
|
|
691
|
+
FIELD DESCRIPTION
|
|
692
|
+
============================================ */
|
|
693
|
+
|
|
694
|
+
.config-form__description {
|
|
324
695
|
margin: 0;
|
|
325
696
|
font-size: 0.75rem;
|
|
326
|
-
color: #6b7280;
|
|
327
|
-
line-height: 1.
|
|
697
|
+
color: var(--color-ref-gray-500, #6b7280);
|
|
698
|
+
line-height: 1.5;
|
|
699
|
+
padding-left: 0.125rem;
|
|
328
700
|
}
|
|
329
701
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
font-style: italic;
|
|
334
|
-
padding: 2rem 1rem;
|
|
335
|
-
}
|
|
702
|
+
/* ============================================
|
|
703
|
+
FOOTER ACTIONS
|
|
704
|
+
============================================ */
|
|
336
705
|
|
|
337
|
-
.
|
|
706
|
+
.config-form__footer {
|
|
338
707
|
display: flex;
|
|
339
708
|
gap: 0.75rem;
|
|
340
709
|
justify-content: flex-end;
|
|
341
|
-
|
|
342
|
-
|
|
710
|
+
padding-top: 1rem;
|
|
711
|
+
border-top: 1px solid var(--color-ref-gray-100, #f3f4f6);
|
|
712
|
+
margin-top: 0.5rem;
|
|
343
713
|
}
|
|
344
714
|
|
|
345
|
-
.
|
|
346
|
-
|
|
347
|
-
|
|
715
|
+
.config-form__button {
|
|
716
|
+
display: inline-flex;
|
|
717
|
+
align-items: center;
|
|
718
|
+
justify-content: center;
|
|
719
|
+
gap: 0.5rem;
|
|
720
|
+
padding: 0.625rem 1rem;
|
|
721
|
+
border-radius: 0.5rem;
|
|
348
722
|
font-size: 0.875rem;
|
|
349
|
-
font-weight:
|
|
723
|
+
font-weight: 600;
|
|
724
|
+
font-family: inherit;
|
|
350
725
|
cursor: pointer;
|
|
351
|
-
transition: all 0.2s;
|
|
726
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
352
727
|
border: 1px solid transparent;
|
|
728
|
+
min-height: 2.5rem;
|
|
353
729
|
}
|
|
354
730
|
|
|
355
|
-
.
|
|
731
|
+
.config-form__button :global(svg) {
|
|
732
|
+
width: 1rem;
|
|
733
|
+
height: 1rem;
|
|
734
|
+
flex-shrink: 0;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
.config-form__button--secondary {
|
|
356
738
|
background-color: #ffffff;
|
|
357
|
-
border-color: #
|
|
358
|
-
color: #374151;
|
|
739
|
+
border-color: var(--color-ref-gray-200, #e5e7eb);
|
|
740
|
+
color: var(--color-ref-gray-700, #374151);
|
|
741
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
359
742
|
}
|
|
360
743
|
|
|
361
|
-
.
|
|
362
|
-
background-color: #f9fafb;
|
|
363
|
-
border-color: #
|
|
744
|
+
.config-form__button--secondary:hover {
|
|
745
|
+
background-color: var(--color-ref-gray-50, #f9fafb);
|
|
746
|
+
border-color: var(--color-ref-gray-300, #d1d5db);
|
|
747
|
+
color: var(--color-ref-gray-900, #111827);
|
|
364
748
|
}
|
|
365
749
|
|
|
366
|
-
.
|
|
367
|
-
|
|
750
|
+
.config-form__button--secondary:focus-visible {
|
|
751
|
+
outline: none;
|
|
752
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.config-form__button--primary {
|
|
756
|
+
background: linear-gradient(
|
|
757
|
+
135deg,
|
|
758
|
+
var(--color-ref-blue-500, #3b82f6) 0%,
|
|
759
|
+
var(--color-ref-blue-600, #2563eb) 100%
|
|
760
|
+
);
|
|
368
761
|
color: #ffffff;
|
|
762
|
+
box-shadow:
|
|
763
|
+
0 1px 3px rgba(59, 130, 246, 0.3),
|
|
764
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
369
765
|
}
|
|
370
766
|
|
|
371
|
-
.
|
|
372
|
-
background
|
|
767
|
+
.config-form__button--primary:hover {
|
|
768
|
+
background: linear-gradient(
|
|
769
|
+
135deg,
|
|
770
|
+
var(--color-ref-blue-600, #2563eb) 0%,
|
|
771
|
+
var(--color-ref-blue-700, #1d4ed8) 100%
|
|
772
|
+
);
|
|
773
|
+
box-shadow:
|
|
774
|
+
0 4px 12px rgba(59, 130, 246, 0.35),
|
|
775
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
776
|
+
transform: translateY(-1px);
|
|
373
777
|
}
|
|
374
778
|
|
|
375
|
-
.
|
|
376
|
-
|
|
377
|
-
border: 1px solid #d1d5db;
|
|
378
|
-
border-radius: 0.375rem;
|
|
379
|
-
padding: 1rem;
|
|
380
|
-
margin: 1rem 0;
|
|
779
|
+
.config-form__button--primary:active {
|
|
780
|
+
transform: translateY(0);
|
|
381
781
|
}
|
|
382
782
|
|
|
383
|
-
.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
783
|
+
.config-form__button--primary:focus-visible {
|
|
784
|
+
outline: none;
|
|
785
|
+
box-shadow:
|
|
786
|
+
0 0 0 3px rgba(59, 130, 246, 0.4),
|
|
787
|
+
0 4px 12px rgba(59, 130, 246, 0.35);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/* ============================================
|
|
791
|
+
DEBUG SECTION
|
|
792
|
+
============================================ */
|
|
793
|
+
|
|
794
|
+
.config-form__debug {
|
|
795
|
+
background-color: var(--color-ref-amber-50, #fffbeb);
|
|
796
|
+
border: 1px solid var(--color-ref-amber-200, #fde68a);
|
|
797
|
+
border-radius: 0.5rem;
|
|
798
|
+
overflow: hidden;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
.config-form__debug-header {
|
|
802
|
+
display: flex;
|
|
803
|
+
align-items: center;
|
|
804
|
+
gap: 0.5rem;
|
|
805
|
+
padding: 0.75rem 1rem;
|
|
806
|
+
background-color: var(--color-ref-amber-100, #fef3c7);
|
|
807
|
+
border-bottom: 1px solid var(--color-ref-amber-200, #fde68a);
|
|
808
|
+
font-size: 0.8125rem;
|
|
809
|
+
font-weight: 600;
|
|
810
|
+
color: var(--color-ref-amber-800, #92400e);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.config-form__debug-header :global(svg) {
|
|
814
|
+
width: 1rem;
|
|
815
|
+
height: 1rem;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
.config-form__debug-content {
|
|
819
|
+
margin: 0;
|
|
820
|
+
padding: 1rem;
|
|
388
821
|
font-size: 0.75rem;
|
|
822
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
823
|
+
color: var(--color-ref-gray-700, #374151);
|
|
389
824
|
overflow-x: auto;
|
|
390
|
-
|
|
825
|
+
background-color: #ffffff;
|
|
826
|
+
line-height: 1.5;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/* ============================================
|
|
830
|
+
EMPTY STATE
|
|
831
|
+
============================================ */
|
|
832
|
+
|
|
833
|
+
.config-form__empty {
|
|
834
|
+
display: flex;
|
|
835
|
+
flex-direction: column;
|
|
836
|
+
align-items: center;
|
|
837
|
+
justify-content: center;
|
|
838
|
+
padding: 3rem 1.5rem;
|
|
839
|
+
text-align: center;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.config-form__empty-icon {
|
|
843
|
+
width: 3rem;
|
|
844
|
+
height: 3rem;
|
|
845
|
+
margin-bottom: 1rem;
|
|
846
|
+
color: var(--color-ref-gray-300, #d1d5db);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
.config-form__empty-icon :global(svg) {
|
|
850
|
+
width: 100%;
|
|
851
|
+
height: 100%;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.config-form__empty-text {
|
|
855
|
+
margin: 0;
|
|
856
|
+
font-size: 0.875rem;
|
|
857
|
+
color: var(--color-ref-gray-500, #6b7280);
|
|
858
|
+
font-style: italic;
|
|
859
|
+
line-height: 1.5;
|
|
391
860
|
}
|
|
392
861
|
</style>
|