@konomi-app/ui 5.1.0 → 5.3.2
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/index.cjs +1106 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +121 -2
- package/dist/index.d.ts +121 -2
- package/dist/index.js +1106 -18
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
package/dist/index.js
CHANGED
|
@@ -35,14 +35,168 @@ var createInitialState = () => ({
|
|
|
35
35
|
queues: [],
|
|
36
36
|
steps: [],
|
|
37
37
|
timer: null,
|
|
38
|
-
title: ""
|
|
38
|
+
title: "",
|
|
39
|
+
formFields: [],
|
|
40
|
+
formValues: {},
|
|
41
|
+
formErrors: {},
|
|
42
|
+
formTouched: {},
|
|
43
|
+
formLayout: {},
|
|
44
|
+
formValidateOnChange: true,
|
|
45
|
+
formValidateOnBlur: true,
|
|
46
|
+
stepFormSteps: [],
|
|
47
|
+
stepFormCurrentIndex: 0,
|
|
48
|
+
stepFormNextText: "\u6B21\u3078",
|
|
49
|
+
stepFormPrevText: "\u623B\u308B",
|
|
50
|
+
stepFormSubmitText: "OK"
|
|
39
51
|
});
|
|
40
52
|
|
|
53
|
+
// src/zod-utils.ts
|
|
54
|
+
function resolveTypeName(field) {
|
|
55
|
+
const raw = field._def.typeName ?? field._def.type;
|
|
56
|
+
if (!raw) return "";
|
|
57
|
+
const v4Map = {
|
|
58
|
+
string: "ZodString",
|
|
59
|
+
number: "ZodNumber",
|
|
60
|
+
boolean: "ZodBoolean",
|
|
61
|
+
enum: "ZodEnum",
|
|
62
|
+
date: "ZodDate",
|
|
63
|
+
optional: "ZodOptional",
|
|
64
|
+
nullable: "ZodNullable",
|
|
65
|
+
default: "ZodDefault",
|
|
66
|
+
object: "ZodObject",
|
|
67
|
+
pipe: "ZodPipe"
|
|
68
|
+
};
|
|
69
|
+
return v4Map[raw] ?? raw;
|
|
70
|
+
}
|
|
71
|
+
function unwrapType(zodType) {
|
|
72
|
+
let inner = zodType;
|
|
73
|
+
let required = true;
|
|
74
|
+
let defaultValue = void 0;
|
|
75
|
+
let description = zodType.description ?? "";
|
|
76
|
+
while (true) {
|
|
77
|
+
const typeName = resolveTypeName(inner);
|
|
78
|
+
if (typeName === "ZodOptional" || typeName === "ZodNullable") {
|
|
79
|
+
required = false;
|
|
80
|
+
inner = inner._def.innerType;
|
|
81
|
+
} else if (typeName === "ZodDefault") {
|
|
82
|
+
const raw = inner._def.defaultValue;
|
|
83
|
+
defaultValue = typeof raw === "function" ? raw() : raw;
|
|
84
|
+
inner = inner._def.innerType;
|
|
85
|
+
} else if (typeName === "ZodEffects") {
|
|
86
|
+
inner = inner._def.schema;
|
|
87
|
+
} else {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
if (!description && inner.description) {
|
|
91
|
+
description = inner.description;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { inner, required, defaultValue, description };
|
|
95
|
+
}
|
|
96
|
+
function extractFieldMeta(key, zodType) {
|
|
97
|
+
const { inner, required, defaultValue, description } = unwrapType(zodType);
|
|
98
|
+
const typeName = resolveTypeName(inner);
|
|
99
|
+
let inputType;
|
|
100
|
+
let options = [];
|
|
101
|
+
let min;
|
|
102
|
+
let max;
|
|
103
|
+
let minLength;
|
|
104
|
+
let maxLength;
|
|
105
|
+
switch (typeName) {
|
|
106
|
+
case "ZodString": {
|
|
107
|
+
inputType = "text";
|
|
108
|
+
if (inner.format === "email") inputType = "email";
|
|
109
|
+
else if (inner.format === "url") inputType = "url";
|
|
110
|
+
if (inner.minLength != null) minLength = inner.minLength;
|
|
111
|
+
if (inner.maxLength != null) maxLength = inner.maxLength;
|
|
112
|
+
const checks = inner._def.checks ?? [];
|
|
113
|
+
for (const check of checks) {
|
|
114
|
+
const kind = check.kind ?? check.def?.check;
|
|
115
|
+
const fmt = check.format ?? check.def?.format;
|
|
116
|
+
if (!fmt && (kind === "email" || fmt === "email")) inputType = "email";
|
|
117
|
+
else if (!fmt && (kind === "url" || fmt === "url")) inputType = "url";
|
|
118
|
+
else if (fmt === "email" && inputType === "text") inputType = "email";
|
|
119
|
+
else if (fmt === "url" && inputType === "text") inputType = "url";
|
|
120
|
+
if (kind === "min" && check.value != null && minLength == null) minLength = check.value;
|
|
121
|
+
if (kind === "max" && check.value != null && maxLength == null) maxLength = check.value;
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "ZodNumber": {
|
|
126
|
+
inputType = "number";
|
|
127
|
+
if (inner.minValue != null) min = inner.minValue;
|
|
128
|
+
if (inner.maxValue != null) max = inner.maxValue;
|
|
129
|
+
if (min == null || max == null) {
|
|
130
|
+
const checks = inner._def.checks ?? [];
|
|
131
|
+
for (const check of checks) {
|
|
132
|
+
if (check.kind === "min" && check.value != null && min == null) min = check.value;
|
|
133
|
+
if (check.kind === "max" && check.value != null && max == null) max = check.value;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "ZodBoolean":
|
|
139
|
+
inputType = "checkbox";
|
|
140
|
+
break;
|
|
141
|
+
case "ZodEnum": {
|
|
142
|
+
inputType = "select";
|
|
143
|
+
if (inner.options?.length) {
|
|
144
|
+
options = [...inner.options];
|
|
145
|
+
} else if (inner._def.entries) {
|
|
146
|
+
options = Object.values(inner._def.entries);
|
|
147
|
+
} else if (inner._def.values?.length) {
|
|
148
|
+
options = [...inner._def.values];
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "ZodNativeEnum": {
|
|
153
|
+
inputType = "select";
|
|
154
|
+
const enumValues = inner._def.values;
|
|
155
|
+
if (enumValues) {
|
|
156
|
+
options = Object.values(enumValues).filter((v) => typeof v === "string");
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "ZodDate":
|
|
161
|
+
inputType = "date";
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const label = description || key;
|
|
167
|
+
return {
|
|
168
|
+
key,
|
|
169
|
+
inputType,
|
|
170
|
+
label,
|
|
171
|
+
description: description && description !== label ? description : "",
|
|
172
|
+
required,
|
|
173
|
+
options,
|
|
174
|
+
placeholder: "",
|
|
175
|
+
min,
|
|
176
|
+
max,
|
|
177
|
+
minLength,
|
|
178
|
+
maxLength,
|
|
179
|
+
defaultValue
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function extractFormFields(schema) {
|
|
183
|
+
const shapeDef = schema._def.shape;
|
|
184
|
+
if (!shapeDef) return [];
|
|
185
|
+
const shape = typeof shapeDef === "function" ? shapeDef() : shapeDef;
|
|
186
|
+
if (!shape) return [];
|
|
187
|
+
const fields = [];
|
|
188
|
+
for (const [key, zodType] of Object.entries(shape)) {
|
|
189
|
+
const meta = extractFieldMeta(key, zodType);
|
|
190
|
+
if (meta) fields.push(meta);
|
|
191
|
+
}
|
|
192
|
+
return fields;
|
|
193
|
+
}
|
|
194
|
+
|
|
41
195
|
// src/controller.ts
|
|
42
196
|
function normalizeItemInput(input) {
|
|
43
197
|
return typeof input === "string" ? { key: input, label: input } : input;
|
|
44
198
|
}
|
|
45
|
-
var _state, _listeners, _resolver, _timerId, _DialogController_instances, emit_fn, update_fn, createPromise_fn, resolve_fn, clearTimer_fn, updateItemStatus_fn;
|
|
199
|
+
var _state, _listeners, _resolver, _timerId, _formSchema, _formResult, _stepFormSchemas, _stepFormResults, _DialogController_instances, emit_fn, update_fn, validateFormField_fn, updateCurrentStep_fn, validateStepField_fn, createPromise_fn, resolve_fn, clearTimer_fn, updateItemStatus_fn;
|
|
46
200
|
var DialogController = class {
|
|
47
201
|
constructor() {
|
|
48
202
|
__privateAdd(this, _DialogController_instances);
|
|
@@ -50,6 +204,10 @@ var DialogController = class {
|
|
|
50
204
|
__privateAdd(this, _listeners, /* @__PURE__ */ new Set());
|
|
51
205
|
__privateAdd(this, _resolver, null);
|
|
52
206
|
__privateAdd(this, _timerId, null);
|
|
207
|
+
__privateAdd(this, _formSchema, null);
|
|
208
|
+
__privateAdd(this, _formResult, null);
|
|
209
|
+
__privateAdd(this, _stepFormSchemas, []);
|
|
210
|
+
__privateAdd(this, _stepFormResults, {});
|
|
53
211
|
__privateSet(this, _state, createInitialState());
|
|
54
212
|
}
|
|
55
213
|
// ─── Observable ──────────────────────────────────────────
|
|
@@ -195,9 +353,202 @@ var DialogController = class {
|
|
|
195
353
|
clearSteps() {
|
|
196
354
|
__privateMethod(this, _DialogController_instances, update_fn).call(this, { steps: [] });
|
|
197
355
|
}
|
|
356
|
+
// ─── Form ─────────────────────────────────────────────────
|
|
357
|
+
form(schema, options) {
|
|
358
|
+
__privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
|
|
359
|
+
__privateSet(this, _formSchema, schema);
|
|
360
|
+
__privateSet(this, _formResult, null);
|
|
361
|
+
const fields = extractFormFields(schema);
|
|
362
|
+
const defaultValues = {};
|
|
363
|
+
for (const field of fields) {
|
|
364
|
+
if (field.defaultValue !== void 0) {
|
|
365
|
+
defaultValues[field.key] = field.defaultValue;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (options?.defaultValues) {
|
|
369
|
+
Object.assign(defaultValues, options.defaultValues);
|
|
370
|
+
}
|
|
371
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, {
|
|
372
|
+
open: true,
|
|
373
|
+
dialogType: "form",
|
|
374
|
+
title: options?.title ?? "",
|
|
375
|
+
label: "",
|
|
376
|
+
description: options?.description ?? "",
|
|
377
|
+
icon: null,
|
|
378
|
+
showConfirmButton: true,
|
|
379
|
+
showCancelButton: true,
|
|
380
|
+
confirmButtonText: options?.confirmButtonText ?? "OK",
|
|
381
|
+
cancelButtonText: options?.cancelButtonText ?? "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
382
|
+
allowOutsideClick: options?.allowOutsideClick ?? false,
|
|
383
|
+
allowEscapeKey: options?.allowEscapeKey ?? true,
|
|
384
|
+
progress: null,
|
|
385
|
+
timer: null,
|
|
386
|
+
formFields: fields,
|
|
387
|
+
formValues: defaultValues,
|
|
388
|
+
formErrors: {},
|
|
389
|
+
formTouched: {},
|
|
390
|
+
formLayout: options?.layout ?? {},
|
|
391
|
+
formValidateOnChange: options?.validateOnChange ?? true,
|
|
392
|
+
formValidateOnBlur: options?.validateOnBlur ?? true
|
|
393
|
+
});
|
|
394
|
+
return __privateMethod(this, _DialogController_instances, createPromise_fn).call(this, null).then((r) => {
|
|
395
|
+
const data = __privateGet(this, _formResult);
|
|
396
|
+
__privateSet(this, _formSchema, null);
|
|
397
|
+
__privateSet(this, _formResult, null);
|
|
398
|
+
return r.isConfirmed ? data : null;
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
updateFormField(key, value) {
|
|
402
|
+
const formValues = { ...__privateGet(this, _state).formValues, [key]: value };
|
|
403
|
+
const formTouched = { ...__privateGet(this, _state).formTouched, [key]: true };
|
|
404
|
+
let formErrors = { ...__privateGet(this, _state).formErrors };
|
|
405
|
+
if (__privateGet(this, _formSchema) && __privateGet(this, _state).formValidateOnChange) {
|
|
406
|
+
formErrors = __privateMethod(this, _DialogController_instances, validateFormField_fn).call(this, key, formValues, formErrors);
|
|
407
|
+
}
|
|
408
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { formValues, formTouched, formErrors });
|
|
409
|
+
}
|
|
410
|
+
touchFormField(key) {
|
|
411
|
+
const formTouched = { ...__privateGet(this, _state).formTouched, [key]: true };
|
|
412
|
+
let formErrors = { ...__privateGet(this, _state).formErrors };
|
|
413
|
+
if (__privateGet(this, _formSchema) && __privateGet(this, _state).formValidateOnBlur) {
|
|
414
|
+
formErrors = __privateMethod(this, _DialogController_instances, validateFormField_fn).call(this, key, __privateGet(this, _state).formValues, formErrors);
|
|
415
|
+
}
|
|
416
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { formTouched, formErrors });
|
|
417
|
+
}
|
|
418
|
+
// ─── Step Form ───────────────────────────────────────────
|
|
419
|
+
showStepForm(steps, options) {
|
|
420
|
+
__privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
|
|
421
|
+
__privateSet(this, _stepFormSchemas, steps.map((s) => s.schema ?? null));
|
|
422
|
+
__privateSet(this, _stepFormResults, {});
|
|
423
|
+
const stepFormSteps = steps.map((s) => {
|
|
424
|
+
const fields = s.schema ? extractFormFields(s.schema) : [];
|
|
425
|
+
const values = {};
|
|
426
|
+
for (const f of fields) {
|
|
427
|
+
if (f.defaultValue !== void 0) values[f.key] = f.defaultValue;
|
|
428
|
+
}
|
|
429
|
+
if (s.defaultValues) Object.assign(values, s.defaultValues);
|
|
430
|
+
return {
|
|
431
|
+
key: s.key,
|
|
432
|
+
label: s.label,
|
|
433
|
+
description: s.description ?? "",
|
|
434
|
+
fields,
|
|
435
|
+
values,
|
|
436
|
+
errors: {},
|
|
437
|
+
touched: {},
|
|
438
|
+
layout: s.layout ?? {}
|
|
439
|
+
};
|
|
440
|
+
});
|
|
441
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, {
|
|
442
|
+
open: true,
|
|
443
|
+
dialogType: "step-form",
|
|
444
|
+
title: options?.title ?? "",
|
|
445
|
+
label: "",
|
|
446
|
+
description: "",
|
|
447
|
+
icon: null,
|
|
448
|
+
showConfirmButton: false,
|
|
449
|
+
showCancelButton: false,
|
|
450
|
+
allowOutsideClick: options?.allowOutsideClick ?? false,
|
|
451
|
+
allowEscapeKey: options?.allowEscapeKey ?? true,
|
|
452
|
+
progress: null,
|
|
453
|
+
timer: null,
|
|
454
|
+
stepFormSteps,
|
|
455
|
+
stepFormCurrentIndex: 0,
|
|
456
|
+
stepFormNextText: options?.nextButtonText ?? "\u6B21\u3078",
|
|
457
|
+
stepFormPrevText: options?.prevButtonText ?? "\u623B\u308B",
|
|
458
|
+
stepFormSubmitText: options?.submitButtonText ?? "OK",
|
|
459
|
+
cancelButtonText: options?.cancelButtonText ?? "\u30AD\u30E3\u30F3\u30BB\u30EB"
|
|
460
|
+
});
|
|
461
|
+
return __privateMethod(this, _DialogController_instances, createPromise_fn).call(this, null).then((r) => {
|
|
462
|
+
const data = __privateGet(this, _stepFormResults);
|
|
463
|
+
__privateSet(this, _stepFormSchemas, []);
|
|
464
|
+
__privateSet(this, _stepFormResults, {});
|
|
465
|
+
return r.isConfirmed ? data : null;
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
onStepNext() {
|
|
469
|
+
const s = __privateGet(this, _state);
|
|
470
|
+
const idx = s.stepFormCurrentIndex;
|
|
471
|
+
const step = s.stepFormSteps[idx];
|
|
472
|
+
if (!step) return;
|
|
473
|
+
const schema = __privateGet(this, _stepFormSchemas)[idx];
|
|
474
|
+
if (schema) {
|
|
475
|
+
const result = schema.safeParse(step.values);
|
|
476
|
+
if (!result.success) {
|
|
477
|
+
const errors = {};
|
|
478
|
+
for (const issue of result.error.issues) {
|
|
479
|
+
const key = issue.path[0]?.toString();
|
|
480
|
+
if (key && !errors[key]) errors[key] = issue.message;
|
|
481
|
+
}
|
|
482
|
+
const touched = {};
|
|
483
|
+
for (const f of step.fields) touched[f.key] = true;
|
|
484
|
+
__privateMethod(this, _DialogController_instances, updateCurrentStep_fn).call(this, { errors, touched });
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
__privateGet(this, _stepFormResults)[step.key] = result.data;
|
|
488
|
+
}
|
|
489
|
+
const isLast = idx === s.stepFormSteps.length - 1;
|
|
490
|
+
if (isLast) {
|
|
491
|
+
const r = { isConfirmed: true, isCanceled: false, isDismissed: false };
|
|
492
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { ...createInitialState(), open: false });
|
|
493
|
+
__privateMethod(this, _DialogController_instances, resolve_fn).call(this, r);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { stepFormCurrentIndex: idx + 1 });
|
|
497
|
+
}
|
|
498
|
+
onStepPrev() {
|
|
499
|
+
const idx = __privateGet(this, _state).stepFormCurrentIndex;
|
|
500
|
+
if (idx <= 0) return;
|
|
501
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { stepFormCurrentIndex: idx - 1 });
|
|
502
|
+
}
|
|
503
|
+
updateStepFormField(fieldKey, value) {
|
|
504
|
+
const s = __privateGet(this, _state);
|
|
505
|
+
const idx = s.stepFormCurrentIndex;
|
|
506
|
+
const step = s.stepFormSteps[idx];
|
|
507
|
+
if (!step) return;
|
|
508
|
+
const values = { ...step.values, [fieldKey]: value };
|
|
509
|
+
const touched = { ...step.touched, [fieldKey]: true };
|
|
510
|
+
let errors = { ...step.errors };
|
|
511
|
+
const schema = __privateGet(this, _stepFormSchemas)[idx];
|
|
512
|
+
if (schema && s.formValidateOnChange) {
|
|
513
|
+
errors = __privateMethod(this, _DialogController_instances, validateStepField_fn).call(this, schema, fieldKey, values, errors);
|
|
514
|
+
}
|
|
515
|
+
__privateMethod(this, _DialogController_instances, updateCurrentStep_fn).call(this, { values, touched, errors });
|
|
516
|
+
}
|
|
517
|
+
touchStepFormField(fieldKey) {
|
|
518
|
+
const s = __privateGet(this, _state);
|
|
519
|
+
const idx = s.stepFormCurrentIndex;
|
|
520
|
+
const step = s.stepFormSteps[idx];
|
|
521
|
+
if (!step) return;
|
|
522
|
+
const touched = { ...step.touched, [fieldKey]: true };
|
|
523
|
+
let errors = { ...step.errors };
|
|
524
|
+
const schema = __privateGet(this, _stepFormSchemas)[idx];
|
|
525
|
+
if (schema && s.formValidateOnBlur) {
|
|
526
|
+
errors = __privateMethod(this, _DialogController_instances, validateStepField_fn).call(this, schema, fieldKey, step.values, errors);
|
|
527
|
+
}
|
|
528
|
+
__privateMethod(this, _DialogController_instances, updateCurrentStep_fn).call(this, { touched, errors });
|
|
529
|
+
}
|
|
198
530
|
// ─── Button actions (called from the component) ──────────
|
|
199
531
|
onConfirm() {
|
|
200
532
|
__privateMethod(this, _DialogController_instances, clearTimer_fn).call(this);
|
|
533
|
+
if (__privateGet(this, _state).dialogType === "form" && __privateGet(this, _formSchema)) {
|
|
534
|
+
const result = __privateGet(this, _formSchema).safeParse(__privateGet(this, _state).formValues);
|
|
535
|
+
if (!result.success) {
|
|
536
|
+
const formErrors = {};
|
|
537
|
+
for (const issue of result.error.issues) {
|
|
538
|
+
const key = issue.path[0]?.toString();
|
|
539
|
+
if (key && !formErrors[key]) {
|
|
540
|
+
formErrors[key] = issue.message;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const formTouched = {};
|
|
544
|
+
for (const field of __privateGet(this, _state).formFields) {
|
|
545
|
+
formTouched[field.key] = true;
|
|
546
|
+
}
|
|
547
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { formErrors, formTouched });
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
__privateSet(this, _formResult, result.data);
|
|
551
|
+
}
|
|
201
552
|
const r = { isConfirmed: true, isCanceled: false, isDismissed: false };
|
|
202
553
|
__privateMethod(this, _DialogController_instances, update_fn).call(this, { ...createInitialState(), open: false });
|
|
203
554
|
__privateMethod(this, _DialogController_instances, resolve_fn).call(this, r);
|
|
@@ -221,6 +572,10 @@ _state = new WeakMap();
|
|
|
221
572
|
_listeners = new WeakMap();
|
|
222
573
|
_resolver = new WeakMap();
|
|
223
574
|
_timerId = new WeakMap();
|
|
575
|
+
_formSchema = new WeakMap();
|
|
576
|
+
_formResult = new WeakMap();
|
|
577
|
+
_stepFormSchemas = new WeakMap();
|
|
578
|
+
_stepFormResults = new WeakMap();
|
|
224
579
|
_DialogController_instances = new WeakSet();
|
|
225
580
|
emit_fn = function() {
|
|
226
581
|
const snapshot = { ...__privateGet(this, _state) };
|
|
@@ -230,6 +585,47 @@ update_fn = function(patch) {
|
|
|
230
585
|
Object.assign(__privateGet(this, _state), patch);
|
|
231
586
|
__privateMethod(this, _DialogController_instances, emit_fn).call(this);
|
|
232
587
|
};
|
|
588
|
+
validateFormField_fn = function(key, values, errors) {
|
|
589
|
+
const result = __privateGet(this, _formSchema).safeParse(values);
|
|
590
|
+
const updated = { ...errors };
|
|
591
|
+
if (result.success) {
|
|
592
|
+
delete updated[key];
|
|
593
|
+
} else {
|
|
594
|
+
const fieldIssue = result.error.issues.find(
|
|
595
|
+
(issue) => issue.path[0]?.toString() === key
|
|
596
|
+
);
|
|
597
|
+
if (fieldIssue) {
|
|
598
|
+
updated[key] = fieldIssue.message;
|
|
599
|
+
} else {
|
|
600
|
+
delete updated[key];
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return updated;
|
|
604
|
+
};
|
|
605
|
+
updateCurrentStep_fn = function(patch) {
|
|
606
|
+
const idx = __privateGet(this, _state).stepFormCurrentIndex;
|
|
607
|
+
const stepFormSteps = __privateGet(this, _state).stepFormSteps.map(
|
|
608
|
+
(st, i) => i === idx ? { ...st, ...patch } : st
|
|
609
|
+
);
|
|
610
|
+
__privateMethod(this, _DialogController_instances, update_fn).call(this, { stepFormSteps });
|
|
611
|
+
};
|
|
612
|
+
validateStepField_fn = function(schema, fieldKey, values, errors) {
|
|
613
|
+
const result = schema.safeParse(values);
|
|
614
|
+
const updated = { ...errors };
|
|
615
|
+
if (result.success) {
|
|
616
|
+
delete updated[fieldKey];
|
|
617
|
+
} else {
|
|
618
|
+
const issue = result.error.issues.find(
|
|
619
|
+
(iss) => iss.path[0]?.toString() === fieldKey
|
|
620
|
+
);
|
|
621
|
+
if (issue) {
|
|
622
|
+
updated[fieldKey] = issue.message;
|
|
623
|
+
} else {
|
|
624
|
+
delete updated[fieldKey];
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return updated;
|
|
628
|
+
};
|
|
233
629
|
// ─── Internal ────────────────────────────────────────────
|
|
234
630
|
createPromise_fn = function(timer) {
|
|
235
631
|
return new Promise((resolve) => {
|
|
@@ -266,6 +662,7 @@ updateItemStatus_fn = function(key, itemKey, status) {
|
|
|
266
662
|
// src/overlay-dialog.ts
|
|
267
663
|
import { LitElement, html, nothing } from "lit";
|
|
268
664
|
import { customElement, property, state } from "lit/decorators.js";
|
|
665
|
+
import { keyed } from "lit/directives/keyed.js";
|
|
269
666
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
270
667
|
|
|
271
668
|
// src/styles.ts
|
|
@@ -282,7 +679,7 @@ var overlayStyles = css`
|
|
|
282
679
|
--dialog-z-index: 1000;
|
|
283
680
|
--dialog-backdrop-color: rgb(255 255 255 / 0.73);
|
|
284
681
|
--dialog-backdrop-blur: 4px;
|
|
285
|
-
--dialog-transition-duration:
|
|
682
|
+
--dialog-transition-duration: 280ms;
|
|
286
683
|
|
|
287
684
|
/* Card */
|
|
288
685
|
--dialog-card-bg: #fff;
|
|
@@ -317,6 +714,24 @@ var overlayStyles = css`
|
|
|
317
714
|
--dialog-spinner-track: rgb(59 130 246 / 0.2);
|
|
318
715
|
--dialog-spinner-arc: var(--dialog-primary);
|
|
319
716
|
|
|
717
|
+
/* Form */
|
|
718
|
+
--dialog-form-width: 500px;
|
|
719
|
+
--dialog-form-max-height: 60vh;
|
|
720
|
+
--dialog-form-gap: 16px;
|
|
721
|
+
--dialog-form-columns: 1;
|
|
722
|
+
--dialog-form-label-color: #374151;
|
|
723
|
+
--dialog-form-label-size: 13px;
|
|
724
|
+
--dialog-form-label-weight: 500;
|
|
725
|
+
--dialog-form-input-bg: #fff;
|
|
726
|
+
--dialog-form-input-border: #d1d5db;
|
|
727
|
+
--dialog-form-input-border-focus: var(--dialog-primary);
|
|
728
|
+
--dialog-form-input-radius: 6px;
|
|
729
|
+
--dialog-form-input-padding: 8px 12px;
|
|
730
|
+
--dialog-form-input-font-size: 14px;
|
|
731
|
+
--dialog-form-error-color: var(--dialog-error);
|
|
732
|
+
--dialog-form-hint-color: #9ca3af;
|
|
733
|
+
--dialog-form-required-color: var(--dialog-error);
|
|
734
|
+
|
|
320
735
|
display: contents;
|
|
321
736
|
font-family: var(--dialog-font-family);
|
|
322
737
|
color: var(--dialog-text-color);
|
|
@@ -372,7 +787,6 @@ var overlayStyles = css`
|
|
|
372
787
|
min-height: var(--dialog-card-min-height);
|
|
373
788
|
position: relative;
|
|
374
789
|
overflow: hidden;
|
|
375
|
-
transition: all var(--dialog-transition-duration) ease;
|
|
376
790
|
}
|
|
377
791
|
|
|
378
792
|
@media (min-width: 640px) {
|
|
@@ -384,22 +798,99 @@ var overlayStyles = css`
|
|
|
384
798
|
}
|
|
385
799
|
}
|
|
386
800
|
|
|
801
|
+
/* ─── Card Open / Close Animations ─── */
|
|
802
|
+
|
|
803
|
+
@keyframes card-enter {
|
|
804
|
+
from {
|
|
805
|
+
opacity: 0;
|
|
806
|
+
transform: translateY(28px) scale(0.96);
|
|
807
|
+
filter: blur(6px);
|
|
808
|
+
}
|
|
809
|
+
to {
|
|
810
|
+
opacity: 1;
|
|
811
|
+
transform: translateY(0) scale(1);
|
|
812
|
+
filter: blur(0);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
@keyframes card-exit {
|
|
817
|
+
from {
|
|
818
|
+
opacity: 1;
|
|
819
|
+
transform: translateY(0) scale(1);
|
|
820
|
+
filter: blur(0);
|
|
821
|
+
}
|
|
822
|
+
to {
|
|
823
|
+
opacity: 0;
|
|
824
|
+
transform: translateY(14px) scale(0.97);
|
|
825
|
+
filter: blur(4px);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.backdrop[data-open] .card {
|
|
830
|
+
animation: card-enter 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.card[data-closing] {
|
|
834
|
+
animation: card-exit 300ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
835
|
+
pointer-events: none;
|
|
836
|
+
}
|
|
837
|
+
|
|
387
838
|
/* ─── Card Body ─── */
|
|
388
839
|
|
|
389
840
|
.card-body {
|
|
390
841
|
flex: 1;
|
|
391
842
|
display: flex;
|
|
392
843
|
flex-direction: column;
|
|
393
|
-
align-items:
|
|
844
|
+
align-items: stretch;
|
|
394
845
|
justify-content: center;
|
|
846
|
+
width: 100%;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/* ─── Body Inner (animated content wrapper) ─── */
|
|
850
|
+
|
|
851
|
+
@keyframes body-enter {
|
|
852
|
+
from {
|
|
853
|
+
opacity: 0;
|
|
854
|
+
transform: translateY(10px);
|
|
855
|
+
filter: blur(3px);
|
|
856
|
+
}
|
|
857
|
+
to {
|
|
858
|
+
opacity: 1;
|
|
859
|
+
transform: translateY(0);
|
|
860
|
+
filter: blur(0);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.body-inner {
|
|
865
|
+
display: flex;
|
|
866
|
+
flex-direction: column;
|
|
867
|
+
align-items: center;
|
|
395
868
|
gap: 16px;
|
|
396
869
|
width: 100%;
|
|
870
|
+
animation: body-enter 380ms 60ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
397
871
|
}
|
|
398
872
|
|
|
399
873
|
/* ─── Spinner ─── */
|
|
400
874
|
|
|
401
|
-
|
|
875
|
+
@keyframes spinner-enter {
|
|
876
|
+
from {
|
|
877
|
+
opacity: 0;
|
|
878
|
+
transform: scale(0.5);
|
|
879
|
+
}
|
|
880
|
+
to {
|
|
881
|
+
opacity: 1;
|
|
882
|
+
transform: scale(1);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.spinner-wrap {
|
|
402
887
|
font-size: var(--dialog-spinner-size);
|
|
888
|
+
width: 1em;
|
|
889
|
+
height: 1em;
|
|
890
|
+
animation: spinner-enter 450ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
.spinner {
|
|
403
894
|
width: 1em;
|
|
404
895
|
height: 1em;
|
|
405
896
|
border-radius: 50%;
|
|
@@ -440,6 +931,19 @@ var overlayStyles = css`
|
|
|
440
931
|
|
|
441
932
|
/* ─── Icon ─── */
|
|
442
933
|
|
|
934
|
+
@keyframes icon-enter {
|
|
935
|
+
from {
|
|
936
|
+
opacity: 0;
|
|
937
|
+
transform: scale(0.4) rotate(-12deg);
|
|
938
|
+
filter: blur(4px);
|
|
939
|
+
}
|
|
940
|
+
to {
|
|
941
|
+
opacity: 1;
|
|
942
|
+
transform: scale(1) rotate(0deg);
|
|
943
|
+
filter: blur(0);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
443
947
|
.icon-container {
|
|
444
948
|
width: 64px;
|
|
445
949
|
height: 64px;
|
|
@@ -448,6 +952,7 @@ var overlayStyles = css`
|
|
|
448
952
|
align-items: center;
|
|
449
953
|
justify-content: center;
|
|
450
954
|
flex-shrink: 0;
|
|
955
|
+
animation: icon-enter 500ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
451
956
|
}
|
|
452
957
|
|
|
453
958
|
.icon-container svg {
|
|
@@ -573,6 +1078,7 @@ var overlayStyles = css`
|
|
|
573
1078
|
gap: 8px;
|
|
574
1079
|
width: 100%;
|
|
575
1080
|
margin-top: 8px;
|
|
1081
|
+
animation: body-enter 320ms 160ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
576
1082
|
}
|
|
577
1083
|
|
|
578
1084
|
@media (min-width: 640px) {
|
|
@@ -592,7 +1098,8 @@ var overlayStyles = css`
|
|
|
592
1098
|
font-weight: 500;
|
|
593
1099
|
transition:
|
|
594
1100
|
background-color 150ms ease,
|
|
595
|
-
transform 80ms ease
|
|
1101
|
+
transform 80ms ease,
|
|
1102
|
+
box-shadow 150ms ease;
|
|
596
1103
|
min-width: 100px;
|
|
597
1104
|
text-align: center;
|
|
598
1105
|
}
|
|
@@ -608,6 +1115,7 @@ var overlayStyles = css`
|
|
|
608
1115
|
|
|
609
1116
|
.btn-confirm:hover {
|
|
610
1117
|
background-color: var(--dialog-primary-hover);
|
|
1118
|
+
box-shadow: 0 4px 12px rgb(59 130 246 / 0.35);
|
|
611
1119
|
}
|
|
612
1120
|
|
|
613
1121
|
.btn-cancel {
|
|
@@ -631,11 +1139,48 @@ var overlayStyles = css`
|
|
|
631
1139
|
list-style: none;
|
|
632
1140
|
}
|
|
633
1141
|
|
|
1142
|
+
@keyframes task-item-enter {
|
|
1143
|
+
from {
|
|
1144
|
+
opacity: 0;
|
|
1145
|
+
transform: translateX(-8px);
|
|
1146
|
+
}
|
|
1147
|
+
to {
|
|
1148
|
+
opacity: 1;
|
|
1149
|
+
transform: translateX(0);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
634
1153
|
.task-item {
|
|
635
1154
|
display: flex;
|
|
636
1155
|
align-items: center;
|
|
637
1156
|
gap: 12px;
|
|
638
1157
|
font-size: 14px;
|
|
1158
|
+
animation: task-item-enter 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
.task-item:nth-child(1) {
|
|
1162
|
+
animation-delay: 40ms;
|
|
1163
|
+
}
|
|
1164
|
+
.task-item:nth-child(2) {
|
|
1165
|
+
animation-delay: 80ms;
|
|
1166
|
+
}
|
|
1167
|
+
.task-item:nth-child(3) {
|
|
1168
|
+
animation-delay: 120ms;
|
|
1169
|
+
}
|
|
1170
|
+
.task-item:nth-child(4) {
|
|
1171
|
+
animation-delay: 160ms;
|
|
1172
|
+
}
|
|
1173
|
+
.task-item:nth-child(5) {
|
|
1174
|
+
animation-delay: 200ms;
|
|
1175
|
+
}
|
|
1176
|
+
.task-item:nth-child(6) {
|
|
1177
|
+
animation-delay: 240ms;
|
|
1178
|
+
}
|
|
1179
|
+
.task-item:nth-child(7) {
|
|
1180
|
+
animation-delay: 280ms;
|
|
1181
|
+
}
|
|
1182
|
+
.task-item:nth-child(8) {
|
|
1183
|
+
animation-delay: 320ms;
|
|
639
1184
|
}
|
|
640
1185
|
|
|
641
1186
|
.task-icon {
|
|
@@ -685,6 +1230,7 @@ var overlayStyles = css`
|
|
|
685
1230
|
|
|
686
1231
|
.task-label {
|
|
687
1232
|
color: #6b7280;
|
|
1233
|
+
transition: color 250ms ease;
|
|
688
1234
|
}
|
|
689
1235
|
|
|
690
1236
|
.task-label[data-status='active'] {
|
|
@@ -692,8 +1238,21 @@ var overlayStyles = css`
|
|
|
692
1238
|
font-weight: 500;
|
|
693
1239
|
}
|
|
694
1240
|
|
|
1241
|
+
@keyframes task-done-flash {
|
|
1242
|
+
0% {
|
|
1243
|
+
transform: translateX(0);
|
|
1244
|
+
}
|
|
1245
|
+
30% {
|
|
1246
|
+
transform: translateX(4px);
|
|
1247
|
+
}
|
|
1248
|
+
100% {
|
|
1249
|
+
transform: translateX(0);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
695
1253
|
.task-label[data-status='done'] {
|
|
696
1254
|
color: var(--dialog-success);
|
|
1255
|
+
animation: task-done-flash 350ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
697
1256
|
}
|
|
698
1257
|
|
|
699
1258
|
.task-label[data-status='error'] {
|
|
@@ -702,7 +1261,6 @@ var overlayStyles = css`
|
|
|
702
1261
|
|
|
703
1262
|
.task-label[data-status='skipped'] {
|
|
704
1263
|
color: #9ca3af;
|
|
705
|
-
text-decoration: line-through;
|
|
706
1264
|
}
|
|
707
1265
|
|
|
708
1266
|
/* ─── Queue ellipsis ─── */
|
|
@@ -738,17 +1296,54 @@ var overlayStyles = css`
|
|
|
738
1296
|
margin-bottom: 8px;
|
|
739
1297
|
}
|
|
740
1298
|
|
|
1299
|
+
@keyframes step-dot-enter {
|
|
1300
|
+
from {
|
|
1301
|
+
opacity: 0;
|
|
1302
|
+
transform: scale(0.4);
|
|
1303
|
+
}
|
|
1304
|
+
to {
|
|
1305
|
+
opacity: 1;
|
|
1306
|
+
transform: scale(1);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
@keyframes step-pulse {
|
|
1311
|
+
0% {
|
|
1312
|
+
box-shadow:
|
|
1313
|
+
0 0 0 0 rgb(59 130 246 / 0.5),
|
|
1314
|
+
0 0 0 3px rgb(59 130 246 / 0.2);
|
|
1315
|
+
}
|
|
1316
|
+
70% {
|
|
1317
|
+
box-shadow:
|
|
1318
|
+
0 0 0 7px rgb(59 130 246 / 0),
|
|
1319
|
+
0 0 0 3px rgb(59 130 246 / 0.2);
|
|
1320
|
+
}
|
|
1321
|
+
100% {
|
|
1322
|
+
box-shadow:
|
|
1323
|
+
0 0 0 0 rgb(59 130 246 / 0),
|
|
1324
|
+
0 0 0 3px rgb(59 130 246 / 0.2);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
|
|
741
1328
|
.step-dot {
|
|
742
1329
|
width: 8px;
|
|
743
1330
|
height: 8px;
|
|
744
1331
|
border-radius: 50%;
|
|
745
1332
|
background-color: #d1d5db;
|
|
746
|
-
transition:
|
|
1333
|
+
transition:
|
|
1334
|
+
background-color 250ms ease,
|
|
1335
|
+
transform 250ms cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
1336
|
+
width 250ms cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
1337
|
+
animation: step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
747
1338
|
}
|
|
748
1339
|
|
|
749
1340
|
.step-dot[data-status='active'] {
|
|
750
1341
|
background-color: var(--dialog-primary);
|
|
751
|
-
|
|
1342
|
+
width: 20px;
|
|
1343
|
+
border-radius: 4px;
|
|
1344
|
+
animation:
|
|
1345
|
+
step-dot-enter 400ms cubic-bezier(0.34, 1.56, 0.64, 1) both,
|
|
1346
|
+
step-pulse 2s 400ms infinite;
|
|
752
1347
|
}
|
|
753
1348
|
|
|
754
1349
|
.step-dot[data-status='done'] {
|
|
@@ -768,6 +1363,205 @@ var overlayStyles = css`
|
|
|
768
1363
|
max-width: 24px;
|
|
769
1364
|
height: 2px;
|
|
770
1365
|
background-color: #e5e7eb;
|
|
1366
|
+
transition: background-color 400ms ease;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
/* ─── Form ─── */
|
|
1370
|
+
|
|
1371
|
+
@media (min-width: 640px) {
|
|
1372
|
+
.card[data-type='form'] {
|
|
1373
|
+
width: var(--dialog-form-width);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
.form-scroll-container {
|
|
1378
|
+
max-height: var(--dialog-form-max-height);
|
|
1379
|
+
overflow-y: auto;
|
|
1380
|
+
width: 100%;
|
|
1381
|
+
padding: 4px 0;
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
.form-grid {
|
|
1385
|
+
display: grid;
|
|
1386
|
+
grid-template-columns: repeat(var(--dialog-form-columns, 1), 1fr);
|
|
1387
|
+
gap: var(--dialog-form-gap);
|
|
1388
|
+
width: 100%;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
@media (max-width: 639px) {
|
|
1392
|
+
.form-grid {
|
|
1393
|
+
grid-template-columns: 1fr !important;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
.form-field {
|
|
1398
|
+
display: flex;
|
|
1399
|
+
flex-direction: column;
|
|
1400
|
+
gap: 4px;
|
|
1401
|
+
text-align: left;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
.form-field[data-type='checkbox'] {
|
|
1405
|
+
grid-column: 1 / -1;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
.form-label {
|
|
1409
|
+
font-size: var(--dialog-form-label-size);
|
|
1410
|
+
font-weight: var(--dialog-form-label-weight);
|
|
1411
|
+
color: var(--dialog-form-label-color);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
.form-required {
|
|
1415
|
+
color: var(--dialog-form-required-color);
|
|
1416
|
+
margin-left: 2px;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
.form-input,
|
|
1420
|
+
.form-select {
|
|
1421
|
+
padding: var(--dialog-form-input-padding);
|
|
1422
|
+
font-size: var(--dialog-form-input-font-size);
|
|
1423
|
+
font-family: inherit;
|
|
1424
|
+
background: var(--dialog-form-input-bg);
|
|
1425
|
+
border: 1px solid var(--dialog-form-input-border);
|
|
1426
|
+
border-radius: var(--dialog-form-input-radius);
|
|
1427
|
+
color: var(--dialog-text-color);
|
|
1428
|
+
outline: none;
|
|
1429
|
+
transition:
|
|
1430
|
+
border-color 150ms ease,
|
|
1431
|
+
box-shadow 150ms ease;
|
|
1432
|
+
width: 100%;
|
|
1433
|
+
box-sizing: border-box;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
.form-input:focus,
|
|
1437
|
+
.form-select:focus {
|
|
1438
|
+
border-color: var(--dialog-form-input-border-focus);
|
|
1439
|
+
box-shadow: 0 0 0 3px rgb(59 130 246 / 0.1);
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
.form-field[data-error] .form-input,
|
|
1443
|
+
.form-field[data-error] .form-select {
|
|
1444
|
+
border-color: var(--dialog-form-error-color);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
.form-field[data-error] .form-input:focus,
|
|
1448
|
+
.form-field[data-error] .form-select:focus {
|
|
1449
|
+
box-shadow: 0 0 0 3px rgb(239 68 68 / 0.1);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
.form-error {
|
|
1453
|
+
font-size: 12px;
|
|
1454
|
+
color: var(--dialog-form-error-color);
|
|
1455
|
+
min-height: 1em;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.form-hint {
|
|
1459
|
+
font-size: 12px;
|
|
1460
|
+
color: var(--dialog-form-hint-color);
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
.form-checkbox {
|
|
1464
|
+
width: 18px;
|
|
1465
|
+
height: 18px;
|
|
1466
|
+
accent-color: var(--dialog-primary);
|
|
1467
|
+
cursor: pointer;
|
|
1468
|
+
flex-shrink: 0;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
.form-checkbox-label {
|
|
1472
|
+
display: flex;
|
|
1473
|
+
align-items: center;
|
|
1474
|
+
gap: 8px;
|
|
1475
|
+
cursor: pointer;
|
|
1476
|
+
font-size: var(--dialog-form-input-font-size);
|
|
1477
|
+
color: var(--dialog-form-label-color);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
.form-checkbox-text {
|
|
1481
|
+
font-size: var(--dialog-form-label-size);
|
|
1482
|
+
font-weight: var(--dialog-form-label-weight);
|
|
1483
|
+
color: var(--dialog-form-label-color);
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
.form-group {
|
|
1487
|
+
border: 1px solid var(--dialog-card-border);
|
|
1488
|
+
border-radius: var(--dialog-form-input-radius);
|
|
1489
|
+
padding: 16px;
|
|
1490
|
+
margin: 0 0 8px;
|
|
1491
|
+
width: 100%;
|
|
1492
|
+
box-sizing: border-box;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
.form-group-label {
|
|
1496
|
+
font-size: var(--dialog-form-label-size);
|
|
1497
|
+
font-weight: 600;
|
|
1498
|
+
color: var(--dialog-form-label-color);
|
|
1499
|
+
padding: 0 4px;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
/* ─── Step Form ─── */
|
|
1503
|
+
|
|
1504
|
+
@media (min-width: 640px) {
|
|
1505
|
+
.card[data-type='step-form'] {
|
|
1506
|
+
width: var(--dialog-form-width);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
.step-form-counter {
|
|
1511
|
+
font-size: 12px;
|
|
1512
|
+
color: var(--dialog-form-hint-color);
|
|
1513
|
+
text-align: center;
|
|
1514
|
+
margin: 0 0 4px;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
.actions-step-form {
|
|
1518
|
+
display: flex;
|
|
1519
|
+
flex-direction: row;
|
|
1520
|
+
justify-content: space-between;
|
|
1521
|
+
align-items: center;
|
|
1522
|
+
gap: 8px;
|
|
1523
|
+
margin-top: 20px;
|
|
1524
|
+
width: 100%;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
.step-form-nav {
|
|
1528
|
+
display: flex;
|
|
1529
|
+
flex-direction: row;
|
|
1530
|
+
gap: 8px;
|
|
1531
|
+
align-items: center;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
.btn-prev {
|
|
1535
|
+
padding: var(--dialog-btn-padding);
|
|
1536
|
+
font-size: var(--dialog-btn-font-size);
|
|
1537
|
+
font-family: inherit;
|
|
1538
|
+
font-weight: 500;
|
|
1539
|
+
border-radius: var(--dialog-btn-radius);
|
|
1540
|
+
cursor: pointer;
|
|
1541
|
+
border: 1px solid var(--dialog-form-input-border);
|
|
1542
|
+
background: transparent;
|
|
1543
|
+
color: var(--dialog-text-color);
|
|
1544
|
+
transition: background-color 120ms ease, border-color 120ms ease;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
.btn-prev:hover {
|
|
1548
|
+
background: #f9fafb;
|
|
1549
|
+
border-color: #9ca3af;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
.btn-prev:active {
|
|
1553
|
+
transform: scale(0.98);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
@media (max-width: 639px) {
|
|
1557
|
+
.actions-step-form {
|
|
1558
|
+
flex-direction: column-reverse;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
.step-form-nav {
|
|
1562
|
+
width: 100%;
|
|
1563
|
+
justify-content: flex-end;
|
|
1564
|
+
}
|
|
771
1565
|
}
|
|
772
1566
|
`;
|
|
773
1567
|
|
|
@@ -776,6 +1570,8 @@ var OverlayDialog = class extends LitElement {
|
|
|
776
1570
|
constructor() {
|
|
777
1571
|
super(...arguments);
|
|
778
1572
|
this._state = createInitialState();
|
|
1573
|
+
this._bodyKey = 0;
|
|
1574
|
+
this._isClosing = false;
|
|
779
1575
|
this._beforeUnloadHandler = (e) => e.preventDefault();
|
|
780
1576
|
this._onKeyDown = (e) => {
|
|
781
1577
|
if (e.key === "Escape" && this._state.open) {
|
|
@@ -789,13 +1585,27 @@ var OverlayDialog = class extends LitElement {
|
|
|
789
1585
|
this._state = { ...this.controller.state };
|
|
790
1586
|
this._unsubscribe = this.controller.subscribe((s) => {
|
|
791
1587
|
const wasOpen = this._state.open;
|
|
792
|
-
this._state
|
|
793
|
-
this.
|
|
1588
|
+
const prevDialogType = this._state.dialogType;
|
|
1589
|
+
const prevStepIndex = this._state.stepFormCurrentIndex;
|
|
794
1590
|
if (s.open && !wasOpen) {
|
|
1591
|
+
this._isClosing = false;
|
|
1592
|
+
clearTimeout(this._closeTimer);
|
|
795
1593
|
window.addEventListener("beforeunload", this._beforeUnloadHandler);
|
|
796
1594
|
} else if (!s.open && wasOpen) {
|
|
1595
|
+
this._isClosing = true;
|
|
1596
|
+
clearTimeout(this._closeTimer);
|
|
1597
|
+
this._closeTimer = setTimeout(() => {
|
|
1598
|
+
this._isClosing = false;
|
|
1599
|
+
}, 320);
|
|
797
1600
|
window.removeEventListener("beforeunload", this._beforeUnloadHandler);
|
|
798
1601
|
}
|
|
1602
|
+
if (s.open && s.dialogType !== prevDialogType) {
|
|
1603
|
+
this._bodyKey++;
|
|
1604
|
+
} else if (s.open && s.dialogType === "step-form" && s.stepFormCurrentIndex !== prevStepIndex) {
|
|
1605
|
+
this._bodyKey++;
|
|
1606
|
+
}
|
|
1607
|
+
this._state = s;
|
|
1608
|
+
this._syncBodyScroll(s.open);
|
|
799
1609
|
});
|
|
800
1610
|
}
|
|
801
1611
|
window.addEventListener("keydown", this._onKeyDown);
|
|
@@ -804,6 +1614,7 @@ var OverlayDialog = class extends LitElement {
|
|
|
804
1614
|
super.disconnectedCallback();
|
|
805
1615
|
this._unsubscribe?.();
|
|
806
1616
|
this._syncBodyScroll(false);
|
|
1617
|
+
clearTimeout(this._closeTimer);
|
|
807
1618
|
window.removeEventListener("beforeunload", this._beforeUnloadHandler);
|
|
808
1619
|
window.removeEventListener("keydown", this._onKeyDown);
|
|
809
1620
|
}
|
|
@@ -879,9 +1690,11 @@ var OverlayDialog = class extends LitElement {
|
|
|
879
1690
|
}
|
|
880
1691
|
_renderSpinner() {
|
|
881
1692
|
return html`
|
|
882
|
-
<div class="spinner">
|
|
883
|
-
<div class="spinner
|
|
884
|
-
<div class="spinner-
|
|
1693
|
+
<div class="spinner-wrap">
|
|
1694
|
+
<div class="spinner">
|
|
1695
|
+
<div class="spinner-half">
|
|
1696
|
+
<div class="spinner-inner"></div>
|
|
1697
|
+
</div>
|
|
885
1698
|
</div>
|
|
886
1699
|
</div>
|
|
887
1700
|
`;
|
|
@@ -1019,6 +1832,187 @@ var OverlayDialog = class extends LitElement {
|
|
|
1019
1832
|
</ul>
|
|
1020
1833
|
`;
|
|
1021
1834
|
}
|
|
1835
|
+
// ─── Form Helpers ────────────────────────────────────────
|
|
1836
|
+
_createFormContext() {
|
|
1837
|
+
const s = this._state;
|
|
1838
|
+
return {
|
|
1839
|
+
getValue: (k) => s.formValues[k],
|
|
1840
|
+
getError: (k) => s.formErrors[k] ?? "",
|
|
1841
|
+
getTouched: (k) => !!s.formTouched[k],
|
|
1842
|
+
onUpdate: (k, v) => this.controller.updateFormField(k, v),
|
|
1843
|
+
onBlur: (k) => this.controller.touchFormField(k)
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
_createStepFormContext() {
|
|
1847
|
+
const s = this._state;
|
|
1848
|
+
const step = s.stepFormSteps[s.stepFormCurrentIndex];
|
|
1849
|
+
return {
|
|
1850
|
+
getValue: (k) => step?.values[k],
|
|
1851
|
+
getError: (k) => step?.errors[k] ?? "",
|
|
1852
|
+
getTouched: (k) => !!step?.touched[k],
|
|
1853
|
+
onUpdate: (k, v) => this.controller.updateStepFormField(k, v),
|
|
1854
|
+
onBlur: (k) => this.controller.touchStepFormField(k)
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
_getOrderedFields(fields, layout) {
|
|
1858
|
+
const order = layout.fieldOrder;
|
|
1859
|
+
if (!order?.length) return fields;
|
|
1860
|
+
const fieldMap = new Map(fields.map((f) => [f.key, f]));
|
|
1861
|
+
const ordered = [];
|
|
1862
|
+
for (const key of order) {
|
|
1863
|
+
const f = fieldMap.get(key);
|
|
1864
|
+
if (f) {
|
|
1865
|
+
ordered.push(f);
|
|
1866
|
+
fieldMap.delete(key);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
for (const f of fieldMap.values()) {
|
|
1870
|
+
ordered.push(f);
|
|
1871
|
+
}
|
|
1872
|
+
return ordered;
|
|
1873
|
+
}
|
|
1874
|
+
_renderFormGrid(fields, columns, gap, ctx) {
|
|
1875
|
+
return html`
|
|
1876
|
+
<div class="form-grid" style="--dialog-form-columns:${columns}; gap:${gap}">
|
|
1877
|
+
${fields.map((f) => this._renderFormField(f, ctx))}
|
|
1878
|
+
</div>
|
|
1879
|
+
`;
|
|
1880
|
+
}
|
|
1881
|
+
_renderGroupedForm(allFields, groups, layout, ctx) {
|
|
1882
|
+
const fieldMap = new Map(allFields.map((f) => [f.key, f]));
|
|
1883
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
1884
|
+
const gap = layout.gap ?? "16px";
|
|
1885
|
+
const groupFragments = groups.map((group) => {
|
|
1886
|
+
const groupFields = [];
|
|
1887
|
+
for (const key of group.fields) {
|
|
1888
|
+
const f = fieldMap.get(key);
|
|
1889
|
+
if (f) {
|
|
1890
|
+
groupFields.push(f);
|
|
1891
|
+
usedKeys.add(key);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
if (!groupFields.length) return nothing;
|
|
1895
|
+
const cols = group.columns ?? layout.columns ?? 1;
|
|
1896
|
+
return html`
|
|
1897
|
+
<fieldset class="form-group">
|
|
1898
|
+
${group.label ? html`<legend class="form-group-label">${group.label}</legend>` : nothing}
|
|
1899
|
+
${this._renderFormGrid(groupFields, cols, gap, ctx)}
|
|
1900
|
+
</fieldset>
|
|
1901
|
+
`;
|
|
1902
|
+
});
|
|
1903
|
+
const remaining = allFields.filter((f) => !usedKeys.has(f.key));
|
|
1904
|
+
return html`
|
|
1905
|
+
${groupFragments}
|
|
1906
|
+
${remaining.length ? this._renderFormGrid(remaining, layout.columns ?? 1, gap, ctx) : nothing}
|
|
1907
|
+
`;
|
|
1908
|
+
}
|
|
1909
|
+
_renderForm(fields, layout, ctx) {
|
|
1910
|
+
const ordered = this._getOrderedFields(fields, layout);
|
|
1911
|
+
const gap = layout.gap ?? "16px";
|
|
1912
|
+
if (layout.groups?.length) {
|
|
1913
|
+
return this._renderGroupedForm(ordered, layout.groups, layout, ctx);
|
|
1914
|
+
}
|
|
1915
|
+
return this._renderFormGrid(ordered, layout.columns ?? 1, gap, ctx);
|
|
1916
|
+
}
|
|
1917
|
+
_renderFormField(field, ctx) {
|
|
1918
|
+
const value = ctx.getValue(field.key);
|
|
1919
|
+
const error = ctx.getError(field.key);
|
|
1920
|
+
const touched = ctx.getTouched(field.key);
|
|
1921
|
+
const showError = touched && !!error;
|
|
1922
|
+
if (field.inputType === "checkbox") {
|
|
1923
|
+
return html`
|
|
1924
|
+
<div class="form-field" data-type="checkbox" ?data-error=${showError}>
|
|
1925
|
+
<label class="form-checkbox-label">
|
|
1926
|
+
<input
|
|
1927
|
+
type="checkbox"
|
|
1928
|
+
class="form-checkbox"
|
|
1929
|
+
.checked=${!!value}
|
|
1930
|
+
@change=${(e) => ctx.onUpdate(field.key, e.target.checked)}
|
|
1931
|
+
@blur=${() => ctx.onBlur(field.key)}
|
|
1932
|
+
/>
|
|
1933
|
+
<span class="form-checkbox-text">
|
|
1934
|
+
${field.label}
|
|
1935
|
+
${field.required ? html`<span class="form-required">*</span>` : nothing}
|
|
1936
|
+
</span>
|
|
1937
|
+
</label>
|
|
1938
|
+
${showError ? html`<span class="form-error">${error}</span>` : nothing}
|
|
1939
|
+
</div>
|
|
1940
|
+
`;
|
|
1941
|
+
}
|
|
1942
|
+
return html`
|
|
1943
|
+
<div class="form-field" data-type=${field.inputType} ?data-error=${showError}>
|
|
1944
|
+
<label class="form-label" for="form-${field.key}">
|
|
1945
|
+
${field.label} ${field.required ? html`<span class="form-required">*</span>` : nothing}
|
|
1946
|
+
</label>
|
|
1947
|
+
${field.description ? html`<span class="form-hint">${field.description}</span>` : nothing}
|
|
1948
|
+
${this._renderFormInput(field, value, ctx)}
|
|
1949
|
+
${showError ? html`<span class="form-error">${error}</span>` : nothing}
|
|
1950
|
+
</div>
|
|
1951
|
+
`;
|
|
1952
|
+
}
|
|
1953
|
+
_renderFormInput(field, value, ctx) {
|
|
1954
|
+
switch (field.inputType) {
|
|
1955
|
+
case "select":
|
|
1956
|
+
return html`
|
|
1957
|
+
<select
|
|
1958
|
+
class="form-select"
|
|
1959
|
+
id="form-${field.key}"
|
|
1960
|
+
@change=${(e) => ctx.onUpdate(field.key, e.target.value)}
|
|
1961
|
+
@blur=${() => ctx.onBlur(field.key)}
|
|
1962
|
+
>
|
|
1963
|
+
<option value="" ?selected=${!value}>選択してください</option>
|
|
1964
|
+
${field.options.map(
|
|
1965
|
+
(opt) => html`<option value=${opt} ?selected=${value === opt}>${opt}</option>`
|
|
1966
|
+
)}
|
|
1967
|
+
</select>
|
|
1968
|
+
`;
|
|
1969
|
+
case "number":
|
|
1970
|
+
return html`
|
|
1971
|
+
<input
|
|
1972
|
+
type="number"
|
|
1973
|
+
class="form-input"
|
|
1974
|
+
id="form-${field.key}"
|
|
1975
|
+
.value=${value != null ? String(value) : ""}
|
|
1976
|
+
min=${field.min ?? nothing}
|
|
1977
|
+
max=${field.max ?? nothing}
|
|
1978
|
+
placeholder=${field.placeholder || nothing}
|
|
1979
|
+
@input=${(e) => {
|
|
1980
|
+
const v = e.target.valueAsNumber;
|
|
1981
|
+
ctx.onUpdate(field.key, Number.isNaN(v) ? void 0 : v);
|
|
1982
|
+
}}
|
|
1983
|
+
@blur=${() => ctx.onBlur(field.key)}
|
|
1984
|
+
/>
|
|
1985
|
+
`;
|
|
1986
|
+
case "date":
|
|
1987
|
+
return html`
|
|
1988
|
+
<input
|
|
1989
|
+
type="date"
|
|
1990
|
+
class="form-input"
|
|
1991
|
+
id="form-${field.key}"
|
|
1992
|
+
.value=${value != null ? String(value) : ""}
|
|
1993
|
+
@input=${(e) => {
|
|
1994
|
+
const str = e.target.value;
|
|
1995
|
+
ctx.onUpdate(field.key, str || void 0);
|
|
1996
|
+
}}
|
|
1997
|
+
@blur=${() => ctx.onBlur(field.key)}
|
|
1998
|
+
/>
|
|
1999
|
+
`;
|
|
2000
|
+
default:
|
|
2001
|
+
return html`
|
|
2002
|
+
<input
|
|
2003
|
+
type=${field.inputType}
|
|
2004
|
+
class="form-input"
|
|
2005
|
+
id="form-${field.key}"
|
|
2006
|
+
.value=${value ?? ""}
|
|
2007
|
+
minlength=${field.minLength ?? nothing}
|
|
2008
|
+
maxlength=${field.maxLength ?? nothing}
|
|
2009
|
+
placeholder=${field.placeholder || nothing}
|
|
2010
|
+
@input=${(e) => ctx.onUpdate(field.key, e.target.value)}
|
|
2011
|
+
@blur=${() => ctx.onBlur(field.key)}
|
|
2012
|
+
/>
|
|
2013
|
+
`;
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
1022
2016
|
_renderButtons() {
|
|
1023
2017
|
const s = this._state;
|
|
1024
2018
|
if (!s.showConfirmButton && !s.showCancelButton) return nothing;
|
|
@@ -1033,6 +2027,39 @@ var OverlayDialog = class extends LitElement {
|
|
|
1033
2027
|
</div>
|
|
1034
2028
|
`;
|
|
1035
2029
|
}
|
|
2030
|
+
// ─── Step Form Helpers ───────────────────────────────────
|
|
2031
|
+
_renderStepFormButtons() {
|
|
2032
|
+
const s = this._state;
|
|
2033
|
+
const isFirst = s.stepFormCurrentIndex === 0;
|
|
2034
|
+
const isLast = s.stepFormCurrentIndex === s.stepFormSteps.length - 1;
|
|
2035
|
+
const submitText = isLast ? s.stepFormSubmitText : s.stepFormNextText;
|
|
2036
|
+
return html`
|
|
2037
|
+
<div class="actions actions-step-form">
|
|
2038
|
+
<button class="btn btn-cancel" @click=${() => this.controller.onCancel()}>
|
|
2039
|
+
${s.cancelButtonText}
|
|
2040
|
+
</button>
|
|
2041
|
+
<div class="step-form-nav">
|
|
2042
|
+
${isFirst ? nothing : html`
|
|
2043
|
+
<button class="btn btn-prev" @click=${() => this.controller.onStepPrev()}>
|
|
2044
|
+
${s.stepFormPrevText}
|
|
2045
|
+
</button>
|
|
2046
|
+
`}
|
|
2047
|
+
<button class="btn btn-confirm" @click=${() => this.controller.onStepNext()}>
|
|
2048
|
+
${submitText}
|
|
2049
|
+
</button>
|
|
2050
|
+
</div>
|
|
2051
|
+
</div>
|
|
2052
|
+
`;
|
|
2053
|
+
}
|
|
2054
|
+
_deriveStepItems() {
|
|
2055
|
+
const s = this._state;
|
|
2056
|
+
return s.stepFormSteps.map((st, i) => {
|
|
2057
|
+
let status = "pending";
|
|
2058
|
+
if (i < s.stepFormCurrentIndex) status = "done";
|
|
2059
|
+
else if (i === s.stepFormCurrentIndex) status = "active";
|
|
2060
|
+
return { key: st.key, label: st.label, status };
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
1036
2063
|
_renderBody() {
|
|
1037
2064
|
const s = this._state;
|
|
1038
2065
|
switch (s.dialogType) {
|
|
@@ -1059,18 +2086,51 @@ var OverlayDialog = class extends LitElement {
|
|
|
1059
2086
|
${s.label ? html`<p class="label">${s.label}</p>` : nothing}
|
|
1060
2087
|
${this._renderStepsList(s.steps)}
|
|
1061
2088
|
`;
|
|
2089
|
+
case "form": {
|
|
2090
|
+
const ctx = this._createFormContext();
|
|
2091
|
+
return html`
|
|
2092
|
+
${s.title ? html`<p class="label">${s.title}</p>` : nothing}
|
|
2093
|
+
${s.description ? html`<p class="description">${s.description}</p>` : nothing}
|
|
2094
|
+
<div class="form-scroll-container">
|
|
2095
|
+
${this._renderForm(s.formFields, s.formLayout, ctx)}
|
|
2096
|
+
</div>
|
|
2097
|
+
${this._renderButtons()}
|
|
2098
|
+
`;
|
|
2099
|
+
}
|
|
2100
|
+
case "step-form": {
|
|
2101
|
+
const stepItems = this._deriveStepItems();
|
|
2102
|
+
const currentStep = s.stepFormSteps[s.stepFormCurrentIndex];
|
|
2103
|
+
if (!currentStep) return html`${nothing}`;
|
|
2104
|
+
const ctx = this._createStepFormContext();
|
|
2105
|
+
const stepCount = s.stepFormSteps.length;
|
|
2106
|
+
const counterText = `${s.stepFormCurrentIndex + 1} / ${stepCount}`;
|
|
2107
|
+
return html`
|
|
2108
|
+
${this._renderStepsHeader(stepItems)}
|
|
2109
|
+
<p class="step-form-counter">${counterText}</p>
|
|
2110
|
+
<p class="label">${currentStep.label}</p>
|
|
2111
|
+
${currentStep.description ? html`<p class="description">${currentStep.description}</p>` : nothing}
|
|
2112
|
+
${currentStep.fields.length ? html`
|
|
2113
|
+
<div class="form-scroll-container">
|
|
2114
|
+
${this._renderForm(currentStep.fields, currentStep.layout, ctx)}
|
|
2115
|
+
</div>
|
|
2116
|
+
` : nothing}
|
|
2117
|
+
${this._renderStepFormButtons()}
|
|
2118
|
+
`;
|
|
2119
|
+
}
|
|
1062
2120
|
default:
|
|
1063
2121
|
return html`${nothing}`;
|
|
1064
2122
|
}
|
|
1065
2123
|
}
|
|
1066
2124
|
render() {
|
|
1067
2125
|
const s = this._state;
|
|
1068
|
-
const showHeaderTitle = s.title && s.dialogType !== "alert" && s.dialogType !== "confirm";
|
|
2126
|
+
const showHeaderTitle = s.title && s.dialogType !== "alert" && s.dialogType !== "confirm" && s.dialogType !== "form" && s.dialogType !== "step-form";
|
|
1069
2127
|
return html`
|
|
1070
2128
|
<div class="backdrop" ?data-open=${s.open} @click=${this._onBackdropClick}>
|
|
1071
|
-
<div class="card">
|
|
2129
|
+
<div class="card" data-type=${s.dialogType} ?data-closing=${this._isClosing}>
|
|
1072
2130
|
${showHeaderTitle ? html`<p class="dialog-title">${s.title}</p>` : nothing}
|
|
1073
|
-
<div class="card-body"
|
|
2131
|
+
<div class="card-body">
|
|
2132
|
+
${keyed(this._bodyKey, html`<div class="body-inner">${this._renderBody()}</div>`)}
|
|
2133
|
+
</div>
|
|
1074
2134
|
<div
|
|
1075
2135
|
class="progress-bar"
|
|
1076
2136
|
style="width:${s.progress ?? 0}%;opacity:${s.progress !== null ? 1 : 0}"
|
|
@@ -1087,6 +2147,12 @@ __decorateClass([
|
|
|
1087
2147
|
__decorateClass([
|
|
1088
2148
|
state()
|
|
1089
2149
|
], OverlayDialog.prototype, "_state", 2);
|
|
2150
|
+
__decorateClass([
|
|
2151
|
+
state()
|
|
2152
|
+
], OverlayDialog.prototype, "_bodyKey", 2);
|
|
2153
|
+
__decorateClass([
|
|
2154
|
+
state()
|
|
2155
|
+
], OverlayDialog.prototype, "_isClosing", 2);
|
|
1090
2156
|
OverlayDialog = __decorateClass([
|
|
1091
2157
|
customElement("overlay-dialog")
|
|
1092
2158
|
], OverlayDialog);
|
|
@@ -1116,6 +2182,28 @@ var DialogSingleton = class {
|
|
|
1116
2182
|
__privateMethod(this, _DialogSingleton_instances, ensureElement_fn).call(this);
|
|
1117
2183
|
return __privateGet(this, _controller).confirm(optionsOrLabel);
|
|
1118
2184
|
}
|
|
2185
|
+
// ─── Form ──────────────────────────────────────────────────
|
|
2186
|
+
form(schema, options) {
|
|
2187
|
+
__privateMethod(this, _DialogSingleton_instances, ensureElement_fn).call(this);
|
|
2188
|
+
return __privateGet(this, _controller).form(schema, options);
|
|
2189
|
+
}
|
|
2190
|
+
// ─── Step Form ─────────────────────────────────────────────
|
|
2191
|
+
showStepForm(steps, options) {
|
|
2192
|
+
__privateMethod(this, _DialogSingleton_instances, ensureElement_fn).call(this);
|
|
2193
|
+
return __privateGet(this, _controller).showStepForm(steps, options);
|
|
2194
|
+
}
|
|
2195
|
+
onStepNext() {
|
|
2196
|
+
__privateGet(this, _controller).onStepNext();
|
|
2197
|
+
}
|
|
2198
|
+
onStepPrev() {
|
|
2199
|
+
__privateGet(this, _controller).onStepPrev();
|
|
2200
|
+
}
|
|
2201
|
+
updateStepFormField(fieldKey, value) {
|
|
2202
|
+
__privateGet(this, _controller).updateStepFormField(fieldKey, value);
|
|
2203
|
+
}
|
|
2204
|
+
touchStepFormField(fieldKey) {
|
|
2205
|
+
__privateGet(this, _controller).touchStepFormField(fieldKey);
|
|
2206
|
+
}
|
|
1119
2207
|
// ─── Loading helpers ─────────────────────────────────────
|
|
1120
2208
|
showLoading(label) {
|
|
1121
2209
|
__privateMethod(this, _DialogSingleton_instances, ensureElement_fn).call(this);
|