@esfaenza/flow-builder 20.0.0
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/README.md +354 -0
- package/fesm2022/esfaenza-flow-builder.mjs +7270 -0
- package/fesm2022/esfaenza-flow-builder.mjs.map +1 -0
- package/index.d.ts +2666 -0
- package/package.json +26 -0
- package/styles/flow-builder.css +483 -0
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@esfaenza/flow-builder",
|
|
3
|
+
"version": "20.0.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^20.3.25",
|
|
6
|
+
"@angular/core": "^20.3.25",
|
|
7
|
+
"@foblex/flow": ">=19.0.0",
|
|
8
|
+
"dagre": "^0.8.5"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"description": "Editor visuale di flow: componente standalone Angular, con tutto il traffico verso il backend dietro un'unica interfaccia.",
|
|
15
|
+
"module": "fesm2022/esfaenza-flow-builder.mjs",
|
|
16
|
+
"typings": "index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./package.json": {
|
|
19
|
+
"default": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./index.d.ts",
|
|
23
|
+
"default": "./fesm2022/esfaenza-flow-builder.mjs"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tema del flow builder — da includere negli `styles` dell'applicazione ospite:
|
|
3
|
+
*
|
|
4
|
+
* "styles": [
|
|
5
|
+
* "node_modules/@foblex/flow/styles/default.scss",
|
|
6
|
+
* "node_modules/@enuma/flow-builder/styles/flow-builder.css",
|
|
7
|
+
* "src/styles.css"
|
|
8
|
+
* ]
|
|
9
|
+
*
|
|
10
|
+
* Contiene due cose che **non possono** stare nel CSS incapsulato dei componenti:
|
|
11
|
+
* 1. le variabili del tema, così l'app le puo' sovrascrivere per integrarsi nel proprio
|
|
12
|
+
* design system senza toccare la libreria;
|
|
13
|
+
* 2. gli stili degli archi: i path SVG delle connessioni sono creati a runtime da
|
|
14
|
+
* @foblex/flow e non portano l'attributo di scope, quindi un selettore scoped non li
|
|
15
|
+
* raggiunge mai.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
.fb-builder,
|
|
19
|
+
.fb-theme {
|
|
20
|
+
/* Superfici e testo */
|
|
21
|
+
--fb-surface: #ffffff;
|
|
22
|
+
--fb-surface-alt: #f7f8fa;
|
|
23
|
+
--fb-surface-sunken: #eef0f4;
|
|
24
|
+
--fb-canvas-bg: #f4f5f7;
|
|
25
|
+
--fb-border: #e2e5eb;
|
|
26
|
+
--fb-border-strong: #cfd4de;
|
|
27
|
+
--fb-border-subtle: #eef0f4;
|
|
28
|
+
--fb-text: #1a1c23;
|
|
29
|
+
--fb-text-muted: #6b7086;
|
|
30
|
+
--fb-text-subtle: #98a2b3;
|
|
31
|
+
|
|
32
|
+
/* Accenti e stati */
|
|
33
|
+
--fb-accent: #4f6ef7;
|
|
34
|
+
--fb-accent-strong: #3d59e0;
|
|
35
|
+
--fb-accent-contrast: #ffffff;
|
|
36
|
+
--fb-error: #dc2626;
|
|
37
|
+
--fb-warning: #b7791f;
|
|
38
|
+
--fb-success: #22a06b;
|
|
39
|
+
|
|
40
|
+
/* Archi, per tipo di connettore (§6.4, `kind`) */
|
|
41
|
+
--fb-edge-next: #98a2b3;
|
|
42
|
+
--fb-edge-rule: #8b5cf6;
|
|
43
|
+
--fb-edge-default: #06b6d4;
|
|
44
|
+
--fb-edge-fault: #dc2626;
|
|
45
|
+
--fb-edge-timeout: #f59e0b;
|
|
46
|
+
--fb-edge-loop: #22a06b;
|
|
47
|
+
|
|
48
|
+
/* Scala dei raggi e delle ombre: una sola, così i pannelli, la card di un node e la
|
|
49
|
+
dialog hanno la stessa morbidezza. */
|
|
50
|
+
--fb-radius-xs: 6px;
|
|
51
|
+
--fb-radius-sm: 8px;
|
|
52
|
+
--fb-radius: 10px;
|
|
53
|
+
--fb-radius-lg: 12px;
|
|
54
|
+
--fb-shadow-sm: 0 1px 2px rgb(16 24 40 / 6%);
|
|
55
|
+
--fb-shadow-md: 0 6px 18px rgb(16 24 40 / 10%);
|
|
56
|
+
--fb-shadow-lg: 0 18px 44px rgb(16 24 40 / 18%);
|
|
57
|
+
--fb-font: inherit;
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* I token di @foblex/flow allineati ai nostri: il canvas, il pattern di sfondo, la
|
|
61
|
+
* minimappa e lo spessore degli archi sono disegnati dalla libreria, e questo e' il punto
|
|
62
|
+
* previsto per ritemizzarli — piu' solido che sovrascriverne le regole.
|
|
63
|
+
*/
|
|
64
|
+
--ff-canvas-background-color: var(--fb-canvas-bg);
|
|
65
|
+
--ff-flow-background-color: var(--fb-canvas-bg);
|
|
66
|
+
--ff-background-dot-color: color-mix(in srgb, var(--fb-text-subtle) 40%, transparent);
|
|
67
|
+
--ff-connection-width: 2px;
|
|
68
|
+
/*
|
|
69
|
+
* Le maniglie di riassegnazione dell'arco restano trascinabili ma invisibili: disegnate,
|
|
70
|
+
* si sovrappongono alla punta della freccia e all'ingresso del node, e nel punto in cui
|
|
71
|
+
* l'arco arriva si vedeva una macchia in cui non si capiva piu' dove finisse.
|
|
72
|
+
*/
|
|
73
|
+
--ff-connection-drag-handle-fill: transparent;
|
|
74
|
+
--ff-connection-drag-handle-stroke: transparent;
|
|
75
|
+
--ff-connection-content-background-color: var(--fb-surface);
|
|
76
|
+
--ff-connection-content-border-color: var(--fb-border);
|
|
77
|
+
--ff-connection-content-color: var(--fb-text-muted);
|
|
78
|
+
--ff-minimap-background-color: var(--fb-surface);
|
|
79
|
+
--ff-minimap-border-color: var(--fb-border);
|
|
80
|
+
--ff-minimap-node-color: var(--fb-border-strong);
|
|
81
|
+
--ff-minimap-view-color: color-mix(in srgb, var(--fb-accent) 12%, transparent);
|
|
82
|
+
--ff-minimap-view-border-color: var(--fb-accent);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Variante scura: si attiva mettendo `data-fb-theme="dark"` sul contenitore. */
|
|
86
|
+
[data-fb-theme='dark'] {
|
|
87
|
+
--fb-surface: #151921;
|
|
88
|
+
--fb-surface-alt: #1c2029;
|
|
89
|
+
--fb-surface-sunken: #232830;
|
|
90
|
+
--fb-canvas-bg: #0c0e14;
|
|
91
|
+
--fb-border: #2d323c;
|
|
92
|
+
--fb-border-strong: #3b414d;
|
|
93
|
+
--fb-border-subtle: #232830;
|
|
94
|
+
--fb-text: #e8eaf0;
|
|
95
|
+
--fb-text-muted: #8b90a0;
|
|
96
|
+
--fb-text-subtle: #6b7684;
|
|
97
|
+
--fb-accent: #818cf8;
|
|
98
|
+
--fb-accent-strong: #6366f1;
|
|
99
|
+
--fb-error: #ef6a5f;
|
|
100
|
+
--fb-warning: #d9a13c;
|
|
101
|
+
--fb-success: #63b57f;
|
|
102
|
+
--fb-edge-next: #6b7684;
|
|
103
|
+
--fb-shadow-sm: 0 1px 2px rgb(0 0 0 / 40%);
|
|
104
|
+
--fb-shadow-md: 0 6px 18px rgb(0 0 0 / 45%);
|
|
105
|
+
--fb-shadow-lg: 0 18px 44px rgb(0 0 0 / 55%);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ---------------------------------------------------------------- archi */
|
|
109
|
+
/*
|
|
110
|
+
* Gli archi si colorano impostando le **custom properties del tema di @foblex/flow**, non
|
|
111
|
+
* sovrascrivendo le sue regole: `f-flow .f-connection .f-connection-path` ha la stessa
|
|
112
|
+
* specificita' dei nostri selettori, e chi vince dipenderebbe dall'ordine con cui l'app
|
|
113
|
+
* ospite carica i due fogli di stile. Le variabili, invece, ereditano dall'elemento della
|
|
114
|
+
* connessione al path e al marker, e valgono qualunque sia l'ordine.
|
|
115
|
+
*
|
|
116
|
+
* `kind` di un arco (§6.4) → colore: un Fault rosso, un Rule etichettato e viola, un
|
|
117
|
+
* LoopNext verde che rientra.
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
.fb-edge {
|
|
121
|
+
--ff-connection-color: var(--fb-edge-next, #98a2b3);
|
|
122
|
+
--ff-marker-color: var(--fb-edge-next, #98a2b3);
|
|
123
|
+
--ff-connection-selected-color: var(--fb-accent, #2f6feb);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.fb-edge--Rule,
|
|
127
|
+
.fb-edge--WaitEvent {
|
|
128
|
+
--ff-connection-color: var(--fb-edge-rule, #7c5cd6);
|
|
129
|
+
--ff-marker-color: var(--fb-edge-rule, #7c5cd6);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.fb-edge--Default {
|
|
133
|
+
--ff-connection-color: var(--fb-edge-default, #0e8a9b);
|
|
134
|
+
--ff-marker-color: var(--fb-edge-default, #0e8a9b);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* Il fault connector non e' un'uscita "di errore" nel senso di eccezione: e' un ramo che
|
|
139
|
+
* l'autore ha previsto, e un flow che lo percorre finisce Completed. Il rosso lo distingue;
|
|
140
|
+
* il tratteggio no, perche' non e' un percorso meno reale degli altri.
|
|
141
|
+
*/
|
|
142
|
+
.fb-edge--Fault {
|
|
143
|
+
--ff-connection-color: var(--fb-edge-fault, #c9372c);
|
|
144
|
+
--ff-marker-color: var(--fb-edge-fault, #c9372c);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.fb-edge--Timeout,
|
|
148
|
+
.fb-edge--ScheduledPath {
|
|
149
|
+
--ff-connection-color: var(--fb-edge-timeout, #b7791f);
|
|
150
|
+
--ff-marker-color: var(--fb-edge-timeout, #b7791f);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.fb-edge--LoopNext,
|
|
154
|
+
.fb-edge--LoopEnd {
|
|
155
|
+
--ff-connection-color: var(--fb-edge-loop, #3f8f5f);
|
|
156
|
+
--ff-marker-color: var(--fb-edge-loop, #3f8f5f);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.fb-edge--creating {
|
|
160
|
+
--ff-connection-color: var(--fb-accent, #2f6feb);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* Il tratteggio non e' esprimibile con una variabile del tema, quindi qui serve una regola.
|
|
165
|
+
* Il prefisso `f-flow` pareggia la specificita' di `f-flow .f-connection .f-connection-path`
|
|
166
|
+
* e, arrivando dopo nel foglio, vince — ma riguarda solo `stroke-dasharray`, cioe' una
|
|
167
|
+
* proprieta' che il tema non imposta: nessun conflitto reale da risolvere.
|
|
168
|
+
*/
|
|
169
|
+
f-flow .fb-edge--Default .f-connection-path {
|
|
170
|
+
stroke-dasharray: 6 4;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
f-flow .fb-edge--Timeout .f-connection-path,
|
|
174
|
+
f-flow .fb-edge--ScheduledPath .f-connection-path {
|
|
175
|
+
stroke-dasharray: 4 4;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
f-flow .fb-edge--creating .f-connection-path {
|
|
179
|
+
stroke-dasharray: 5 4;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* `isGoTo` e' solo un suggerimento di disegno: l'arco torna indietro nel grafo. */
|
|
183
|
+
f-flow .fb-edge--goto .f-connection-path {
|
|
184
|
+
stroke-dasharray: 2 5;
|
|
185
|
+
stroke-linecap: round;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.fb-edge-label {
|
|
189
|
+
padding: 2px 7px;
|
|
190
|
+
border: 1px solid var(--fb-border, #e2e5eb);
|
|
191
|
+
border-radius: 999px;
|
|
192
|
+
background: var(--fb-surface, #fff);
|
|
193
|
+
box-shadow: var(--fb-shadow-sm, 0 1px 2px rgb(16 24 40 / 6%));
|
|
194
|
+
font-size: 10px;
|
|
195
|
+
font-weight: 600;
|
|
196
|
+
color: var(--fb-text-muted, #6b7086);
|
|
197
|
+
white-space: nowrap;
|
|
198
|
+
pointer-events: none;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* ------------------------------------------------------------- controlli */
|
|
202
|
+
/*
|
|
203
|
+
* I controlli di form vivono qui, non nel CSS incapsulato dei singoli inspector: sono
|
|
204
|
+
* venti form che condividono lo stesso aspetto, e l'app ospite deve poterli ritemizzare
|
|
205
|
+
* in un punto solo.
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
.fb-field {
|
|
209
|
+
display: flex;
|
|
210
|
+
flex-direction: column;
|
|
211
|
+
gap: 3px;
|
|
212
|
+
margin-bottom: 10px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.fb-field__label {
|
|
216
|
+
font-size: 11px;
|
|
217
|
+
font-weight: 600;
|
|
218
|
+
color: var(--fb-text-muted, #667085);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.fb-field__label--required::after {
|
|
222
|
+
content: ' *';
|
|
223
|
+
color: var(--fb-error, #c9372c);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.fb-field__hint {
|
|
227
|
+
margin: 0;
|
|
228
|
+
font-size: 10px;
|
|
229
|
+
line-height: 1.35;
|
|
230
|
+
color: var(--fb-text-subtle, #98a2b3);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.fb-field__hint--warn {
|
|
234
|
+
color: var(--fb-warning, #b7791f);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.fb-field__error {
|
|
238
|
+
margin: 0;
|
|
239
|
+
font-size: 10px;
|
|
240
|
+
color: var(--fb-error, #c9372c);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.fb-field__row {
|
|
244
|
+
display: flex;
|
|
245
|
+
gap: 6px;
|
|
246
|
+
align-items: flex-start;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.fb-field__row > * {
|
|
250
|
+
min-width: 0;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.fb-input,
|
|
254
|
+
.fb-select,
|
|
255
|
+
.fb-textarea {
|
|
256
|
+
box-sizing: border-box;
|
|
257
|
+
width: 100%;
|
|
258
|
+
padding: 6px 8px;
|
|
259
|
+
border: 1px solid var(--fb-border-strong, #cfd4de);
|
|
260
|
+
border-radius: var(--fb-radius-xs, 6px);
|
|
261
|
+
background: var(--fb-surface, #fff);
|
|
262
|
+
color: var(--fb-text, #1a1c23);
|
|
263
|
+
font: inherit;
|
|
264
|
+
font-size: 12px;
|
|
265
|
+
transition: border-color 0.12s ease, box-shadow 0.12s ease;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.fb-input:hover:not(:disabled),
|
|
269
|
+
.fb-select:hover:not(:disabled),
|
|
270
|
+
.fb-textarea:hover:not(:disabled) {
|
|
271
|
+
border-color: var(--fb-text-subtle, #98a2b3);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.fb-textarea {
|
|
275
|
+
min-height: 56px;
|
|
276
|
+
resize: vertical;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.fb-input:focus-visible,
|
|
280
|
+
.fb-select:focus-visible,
|
|
281
|
+
.fb-textarea:focus-visible {
|
|
282
|
+
outline: none;
|
|
283
|
+
border-color: var(--fb-accent, #4f6ef7);
|
|
284
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fb-accent, #4f6ef7) 18%, transparent);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.fb-input:disabled,
|
|
288
|
+
.fb-select:disabled,
|
|
289
|
+
.fb-textarea:disabled {
|
|
290
|
+
background: var(--fb-surface-alt, #f8f9fb);
|
|
291
|
+
color: var(--fb-text-muted, #667085);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.fb-input--invalid,
|
|
295
|
+
.fb-select--invalid {
|
|
296
|
+
border-color: var(--fb-error, #c9372c);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.fb-input--mono {
|
|
300
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.fb-check {
|
|
304
|
+
display: flex;
|
|
305
|
+
align-items: center;
|
|
306
|
+
gap: 6px;
|
|
307
|
+
font-size: 12px;
|
|
308
|
+
color: var(--fb-text, #1d2939);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.fb-btn {
|
|
312
|
+
display: inline-flex;
|
|
313
|
+
align-items: center;
|
|
314
|
+
gap: 5px;
|
|
315
|
+
padding: 5px 11px;
|
|
316
|
+
border: 1px solid var(--fb-border-strong, #cfd4de);
|
|
317
|
+
border-radius: var(--fb-radius-xs, 6px);
|
|
318
|
+
background: var(--fb-surface, #fff);
|
|
319
|
+
color: var(--fb-text, #1a1c23);
|
|
320
|
+
font: inherit;
|
|
321
|
+
font-size: 12px;
|
|
322
|
+
font-weight: 500;
|
|
323
|
+
cursor: pointer;
|
|
324
|
+
transition: background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.fb-btn:hover:not(:disabled) {
|
|
328
|
+
background: var(--fb-surface-alt, #f7f8fa);
|
|
329
|
+
border-color: var(--fb-text-subtle, #98a2b3);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.fb-btn:disabled {
|
|
333
|
+
opacity: 0.5;
|
|
334
|
+
cursor: not-allowed;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.fb-btn:focus-visible {
|
|
338
|
+
outline: 2px solid var(--fb-accent, #2f6feb);
|
|
339
|
+
outline-offset: 1px;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.fb-btn--primary {
|
|
343
|
+
border-color: var(--fb-accent, #4f6ef7);
|
|
344
|
+
background: var(--fb-accent, #4f6ef7);
|
|
345
|
+
color: var(--fb-accent-contrast, #fff);
|
|
346
|
+
box-shadow: var(--fb-shadow-sm, 0 1px 2px rgb(16 24 40 / 6%));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.fb-btn--primary:hover:not(:disabled) {
|
|
350
|
+
border-color: var(--fb-accent-strong, #3d59e0);
|
|
351
|
+
background: var(--fb-accent-strong, #3d59e0);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.fb-btn--danger {
|
|
355
|
+
border-color: color-mix(in srgb, var(--fb-error, #c9372c) 45%, transparent);
|
|
356
|
+
color: var(--fb-error, #c9372c);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.fb-btn--ghost {
|
|
360
|
+
border-color: transparent;
|
|
361
|
+
background: transparent;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.fb-btn--icon {
|
|
365
|
+
padding: 3px 6px;
|
|
366
|
+
font-size: 12px;
|
|
367
|
+
line-height: 1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.fb-section {
|
|
371
|
+
margin: 0 0 14px;
|
|
372
|
+
padding: 0;
|
|
373
|
+
border: 0;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.fb-section__title {
|
|
377
|
+
display: flex;
|
|
378
|
+
align-items: center;
|
|
379
|
+
justify-content: space-between;
|
|
380
|
+
gap: 8px;
|
|
381
|
+
margin: 0 0 6px;
|
|
382
|
+
font-size: 11px;
|
|
383
|
+
font-weight: 700;
|
|
384
|
+
letter-spacing: 0.05em;
|
|
385
|
+
text-transform: uppercase;
|
|
386
|
+
color: var(--fb-text-subtle, #98a2b3);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.fb-section__note {
|
|
390
|
+
margin: 0 0 8px;
|
|
391
|
+
font-size: 11px;
|
|
392
|
+
line-height: 1.45;
|
|
393
|
+
color: var(--fb-text-muted, #667085);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.fb-list {
|
|
397
|
+
display: flex;
|
|
398
|
+
flex-direction: column;
|
|
399
|
+
gap: 8px;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.fb-list__item {
|
|
403
|
+
padding: 9px 10px;
|
|
404
|
+
border: 1px solid var(--fb-border, #e2e5eb);
|
|
405
|
+
border-radius: var(--fb-radius-sm, 8px);
|
|
406
|
+
background: var(--fb-surface-alt, #f7f8fa);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.fb-list__header {
|
|
410
|
+
display: flex;
|
|
411
|
+
align-items: center;
|
|
412
|
+
gap: 6px;
|
|
413
|
+
margin-bottom: 6px;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.fb-list__index {
|
|
417
|
+
display: grid;
|
|
418
|
+
place-items: center;
|
|
419
|
+
width: 18px;
|
|
420
|
+
height: 18px;
|
|
421
|
+
border-radius: 50%;
|
|
422
|
+
background: var(--fb-border, #d6dae1);
|
|
423
|
+
font-size: 10px;
|
|
424
|
+
font-weight: 700;
|
|
425
|
+
color: var(--fb-text, #1d2939);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.fb-list__spacer {
|
|
429
|
+
flex: 1;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.fb-empty {
|
|
433
|
+
margin: 0;
|
|
434
|
+
padding: 8px;
|
|
435
|
+
border: 1px dashed var(--fb-border, #d6dae1);
|
|
436
|
+
border-radius: 6px;
|
|
437
|
+
font-size: 11px;
|
|
438
|
+
color: var(--fb-text-muted, #667085);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.fb-callout {
|
|
442
|
+
margin: 0 0 10px;
|
|
443
|
+
padding: 7px 9px;
|
|
444
|
+
border-left: 3px solid var(--fb-accent, #2f6feb);
|
|
445
|
+
border-radius: 4px;
|
|
446
|
+
background: color-mix(in srgb, var(--fb-accent, #2f6feb) 7%, transparent);
|
|
447
|
+
font-size: 11px;
|
|
448
|
+
line-height: 1.45;
|
|
449
|
+
color: var(--fb-text, #1d2939);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.fb-callout--warn {
|
|
453
|
+
border-left-color: var(--fb-warning, #b7791f);
|
|
454
|
+
background: color-mix(in srgb, var(--fb-warning, #b7791f) 10%, transparent);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.fb-callout--error {
|
|
458
|
+
border-left-color: var(--fb-error, #c9372c);
|
|
459
|
+
background: color-mix(in srgb, var(--fb-error, #c9372c) 8%, transparent);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.fb-fields-grid {
|
|
463
|
+
display: grid;
|
|
464
|
+
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
|
465
|
+
gap: 2px 8px;
|
|
466
|
+
max-height: 180px;
|
|
467
|
+
overflow-y: auto;
|
|
468
|
+
padding: 6px;
|
|
469
|
+
border: 1px solid var(--fb-border-subtle, #e6e9ee);
|
|
470
|
+
border-radius: 6px;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.fb-fields-grid .fb-check {
|
|
474
|
+
font-size: 11px;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.fb-confirm {
|
|
478
|
+
padding: 7px 9px;
|
|
479
|
+
border: 1px solid var(--fb-warning, #b7791f);
|
|
480
|
+
border-radius: 6px;
|
|
481
|
+
background: color-mix(in srgb, var(--fb-warning, #b7791f) 8%, transparent);
|
|
482
|
+
font-size: 11px;
|
|
483
|
+
}
|