@frame-kit/ui-ng 0.2.7 → 0.2.9
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, computed, HostBinding, ChangeDetectionStrategy, Component, InjectionToken, signal, output, Directive, contentChild, inject, ChangeDetectorRef, effect, Injectable, TemplateRef, viewChild, forwardRef, DestroyRef, ViewContainerRef
|
|
2
|
+
import { input, computed, HostBinding, ChangeDetectionStrategy, Component, InjectionToken, signal, output, Directive, contentChild, inject, ChangeDetectorRef, ElementRef, isDevMode, effect, Injectable, TemplateRef, viewChild, forwardRef, DestroyRef, ViewContainerRef } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { Validators, FormControl, FormGroup, FormArray, NgControl, ReactiveFormsModule } from '@angular/forms';
|
|
5
5
|
import { NgTemplateOutlet } from '@angular/common';
|
|
@@ -128,11 +128,11 @@ class FormComponent {
|
|
|
128
128
|
this.status.set('idle');
|
|
129
129
|
}
|
|
130
130
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
131
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: FormComponent, isStandalone: true, selector: "fk-form", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formSubmit: "formSubmit" }, host: { properties: { "class": "this.hostClass" } }, providers: [{ provide: FORM, useExisting: FormComponent }], ngImport: i0, template: "<form class=\"fk-form__native\" (submit)=\"$event.preventDefault(); onSubmit()\">\n <ng-content />\n</form>\n", styles: ["
|
|
131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: FormComponent, isStandalone: true, selector: "fk-form", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formSubmit: "formSubmit" }, host: { properties: { "class": "this.hostClass" } }, providers: [{ provide: FORM, useExisting: FormComponent }], ngImport: i0, template: "<form class=\"fk-form__native\" (submit)=\"$event.preventDefault(); onSubmit()\">\n <ng-content />\n</form>\n", styles: ["@charset \"UTF-8\";:host{display:block}.fk-form__native{display:flex;flex-direction:column;gap:var(--fk-form-gap, 0)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
132
132
|
}
|
|
133
133
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormComponent, decorators: [{
|
|
134
134
|
type: Component,
|
|
135
|
-
args: [{ selector: 'fk-form', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: FORM, useExisting: FormComponent }], template: "<form class=\"fk-form__native\" (submit)=\"$event.preventDefault(); onSubmit()\">\n <ng-content />\n</form>\n", styles: ["
|
|
135
|
+
args: [{ selector: 'fk-form', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: FORM, useExisting: FormComponent }], template: "<form class=\"fk-form__native\" (submit)=\"$event.preventDefault(); onSubmit()\">\n <ng-content />\n</form>\n", styles: ["@charset \"UTF-8\";:host{display:block}.fk-form__native{display:flex;flex-direction:column;gap:var(--fk-form-gap, 0)}\n"] }]
|
|
136
136
|
}], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], hostClass: [{
|
|
137
137
|
type: HostBinding,
|
|
138
138
|
args: ['class']
|
|
@@ -289,6 +289,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
289
289
|
args: ['attr.for']
|
|
290
290
|
}] } });
|
|
291
291
|
|
|
292
|
+
const FK_LABEL_ACTION = new InjectionToken('FK_LABEL_ACTION');
|
|
293
|
+
/**
|
|
294
|
+
* Marks content that belongs on the label's own row, aligned to the trailing
|
|
295
|
+
* edge — a "Forgot password?" link beside a Password label being the canonical
|
|
296
|
+
* case.
|
|
297
|
+
*
|
|
298
|
+
* It sits outside the `<label>` element deliberately. A link inside a label is
|
|
299
|
+
* activated when the label is clicked, so the user reaches for the link and
|
|
300
|
+
* focuses the input instead; and its text would join the input's accessible
|
|
301
|
+
* name.
|
|
302
|
+
*/
|
|
303
|
+
class FkLabelActionDirective {
|
|
304
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkLabelActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
305
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkLabelActionDirective, isStandalone: true, selector: "[fkLabelAction]", providers: [{ provide: FK_LABEL_ACTION, useExisting: FkLabelActionDirective }], ngImport: i0 });
|
|
306
|
+
}
|
|
307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkLabelActionDirective, decorators: [{
|
|
308
|
+
type: Directive,
|
|
309
|
+
args: [{
|
|
310
|
+
selector: '[fkLabelAction]',
|
|
311
|
+
standalone: true,
|
|
312
|
+
providers: [{ provide: FK_LABEL_ACTION, useExisting: FkLabelActionDirective }],
|
|
313
|
+
}]
|
|
314
|
+
}] });
|
|
315
|
+
|
|
292
316
|
const FK_PREFIX = new InjectionToken('FK_PREFIX');
|
|
293
317
|
class FkPrefixDirective {
|
|
294
318
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkPrefixDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -349,11 +373,53 @@ class FormFieldComponent {
|
|
|
349
373
|
hintRef = contentChild(HintComponent, ...(ngDevMode ? [{ debugName: "hintRef" }] : /* istanbul ignore next */ []));
|
|
350
374
|
errorRef = contentChild(ErrorComponent, ...(ngDevMode ? [{ debugName: "errorRef" }] : /* istanbul ignore next */ []));
|
|
351
375
|
labelRef = contentChild(LabelComponent, ...(ngDevMode ? [{ debugName: "labelRef" }] : /* istanbul ignore next */ []));
|
|
376
|
+
labelActionRef = contentChild(FK_LABEL_ACTION, ...(ngDevMode ? [{ debugName: "labelActionRef" }] : /* istanbul ignore next */ []));
|
|
352
377
|
prefixRef = contentChild(FK_PREFIX, ...(ngDevMode ? [{ debugName: "prefixRef" }] : /* istanbul ignore next */ []));
|
|
353
378
|
suffixRef = contentChild(FK_SUFFIX, ...(ngDevMode ? [{ debugName: "suffixRef" }] : /* istanbul ignore next */ []));
|
|
354
379
|
// ===== INJECTED SERVICES =====
|
|
355
380
|
globalErrorMessages = inject(ERROR_MESSAGES);
|
|
356
381
|
cdr = inject(ChangeDetectorRef);
|
|
382
|
+
host = inject((ElementRef));
|
|
383
|
+
/**
|
|
384
|
+
* `fkPrefix` and `fkSuffix` project only when their directive resolves, and
|
|
385
|
+
* it only resolves when the consumer imports it. Forget the import and the
|
|
386
|
+
* attribute stays inert markup: Angular does not warn about an unknown
|
|
387
|
+
* attribute on a known element, the content query returns undefined, the
|
|
388
|
+
* wrapper is never rendered, and the icon simply is not there. Nothing fails
|
|
389
|
+
* — which is what makes it slow to diagnose.
|
|
390
|
+
*
|
|
391
|
+
* Content queries have resolved by this point, and the element is still in
|
|
392
|
+
* the DOM either way, so an element carrying the attribute with no resolved
|
|
393
|
+
* directive is an unambiguous signal.
|
|
394
|
+
*/
|
|
395
|
+
ngAfterContentInit() {
|
|
396
|
+
if (isDevMode()) {
|
|
397
|
+
this.warnOnUnresolvedProjection();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
warnOnUnresolvedProjection() {
|
|
401
|
+
const checks = [
|
|
402
|
+
['fkPrefix', 'FkPrefixDirective', 'prefix', this.prefixRef()],
|
|
403
|
+
[
|
|
404
|
+
'fkLabelAction',
|
|
405
|
+
'FkLabelActionDirective',
|
|
406
|
+
'label-action',
|
|
407
|
+
this.labelActionRef(),
|
|
408
|
+
],
|
|
409
|
+
['fkSuffix', 'FkSuffixDirective', 'suffix', this.suffixRef()],
|
|
410
|
+
];
|
|
411
|
+
for (const [attribute, directive, slot, resolved] of checks) {
|
|
412
|
+
if (resolved)
|
|
413
|
+
continue;
|
|
414
|
+
const wrapper = this.host.nativeElement.querySelector(`.fk-form-field__${slot}`);
|
|
415
|
+
if (!wrapper?.hasChildNodes())
|
|
416
|
+
continue;
|
|
417
|
+
console.warn(`[fk-form-field] Content was projected into the ${slot} slot but ` +
|
|
418
|
+
`\`${directive}\` did not resolve, so the field will not be spaced ` +
|
|
419
|
+
`for it. Add \`${directive}\` to the imports of the component whose ` +
|
|
420
|
+
`template uses \`${attribute}\`.`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
357
423
|
// ===== HOST CLASS =====
|
|
358
424
|
get hostClass() {
|
|
359
425
|
return [
|
|
@@ -451,6 +517,12 @@ class FormFieldComponent {
|
|
|
451
517
|
return this.showError();
|
|
452
518
|
}
|
|
453
519
|
constructor() {
|
|
520
|
+
// `fkPrefix` and `fkSuffix` project only when their directive resolves, and
|
|
521
|
+
// it only resolves when the consumer imports it. Forget the import and the
|
|
522
|
+
// attribute stays inert markup: Angular does not warn about an unknown
|
|
523
|
+
// attribute on a known element, the `contentChild` query returns undefined,
|
|
524
|
+
// the wrapper is never rendered, and the icon simply is not there. Nothing
|
|
525
|
+
// fails — which is what makes it slow to diagnose.
|
|
454
526
|
effect(() => {
|
|
455
527
|
this.syncDescribedByIds();
|
|
456
528
|
});
|
|
@@ -494,12 +566,12 @@ class FormFieldComponent {
|
|
|
494
566
|
control.setDescribedByIds(ids);
|
|
495
567
|
}
|
|
496
568
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
497
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FormFieldComponent, isStandalone: true, selector: "fk-form-field", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showErrorsOn: { classPropertyName: "showErrorsOn", publicName: "showErrorsOn", isSignal: true, isRequired: false, transformFunction: null }, submitted: { classPropertyName: "submitted", publicName: "submitted", isSignal: true, isRequired: false, transformFunction: null }, externalDescribedBy: { classPropertyName: "externalDescribedBy", publicName: "externalDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, fallbackControl: { classPropertyName: "fallbackControl", publicName: "fallbackControl", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass" } }, queries: [{ propertyName: "control", first: true, predicate: FIELD_CONTROL, descendants: true, isSignal: true }, { propertyName: "hintRef", first: true, predicate: HintComponent, descendants: true, isSignal: true }, { propertyName: "errorRef", first: true, predicate: ErrorComponent, descendants: true, isSignal: true }, { propertyName: "labelRef", first: true, predicate: LabelComponent, descendants: true, isSignal: true }, { propertyName: "prefixRef", first: true, predicate: FK_PREFIX, descendants: true, isSignal: true }, { propertyName: "suffixRef", first: true, predicate: FK_SUFFIX, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fk-form-field__wrapper\">\n @if (label() || labelRef()) {\n <div class=\"fk-form-field__label-row\">\n <label\n class=\"fk-form-field__label\"\n [attr.id]=\"labelId\"\n [attr.for]=\"control()?.id ?? null\"\n >\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content select=\"fk-label\" />\n }\n </label>\n <!-- The required marker lives OUTSIDE the <label> so it never leaks into\n the label's text/accessible name (keeping getByLabel + AT clean); the\n input's aria-required conveys the requirement to assistive tech. -->\n @if (isRequired()) {\n <span class=\"fk-form-field__required\" aria-hidden=\"true\">*</span>\n }\n </div>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"fk-form-field__control\"\n (click)=\"control()?.onContainerClick?.($event)\"\n >\n
|
|
569
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FormFieldComponent, isStandalone: true, selector: "fk-form-field", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, showErrorsOn: { classPropertyName: "showErrorsOn", publicName: "showErrorsOn", isSignal: true, isRequired: false, transformFunction: null }, submitted: { classPropertyName: "submitted", publicName: "submitted", isSignal: true, isRequired: false, transformFunction: null }, externalDescribedBy: { classPropertyName: "externalDescribedBy", publicName: "externalDescribedBy", isSignal: true, isRequired: false, transformFunction: null }, fallbackControl: { classPropertyName: "fallbackControl", publicName: "fallbackControl", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass" } }, queries: [{ propertyName: "control", first: true, predicate: FIELD_CONTROL, descendants: true, isSignal: true }, { propertyName: "hintRef", first: true, predicate: HintComponent, descendants: true, isSignal: true }, { propertyName: "errorRef", first: true, predicate: ErrorComponent, descendants: true, isSignal: true }, { propertyName: "labelRef", first: true, predicate: LabelComponent, descendants: true, isSignal: true }, { propertyName: "labelActionRef", first: true, predicate: FK_LABEL_ACTION, descendants: true, isSignal: true }, { propertyName: "prefixRef", first: true, predicate: FK_PREFIX, descendants: true, isSignal: true }, { propertyName: "suffixRef", first: true, predicate: FK_SUFFIX, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fk-form-field__wrapper\">\n @if (label() || labelRef()) {\n <div class=\"fk-form-field__label-row\">\n <label\n class=\"fk-form-field__label\"\n [attr.id]=\"labelId\"\n [attr.for]=\"control()?.id ?? null\"\n >\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content select=\"fk-label\" />\n }\n </label>\n <!-- The required marker lives OUTSIDE the <label> so it never leaks into\n the label's text/accessible name (keeping getByLabel + AT clean); the\n input's aria-required conveys the requirement to assistive tech. -->\n @if (isRequired()) {\n <span class=\"fk-form-field__required\" aria-hidden=\"true\">*</span>\n }\n\n <!-- Trailing content on the label's row. Outside the <label> so it is not\n activated by a label click and does not join the input's accessible\n name. Rendered unconditionally for the same reason as the prefix and\n suffix slots: an unprojected node is never placed in the DOM, so\n gating this on the directive would make a forgotten import vanish\n silently. `:empty` keeps it from taking space. -->\n <div class=\"fk-form-field__label-action\">\n <ng-content select=\"[fkLabelAction]\" />\n </div>\n </div>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"fk-form-field__control\"\n (click)=\"control()?.onContainerClick?.($event)\"\n >\n <!-- Rendered unconditionally, and deliberately so. Gating these on the\n directive resolving means a consumer who marks an element `fkPrefix`\n but forgets to import `FkPrefixDirective` gets no slot, and because an\n unprojected node is never placed in the DOM at all, their icon\n disappears with no error anywhere. Both wrappers are absolutely\n positioned and `:empty`-hidden, so rendering them always costs nothing\n and turns that failure into something visible. -->\n <div class=\"fk-form-field__prefix\">\n <ng-content select=\"[fkPrefix]\" />\n </div>\n <ng-content />\n <div class=\"fk-form-field__suffix\">\n <ng-content select=\"[fkSuffix]\" />\n </div>\n </div>\n\n <div class=\"fk-form-field__subscript\">\n @if (showError()) {\n @if (hasAutoError) {\n <span class=\"fk-error\" role=\"alert\" [attr.id]=\"autoErrorId\">\n {{ autoErrorMessage() }}\n </span>\n } @else {\n <ng-content select=\"fk-error\" />\n }\n } @else {\n <ng-content select=\"fk-hint\" />\n }\n </div>\n</div>\n", styles: [":host{display:block}.fk-form-field__wrapper{display:flex;flex-direction:column}.fk-form-field__label-action{margin-inline-start:auto;display:flex;align-items:baseline}.fk-form-field__label-action:empty{display:none}.fk-form-field__label-row{display:flex;align-items:center;gap:.25em;margin-top:var(--fk-form-label-margin-top, var(--fk-rhythm-2, .5rem))}.fk-form-field__label{display:flex;align-items:center;gap:.25em;font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .8125rem));font-weight:var(--fk-form-label-font-weight, var(--fk-typography-label-font-weight, 600));line-height:var(--fk-form-label-line-height, var(--fk-typography-label-line-height, 1.25));color:var(--fk-form-label-color, var(--fk-color-text-strong, #0b1420));cursor:default}.fk-form-field__label fk-icon{flex:none;color:var(--fk-form-label-icon-color, currentColor)}.fk-form-field__required{color:var(--fk-form-error-color, var(--fk-color-danger, #e02424))}.fk-form-field__control{position:relative;margin-top:var(--fk-form-label-gap, var(--fk-rhythm-2, .5rem))}.fk-form-field__prefix,.fk-form-field__suffix{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;color:var(--fk-input-placeholder-color, var(--fk-color-muted, #8a98a8));z-index:1}.fk-form-field__prefix{pointer-events:none}.fk-form-field__prefix:empty,.fk-form-field__suffix:empty{display:none}.fk-form-field__prefix{left:var(--fk-input-affix-offset, .75rem)}.fk-form-field__suffix{right:var(--fk-input-affix-offset, .75rem)}.fk-form-field__subscript{display:var(--fk-form-subscript-display, block);min-height:var(--fk-form-subscript-min-height, calc(var(--fk-form-hint-font-size, var(--fk-typography-small-font-size, .8125rem)) * 1.4));margin-top:var(--fk-form-subscript-gap, var(--fk-rhythm-1, .25rem))}.fk-form-field__subscript .fk-error{display:block;font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-form-error-font-size, var(--fk-typography-small-font-size, .8125rem));line-height:1.4;color:var(--fk-form-error-color, var(--fk-color-danger, #e02424))}:host(.fk-form-field--focused) .fk-form-field__label{color:var(--fk-input-border-color-focus, var(--fk-color-primary, #0a84ff))}:host(.fk-form-field--disabled) .fk-form-field__label{opacity:var(--fk-input-disabled-opacity, .5);cursor:not-allowed}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
498
570
|
}
|
|
499
571
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormFieldComponent, decorators: [{
|
|
500
572
|
type: Component,
|
|
501
|
-
args: [{ selector: 'fk-form-field', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fk-form-field__wrapper\">\n @if (label() || labelRef()) {\n <div class=\"fk-form-field__label-row\">\n <label\n class=\"fk-form-field__label\"\n [attr.id]=\"labelId\"\n [attr.for]=\"control()?.id ?? null\"\n >\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content select=\"fk-label\" />\n }\n </label>\n <!-- The required marker lives OUTSIDE the <label> so it never leaks into\n the label's text/accessible name (keeping getByLabel + AT clean); the\n input's aria-required conveys the requirement to assistive tech. -->\n @if (isRequired()) {\n <span class=\"fk-form-field__required\" aria-hidden=\"true\">*</span>\n }\n </div>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"fk-form-field__control\"\n (click)=\"control()?.onContainerClick?.($event)\"\n >\n
|
|
502
|
-
}], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showErrorsOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showErrorsOn", required: false }] }], submitted: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitted", required: false }] }], externalDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "externalDescribedBy", required: false }] }], fallbackControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackControl", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], control: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FIELD_CONTROL), { isSignal: true }] }], hintRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HintComponent), { isSignal: true }] }], errorRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ErrorComponent), { isSignal: true }] }], labelRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => LabelComponent), { isSignal: true }] }], prefixRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_PREFIX), { isSignal: true }] }], suffixRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_SUFFIX), { isSignal: true }] }], hostClass: [{
|
|
573
|
+
args: [{ selector: 'fk-form-field', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fk-form-field__wrapper\">\n @if (label() || labelRef()) {\n <div class=\"fk-form-field__label-row\">\n <label\n class=\"fk-form-field__label\"\n [attr.id]=\"labelId\"\n [attr.for]=\"control()?.id ?? null\"\n >\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content select=\"fk-label\" />\n }\n </label>\n <!-- The required marker lives OUTSIDE the <label> so it never leaks into\n the label's text/accessible name (keeping getByLabel + AT clean); the\n input's aria-required conveys the requirement to assistive tech. -->\n @if (isRequired()) {\n <span class=\"fk-form-field__required\" aria-hidden=\"true\">*</span>\n }\n\n <!-- Trailing content on the label's row. Outside the <label> so it is not\n activated by a label click and does not join the input's accessible\n name. Rendered unconditionally for the same reason as the prefix and\n suffix slots: an unprojected node is never placed in the DOM, so\n gating this on the directive would make a forgotten import vanish\n silently. `:empty` keeps it from taking space. -->\n <div class=\"fk-form-field__label-action\">\n <ng-content select=\"[fkLabelAction]\" />\n </div>\n </div>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"fk-form-field__control\"\n (click)=\"control()?.onContainerClick?.($event)\"\n >\n <!-- Rendered unconditionally, and deliberately so. Gating these on the\n directive resolving means a consumer who marks an element `fkPrefix`\n but forgets to import `FkPrefixDirective` gets no slot, and because an\n unprojected node is never placed in the DOM at all, their icon\n disappears with no error anywhere. Both wrappers are absolutely\n positioned and `:empty`-hidden, so rendering them always costs nothing\n and turns that failure into something visible. -->\n <div class=\"fk-form-field__prefix\">\n <ng-content select=\"[fkPrefix]\" />\n </div>\n <ng-content />\n <div class=\"fk-form-field__suffix\">\n <ng-content select=\"[fkSuffix]\" />\n </div>\n </div>\n\n <div class=\"fk-form-field__subscript\">\n @if (showError()) {\n @if (hasAutoError) {\n <span class=\"fk-error\" role=\"alert\" [attr.id]=\"autoErrorId\">\n {{ autoErrorMessage() }}\n </span>\n } @else {\n <ng-content select=\"fk-error\" />\n }\n } @else {\n <ng-content select=\"fk-hint\" />\n }\n </div>\n</div>\n", styles: [":host{display:block}.fk-form-field__wrapper{display:flex;flex-direction:column}.fk-form-field__label-action{margin-inline-start:auto;display:flex;align-items:baseline}.fk-form-field__label-action:empty{display:none}.fk-form-field__label-row{display:flex;align-items:center;gap:.25em;margin-top:var(--fk-form-label-margin-top, var(--fk-rhythm-2, .5rem))}.fk-form-field__label{display:flex;align-items:center;gap:.25em;font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .8125rem));font-weight:var(--fk-form-label-font-weight, var(--fk-typography-label-font-weight, 600));line-height:var(--fk-form-label-line-height, var(--fk-typography-label-line-height, 1.25));color:var(--fk-form-label-color, var(--fk-color-text-strong, #0b1420));cursor:default}.fk-form-field__label fk-icon{flex:none;color:var(--fk-form-label-icon-color, currentColor)}.fk-form-field__required{color:var(--fk-form-error-color, var(--fk-color-danger, #e02424))}.fk-form-field__control{position:relative;margin-top:var(--fk-form-label-gap, var(--fk-rhythm-2, .5rem))}.fk-form-field__prefix,.fk-form-field__suffix{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;color:var(--fk-input-placeholder-color, var(--fk-color-muted, #8a98a8));z-index:1}.fk-form-field__prefix{pointer-events:none}.fk-form-field__prefix:empty,.fk-form-field__suffix:empty{display:none}.fk-form-field__prefix{left:var(--fk-input-affix-offset, .75rem)}.fk-form-field__suffix{right:var(--fk-input-affix-offset, .75rem)}.fk-form-field__subscript{display:var(--fk-form-subscript-display, block);min-height:var(--fk-form-subscript-min-height, calc(var(--fk-form-hint-font-size, var(--fk-typography-small-font-size, .8125rem)) * 1.4));margin-top:var(--fk-form-subscript-gap, var(--fk-rhythm-1, .25rem))}.fk-form-field__subscript .fk-error{display:block;font-family:var(--fk-font-family-base, \"Inter\", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\");font-size:var(--fk-form-error-font-size, var(--fk-typography-small-font-size, .8125rem));line-height:1.4;color:var(--fk-form-error-color, var(--fk-color-danger, #e02424))}:host(.fk-form-field--focused) .fk-form-field__label{color:var(--fk-input-border-color-focus, var(--fk-color-primary, #0a84ff))}:host(.fk-form-field--disabled) .fk-form-field__label{opacity:var(--fk-input-disabled-opacity, .5);cursor:not-allowed}\n"] }]
|
|
574
|
+
}], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], showErrorsOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showErrorsOn", required: false }] }], submitted: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitted", required: false }] }], externalDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "externalDescribedBy", required: false }] }], fallbackControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackControl", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], control: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FIELD_CONTROL), { isSignal: true }] }], hintRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HintComponent), { isSignal: true }] }], errorRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ErrorComponent), { isSignal: true }] }], labelRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => LabelComponent), { isSignal: true }] }], labelActionRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_LABEL_ACTION), { isSignal: true }] }], prefixRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_PREFIX), { isSignal: true }] }], suffixRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_SUFFIX), { isSignal: true }] }], hostClass: [{
|
|
503
575
|
type: HostBinding,
|
|
504
576
|
args: ['class']
|
|
505
577
|
}] } });
|
|
@@ -3678,5 +3750,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3678
3750
|
* Generated bundle index. Do not edit.
|
|
3679
3751
|
*/
|
|
3680
3752
|
|
|
3681
|
-
export { AutocompleteComponent, CheckboxComponent, DEFAULT_ERROR_MESSAGES, DateInputComponent, DatetimeInputComponent, ERROR_MESSAGES, ErrorComponent, FIELD_CONTROL, FK_AUTOCOMPLETE_OPTION_TPL, FK_FILE_DROPZONE_ICON, FK_PREFIX, FK_SUFFIX, FORM, FieldArrayOutletComponent, FieldGroupComponent, FieldOutletComponent, FieldRegistry, FileDropzoneComponent, FileUploadComponent, FkAutocompleteOptionTplDirective, FkFileDropzoneIconDirective, FkPrefixDirective, FkSuffixDirective, FormComponent, FormFieldComponent, FormRendererComponent, FormSectionComponent, HintComponent, InputComponent, LabelComponent, NumberInputComponent, PasswordInputComponent, RadioComponent, SchemaParser, SectionOutletComponent, SegmentedBarComponent, SelectComponent, SliderComponent, SwitchComponent, TagInputComponent, TextareaComponent, TimeInputComponent, ValidationRegistry, getError, getFieldState, getInvalidFields, hasError, interpolateMessage, isFormValid, markAllTouched, resolveErrorMessage };
|
|
3753
|
+
export { AutocompleteComponent, CheckboxComponent, DEFAULT_ERROR_MESSAGES, DateInputComponent, DatetimeInputComponent, ERROR_MESSAGES, ErrorComponent, FIELD_CONTROL, FK_AUTOCOMPLETE_OPTION_TPL, FK_FILE_DROPZONE_ICON, FK_LABEL_ACTION, FK_PREFIX, FK_SUFFIX, FORM, FieldArrayOutletComponent, FieldGroupComponent, FieldOutletComponent, FieldRegistry, FileDropzoneComponent, FileUploadComponent, FkAutocompleteOptionTplDirective, FkFileDropzoneIconDirective, FkLabelActionDirective, FkPrefixDirective, FkSuffixDirective, FormComponent, FormFieldComponent, FormRendererComponent, FormSectionComponent, HintComponent, InputComponent, LabelComponent, NumberInputComponent, PasswordInputComponent, RadioComponent, SchemaParser, SectionOutletComponent, SegmentedBarComponent, SelectComponent, SliderComponent, SwitchComponent, TagInputComponent, TextareaComponent, TimeInputComponent, ValidationRegistry, getError, getFieldState, getInvalidFields, hasError, interpolateMessage, isFormValid, markAllTouched, resolveErrorMessage };
|
|
3682
3754
|
//# sourceMappingURL=frame-kit-ui-ng-forms.mjs.map
|