@maro-tech/form 0.1.1 → 0.1.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/fesm2022/maro-tech-form.mjs +1042 -350
- package/fesm2022/maro-tech-form.mjs.map +1 -1
- package/package.json +1 -1
- package/types/maro-tech-form.d.ts +376 -80
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, Injectable, inject,
|
|
2
|
+
import { signal, Injectable, inject, EventEmitter, Output, Input, ChangeDetectionStrategy, Component, input, output, ViewChild, forwardRef, ChangeDetectorRef, HostListener, DestroyRef, ElementRef, booleanAttribute, ViewContainerRef, computed } from '@angular/core';
|
|
3
3
|
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { throwError, forkJoin, map, Subject, debounceTime, distinctUntilChanged, of } from 'rxjs';
|
|
4
5
|
import * as i1$2 from '@angular/common';
|
|
5
6
|
import { CommonModule } from '@angular/common';
|
|
6
7
|
import * as i2 from '@angular/forms';
|
|
7
8
|
import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
8
9
|
import { UiButtonComponent, UiToastService } from '@maro-tech/core';
|
|
10
|
+
import * as i1 from 'lucide-angular';
|
|
11
|
+
import { Camera, CameraOff, CalendarDays, ChevronLeft, ChevronRight, LucideAngularModule, Eye, EyeOff, X, ChevronDown, Check } from 'lucide-angular';
|
|
9
12
|
import { BrowserMultiFormatOneDReader } from '@zxing/browser';
|
|
10
13
|
import { DecodeHintType, BarcodeFormat } from '@zxing/library';
|
|
11
|
-
import * as i1 from 'lucide-angular';
|
|
12
|
-
import { CalendarDays, ChevronLeft, ChevronRight, LucideAngularModule, Eye, EyeOff, X, ChevronDown, Check } from 'lucide-angular';
|
|
13
14
|
import * as i1$1 from '@angular/cdk/drag-drop';
|
|
14
|
-
import {
|
|
15
|
-
import { forkJoin, map, Subject, debounceTime, distinctUntilChanged, of } from 'rxjs';
|
|
15
|
+
import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
|
|
16
16
|
import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
|
|
17
17
|
import { Router } from '@angular/router';
|
|
18
18
|
|
|
@@ -56,9 +56,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
56
56
|
args: [{ providedIn: 'root' }]
|
|
57
57
|
}] });
|
|
58
58
|
|
|
59
|
+
const ACTION_PRINT = 'ACTION_PRINT';
|
|
60
|
+
const ACTION_FORM = 'ACTION_FORM';
|
|
61
|
+
const ACTION_API = 'ACTION_API';
|
|
62
|
+
const ACTION_SUBMIT = 'ACTION_SUBMIT';
|
|
63
|
+
const isDynamicFormContainerField = (field) => field.type === 'container';
|
|
64
|
+
const isDynamicFormTemplateField = (field) => field.type === 'template';
|
|
65
|
+
const isDynamicFormLookupField = (field) => field.type === 'select' || field.type === 'barcode';
|
|
66
|
+
const flattenDynamicFormFields = (fields) => {
|
|
67
|
+
const result = [];
|
|
68
|
+
for (const field of fields || []) {
|
|
69
|
+
if (!field) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
result.push(field);
|
|
73
|
+
if (isDynamicFormContainerField(field) && Array.isArray(field.fields) && field.fields.length) {
|
|
74
|
+
result.push(...flattenDynamicFormFields(field.fields));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
|
|
59
80
|
class UiFormLookupService {
|
|
60
81
|
http = inject(HttpClient);
|
|
61
82
|
lookup(field, value) {
|
|
83
|
+
if (!isDynamicFormLookupField(field)) {
|
|
84
|
+
return throwError(() => new Error('Lookup is not supported for this field type'));
|
|
85
|
+
}
|
|
62
86
|
const api = String(field.lookupApi || '').trim();
|
|
63
87
|
const endpoint = api
|
|
64
88
|
.replace(/:value/g, encodeURIComponent(value))
|
|
@@ -79,39 +103,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
79
103
|
type: Injectable
|
|
80
104
|
}] });
|
|
81
105
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
class FieldFrameComponent {
|
|
107
|
+
label;
|
|
108
|
+
hint;
|
|
109
|
+
error;
|
|
110
|
+
required = false;
|
|
111
|
+
forId;
|
|
112
|
+
disabled = false;
|
|
113
|
+
actions = [];
|
|
114
|
+
actionTriggered = new EventEmitter();
|
|
115
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FieldFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
116
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: FieldFrameComponent, isStandalone: true, selector: "field-frame", inputs: { label: "label", hint: "hint", error: "error", required: "required", forId: "forId", disabled: "disabled", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, ngImport: i0, template: "<div class=\"relative w-full flex flex-col gap-1 text-[0.65rem] uppercase tracking-[0.3em] text-slate-500\">\n @if (label) {\n <label class=\"text-[0.7rem] font-semibold text-slate-600\" [attr.for]=\"forId\">\n {{ label }}\n @if (required) {\n <span aria-hidden=\"true\" class=\"text-rose-500\"> *</span>\n }\n </label>\n }\n\n <div class=\"flex items-end gap-2\">\n <div class=\"min-w-0 flex-1\">\n <ng-content />\n </div>\n\n @if (actions.length) {\n <div class=\"flex flex-none items-center gap-2 pb-0.5\">\n @for (action of actions; track action.id) {\n <ui-button\n type=\"button\"\n [variant]=\"action.variant ?? 'secondary'\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"actionTriggered.emit(action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </div>\n\n @if (hint) {\n <p class=\"text-[0.5rem] text-slate-500\">{{ hint }}</p>\n }\n @if (error) {\n <p class=\"absolute left-0 top-full z-10 mt-1 text-[0.5rem] text-rose-400\">{{ error }}</p>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
117
|
+
}
|
|
118
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FieldFrameComponent, decorators: [{
|
|
119
|
+
type: Component,
|
|
120
|
+
args: [{ selector: 'field-frame', standalone: true, imports: [CommonModule, UiButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative w-full flex flex-col gap-1 text-[0.65rem] uppercase tracking-[0.3em] text-slate-500\">\n @if (label) {\n <label class=\"text-[0.7rem] font-semibold text-slate-600\" [attr.for]=\"forId\">\n {{ label }}\n @if (required) {\n <span aria-hidden=\"true\" class=\"text-rose-500\"> *</span>\n }\n </label>\n }\n\n <div class=\"flex items-end gap-2\">\n <div class=\"min-w-0 flex-1\">\n <ng-content />\n </div>\n\n @if (actions.length) {\n <div class=\"flex flex-none items-center gap-2 pb-0.5\">\n @for (action of actions; track action.id) {\n <ui-button\n type=\"button\"\n [variant]=\"action.variant ?? 'secondary'\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"actionTriggered.emit(action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </div>\n\n @if (hint) {\n <p class=\"text-[0.5rem] text-slate-500\">{{ hint }}</p>\n }\n @if (error) {\n <p class=\"absolute left-0 top-full z-10 mt-1 text-[0.5rem] text-rose-400\">{{ error }}</p>\n }\n</div>\n" }]
|
|
121
|
+
}], propDecorators: { label: [{
|
|
122
|
+
type: Input
|
|
123
|
+
}], hint: [{
|
|
124
|
+
type: Input
|
|
125
|
+
}], error: [{
|
|
126
|
+
type: Input
|
|
127
|
+
}], required: [{
|
|
128
|
+
type: Input
|
|
129
|
+
}], forId: [{
|
|
130
|
+
type: Input
|
|
131
|
+
}], disabled: [{
|
|
132
|
+
type: Input
|
|
133
|
+
}], actions: [{
|
|
134
|
+
type: Input
|
|
135
|
+
}], actionTriggered: [{
|
|
136
|
+
type: Output
|
|
137
|
+
}] } });
|
|
101
138
|
|
|
102
|
-
class
|
|
139
|
+
class InputBarcodeControlComponent {
|
|
140
|
+
cameraIcon = Camera;
|
|
141
|
+
cameraOffIcon = CameraOff;
|
|
103
142
|
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
104
143
|
label = input('Штрихкод', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
105
144
|
placeholder = input('Відскануйте або введіть штрихкод', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
106
145
|
hint = input('Сканер може просто ввести код і натиснути Enter.', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
146
|
+
error = input('', ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
147
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
107
148
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
108
|
-
autoOpen = input(true, ...(ngDevMode ? [{ debugName: "autoOpen" }] : /* istanbul ignore next */ []));
|
|
109
|
-
searchButtonLabel = input('Знайти', ...(ngDevMode ? [{ debugName: "searchButtonLabel" }] : /* istanbul ignore next */ []));
|
|
110
|
-
openCameraLabel = input('Відкрити камеру', ...(ngDevMode ? [{ debugName: "openCameraLabel" }] : /* istanbul ignore next */ []));
|
|
111
|
-
closeCameraLabel = input('Закрити камеру', ...(ngDevMode ? [{ debugName: "closeCameraLabel" }] : /* istanbul ignore next */ []));
|
|
112
|
-
cameraTitle = input('Камера', ...(ngDevMode ? [{ debugName: "cameraTitle" }] : /* istanbul ignore next */ []));
|
|
113
|
-
cameraStartingLabel = input('Запускаємо камеру…', ...(ngDevMode ? [{ debugName: "cameraStartingLabel" }] : /* istanbul ignore next */ []));
|
|
114
|
-
cameraHint = input('Наведіть камеру на штрихкод. Після зчитування код підставиться автоматично.', ...(ngDevMode ? [{ debugName: "cameraHint" }] : /* istanbul ignore next */ []));
|
|
115
149
|
valueChange = output();
|
|
116
150
|
scanned = output();
|
|
117
151
|
searchRequested = output();
|
|
@@ -138,9 +172,8 @@ class InputBarcodeComponent {
|
|
|
138
172
|
this.autoOpenQueued = false;
|
|
139
173
|
return;
|
|
140
174
|
}
|
|
141
|
-
if (
|
|
175
|
+
if (!this.disabled())
|
|
142
176
|
this.scheduleAutoOpen();
|
|
143
|
-
}
|
|
144
177
|
}
|
|
145
178
|
ngAfterViewInit() {
|
|
146
179
|
this.scheduleAutoOpen();
|
|
@@ -210,13 +243,13 @@ class InputBarcodeComponent {
|
|
|
210
243
|
this.stopCamera();
|
|
211
244
|
}
|
|
212
245
|
scheduleAutoOpen() {
|
|
213
|
-
if (typeof window === 'undefined' ||
|
|
246
|
+
if (typeof window === 'undefined' || this.disabled() || this.isCameraOpen() || this.isCameraStarting() || this.autoOpenQueued) {
|
|
214
247
|
return;
|
|
215
248
|
}
|
|
216
249
|
this.autoOpenQueued = true;
|
|
217
250
|
window.requestAnimationFrame(() => {
|
|
218
251
|
this.autoOpenQueued = false;
|
|
219
|
-
if (
|
|
252
|
+
if (this.disabled() || this.isCameraOpen() || this.isCameraStarting()) {
|
|
220
253
|
return;
|
|
221
254
|
}
|
|
222
255
|
void this.openCamera();
|
|
@@ -363,18 +396,10 @@ class InputBarcodeComponent {
|
|
|
363
396
|
return null;
|
|
364
397
|
}
|
|
365
398
|
}
|
|
366
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
367
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type:
|
|
368
|
-
<div class="space-y-2">
|
|
369
|
-
@if (label()) {
|
|
370
|
-
<label class="flex flex-col gap-1 text-[0.65rem] uppercase tracking-[0.3em] text-slate-500" for="barcode-scanner-input">
|
|
371
|
-
<span class="text-[0.7rem] font-semibold text-slate-600">
|
|
372
|
-
{{ label() }}
|
|
373
|
-
</span>
|
|
374
|
-
</label>
|
|
375
|
-
}
|
|
399
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBarcodeControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
400
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputBarcodeControlComponent, isStandalone: true, selector: "input-barcode-control", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", scanned: "scanned", searchRequested: "searchRequested", cameraStateChange: "cameraStateChange" }, viewQueries: [{ propertyName: "cameraVideo", first: true, predicate: ["cameraVideo"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
376
401
|
|
|
377
|
-
<div class="flex items-start gap-2">
|
|
402
|
+
<div class="relative flex items-start gap-2">
|
|
378
403
|
<div class="min-w-0 flex-1">
|
|
379
404
|
<input
|
|
380
405
|
#barcodeInput
|
|
@@ -387,16 +412,14 @@ class InputBarcodeComponent {
|
|
|
387
412
|
(ngModelChange)="onValueChange($event)"
|
|
388
413
|
(keydown.enter)="requestSearch()"
|
|
389
414
|
class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200"
|
|
415
|
+
[class.border-rose-300]="!!error()"
|
|
416
|
+
[class.ring-2]="!!error()"
|
|
417
|
+
[class.ring-rose-200]="!!error()"
|
|
390
418
|
[placeholder]="placeholder()"
|
|
391
419
|
/>
|
|
392
|
-
@if (hint()) {
|
|
393
|
-
<p class="mt-2 text-[0.5rem] text-slate-500">
|
|
394
|
-
{{ hint() }}
|
|
395
|
-
</p>
|
|
396
|
-
}
|
|
397
420
|
</div>
|
|
398
421
|
|
|
399
|
-
<div class="mt-0.5 flex flex-
|
|
422
|
+
<div class="mt-0.5 flex flex-row flex-wrap items-center gap-2">
|
|
400
423
|
<ui-button
|
|
401
424
|
type="button"
|
|
402
425
|
variant="secondary"
|
|
@@ -404,31 +427,39 @@ class InputBarcodeComponent {
|
|
|
404
427
|
[disabled]="disabled()"
|
|
405
428
|
(click)="requestSearch()"
|
|
406
429
|
>
|
|
407
|
-
|
|
408
|
-
</ui-button>
|
|
409
|
-
<ui-button
|
|
410
|
-
type="button"
|
|
411
|
-
variant="ghost"
|
|
412
|
-
size="sm"
|
|
413
|
-
[disabled]="disabled() || isCameraStarting()"
|
|
414
|
-
(click)="isCameraOpen() ? closeCamera() : openCamera()"
|
|
415
|
-
>
|
|
416
|
-
{{ isCameraOpen() ? closeCameraLabel() : openCameraLabel() }}
|
|
430
|
+
Знайти
|
|
417
431
|
</ui-button>
|
|
432
|
+
<ui-button
|
|
433
|
+
type="button"
|
|
434
|
+
variant="ghost"
|
|
435
|
+
size="sm"
|
|
436
|
+
[iconOnly]="true"
|
|
437
|
+
[icon]="isCameraOpen() ? cameraOffIcon : cameraIcon"
|
|
438
|
+
[ariaLabel]="isCameraOpen() ? 'Закрити камеру' : 'Відкрити камеру'"
|
|
439
|
+
[disabled]="disabled() || isCameraStarting()"
|
|
440
|
+
(click)="isCameraOpen() ? closeCamera() : openCamera()"
|
|
441
|
+
></ui-button>
|
|
418
442
|
</div>
|
|
419
443
|
</div>
|
|
420
444
|
|
|
445
|
+
@if (hint()) {
|
|
446
|
+
<p class="mt-2 text-[0.5rem] text-slate-500">{{ hint() }}</p>
|
|
447
|
+
}
|
|
448
|
+
@if (error()) {
|
|
449
|
+
<p class="absolute left-0 top-full z-10 mt-1 text-[0.5rem] text-rose-400">{{ error() }}</p>
|
|
450
|
+
}
|
|
451
|
+
|
|
421
452
|
@if (isCameraStarting()) {
|
|
422
453
|
<div class="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500">
|
|
423
|
-
|
|
454
|
+
Запускаємо камеру…
|
|
424
455
|
</div>
|
|
425
456
|
}
|
|
426
457
|
|
|
427
458
|
@if (isCameraOpen()) {
|
|
428
|
-
<section class="space-y-3 rounded-3xl border border-slate-200 bg-slate-950 p-3 text-white">
|
|
459
|
+
<section class="mt-3 space-y-3 rounded-3xl border border-slate-200 bg-slate-950 p-3 text-white">
|
|
429
460
|
<div class="flex items-center justify-between gap-3">
|
|
430
461
|
<div>
|
|
431
|
-
<p class="text-xs font-semibold uppercase tracking-[0.22em] text-slate-300"
|
|
462
|
+
<p class="text-xs font-semibold uppercase tracking-[0.22em] text-slate-300">Камера</p>
|
|
432
463
|
<p class="text-sm text-slate-200">{{ cameraStatus() }}</p>
|
|
433
464
|
</div>
|
|
434
465
|
<button
|
|
@@ -436,7 +467,7 @@ class InputBarcodeComponent {
|
|
|
436
467
|
class="rounded-full border border-slate-700 px-3 py-1 text-xs font-semibold text-slate-200 transition hover:border-slate-500 hover:text-white"
|
|
437
468
|
(click)="closeCamera()"
|
|
438
469
|
>
|
|
439
|
-
|
|
470
|
+
Закрити камеру
|
|
440
471
|
</button>
|
|
441
472
|
</div>
|
|
442
473
|
|
|
@@ -445,7 +476,7 @@ class InputBarcodeComponent {
|
|
|
445
476
|
</div>
|
|
446
477
|
|
|
447
478
|
<p class="text-xs text-slate-300">
|
|
448
|
-
|
|
479
|
+
Наведіть камеру на штрихкод.
|
|
449
480
|
</p>
|
|
450
481
|
</section>
|
|
451
482
|
}
|
|
@@ -455,26 +486,18 @@ class InputBarcodeComponent {
|
|
|
455
486
|
{{ cameraError() }}
|
|
456
487
|
</div>
|
|
457
488
|
}
|
|
458
|
-
|
|
489
|
+
|
|
459
490
|
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }] });
|
|
460
491
|
}
|
|
461
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
492
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBarcodeControlComponent, decorators: [{
|
|
462
493
|
type: Component,
|
|
463
494
|
args: [{
|
|
464
|
-
selector: 'input-barcode',
|
|
495
|
+
selector: 'input-barcode-control',
|
|
465
496
|
standalone: true,
|
|
466
497
|
imports: [CommonModule, FormsModule, UiButtonComponent],
|
|
467
498
|
template: `
|
|
468
|
-
<div class="space-y-2">
|
|
469
|
-
@if (label()) {
|
|
470
|
-
<label class="flex flex-col gap-1 text-[0.65rem] uppercase tracking-[0.3em] text-slate-500" for="barcode-scanner-input">
|
|
471
|
-
<span class="text-[0.7rem] font-semibold text-slate-600">
|
|
472
|
-
{{ label() }}
|
|
473
|
-
</span>
|
|
474
|
-
</label>
|
|
475
|
-
}
|
|
476
499
|
|
|
477
|
-
<div class="flex items-start gap-2">
|
|
500
|
+
<div class="relative flex items-start gap-2">
|
|
478
501
|
<div class="min-w-0 flex-1">
|
|
479
502
|
<input
|
|
480
503
|
#barcodeInput
|
|
@@ -487,16 +510,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
487
510
|
(ngModelChange)="onValueChange($event)"
|
|
488
511
|
(keydown.enter)="requestSearch()"
|
|
489
512
|
class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200"
|
|
513
|
+
[class.border-rose-300]="!!error()"
|
|
514
|
+
[class.ring-2]="!!error()"
|
|
515
|
+
[class.ring-rose-200]="!!error()"
|
|
490
516
|
[placeholder]="placeholder()"
|
|
491
517
|
/>
|
|
492
|
-
@if (hint()) {
|
|
493
|
-
<p class="mt-2 text-[0.5rem] text-slate-500">
|
|
494
|
-
{{ hint() }}
|
|
495
|
-
</p>
|
|
496
|
-
}
|
|
497
518
|
</div>
|
|
498
519
|
|
|
499
|
-
<div class="mt-0.5 flex flex-
|
|
520
|
+
<div class="mt-0.5 flex flex-row flex-wrap items-center gap-2">
|
|
500
521
|
<ui-button
|
|
501
522
|
type="button"
|
|
502
523
|
variant="secondary"
|
|
@@ -504,31 +525,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
504
525
|
[disabled]="disabled()"
|
|
505
526
|
(click)="requestSearch()"
|
|
506
527
|
>
|
|
507
|
-
|
|
508
|
-
</ui-button>
|
|
509
|
-
<ui-button
|
|
510
|
-
type="button"
|
|
511
|
-
variant="ghost"
|
|
512
|
-
size="sm"
|
|
513
|
-
[disabled]="disabled() || isCameraStarting()"
|
|
514
|
-
(click)="isCameraOpen() ? closeCamera() : openCamera()"
|
|
515
|
-
>
|
|
516
|
-
{{ isCameraOpen() ? closeCameraLabel() : openCameraLabel() }}
|
|
528
|
+
Знайти
|
|
517
529
|
</ui-button>
|
|
530
|
+
<ui-button
|
|
531
|
+
type="button"
|
|
532
|
+
variant="ghost"
|
|
533
|
+
size="sm"
|
|
534
|
+
[iconOnly]="true"
|
|
535
|
+
[icon]="isCameraOpen() ? cameraOffIcon : cameraIcon"
|
|
536
|
+
[ariaLabel]="isCameraOpen() ? 'Закрити камеру' : 'Відкрити камеру'"
|
|
537
|
+
[disabled]="disabled() || isCameraStarting()"
|
|
538
|
+
(click)="isCameraOpen() ? closeCamera() : openCamera()"
|
|
539
|
+
></ui-button>
|
|
518
540
|
</div>
|
|
519
541
|
</div>
|
|
520
542
|
|
|
543
|
+
@if (hint()) {
|
|
544
|
+
<p class="mt-2 text-[0.5rem] text-slate-500">{{ hint() }}</p>
|
|
545
|
+
}
|
|
546
|
+
@if (error()) {
|
|
547
|
+
<p class="absolute left-0 top-full z-10 mt-1 text-[0.5rem] text-rose-400">{{ error() }}</p>
|
|
548
|
+
}
|
|
549
|
+
|
|
521
550
|
@if (isCameraStarting()) {
|
|
522
551
|
<div class="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500">
|
|
523
|
-
|
|
552
|
+
Запускаємо камеру…
|
|
524
553
|
</div>
|
|
525
554
|
}
|
|
526
555
|
|
|
527
556
|
@if (isCameraOpen()) {
|
|
528
|
-
<section class="space-y-3 rounded-3xl border border-slate-200 bg-slate-950 p-3 text-white">
|
|
557
|
+
<section class="mt-3 space-y-3 rounded-3xl border border-slate-200 bg-slate-950 p-3 text-white">
|
|
529
558
|
<div class="flex items-center justify-between gap-3">
|
|
530
559
|
<div>
|
|
531
|
-
<p class="text-xs font-semibold uppercase tracking-[0.22em] text-slate-300"
|
|
560
|
+
<p class="text-xs font-semibold uppercase tracking-[0.22em] text-slate-300">Камера</p>
|
|
532
561
|
<p class="text-sm text-slate-200">{{ cameraStatus() }}</p>
|
|
533
562
|
</div>
|
|
534
563
|
<button
|
|
@@ -536,7 +565,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
536
565
|
class="rounded-full border border-slate-700 px-3 py-1 text-xs font-semibold text-slate-200 transition hover:border-slate-500 hover:text-white"
|
|
537
566
|
(click)="closeCamera()"
|
|
538
567
|
>
|
|
539
|
-
|
|
568
|
+
Закрити камеру
|
|
540
569
|
</button>
|
|
541
570
|
</div>
|
|
542
571
|
|
|
@@ -545,7 +574,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
545
574
|
</div>
|
|
546
575
|
|
|
547
576
|
<p class="text-xs text-slate-300">
|
|
548
|
-
|
|
577
|
+
Наведіть камеру на штрихкод.
|
|
549
578
|
</p>
|
|
550
579
|
</section>
|
|
551
580
|
}
|
|
@@ -555,19 +584,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
555
584
|
{{ cameraError() }}
|
|
556
585
|
</div>
|
|
557
586
|
}
|
|
558
|
-
|
|
587
|
+
|
|
559
588
|
`,
|
|
560
589
|
}]
|
|
561
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }],
|
|
590
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], scanned: [{ type: i0.Output, args: ["scanned"] }], searchRequested: [{ type: i0.Output, args: ["searchRequested"] }], cameraStateChange: [{ type: i0.Output, args: ["cameraStateChange"] }], cameraVideo: [{
|
|
562
591
|
type: ViewChild,
|
|
563
592
|
args: ['cameraVideo']
|
|
564
593
|
}] } });
|
|
565
594
|
|
|
595
|
+
class InputBarcodeComponent {
|
|
596
|
+
value = '';
|
|
597
|
+
label = 'Штрихкод';
|
|
598
|
+
placeholder = 'Відскануйте або введіть штрихкод';
|
|
599
|
+
hint = 'Сканер може просто ввести код і натиснути Enter.';
|
|
600
|
+
error = '';
|
|
601
|
+
required = false;
|
|
602
|
+
disabled = false;
|
|
603
|
+
valueChange = new EventEmitter();
|
|
604
|
+
scanned = new EventEmitter();
|
|
605
|
+
searchRequested = new EventEmitter();
|
|
606
|
+
cameraStateChange = new EventEmitter();
|
|
607
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBarcodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
608
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputBarcodeComponent, isStandalone: true, selector: "input-barcode", inputs: { value: "value", label: "label", placeholder: "placeholder", hint: "hint", error: "error", required: "required", disabled: "disabled" }, outputs: { valueChange: "valueChange", scanned: "scanned", searchRequested: "searchRequested", cameraStateChange: "cameraStateChange" }, ngImport: i0, template: `
|
|
609
|
+
<field-frame [label]="label" [required]="required" [forId]="'barcode-scanner-input'" [disabled]="disabled">
|
|
610
|
+
<input-barcode-control [value]="value" [label]="label" [placeholder]="placeholder" [hint]="hint" [error]="error" [required]="required" [disabled]="disabled" (valueChange)="valueChange.emit($event)" (scanned)="scanned.emit($event)" (searchRequested)="searchRequested.emit()" (cameraStateChange)="cameraStateChange.emit($event)" />
|
|
611
|
+
</field-frame>
|
|
612
|
+
`, isInline: true, dependencies: [{ kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputBarcodeControlComponent, selector: "input-barcode-control", inputs: ["value", "label", "placeholder", "hint", "error", "required", "disabled"], outputs: ["valueChange", "scanned", "searchRequested", "cameraStateChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
613
|
+
}
|
|
614
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBarcodeComponent, decorators: [{
|
|
615
|
+
type: Component,
|
|
616
|
+
args: [{
|
|
617
|
+
selector: 'input-barcode',
|
|
618
|
+
standalone: true,
|
|
619
|
+
imports: [FieldFrameComponent, InputBarcodeControlComponent],
|
|
620
|
+
template: `
|
|
621
|
+
<field-frame [label]="label" [required]="required" [forId]="'barcode-scanner-input'" [disabled]="disabled">
|
|
622
|
+
<input-barcode-control [value]="value" [label]="label" [placeholder]="placeholder" [hint]="hint" [error]="error" [required]="required" [disabled]="disabled" (valueChange)="valueChange.emit($event)" (scanned)="scanned.emit($event)" (searchRequested)="searchRequested.emit()" (cameraStateChange)="cameraStateChange.emit($event)" />
|
|
623
|
+
</field-frame>
|
|
624
|
+
`,
|
|
625
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
626
|
+
}]
|
|
627
|
+
}], propDecorators: { value: [{
|
|
628
|
+
type: Input
|
|
629
|
+
}], label: [{
|
|
630
|
+
type: Input
|
|
631
|
+
}], placeholder: [{
|
|
632
|
+
type: Input
|
|
633
|
+
}], hint: [{
|
|
634
|
+
type: Input
|
|
635
|
+
}], error: [{
|
|
636
|
+
type: Input
|
|
637
|
+
}], required: [{
|
|
638
|
+
type: Input
|
|
639
|
+
}], disabled: [{
|
|
640
|
+
type: Input
|
|
641
|
+
}], valueChange: [{
|
|
642
|
+
type: Output
|
|
643
|
+
}], scanned: [{
|
|
644
|
+
type: Output
|
|
645
|
+
}], searchRequested: [{
|
|
646
|
+
type: Output
|
|
647
|
+
}], cameraStateChange: [{
|
|
648
|
+
type: Output
|
|
649
|
+
}] } });
|
|
650
|
+
|
|
651
|
+
class InputCheckboxControlComponent {
|
|
652
|
+
value = false;
|
|
653
|
+
disabled = false;
|
|
654
|
+
valueChange = new EventEmitter();
|
|
655
|
+
touched = new EventEmitter();
|
|
656
|
+
onValueChange(event) {
|
|
657
|
+
this.valueChange.emit(event.target.checked);
|
|
658
|
+
}
|
|
659
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputCheckboxControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
660
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputCheckboxControlComponent, isStandalone: true, selector: "input-checkbox-control", inputs: { value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input type="checkbox" class="h-4 w-4 rounded border-slate-300 text-slate-900 focus:ring-slate-400" [checked]="value" [disabled]="disabled" (change)="onValueChange($event)" (blur)="touched.emit()" />`, isInline: true });
|
|
661
|
+
}
|
|
662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputCheckboxControlComponent, decorators: [{
|
|
663
|
+
type: Component,
|
|
664
|
+
args: [{
|
|
665
|
+
selector: 'input-checkbox-control',
|
|
666
|
+
standalone: true,
|
|
667
|
+
template: `<input type="checkbox" class="h-4 w-4 rounded border-slate-300 text-slate-900 focus:ring-slate-400" [checked]="value" [disabled]="disabled" (change)="onValueChange($event)" (blur)="touched.emit()" />`,
|
|
668
|
+
}]
|
|
669
|
+
}], propDecorators: { value: [{
|
|
670
|
+
type: Input
|
|
671
|
+
}], disabled: [{
|
|
672
|
+
type: Input
|
|
673
|
+
}], valueChange: [{
|
|
674
|
+
type: Output
|
|
675
|
+
}], touched: [{
|
|
676
|
+
type: Output
|
|
677
|
+
}] } });
|
|
678
|
+
|
|
566
679
|
class InputCheckboxComponent {
|
|
567
680
|
label;
|
|
681
|
+
hint;
|
|
682
|
+
error;
|
|
683
|
+
required = false;
|
|
568
684
|
disabled = false;
|
|
569
685
|
value = false;
|
|
570
|
-
valueChange = new EventEmitter();
|
|
571
686
|
onChange = () => undefined;
|
|
572
687
|
onTouched = () => undefined;
|
|
573
688
|
writeValue(value) { this.value = !!value; }
|
|
@@ -578,22 +693,27 @@ class InputCheckboxComponent {
|
|
|
578
693
|
const value = event.target.checked;
|
|
579
694
|
this.value = value;
|
|
580
695
|
this.onChange(value);
|
|
581
|
-
|
|
696
|
+
}
|
|
697
|
+
handleValueChange(value) {
|
|
698
|
+
this.value = value;
|
|
699
|
+
this.onChange(value);
|
|
582
700
|
}
|
|
583
701
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
584
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputCheckboxComponent, isStandalone: true, selector: "input-checkbox", inputs: { label: "label",
|
|
702
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputCheckboxComponent, isStandalone: true, selector: "input-checkbox", inputs: { label: "label", hint: "hint", error: "error", required: "required", disabled: "disabled" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputCheckboxComponent), multi: true }], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-checkbox-control [value]=\"value\" [disabled]=\"disabled\" (valueChange)=\"handleValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputCheckboxControlComponent, selector: "input-checkbox-control", inputs: ["value", "disabled"], outputs: ["valueChange", "touched"] }] });
|
|
585
703
|
}
|
|
586
704
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputCheckboxComponent, decorators: [{
|
|
587
705
|
type: Component,
|
|
588
|
-
args: [{ selector: 'input-checkbox', standalone: true, imports: [CommonModule], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputCheckboxComponent), multi: true }], template: "<label
|
|
706
|
+
args: [{ selector: 'input-checkbox', standalone: true, imports: [CommonModule, FieldFrameComponent, InputCheckboxControlComponent], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputCheckboxComponent), multi: true }], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-checkbox-control [value]=\"value\" [disabled]=\"disabled\" (valueChange)=\"handleValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
589
707
|
}], propDecorators: { label: [{
|
|
590
708
|
type: Input
|
|
591
|
-
}],
|
|
709
|
+
}], hint: [{
|
|
592
710
|
type: Input
|
|
593
|
-
}],
|
|
711
|
+
}], error: [{
|
|
712
|
+
type: Input
|
|
713
|
+
}], required: [{
|
|
714
|
+
type: Input
|
|
715
|
+
}], disabled: [{
|
|
594
716
|
type: Input
|
|
595
|
-
}], valueChange: [{
|
|
596
|
-
type: Output
|
|
597
717
|
}] } });
|
|
598
718
|
|
|
599
719
|
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -618,6 +738,56 @@ const validateFormControl = (control, required, pattern, email = false) => {
|
|
|
618
738
|
return null;
|
|
619
739
|
};
|
|
620
740
|
|
|
741
|
+
class InputColorControlComponent {
|
|
742
|
+
id;
|
|
743
|
+
name;
|
|
744
|
+
disabled = false;
|
|
745
|
+
value = '#000000';
|
|
746
|
+
pickerValue = '#000000';
|
|
747
|
+
valueChange = new EventEmitter();
|
|
748
|
+
touched = new EventEmitter();
|
|
749
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputColorControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
750
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputColorControlComponent, isStandalone: true, selector: "input-color-control", inputs: { id: "id", name: "name", disabled: "disabled", value: "value", pickerValue: "pickerValue" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `
|
|
751
|
+
<div class="flex items-center gap-3">
|
|
752
|
+
<label class="relative inline-flex h-11 w-11 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white shadow-sm transition hover:border-slate-300" [class.cursor-not-allowed]="disabled" [class.opacity-60]="disabled" [attr.for]="id">
|
|
753
|
+
<span class="block h-9 w-9 rounded-full border border-black/10" [style.backgroundColor]="pickerValue"></span>
|
|
754
|
+
<input class="absolute inset-0 h-full w-full cursor-pointer opacity-0" type="color" [attr.id]="id" [attr.name]="name ? name + '-picker' : null" [disabled]="disabled" [value]="pickerValue" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
755
|
+
</label>
|
|
756
|
+
<input class="min-w-[110px] rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-xs font-semibold uppercase text-slate-700 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200 disabled:cursor-not-allowed disabled:opacity-60" type="text" [attr.name]="name" [disabled]="disabled" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
757
|
+
</div>
|
|
758
|
+
`, isInline: true });
|
|
759
|
+
}
|
|
760
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputColorControlComponent, decorators: [{
|
|
761
|
+
type: Component,
|
|
762
|
+
args: [{
|
|
763
|
+
selector: 'input-color-control',
|
|
764
|
+
standalone: true,
|
|
765
|
+
template: `
|
|
766
|
+
<div class="flex items-center gap-3">
|
|
767
|
+
<label class="relative inline-flex h-11 w-11 cursor-pointer items-center justify-center rounded-full border border-slate-200 bg-white shadow-sm transition hover:border-slate-300" [class.cursor-not-allowed]="disabled" [class.opacity-60]="disabled" [attr.for]="id">
|
|
768
|
+
<span class="block h-9 w-9 rounded-full border border-black/10" [style.backgroundColor]="pickerValue"></span>
|
|
769
|
+
<input class="absolute inset-0 h-full w-full cursor-pointer opacity-0" type="color" [attr.id]="id" [attr.name]="name ? name + '-picker' : null" [disabled]="disabled" [value]="pickerValue" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
770
|
+
</label>
|
|
771
|
+
<input class="min-w-[110px] rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-xs font-semibold uppercase text-slate-700 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200 disabled:cursor-not-allowed disabled:opacity-60" type="text" [attr.name]="name" [disabled]="disabled" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
772
|
+
</div>
|
|
773
|
+
`,
|
|
774
|
+
}]
|
|
775
|
+
}], propDecorators: { id: [{
|
|
776
|
+
type: Input
|
|
777
|
+
}], name: [{
|
|
778
|
+
type: Input
|
|
779
|
+
}], disabled: [{
|
|
780
|
+
type: Input
|
|
781
|
+
}], value: [{
|
|
782
|
+
type: Input
|
|
783
|
+
}], pickerValue: [{
|
|
784
|
+
type: Input
|
|
785
|
+
}], valueChange: [{
|
|
786
|
+
type: Output
|
|
787
|
+
}], touched: [{
|
|
788
|
+
type: Output
|
|
789
|
+
}] } });
|
|
790
|
+
|
|
621
791
|
class InputColorComponent {
|
|
622
792
|
cdr = inject(ChangeDetectorRef);
|
|
623
793
|
label;
|
|
@@ -625,7 +795,6 @@ class InputColorComponent {
|
|
|
625
795
|
name;
|
|
626
796
|
id;
|
|
627
797
|
required = false;
|
|
628
|
-
fullWidth = false;
|
|
629
798
|
error;
|
|
630
799
|
disabled = false;
|
|
631
800
|
value = '#000000';
|
|
@@ -662,6 +831,10 @@ class InputColorComponent {
|
|
|
662
831
|
this.value = this.normalizeHexInput(value);
|
|
663
832
|
this.onChange(this.value);
|
|
664
833
|
}
|
|
834
|
+
handleValueChange(value) {
|
|
835
|
+
this.value = value;
|
|
836
|
+
this.onChange(value);
|
|
837
|
+
}
|
|
665
838
|
markTouched() {
|
|
666
839
|
this.onTouched();
|
|
667
840
|
}
|
|
@@ -676,25 +849,25 @@ class InputColorComponent {
|
|
|
676
849
|
return /^#([0-9a-fA-F]{6})$/.test(value.trim());
|
|
677
850
|
}
|
|
678
851
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputColorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
679
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
852
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputColorComponent, isStandalone: true, selector: "input-color", inputs: { label: "label", hint: "hint", name: "name", id: "id", required: "required", error: "error" }, providers: [
|
|
680
853
|
{
|
|
681
854
|
provide: NG_VALUE_ACCESSOR,
|
|
682
855
|
useExisting: forwardRef(() => InputColorComponent),
|
|
683
856
|
multi: true,
|
|
684
857
|
},
|
|
685
858
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputColorComponent), multi: true },
|
|
686
|
-
], ngImport: i0, template: "<
|
|
859
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\">\n <input-color-control [id]=\"controlId\" [name]=\"name\" [disabled]=\"disabled\" [value]=\"value\" [pickerValue]=\"pickerValue\" (valueChange)=\"handleValueChange($event)\" (touched)=\"markTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputColorControlComponent, selector: "input-color-control", inputs: ["id", "name", "disabled", "value", "pickerValue"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
687
860
|
}
|
|
688
861
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputColorComponent, decorators: [{
|
|
689
862
|
type: Component,
|
|
690
|
-
args: [{ selector: 'input-color', standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
863
|
+
args: [{ selector: 'input-color', standalone: true, imports: [CommonModule, FormsModule, FieldFrameComponent, InputColorControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
691
864
|
{
|
|
692
865
|
provide: NG_VALUE_ACCESSOR,
|
|
693
866
|
useExisting: forwardRef(() => InputColorComponent),
|
|
694
867
|
multi: true,
|
|
695
868
|
},
|
|
696
869
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputColorComponent), multi: true },
|
|
697
|
-
], template: "<
|
|
870
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\">\n <input-color-control [id]=\"controlId\" [name]=\"name\" [disabled]=\"disabled\" [value]=\"value\" [pickerValue]=\"pickerValue\" (valueChange)=\"handleValueChange($event)\" (touched)=\"markTouched()\" />\n</field-frame>\n" }]
|
|
698
871
|
}], propDecorators: { label: [{
|
|
699
872
|
type: Input
|
|
700
873
|
}], hint: [{
|
|
@@ -705,8 +878,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
705
878
|
type: Input
|
|
706
879
|
}], required: [{
|
|
707
880
|
type: Input
|
|
708
|
-
}], fullWidth: [{
|
|
709
|
-
type: Input
|
|
710
881
|
}], error: [{
|
|
711
882
|
type: Input
|
|
712
883
|
}] } });
|
|
@@ -733,7 +904,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
733
904
|
args: [{ providedIn: 'root' }]
|
|
734
905
|
}] });
|
|
735
906
|
|
|
736
|
-
class
|
|
907
|
+
class InputDateControlComponent {
|
|
737
908
|
cdr = inject(ChangeDetectorRef);
|
|
738
909
|
popupService = inject(UiPopupService);
|
|
739
910
|
closeActivePopup = () => this.closeCalendar();
|
|
@@ -749,7 +920,6 @@ class InputDateComponent {
|
|
|
749
920
|
nextMonthIcon = ChevronRight;
|
|
750
921
|
rows = 4;
|
|
751
922
|
required = false;
|
|
752
|
-
fullWidth = false;
|
|
753
923
|
autocomplete = 'off';
|
|
754
924
|
pattern;
|
|
755
925
|
error;
|
|
@@ -757,7 +927,7 @@ class InputDateComponent {
|
|
|
757
927
|
disabled = false;
|
|
758
928
|
value = '';
|
|
759
929
|
static nextId = 0;
|
|
760
|
-
generatedId = `input-date-${
|
|
930
|
+
generatedId = `input-date-${InputDateControlComponent.nextId++}`;
|
|
761
931
|
visibleMonth = this.startOfMonth(new Date());
|
|
762
932
|
calendarView = 'days';
|
|
763
933
|
isCalendarOpen = false;
|
|
@@ -966,26 +1136,26 @@ class InputDateComponent {
|
|
|
966
1136
|
const day = String(date.getDate()).padStart(2, '0');
|
|
967
1137
|
return `${year}-${month}-${day}`;
|
|
968
1138
|
}
|
|
969
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
970
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type:
|
|
1139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDateControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1140
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputDateControlComponent, isStandalone: true, selector: "input-date-control", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions", disabled: "disabled" }, outputs: { actionTriggered: "actionTriggered" }, host: { listeners: { "document:click": "onDocumentClick()", "document:keydown.escape": "onEscape()" } }, providers: [
|
|
971
1141
|
{
|
|
972
1142
|
provide: NG_VALUE_ACCESSOR,
|
|
973
|
-
useExisting: forwardRef(() =>
|
|
1143
|
+
useExisting: forwardRef(() => InputDateControlComponent),
|
|
974
1144
|
multi: true,
|
|
975
1145
|
},
|
|
976
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
977
|
-
], ngImport: i0, template: "
|
|
1146
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDateControlComponent), multi: true },
|
|
1147
|
+
], ngImport: i0, template: "\n <div class=\"flex items-end gap-2\">\n <div class=\"min-w-0 flex-1\">\n @if (element === 'textarea') {\n <textarea\n [attr.rows]=\"rows\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.id]=\"controlId\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (blur)=\"onTouched()\"\n ></textarea>\n } @else {\n <div class=\"relative\">\n <input\n type=\"text\"\n [attr.placeholder]=\"placeholder ?? '\u0414\u0414.\u041C\u041C.\u0420\u0420\u0420\u0420'\"\n maxlength=\"10\"\n inputmode=\"numeric\"\n [attr.name]=\"name\"\n [attr.autocomplete]=\"autocomplete\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [attr.id]=\"controlId\"\n [value]=\"displayValue\"\n (click)=\"openCalendar($event)\"\n (keydown)=\"allowDateKey($event)\"\n (input)=\"onValueChange($any($event.target).value)\"\n (blur)=\"onTouched()\"\n />\n <lucide-icon\n [img]=\"calendarIcon\"\n class=\"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400\"\n aria-hidden=\"true\"\n ></lucide-icon>\n\n @if (isCalendarOpen) {\n <div\n class=\"absolute left-0 top-full z-50 mt-2 w-[min(20rem,calc(100vw-2rem))] rounded-xl border border-slate-200 bg-white p-4 shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"mb-4 flex items-center justify-between\" [class.justify-center]=\"calendarView === 'months'\">\n @if (calendarView !== 'months') {\n <button\n type=\"button\"\n class=\"rounded-lg p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900\"\n aria-label=\"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0456\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\"\n (click)=\"changeMonth(-1, $event)\"\n >\n <lucide-icon [img]=\"previousMonthIcon\" class=\"h-4 w-4\"></lucide-icon>\n </button>\n }\n <div class=\"flex items-center gap-1\">\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-1 text-sm font-semibold capitalize text-slate-900 transition hover:bg-slate-100\"\n (click)=\"showMonthPicker($event)\"\n >\n {{ monthName }}\n </button>\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-1 text-sm font-semibold text-slate-900 transition hover:bg-slate-100\"\n (click)=\"showYearPicker($event)\"\n >\n {{ yearLabel }}\n </button>\n </div>\n @if (calendarView !== 'months') {\n <button\n type=\"button\"\n class=\"rounded-lg p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900\"\n aria-label=\"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\"\n (click)=\"changeMonth(1, $event)\"\n >\n <lucide-icon [img]=\"nextMonthIcon\" class=\"h-4 w-4\"></lucide-icon>\n </button>\n }\n </div>\n\n @if (calendarView === 'days') {\n <div class=\"mb-2 grid grid-cols-7 text-center text-xs font-medium text-slate-400\">\n @for (weekday of ['\u041F\u043D', '\u0412\u0442', '\u0421\u0440', '\u0427\u0442', '\u041F\u0442', '\u0421\u0431', '\u041D\u0434']; track weekday) {\n <span class=\"py-1\">{{ weekday }}</span>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-1\">\n @for (day of calendarDays; track day.date) {\n <button\n type=\"button\"\n class=\"aspect-square rounded-lg text-sm transition hover:bg-slate-100 hover:text-slate-900\"\n [class.text-slate-300]=\"!day.currentMonth\"\n [class.text-slate-700]=\"day.currentMonth && !isSelected(day.date)\"\n [class.bg-slate-900]=\"isSelected(day.date)\"\n [class.text-white]=\"isSelected(day.date)\"\n (click)=\"selectDate(day.date, $event)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n } @else if (calendarView === 'months') {\n <div class=\"grid grid-cols-3 gap-2\">\n @for (month of monthOptions; track month.value) {\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-3 text-sm capitalize text-slate-700 transition hover:bg-slate-100 hover:text-slate-900\"\n [class.bg-slate-900]=\"isSelectedMonth(month.value)\"\n [class.text-white]=\"isSelectedMonth(month.value)\"\n (click)=\"selectMonth(month.value, $event)\"\n >\n {{ month.label }}\n </button>\n }\n </div>\n } @else {\n <div class=\"grid grid-cols-3 gap-2\">\n @for (year of yearOptions; track year) {\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-3 text-sm text-slate-700 transition hover:bg-slate-100 hover:text-slate-900\"\n [class.bg-slate-900]=\"isSelectedYear(year)\"\n [class.text-white]=\"isSelectedYear(year)\"\n (click)=\"selectYear(year, $event)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n </div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
978
1148
|
}
|
|
979
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
1149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDateControlComponent, decorators: [{
|
|
980
1150
|
type: Component,
|
|
981
|
-
args: [{ selector: 'input-date', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1151
|
+
args: [{ selector: 'input-date-control', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
982
1152
|
{
|
|
983
1153
|
provide: NG_VALUE_ACCESSOR,
|
|
984
|
-
useExisting: forwardRef(() =>
|
|
1154
|
+
useExisting: forwardRef(() => InputDateControlComponent),
|
|
985
1155
|
multi: true,
|
|
986
1156
|
},
|
|
987
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
988
|
-
], template: "
|
|
1157
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDateControlComponent), multi: true },
|
|
1158
|
+
], template: "\n <div class=\"flex items-end gap-2\">\n <div class=\"min-w-0 flex-1\">\n @if (element === 'textarea') {\n <textarea\n [attr.rows]=\"rows\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.id]=\"controlId\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (blur)=\"onTouched()\"\n ></textarea>\n } @else {\n <div class=\"relative\">\n <input\n type=\"text\"\n [attr.placeholder]=\"placeholder ?? '\u0414\u0414.\u041C\u041C.\u0420\u0420\u0420\u0420'\"\n maxlength=\"10\"\n inputmode=\"numeric\"\n [attr.name]=\"name\"\n [attr.autocomplete]=\"autocomplete\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [attr.id]=\"controlId\"\n [value]=\"displayValue\"\n (click)=\"openCalendar($event)\"\n (keydown)=\"allowDateKey($event)\"\n (input)=\"onValueChange($any($event.target).value)\"\n (blur)=\"onTouched()\"\n />\n <lucide-icon\n [img]=\"calendarIcon\"\n class=\"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400\"\n aria-hidden=\"true\"\n ></lucide-icon>\n\n @if (isCalendarOpen) {\n <div\n class=\"absolute left-0 top-full z-50 mt-2 w-[min(20rem,calc(100vw-2rem))] rounded-xl border border-slate-200 bg-white p-4 shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"mb-4 flex items-center justify-between\" [class.justify-center]=\"calendarView === 'months'\">\n @if (calendarView !== 'months') {\n <button\n type=\"button\"\n class=\"rounded-lg p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900\"\n aria-label=\"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0456\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\"\n (click)=\"changeMonth(-1, $event)\"\n >\n <lucide-icon [img]=\"previousMonthIcon\" class=\"h-4 w-4\"></lucide-icon>\n </button>\n }\n <div class=\"flex items-center gap-1\">\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-1 text-sm font-semibold capitalize text-slate-900 transition hover:bg-slate-100\"\n (click)=\"showMonthPicker($event)\"\n >\n {{ monthName }}\n </button>\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-1 text-sm font-semibold text-slate-900 transition hover:bg-slate-100\"\n (click)=\"showYearPicker($event)\"\n >\n {{ yearLabel }}\n </button>\n </div>\n @if (calendarView !== 'months') {\n <button\n type=\"button\"\n class=\"rounded-lg p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900\"\n aria-label=\"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\"\n (click)=\"changeMonth(1, $event)\"\n >\n <lucide-icon [img]=\"nextMonthIcon\" class=\"h-4 w-4\"></lucide-icon>\n </button>\n }\n </div>\n\n @if (calendarView === 'days') {\n <div class=\"mb-2 grid grid-cols-7 text-center text-xs font-medium text-slate-400\">\n @for (weekday of ['\u041F\u043D', '\u0412\u0442', '\u0421\u0440', '\u0427\u0442', '\u041F\u0442', '\u0421\u0431', '\u041D\u0434']; track weekday) {\n <span class=\"py-1\">{{ weekday }}</span>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-1\">\n @for (day of calendarDays; track day.date) {\n <button\n type=\"button\"\n class=\"aspect-square rounded-lg text-sm transition hover:bg-slate-100 hover:text-slate-900\"\n [class.text-slate-300]=\"!day.currentMonth\"\n [class.text-slate-700]=\"day.currentMonth && !isSelected(day.date)\"\n [class.bg-slate-900]=\"isSelected(day.date)\"\n [class.text-white]=\"isSelected(day.date)\"\n (click)=\"selectDate(day.date, $event)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n } @else if (calendarView === 'months') {\n <div class=\"grid grid-cols-3 gap-2\">\n @for (month of monthOptions; track month.value) {\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-3 text-sm capitalize text-slate-700 transition hover:bg-slate-100 hover:text-slate-900\"\n [class.bg-slate-900]=\"isSelectedMonth(month.value)\"\n [class.text-white]=\"isSelectedMonth(month.value)\"\n (click)=\"selectMonth(month.value, $event)\"\n >\n {{ month.label }}\n </button>\n }\n </div>\n } @else {\n <div class=\"grid grid-cols-3 gap-2\">\n @for (year of yearOptions; track year) {\n <button\n type=\"button\"\n class=\"rounded-lg px-2 py-3 text-sm text-slate-700 transition hover:bg-slate-100 hover:text-slate-900\"\n [class.bg-slate-900]=\"isSelectedYear(year)\"\n [class.text-white]=\"isSelectedYear(year)\"\n (click)=\"selectYear(year, $event)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n </div>\n" }]
|
|
989
1159
|
}], propDecorators: { label: [{
|
|
990
1160
|
type: Input
|
|
991
1161
|
}], hint: [{
|
|
@@ -1000,8 +1170,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1000
1170
|
type: Input
|
|
1001
1171
|
}], required: [{
|
|
1002
1172
|
type: Input
|
|
1003
|
-
}], fullWidth: [{
|
|
1004
|
-
type: Input
|
|
1005
1173
|
}], autocomplete: [{
|
|
1006
1174
|
type: Input
|
|
1007
1175
|
}], pattern: [{
|
|
@@ -1010,6 +1178,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1010
1178
|
type: Input
|
|
1011
1179
|
}], actions: [{
|
|
1012
1180
|
type: Input
|
|
1181
|
+
}], disabled: [{
|
|
1182
|
+
type: Input
|
|
1013
1183
|
}], actionTriggered: [{
|
|
1014
1184
|
type: Output
|
|
1015
1185
|
}], onDocumentClick: [{
|
|
@@ -1020,7 +1190,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1020
1190
|
args: ['document:keydown.escape']
|
|
1021
1191
|
}] } });
|
|
1022
1192
|
|
|
1023
|
-
class
|
|
1193
|
+
class InputDateComponent {
|
|
1194
|
+
control;
|
|
1195
|
+
label;
|
|
1196
|
+
hint;
|
|
1197
|
+
error;
|
|
1198
|
+
placeholder;
|
|
1199
|
+
name;
|
|
1200
|
+
id;
|
|
1201
|
+
required = false;
|
|
1202
|
+
disabled = false;
|
|
1203
|
+
autocomplete = 'off';
|
|
1204
|
+
pattern;
|
|
1205
|
+
rows = 4;
|
|
1206
|
+
actions = [];
|
|
1207
|
+
actionTriggered = new EventEmitter();
|
|
1208
|
+
pendingValue = '';
|
|
1209
|
+
onChange = () => undefined;
|
|
1210
|
+
onTouched = () => undefined;
|
|
1211
|
+
ngAfterViewInit() { this.control?.registerOnChange((value) => this.onChange(value)); this.control?.registerOnTouched(() => this.onTouched()); this.control?.writeValue(this.pendingValue); }
|
|
1212
|
+
writeValue(value) { this.pendingValue = value; this.control?.writeValue(value); }
|
|
1213
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
1214
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
1215
|
+
setDisabledState(value) { this.disabled = value; }
|
|
1216
|
+
validate(control) { return validateFormControl(control, this.required, this.pattern); }
|
|
1217
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1218
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputDateComponent, isStandalone: true, selector: "input-date", inputs: { label: "label", hint: "hint", error: "error", placeholder: "placeholder", name: "name", id: "id", required: "required", disabled: "disabled", autocomplete: "autocomplete", pattern: "pattern", rows: "rows", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDateComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDateComponent), multi: true }], viewQueries: [{ propertyName: "control", first: true, predicate: InputDateControlComponent, descendants: true }], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"id\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"actionTriggered.emit($event)\">\n <input-date-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"id\" [required]=\"required\" [disabled]=\"disabled\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [rows]=\"rows\" />\n</field-frame>\n", dependencies: [{ kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputDateControlComponent, selector: "input-date-control", inputs: ["label", "hint", "placeholder", "name", "id", "rows", "required", "autocomplete", "pattern", "error", "actions", "disabled"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1219
|
+
}
|
|
1220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDateComponent, decorators: [{
|
|
1221
|
+
type: Component,
|
|
1222
|
+
args: [{ selector: 'input-date', standalone: true, imports: [FieldFrameComponent, InputDateControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDateComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDateComponent), multi: true }], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"id\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"actionTriggered.emit($event)\">\n <input-date-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"id\" [required]=\"required\" [disabled]=\"disabled\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [rows]=\"rows\" />\n</field-frame>\n" }]
|
|
1223
|
+
}], propDecorators: { control: [{
|
|
1224
|
+
type: ViewChild,
|
|
1225
|
+
args: [InputDateControlComponent]
|
|
1226
|
+
}], label: [{
|
|
1227
|
+
type: Input
|
|
1228
|
+
}], hint: [{
|
|
1229
|
+
type: Input
|
|
1230
|
+
}], error: [{
|
|
1231
|
+
type: Input
|
|
1232
|
+
}], placeholder: [{
|
|
1233
|
+
type: Input
|
|
1234
|
+
}], name: [{
|
|
1235
|
+
type: Input
|
|
1236
|
+
}], id: [{
|
|
1237
|
+
type: Input
|
|
1238
|
+
}], required: [{
|
|
1239
|
+
type: Input
|
|
1240
|
+
}], disabled: [{
|
|
1241
|
+
type: Input
|
|
1242
|
+
}], autocomplete: [{
|
|
1243
|
+
type: Input
|
|
1244
|
+
}], pattern: [{
|
|
1245
|
+
type: Input
|
|
1246
|
+
}], rows: [{
|
|
1247
|
+
type: Input
|
|
1248
|
+
}], actions: [{
|
|
1249
|
+
type: Input
|
|
1250
|
+
}], actionTriggered: [{
|
|
1251
|
+
type: Output
|
|
1252
|
+
}] } });
|
|
1253
|
+
|
|
1254
|
+
class InputDatetimeControlComponent {
|
|
1024
1255
|
cdr = inject(ChangeDetectorRef);
|
|
1025
1256
|
popupService = inject(UiPopupService);
|
|
1026
1257
|
closeActivePopup = () => this.closeCalendar();
|
|
@@ -1031,7 +1262,6 @@ class InputDatetimeComponent {
|
|
|
1031
1262
|
id;
|
|
1032
1263
|
rows = 4;
|
|
1033
1264
|
required = false;
|
|
1034
|
-
fullWidth = false;
|
|
1035
1265
|
autocomplete = 'off';
|
|
1036
1266
|
pattern;
|
|
1037
1267
|
error;
|
|
@@ -1048,7 +1278,7 @@ class InputDatetimeComponent {
|
|
|
1048
1278
|
selectedHour = 12;
|
|
1049
1279
|
selectedMinute = 0;
|
|
1050
1280
|
static nextId = 0;
|
|
1051
|
-
generatedId = `input-datetime-${
|
|
1281
|
+
generatedId = `input-datetime-${InputDatetimeControlComponent.nextId++}`;
|
|
1052
1282
|
actionTriggered = new EventEmitter();
|
|
1053
1283
|
onChange = () => undefined;
|
|
1054
1284
|
onTouched = () => undefined;
|
|
@@ -1118,18 +1348,18 @@ class InputDatetimeComponent {
|
|
|
1118
1348
|
startOfMonth(date) { return new Date(date.getFullYear(), date.getMonth(), 1); }
|
|
1119
1349
|
parseDate(value) { const [year, month, day] = value.split('-').map(Number); return year && month && day ? new Date(year, month - 1, day) : null; }
|
|
1120
1350
|
toDateValue(date) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; }
|
|
1121
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
1122
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type:
|
|
1123
|
-
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() =>
|
|
1124
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
1125
|
-
], ngImport: i0, template: "
|
|
1351
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDatetimeControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1352
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputDatetimeControlComponent, isStandalone: true, selector: "input-datetime-control", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions", disabled: "disabled" }, outputs: { actionTriggered: "actionTriggered" }, host: { listeners: { "document:click": "onDocumentClick()", "document:keydown.escape": "onEscape()" } }, providers: [
|
|
1353
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDatetimeControlComponent), multi: true },
|
|
1354
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDatetimeControlComponent), multi: true },
|
|
1355
|
+
], ngImport: i0, template: " <div class=\"flex items-end gap-2\"><div class=\"min-w-0 flex-1\"><div class=\"relative\">\n <input type=\"text\" [attr.placeholder]=\"placeholder ?? '\u0414\u0414.\u041C\u041C.\u0420\u0420\u0420\u0420 \u0413\u0413:\u0425\u0425'\" maxlength=\"16\" inputmode=\"numeric\" [attr.name]=\"name\" [attr.autocomplete]=\"autocomplete\" [disabled]=\"disabled\" class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" [attr.id]=\"controlId\" [value]=\"displayValue\" (click)=\"openCalendar($event)\" (keydown)=\"allowDateKey($event)\" (input)=\"onValueChange($any($event.target).value)\" (blur)=\"onTouched()\" />\n <lucide-icon [img]=\"calendarIcon\" class=\"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400\"></lucide-icon>\n @if (isCalendarOpen) { <div class=\"absolute left-0 top-full z-50 mt-2 w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-slate-200 bg-white p-4 shadow-xl\" (click)=\"$event.stopPropagation()\">\n <div class=\"mb-4 flex items-center justify-between\" [class.justify-center]=\"calendarView === 'months'\">\n @if (calendarView !== 'months') { <button type=\"button\" class=\"rounded-lg p-2 text-slate-500 hover:bg-slate-100\" aria-label=\"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0456\u0439 \u043F\u0435\u0440\u0456\u043E\u0434\" (click)=\"changeMonth(-1, $event)\"><lucide-icon [img]=\"previousMonthIcon\" class=\"h-4 w-4\"></lucide-icon></button> }\n <div class=\"flex items-center gap-1\"><button type=\"button\" class=\"rounded-lg px-2 py-1 text-sm font-semibold capitalize text-slate-900 hover:bg-slate-100\" (click)=\"showMonthPicker($event)\">{{ monthName }}</button><button type=\"button\" class=\"rounded-lg px-2 py-1 text-sm font-semibold text-slate-900 hover:bg-slate-100\" (click)=\"showYearPicker($event)\">{{ yearLabel }}</button></div>\n @if (calendarView !== 'months') { <button type=\"button\" class=\"rounded-lg p-2 text-slate-500 hover:bg-slate-100\" aria-label=\"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u043F\u0435\u0440\u0456\u043E\u0434\" (click)=\"changeMonth(1, $event)\"><lucide-icon [img]=\"nextMonthIcon\" class=\"h-4 w-4\"></lucide-icon></button> }\n </div>\n @if (calendarView === 'days') {\n <div class=\"mb-2 grid grid-cols-7 text-center text-xs font-medium text-slate-400\">@for (weekday of ['\u041F\u043D','\u0412\u0442','\u0421\u0440','\u0427\u0442','\u041F\u0442','\u0421\u0431','\u041D\u0434']; track weekday) { <span class=\"py-1\">{{ weekday }}</span> }</div>\n <div class=\"grid grid-cols-7 gap-1\">@for (day of calendarDays; track day.date) { <button type=\"button\" class=\"aspect-square rounded-lg text-sm hover:bg-slate-100 hover:text-slate-900\" [class.text-slate-300]=\"!day.currentMonth\" [class.text-slate-700]=\"day.currentMonth && !isSelected(day.date)\" [class.bg-slate-900]=\"isSelected(day.date)\" [class.text-white]=\"isSelected(day.date)\" (click)=\"selectDate(day.date, $event)\">{{ day.day }}</button> }</div>\n <div class=\"mt-4 grid grid-cols-2 gap-2 border-t border-slate-100 pt-3\"><label class=\"text-[0.65rem] font-medium text-slate-500\">\u0413\u043E\u0434\u0438\u043D\u0438<input type=\"number\" min=\"0\" max=\"23\" [value]=\"selectedHour\" (input)=\"selectedHour = +$any($event.target).value; onTimeChange()\" class=\"mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" /></label><label class=\"text-[0.65rem] font-medium text-slate-500\">\u0425\u0432\u0438\u043B\u0438\u043D\u0438<input type=\"number\" min=\"0\" max=\"59\" [value]=\"selectedMinute\" (input)=\"selectedMinute = +$any($event.target).value; onTimeChange()\" class=\"mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" /></label></div>\n } @else if (calendarView === 'months') { <div class=\"grid grid-cols-3 gap-2\">@for (month of monthOptions; track month.value) { <button type=\"button\" class=\"rounded-lg px-2 py-3 text-sm capitalize text-slate-700 hover:bg-slate-100 hover:text-slate-900\" [class.bg-slate-900]=\"isSelectedMonth(month.value)\" [class.text-white]=\"isSelectedMonth(month.value)\" (click)=\"selectMonth(month.value, $event)\">{{ month.label }}</button> }</div>\n } @else { <div class=\"grid grid-cols-3 gap-2\">@for (year of yearOptions; track year) { <button type=\"button\" class=\"rounded-lg px-2 py-3 text-sm text-slate-700 hover:bg-slate-100 hover:text-slate-900\" [class.bg-slate-900]=\"isSelectedYear(year)\" [class.text-white]=\"isSelectedYear(year)\" (click)=\"selectYear(year, $event)\">{{ year }}</button> }</div> }\n </div> }\n </div></div>\n </div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1126
1356
|
}
|
|
1127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
1357
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDatetimeControlComponent, decorators: [{
|
|
1128
1358
|
type: Component,
|
|
1129
|
-
args: [{ selector: 'input-datetime', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1130
|
-
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() =>
|
|
1131
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
1132
|
-
], template: "
|
|
1359
|
+
args: [{ selector: 'input-datetime-control', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1360
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDatetimeControlComponent), multi: true },
|
|
1361
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDatetimeControlComponent), multi: true },
|
|
1362
|
+
], template: " <div class=\"flex items-end gap-2\"><div class=\"min-w-0 flex-1\"><div class=\"relative\">\n <input type=\"text\" [attr.placeholder]=\"placeholder ?? '\u0414\u0414.\u041C\u041C.\u0420\u0420\u0420\u0420 \u0413\u0413:\u0425\u0425'\" maxlength=\"16\" inputmode=\"numeric\" [attr.name]=\"name\" [attr.autocomplete]=\"autocomplete\" [disabled]=\"disabled\" class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" [attr.id]=\"controlId\" [value]=\"displayValue\" (click)=\"openCalendar($event)\" (keydown)=\"allowDateKey($event)\" (input)=\"onValueChange($any($event.target).value)\" (blur)=\"onTouched()\" />\n <lucide-icon [img]=\"calendarIcon\" class=\"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400\"></lucide-icon>\n @if (isCalendarOpen) { <div class=\"absolute left-0 top-full z-50 mt-2 w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-slate-200 bg-white p-4 shadow-xl\" (click)=\"$event.stopPropagation()\">\n <div class=\"mb-4 flex items-center justify-between\" [class.justify-center]=\"calendarView === 'months'\">\n @if (calendarView !== 'months') { <button type=\"button\" class=\"rounded-lg p-2 text-slate-500 hover:bg-slate-100\" aria-label=\"\u041F\u043E\u043F\u0435\u0440\u0435\u0434\u043D\u0456\u0439 \u043F\u0435\u0440\u0456\u043E\u0434\" (click)=\"changeMonth(-1, $event)\"><lucide-icon [img]=\"previousMonthIcon\" class=\"h-4 w-4\"></lucide-icon></button> }\n <div class=\"flex items-center gap-1\"><button type=\"button\" class=\"rounded-lg px-2 py-1 text-sm font-semibold capitalize text-slate-900 hover:bg-slate-100\" (click)=\"showMonthPicker($event)\">{{ monthName }}</button><button type=\"button\" class=\"rounded-lg px-2 py-1 text-sm font-semibold text-slate-900 hover:bg-slate-100\" (click)=\"showYearPicker($event)\">{{ yearLabel }}</button></div>\n @if (calendarView !== 'months') { <button type=\"button\" class=\"rounded-lg p-2 text-slate-500 hover:bg-slate-100\" aria-label=\"\u041D\u0430\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u043F\u0435\u0440\u0456\u043E\u0434\" (click)=\"changeMonth(1, $event)\"><lucide-icon [img]=\"nextMonthIcon\" class=\"h-4 w-4\"></lucide-icon></button> }\n </div>\n @if (calendarView === 'days') {\n <div class=\"mb-2 grid grid-cols-7 text-center text-xs font-medium text-slate-400\">@for (weekday of ['\u041F\u043D','\u0412\u0442','\u0421\u0440','\u0427\u0442','\u041F\u0442','\u0421\u0431','\u041D\u0434']; track weekday) { <span class=\"py-1\">{{ weekday }}</span> }</div>\n <div class=\"grid grid-cols-7 gap-1\">@for (day of calendarDays; track day.date) { <button type=\"button\" class=\"aspect-square rounded-lg text-sm hover:bg-slate-100 hover:text-slate-900\" [class.text-slate-300]=\"!day.currentMonth\" [class.text-slate-700]=\"day.currentMonth && !isSelected(day.date)\" [class.bg-slate-900]=\"isSelected(day.date)\" [class.text-white]=\"isSelected(day.date)\" (click)=\"selectDate(day.date, $event)\">{{ day.day }}</button> }</div>\n <div class=\"mt-4 grid grid-cols-2 gap-2 border-t border-slate-100 pt-3\"><label class=\"text-[0.65rem] font-medium text-slate-500\">\u0413\u043E\u0434\u0438\u043D\u0438<input type=\"number\" min=\"0\" max=\"23\" [value]=\"selectedHour\" (input)=\"selectedHour = +$any($event.target).value; onTimeChange()\" class=\"mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" /></label><label class=\"text-[0.65rem] font-medium text-slate-500\">\u0425\u0432\u0438\u043B\u0438\u043D\u0438<input type=\"number\" min=\"0\" max=\"59\" [value]=\"selectedMinute\" (input)=\"selectedMinute = +$any($event.target).value; onTimeChange()\" class=\"mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\" /></label></div>\n } @else if (calendarView === 'months') { <div class=\"grid grid-cols-3 gap-2\">@for (month of monthOptions; track month.value) { <button type=\"button\" class=\"rounded-lg px-2 py-3 text-sm capitalize text-slate-700 hover:bg-slate-100 hover:text-slate-900\" [class.bg-slate-900]=\"isSelectedMonth(month.value)\" [class.text-white]=\"isSelectedMonth(month.value)\" (click)=\"selectMonth(month.value, $event)\">{{ month.label }}</button> }</div>\n } @else { <div class=\"grid grid-cols-3 gap-2\">@for (year of yearOptions; track year) { <button type=\"button\" class=\"rounded-lg px-2 py-3 text-sm text-slate-700 hover:bg-slate-100 hover:text-slate-900\" [class.bg-slate-900]=\"isSelectedYear(year)\" [class.text-white]=\"isSelectedYear(year)\" (click)=\"selectYear(year, $event)\">{{ year }}</button> }</div> }\n </div> }\n </div></div>\n </div>\n" }]
|
|
1133
1363
|
}], propDecorators: { label: [{
|
|
1134
1364
|
type: Input
|
|
1135
1365
|
}], hint: [{
|
|
@@ -1144,8 +1374,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1144
1374
|
type: Input
|
|
1145
1375
|
}], required: [{
|
|
1146
1376
|
type: Input
|
|
1147
|
-
}], fullWidth: [{
|
|
1148
|
-
type: Input
|
|
1149
1377
|
}], autocomplete: [{
|
|
1150
1378
|
type: Input
|
|
1151
1379
|
}], pattern: [{
|
|
@@ -1154,6 +1382,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1154
1382
|
type: Input
|
|
1155
1383
|
}], actions: [{
|
|
1156
1384
|
type: Input
|
|
1385
|
+
}], disabled: [{
|
|
1386
|
+
type: Input
|
|
1157
1387
|
}], actionTriggered: [{
|
|
1158
1388
|
type: Output
|
|
1159
1389
|
}], onDocumentClick: [{
|
|
@@ -1164,6 +1394,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1164
1394
|
args: ['document:keydown.escape']
|
|
1165
1395
|
}] } });
|
|
1166
1396
|
|
|
1397
|
+
class InputDatetimeComponent {
|
|
1398
|
+
control;
|
|
1399
|
+
label;
|
|
1400
|
+
hint;
|
|
1401
|
+
error;
|
|
1402
|
+
placeholder;
|
|
1403
|
+
name;
|
|
1404
|
+
id;
|
|
1405
|
+
required = false;
|
|
1406
|
+
disabled = false;
|
|
1407
|
+
autocomplete = 'off';
|
|
1408
|
+
pattern;
|
|
1409
|
+
rows = 4;
|
|
1410
|
+
actions = [];
|
|
1411
|
+
actionTriggered = new EventEmitter();
|
|
1412
|
+
pendingValue = '';
|
|
1413
|
+
onChange = () => undefined;
|
|
1414
|
+
onTouched = () => undefined;
|
|
1415
|
+
ngAfterViewInit() { this.control?.registerOnChange((value) => this.onChange(value)); this.control?.registerOnTouched(() => this.onTouched()); this.control?.writeValue(this.pendingValue); }
|
|
1416
|
+
writeValue(value) { this.pendingValue = value; this.control?.writeValue(value); }
|
|
1417
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
1418
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
1419
|
+
setDisabledState(value) { this.disabled = value; }
|
|
1420
|
+
validate(control) { return validateFormControl(control, this.required, this.pattern); }
|
|
1421
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDatetimeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1422
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputDatetimeComponent, isStandalone: true, selector: "input-datetime", inputs: { label: "label", hint: "hint", error: "error", placeholder: "placeholder", name: "name", id: "id", required: "required", disabled: "disabled", autocomplete: "autocomplete", pattern: "pattern", rows: "rows", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDatetimeComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDatetimeComponent), multi: true }], viewQueries: [{ propertyName: "control", first: true, predicate: InputDatetimeControlComponent, descendants: true }], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"id\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"actionTriggered.emit($event)\">\n <input-datetime-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"id\" [required]=\"required\" [disabled]=\"disabled\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [rows]=\"rows\" />\n</field-frame>\n", dependencies: [{ kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputDatetimeControlComponent, selector: "input-datetime-control", inputs: ["label", "hint", "placeholder", "name", "id", "rows", "required", "autocomplete", "pattern", "error", "actions", "disabled"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1423
|
+
}
|
|
1424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputDatetimeComponent, decorators: [{
|
|
1425
|
+
type: Component,
|
|
1426
|
+
args: [{ selector: 'input-datetime', standalone: true, imports: [FieldFrameComponent, InputDatetimeControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputDatetimeComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => InputDatetimeComponent), multi: true }], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"id\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"actionTriggered.emit($event)\">\n <input-datetime-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"id\" [required]=\"required\" [disabled]=\"disabled\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [rows]=\"rows\" />\n</field-frame>\n" }]
|
|
1427
|
+
}], propDecorators: { control: [{
|
|
1428
|
+
type: ViewChild,
|
|
1429
|
+
args: [InputDatetimeControlComponent]
|
|
1430
|
+
}], label: [{
|
|
1431
|
+
type: Input
|
|
1432
|
+
}], hint: [{
|
|
1433
|
+
type: Input
|
|
1434
|
+
}], error: [{
|
|
1435
|
+
type: Input
|
|
1436
|
+
}], placeholder: [{
|
|
1437
|
+
type: Input
|
|
1438
|
+
}], name: [{
|
|
1439
|
+
type: Input
|
|
1440
|
+
}], id: [{
|
|
1441
|
+
type: Input
|
|
1442
|
+
}], required: [{
|
|
1443
|
+
type: Input
|
|
1444
|
+
}], disabled: [{
|
|
1445
|
+
type: Input
|
|
1446
|
+
}], autocomplete: [{
|
|
1447
|
+
type: Input
|
|
1448
|
+
}], pattern: [{
|
|
1449
|
+
type: Input
|
|
1450
|
+
}], rows: [{
|
|
1451
|
+
type: Input
|
|
1452
|
+
}], actions: [{
|
|
1453
|
+
type: Input
|
|
1454
|
+
}], actionTriggered: [{
|
|
1455
|
+
type: Output
|
|
1456
|
+
}] } });
|
|
1457
|
+
|
|
1458
|
+
class InputTextControlComponent {
|
|
1459
|
+
placeholder;
|
|
1460
|
+
name;
|
|
1461
|
+
id;
|
|
1462
|
+
type = 'text';
|
|
1463
|
+
element = 'input';
|
|
1464
|
+
rows = 4;
|
|
1465
|
+
autocomplete;
|
|
1466
|
+
pattern;
|
|
1467
|
+
disabled = false;
|
|
1468
|
+
value = '';
|
|
1469
|
+
valueChange = new EventEmitter();
|
|
1470
|
+
touched = new EventEmitter();
|
|
1471
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1472
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputTextControlComponent, isStandalone: true, selector: "input-text-control", inputs: { placeholder: "placeholder", name: "name", id: "id", type: "type", element: "element", rows: "rows", autocomplete: "autocomplete", pattern: "pattern", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: "@if (element === 'textarea') {\n <textarea\n [attr.rows]=\"rows\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.id]=\"id\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [value]=\"value\"\n (input)=\"valueChange.emit($any($event.target).value)\"\n (blur)=\"touched.emit()\"\n ></textarea>\n} @else {\n <input\n [attr.type]=\"type\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.pattern]=\"pattern\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [attr.id]=\"id\"\n [value]=\"value\"\n (input)=\"valueChange.emit($any($event.target).value)\"\n (blur)=\"touched.emit()\"\n />\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1473
|
+
}
|
|
1474
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextControlComponent, decorators: [{
|
|
1475
|
+
type: Component,
|
|
1476
|
+
args: [{ selector: 'input-text-control', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (element === 'textarea') {\n <textarea\n [attr.rows]=\"rows\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.id]=\"id\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [value]=\"value\"\n (input)=\"valueChange.emit($any($event.target).value)\"\n (blur)=\"touched.emit()\"\n ></textarea>\n} @else {\n <input\n [attr.type]=\"type\"\n [attr.placeholder]=\"placeholder\"\n [attr.name]=\"name\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.pattern]=\"pattern\"\n [disabled]=\"disabled\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [attr.id]=\"id\"\n [value]=\"value\"\n (input)=\"valueChange.emit($any($event.target).value)\"\n (blur)=\"touched.emit()\"\n />\n}\n" }]
|
|
1477
|
+
}], propDecorators: { placeholder: [{
|
|
1478
|
+
type: Input
|
|
1479
|
+
}], name: [{
|
|
1480
|
+
type: Input
|
|
1481
|
+
}], id: [{
|
|
1482
|
+
type: Input
|
|
1483
|
+
}], type: [{
|
|
1484
|
+
type: Input
|
|
1485
|
+
}], element: [{
|
|
1486
|
+
type: Input
|
|
1487
|
+
}], rows: [{
|
|
1488
|
+
type: Input
|
|
1489
|
+
}], autocomplete: [{
|
|
1490
|
+
type: Input
|
|
1491
|
+
}], pattern: [{
|
|
1492
|
+
type: Input
|
|
1493
|
+
}], disabled: [{
|
|
1494
|
+
type: Input
|
|
1495
|
+
}], value: [{
|
|
1496
|
+
type: Input
|
|
1497
|
+
}], valueChange: [{
|
|
1498
|
+
type: Output
|
|
1499
|
+
}], touched: [{
|
|
1500
|
+
type: Output
|
|
1501
|
+
}] } });
|
|
1502
|
+
|
|
1503
|
+
class InputEmailControlComponent {
|
|
1504
|
+
placeholder;
|
|
1505
|
+
name;
|
|
1506
|
+
id;
|
|
1507
|
+
autocomplete;
|
|
1508
|
+
pattern;
|
|
1509
|
+
disabled = false;
|
|
1510
|
+
value = '';
|
|
1511
|
+
valueChange = new EventEmitter();
|
|
1512
|
+
touched = new EventEmitter();
|
|
1513
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputEmailControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1514
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputEmailControlComponent, isStandalone: true, selector: "input-email-control", inputs: { placeholder: "placeholder", name: "name", id: "id", autocomplete: "autocomplete", pattern: "pattern", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" type="email" [autocomplete]="autocomplete" [pattern]="pattern" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />`, isInline: true, dependencies: [{ kind: "component", type: InputTextControlComponent, selector: "input-text-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }] });
|
|
1515
|
+
}
|
|
1516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputEmailControlComponent, decorators: [{
|
|
1517
|
+
type: Component,
|
|
1518
|
+
args: [{ selector: 'input-email-control', standalone: true, imports: [InputTextControlComponent], template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" type="email" [autocomplete]="autocomplete" [pattern]="pattern" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />` }]
|
|
1519
|
+
}], propDecorators: { placeholder: [{
|
|
1520
|
+
type: Input
|
|
1521
|
+
}], name: [{
|
|
1522
|
+
type: Input
|
|
1523
|
+
}], id: [{
|
|
1524
|
+
type: Input
|
|
1525
|
+
}], autocomplete: [{
|
|
1526
|
+
type: Input
|
|
1527
|
+
}], pattern: [{
|
|
1528
|
+
type: Input
|
|
1529
|
+
}], disabled: [{
|
|
1530
|
+
type: Input
|
|
1531
|
+
}], value: [{
|
|
1532
|
+
type: Input
|
|
1533
|
+
}], valueChange: [{
|
|
1534
|
+
type: Output
|
|
1535
|
+
}], touched: [{
|
|
1536
|
+
type: Output
|
|
1537
|
+
}] } });
|
|
1538
|
+
|
|
1167
1539
|
class InputEmailComponent {
|
|
1168
1540
|
cdr = inject(ChangeDetectorRef);
|
|
1169
1541
|
label;
|
|
@@ -1175,7 +1547,6 @@ class InputEmailComponent {
|
|
|
1175
1547
|
element = 'input';
|
|
1176
1548
|
rows = 4;
|
|
1177
1549
|
required = false;
|
|
1178
|
-
fullWidth = false;
|
|
1179
1550
|
autocomplete;
|
|
1180
1551
|
pattern;
|
|
1181
1552
|
error;
|
|
@@ -1214,25 +1585,25 @@ class InputEmailComponent {
|
|
|
1214
1585
|
this.actionTriggered.emit(action);
|
|
1215
1586
|
}
|
|
1216
1587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputEmailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1217
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputEmailComponent, isStandalone: true, selector: "input-email", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
1218
1589
|
{
|
|
1219
1590
|
provide: NG_VALUE_ACCESSOR,
|
|
1220
1591
|
useExisting: forwardRef(() => InputEmailComponent),
|
|
1221
1592
|
multi: true,
|
|
1222
1593
|
},
|
|
1223
1594
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputEmailComponent), multi: true },
|
|
1224
|
-
], ngImport: i0, template: "<
|
|
1595
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-email-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputEmailControlComponent, selector: "input-email-control", inputs: ["placeholder", "name", "id", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1225
1596
|
}
|
|
1226
1597
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputEmailComponent, decorators: [{
|
|
1227
1598
|
type: Component,
|
|
1228
|
-
args: [{ selector: 'input-email', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1599
|
+
args: [{ selector: 'input-email', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldFrameComponent, InputEmailControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1229
1600
|
{
|
|
1230
1601
|
provide: NG_VALUE_ACCESSOR,
|
|
1231
1602
|
useExisting: forwardRef(() => InputEmailComponent),
|
|
1232
1603
|
multi: true,
|
|
1233
1604
|
},
|
|
1234
1605
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputEmailComponent), multi: true },
|
|
1235
|
-
], template: "<
|
|
1606
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-email-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
1236
1607
|
}], propDecorators: { label: [{
|
|
1237
1608
|
type: Input
|
|
1238
1609
|
}], hint: [{
|
|
@@ -1247,8 +1618,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1247
1618
|
type: Input
|
|
1248
1619
|
}], required: [{
|
|
1249
1620
|
type: Input
|
|
1250
|
-
}], fullWidth: [{
|
|
1251
|
-
type: Input
|
|
1252
1621
|
}], autocomplete: [{
|
|
1253
1622
|
type: Input
|
|
1254
1623
|
}], pattern: [{
|
|
@@ -1261,6 +1630,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1261
1630
|
type: Output
|
|
1262
1631
|
}] } });
|
|
1263
1632
|
|
|
1633
|
+
class InputNumberControlComponent {
|
|
1634
|
+
placeholder;
|
|
1635
|
+
name;
|
|
1636
|
+
id;
|
|
1637
|
+
disabled = false;
|
|
1638
|
+
value = '';
|
|
1639
|
+
valueChange = new EventEmitter();
|
|
1640
|
+
touched = new EventEmitter();
|
|
1641
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputNumberControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1642
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputNumberControlComponent, isStandalone: true, selector: "input-number-control", inputs: { placeholder: "placeholder", name: "name", id: "id", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" type="number" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />`, isInline: true, dependencies: [{ kind: "component", type: InputTextControlComponent, selector: "input-text-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }] });
|
|
1643
|
+
}
|
|
1644
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputNumberControlComponent, decorators: [{
|
|
1645
|
+
type: Component,
|
|
1646
|
+
args: [{ selector: 'input-number-control', standalone: true, imports: [InputTextControlComponent], template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" type="number" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />` }]
|
|
1647
|
+
}], propDecorators: { placeholder: [{
|
|
1648
|
+
type: Input
|
|
1649
|
+
}], name: [{
|
|
1650
|
+
type: Input
|
|
1651
|
+
}], id: [{
|
|
1652
|
+
type: Input
|
|
1653
|
+
}], disabled: [{
|
|
1654
|
+
type: Input
|
|
1655
|
+
}], value: [{
|
|
1656
|
+
type: Input
|
|
1657
|
+
}], valueChange: [{
|
|
1658
|
+
type: Output
|
|
1659
|
+
}], touched: [{
|
|
1660
|
+
type: Output
|
|
1661
|
+
}] } });
|
|
1662
|
+
|
|
1264
1663
|
class InputNumberComponent {
|
|
1265
1664
|
cdr = inject(ChangeDetectorRef);
|
|
1266
1665
|
label;
|
|
@@ -1272,7 +1671,6 @@ class InputNumberComponent {
|
|
|
1272
1671
|
element = 'input';
|
|
1273
1672
|
rows = 4;
|
|
1274
1673
|
required = false;
|
|
1275
|
-
fullWidth = false;
|
|
1276
1674
|
autocomplete;
|
|
1277
1675
|
disabled = false;
|
|
1278
1676
|
pattern;
|
|
@@ -1314,25 +1712,25 @@ class InputNumberComponent {
|
|
|
1314
1712
|
this.actionTriggered.emit(action);
|
|
1315
1713
|
}
|
|
1316
1714
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputNumberComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1317
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1715
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputNumberComponent, isStandalone: true, selector: "input-number", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", disabled: "disabled", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
1318
1716
|
{
|
|
1319
1717
|
provide: NG_VALUE_ACCESSOR,
|
|
1320
1718
|
useExisting: forwardRef(() => InputNumberComponent),
|
|
1321
1719
|
multi: true,
|
|
1322
1720
|
},
|
|
1323
1721
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputNumberComponent), multi: true },
|
|
1324
|
-
], ngImport: i0, template: "<
|
|
1722
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-number-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;-webkit-appearance:none;margin:0}\n", "input[type=number]{-moz-appearance:textfield}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputNumberControlComponent, selector: "input-number-control", inputs: ["placeholder", "name", "id", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1325
1723
|
}
|
|
1326
1724
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputNumberComponent, decorators: [{
|
|
1327
1725
|
type: Component,
|
|
1328
|
-
args: [{ selector: 'input-number', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1726
|
+
args: [{ selector: 'input-number', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldFrameComponent, InputNumberControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1329
1727
|
{
|
|
1330
1728
|
provide: NG_VALUE_ACCESSOR,
|
|
1331
1729
|
useExisting: forwardRef(() => InputNumberComponent),
|
|
1332
1730
|
multi: true,
|
|
1333
1731
|
},
|
|
1334
1732
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputNumberComponent), multi: true },
|
|
1335
|
-
], template: "<
|
|
1733
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-number-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;-webkit-appearance:none;margin:0}\n", "input[type=number]{-moz-appearance:textfield}\n"] }]
|
|
1336
1734
|
}], propDecorators: { label: [{
|
|
1337
1735
|
type: Input
|
|
1338
1736
|
}], hint: [{
|
|
@@ -1347,8 +1745,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1347
1745
|
type: Input
|
|
1348
1746
|
}], required: [{
|
|
1349
1747
|
type: Input
|
|
1350
|
-
}], fullWidth: [{
|
|
1351
|
-
type: Input
|
|
1352
1748
|
}], autocomplete: [{
|
|
1353
1749
|
type: Input
|
|
1354
1750
|
}], disabled: [{
|
|
@@ -1363,6 +1759,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1363
1759
|
type: Output
|
|
1364
1760
|
}] } });
|
|
1365
1761
|
|
|
1762
|
+
class InputPasswordControlComponent {
|
|
1763
|
+
showIcon = Eye;
|
|
1764
|
+
hideIcon = EyeOff;
|
|
1765
|
+
placeholder;
|
|
1766
|
+
name;
|
|
1767
|
+
id;
|
|
1768
|
+
autocomplete;
|
|
1769
|
+
pattern;
|
|
1770
|
+
disabled = false;
|
|
1771
|
+
value = '';
|
|
1772
|
+
valueChange = new EventEmitter();
|
|
1773
|
+
touched = new EventEmitter();
|
|
1774
|
+
visible = false;
|
|
1775
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPasswordControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1776
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputPasswordControlComponent, isStandalone: true, selector: "input-password-control", inputs: { placeholder: "placeholder", name: "name", id: "id", autocomplete: "autocomplete", pattern: "pattern", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `
|
|
1777
|
+
<div class="relative">
|
|
1778
|
+
<input [attr.type]="visible ? 'text' : 'password'" [attr.placeholder]="placeholder" [attr.name]="name" [attr.autocomplete]="autocomplete" [attr.pattern]="pattern" [disabled]="disabled" class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.id]="id" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
1779
|
+
<button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 transition hover:text-slate-700 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.aria-label]="visible ? 'Сховати пароль' : 'Показати пароль'" [disabled]="disabled" (mousedown)="$event.preventDefault()" (click)="visible = !visible">
|
|
1780
|
+
<lucide-icon [img]="visible ? hideIcon : showIcon" class="h-4 w-4" aria-hidden="true"></lucide-icon>
|
|
1781
|
+
</button>
|
|
1782
|
+
</div>
|
|
1783
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
|
|
1784
|
+
}
|
|
1785
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPasswordControlComponent, decorators: [{
|
|
1786
|
+
type: Component,
|
|
1787
|
+
args: [{
|
|
1788
|
+
selector: 'input-password-control',
|
|
1789
|
+
standalone: true,
|
|
1790
|
+
imports: [CommonModule, LucideAngularModule],
|
|
1791
|
+
template: `
|
|
1792
|
+
<div class="relative">
|
|
1793
|
+
<input [attr.type]="visible ? 'text' : 'password'" [attr.placeholder]="placeholder" [attr.name]="name" [attr.autocomplete]="autocomplete" [attr.pattern]="pattern" [disabled]="disabled" class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 pr-10 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.id]="id" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />
|
|
1794
|
+
<button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 transition hover:text-slate-700 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.aria-label]="visible ? 'Сховати пароль' : 'Показати пароль'" [disabled]="disabled" (mousedown)="$event.preventDefault()" (click)="visible = !visible">
|
|
1795
|
+
<lucide-icon [img]="visible ? hideIcon : showIcon" class="h-4 w-4" aria-hidden="true"></lucide-icon>
|
|
1796
|
+
</button>
|
|
1797
|
+
</div>
|
|
1798
|
+
`,
|
|
1799
|
+
}]
|
|
1800
|
+
}], propDecorators: { placeholder: [{
|
|
1801
|
+
type: Input
|
|
1802
|
+
}], name: [{
|
|
1803
|
+
type: Input
|
|
1804
|
+
}], id: [{
|
|
1805
|
+
type: Input
|
|
1806
|
+
}], autocomplete: [{
|
|
1807
|
+
type: Input
|
|
1808
|
+
}], pattern: [{
|
|
1809
|
+
type: Input
|
|
1810
|
+
}], disabled: [{
|
|
1811
|
+
type: Input
|
|
1812
|
+
}], value: [{
|
|
1813
|
+
type: Input
|
|
1814
|
+
}], valueChange: [{
|
|
1815
|
+
type: Output
|
|
1816
|
+
}], touched: [{
|
|
1817
|
+
type: Output
|
|
1818
|
+
}] } });
|
|
1819
|
+
|
|
1366
1820
|
class InputPasswordComponent {
|
|
1367
1821
|
cdr = inject(ChangeDetectorRef);
|
|
1368
1822
|
label;
|
|
@@ -1376,7 +1830,6 @@ class InputPasswordComponent {
|
|
|
1376
1830
|
element = 'input';
|
|
1377
1831
|
rows = 4;
|
|
1378
1832
|
required = false;
|
|
1379
|
-
fullWidth = false;
|
|
1380
1833
|
autocomplete;
|
|
1381
1834
|
pattern;
|
|
1382
1835
|
error;
|
|
@@ -1421,25 +1874,25 @@ class InputPasswordComponent {
|
|
|
1421
1874
|
this.actionTriggered.emit(action);
|
|
1422
1875
|
}
|
|
1423
1876
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1424
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1877
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputPasswordComponent, isStandalone: true, selector: "input-password", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
1425
1878
|
{
|
|
1426
1879
|
provide: NG_VALUE_ACCESSOR,
|
|
1427
1880
|
useExisting: forwardRef(() => InputPasswordComponent),
|
|
1428
1881
|
multi: true,
|
|
1429
1882
|
},
|
|
1430
1883
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputPasswordComponent), multi: true },
|
|
1431
|
-
], ngImport: i0, template: "<
|
|
1884
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-password-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputPasswordControlComponent, selector: "input-password-control", inputs: ["placeholder", "name", "id", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1432
1885
|
}
|
|
1433
1886
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPasswordComponent, decorators: [{
|
|
1434
1887
|
type: Component,
|
|
1435
|
-
args: [{ selector: 'input-password', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1888
|
+
args: [{ selector: 'input-password', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, LucideAngularModule, FieldFrameComponent, InputPasswordControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1436
1889
|
{
|
|
1437
1890
|
provide: NG_VALUE_ACCESSOR,
|
|
1438
1891
|
useExisting: forwardRef(() => InputPasswordComponent),
|
|
1439
1892
|
multi: true,
|
|
1440
1893
|
},
|
|
1441
1894
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputPasswordComponent), multi: true },
|
|
1442
|
-
], template: "<
|
|
1895
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-password-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
1443
1896
|
}], propDecorators: { label: [{
|
|
1444
1897
|
type: Input
|
|
1445
1898
|
}], hint: [{
|
|
@@ -1454,8 +1907,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1454
1907
|
type: Input
|
|
1455
1908
|
}], required: [{
|
|
1456
1909
|
type: Input
|
|
1457
|
-
}], fullWidth: [{
|
|
1458
|
-
type: Input
|
|
1459
1910
|
}], autocomplete: [{
|
|
1460
1911
|
type: Input
|
|
1461
1912
|
}], pattern: [{
|
|
@@ -1479,7 +1930,6 @@ class InputTextComponent {
|
|
|
1479
1930
|
element = 'input';
|
|
1480
1931
|
rows = 4;
|
|
1481
1932
|
required = false;
|
|
1482
|
-
fullWidth = false;
|
|
1483
1933
|
autocomplete;
|
|
1484
1934
|
pattern;
|
|
1485
1935
|
error;
|
|
@@ -1518,25 +1968,25 @@ class InputTextComponent {
|
|
|
1518
1968
|
this.actionTriggered.emit(action);
|
|
1519
1969
|
}
|
|
1520
1970
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1521
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1971
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputTextComponent, isStandalone: true, selector: "input-text", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
1522
1972
|
{
|
|
1523
1973
|
provide: NG_VALUE_ACCESSOR,
|
|
1524
1974
|
useExisting: forwardRef(() => InputTextComponent),
|
|
1525
1975
|
multi: true,
|
|
1526
1976
|
},
|
|
1527
1977
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputTextComponent), multi: true },
|
|
1528
|
-
], ngImport: i0, template: "<
|
|
1978
|
+
], ngImport: i0, template: "<field-frame\n [label]=\"label\"\n [hint]=\"hint\"\n [error]=\"error\"\n [required]=\"required\"\n [forId]=\"controlId\"\n [disabled]=\"disabled\"\n [actions]=\"actions\"\n (actionTriggered)=\"triggerAction($event)\"\n>\n <input-text-control\n [placeholder]=\"placeholder\"\n [name]=\"name\"\n [id]=\"controlId\"\n [type]=\"type\"\n [element]=\"element\"\n [rows]=\"rows\"\n [autocomplete]=\"autocomplete\"\n [pattern]=\"pattern\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (touched)=\"onTouched()\"\n />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputTextControlComponent, selector: "input-text-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1529
1979
|
}
|
|
1530
1980
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextComponent, decorators: [{
|
|
1531
1981
|
type: Component,
|
|
1532
|
-
args: [{ selector: 'input-text', standalone: true, imports: [CommonModule, FormsModule,
|
|
1982
|
+
args: [{ selector: 'input-text', standalone: true, imports: [CommonModule, FormsModule, FieldFrameComponent, InputTextControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1533
1983
|
{
|
|
1534
1984
|
provide: NG_VALUE_ACCESSOR,
|
|
1535
1985
|
useExisting: forwardRef(() => InputTextComponent),
|
|
1536
1986
|
multi: true,
|
|
1537
1987
|
},
|
|
1538
1988
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputTextComponent), multi: true },
|
|
1539
|
-
], template: "<
|
|
1989
|
+
], template: "<field-frame\n [label]=\"label\"\n [hint]=\"hint\"\n [error]=\"error\"\n [required]=\"required\"\n [forId]=\"controlId\"\n [disabled]=\"disabled\"\n [actions]=\"actions\"\n (actionTriggered)=\"triggerAction($event)\"\n>\n <input-text-control\n [placeholder]=\"placeholder\"\n [name]=\"name\"\n [id]=\"controlId\"\n [type]=\"type\"\n [element]=\"element\"\n [rows]=\"rows\"\n [autocomplete]=\"autocomplete\"\n [pattern]=\"pattern\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (touched)=\"onTouched()\"\n />\n</field-frame>\n" }]
|
|
1540
1990
|
}], propDecorators: { label: [{
|
|
1541
1991
|
type: Input
|
|
1542
1992
|
}], hint: [{
|
|
@@ -1551,8 +2001,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1551
2001
|
type: Input
|
|
1552
2002
|
}], required: [{
|
|
1553
2003
|
type: Input
|
|
1554
|
-
}], fullWidth: [{
|
|
1555
|
-
type: Input
|
|
1556
2004
|
}], autocomplete: [{
|
|
1557
2005
|
type: Input
|
|
1558
2006
|
}], pattern: [{
|
|
@@ -1565,6 +2013,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1565
2013
|
type: Output
|
|
1566
2014
|
}] } });
|
|
1567
2015
|
|
|
2016
|
+
class InputTextareaControlComponent {
|
|
2017
|
+
placeholder;
|
|
2018
|
+
name;
|
|
2019
|
+
id;
|
|
2020
|
+
rows = 4;
|
|
2021
|
+
disabled = false;
|
|
2022
|
+
value = '';
|
|
2023
|
+
valueChange = new EventEmitter();
|
|
2024
|
+
touched = new EventEmitter();
|
|
2025
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextareaControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2026
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputTextareaControlComponent, isStandalone: true, selector: "input-textarea-control", inputs: { placeholder: "placeholder", name: "name", id: "id", rows: "rows", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" element="textarea" [rows]="rows" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />`, isInline: true, dependencies: [{ kind: "component", type: InputTextControlComponent, selector: "input-text-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }] });
|
|
2027
|
+
}
|
|
2028
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextareaControlComponent, decorators: [{
|
|
2029
|
+
type: Component,
|
|
2030
|
+
args: [{ selector: 'input-textarea-control', standalone: true, imports: [InputTextControlComponent], template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" element="textarea" [rows]="rows" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />` }]
|
|
2031
|
+
}], propDecorators: { placeholder: [{
|
|
2032
|
+
type: Input
|
|
2033
|
+
}], name: [{
|
|
2034
|
+
type: Input
|
|
2035
|
+
}], id: [{
|
|
2036
|
+
type: Input
|
|
2037
|
+
}], rows: [{
|
|
2038
|
+
type: Input
|
|
2039
|
+
}], disabled: [{
|
|
2040
|
+
type: Input
|
|
2041
|
+
}], value: [{
|
|
2042
|
+
type: Input
|
|
2043
|
+
}], valueChange: [{
|
|
2044
|
+
type: Output
|
|
2045
|
+
}], touched: [{
|
|
2046
|
+
type: Output
|
|
2047
|
+
}] } });
|
|
2048
|
+
|
|
1568
2049
|
class InputTextareaComponent {
|
|
1569
2050
|
cdr = inject(ChangeDetectorRef);
|
|
1570
2051
|
label;
|
|
@@ -1576,7 +2057,6 @@ class InputTextareaComponent {
|
|
|
1576
2057
|
element = 'textarea';
|
|
1577
2058
|
rows = 4;
|
|
1578
2059
|
required = false;
|
|
1579
|
-
fullWidth = false;
|
|
1580
2060
|
autocomplete;
|
|
1581
2061
|
pattern;
|
|
1582
2062
|
error;
|
|
@@ -1615,25 +2095,25 @@ class InputTextareaComponent {
|
|
|
1615
2095
|
this.actionTriggered.emit(action);
|
|
1616
2096
|
}
|
|
1617
2097
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1618
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2098
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputTextareaComponent, isStandalone: true, selector: "input-textarea", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
1619
2099
|
{
|
|
1620
2100
|
provide: NG_VALUE_ACCESSOR,
|
|
1621
2101
|
useExisting: forwardRef(() => InputTextareaComponent),
|
|
1622
2102
|
multi: true,
|
|
1623
2103
|
},
|
|
1624
2104
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputTextareaComponent), multi: true },
|
|
1625
|
-
], ngImport: i0, template: "<
|
|
2105
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-textarea-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [rows]=\"rows\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputTextareaControlComponent, selector: "input-textarea-control", inputs: ["placeholder", "name", "id", "rows", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1626
2106
|
}
|
|
1627
2107
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputTextareaComponent, decorators: [{
|
|
1628
2108
|
type: Component,
|
|
1629
|
-
args: [{ selector: 'input-textarea', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2109
|
+
args: [{ selector: 'input-textarea', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldFrameComponent, InputTextareaControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1630
2110
|
{
|
|
1631
2111
|
provide: NG_VALUE_ACCESSOR,
|
|
1632
2112
|
useExisting: forwardRef(() => InputTextareaComponent),
|
|
1633
2113
|
multi: true,
|
|
1634
2114
|
},
|
|
1635
2115
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputTextareaComponent), multi: true },
|
|
1636
|
-
], template: "<
|
|
2116
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-textarea-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [rows]=\"rows\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
1637
2117
|
}], propDecorators: { label: [{
|
|
1638
2118
|
type: Input
|
|
1639
2119
|
}], hint: [{
|
|
@@ -1648,8 +2128,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1648
2128
|
type: Input
|
|
1649
2129
|
}], required: [{
|
|
1650
2130
|
type: Input
|
|
1651
|
-
}], fullWidth: [{
|
|
1652
|
-
type: Input
|
|
1653
2131
|
}], autocomplete: [{
|
|
1654
2132
|
type: Input
|
|
1655
2133
|
}], pattern: [{
|
|
@@ -1662,15 +2140,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1662
2140
|
type: Output
|
|
1663
2141
|
}] } });
|
|
1664
2142
|
|
|
2143
|
+
class InputFileControlComponent {
|
|
2144
|
+
accept;
|
|
2145
|
+
multiple = false;
|
|
2146
|
+
disabled = false;
|
|
2147
|
+
selectedFiles = [];
|
|
2148
|
+
filesSelected = new EventEmitter();
|
|
2149
|
+
removeFile = new EventEmitter();
|
|
2150
|
+
touched = new EventEmitter();
|
|
2151
|
+
onFilesSelected(event) {
|
|
2152
|
+
const input = event.target;
|
|
2153
|
+
this.filesSelected.emit(Array.from(input.files ?? []));
|
|
2154
|
+
input.value = '';
|
|
2155
|
+
}
|
|
2156
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputFileControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2157
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputFileControlComponent, isStandalone: true, selector: "input-file-control", inputs: { accept: "accept", multiple: "multiple", disabled: "disabled", selectedFiles: "selectedFiles" }, outputs: { filesSelected: "filesSelected", removeFile: "removeFile", touched: "touched" }, ngImport: i0, template: "<input type=\"file\" class=\"rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm normal-case tracking-normal text-slate-800 file:mr-3 file:rounded-lg file:border-0 file:bg-slate-900 file:px-3 file:py-2 file:text-sm file:font-medium file:text-white\" [attr.accept]=\"accept ?? null\" [attr.multiple]=\"multiple ? '' : null\" [disabled]=\"disabled\" (change)=\"onFilesSelected($event)\" (blur)=\"touched.emit()\" />\n@if (selectedFiles.length) {\n <div class=\"mt-1 flex flex-col gap-1 text-[0.7rem] font-normal normal-case tracking-normal text-slate-700\">\n @for (file of selectedFiles; track file.name + file.size; let i = $index) {\n <div class=\"flex items-center justify-between rounded border border-slate-200 bg-slate-50 px-2 py-1\">\n <span class=\"truncate pr-2\">{{ file.name }}</span>\n <button type=\"button\" class=\"text-rose-600\" [disabled]=\"disabled\" (click)=\"removeFile.emit(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n </div>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2158
|
+
}
|
|
2159
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputFileControlComponent, decorators: [{
|
|
2160
|
+
type: Component,
|
|
2161
|
+
args: [{ selector: 'input-file-control', standalone: true, imports: [CommonModule], template: "<input type=\"file\" class=\"rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm normal-case tracking-normal text-slate-800 file:mr-3 file:rounded-lg file:border-0 file:bg-slate-900 file:px-3 file:py-2 file:text-sm file:font-medium file:text-white\" [attr.accept]=\"accept ?? null\" [attr.multiple]=\"multiple ? '' : null\" [disabled]=\"disabled\" (change)=\"onFilesSelected($event)\" (blur)=\"touched.emit()\" />\n@if (selectedFiles.length) {\n <div class=\"mt-1 flex flex-col gap-1 text-[0.7rem] font-normal normal-case tracking-normal text-slate-700\">\n @for (file of selectedFiles; track file.name + file.size; let i = $index) {\n <div class=\"flex items-center justify-between rounded border border-slate-200 bg-slate-50 px-2 py-1\">\n <span class=\"truncate pr-2\">{{ file.name }}</span>\n <button type=\"button\" class=\"text-rose-600\" [disabled]=\"disabled\" (click)=\"removeFile.emit(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n </div>\n }\n </div>\n}\n" }]
|
|
2162
|
+
}], propDecorators: { accept: [{
|
|
2163
|
+
type: Input
|
|
2164
|
+
}], multiple: [{
|
|
2165
|
+
type: Input
|
|
2166
|
+
}], disabled: [{
|
|
2167
|
+
type: Input
|
|
2168
|
+
}], selectedFiles: [{
|
|
2169
|
+
type: Input
|
|
2170
|
+
}], filesSelected: [{
|
|
2171
|
+
type: Output
|
|
2172
|
+
}], removeFile: [{
|
|
2173
|
+
type: Output
|
|
2174
|
+
}], touched: [{
|
|
2175
|
+
type: Output
|
|
2176
|
+
}] } });
|
|
2177
|
+
|
|
1665
2178
|
class InputFileComponent {
|
|
1666
2179
|
label;
|
|
1667
2180
|
hint;
|
|
2181
|
+
error;
|
|
2182
|
+
required = false;
|
|
1668
2183
|
accept;
|
|
1669
2184
|
multiple = false;
|
|
1670
2185
|
disabled = false;
|
|
1671
|
-
value = null;
|
|
1672
|
-
valueChange = new EventEmitter();
|
|
1673
2186
|
filesChange = new EventEmitter();
|
|
2187
|
+
value = null;
|
|
1674
2188
|
onChange = () => undefined;
|
|
1675
2189
|
onTouched = () => undefined;
|
|
1676
2190
|
writeValue(value) { this.value = value; }
|
|
@@ -1688,39 +2202,85 @@ class InputFileComponent {
|
|
|
1688
2202
|
const value = this.multiple ? files : (files[0] ?? null);
|
|
1689
2203
|
this.value = value;
|
|
1690
2204
|
this.onChange(value);
|
|
1691
|
-
this.valueChange.emit(value);
|
|
1692
2205
|
this.filesChange.emit(files);
|
|
1693
2206
|
input.value = '';
|
|
1694
2207
|
}
|
|
2208
|
+
handleFilesSelected(files) {
|
|
2209
|
+
const value = this.multiple ? files : (files[0] ?? null);
|
|
2210
|
+
this.value = value;
|
|
2211
|
+
this.onChange(value);
|
|
2212
|
+
this.filesChange.emit(files);
|
|
2213
|
+
}
|
|
1695
2214
|
remove(index) {
|
|
1696
2215
|
const files = this.selectedFiles.filter((_file, fileIndex) => fileIndex !== index);
|
|
1697
2216
|
const value = this.multiple ? files : (files[0] ?? null);
|
|
1698
2217
|
this.value = value;
|
|
1699
2218
|
this.onChange(value);
|
|
1700
|
-
this.valueChange.emit(value);
|
|
1701
2219
|
this.filesChange.emit(files);
|
|
1702
2220
|
}
|
|
1703
2221
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1704
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2222
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputFileComponent, isStandalone: true, selector: "input-file", inputs: { label: "label", hint: "hint", error: "error", required: "required", accept: "accept", multiple: "multiple", disabled: "disabled" }, outputs: { filesChange: "filesChange" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputFileComponent), multi: true }], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-file-control [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled\" [selectedFiles]=\"selectedFiles\" (filesSelected)=\"handleFilesSelected($event)\" (removeFile)=\"remove($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputFileControlComponent, selector: "input-file-control", inputs: ["accept", "multiple", "disabled", "selectedFiles"], outputs: ["filesSelected", "removeFile", "touched"] }] });
|
|
1705
2223
|
}
|
|
1706
2224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputFileComponent, decorators: [{
|
|
1707
2225
|
type: Component,
|
|
1708
|
-
args: [{ selector: 'input-file', standalone: true, imports: [CommonModule], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputFileComponent), multi: true }], template: "<label
|
|
2226
|
+
args: [{ selector: 'input-file', standalone: true, imports: [CommonModule, FieldFrameComponent, InputFileControlComponent], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputFileComponent), multi: true }], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-file-control [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled\" [selectedFiles]=\"selectedFiles\" (filesSelected)=\"handleFilesSelected($event)\" (removeFile)=\"remove($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
1709
2227
|
}], propDecorators: { label: [{
|
|
1710
2228
|
type: Input
|
|
1711
2229
|
}], hint: [{
|
|
1712
2230
|
type: Input
|
|
2231
|
+
}], error: [{
|
|
2232
|
+
type: Input
|
|
2233
|
+
}], required: [{
|
|
2234
|
+
type: Input
|
|
1713
2235
|
}], accept: [{
|
|
1714
2236
|
type: Input
|
|
1715
2237
|
}], multiple: [{
|
|
1716
2238
|
type: Input
|
|
1717
2239
|
}], disabled: [{
|
|
1718
2240
|
type: Input
|
|
1719
|
-
}],
|
|
2241
|
+
}], filesChange: [{
|
|
2242
|
+
type: Output
|
|
2243
|
+
}] } });
|
|
2244
|
+
|
|
2245
|
+
class InputPhotoControlComponent {
|
|
2246
|
+
accept = 'image/*';
|
|
2247
|
+
multiple = false;
|
|
2248
|
+
disabled = false;
|
|
2249
|
+
canSelectMore = true;
|
|
2250
|
+
previews = [];
|
|
2251
|
+
filesSelected = new EventEmitter();
|
|
2252
|
+
removed = new EventEmitter();
|
|
2253
|
+
dropped = new EventEmitter();
|
|
2254
|
+
touched = new EventEmitter();
|
|
2255
|
+
selectFiles(event) {
|
|
2256
|
+
const input = event.target;
|
|
2257
|
+
this.filesSelected.emit(Array.from(input.files ?? []));
|
|
2258
|
+
input.value = '';
|
|
2259
|
+
this.touched.emit();
|
|
2260
|
+
}
|
|
2261
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2262
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputPhotoControlComponent, isStandalone: true, selector: "input-photo-control", inputs: { accept: "accept", multiple: "multiple", disabled: "disabled", canSelectMore: "canSelectMore", previews: "previews" }, outputs: { filesSelected: "filesSelected", removed: "removed", dropped: "dropped", touched: "touched" }, ngImport: i0, template: "<button type=\"button\" class=\"flex min-h-24 w-full items-center justify-center rounded-xl border border-dashed border-slate-300 bg-slate-50 px-4 py-3 text-xs font-semibold uppercase tracking-[0.15em] text-slate-600 transition hover:bg-slate-100 disabled:opacity-60\" [disabled]=\"disabled || !canSelectMore\" (click)=\"photoInput.click()\">\n {{ previews.length ? '\u0414\u043E\u0434\u0430\u0442\u0438 \u0449\u0435 \u0444\u0430\u0439\u043B' : '\u041E\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B' }}\n</button>\n<input #photoInput type=\"file\" class=\"hidden\" [attr.accept]=\"accept\" [attr.multiple]=\"multiple && canSelectMore ? '' : null\" [disabled]=\"disabled\" (change)=\"selectFiles($event)\" />\n@if (previews.length) {\n <div class=\"mt-2 grid grid-cols-2 gap-2 md:grid-cols-4\" cdkDropList cdkDropListOrientation=\"mixed\" [cdkDropListData]=\"previews\" (cdkDropListDropped)=\"dropped.emit($event)\">\n @for (preview of previews; track preview.url; let i = $index) {\n <div class=\"relative overflow-hidden rounded-lg border border-slate-200 bg-slate-50\" cdkDrag [cdkDragDisabled]=\"disabled || preview.source === 'file'\">\n @if (preview.isImage) { <img [src]=\"preview.url\" [alt]=\"preview.name\" class=\"h-28 w-full object-cover\" /> }\n @else { <div class=\"flex h-28 items-center justify-center px-2 text-center text-[0.65rem] text-slate-600\">{{ preview.name }}</div> }\n <div class=\"absolute left-1 top-1 rounded bg-slate-900/85 px-2 py-1 text-[10px] font-semibold text-white\">#{{ i + 1 }}</div>\n <button type=\"button\" class=\"absolute right-1 top-1 rounded bg-white/95 px-2 py-1 text-[10px] text-rose-600\" [disabled]=\"disabled\" (click)=\"removed.emit(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n </div>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }] });
|
|
2263
|
+
}
|
|
2264
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoControlComponent, decorators: [{
|
|
2265
|
+
type: Component,
|
|
2266
|
+
args: [{ selector: 'input-photo-control', standalone: true, imports: [CommonModule, DragDropModule], template: "<button type=\"button\" class=\"flex min-h-24 w-full items-center justify-center rounded-xl border border-dashed border-slate-300 bg-slate-50 px-4 py-3 text-xs font-semibold uppercase tracking-[0.15em] text-slate-600 transition hover:bg-slate-100 disabled:opacity-60\" [disabled]=\"disabled || !canSelectMore\" (click)=\"photoInput.click()\">\n {{ previews.length ? '\u0414\u043E\u0434\u0430\u0442\u0438 \u0449\u0435 \u0444\u0430\u0439\u043B' : '\u041E\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B' }}\n</button>\n<input #photoInput type=\"file\" class=\"hidden\" [attr.accept]=\"accept\" [attr.multiple]=\"multiple && canSelectMore ? '' : null\" [disabled]=\"disabled\" (change)=\"selectFiles($event)\" />\n@if (previews.length) {\n <div class=\"mt-2 grid grid-cols-2 gap-2 md:grid-cols-4\" cdkDropList cdkDropListOrientation=\"mixed\" [cdkDropListData]=\"previews\" (cdkDropListDropped)=\"dropped.emit($event)\">\n @for (preview of previews; track preview.url; let i = $index) {\n <div class=\"relative overflow-hidden rounded-lg border border-slate-200 bg-slate-50\" cdkDrag [cdkDragDisabled]=\"disabled || preview.source === 'file'\">\n @if (preview.isImage) { <img [src]=\"preview.url\" [alt]=\"preview.name\" class=\"h-28 w-full object-cover\" /> }\n @else { <div class=\"flex h-28 items-center justify-center px-2 text-center text-[0.65rem] text-slate-600\">{{ preview.name }}</div> }\n <div class=\"absolute left-1 top-1 rounded bg-slate-900/85 px-2 py-1 text-[10px] font-semibold text-white\">#{{ i + 1 }}</div>\n <button type=\"button\" class=\"absolute right-1 top-1 rounded bg-white/95 px-2 py-1 text-[10px] text-rose-600\" [disabled]=\"disabled\" (click)=\"removed.emit(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n </div>\n }\n </div>\n}\n" }]
|
|
2267
|
+
}], propDecorators: { accept: [{
|
|
1720
2268
|
type: Input
|
|
1721
|
-
}],
|
|
2269
|
+
}], multiple: [{
|
|
2270
|
+
type: Input
|
|
2271
|
+
}], disabled: [{
|
|
2272
|
+
type: Input
|
|
2273
|
+
}], canSelectMore: [{
|
|
2274
|
+
type: Input
|
|
2275
|
+
}], previews: [{
|
|
2276
|
+
type: Input
|
|
2277
|
+
}], filesSelected: [{
|
|
1722
2278
|
type: Output
|
|
1723
|
-
}],
|
|
2279
|
+
}], removed: [{
|
|
2280
|
+
type: Output
|
|
2281
|
+
}], dropped: [{
|
|
2282
|
+
type: Output
|
|
2283
|
+
}], touched: [{
|
|
1724
2284
|
type: Output
|
|
1725
2285
|
}] } });
|
|
1726
2286
|
|
|
@@ -1728,14 +2288,15 @@ class InputPhotoComponent {
|
|
|
1728
2288
|
http = inject(HttpClient);
|
|
1729
2289
|
label;
|
|
1730
2290
|
hint;
|
|
2291
|
+
error;
|
|
2292
|
+
required = false;
|
|
1731
2293
|
accept = 'image/*';
|
|
1732
2294
|
multiple = false;
|
|
1733
2295
|
limit = Number.MAX_SAFE_INTEGER;
|
|
1734
2296
|
disabled = false;
|
|
1735
|
-
value = null;
|
|
1736
|
-
valueChange = new EventEmitter();
|
|
1737
2297
|
filesChange = new EventEmitter();
|
|
1738
2298
|
uploadingChange = new EventEmitter();
|
|
2299
|
+
value = null;
|
|
1739
2300
|
pendingFiles = [];
|
|
1740
2301
|
previews = [];
|
|
1741
2302
|
uploading = false;
|
|
@@ -1750,7 +2311,7 @@ class InputPhotoComponent {
|
|
|
1750
2311
|
registerOnTouched(fn) { this.onTouched = fn; }
|
|
1751
2312
|
setDisabledState(isDisabled) { this.disabled = isDisabled; }
|
|
1752
2313
|
ngOnChanges(changes) {
|
|
1753
|
-
if (changes['
|
|
2314
|
+
if (changes['multiple'])
|
|
1754
2315
|
this.rebuildPreviews();
|
|
1755
2316
|
}
|
|
1756
2317
|
ngOnDestroy() {
|
|
@@ -1771,6 +2332,15 @@ class InputPhotoComponent {
|
|
|
1771
2332
|
this.rebuildPreviews();
|
|
1772
2333
|
this.uploadFiles(accepted);
|
|
1773
2334
|
}
|
|
2335
|
+
handleFilesSelected(files) {
|
|
2336
|
+
if (!files.length || this.disabled)
|
|
2337
|
+
return;
|
|
2338
|
+
const accepted = this.multiple ? files.slice(0, Math.max(0, this.normalizedLimit - this.ids.length - this.pendingFiles.length)) : [files[0]];
|
|
2339
|
+
this.pendingFiles = this.multiple ? [...this.pendingFiles, ...accepted] : [accepted[0]];
|
|
2340
|
+
this.filesChange.emit(this.pendingFiles);
|
|
2341
|
+
this.rebuildPreviews();
|
|
2342
|
+
this.uploadFiles(accepted);
|
|
2343
|
+
}
|
|
1774
2344
|
remove(index) {
|
|
1775
2345
|
const ids = [...this.ids];
|
|
1776
2346
|
if (index < ids.length) {
|
|
@@ -1801,7 +2371,6 @@ class InputPhotoComponent {
|
|
|
1801
2371
|
emitValue(value) {
|
|
1802
2372
|
this.value = value;
|
|
1803
2373
|
this.onChange(value);
|
|
1804
|
-
this.valueChange.emit(value);
|
|
1805
2374
|
this.rebuildPreviews(value);
|
|
1806
2375
|
}
|
|
1807
2376
|
uploadFiles(files) {
|
|
@@ -1862,15 +2431,19 @@ class InputPhotoComponent {
|
|
|
1862
2431
|
return normalized.startsWith('image/') || normalized === 'application/pdf';
|
|
1863
2432
|
}
|
|
1864
2433
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1865
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2434
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputPhotoComponent, isStandalone: true, selector: "input-photo", inputs: { label: "label", hint: "hint", error: "error", required: "required", accept: "accept", multiple: "multiple", limit: "limit", disabled: "disabled" }, outputs: { filesChange: "filesChange", uploadingChange: "uploadingChange" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputPhotoComponent), multi: true }], usesOnChanges: true, ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-photo-control [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled\" [canSelectMore]=\"canSelectMore\" [previews]=\"previews\" (filesSelected)=\"handleFilesSelected($event)\" (removed)=\"remove($event)\" (dropped)=\"drop($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputPhotoControlComponent, selector: "input-photo-control", inputs: ["accept", "multiple", "disabled", "canSelectMore", "previews"], outputs: ["filesSelected", "removed", "dropped", "touched"] }] });
|
|
1866
2435
|
}
|
|
1867
2436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoComponent, decorators: [{
|
|
1868
2437
|
type: Component,
|
|
1869
|
-
args: [{ selector: 'input-photo', standalone: true, imports: [CommonModule, DragDropModule], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputPhotoComponent), multi: true }], template: "<
|
|
2438
|
+
args: [{ selector: 'input-photo', standalone: true, imports: [CommonModule, DragDropModule, FieldFrameComponent, InputPhotoControlComponent], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputPhotoComponent), multi: true }], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <input-photo-control [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled\" [canSelectMore]=\"canSelectMore\" [previews]=\"previews\" (filesSelected)=\"handleFilesSelected($event)\" (removed)=\"remove($event)\" (dropped)=\"drop($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
1870
2439
|
}], propDecorators: { label: [{
|
|
1871
2440
|
type: Input
|
|
1872
2441
|
}], hint: [{
|
|
1873
2442
|
type: Input
|
|
2443
|
+
}], error: [{
|
|
2444
|
+
type: Input
|
|
2445
|
+
}], required: [{
|
|
2446
|
+
type: Input
|
|
1874
2447
|
}], accept: [{
|
|
1875
2448
|
type: Input
|
|
1876
2449
|
}], multiple: [{
|
|
@@ -1879,17 +2452,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1879
2452
|
type: Input
|
|
1880
2453
|
}], disabled: [{
|
|
1881
2454
|
type: Input
|
|
1882
|
-
}], value: [{
|
|
1883
|
-
type: Input
|
|
1884
|
-
}], valueChange: [{
|
|
1885
|
-
type: Output
|
|
1886
2455
|
}], filesChange: [{
|
|
1887
2456
|
type: Output
|
|
1888
2457
|
}], uploadingChange: [{
|
|
1889
2458
|
type: Output
|
|
1890
2459
|
}] } });
|
|
1891
2460
|
|
|
1892
|
-
class
|
|
2461
|
+
class InputSelectControlComponent {
|
|
1893
2462
|
closeIcon = X;
|
|
1894
2463
|
chevronDownIcon = ChevronDown;
|
|
1895
2464
|
checkIcon = Check;
|
|
@@ -1903,15 +2472,12 @@ class InputSelectComponent {
|
|
|
1903
2472
|
name;
|
|
1904
2473
|
data;
|
|
1905
2474
|
required = false;
|
|
1906
|
-
fullWidth = false;
|
|
1907
2475
|
disabled = false;
|
|
1908
2476
|
multiple = false;
|
|
1909
2477
|
includeBlankOption = false;
|
|
1910
2478
|
blankOptionLabel = 'Оберіть…';
|
|
1911
2479
|
emptyStateLabel = 'Немає варіантів для вибору';
|
|
1912
2480
|
searchable = true;
|
|
1913
|
-
remoteSearch = false;
|
|
1914
|
-
searchPlaceholder = 'Пошук...';
|
|
1915
2481
|
_options = [];
|
|
1916
2482
|
set options(value) {
|
|
1917
2483
|
this._options = value ?? [];
|
|
@@ -2086,7 +2652,7 @@ class InputSelectComponent {
|
|
|
2086
2652
|
}
|
|
2087
2653
|
get visibleOptions() {
|
|
2088
2654
|
const options = this.getRenderOptions();
|
|
2089
|
-
if (!this.searchable || this.
|
|
2655
|
+
if (!this.searchable || this.getDictionaryName() || !this.searchTerm.trim()) {
|
|
2090
2656
|
return options;
|
|
2091
2657
|
}
|
|
2092
2658
|
const search = this.searchTerm.trim().toLowerCase();
|
|
@@ -2239,26 +2805,26 @@ class InputSelectComponent {
|
|
|
2239
2805
|
loadSuggestItem(name, key) {
|
|
2240
2806
|
return this.http.get(`/api/suggest/${encodeURIComponent(name)}/${encodeURIComponent(key)}`);
|
|
2241
2807
|
}
|
|
2242
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
2243
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type:
|
|
2808
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSelectControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2809
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputSelectControlComponent, isStandalone: true, selector: "input-select-control", inputs: { label: "label", placeholder: "placeholder", name: "name", data: "data", required: "required", disabled: "disabled", multiple: ["multiple", "multiple", booleanAttribute], includeBlankOption: "includeBlankOption", blankOptionLabel: "blankOptionLabel", emptyStateLabel: "emptyStateLabel", searchable: "searchable", options: "options", error: "error", hint: "hint", triggerClass: "triggerClass", panelClass: "panelClass" }, outputs: { valueChange: "valueChange", searchChange: "searchChange" }, host: { listeners: { "document:click": "onDocumentClick()", "document:keydown.escape": "onEscape()" } }, providers: [
|
|
2244
2810
|
{
|
|
2245
2811
|
provide: NG_VALUE_ACCESSOR,
|
|
2246
|
-
useExisting: forwardRef(() =>
|
|
2812
|
+
useExisting: forwardRef(() => InputSelectControlComponent),
|
|
2247
2813
|
multi: true,
|
|
2248
2814
|
},
|
|
2249
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
2250
|
-
], viewQueries: [{ propertyName: "dropdownTrigger", first: true, predicate: ["dropdownTrigger"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: "
|
|
2815
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSelectControlComponent), multi: true },
|
|
2816
|
+
], viewQueries: [{ propertyName: "dropdownTrigger", first: true, predicate: ["dropdownTrigger"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: " <div class=\"relative w-full\">\n\n <button\n cdkOverlayOrigin\n #dropdownTrigger=\"cdkOverlayOrigin\"\n type=\"button\"\n class=\"flex min-h-10 w-full flex-nowrap items-center gap-2 rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 transition hover:border-slate-300 focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [class]=\"triggerClass\"\n [class.opacity-50]=\"disabled\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown($event)\"\n >\n\n <span class=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\" [class.-ml-2]=\"multiple\">\n <!-- MULTIPLE MODE -->\n @if (multiple) {\n\n @if (selectedOptions.length) {\n\n @for (option of selectedOptions; track option.value) {\n <span\n class=\"inline-flex h-6 shrink-0 items-center gap-1 rounded-md bg-slate-100 px-2 text-xs font-medium text-slate-700\"\n >\n {{ option.label }}\n\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"text-slate-400 hover:text-rose-500 transition-colors\"\n (click)=\"removeOption(option, $event)\"\n (keydown.enter)=\"removeOption(option, $event)\"\n (keydown.space)=\"$event.preventDefault(); removeOption(option, $event)\"\n >\n <lucide-icon [img]=\"closeIcon\" class=\"h-4 w-4 shrink-0\"></lucide-icon>\n </span>\n </span>\n }\n\n } @else {\n <span class=\"text-slate-400\">\n {{ placeholder ?? blankOptionLabel }}\n </span>\n }\n\n } @else {\n\n <!-- SINGLE MODE -->\n @if (selectedOptions[0]?.imageUrl) {\n <img [src]=\"selectedOptions[0]?.imageUrl\" alt=\"\" class=\"h-7 w-7 rounded object-cover\" />\n }\n <span class=\"min-w-0 truncate\">\n {{ selectedOptions[0]?.label ?? placeholder ?? blankOptionLabel }}\n </span>\n\n }\n </span>\n\n <lucide-icon [img]=\"chevronDownIcon\" class=\"shrink-0 text-xs text-slate-400\"></lucide-icon>\n\n </button>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"dropdownTrigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPositions]=\"dropdownPositions\"\n [cdkConnectedOverlayViewportMargin]=\"popupViewportMargin\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayPush]=\"true\"\n (detach)=\"closeDropdown()\"\n >\n <!-- DROPDOWN -->\n <div\n class=\"z-50 w-full max-w-[calc(100vw-2rem)] rounded-xl border border-slate-200 bg-white shadow-lg\"\n [style.width.px]=\"popupWidth\"\n [style.max-width]=\"'calc(100vw - 2rem)'\"\n [class]=\"panelClass\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (searchable) {\n <div class=\"border-b border-slate-100 p-2\">\n <input\n type=\"text\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 outline-none transition focus:border-slate-900 focus:ring-2 focus:ring-slate-200\"\n placeholder=\"\u041F\u043E\u0448\u0443\u043A...\"\n [ngModel]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </div>\n }\n\n <div class=\"max-h-60 overflow-auto\">\n @if (!visibleOptions.length) {\n <div class=\"px-4 py-3 text-sm text-slate-500\">\n @if (isDictionaryLoading && data) {\n \u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F...\n } @else {\n {{ emptyStateLabel }}\n }\n </div>\n } @else {\n @for (option of visibleOptions; track trackOption($index, option)) {\n <button\n type=\"button\"\n class=\"flex w-full items-start justify-between gap-3 whitespace-normal break-words px-4 py-2 text-left text-sm hover:bg-slate-50\"\n [class.bg-slate-100]=\"isSelected(option)\"\n (click)=\"selectOption(option, $event)\"\n >\n <span class=\"flex min-w-0 flex-1 items-center gap-2\">\n @if (option.imageUrl) {\n <img [src]=\"option.imageUrl\" alt=\"\" class=\"h-8 w-8 shrink-0 rounded object-cover\" />\n }\n <span class=\"whitespace-normal break-words\">{{ option.label }}</span>\n </span>\n\n @if (isSelected(option)) {\n <lucide-icon [img]=\"checkIcon\" class=\"text-xs text-sky-500\"></lucide-icon>\n }\n </button>\n }\n }\n </div>\n\n </div>\n </ng-template>\n\n </div>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2251
2817
|
}
|
|
2252
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type:
|
|
2818
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSelectControlComponent, decorators: [{
|
|
2253
2819
|
type: Component,
|
|
2254
|
-
args: [{ selector: 'input-select', standalone: true, imports: [LucideAngularModule, CommonModule, FormsModule, CdkConnectedOverlay, CdkOverlayOrigin], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2820
|
+
args: [{ selector: 'input-select-control', standalone: true, imports: [LucideAngularModule, CommonModule, FormsModule, CdkConnectedOverlay, CdkOverlayOrigin], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2255
2821
|
{
|
|
2256
2822
|
provide: NG_VALUE_ACCESSOR,
|
|
2257
|
-
useExisting: forwardRef(() =>
|
|
2823
|
+
useExisting: forwardRef(() => InputSelectControlComponent),
|
|
2258
2824
|
multi: true,
|
|
2259
2825
|
},
|
|
2260
|
-
{ provide: NG_VALIDATORS, useExisting: forwardRef(() =>
|
|
2261
|
-
], template: "
|
|
2826
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSelectControlComponent), multi: true },
|
|
2827
|
+
], template: " <div class=\"relative w-full\">\n\n <button\n cdkOverlayOrigin\n #dropdownTrigger=\"cdkOverlayOrigin\"\n type=\"button\"\n class=\"flex min-h-10 w-full flex-nowrap items-center gap-2 rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 transition hover:border-slate-300 focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200\"\n [class]=\"triggerClass\"\n [class.opacity-50]=\"disabled\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown($event)\"\n >\n\n <span class=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\" [class.-ml-2]=\"multiple\">\n <!-- MULTIPLE MODE -->\n @if (multiple) {\n\n @if (selectedOptions.length) {\n\n @for (option of selectedOptions; track option.value) {\n <span\n class=\"inline-flex h-6 shrink-0 items-center gap-1 rounded-md bg-slate-100 px-2 text-xs font-medium text-slate-700\"\n >\n {{ option.label }}\n\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"text-slate-400 hover:text-rose-500 transition-colors\"\n (click)=\"removeOption(option, $event)\"\n (keydown.enter)=\"removeOption(option, $event)\"\n (keydown.space)=\"$event.preventDefault(); removeOption(option, $event)\"\n >\n <lucide-icon [img]=\"closeIcon\" class=\"h-4 w-4 shrink-0\"></lucide-icon>\n </span>\n </span>\n }\n\n } @else {\n <span class=\"text-slate-400\">\n {{ placeholder ?? blankOptionLabel }}\n </span>\n }\n\n } @else {\n\n <!-- SINGLE MODE -->\n @if (selectedOptions[0]?.imageUrl) {\n <img [src]=\"selectedOptions[0]?.imageUrl\" alt=\"\" class=\"h-7 w-7 rounded object-cover\" />\n }\n <span class=\"min-w-0 truncate\">\n {{ selectedOptions[0]?.label ?? placeholder ?? blankOptionLabel }}\n </span>\n\n }\n </span>\n\n <lucide-icon [img]=\"chevronDownIcon\" class=\"shrink-0 text-xs text-slate-400\"></lucide-icon>\n\n </button>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"dropdownTrigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPositions]=\"dropdownPositions\"\n [cdkConnectedOverlayViewportMargin]=\"popupViewportMargin\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayPush]=\"true\"\n (detach)=\"closeDropdown()\"\n >\n <!-- DROPDOWN -->\n <div\n class=\"z-50 w-full max-w-[calc(100vw-2rem)] rounded-xl border border-slate-200 bg-white shadow-lg\"\n [style.width.px]=\"popupWidth\"\n [style.max-width]=\"'calc(100vw - 2rem)'\"\n [class]=\"panelClass\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (searchable) {\n <div class=\"border-b border-slate-100 p-2\">\n <input\n type=\"text\"\n class=\"w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 outline-none transition focus:border-slate-900 focus:ring-2 focus:ring-slate-200\"\n placeholder=\"\u041F\u043E\u0448\u0443\u043A...\"\n [ngModel]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </div>\n }\n\n <div class=\"max-h-60 overflow-auto\">\n @if (!visibleOptions.length) {\n <div class=\"px-4 py-3 text-sm text-slate-500\">\n @if (isDictionaryLoading && data) {\n \u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F...\n } @else {\n {{ emptyStateLabel }}\n }\n </div>\n } @else {\n @for (option of visibleOptions; track trackOption($index, option)) {\n <button\n type=\"button\"\n class=\"flex w-full items-start justify-between gap-3 whitespace-normal break-words px-4 py-2 text-left text-sm hover:bg-slate-50\"\n [class.bg-slate-100]=\"isSelected(option)\"\n (click)=\"selectOption(option, $event)\"\n >\n <span class=\"flex min-w-0 flex-1 items-center gap-2\">\n @if (option.imageUrl) {\n <img [src]=\"option.imageUrl\" alt=\"\" class=\"h-8 w-8 shrink-0 rounded object-cover\" />\n }\n <span class=\"whitespace-normal break-words\">{{ option.label }}</span>\n </span>\n\n @if (isSelected(option)) {\n <lucide-icon [img]=\"checkIcon\" class=\"text-xs text-sky-500\"></lucide-icon>\n }\n </button>\n }\n }\n </div>\n\n </div>\n </ng-template>\n\n </div>\n" }]
|
|
2262
2828
|
}], ctorParameters: () => [], propDecorators: { label: [{
|
|
2263
2829
|
type: Input
|
|
2264
2830
|
}], placeholder: [{
|
|
@@ -2269,8 +2835,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2269
2835
|
type: Input
|
|
2270
2836
|
}], required: [{
|
|
2271
2837
|
type: Input
|
|
2272
|
-
}], fullWidth: [{
|
|
2273
|
-
type: Input
|
|
2274
2838
|
}], disabled: [{
|
|
2275
2839
|
type: Input
|
|
2276
2840
|
}], multiple: [{
|
|
@@ -2284,10 +2848,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2284
2848
|
type: Input
|
|
2285
2849
|
}], searchable: [{
|
|
2286
2850
|
type: Input
|
|
2287
|
-
}], remoteSearch: [{
|
|
2288
|
-
type: Input
|
|
2289
|
-
}], searchPlaceholder: [{
|
|
2290
|
-
type: Input
|
|
2291
2851
|
}], options: [{
|
|
2292
2852
|
type: Input
|
|
2293
2853
|
}], error: [{
|
|
@@ -2313,6 +2873,136 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2313
2873
|
args: ['document:keydown.escape']
|
|
2314
2874
|
}] } });
|
|
2315
2875
|
|
|
2876
|
+
class InputSelectComponent {
|
|
2877
|
+
control;
|
|
2878
|
+
label;
|
|
2879
|
+
hint;
|
|
2880
|
+
error;
|
|
2881
|
+
placeholder;
|
|
2882
|
+
name;
|
|
2883
|
+
data;
|
|
2884
|
+
required = false;
|
|
2885
|
+
disabled = false;
|
|
2886
|
+
multiple = false;
|
|
2887
|
+
includeBlankOption = false;
|
|
2888
|
+
blankOptionLabel = 'Оберіть…';
|
|
2889
|
+
emptyStateLabel = 'Немає варіантів для вибору';
|
|
2890
|
+
searchable = true;
|
|
2891
|
+
options = [];
|
|
2892
|
+
triggerClass = '';
|
|
2893
|
+
panelClass = '';
|
|
2894
|
+
valueChange = new EventEmitter();
|
|
2895
|
+
searchChange = new EventEmitter();
|
|
2896
|
+
pendingValue = null;
|
|
2897
|
+
onChange = () => undefined;
|
|
2898
|
+
onTouched = () => undefined;
|
|
2899
|
+
ngAfterViewInit() {
|
|
2900
|
+
this.control?.registerOnChange((value) => {
|
|
2901
|
+
this.onChange(value);
|
|
2902
|
+
this.valueChange.emit(value);
|
|
2903
|
+
});
|
|
2904
|
+
this.control?.registerOnTouched(() => this.onTouched());
|
|
2905
|
+
this.control?.writeValue(this.pendingValue);
|
|
2906
|
+
}
|
|
2907
|
+
writeValue(value) {
|
|
2908
|
+
this.pendingValue = value;
|
|
2909
|
+
this.control?.writeValue(value);
|
|
2910
|
+
}
|
|
2911
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
2912
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
2913
|
+
setDisabledState(isDisabled) { this.disabled = isDisabled; }
|
|
2914
|
+
validate(control) { return validateFormControl(control, this.required); }
|
|
2915
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2916
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.2.19", type: InputSelectComponent, isStandalone: true, selector: "input-select", inputs: { label: "label", hint: "hint", error: "error", placeholder: "placeholder", name: "name", data: "data", required: "required", disabled: "disabled", multiple: ["multiple", "multiple", booleanAttribute], includeBlankOption: "includeBlankOption", blankOptionLabel: "blankOptionLabel", emptyStateLabel: "emptyStateLabel", searchable: "searchable", options: "options", triggerClass: "triggerClass", panelClass: "panelClass" }, outputs: { valueChange: "valueChange", searchChange: "searchChange" }, providers: [
|
|
2917
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputSelectComponent), multi: true },
|
|
2918
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSelectComponent), multi: true },
|
|
2919
|
+
], viewQueries: [{ propertyName: "control", first: true, predicate: InputSelectControlComponent, descendants: true }], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [disabled]=\"disabled\">\n <input-select-control\n [placeholder]=\"placeholder\"\n [name]=\"name\"\n [data]=\"data\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [includeBlankOption]=\"includeBlankOption\"\n [blankOptionLabel]=\"blankOptionLabel\"\n [emptyStateLabel]=\"emptyStateLabel\"\n [searchable]=\"searchable\"\n [options]=\"options\"\n [triggerClass]=\"triggerClass\"\n [panelClass]=\"panelClass\"\n (valueChange)=\"valueChange.emit($event)\"\n (searchChange)=\"searchChange.emit($event)\"\n />\n</field-frame>\n", dependencies: [{ kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputSelectControlComponent, selector: "input-select-control", inputs: ["label", "placeholder", "name", "data", "required", "disabled", "multiple", "includeBlankOption", "blankOptionLabel", "emptyStateLabel", "searchable", "options", "error", "hint", "triggerClass", "panelClass"], outputs: ["valueChange", "searchChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2920
|
+
}
|
|
2921
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSelectComponent, decorators: [{
|
|
2922
|
+
type: Component,
|
|
2923
|
+
args: [{ selector: 'input-select', standalone: true, imports: [FieldFrameComponent, InputSelectControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2924
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputSelectComponent), multi: true },
|
|
2925
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSelectComponent), multi: true },
|
|
2926
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [disabled]=\"disabled\">\n <input-select-control\n [placeholder]=\"placeholder\"\n [name]=\"name\"\n [data]=\"data\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [includeBlankOption]=\"includeBlankOption\"\n [blankOptionLabel]=\"blankOptionLabel\"\n [emptyStateLabel]=\"emptyStateLabel\"\n [searchable]=\"searchable\"\n [options]=\"options\"\n [triggerClass]=\"triggerClass\"\n [panelClass]=\"panelClass\"\n (valueChange)=\"valueChange.emit($event)\"\n (searchChange)=\"searchChange.emit($event)\"\n />\n</field-frame>\n" }]
|
|
2927
|
+
}], propDecorators: { control: [{
|
|
2928
|
+
type: ViewChild,
|
|
2929
|
+
args: [InputSelectControlComponent]
|
|
2930
|
+
}], label: [{
|
|
2931
|
+
type: Input
|
|
2932
|
+
}], hint: [{
|
|
2933
|
+
type: Input
|
|
2934
|
+
}], error: [{
|
|
2935
|
+
type: Input
|
|
2936
|
+
}], placeholder: [{
|
|
2937
|
+
type: Input
|
|
2938
|
+
}], name: [{
|
|
2939
|
+
type: Input
|
|
2940
|
+
}], data: [{
|
|
2941
|
+
type: Input
|
|
2942
|
+
}], required: [{
|
|
2943
|
+
type: Input
|
|
2944
|
+
}], disabled: [{
|
|
2945
|
+
type: Input
|
|
2946
|
+
}], multiple: [{
|
|
2947
|
+
type: Input,
|
|
2948
|
+
args: [{ transform: booleanAttribute }]
|
|
2949
|
+
}], includeBlankOption: [{
|
|
2950
|
+
type: Input
|
|
2951
|
+
}], blankOptionLabel: [{
|
|
2952
|
+
type: Input
|
|
2953
|
+
}], emptyStateLabel: [{
|
|
2954
|
+
type: Input
|
|
2955
|
+
}], searchable: [{
|
|
2956
|
+
type: Input
|
|
2957
|
+
}], options: [{
|
|
2958
|
+
type: Input
|
|
2959
|
+
}], triggerClass: [{
|
|
2960
|
+
type: Input
|
|
2961
|
+
}], panelClass: [{
|
|
2962
|
+
type: Input
|
|
2963
|
+
}], valueChange: [{
|
|
2964
|
+
type: Output
|
|
2965
|
+
}], searchChange: [{
|
|
2966
|
+
type: Output
|
|
2967
|
+
}] } });
|
|
2968
|
+
|
|
2969
|
+
class InputSlugControlComponent {
|
|
2970
|
+
placeholder;
|
|
2971
|
+
name;
|
|
2972
|
+
id;
|
|
2973
|
+
autocomplete = 'off';
|
|
2974
|
+
disabled = false;
|
|
2975
|
+
value = '';
|
|
2976
|
+
valueChange = new EventEmitter();
|
|
2977
|
+
touched = new EventEmitter();
|
|
2978
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSlugControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2979
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputSlugControlComponent, isStandalone: true, selector: "input-slug-control", inputs: { placeholder: "placeholder", name: "name", id: "id", autocomplete: "autocomplete", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input type="text" class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.placeholder]="placeholder" [attr.name]="name" [attr.autocomplete]="autocomplete" [disabled]="disabled" [attr.id]="id" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />`, isInline: true });
|
|
2980
|
+
}
|
|
2981
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSlugControlComponent, decorators: [{
|
|
2982
|
+
type: Component,
|
|
2983
|
+
args: [{
|
|
2984
|
+
selector: 'input-slug-control',
|
|
2985
|
+
standalone: true,
|
|
2986
|
+
template: `<input type="text" class="w-full rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-900 placeholder:text-slate-400 transition focus:border-slate-900 focus:outline-none focus:ring-2 focus:ring-slate-200" [attr.placeholder]="placeholder" [attr.name]="name" [attr.autocomplete]="autocomplete" [disabled]="disabled" [attr.id]="id" [value]="value" (input)="valueChange.emit($any($event.target).value)" (blur)="touched.emit()" />`,
|
|
2987
|
+
}]
|
|
2988
|
+
}], propDecorators: { placeholder: [{
|
|
2989
|
+
type: Input
|
|
2990
|
+
}], name: [{
|
|
2991
|
+
type: Input
|
|
2992
|
+
}], id: [{
|
|
2993
|
+
type: Input
|
|
2994
|
+
}], autocomplete: [{
|
|
2995
|
+
type: Input
|
|
2996
|
+
}], disabled: [{
|
|
2997
|
+
type: Input
|
|
2998
|
+
}], value: [{
|
|
2999
|
+
type: Input
|
|
3000
|
+
}], valueChange: [{
|
|
3001
|
+
type: Output
|
|
3002
|
+
}], touched: [{
|
|
3003
|
+
type: Output
|
|
3004
|
+
}] } });
|
|
3005
|
+
|
|
2316
3006
|
class InputSlugComponent {
|
|
2317
3007
|
label;
|
|
2318
3008
|
hint;
|
|
@@ -2320,7 +3010,6 @@ class InputSlugComponent {
|
|
|
2320
3010
|
name;
|
|
2321
3011
|
id;
|
|
2322
3012
|
required = false;
|
|
2323
|
-
fullWidth = false;
|
|
2324
3013
|
autocomplete = 'off';
|
|
2325
3014
|
error;
|
|
2326
3015
|
invalidInput = new EventEmitter();
|
|
@@ -2355,6 +3044,13 @@ class InputSlugComponent {
|
|
|
2355
3044
|
this.value = normalized;
|
|
2356
3045
|
this.onChange(normalized);
|
|
2357
3046
|
}
|
|
3047
|
+
handleValueChange(value) {
|
|
3048
|
+
const normalized = this.normalizeSlug(value);
|
|
3049
|
+
if (value !== normalized)
|
|
3050
|
+
this.invalidInput.emit();
|
|
3051
|
+
this.value = normalized;
|
|
3052
|
+
this.onChange(normalized);
|
|
3053
|
+
}
|
|
2358
3054
|
normalizeSlug(value) {
|
|
2359
3055
|
return (value ?? '')
|
|
2360
3056
|
.toLowerCase()
|
|
@@ -2362,25 +3058,25 @@ class InputSlugComponent {
|
|
|
2362
3058
|
.replace(/[^a-z0-9_]/g, '');
|
|
2363
3059
|
}
|
|
2364
3060
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSlugComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2365
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3061
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputSlugComponent, isStandalone: true, selector: "input-slug", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", required: "required", autocomplete: "autocomplete", error: "error" }, outputs: { invalidInput: "invalidInput" }, providers: [
|
|
2366
3062
|
{
|
|
2367
3063
|
provide: NG_VALUE_ACCESSOR,
|
|
2368
3064
|
useExisting: forwardRef(() => InputSlugComponent),
|
|
2369
3065
|
multi: true,
|
|
2370
3066
|
},
|
|
2371
3067
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSlugComponent), multi: true },
|
|
2372
|
-
], ngImport: i0, template: "<
|
|
3068
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\">\n <input-slug-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"handleValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputSlugControlComponent, selector: "input-slug-control", inputs: ["placeholder", "name", "id", "autocomplete", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2373
3069
|
}
|
|
2374
3070
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputSlugComponent, decorators: [{
|
|
2375
3071
|
type: Component,
|
|
2376
|
-
args: [{ selector: 'input-slug', standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3072
|
+
args: [{ selector: 'input-slug', standalone: true, imports: [CommonModule, FormsModule, FieldFrameComponent, InputSlugControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2377
3073
|
{
|
|
2378
3074
|
provide: NG_VALUE_ACCESSOR,
|
|
2379
3075
|
useExisting: forwardRef(() => InputSlugComponent),
|
|
2380
3076
|
multi: true,
|
|
2381
3077
|
},
|
|
2382
3078
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => InputSlugComponent), multi: true },
|
|
2383
|
-
], template: "<
|
|
3079
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\">\n <input-slug-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [autocomplete]=\"autocomplete\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"handleValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
2384
3080
|
}], propDecorators: { label: [{
|
|
2385
3081
|
type: Input
|
|
2386
3082
|
}], hint: [{
|
|
@@ -2393,8 +3089,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2393
3089
|
type: Input
|
|
2394
3090
|
}], required: [{
|
|
2395
3091
|
type: Input
|
|
2396
|
-
}], fullWidth: [{
|
|
2397
|
-
type: Input
|
|
2398
3092
|
}], autocomplete: [{
|
|
2399
3093
|
type: Input
|
|
2400
3094
|
}], error: [{
|
|
@@ -2425,7 +3119,7 @@ class FieldInputComponent {
|
|
|
2425
3119
|
value;
|
|
2426
3120
|
error = '';
|
|
2427
3121
|
disabled = false;
|
|
2428
|
-
|
|
3122
|
+
visibleActions = [];
|
|
2429
3123
|
valueChange = new EventEmitter();
|
|
2430
3124
|
actionTriggered = new EventEmitter();
|
|
2431
3125
|
lookupRequested = new EventEmitter();
|
|
@@ -2476,11 +3170,17 @@ class FieldInputComponent {
|
|
|
2476
3170
|
if (!this.componentRef || !this.field)
|
|
2477
3171
|
return;
|
|
2478
3172
|
const field = this.field;
|
|
3173
|
+
const config = field;
|
|
2479
3174
|
const setInput = (name, value) => this.componentRef?.setInput(name, value);
|
|
2480
3175
|
const inputType = String(field.type || 'text');
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
3176
|
+
if (field.label !== undefined)
|
|
3177
|
+
setInput('label', field.label);
|
|
3178
|
+
if (field.hint !== undefined)
|
|
3179
|
+
setInput('hint', field.hint);
|
|
3180
|
+
setInput('error', this.error);
|
|
3181
|
+
if (typeof field.required === 'boolean')
|
|
3182
|
+
setInput('required', field.required);
|
|
3183
|
+
// FieldInput only adapts the dynamic field to the selected control.
|
|
2484
3184
|
switch (inputType) {
|
|
2485
3185
|
case 'text':
|
|
2486
3186
|
case 'number':
|
|
@@ -2489,57 +3189,44 @@ class FieldInputComponent {
|
|
|
2489
3189
|
case 'email':
|
|
2490
3190
|
case 'password':
|
|
2491
3191
|
case 'textarea':
|
|
3192
|
+
setInput('actions', this.visibleActions);
|
|
2492
3193
|
setInput('name', field.id);
|
|
2493
3194
|
setInput('id', field.id);
|
|
2494
3195
|
setInput('placeholder', field.placeholder);
|
|
2495
|
-
setInput('pattern',
|
|
2496
|
-
setInput('rows',
|
|
2497
|
-
setInput('fullWidth', fullWidth);
|
|
3196
|
+
setInput('pattern', config['pattern']);
|
|
3197
|
+
setInput('rows', config['rows'] ?? 4);
|
|
2498
3198
|
break;
|
|
2499
3199
|
case 'slug':
|
|
2500
3200
|
setInput('name', field.id);
|
|
2501
3201
|
setInput('id', field.id);
|
|
2502
3202
|
setInput('placeholder', field.placeholder);
|
|
2503
|
-
setInput('fullWidth', fullWidth);
|
|
2504
3203
|
break;
|
|
2505
3204
|
case 'select':
|
|
2506
3205
|
setInput('name', field.id);
|
|
2507
3206
|
setInput('placeholder', field.placeholder);
|
|
2508
|
-
setInput('data',
|
|
2509
|
-
setInput('options',
|
|
2510
|
-
setInput('multiple', !!
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
setInput('fullWidth', fullWidth);
|
|
3207
|
+
setInput('data', config['data']);
|
|
3208
|
+
setInput('options', config['options'] || []);
|
|
3209
|
+
setInput('multiple', !!config['multiple']);
|
|
3210
|
+
if (typeof config['searchable'] === 'boolean') {
|
|
3211
|
+
setInput('searchable', config['searchable']);
|
|
3212
|
+
}
|
|
2515
3213
|
break;
|
|
2516
3214
|
case 'color':
|
|
2517
3215
|
setInput('name', field.id);
|
|
2518
3216
|
setInput('id', field.id);
|
|
2519
|
-
setInput('required', false);
|
|
2520
|
-
setInput('fullWidth', fullWidth);
|
|
2521
3217
|
break;
|
|
2522
3218
|
case 'file':
|
|
2523
|
-
setInput('accept',
|
|
2524
|
-
setInput('multiple', !!
|
|
3219
|
+
setInput('accept', config['accept']);
|
|
3220
|
+
setInput('multiple', !!config['multiple']);
|
|
2525
3221
|
break;
|
|
2526
3222
|
case 'photo':
|
|
2527
|
-
setInput('accept',
|
|
2528
|
-
setInput('multiple', !!
|
|
2529
|
-
setInput('limit',
|
|
3223
|
+
setInput('accept', config['accept'] || 'image/*');
|
|
3224
|
+
setInput('multiple', !!config['multiple']);
|
|
3225
|
+
setInput('limit', config['limit'] ?? 0);
|
|
2530
3226
|
break;
|
|
2531
3227
|
case 'barcode':
|
|
2532
|
-
setInput('label', '');
|
|
2533
|
-
setInput('hint', '');
|
|
2534
3228
|
setInput('placeholder', field.placeholder);
|
|
2535
3229
|
setInput('disabled', this.disabled);
|
|
2536
|
-
setInput('autoOpen', field.autoOpen !== false);
|
|
2537
|
-
setInput('searchButtonLabel', field.searchButtonLabel || 'Знайти');
|
|
2538
|
-
setInput('openCameraLabel', field.openCameraLabel || 'Відкрити камеру');
|
|
2539
|
-
setInput('closeCameraLabel', field.closeCameraLabel || 'Закрити камеру');
|
|
2540
|
-
setInput('cameraTitle', field.cameraTitle || 'Камера');
|
|
2541
|
-
setInput('cameraStartingLabel', field.cameraStartingLabel || 'Запускаємо камеру…');
|
|
2542
|
-
setInput('cameraHint', field.cameraHint || 'Наведіть камеру на штрихкод. Після зчитування код підставиться автоматично.');
|
|
2543
3230
|
setInput('value', this.value ?? '');
|
|
2544
3231
|
break;
|
|
2545
3232
|
case 'checkbox':
|
|
@@ -2550,84 +3237,18 @@ class FieldInputComponent {
|
|
|
2550
3237
|
instance.setDisabledState?.(this.disabled);
|
|
2551
3238
|
}
|
|
2552
3239
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FieldInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2553
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2554
|
-
<
|
|
2555
|
-
|
|
2556
|
-
<label class="text-[0.7rem] font-semibold uppercase tracking-[0.2em] text-slate-600" [attr.for]="field.id">
|
|
2557
|
-
{{ field.label }}
|
|
2558
|
-
@if (field.required) { <span aria-hidden="true" class="text-rose-500"> *</span> }
|
|
2559
|
-
</label>
|
|
2560
|
-
}
|
|
2561
|
-
|
|
2562
|
-
<div class="flex items-start gap-2" [class.rounded-xl]="!!error" [class.ring-2]="!!error" [class.ring-rose-200]="!!error">
|
|
2563
|
-
<div class="min-w-0 w-full flex-1">
|
|
2564
|
-
<ng-container #inputContainer></ng-container>
|
|
2565
|
-
</div>
|
|
2566
|
-
|
|
2567
|
-
@if (actions.length) {
|
|
2568
|
-
<div class="flex flex-none items-center gap-2 pt-0.5">
|
|
2569
|
-
@for (action of actions; track action.id) {
|
|
2570
|
-
<ui-button
|
|
2571
|
-
type="button"
|
|
2572
|
-
[variant]="action.variant ?? 'secondary'"
|
|
2573
|
-
[icon]="action.icon || ''"
|
|
2574
|
-
[size]="action.size || 'sm'"
|
|
2575
|
-
[disabled]="disabled"
|
|
2576
|
-
(click)="actionTriggered.emit(action)"
|
|
2577
|
-
>
|
|
2578
|
-
{{ action.label }}
|
|
2579
|
-
</ui-button>
|
|
2580
|
-
}
|
|
2581
|
-
</div>
|
|
2582
|
-
}
|
|
2583
|
-
</div>
|
|
2584
|
-
|
|
2585
|
-
@if (field.hint) { <p class="text-[0.5rem] text-slate-500">{{ field.hint }}</p> }
|
|
2586
|
-
@if (error) { <p class="text-[0.65rem] text-rose-500">{{ error }}</p> }
|
|
2587
|
-
</div>
|
|
2588
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }] });
|
|
3240
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: FieldInputComponent, isStandalone: true, selector: "field-input", inputs: { field: "field", value: "value", error: "error", disabled: "disabled", visibleActions: "visibleActions" }, outputs: { valueChange: "valueChange", actionTriggered: "actionTriggered", lookupRequested: "lookupRequested", barcodeScanned: "barcodeScanned", filesChange: "filesChange", uploadingChange: "uploadingChange" }, viewQueries: [{ propertyName: "inputContainer", first: true, predicate: ["inputContainer"], descendants: true, read: ViewContainerRef }], usesOnChanges: true, ngImport: i0, template: `
|
|
3241
|
+
<ng-container #inputContainer></ng-container>
|
|
3242
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2589
3243
|
}
|
|
2590
3244
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FieldInputComponent, decorators: [{
|
|
2591
3245
|
type: Component,
|
|
2592
3246
|
args: [{
|
|
2593
3247
|
selector: 'field-input',
|
|
2594
3248
|
standalone: true,
|
|
2595
|
-
imports: [CommonModule
|
|
3249
|
+
imports: [CommonModule],
|
|
2596
3250
|
template: `
|
|
2597
|
-
<
|
|
2598
|
-
@if (field.label) {
|
|
2599
|
-
<label class="text-[0.7rem] font-semibold uppercase tracking-[0.2em] text-slate-600" [attr.for]="field.id">
|
|
2600
|
-
{{ field.label }}
|
|
2601
|
-
@if (field.required) { <span aria-hidden="true" class="text-rose-500"> *</span> }
|
|
2602
|
-
</label>
|
|
2603
|
-
}
|
|
2604
|
-
|
|
2605
|
-
<div class="flex items-start gap-2" [class.rounded-xl]="!!error" [class.ring-2]="!!error" [class.ring-rose-200]="!!error">
|
|
2606
|
-
<div class="min-w-0 w-full flex-1">
|
|
2607
|
-
<ng-container #inputContainer></ng-container>
|
|
2608
|
-
</div>
|
|
2609
|
-
|
|
2610
|
-
@if (actions.length) {
|
|
2611
|
-
<div class="flex flex-none items-center gap-2 pt-0.5">
|
|
2612
|
-
@for (action of actions; track action.id) {
|
|
2613
|
-
<ui-button
|
|
2614
|
-
type="button"
|
|
2615
|
-
[variant]="action.variant ?? 'secondary'"
|
|
2616
|
-
[icon]="action.icon || ''"
|
|
2617
|
-
[size]="action.size || 'sm'"
|
|
2618
|
-
[disabled]="disabled"
|
|
2619
|
-
(click)="actionTriggered.emit(action)"
|
|
2620
|
-
>
|
|
2621
|
-
{{ action.label }}
|
|
2622
|
-
</ui-button>
|
|
2623
|
-
}
|
|
2624
|
-
</div>
|
|
2625
|
-
}
|
|
2626
|
-
</div>
|
|
2627
|
-
|
|
2628
|
-
@if (field.hint) { <p class="text-[0.5rem] text-slate-500">{{ field.hint }}</p> }
|
|
2629
|
-
@if (error) { <p class="text-[0.65rem] text-rose-500">{{ error }}</p> }
|
|
2630
|
-
</div>
|
|
3251
|
+
<ng-container #inputContainer></ng-container>
|
|
2631
3252
|
`,
|
|
2632
3253
|
}]
|
|
2633
3254
|
}], propDecorators: { field: [{
|
|
@@ -2638,7 +3259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2638
3259
|
type: Input
|
|
2639
3260
|
}], disabled: [{
|
|
2640
3261
|
type: Input
|
|
2641
|
-
}],
|
|
3262
|
+
}], visibleActions: [{
|
|
2642
3263
|
type: Input
|
|
2643
3264
|
}], valueChange: [{
|
|
2644
3265
|
type: Output
|
|
@@ -2898,6 +3519,8 @@ class DynamicFormComponent {
|
|
|
2898
3519
|
this.runFieldLookup(field);
|
|
2899
3520
|
}
|
|
2900
3521
|
runFieldLookup(field, overrideValue) {
|
|
3522
|
+
if (!isDynamicFormLookupField(field))
|
|
3523
|
+
return;
|
|
2901
3524
|
const api = String(field.lookupApi || '').trim();
|
|
2902
3525
|
if (!api)
|
|
2903
3526
|
return;
|
|
@@ -3047,7 +3670,7 @@ class DynamicFormComponent {
|
|
|
3047
3670
|
].filter(Boolean).join(' ');
|
|
3048
3671
|
}
|
|
3049
3672
|
getContainerContentClass(field) {
|
|
3050
|
-
const className = String(field.contentClassName || '').trim();
|
|
3673
|
+
const className = String(this.isContainerField(field) ? field.contentClassName || '' : '').trim();
|
|
3051
3674
|
const layout = this.isContainerField(field) ? field.layout : undefined;
|
|
3052
3675
|
return [
|
|
3053
3676
|
layout === 'stack' ? 'space-y-4' : 'grid grid-cols-1 gap-4 md:grid-cols-12',
|
|
@@ -3090,6 +3713,8 @@ class DynamicFormComponent {
|
|
|
3090
3713
|
return classes[span] || classes[12];
|
|
3091
3714
|
}
|
|
3092
3715
|
applyLookupResponse(field, response) {
|
|
3716
|
+
if (!isDynamicFormLookupField(field))
|
|
3717
|
+
return;
|
|
3093
3718
|
const lookupMap = field.lookupMap || {};
|
|
3094
3719
|
const mapped = Object.entries(lookupMap).reduce((acc, [targetField, sourcePath]) => {
|
|
3095
3720
|
acc[targetField] = this.resolveTemplateValue(response, sourcePath);
|
|
@@ -3121,11 +3746,11 @@ class DynamicFormComponent {
|
|
|
3121
3746
|
return this.getFlatFields().filter((field) => field.type !== 'container' && field.type !== 'template');
|
|
3122
3747
|
}
|
|
3123
3748
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3124
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { fields: "fields", value: "value", errors: "errors", submitLabel: "submitLabel", showSubmit: "showSubmit", disabled: "disabled" }, outputs: { valueChange: "valueChange", lookupCompleted: "lookupCompleted", submitted: "submitted", filesChange: "filesChange", uploadingChange: "uploadingChange", fieldActionTriggered: "fieldActionTriggered" }, providers: [UiFormContext, UiFormLookupService], usesOnChanges: true, ngImport: i0, template: "<form class=\"grid grid-cols-1 gap-4 md:grid-cols-12\" (ngSubmit)=\"submitForm()\" #dynamicForm=\"ngForm\">\n <ng-template #renderField let-field>\n @if (isFieldVisible(field)) {\n @if (isContainerField(field)) {\n @if (getContainerTag(field) === 'aside') {\n <aside [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <p class=\"text-xs font-semibold uppercase tracking-[0.22em] text-slate-500\">\n {{ field.label || field.title }}\n </p>\n }\n @if (field.hint) {\n <h3 class=\"mt-1 text-lg font-semibold text-slate-900\">{{ field.hint }}</h3>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </aside>\n } @else if (getContainerTag(field) === 'fieldset') {\n <fieldset [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <legend class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</legend>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </fieldset>\n } @else {\n <section [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <h3 class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</h3>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </section>\n }\n } @else if (isTemplateField(field)) {\n <div [ngClass]=\"resolveClassName(field.className)\" [innerHTML]=\"renderTemplate(field)\"></div>\n } @else {\n <div [ngClass]=\"getFieldClass(field)\">\n <field-input\n [field]=\"field\"\n [value]=\"modelSignal()[field.id]\"\n [disabled]=\"disabled || isFieldDisabled(field) || isLookupLoading(field.id)\"\n [error]=\"errors[field.id] ?? getLookupError(field.id)\"\n [
|
|
3749
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { fields: "fields", value: "value", errors: "errors", submitLabel: "submitLabel", showSubmit: "showSubmit", disabled: "disabled" }, outputs: { valueChange: "valueChange", lookupCompleted: "lookupCompleted", submitted: "submitted", filesChange: "filesChange", uploadingChange: "uploadingChange", fieldActionTriggered: "fieldActionTriggered" }, providers: [UiFormContext, UiFormLookupService], usesOnChanges: true, ngImport: i0, template: "<form class=\"grid grid-cols-1 gap-4 md:grid-cols-12\" (ngSubmit)=\"submitForm()\" #dynamicForm=\"ngForm\">\n <ng-template #renderField let-field>\n @if (isFieldVisible(field)) {\n @if (isContainerField(field)) {\n @if (getContainerTag(field) === 'aside') {\n <aside [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <p class=\"text-xs font-semibold uppercase tracking-[0.22em] text-slate-500\">\n {{ field.label || field.title }}\n </p>\n }\n @if (field.hint) {\n <h3 class=\"mt-1 text-lg font-semibold text-slate-900\">{{ field.hint }}</h3>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </aside>\n } @else if (getContainerTag(field) === 'fieldset') {\n <fieldset [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <legend class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</legend>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </fieldset>\n } @else {\n <section [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <h3 class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</h3>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </section>\n }\n } @else if (isTemplateField(field)) {\n <div [ngClass]=\"resolveClassName(field.className)\" [innerHTML]=\"renderTemplate(field)\"></div>\n } @else {\n <div [ngClass]=\"getFieldClass(field)\">\n <field-input\n [field]=\"field\"\n [value]=\"modelSignal()[field.id]\"\n [disabled]=\"disabled || isFieldDisabled(field) || isLookupLoading(field.id)\"\n [error]=\"errors[field.id] ?? getLookupError(field.id)\"\n [visibleActions]=\"resolveFieldActions(field)\"\n (valueChange)=\"onFieldValueChange(field, $event)\"\n (actionTriggered)=\"onFieldActionTriggered(field.id, $event)\"\n (lookupRequested)=\"runBarcodeLookup(field)\"\n (barcodeScanned)=\"onBarcodeScanned(field, $event)\"\n (filesChange)=\"filesChange.emit({ fieldId: field.id, files: $event })\"\n (uploadingChange)=\"uploadingChange.emit($event)\"\n ></field-input>\n </div>\n }\n }\n </ng-template>\n\n @for (field of fields; track field.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: field }\"></ng-container>\n }\n\n @if (showSubmit) {\n <div class=\"flex justify-end md:col-span-12\">\n <button\n type=\"submit\"\n class=\"inline-flex items-center rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-slate-800 disabled:opacity-50\"\n [disabled]=\"disabled || !dynamicForm.form.valid\"\n >\n {{ submitLabel }}\n </button>\n </div>\n }\n</form>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "withShadow", "icon", "iconOnly", "ariaLabel"] }, { kind: "component", type: FieldInputComponent, selector: "field-input", inputs: ["field", "value", "error", "disabled", "visibleActions"], outputs: ["valueChange", "actionTriggered", "lookupRequested", "barcodeScanned", "filesChange", "uploadingChange"] }] });
|
|
3125
3750
|
}
|
|
3126
3751
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DynamicFormComponent, decorators: [{
|
|
3127
3752
|
type: Component,
|
|
3128
|
-
args: [{ selector: 'dynamic-form', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldInputComponent], providers: [UiFormContext, UiFormLookupService], template: "<form class=\"grid grid-cols-1 gap-4 md:grid-cols-12\" (ngSubmit)=\"submitForm()\" #dynamicForm=\"ngForm\">\n <ng-template #renderField let-field>\n @if (isFieldVisible(field)) {\n @if (isContainerField(field)) {\n @if (getContainerTag(field) === 'aside') {\n <aside [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <p class=\"text-xs font-semibold uppercase tracking-[0.22em] text-slate-500\">\n {{ field.label || field.title }}\n </p>\n }\n @if (field.hint) {\n <h3 class=\"mt-1 text-lg font-semibold text-slate-900\">{{ field.hint }}</h3>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </aside>\n } @else if (getContainerTag(field) === 'fieldset') {\n <fieldset [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <legend class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</legend>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </fieldset>\n } @else {\n <section [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <h3 class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</h3>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </section>\n }\n } @else if (isTemplateField(field)) {\n <div [ngClass]=\"resolveClassName(field.className)\" [innerHTML]=\"renderTemplate(field)\"></div>\n } @else {\n <div [ngClass]=\"getFieldClass(field)\">\n <field-input\n [field]=\"field\"\n [value]=\"modelSignal()[field.id]\"\n [disabled]=\"disabled || isFieldDisabled(field) || isLookupLoading(field.id)\"\n [error]=\"errors[field.id] ?? getLookupError(field.id)\"\n [
|
|
3753
|
+
args: [{ selector: 'dynamic-form', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldInputComponent], providers: [UiFormContext, UiFormLookupService], template: "<form class=\"grid grid-cols-1 gap-4 md:grid-cols-12\" (ngSubmit)=\"submitForm()\" #dynamicForm=\"ngForm\">\n <ng-template #renderField let-field>\n @if (isFieldVisible(field)) {\n @if (isContainerField(field)) {\n @if (getContainerTag(field) === 'aside') {\n <aside [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <p class=\"text-xs font-semibold uppercase tracking-[0.22em] text-slate-500\">\n {{ field.label || field.title }}\n </p>\n }\n @if (field.hint) {\n <h3 class=\"mt-1 text-lg font-semibold text-slate-900\">{{ field.hint }}</h3>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </aside>\n } @else if (getContainerTag(field) === 'fieldset') {\n <fieldset [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <legend class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</legend>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </fieldset>\n } @else {\n <section [ngClass]=\"getContainerClass(field)\">\n @if (field.label || field.title || getActions(field).length || field.hint) {\n <header class=\"flex flex-col gap-3 border-b border-slate-100 pb-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n @if (field.label || field.title) {\n <h3 class=\"text-lg font-semibold text-slate-900\">{{ field.label || field.title }}</h3>\n }\n @if (field.hint) {\n <p class=\"mt-1 text-sm text-slate-500\">{{ field.hint }}</p>\n }\n </div>\n\n @if (getActions(field).length) {\n <div class=\"flex flex-wrap gap-2 md:justify-end\">\n @for (action of getActions(field); track action.id; let i = $index) {\n <ui-button\n [variant]=\"action.variant || (i === 0 ? 'primary' : 'ghost')\"\n [icon]=\"action.icon || ''\"\n size=\"sm\"\n [disabled]=\"disabled\"\n (click)=\"onFieldActionTriggered(field.id, action)\"\n >\n {{ action.label }}\n </ui-button>\n }\n </div>\n }\n </header>\n }\n\n <div [ngClass]=\"getContainerContentClass(field)\">\n @for (child of field.fields; track child.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: child }\"></ng-container>\n }\n </div>\n </section>\n }\n } @else if (isTemplateField(field)) {\n <div [ngClass]=\"resolveClassName(field.className)\" [innerHTML]=\"renderTemplate(field)\"></div>\n } @else {\n <div [ngClass]=\"getFieldClass(field)\">\n <field-input\n [field]=\"field\"\n [value]=\"modelSignal()[field.id]\"\n [disabled]=\"disabled || isFieldDisabled(field) || isLookupLoading(field.id)\"\n [error]=\"errors[field.id] ?? getLookupError(field.id)\"\n [visibleActions]=\"resolveFieldActions(field)\"\n (valueChange)=\"onFieldValueChange(field, $event)\"\n (actionTriggered)=\"onFieldActionTriggered(field.id, $event)\"\n (lookupRequested)=\"runBarcodeLookup(field)\"\n (barcodeScanned)=\"onBarcodeScanned(field, $event)\"\n (filesChange)=\"filesChange.emit({ fieldId: field.id, files: $event })\"\n (uploadingChange)=\"uploadingChange.emit($event)\"\n ></field-input>\n </div>\n }\n }\n </ng-template>\n\n @for (field of fields; track field.id) {\n <ng-container *ngTemplateOutlet=\"renderField; context: { $implicit: field }\"></ng-container>\n }\n\n @if (showSubmit) {\n <div class=\"flex justify-end md:col-span-12\">\n <button\n type=\"submit\"\n class=\"inline-flex items-center rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-slate-800 disabled:opacity-50\"\n [disabled]=\"disabled || !dynamicForm.form.valid\"\n >\n {{ submitLabel }}\n </button>\n </div>\n }\n</form>\n" }]
|
|
3129
3754
|
}], propDecorators: { fields: [{
|
|
3130
3755
|
type: Input
|
|
3131
3756
|
}], value: [{
|
|
@@ -3353,6 +3978,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3353
3978
|
args: [{ selector: 'form-modal', standalone: true, imports: [CommonModule, UiButtonComponent, DynamicFormComponent], template: "@if (isOpen()) {\n <div class=\"fixed inset-0 z-50 flex min-h-full items-center justify-center overflow-y-auto bg-slate-950/40 p-4 sm:p-6\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"my-0 flex min-h-0 max-h-[calc(100vh-2rem)] w-full flex-col overflow-hidden rounded-2xl bg-slate-50 shadow-2xl sm:max-h-[calc(100vh-3rem)]\" [ngClass]=\"panelClass()\">\n <div class=\"flex shrink-0 items-center justify-between border-b border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <h2 class=\"text-lg font-semibold\">{{ formConfig()?.title || 'Form' }}</h2>\n <button type=\"button\" class=\"text-xl text-slate-400 hover:text-slate-900\" aria-label=\"Close\" (click)=\"close()\">\u00D7</button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6\">\n @if (isLoading()) {\n <p class=\"text-sm text-slate-500\">Loading form\u2026</p>\n } @else {\n <dynamic-form [fields]=\"fields()\" [value]=\"formValue()\" [disabled]=\"isLoading() || isSubmitting() || isActionRunning()\" [showSubmit]=\"false\" (valueChange)=\"onValueChange($event)\" (lookupCompleted)=\"onLookupCompleted($event)\" (uploadingChange)=\"onUploadingChange($event)\" (fieldActionTriggered)=\"onFieldActionTriggered($event)\"></dynamic-form>\n }\n </div>\n <div class=\"relative z-10 flex shrink-0 justify-end gap-3 border-t border-slate-200 bg-white px-5 py-4 sm:px-6\">\n <ui-button variant=\"ghost\" (click)=\"close()\">{{ cancelLabel() }}</ui-button>\n @if (submitAction()) { <ui-button variant=\"primary\" [disabled]=\"isLoading() || isSubmitting() || isUploading()\" (click)=\"confirm()\">{{ submitLabel() }}</ui-button> }\n </div>\n </div>\n </div>\n}\n" }]
|
|
3354
3979
|
}], propDecorators: { formId: [{ type: i0.Input, args: [{ isSignal: true, alias: "formId", required: false }] }], recordId: [{ type: i0.Input, args: [{ isSignal: true, alias: "recordId", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], initialValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValue", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], completed: [{ type: i0.Output, args: ["completed"] }] } });
|
|
3355
3980
|
|
|
3981
|
+
class InputBaseControlComponent {
|
|
3982
|
+
placeholder;
|
|
3983
|
+
name;
|
|
3984
|
+
id;
|
|
3985
|
+
type = 'text';
|
|
3986
|
+
element = 'input';
|
|
3987
|
+
rows = 4;
|
|
3988
|
+
autocomplete;
|
|
3989
|
+
pattern;
|
|
3990
|
+
disabled = false;
|
|
3991
|
+
value = '';
|
|
3992
|
+
valueChange = new EventEmitter();
|
|
3993
|
+
touched = new EventEmitter();
|
|
3994
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBaseControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3995
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputBaseControlComponent, isStandalone: true, selector: "input-base-control", inputs: { placeholder: "placeholder", name: "name", id: "id", type: "type", element: "element", rows: "rows", autocomplete: "autocomplete", pattern: "pattern", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange", touched: "touched" }, ngImport: i0, template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" [type]="type" [element]="element" [rows]="rows" [autocomplete]="autocomplete" [pattern]="pattern" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />`, isInline: true, dependencies: [{ kind: "component", type: InputTextControlComponent, selector: "input-text-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }] });
|
|
3996
|
+
}
|
|
3997
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputBaseControlComponent, decorators: [{
|
|
3998
|
+
type: Component,
|
|
3999
|
+
args: [{ selector: 'input-base-control', standalone: true, imports: [InputTextControlComponent], template: `<input-text-control [placeholder]="placeholder" [name]="name" [id]="id" [type]="type" [element]="element" [rows]="rows" [autocomplete]="autocomplete" [pattern]="pattern" [disabled]="disabled" [value]="value" (valueChange)="valueChange.emit($event)" (touched)="touched.emit()" />` }]
|
|
4000
|
+
}], propDecorators: { placeholder: [{
|
|
4001
|
+
type: Input
|
|
4002
|
+
}], name: [{
|
|
4003
|
+
type: Input
|
|
4004
|
+
}], id: [{
|
|
4005
|
+
type: Input
|
|
4006
|
+
}], type: [{
|
|
4007
|
+
type: Input
|
|
4008
|
+
}], element: [{
|
|
4009
|
+
type: Input
|
|
4010
|
+
}], rows: [{
|
|
4011
|
+
type: Input
|
|
4012
|
+
}], autocomplete: [{
|
|
4013
|
+
type: Input
|
|
4014
|
+
}], pattern: [{
|
|
4015
|
+
type: Input
|
|
4016
|
+
}], disabled: [{
|
|
4017
|
+
type: Input
|
|
4018
|
+
}], value: [{
|
|
4019
|
+
type: Input
|
|
4020
|
+
}], valueChange: [{
|
|
4021
|
+
type: Output
|
|
4022
|
+
}], touched: [{
|
|
4023
|
+
type: Output
|
|
4024
|
+
}] } });
|
|
4025
|
+
|
|
3356
4026
|
class InputComponent {
|
|
3357
4027
|
cdr = inject(ChangeDetectorRef);
|
|
3358
4028
|
label;
|
|
@@ -3364,7 +4034,6 @@ class InputComponent {
|
|
|
3364
4034
|
element = 'input';
|
|
3365
4035
|
rows = 4;
|
|
3366
4036
|
required = false;
|
|
3367
|
-
fullWidth = false;
|
|
3368
4037
|
autocomplete;
|
|
3369
4038
|
pattern;
|
|
3370
4039
|
error;
|
|
@@ -3402,23 +4071,23 @@ class InputComponent {
|
|
|
3402
4071
|
this.actionTriggered.emit(action);
|
|
3403
4072
|
}
|
|
3404
4073
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3405
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
4074
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputComponent, isStandalone: true, selector: "input-base", inputs: { label: "label", hint: "hint", placeholder: "placeholder", name: "name", id: "id", type: "type", element: "element", rows: "rows", required: "required", autocomplete: "autocomplete", pattern: "pattern", error: "error", actions: "actions" }, outputs: { actionTriggered: "actionTriggered" }, providers: [
|
|
3406
4075
|
{
|
|
3407
4076
|
provide: NG_VALUE_ACCESSOR,
|
|
3408
4077
|
useExisting: forwardRef(() => InputComponent),
|
|
3409
4078
|
multi: true,
|
|
3410
4079
|
},
|
|
3411
|
-
], ngImport: i0, template: "<
|
|
4080
|
+
], ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-base-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [type]=\"type\" [element]=\"element\" [rows]=\"rows\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }, { kind: "component", type: InputBaseControlComponent, selector: "input-base-control", inputs: ["placeholder", "name", "id", "type", "element", "rows", "autocomplete", "pattern", "disabled", "value"], outputs: ["valueChange", "touched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3412
4081
|
}
|
|
3413
4082
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputComponent, decorators: [{
|
|
3414
4083
|
type: Component,
|
|
3415
|
-
args: [{ selector: 'input-base', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
4084
|
+
args: [{ selector: 'input-base', standalone: true, imports: [CommonModule, FormsModule, UiButtonComponent, FieldFrameComponent, InputBaseControlComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3416
4085
|
{
|
|
3417
4086
|
provide: NG_VALUE_ACCESSOR,
|
|
3418
4087
|
useExisting: forwardRef(() => InputComponent),
|
|
3419
4088
|
multi: true,
|
|
3420
4089
|
},
|
|
3421
|
-
], template: "<
|
|
4090
|
+
], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\" [forId]=\"controlId\" [disabled]=\"disabled\" [actions]=\"actions\" (actionTriggered)=\"triggerAction($event)\">\n <input-base-control [placeholder]=\"placeholder\" [name]=\"name\" [id]=\"controlId\" [type]=\"type\" [element]=\"element\" [rows]=\"rows\" [autocomplete]=\"autocomplete\" [pattern]=\"pattern\" [disabled]=\"disabled\" [value]=\"value\" (valueChange)=\"onValueChange($event)\" (touched)=\"onTouched()\" />\n</field-frame>\n" }]
|
|
3422
4091
|
}], propDecorators: { label: [{
|
|
3423
4092
|
type: Input
|
|
3424
4093
|
}], hint: [{
|
|
@@ -3437,8 +4106,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3437
4106
|
type: Input
|
|
3438
4107
|
}], required: [{
|
|
3439
4108
|
type: Input
|
|
3440
|
-
}], fullWidth: [{
|
|
3441
|
-
type: Input
|
|
3442
4109
|
}], autocomplete: [{
|
|
3443
4110
|
type: Input
|
|
3444
4111
|
}], pattern: [{
|
|
@@ -3454,6 +4121,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3454
4121
|
class InputPhotoGalleryComponent {
|
|
3455
4122
|
http = inject(HttpClient);
|
|
3456
4123
|
label = 'Фото';
|
|
4124
|
+
hint;
|
|
4125
|
+
error;
|
|
4126
|
+
required = false;
|
|
3457
4127
|
orderLabel = 'Порядок фото (перетягуй)';
|
|
3458
4128
|
imageIds = [];
|
|
3459
4129
|
disabled = false;
|
|
@@ -3594,13 +4264,19 @@ class InputPhotoGalleryComponent {
|
|
|
3594
4264
|
return this.http.post('/api/files/', formData).pipe(map((response) => ({ imageId: response.id })));
|
|
3595
4265
|
}
|
|
3596
4266
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoGalleryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputPhotoGalleryComponent, isStandalone: true, selector: "input-photo-gallery", inputs: { label: "label", orderLabel: "orderLabel", imageIds: "imageIds", disabled: "disabled", afterUpload: "afterUpload", resolveImageUrl: "resolveImageUrl", notify: "notify" }, outputs: { imageIdsChange: "imageIdsChange" }, usesOnChanges: true, ngImport: i0, template: "<label
|
|
4267
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InputPhotoGalleryComponent, isStandalone: true, selector: "input-photo-gallery", inputs: { label: "label", hint: "hint", error: "error", required: "required", orderLabel: "orderLabel", imageIds: "imageIds", disabled: "disabled", afterUpload: "afterUpload", resolveImageUrl: "resolveImageUrl", notify: "notify" }, outputs: { imageIdsChange: "imageIdsChange" }, usesOnChanges: true, ngImport: i0, template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <p class=\"mb-2 text-xs uppercase tracking-[0.2em] text-slate-500\">{{ orderLabel }}</p>\n <div class=\"grid gap-3 md:grid-cols-4\" cdkDropList [cdkDropListData]=\"entries\" (cdkDropListDropped)=\"onDrop($event)\">\n @for (entry of entries; let i = $index; track entry.clientKey + '-' + i) {\n <div class=\"image-drag-item relative overflow-hidden rounded-xl border border-slate-200 bg-white\" cdkDrag [cdkDragDisabled]=\"disabled || (!entry.imageId && !entry.file)\">\n <label class=\"block h-full w-full cursor-pointer\">\n @if (entry.preview) {\n <img [src]=\"entry.preview\" alt=\"photo\" class=\"h-48 w-full object-cover\" />\n } @else {\n <button type=\"button\" class=\"flex h-48 w-full items-center justify-center bg-slate-50 text-xs text-slate-500\" (click)=\"openFilePicker(fileInput, $event)\">+ \u0414\u043E\u0434\u0430\u0442\u0438 \u0444\u043E\u0442\u043E</button>\n }\n <input #fileInput type=\"file\" class=\"hidden\" [disabled]=\"disabled\" multiple (change)=\"onFilesChange($event, i)\" />\n </label>\n @if (entry.imageId || entry.file) {\n @if (i === 0) {\n <span class=\"absolute left-2 top-2 rounded-full border border-slate-200 bg-white/95 px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.15em] text-slate-700\">\u041E\u0431\u043A\u043B\u0430\u0434\u0438\u043D\u043A\u0430</span>\n }\n <span class=\"absolute left-2 bottom-2 rounded-full bg-slate-900/85 px-2 py-1 text-[10px] font-semibold text-white\">#{{ i + 1 }}</span>\n <button type=\"button\" class=\"absolute right-2 top-2 rounded-full bg-white/95 px-2 py-1 text-xs text-rose-600 shadow\" [disabled]=\"disabled\" (click)=\"removeAt(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n }\n </div>\n }\n </div>\n <div class=\"mt-1 text-xs text-slate-500\">\u041A\u0456\u043B\u044C\u043A\u0456\u0441\u0442\u044C \u0444\u043E\u0442\u043E: {{ photoCount }}</div>\n</field-frame>\n", styles: [".image-drag-item.cdk-drag-preview{transform:scale(1.03) rotate(.6deg);box-shadow:0 28px 60px #0f172a66;border-radius:.9rem}.image-drag-item.cdk-drag-placeholder{opacity:.4;outline:2px dashed #94a3b8;outline-offset:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }] });
|
|
3598
4268
|
}
|
|
3599
4269
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputPhotoGalleryComponent, decorators: [{
|
|
3600
4270
|
type: Component,
|
|
3601
|
-
args: [{ selector: 'input-photo-gallery', standalone: true, imports: [CommonModule, DragDropModule], template: "<label
|
|
4271
|
+
args: [{ selector: 'input-photo-gallery', standalone: true, imports: [CommonModule, DragDropModule, FieldFrameComponent], template: "<field-frame [label]=\"label\" [hint]=\"hint\" [error]=\"error\" [required]=\"required\">\n <p class=\"mb-2 text-xs uppercase tracking-[0.2em] text-slate-500\">{{ orderLabel }}</p>\n <div class=\"grid gap-3 md:grid-cols-4\" cdkDropList [cdkDropListData]=\"entries\" (cdkDropListDropped)=\"onDrop($event)\">\n @for (entry of entries; let i = $index; track entry.clientKey + '-' + i) {\n <div class=\"image-drag-item relative overflow-hidden rounded-xl border border-slate-200 bg-white\" cdkDrag [cdkDragDisabled]=\"disabled || (!entry.imageId && !entry.file)\">\n <label class=\"block h-full w-full cursor-pointer\">\n @if (entry.preview) {\n <img [src]=\"entry.preview\" alt=\"photo\" class=\"h-48 w-full object-cover\" />\n } @else {\n <button type=\"button\" class=\"flex h-48 w-full items-center justify-center bg-slate-50 text-xs text-slate-500\" (click)=\"openFilePicker(fileInput, $event)\">+ \u0414\u043E\u0434\u0430\u0442\u0438 \u0444\u043E\u0442\u043E</button>\n }\n <input #fileInput type=\"file\" class=\"hidden\" [disabled]=\"disabled\" multiple (change)=\"onFilesChange($event, i)\" />\n </label>\n @if (entry.imageId || entry.file) {\n @if (i === 0) {\n <span class=\"absolute left-2 top-2 rounded-full border border-slate-200 bg-white/95 px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.15em] text-slate-700\">\u041E\u0431\u043A\u043B\u0430\u0434\u0438\u043D\u043A\u0430</span>\n }\n <span class=\"absolute left-2 bottom-2 rounded-full bg-slate-900/85 px-2 py-1 text-[10px] font-semibold text-white\">#{{ i + 1 }}</span>\n <button type=\"button\" class=\"absolute right-2 top-2 rounded-full bg-white/95 px-2 py-1 text-xs text-rose-600 shadow\" [disabled]=\"disabled\" (click)=\"removeAt(i)\">\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438</button>\n }\n </div>\n }\n </div>\n <div class=\"mt-1 text-xs text-slate-500\">\u041A\u0456\u043B\u044C\u043A\u0456\u0441\u0442\u044C \u0444\u043E\u0442\u043E: {{ photoCount }}</div>\n</field-frame>\n", styles: [".image-drag-item.cdk-drag-preview{transform:scale(1.03) rotate(.6deg);box-shadow:0 28px 60px #0f172a66;border-radius:.9rem}.image-drag-item.cdk-drag-placeholder{opacity:.4;outline:2px dashed #94a3b8;outline-offset:4px}\n"] }]
|
|
3602
4272
|
}], propDecorators: { label: [{
|
|
3603
4273
|
type: Input
|
|
4274
|
+
}], hint: [{
|
|
4275
|
+
type: Input
|
|
4276
|
+
}], error: [{
|
|
4277
|
+
type: Input
|
|
4278
|
+
}], required: [{
|
|
4279
|
+
type: Input
|
|
3604
4280
|
}], orderLabel: [{
|
|
3605
4281
|
type: Input
|
|
3606
4282
|
}], imageIds: [{
|
|
@@ -3618,6 +4294,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3618
4294
|
}] } });
|
|
3619
4295
|
|
|
3620
4296
|
class InputRangeSliderComponent {
|
|
4297
|
+
label;
|
|
4298
|
+
hint;
|
|
4299
|
+
error;
|
|
4300
|
+
required = false;
|
|
3621
4301
|
min = 0;
|
|
3622
4302
|
max = 100;
|
|
3623
4303
|
step = 1;
|
|
@@ -3707,7 +4387,8 @@ class InputRangeSliderComponent {
|
|
|
3707
4387
|
input.value = String(value);
|
|
3708
4388
|
}
|
|
3709
4389
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputRangeSliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3710
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputRangeSliderComponent, isStandalone: true, selector: "input-range-slider", inputs: { min: "min", max: "max", step: "step", startValue: "startValue", endValue: "endValue", startLabel: "startLabel", endLabel: "endLabel" }, outputs: { startValueChange: "startValueChange", endValueChange: "endValueChange", interactionEnd: "interactionEnd" }, viewQueries: [{ propertyName: "startInput", first: true, predicate: ["startInput"], descendants: true }, { propertyName: "endInput", first: true, predicate: ["endInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
4390
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: InputRangeSliderComponent, isStandalone: true, selector: "input-range-slider", inputs: { label: "label", hint: "hint", error: "error", required: "required", min: "min", max: "max", step: "step", startValue: "startValue", endValue: "endValue", startLabel: "startLabel", endLabel: "endLabel" }, outputs: { startValueChange: "startValueChange", endValueChange: "endValueChange", interactionEnd: "interactionEnd" }, viewQueries: [{ propertyName: "startInput", first: true, predicate: ["startInput"], descendants: true }, { propertyName: "endInput", first: true, predicate: ["endInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
4391
|
+
<field-frame [label]="label" [hint]="hint" [error]="error" [required]="required">
|
|
3711
4392
|
<div class="range-slider">
|
|
3712
4393
|
<div class="range-slider__track"></div>
|
|
3713
4394
|
<div
|
|
@@ -3740,11 +4421,13 @@ class InputRangeSliderComponent {
|
|
|
3740
4421
|
(input)="onEndInput($event)"
|
|
3741
4422
|
(change)="interactionEnd.emit()">
|
|
3742
4423
|
</div>
|
|
3743
|
-
|
|
4424
|
+
</field-frame>
|
|
4425
|
+
`, isInline: true, styles: [".range-slider{position:relative;height:2rem;width:100%;display:flex;align-items:center}.range-slider__track,.range-slider__range{position:absolute;left:0;right:0;height:6px;border-radius:999px}.range-slider__track{background:#dbe1ea}.range-slider__range{background:linear-gradient(90deg,#334155,#0f172a)}.range-slider__input{pointer-events:none;position:absolute;left:0;width:100%;height:2rem;margin:0;background:transparent;appearance:none;-webkit-appearance:none}.range-slider__input::-webkit-slider-runnable-track{height:6px;background:transparent}.range-slider__input::-moz-range-track{height:6px;background:transparent}.range-slider__input::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;pointer-events:auto;width:20px;height:20px;margin-top:-7px;border-radius:50%;border:2px solid #ffffff;background:#0f172a;box-shadow:0 8px 22px #0f172a38;cursor:pointer}.range-slider__input::-moz-range-thumb{pointer-events:auto;width:20px;height:20px;border-radius:50%;border:2px solid #ffffff;background:#0f172a;box-shadow:0 8px 22px #0f172a38;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FieldFrameComponent, selector: "field-frame", inputs: ["label", "hint", "error", "required", "forId", "disabled", "actions"], outputs: ["actionTriggered"] }] });
|
|
3744
4426
|
}
|
|
3745
4427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InputRangeSliderComponent, decorators: [{
|
|
3746
4428
|
type: Component,
|
|
3747
|
-
args: [{ selector: 'input-range-slider', standalone: true, imports: [CommonModule], template: `
|
|
4429
|
+
args: [{ selector: 'input-range-slider', standalone: true, imports: [CommonModule, FieldFrameComponent], template: `
|
|
4430
|
+
<field-frame [label]="label" [hint]="hint" [error]="error" [required]="required">
|
|
3748
4431
|
<div class="range-slider">
|
|
3749
4432
|
<div class="range-slider__track"></div>
|
|
3750
4433
|
<div
|
|
@@ -3777,8 +4460,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3777
4460
|
(input)="onEndInput($event)"
|
|
3778
4461
|
(change)="interactionEnd.emit()">
|
|
3779
4462
|
</div>
|
|
4463
|
+
</field-frame>
|
|
3780
4464
|
`, styles: [".range-slider{position:relative;height:2rem;width:100%;display:flex;align-items:center}.range-slider__track,.range-slider__range{position:absolute;left:0;right:0;height:6px;border-radius:999px}.range-slider__track{background:#dbe1ea}.range-slider__range{background:linear-gradient(90deg,#334155,#0f172a)}.range-slider__input{pointer-events:none;position:absolute;left:0;width:100%;height:2rem;margin:0;background:transparent;appearance:none;-webkit-appearance:none}.range-slider__input::-webkit-slider-runnable-track{height:6px;background:transparent}.range-slider__input::-moz-range-track{height:6px;background:transparent}.range-slider__input::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;pointer-events:auto;width:20px;height:20px;margin-top:-7px;border-radius:50%;border:2px solid #ffffff;background:#0f172a;box-shadow:0 8px 22px #0f172a38;cursor:pointer}.range-slider__input::-moz-range-thumb{pointer-events:auto;width:20px;height:20px;border-radius:50%;border:2px solid #ffffff;background:#0f172a;box-shadow:0 8px 22px #0f172a38;cursor:pointer}\n"] }]
|
|
3781
|
-
}], propDecorators: {
|
|
4465
|
+
}], propDecorators: { label: [{
|
|
4466
|
+
type: Input
|
|
4467
|
+
}], hint: [{
|
|
4468
|
+
type: Input
|
|
4469
|
+
}], error: [{
|
|
4470
|
+
type: Input
|
|
4471
|
+
}], required: [{
|
|
4472
|
+
type: Input
|
|
4473
|
+
}], min: [{
|
|
3782
4474
|
type: Input
|
|
3783
4475
|
}], max: [{
|
|
3784
4476
|
type: Input
|
|
@@ -3810,5 +4502,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3810
4502
|
* Generated bundle index. Do not edit.
|
|
3811
4503
|
*/
|
|
3812
4504
|
|
|
3813
|
-
export { ACTION_API, ACTION_FORM, ACTION_PRINT, ACTION_SUBMIT, DynamicFormComponent, FieldInputComponent, FormModalComponent, InputBarcodeComponent, InputCheckboxComponent, InputColorComponent, InputComponent, InputDateComponent, InputDatetimeComponent, InputEmailComponent, InputFileComponent, InputNumberComponent, InputPasswordComponent, InputPhotoComponent, InputPhotoGalleryComponent, InputRangeSliderComponent, InputSelectComponent, InputSlugComponent, InputTextComponent, InputTextareaComponent, MaroFormsApiService, UI_FORM_INPUT_REGISTRY, UiFormContext, UiFormLookupService, flattenDynamicFormFields, isDynamicFormContainerField, isDynamicFormTemplateField };
|
|
4505
|
+
export { ACTION_API, ACTION_FORM, ACTION_PRINT, ACTION_SUBMIT, DynamicFormComponent, FieldFrameComponent, FieldInputComponent, FormModalComponent, InputBarcodeComponent, InputBarcodeControlComponent, InputBaseControlComponent, InputCheckboxComponent, InputCheckboxControlComponent, InputColorComponent, InputColorControlComponent, InputComponent, InputDateComponent, InputDateControlComponent, InputDatetimeComponent, InputDatetimeControlComponent, InputEmailComponent, InputEmailControlComponent, InputFileComponent, InputFileControlComponent, InputNumberComponent, InputNumberControlComponent, InputPasswordComponent, InputPasswordControlComponent, InputPhotoComponent, InputPhotoControlComponent, InputPhotoGalleryComponent, InputRangeSliderComponent, InputSelectComponent, InputSelectControlComponent, InputSlugComponent, InputSlugControlComponent, InputTextComponent, InputTextControlComponent, InputTextareaComponent, InputTextareaControlComponent, MaroFormsApiService, UI_FORM_INPUT_REGISTRY, UiFormContext, UiFormLookupService, flattenDynamicFormFields, isDynamicFormContainerField, isDynamicFormLookupField, isDynamicFormTemplateField };
|
|
3814
4506
|
//# sourceMappingURL=maro-tech-form.mjs.map
|