commons-shared-web-ui 0.0.27 → 0.0.28
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/index.d.ts
CHANGED
|
@@ -58,6 +58,12 @@ interface FormSchema {
|
|
|
58
58
|
metadata?: {
|
|
59
59
|
[key: string]: any;
|
|
60
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* When true, top-level GROUP children of sectionConfig are rendered as
|
|
63
|
+
* a horizontal stepper at the top, showing one section at a time.
|
|
64
|
+
* Navigate between sections via the Next/Previous buttons in the host app.
|
|
65
|
+
*/
|
|
66
|
+
sectionStepper?: boolean;
|
|
61
67
|
sectionConfig?: SectionConfig;
|
|
62
68
|
stepperConfig?: StepperConfig;
|
|
63
69
|
submitConfig?: SubmitConfig;
|
|
@@ -1087,6 +1093,15 @@ declare class SmartFormComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
1087
1093
|
fileAdded: EventEmitter<any>;
|
|
1088
1094
|
fileUploadFinished: EventEmitter<any>;
|
|
1089
1095
|
fileRemoved: EventEmitter<any>;
|
|
1096
|
+
/** Emitted whenever the active section step changes. Carries current state so the
|
|
1097
|
+
* host can show/hide Previous/Next/Submit buttons in its own footer. */
|
|
1098
|
+
stepChange: EventEmitter<{
|
|
1099
|
+
currentStep: number;
|
|
1100
|
+
totalSteps: number;
|
|
1101
|
+
isFirst: boolean;
|
|
1102
|
+
isLast: boolean;
|
|
1103
|
+
stepLabel: string;
|
|
1104
|
+
}>;
|
|
1090
1105
|
formSchema: FormSchema;
|
|
1091
1106
|
formGroup: FormGroup;
|
|
1092
1107
|
fieldList: FieldConfig[];
|
|
@@ -1094,9 +1109,27 @@ declare class SmartFormComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
1094
1109
|
currentStep: number;
|
|
1095
1110
|
isLoading: boolean;
|
|
1096
1111
|
isDraftLoading: boolean;
|
|
1112
|
+
/** True when sectionStepper mode is active (SECTION form with top-level GROUPs as steps). */
|
|
1113
|
+
isSectionStepper: boolean;
|
|
1114
|
+
/** Index of the currently visible section step. */
|
|
1115
|
+
currentSectionStep: number;
|
|
1116
|
+
/** Flat list of top-level GROUP FieldConfigs that become the stepper steps. */
|
|
1117
|
+
sectionSteps: FieldConfig[];
|
|
1118
|
+
/** Validation state per section step — drives badge colour/icon. */
|
|
1119
|
+
stepValidationStates: ('untouched' | 'valid' | 'warning')[];
|
|
1120
|
+
/** Flat field-name lists per step used for targeted validation. */
|
|
1121
|
+
private stepFieldNames;
|
|
1122
|
+
/** Controls skeleton visibility. Stays false until schema is parsed AND
|
|
1123
|
+
* any EDIT-mode data fetch completes, but always shows for at least
|
|
1124
|
+
* SKELETON_MIN_MS so the animation is visible even on fast loads. */
|
|
1125
|
+
isFormReady: boolean;
|
|
1126
|
+
private readonly SKELETON_MIN_MS;
|
|
1127
|
+
private _skeletonStart;
|
|
1097
1128
|
constructor(fb: FormBuilder, controller: SmartFormController, expressionService: ExpressionService, http: HttpClient, snackbarService: SnackbarService, router: Router);
|
|
1098
1129
|
ngOnInit(): void;
|
|
1099
1130
|
loadEditData(): void;
|
|
1131
|
+
/** Flips isFormReady=true after the skeleton has been visible for at least SKELETON_MIN_MS. */
|
|
1132
|
+
private _markReady;
|
|
1100
1133
|
ngOnChanges(changes: SimpleChanges): void;
|
|
1101
1134
|
ngOnDestroy(): void;
|
|
1102
1135
|
parseFormJson(): void;
|
|
@@ -1133,6 +1166,25 @@ declare class SmartFormComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
1133
1166
|
get canGoNext(): boolean;
|
|
1134
1167
|
get canGoPrevious(): boolean;
|
|
1135
1168
|
get currentStepConfig(): FieldConfig | undefined;
|
|
1169
|
+
/** Advance to the next section step. Called by the host footer "Next" button.
|
|
1170
|
+
* Validates the current step first — marks it valid (green) or warning (orange). */
|
|
1171
|
+
navigateToNext(): void;
|
|
1172
|
+
/** Go back to the previous section step. Called by the host footer "Previous" button. */
|
|
1173
|
+
navigateToPrevious(): void;
|
|
1174
|
+
/** Jump directly to a specific section step by index.
|
|
1175
|
+
* Validates the step being left so the badge state updates correctly. */
|
|
1176
|
+
goToSectionStep(index: number): void;
|
|
1177
|
+
get isSectionStepFirst(): boolean;
|
|
1178
|
+
get isSectionStepLast(): boolean;
|
|
1179
|
+
/** Returns the SectionConfig for a given step — passed to lib-form-section.
|
|
1180
|
+
* The outer label is intentionally omitted because the stepper nav already
|
|
1181
|
+
* displays it; showing it again inside the content would be redundant. */
|
|
1182
|
+
getSectionStepConfig(step: FieldConfig): any;
|
|
1183
|
+
private _emitStepChange;
|
|
1184
|
+
/** Marks all controls in the given step as touched and records valid/warning state. */
|
|
1185
|
+
private _validateStep;
|
|
1186
|
+
/** Recursively collects all leaf field names from a set of FieldConfigs. */
|
|
1187
|
+
private _collectFieldNames;
|
|
1136
1188
|
get nextLabel(): string;
|
|
1137
1189
|
get submitLabel(): string;
|
|
1138
1190
|
get previousLabel(): string;
|
|
@@ -1146,7 +1198,7 @@ declare class SmartFormComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
1146
1198
|
private getButtonByActionKind;
|
|
1147
1199
|
private navigateTo;
|
|
1148
1200
|
static ɵfac: i0.ɵɵFactoryDeclaration<SmartFormComponent, never>;
|
|
1149
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SmartFormComponent, "lib-smart-form", never, { "formJson": { "alias": "formJson"; "required": false; }; "initialValues": { "alias": "initialValues"; "required": false; }; "enableDraftAutoSave": { "alias": "enableDraftAutoSave"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; }, { "submit": "submit"; "draftSave": "draftSave"; "actionClick": "actionClick"; "valueChange": "valueChange"; "fileAdded": "fileAdded"; "fileUploadFinished": "fileUploadFinished"; "fileRemoved": "fileRemoved"; }, never, never, false, never>;
|
|
1201
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SmartFormComponent, "lib-smart-form", never, { "formJson": { "alias": "formJson"; "required": false; }; "initialValues": { "alias": "initialValues"; "required": false; }; "enableDraftAutoSave": { "alias": "enableDraftAutoSave"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; }, { "submit": "submit"; "draftSave": "draftSave"; "actionClick": "actionClick"; "valueChange": "valueChange"; "fileAdded": "fileAdded"; "fileUploadFinished": "fileUploadFinished"; "fileRemoved": "fileRemoved"; "stepChange": "stepChange"; }, never, never, false, never>;
|
|
1150
1202
|
}
|
|
1151
1203
|
|
|
1152
1204
|
declare class FormSectionComponent implements OnInit, OnDestroy {
|
|
@@ -1159,6 +1211,8 @@ declare class FormSectionComponent implements OnInit, OnDestroy {
|
|
|
1159
1211
|
* Each element is a FormGroup representing one repeater instance.
|
|
1160
1212
|
*/
|
|
1161
1213
|
repeaterFormArray: FormArray;
|
|
1214
|
+
/** Tracks which accordion panels are open (by index). New instances start expanded. */
|
|
1215
|
+
expandedInstances: Set<number>;
|
|
1162
1216
|
/**
|
|
1163
1217
|
* The key under which the FormArray is registered in the root formGroup.
|
|
1164
1218
|
* Falls back to config.name or a generated key.
|
|
@@ -1171,6 +1225,8 @@ declare class FormSectionComponent implements OnInit, OnDestroy {
|
|
|
1171
1225
|
private createInstanceGroup;
|
|
1172
1226
|
addInstance(): void;
|
|
1173
1227
|
removeInstance(index: number): void;
|
|
1228
|
+
toggleInstance(index: number): void;
|
|
1229
|
+
isExpanded(index: number): boolean;
|
|
1174
1230
|
getInstanceGroup(index: number): FormGroup;
|
|
1175
1231
|
get instanceGroups(): FormGroup[];
|
|
1176
1232
|
/** For non-allowMulti sections we simply pass the root formGroup down */
|
|
@@ -1262,6 +1318,8 @@ declare class FormFieldComponent implements OnInit, OnDestroy {
|
|
|
1262
1318
|
isExpanded?: boolean;
|
|
1263
1319
|
}[];
|
|
1264
1320
|
private _nextInstanceId;
|
|
1321
|
+
/** Tracks open accordion panels for standard (non-multiSave) GROUP repeaters. */
|
|
1322
|
+
expandedGroupInstances: Set<number>;
|
|
1265
1323
|
/**
|
|
1266
1324
|
* Key used to register the GROUP control on the parent formGroup.
|
|
1267
1325
|
* Priority: sectionConfig.name > field.name > camelCase(label) > '__group__'
|
|
@@ -1283,6 +1341,8 @@ declare class FormFieldComponent implements OnInit, OnDestroy {
|
|
|
1283
1341
|
editGroupInstance(index: number): void;
|
|
1284
1342
|
toggleExpandGroupInstance(index: number): void;
|
|
1285
1343
|
removeGroupInstance(index: number, force?: boolean): void;
|
|
1344
|
+
toggleGroupAccordion(index: number): void;
|
|
1345
|
+
isGroupExpanded(index: number): boolean;
|
|
1286
1346
|
trackByInstanceId(_: number, item: {
|
|
1287
1347
|
id: number;
|
|
1288
1348
|
fg: FormGroup;
|
package/package.json
CHANGED
|
@@ -14,6 +14,9 @@ $default-smart-form-config: (
|
|
|
14
14
|
font-family: ('Inter', 'Segoe UI', sans-serif),
|
|
15
15
|
font-size-base: 0.875rem,
|
|
16
16
|
|
|
17
|
+
// ── Accent colour (flows from app primary; replaces hard-coded blue) ────────
|
|
18
|
+
accent-color: #3B82F6,
|
|
19
|
+
|
|
17
20
|
// ── Form container ──────────────────────────────────────────────────────────
|
|
18
21
|
form-bg: #ffffff,
|
|
19
22
|
form-padding: 24px,
|
|
@@ -21,6 +24,7 @@ $default-smart-form-config: (
|
|
|
21
24
|
form-border: none,
|
|
22
25
|
form-shadow: 0 1px 3px rgba(0, 0, 0, 0.06),
|
|
23
26
|
form-max-width: 1200px,
|
|
27
|
+
form-section-gap: 24px,
|
|
24
28
|
|
|
25
29
|
// ── Form header (title + description) ──────────────────────────────────────
|
|
26
30
|
form-title-size: 1.5rem,
|
|
@@ -29,7 +33,7 @@ $default-smart-form-config: (
|
|
|
29
33
|
form-desc-size: 0.875rem,
|
|
30
34
|
form-desc-color: #6B7280,
|
|
31
35
|
|
|
32
|
-
// ── Section / GROUP card
|
|
36
|
+
// ── Section / GROUP — flat layout (no card shell) ───────────────────────────
|
|
33
37
|
section-bg: #ffffff,
|
|
34
38
|
section-border: 1px solid #E5E7EB,
|
|
35
39
|
section-radius: 10px,
|
|
@@ -42,6 +46,19 @@ $default-smart-form-config: (
|
|
|
42
46
|
section-label-color: #1F2937,
|
|
43
47
|
section-label-border: 2px solid #E5E7EB,
|
|
44
48
|
|
|
49
|
+
// ── Section heading left-accent bar ─────────────────────────────────────────
|
|
50
|
+
section-header-accent-width: 4px,
|
|
51
|
+
section-header-accent-color: #3B82F6,
|
|
52
|
+
section-header-bg: #F9FAFB,
|
|
53
|
+
|
|
54
|
+
// ── Repeater accordion ──────────────────────────────────────────────────────
|
|
55
|
+
repeater-accordion-header-bg: #F9FAFB,
|
|
56
|
+
repeater-accordion-header-color: #1F2937,
|
|
57
|
+
repeater-accordion-active-bg: #EFF6FF,
|
|
58
|
+
repeater-badge-bg: #E5E7EB,
|
|
59
|
+
repeater-badge-color: #374151,
|
|
60
|
+
section-border-radius-inner: 8px,
|
|
61
|
+
|
|
45
62
|
// ── GROUP repeater instance card ────────────────────────────────────────────
|
|
46
63
|
instance-bg: #F9FAFB,
|
|
47
64
|
instance-border: 1px solid #E5E7EB,
|
|
@@ -51,8 +68,13 @@ $default-smart-form-config: (
|
|
|
51
68
|
instance-num-color: #4B5563,
|
|
52
69
|
instance-num-size: 0.8125rem,
|
|
53
70
|
|
|
54
|
-
// ── Grid gap
|
|
71
|
+
// ── Grid gap + field gap ─────────────────────────────────────────────────────
|
|
55
72
|
grid-gap: 16px,
|
|
73
|
+
field-gap: 6px,
|
|
74
|
+
|
|
75
|
+
// ── Focus ring ──────────────────────────────────────────────────────────────
|
|
76
|
+
focus-ring-width: 3px,
|
|
77
|
+
focus-ring-offset: 0,
|
|
56
78
|
|
|
57
79
|
// ── Field label ─────────────────────────────────────────────────────────────
|
|
58
80
|
label-size: 0.875rem,
|
|
@@ -119,7 +141,7 @@ $default-smart-form-config: (
|
|
|
119
141
|
generated-padding: 0.625rem 0.875rem,
|
|
120
142
|
|
|
121
143
|
// ── File upload drop-zone ───────────────────────────────────────────────────
|
|
122
|
-
dropzone-bg: #
|
|
144
|
+
dropzone-bg: #F8FAFC,
|
|
123
145
|
dropzone-border: 1.5px dashed #CBD5E1,
|
|
124
146
|
dropzone-radius: 12px,
|
|
125
147
|
dropzone-hover-bg: #EFF6FF,
|
|
@@ -127,6 +149,7 @@ $default-smart-form-config: (
|
|
|
127
149
|
dropzone-over-border: #3B82F6,
|
|
128
150
|
dropzone-over-shadow: 0 0 0 4px rgba(59, 130, 246, 0.12),
|
|
129
151
|
dropzone-icon-color: #94A3B8,
|
|
152
|
+
dropzone-icon-bg: rgba(59, 130, 246, 0.10),
|
|
130
153
|
dropzone-link-color: #3B82F6,
|
|
131
154
|
dropzone-hint-color: #64748B,
|
|
132
155
|
|
|
@@ -194,6 +217,31 @@ $default-smart-form-config: (
|
|
|
194
217
|
btn-font-weight: 600,
|
|
195
218
|
btn-transition: all 0.2s ease,
|
|
196
219
|
btn-disabled-opacity: 0.55,
|
|
220
|
+
|
|
221
|
+
// ── Repeater button sizing ──────────────────────────────────────────────────
|
|
222
|
+
btn-remove-padding: 0.375rem 0.75rem,
|
|
223
|
+
btn-remove-font-size: 0.875rem,
|
|
224
|
+
btn-remove-font-weight: 500,
|
|
225
|
+
|
|
226
|
+
btn-add-padding: 0.625rem 1.5rem,
|
|
227
|
+
btn-add-font-size: 0.875rem,
|
|
228
|
+
btn-add-font-weight: 600,
|
|
229
|
+
|
|
230
|
+
// ── Instance card polish ────────────────────────────────────────────────────
|
|
231
|
+
stepper-connector-display: block,
|
|
232
|
+
instance-shadow: none,
|
|
233
|
+
instance-hover-shadow: none,
|
|
234
|
+
instance-transition: none,
|
|
235
|
+
instance-header-divider: none,
|
|
236
|
+
instance-header-pb: 0px,
|
|
237
|
+
instance-header-mb: 0px,
|
|
238
|
+
instance-num-weight: 600,
|
|
239
|
+
|
|
240
|
+
// ── Section stepper accent (top stripe + active badge) ──────────────────────
|
|
241
|
+
section-stepper-accent: #6366F1,
|
|
242
|
+
section-stepper-accent-end: #8B5CF6,
|
|
243
|
+
section-stepper-active-label: #4F46E5,
|
|
244
|
+
section-stepper-active-glow: rgba(99, 102, 241, 0.25),
|
|
197
245
|
);
|
|
198
246
|
|
|
199
247
|
// ── Theme 2 — Vibrant & Modern (dark) ────────────────────────────────────────
|
|
@@ -202,6 +250,9 @@ $theme-2-smart-form-config: (
|
|
|
202
250
|
font-family: ('Poppins', 'Segoe UI', sans-serif),
|
|
203
251
|
font-size-base: 0.875rem,
|
|
204
252
|
|
|
253
|
+
// ── Accent colour ───────────────────────────────────────────────────────────
|
|
254
|
+
accent-color: #818CF8,
|
|
255
|
+
|
|
205
256
|
// ── Form container ──────────────────────────────────────────────────────────
|
|
206
257
|
form-bg: #0F172A,
|
|
207
258
|
form-padding: 28px,
|
|
@@ -209,6 +260,7 @@ $theme-2-smart-form-config: (
|
|
|
209
260
|
form-border: 1px solid rgba(255, 255, 255, 0.06),
|
|
210
261
|
form-shadow: 0 8px 32px rgba(0, 0, 0, 0.4),
|
|
211
262
|
form-max-width: 1200px,
|
|
263
|
+
form-section-gap: 24px,
|
|
212
264
|
|
|
213
265
|
// ── Form header ─────────────────────────────────────────────────────────────
|
|
214
266
|
form-title-size: 1.75rem,
|
|
@@ -217,7 +269,7 @@ $theme-2-smart-form-config: (
|
|
|
217
269
|
form-desc-size: 0.9rem,
|
|
218
270
|
form-desc-color: #94A3B8,
|
|
219
271
|
|
|
220
|
-
// ── Section / GROUP
|
|
272
|
+
// ── Section / GROUP — flat layout ───────────────────────────────────────────
|
|
221
273
|
section-bg: #1E293B,
|
|
222
274
|
section-border: 1px solid rgba(255, 255, 255, 0.08),
|
|
223
275
|
section-radius: 12px,
|
|
@@ -230,6 +282,19 @@ $theme-2-smart-form-config: (
|
|
|
230
282
|
section-label-color: #E2E8F0,
|
|
231
283
|
section-label-border: 2px solid #334155,
|
|
232
284
|
|
|
285
|
+
// ── Section heading left-accent bar ─────────────────────────────────────────
|
|
286
|
+
section-header-accent-width: 4px,
|
|
287
|
+
section-header-accent-color: #818CF8,
|
|
288
|
+
section-header-bg: #162032,
|
|
289
|
+
|
|
290
|
+
// ── Repeater accordion ──────────────────────────────────────────────────────
|
|
291
|
+
repeater-accordion-header-bg: #162032,
|
|
292
|
+
repeater-accordion-header-color: #E2E8F0,
|
|
293
|
+
repeater-accordion-active-bg: rgba(129, 140, 248, 0.10),
|
|
294
|
+
repeater-badge-bg: #334155,
|
|
295
|
+
repeater-badge-color: #CBD5E1,
|
|
296
|
+
section-border-radius-inner: 8px,
|
|
297
|
+
|
|
233
298
|
// ── GROUP repeater instance card ────────────────────────────────────────────
|
|
234
299
|
instance-bg: #162032,
|
|
235
300
|
instance-border: 1px solid rgba(255, 255, 255, 0.07),
|
|
@@ -239,8 +304,13 @@ $theme-2-smart-form-config: (
|
|
|
239
304
|
instance-num-color: #94A3B8,
|
|
240
305
|
instance-num-size: 0.8125rem,
|
|
241
306
|
|
|
242
|
-
// ── Grid gap
|
|
307
|
+
// ── Grid gap + field gap ─────────────────────────────────────────────────────
|
|
243
308
|
grid-gap: 16px,
|
|
309
|
+
field-gap: 6px,
|
|
310
|
+
|
|
311
|
+
// ── Focus ring ──────────────────────────────────────────────────────────────
|
|
312
|
+
focus-ring-width: 3px,
|
|
313
|
+
focus-ring-offset: 0,
|
|
244
314
|
|
|
245
315
|
// ── Field label ─────────────────────────────────────────────────────────────
|
|
246
316
|
label-size: 0.875rem,
|
|
@@ -315,6 +385,7 @@ $theme-2-smart-form-config: (
|
|
|
315
385
|
dropzone-over-border: #818CF8,
|
|
316
386
|
dropzone-over-shadow: 0 0 0 4px rgba(129, 140, 248, 0.2),
|
|
317
387
|
dropzone-icon-color: #475569,
|
|
388
|
+
dropzone-icon-bg: rgba(129, 140, 248, 0.12),
|
|
318
389
|
dropzone-link-color: #818CF8,
|
|
319
390
|
dropzone-hint-color: #64748B,
|
|
320
391
|
|
|
@@ -382,8 +453,90 @@ $theme-2-smart-form-config: (
|
|
|
382
453
|
btn-font-weight: 600,
|
|
383
454
|
btn-transition: all 0.2s ease,
|
|
384
455
|
btn-disabled-opacity: 0.45,
|
|
456
|
+
|
|
457
|
+
// ── Repeater button sizing ──────────────────────────────────────────────────
|
|
458
|
+
btn-remove-padding: 0.375rem 0.75rem,
|
|
459
|
+
btn-remove-font-size: 0.875rem,
|
|
460
|
+
btn-remove-font-weight: 600,
|
|
461
|
+
|
|
462
|
+
btn-add-padding: 0.625rem 1.5rem,
|
|
463
|
+
btn-add-font-size: 0.875rem,
|
|
464
|
+
btn-add-font-weight: 600,
|
|
465
|
+
|
|
466
|
+
// ── Instance card polish ────────────────────────────────────────────────────
|
|
467
|
+
stepper-connector-display: block,
|
|
468
|
+
instance-shadow: 0 2px 8px rgba(0, 0, 0, 0.3),
|
|
469
|
+
instance-hover-shadow: 0 4px 16px rgba(0, 0, 0, 0.4),
|
|
470
|
+
instance-transition: box-shadow 0.15s ease,
|
|
471
|
+
instance-header-divider: 1px solid #1a253a,
|
|
472
|
+
instance-header-pb: 12px,
|
|
473
|
+
instance-header-mb: 16px,
|
|
474
|
+
instance-num-weight: 600,
|
|
475
|
+
|
|
476
|
+
// ── Section stepper accent ──────────────────────────────────────────────────
|
|
477
|
+
section-stepper-accent: #818CF8,
|
|
478
|
+
section-stepper-accent-end: #A5B4FC,
|
|
479
|
+
section-stepper-active-label: #A5B4FC,
|
|
480
|
+
section-stepper-active-glow: rgba(129, 140, 248, 0.25),
|
|
385
481
|
);
|
|
386
482
|
|
|
483
|
+
// ── Theme 3 — Campus Students (campus red accent) ─────────────────────────────
|
|
484
|
+
$type1-config: map.merge($default-smart-form-config, (
|
|
485
|
+
input-focus-border: #E63E30,
|
|
486
|
+
input-focus-shadow: 0 0 0 3px rgba(230, 62, 48, 0.08),
|
|
487
|
+
chip-selected-bg: #E63E30,
|
|
488
|
+
chip-selected-border: #E63E30,
|
|
489
|
+
switch-track-on: #E63E30,
|
|
490
|
+
|
|
491
|
+
section-bg: transparent,
|
|
492
|
+
section-border: none,
|
|
493
|
+
section-shadow: none,
|
|
494
|
+
section-header-accent-color: #E63E30,
|
|
495
|
+
|
|
496
|
+
step-active-bg: #E63E30,
|
|
497
|
+
step-active-label: #C13320,
|
|
498
|
+
stepper-connector-display: none,
|
|
499
|
+
|
|
500
|
+
btn-add-color: #E63E30,
|
|
501
|
+
btn-add-border: 1.5px dashed rgba(230, 62, 48, 0.3),
|
|
502
|
+
btn-add-hover-bg: rgba(230, 62, 48, 0.04),
|
|
503
|
+
btn-add-hover-border: rgba(230, 62, 48, 0.6),
|
|
504
|
+
|
|
505
|
+
btn-remove-bg: transparent,
|
|
506
|
+
btn-remove-color: #EF4444,
|
|
507
|
+
btn-remove-border: 1px solid #FECACA,
|
|
508
|
+
btn-remove-hover-bg: #FEF2F2,
|
|
509
|
+
btn-remove-radius: 6px,
|
|
510
|
+
btn-remove-padding: 5px 12px,
|
|
511
|
+
btn-remove-font-size: 0.75rem,
|
|
512
|
+
btn-remove-font-weight: 600,
|
|
513
|
+
|
|
514
|
+
btn-add-padding: 10px 20px,
|
|
515
|
+
btn-add-font-size: 0.875rem,
|
|
516
|
+
btn-add-font-weight: 600,
|
|
517
|
+
|
|
518
|
+
btn-primary-bg: #E63E30,
|
|
519
|
+
btn-primary-hover-bg: #C13320,
|
|
520
|
+
btn-primary-color: #ffffff,
|
|
521
|
+
|
|
522
|
+
instance-bg: #ffffff,
|
|
523
|
+
instance-border: 1px solid #E5E7EB,
|
|
524
|
+
instance-radius: 12px,
|
|
525
|
+
instance-shadow: 0 1px 4px rgba(0, 0, 0, 0.04),
|
|
526
|
+
instance-hover-shadow: 0 2px 8px rgba(0, 0, 0, 0.07),
|
|
527
|
+
instance-transition: box-shadow 0.15s ease,
|
|
528
|
+
instance-header-divider: 1px solid #F5F5F5,
|
|
529
|
+
instance-header-pb: 12px,
|
|
530
|
+
instance-header-mb: 16px,
|
|
531
|
+
instance-num-color: #9CA3AF,
|
|
532
|
+
instance-num-weight: 600,
|
|
533
|
+
|
|
534
|
+
section-stepper-accent: #E63E30,
|
|
535
|
+
section-stepper-accent-end: #C13320,
|
|
536
|
+
section-stepper-active-label: #C13320,
|
|
537
|
+
section-stepper-active-glow: rgba(230, 62, 48, 0.2),
|
|
538
|
+
));
|
|
539
|
+
|
|
387
540
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
388
541
|
// Mixin — apply theme by emitting CSS custom properties
|
|
389
542
|
// Usage:
|
|
@@ -398,6 +551,9 @@ $theme-2-smart-form-config: (
|
|
|
398
551
|
--cc-sf-font-family: #{map.get($config, font-family)};
|
|
399
552
|
--cc-sf-font-size-base: #{map.get($config, font-size-base)};
|
|
400
553
|
|
|
554
|
+
// Accent colour
|
|
555
|
+
--cc-sf-accent-color: #{map.get($config, accent-color)};
|
|
556
|
+
|
|
401
557
|
// Form container
|
|
402
558
|
--cc-sf-form-bg: #{map.get($config, form-bg)};
|
|
403
559
|
--cc-sf-form-padding: #{map.get($config, form-padding)};
|
|
@@ -405,6 +561,7 @@ $theme-2-smart-form-config: (
|
|
|
405
561
|
--cc-sf-form-border: #{map.get($config, form-border)};
|
|
406
562
|
--cc-sf-form-shadow: #{map.get($config, form-shadow)};
|
|
407
563
|
--cc-sf-form-max-width: #{map.get($config, form-max-width)};
|
|
564
|
+
--cc-sf-form-section-gap: #{map.get($config, form-section-gap)};
|
|
408
565
|
|
|
409
566
|
// Header
|
|
410
567
|
--cc-sf-form-title-size: #{map.get($config, form-title-size)};
|
|
@@ -413,7 +570,7 @@ $theme-2-smart-form-config: (
|
|
|
413
570
|
--cc-sf-form-desc-size: #{map.get($config, form-desc-size)};
|
|
414
571
|
--cc-sf-form-desc-color: #{map.get($config, form-desc-color)};
|
|
415
572
|
|
|
416
|
-
// Section
|
|
573
|
+
// Section — flat layout tokens
|
|
417
574
|
--cc-sf-section-bg: #{map.get($config, section-bg)};
|
|
418
575
|
--cc-sf-section-border: #{map.get($config, section-border)};
|
|
419
576
|
--cc-sf-section-radius: #{map.get($config, section-radius)};
|
|
@@ -425,6 +582,19 @@ $theme-2-smart-form-config: (
|
|
|
425
582
|
--cc-sf-section-label-color: #{map.get($config, section-label-color)};
|
|
426
583
|
--cc-sf-section-label-border: #{map.get($config, section-label-border)};
|
|
427
584
|
|
|
585
|
+
// Section heading accent bar
|
|
586
|
+
--cc-sf-section-header-accent-width: #{map.get($config, section-header-accent-width)};
|
|
587
|
+
--cc-sf-section-header-accent-color: #{map.get($config, section-header-accent-color)};
|
|
588
|
+
--cc-sf-section-header-bg: #{map.get($config, section-header-bg)};
|
|
589
|
+
|
|
590
|
+
// Repeater accordion
|
|
591
|
+
--cc-sf-repeater-accordion-header-bg: #{map.get($config, repeater-accordion-header-bg)};
|
|
592
|
+
--cc-sf-repeater-accordion-header-color: #{map.get($config, repeater-accordion-header-color)};
|
|
593
|
+
--cc-sf-repeater-accordion-active-bg: #{map.get($config, repeater-accordion-active-bg)};
|
|
594
|
+
--cc-sf-repeater-badge-bg: #{map.get($config, repeater-badge-bg)};
|
|
595
|
+
--cc-sf-repeater-badge-color: #{map.get($config, repeater-badge-color)};
|
|
596
|
+
--cc-sf-section-border-radius-inner: #{map.get($config, section-border-radius-inner)};
|
|
597
|
+
|
|
428
598
|
// Repeater instance
|
|
429
599
|
--cc-sf-instance-bg: #{map.get($config, instance-bg)};
|
|
430
600
|
--cc-sf-instance-border: #{map.get($config, instance-border)};
|
|
@@ -434,8 +604,13 @@ $theme-2-smart-form-config: (
|
|
|
434
604
|
--cc-sf-instance-num-color:#{map.get($config, instance-num-color)};
|
|
435
605
|
--cc-sf-instance-num-size: #{map.get($config, instance-num-size)};
|
|
436
606
|
|
|
437
|
-
// Grid
|
|
607
|
+
// Grid + field gap
|
|
438
608
|
--cc-sf-grid-gap: #{map.get($config, grid-gap)};
|
|
609
|
+
--cc-sf-field-gap: #{map.get($config, field-gap)};
|
|
610
|
+
|
|
611
|
+
// Focus ring
|
|
612
|
+
--cc-sf-focus-ring-width: #{map.get($config, focus-ring-width)};
|
|
613
|
+
--cc-sf-focus-ring-offset: #{map.get($config, focus-ring-offset)};
|
|
439
614
|
|
|
440
615
|
// Label
|
|
441
616
|
--cc-sf-label-size: #{map.get($config, label-size)};
|
|
@@ -508,6 +683,7 @@ $theme-2-smart-form-config: (
|
|
|
508
683
|
--cc-sf-dropzone-over-border: #{map.get($config, dropzone-over-border)};
|
|
509
684
|
--cc-sf-dropzone-over-shadow: #{map.get($config, dropzone-over-shadow)};
|
|
510
685
|
--cc-sf-dropzone-icon-color: #{map.get($config, dropzone-icon-color)};
|
|
686
|
+
--cc-sf-dropzone-icon-bg: #{map.get($config, dropzone-icon-bg)};
|
|
511
687
|
--cc-sf-dropzone-link-color: #{map.get($config, dropzone-link-color)};
|
|
512
688
|
--cc-sf-dropzone-hint-color: #{map.get($config, dropzone-hint-color)};
|
|
513
689
|
|
|
@@ -531,6 +707,24 @@ $theme-2-smart-form-config: (
|
|
|
531
707
|
--cc-sf-btn-remove-border: #{map.get($config, btn-remove-border)};
|
|
532
708
|
--cc-sf-btn-remove-radius: #{map.get($config, btn-remove-radius)};
|
|
533
709
|
--cc-sf-btn-remove-hover-bg: #{map.get($config, btn-remove-hover-bg)};
|
|
710
|
+
--cc-sf-btn-remove-padding: #{map.get($config, btn-remove-padding)};
|
|
711
|
+
--cc-sf-btn-remove-font-size: #{map.get($config, btn-remove-font-size)};
|
|
712
|
+
--cc-sf-btn-remove-font-weight: #{map.get($config, btn-remove-font-weight)};
|
|
713
|
+
--cc-sf-btn-add-padding: #{map.get($config, btn-add-padding)};
|
|
714
|
+
--cc-sf-btn-add-font-size: #{map.get($config, btn-add-font-size)};
|
|
715
|
+
--cc-sf-btn-add-font-weight: #{map.get($config, btn-add-font-weight)};
|
|
716
|
+
--cc-sf-stepper-connector-display: #{map.get($config, stepper-connector-display)};
|
|
717
|
+
--cc-sf-instance-shadow: #{map.get($config, instance-shadow)};
|
|
718
|
+
--cc-sf-instance-hover-shadow: #{map.get($config, instance-hover-shadow)};
|
|
719
|
+
--cc-sf-instance-transition: #{map.get($config, instance-transition)};
|
|
720
|
+
--cc-sf-instance-header-divider: #{map.get($config, instance-header-divider)};
|
|
721
|
+
--cc-sf-instance-header-pb: #{map.get($config, instance-header-pb)};
|
|
722
|
+
--cc-sf-instance-header-mb: #{map.get($config, instance-header-mb)};
|
|
723
|
+
--cc-sf-instance-num-weight: #{map.get($config, instance-num-weight)};
|
|
724
|
+
--cc-sf-section-stepper-accent: #{map.get($config, section-stepper-accent)};
|
|
725
|
+
--cc-sf-section-stepper-accent-end: #{map.get($config, section-stepper-accent-end)};
|
|
726
|
+
--cc-sf-section-stepper-active-label: #{map.get($config, section-stepper-active-label)};
|
|
727
|
+
--cc-sf-section-stepper-active-glow: #{map.get($config, section-stepper-active-glow)};
|
|
534
728
|
|
|
535
729
|
// Stepper
|
|
536
730
|
--cc-sf-step-connector-color: #{map.get($config, step-connector-color)};
|
|
@@ -571,4 +765,120 @@ $theme-2-smart-form-config: (
|
|
|
571
765
|
--cc-sf-btn-font-weight: #{map.get($config, btn-font-weight)};
|
|
572
766
|
--cc-sf-btn-transition: #{map.get($config, btn-transition)};
|
|
573
767
|
--cc-sf-btn-disabled-opacity: #{map.get($config, btn-disabled-opacity)};
|
|
768
|
+
|
|
769
|
+
// ── Structural rules using the emitted tokens ─────────────────────────────
|
|
770
|
+
::ng-deep {
|
|
771
|
+
.stepper-nav .stepper-step:not(:last-child)::after {
|
|
772
|
+
display: var(--cc-sf-stepper-connector-display) !important;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
.section-instance {
|
|
776
|
+
background: var(--cc-sf-instance-bg) !important;
|
|
777
|
+
border: var(--cc-sf-instance-border) !important;
|
|
778
|
+
border-radius: var(--cc-sf-instance-radius) !important;
|
|
779
|
+
box-shadow: var(--cc-sf-instance-shadow);
|
|
780
|
+
transition: var(--cc-sf-instance-transition);
|
|
781
|
+
|
|
782
|
+
&:hover {
|
|
783
|
+
box-shadow: var(--cc-sf-instance-hover-shadow);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.section-instance-header {
|
|
788
|
+
display: flex;
|
|
789
|
+
align-items: center;
|
|
790
|
+
justify-content: space-between;
|
|
791
|
+
padding-bottom: var(--cc-sf-instance-header-pb);
|
|
792
|
+
margin-bottom: var(--cc-sf-instance-header-mb);
|
|
793
|
+
border-bottom: var(--cc-sf-instance-header-divider);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.section-instance-num {
|
|
797
|
+
font-size: var(--cc-sf-instance-num-size);
|
|
798
|
+
font-weight: var(--cc-sf-instance-num-weight);
|
|
799
|
+
color: var(--cc-sf-instance-num-color);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
.btn-instance-remove {
|
|
803
|
+
display: inline-flex;
|
|
804
|
+
align-items: center;
|
|
805
|
+
gap: 6px;
|
|
806
|
+
padding: var(--cc-sf-btn-remove-padding);
|
|
807
|
+
border-radius: var(--cc-sf-btn-remove-radius);
|
|
808
|
+
border: var(--cc-sf-btn-remove-border) !important;
|
|
809
|
+
background: var(--cc-sf-btn-remove-bg);
|
|
810
|
+
color: var(--cc-sf-btn-remove-color) !important;
|
|
811
|
+
font-size: var(--cc-sf-btn-remove-font-size);
|
|
812
|
+
font-weight: var(--cc-sf-btn-remove-font-weight);
|
|
813
|
+
cursor: pointer;
|
|
814
|
+
transition: all 0.15s ease;
|
|
815
|
+
|
|
816
|
+
&:hover {
|
|
817
|
+
background: var(--cc-sf-btn-remove-hover-bg);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
.btn-add-section {
|
|
822
|
+
display: inline-flex;
|
|
823
|
+
align-items: center;
|
|
824
|
+
gap: 8px;
|
|
825
|
+
padding: var(--cc-sf-btn-add-padding);
|
|
826
|
+
border-radius: var(--cc-sf-btn-add-radius);
|
|
827
|
+
border: var(--cc-sf-btn-add-border) !important;
|
|
828
|
+
background: var(--cc-sf-btn-add-bg);
|
|
829
|
+
color: var(--cc-sf-btn-add-color);
|
|
830
|
+
font-size: var(--cc-sf-btn-add-font-size);
|
|
831
|
+
font-weight: var(--cc-sf-btn-add-font-weight);
|
|
832
|
+
cursor: pointer;
|
|
833
|
+
transition: all 0.18s ease;
|
|
834
|
+
|
|
835
|
+
&:hover {
|
|
836
|
+
background: var(--cc-sf-btn-add-hover-bg);
|
|
837
|
+
border-color: var(--cc-sf-btn-add-hover-border) !important;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// ── Section stepper — accent colour override ──────────────────────────
|
|
842
|
+
.section-stepper-nav::before {
|
|
843
|
+
background: linear-gradient(
|
|
844
|
+
90deg,
|
|
845
|
+
var(--cc-sf-section-stepper-accent) 0%,
|
|
846
|
+
var(--cc-sf-section-stepper-accent-end) 100%
|
|
847
|
+
) !important;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.section-stepper-step {
|
|
851
|
+
&.ss-active {
|
|
852
|
+
.ss-badge {
|
|
853
|
+
background: linear-gradient(
|
|
854
|
+
135deg,
|
|
855
|
+
var(--cc-sf-section-stepper-accent) 0%,
|
|
856
|
+
var(--cc-sf-section-stepper-accent-end) 100%
|
|
857
|
+
) !important;
|
|
858
|
+
box-shadow:
|
|
859
|
+
0 0 0 4px var(--cc-sf-section-stepper-active-glow),
|
|
860
|
+
0 4px 12px var(--cc-sf-section-stepper-active-glow) !important;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.ss-label {
|
|
864
|
+
color: var(--cc-sf-section-stepper-active-label) !important;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
&:not(.ss-active):not(.ss-completed):not(.ss-warning):hover {
|
|
869
|
+
.ss-badge {
|
|
870
|
+
color: var(--cc-sf-section-stepper-accent) !important;
|
|
871
|
+
border-color: var(--cc-sf-section-stepper-accent-end) !important;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
.ss-connector::after {
|
|
876
|
+
background: linear-gradient(
|
|
877
|
+
90deg,
|
|
878
|
+
var(--cc-sf-section-stepper-accent),
|
|
879
|
+
var(--cc-sf-section-stepper-accent-end)
|
|
880
|
+
) !important;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
574
884
|
}
|