@lifecorner/angular-ui-kit 3.11.5 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/lifecorner-angular-ui-kit-alert.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-alert.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs +6 -6
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs +2 -0
- package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs +2 -0
- package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-email-input.mjs +2 -0
- package/fesm2022/lifecorner-angular-ui-kit-email-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-input.mjs +42 -5
- package/fesm2022/lifecorner-angular-ui-kit-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs +2 -0
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs +47 -7
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs.map +1 -1
- package/package.json +1 -1
- package/types/lifecorner-angular-ui-kit-alert.d.ts +8 -1
- package/types/lifecorner-angular-ui-kit-button.d.ts +19 -2
- package/types/lifecorner-angular-ui-kit-input.d.ts +52 -3
- package/types/lifecorner-angular-ui-kit-textarea.d.ts +46 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-email-input.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/email-input/email-input.component.ts","../../../../libs/angular-ui-kit/src/lib/email-input/email-input.component.html"],"sourcesContent":["/* eslint-disable @typescript-eslint/member-ordering */\n/* ControlValueAccessor implementation requires specific method placement */\n\nimport {\n Component,\n input,\n output,\n signal,\n computed,\n ChangeDetectionStrategy,\n forwardRef,\n effect,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { InputAutocapitalize, InputComponent, InputEnterKeyHint } from '@lifecorner/angular-ui-kit/input';\nimport { ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_MAIL } from '@lifecorner/angular-ui-kit/icons';\n\n/**\n * Email input component with built-in RFC 5322 validation.\n *\n * Features:\n * - RFC 5322 regex email format validation\n * - Real-time validation feedback on input\n * - Valid/invalid visual indicators\n * - Size presets (xs, sm, md, lg)\n * - Helper text and error message display\n * - Disabled and readonly states (read-only addresses can wrap: `readonlyWrap`)\n * - Optional leading mail icon (`showIcon`)\n * - Autofill and keyboard hints: `autocomplete`, `name`, `autocapitalize`, `spellcheck`, `enterkeyhint`\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-email-input label=\"Email\" placeholder=\"you@example.com\" [(ngModel)]=\"email\" />\n * ```\n */\n@Component({\n selector: 'lc-email-input',\n imports: [CommonModule, InputComponent],\n // The `envelope` icon it hands to lc-input (an alias of the Tabler `mail`).\n viewProviders: [ɵprovideKitIcons([ICON_MAIL])],\n templateUrl: './email-input.component.html',\n styleUrl: './email-input.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => EmailInputComponent),\n multi: true,\n },\n ],\n})\nexport class EmailInputComponent implements ControlValueAccessor {\n // Input Properties\n /**\n * Input label (displayed above input)\n * @default 'Email'\n */\n readonly label = input<string>('Email');\n\n /**\n * Placeholder text\n * @default 'you@example.com'\n */\n readonly placeholder = input<string>('you@example.com');\n\n /**\n * Size of the input\n * @default 'md'\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the input is disabled\n * @default false\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the input is read-only\n * @default false\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Whether the input is required\n * @default false\n */\n readonly required = input<boolean>(false);\n\n /**\n * Custom error message (overrides validation error)\n */\n readonly error = input<string>();\n\n /**\n * Helper text to display below input\n */\n readonly helperText = input<string>();\n\n /**\n * Whether to show validation feedback immediately\n * @default false (validates on blur)\n */\n readonly validateOnInput = input<boolean>(false);\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string>();\n\n /**\n * Native `autocomplete` (input purpose, WCAG 1.3.5): `email` (registration),\n * `username` (the address as the sign-in name), `username webauthn` (sign-in:\n * the browser offers passkeys in this field). Unset = no attribute.\n */\n readonly autocomplete = input<string>();\n\n /** Native `name` of the inner input. Unset = no attribute. */\n readonly name = input<string>();\n\n /** Native `autocapitalize` (`off` keeps keyboards from capitalising the address). Unset = no attribute. */\n readonly autocapitalize = input<InputAutocapitalize>();\n\n /** Native `spellcheck`. Unset = no attribute. */\n readonly spellcheck = input<boolean>();\n\n /** Native `enterkeyhint`: the label of the on-screen keyboard's Enter key. Unset = no attribute. */\n readonly enterkeyhint = input<InputEnterKeyHint>();\n\n /**\n * Show the leading mail icon. `false` gives the address the icon's width\n * (about 36 px) — long addresses fit on a phone.\n * @default true\n */\n readonly showIcon = input<boolean>(true);\n\n /**\n * While `readonly`: the address wraps onto more lines instead of being\n * clipped. A hidden native input keeps value, `name` and `autocomplete`\n * (e.g. `username` for password managers on a password page).\n * @default false\n */\n readonly readonlyWrap = input<boolean>(false);\n\n /**\n * Show the `*` of a `required` field; `false` keeps the required semantics without it.\n * @default true\n */\n readonly requiredIndicator = input<boolean>(true);\n\n /** Error shown for an empty `required` field. */\n readonly requiredMessage = input('Email address is required');\n\n /** Error shown for a malformed address. */\n readonly invalidMessage = input('Please enter a valid email address');\n\n // Output Events\n /**\n * Emitted when email value changes\n */\n readonly valueChange = output<string>();\n\n /**\n * Emitted when validation state changes\n */\n readonly validationChange = output<{ valid: boolean; error?: string }>();\n\n /**\n * Emitted when input receives focus\n */\n readonly focused = output<void>();\n\n /**\n * Emitted when input loses focus\n */\n readonly blurred = output<void>();\n\n /**\n * Emitted when Enter key is pressed\n */\n readonly enterPressed = output<void>();\n\n // Internal state\n readonly value = signal<string>('');\n private readonly touched = signal<boolean>(false);\n private readonly _formDisabled = signal<boolean>(false);\n\n /**\n * RFC 5322 compliant email regex (simplified but robust)\n * Validates: local-part@domain\n * - Local part: alphanumeric, dots, hyphens, underscores, plus signs\n * - Domain: alphanumeric, dots, hyphens with valid TLD\n */\n private readonly EMAIL_REGEX =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n\n // ControlValueAccessor callbacks\n private onChange: (value: string) => void = () => { /* set by registerOnChange */ };\n private onTouched: () => void = () => { /* set by registerOnTouched */ };\n\n /**\n * Computed validation state\n */\n protected readonly isValid = computed(() => {\n const val = this.value();\n if (!val) return this.required() ? false : true;\n return this.EMAIL_REGEX.test(val);\n });\n\n /**\n * Computed error message\n */\n protected readonly validationError = computed(() => {\n // Custom error takes precedence\n if (this.error()) return this.error();\n\n // Show validation errors only after touched or validateOnInput\n if (!this.touched() && !this.validateOnInput()) return undefined;\n\n const val = this.value();\n if (this.required() && !val) {\n return this.requiredMessage();\n }\n if (val && !this.isValid()) {\n return this.invalidMessage();\n }\n return undefined;\n });\n\n /**\n * Computed disabled state\n */\n protected get isDisabled(): boolean {\n return this.disabled() || this._formDisabled();\n }\n\n constructor() {\n // Emit validation state changes\n effect(() => {\n const valid = this.isValid();\n const error = this.validationError();\n this.validationChange.emit({ valid, error });\n });\n }\n\n // ===== ControlValueAccessor implementation =====\n\n writeValue(value: string): void {\n this.value.set(value || '');\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._formDisabled.set(isDisabled);\n }\n\n // ===== Public API methods =====\n\n /**\n * Public method to trigger validation\n */\n public validate(): boolean {\n this.touched.set(true);\n return this.isValid();\n }\n\n /**\n * Public method to reset validation state\n */\n public resetValidation(): void {\n this.touched.set(false);\n }\n\n // ===== Event handlers (protected) =====\n\n /**\n * Handles value changes from base input\n */\n protected onValueChange(newValue: string): void {\n this.value.set(newValue);\n this.onChange(newValue);\n this.valueChange.emit(newValue);\n }\n\n /**\n * Handles focus events\n */\n protected onFocus(): void {\n this.focused.emit();\n }\n\n /**\n * Handles blur events\n */\n protected onBlur(): void {\n this.touched.set(true);\n this.onTouched();\n this.blurred.emit();\n }\n\n /**\n * Handles Enter key press\n */\n protected onEnterPressed(): void {\n this.enterPressed.emit();\n }\n}\n","<lc-input\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n type=\"email\"\n [size]=\"size()\"\n [value]=\"value()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [readonlyWrap]=\"readonlyWrap()\"\n [required]=\"required()\"\n [requiredIndicator]=\"requiredIndicator()\"\n [error]=\"validationError()\"\n [helperText]=\"helperText()\"\n [iconBefore]=\"showIcon() ? 'envelope' : undefined\"\n [ariaLabel]=\"ariaLabel() || label()\"\n [autocomplete]=\"autocomplete()\"\n [name]=\"name()\"\n [autocapitalize]=\"autocapitalize()\"\n [spellcheck]=\"spellcheck()\"\n [enterkeyhint]=\"enterkeyhint()\"\n (valueChange)=\"onValueChange($event)\"\n (focused)=\"onFocus()\"\n (blurred)=\"onBlur()\"\n (enterPressed)=\"onEnterPressed()\"\n/>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-email-input.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/email-input/email-input.component.ts","../../../../libs/angular-ui-kit/src/lib/email-input/email-input.component.html"],"sourcesContent":["/* eslint-disable @typescript-eslint/member-ordering */\n/* ControlValueAccessor implementation requires specific method placement */\n\nimport {\n Component,\n input,\n output,\n signal,\n computed,\n ChangeDetectionStrategy,\n forwardRef,\n effect,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { InputAutocapitalize, InputComponent, InputEnterKeyHint } from '@lifecorner/angular-ui-kit/input';\nimport { ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_MAIL } from '@lifecorner/angular-ui-kit/icons';\n\n/**\n * Email input component with built-in RFC 5322 validation.\n *\n * Features:\n * - RFC 5322 regex email format validation\n * - Real-time validation feedback on input\n * - Valid/invalid visual indicators\n * - Size presets (xs, sm, md, lg)\n * - Helper text and error message display\n * - Disabled and readonly states (read-only addresses can wrap: `readonlyWrap`)\n * - Optional leading mail icon (`showIcon`)\n * - Autofill and keyboard hints: `autocomplete`, `name`, `autocapitalize`, `spellcheck`, `enterkeyhint`\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-email-input label=\"Email\" placeholder=\"you@example.com\" [(ngModel)]=\"email\" />\n * ```\n */\n@Component({\n selector: 'lc-email-input',\n imports: [CommonModule, InputComponent],\n // The `envelope` icon it hands to lc-input (an alias of the Tabler `mail`).\n viewProviders: [ɵprovideKitIcons([ICON_MAIL])],\n templateUrl: './email-input.component.html',\n styleUrl: './email-input.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => EmailInputComponent),\n multi: true,\n },\n ],\n})\nexport class EmailInputComponent implements ControlValueAccessor {\n // Input Properties\n /**\n * Input label (displayed above input)\n * @default 'Email'\n */\n readonly label = input<string>('Email');\n\n /**\n * Placeholder text\n * @default 'you@example.com'\n */\n readonly placeholder = input<string>('you@example.com');\n\n /**\n * Size of the input\n * @default 'md'\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the input is disabled\n * @default false\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the input is read-only\n * @default false\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Whether the input is required\n * @default false\n */\n readonly required = input<boolean>(false);\n\n /**\n * Custom error message (overrides validation error)\n */\n readonly error = input<string>();\n\n /**\n * Helper text to display below input\n */\n readonly helperText = input<string>();\n\n /**\n * Whether to show validation feedback immediately\n * @default false (validates on blur)\n */\n readonly validateOnInput = input<boolean>(false);\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string>();\n\n /**\n * Native `autocomplete` (input purpose, WCAG 1.3.5): `email` (registration),\n * `username` (the address as the sign-in name), `username webauthn` (sign-in:\n * the browser offers passkeys in this field). Unset = no attribute.\n */\n readonly autocomplete = input<string>();\n\n /** Native `name` of the inner input. Unset = no attribute. */\n readonly name = input<string>();\n\n /** Native `autocapitalize` (`off` keeps keyboards from capitalising the address). Unset = no attribute. */\n readonly autocapitalize = input<InputAutocapitalize>();\n\n /** Native `spellcheck`. Unset = no attribute. */\n readonly spellcheck = input<boolean>();\n\n /** Native `enterkeyhint`: the label of the on-screen keyboard's Enter key. Unset = no attribute. */\n readonly enterkeyhint = input<InputEnterKeyHint>();\n\n /**\n * Show the leading mail icon. `false` gives the address the icon's width\n * (about 36 px) — long addresses fit on a phone.\n * @default true\n */\n readonly showIcon = input<boolean>(true);\n\n /**\n * While `readonly`: the address wraps onto more lines instead of being\n * clipped. A hidden native input keeps value, `name` and `autocomplete`\n * (e.g. `username` for password managers on a password page).\n * @default false\n */\n readonly readonlyWrap = input<boolean>(false);\n\n /**\n * Show the `*` of a `required` field; `false` keeps the required semantics without it.\n * @default true\n */\n readonly requiredIndicator = input<boolean>(true);\n\n /** Error shown for an empty `required` field. */\n readonly requiredMessage = input('Email address is required');\n\n /** Error shown for a malformed address. */\n readonly invalidMessage = input('Please enter a valid email address');\n\n // Output Events\n /**\n * Emitted when email value changes\n */\n readonly valueChange = output<string>();\n\n /**\n * Emitted when validation state changes\n */\n readonly validationChange = output<{ valid: boolean; error?: string }>();\n\n /**\n * Emitted when input receives focus\n */\n readonly focused = output<void>();\n\n /**\n * Emitted when input loses focus\n */\n readonly blurred = output<void>();\n\n /**\n * Emitted when Enter key is pressed\n */\n readonly enterPressed = output<void>();\n\n // Internal state\n readonly value = signal<string>('');\n private readonly touched = signal<boolean>(false);\n private readonly _formDisabled = signal<boolean>(false);\n\n /**\n * RFC 5322 compliant email regex (simplified but robust)\n * Validates: local-part@domain\n * - Local part: alphanumeric, dots, hyphens, underscores, plus signs\n * - Domain: alphanumeric, dots, hyphens with valid TLD\n */\n private readonly EMAIL_REGEX =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n\n // ControlValueAccessor callbacks\n private onChange: (value: string) => void = () => { /* set by registerOnChange */ };\n private onTouched: () => void = () => { /* set by registerOnTouched */ };\n\n /**\n * Computed validation state\n */\n protected readonly isValid = computed(() => {\n const val = this.value();\n if (!val) return this.required() ? false : true;\n return this.EMAIL_REGEX.test(val);\n });\n\n /**\n * Computed error message\n */\n protected readonly validationError = computed(() => {\n // Custom error takes precedence\n if (this.error()) return this.error();\n\n // Show validation errors only after touched or validateOnInput\n if (!this.touched() && !this.validateOnInput()) return undefined;\n\n const val = this.value();\n if (this.required() && !val) {\n return this.requiredMessage();\n }\n if (val && !this.isValid()) {\n return this.invalidMessage();\n }\n return undefined;\n });\n\n /**\n * Computed disabled state\n */\n protected get isDisabled(): boolean {\n return this.disabled() || this._formDisabled();\n }\n\n constructor() {\n // Emit validation state changes\n effect(() => {\n const valid = this.isValid();\n const error = this.validationError();\n this.validationChange.emit({ valid, error });\n });\n }\n\n // ===== ControlValueAccessor implementation =====\n\n writeValue(value: string): void {\n this.value.set(value || '');\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._formDisabled.set(isDisabled);\n }\n\n // ===== Public API methods =====\n\n /**\n * Public method to trigger validation\n */\n public validate(): boolean {\n this.touched.set(true);\n return this.isValid();\n }\n\n /**\n * Public method to reset validation state\n */\n public resetValidation(): void {\n this.touched.set(false);\n }\n\n // ===== Event handlers (protected) =====\n\n /**\n * Handles value changes from base input\n */\n protected onValueChange(newValue: string): void {\n this.value.set(newValue);\n this.onChange(newValue);\n this.valueChange.emit(newValue);\n }\n\n /**\n * Handles focus events\n */\n protected onFocus(): void {\n this.focused.emit();\n }\n\n /**\n * Handles blur events\n */\n protected onBlur(): void {\n this.touched.set(true);\n this.onTouched();\n this.blurred.emit();\n }\n\n /**\n * Handles Enter key press\n */\n protected onEnterPressed(): void {\n this.enterPressed.emit();\n }\n}\n","<lc-input\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n type=\"email\"\n [size]=\"size()\"\n [value]=\"value()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [readonlyWrap]=\"readonlyWrap()\"\n [required]=\"required()\"\n [requiredIndicator]=\"requiredIndicator()\"\n [error]=\"validationError()\"\n [helperText]=\"helperText()\"\n [iconBefore]=\"showIcon() ? 'envelope' : undefined\"\n [ariaLabel]=\"ariaLabel() || label()\"\n [autocomplete]=\"autocomplete()\"\n [name]=\"name()\"\n [autocapitalize]=\"autocapitalize()\"\n [spellcheck]=\"spellcheck()\"\n [enterkeyhint]=\"enterkeyhint()\"\n (valueChange)=\"onValueChange($event)\"\n (focused)=\"onFocus()\"\n (blurred)=\"onBlur()\"\n (enterPressed)=\"onEnterPressed()\"\n/>\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import * as i0 from "@angular/core";
|
|
|
2
2
|
import { ChangeDetectionStrategy, Component, computed, forwardRef, input, model, output, signal, viewChild } from "@angular/core";
|
|
3
3
|
import { NG_VALUE_ACCESSOR } from "@angular/forms";
|
|
4
4
|
import { IconComponent } from "@lifecorner/angular-ui-kit/icon";
|
|
5
|
+
let nextUniqueId = 0;
|
|
5
6
|
var InputComponent = class InputComponent {
|
|
6
7
|
label = input(...ngDevMode ? [void 0, { debugName: "label" }] : /* istanbul ignore next */ []);
|
|
7
8
|
placeholder = input("", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
|
|
@@ -27,11 +28,17 @@ var InputComponent = class InputComponent {
|
|
|
27
28
|
spellcheck = input(...ngDevMode ? [void 0, { debugName: "spellcheck" }] : /* istanbul ignore next */ []);
|
|
28
29
|
enterkeyhint = input(...ngDevMode ? [void 0, { debugName: "enterkeyhint" }] : /* istanbul ignore next */ []);
|
|
29
30
|
requiredAriaLabel = input("required", ...ngDevMode ? [{ debugName: "requiredAriaLabel" }] : /* istanbul ignore next */ []);
|
|
31
|
+
controlId = input(void 0, ...ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []);
|
|
32
|
+
announceError = input(true, ...ngDevMode ? [{ debugName: "announceError" }] : /* istanbul ignore next */ []);
|
|
30
33
|
value = model("", ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
31
34
|
focused = output();
|
|
32
35
|
blurred = output();
|
|
33
36
|
enterPressed = output();
|
|
34
|
-
|
|
37
|
+
generatedId = `lc-input-${nextUniqueId++}`;
|
|
38
|
+
resolvedId = computed(() => this.controlId() || this.generatedId, ...ngDevMode ? [{ debugName: "resolvedId" }] : /* istanbul ignore next */ []);
|
|
39
|
+
get inputId() {
|
|
40
|
+
return this.resolvedId();
|
|
41
|
+
}
|
|
35
42
|
inputElement = viewChild("inputRef", ...ngDevMode ? [{ debugName: "inputElement" }] : /* istanbul ignore next */ []);
|
|
36
43
|
readonlyValueElement = viewChild("readonlyValueRef", ...ngDevMode ? [{ debugName: "readonlyValueElement" }] : /* istanbul ignore next */ []);
|
|
37
44
|
_formDisabled = signal(false, ...ngDevMode ? [{ debugName: "_formDisabled" }] : /* istanbul ignore next */ []);
|
|
@@ -292,6 +299,20 @@ var InputComponent = class InputComponent {
|
|
|
292
299
|
isRequired: false,
|
|
293
300
|
transformFunction: null
|
|
294
301
|
},
|
|
302
|
+
controlId: {
|
|
303
|
+
classPropertyName: "controlId",
|
|
304
|
+
publicName: "controlId",
|
|
305
|
+
isSignal: true,
|
|
306
|
+
isRequired: false,
|
|
307
|
+
transformFunction: null
|
|
308
|
+
},
|
|
309
|
+
announceError: {
|
|
310
|
+
classPropertyName: "announceError",
|
|
311
|
+
publicName: "announceError",
|
|
312
|
+
isSignal: true,
|
|
313
|
+
isRequired: false,
|
|
314
|
+
transformFunction: null
|
|
315
|
+
},
|
|
295
316
|
value: {
|
|
296
317
|
classPropertyName: "value",
|
|
297
318
|
publicName: "value",
|
|
@@ -325,8 +346,8 @@ var InputComponent = class InputComponent {
|
|
|
325
346
|
isSignal: true
|
|
326
347
|
}],
|
|
327
348
|
ngImport: i0,
|
|
328
|
-
template: "<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}
|
|
329
|
-
styles: [".input-wrapper{position:relative;display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%}.input-label{display:block;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);margin-bottom:var(--spacing-1)}.input-label .required-indicator{color:var(--color-error-600);margin-
|
|
349
|
+
template: "<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <!-- No whitespace before the *: the gap is its margin, and it never wraps onto a line alone -->\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}@if (required() && requiredIndicator()) {<span class=\"required-indicator\" aria-hidden=\"true\">*</span>}\n </label>\n }\n\n <!-- Input Container -->\n <div\n class=\"input-container\"\n [class.input-xs]=\"size() === 'xs'\"\n [class.input-sm]=\"size() === 'sm'\"\n [class.input-md]=\"size() === 'md'\"\n [class.input-lg]=\"size() === 'lg'\"\n [class.input-invalid]=\"hasError\"\n [class.input-disabled]=\"isDisabled\"\n [class.input-readonly]=\"readonly()\"\n [class.input-readonly-wrap]=\"wrapsReadonlyValue()\"\n >\n <!-- Icon Before -->\n @if (iconBefore()) {\n <span class=\"input-icon input-icon-before\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconBefore()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n\n <!-- Read-only value that wraps (SI-10): a read-only textbox named by the label -->\n @if (wrapsReadonlyValue()) {\n <div\n #readonlyValueRef\n class=\"input-field input-readonly-value\"\n role=\"textbox\"\n aria-readonly=\"true\"\n tabindex=\"0\"\n [attr.aria-labelledby]=\"label() ? inputId + '-label' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n >{{ value() }}</div>\n }\n\n <!-- Input Element (hidden while the read-only value wraps; it keeps value, name and autocomplete) -->\n <input\n #inputRef\n [id]=\"inputId\"\n [type]=\"type()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [hidden]=\"wrapsReadonlyValue()\"\n [attr.maxlength]=\"maxLength() || null\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.name]=\"name() ?? null\"\n [attr.autocapitalize]=\"autocapitalize() ?? null\"\n [attr.spellcheck]=\"spellcheck() === undefined ? null : spellcheck() ? 'true' : 'false'\"\n [attr.enterkeyhint]=\"enterkeyhint() ?? null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-required]=\"required() || undefined\"\n [attr.aria-invalid]=\"hasError || undefined\"\n [attr.aria-describedby]=\"describedBy()\"\n class=\"input-field\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <!-- Icon After -->\n @if (iconAfter()) {\n <span class=\"input-icon input-icon-after\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconAfter()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n </div>\n\n <!-- Helper Text / Error Message / Character Count -->\n @if (error() || helperText() || (showCharCount() && maxLength())) {\n <div class=\"input-footer\">\n <!-- Error Message -->\n @if (error()) {\n <p [id]=\"inputId + '-error'\" class=\"input-error\" [attr.role]=\"announceError() ? 'alert' : null\">\n {{ error() }}\n </p>\n }\n\n <!-- Helper Text -->\n @if (helperText() && !error()) {\n <p [id]=\"inputId + '-helper'\" class=\"input-helper\">\n {{ helperText() }}\n </p>\n }\n\n <!-- Character Count: always visible; spoken only near the limit (live region below) -->\n @if (showCharCount() && maxLength()) {\n <p class=\"char-count\">\n {{ charCount }} / {{ maxLength() }}\n </p>\n }\n </div>\n }\n\n @if (showCharCount() && maxLength()) {\n <span class=\"input-char-count-live\" aria-live=\"polite\">{{ charCountAnnouncement() }}</span>\n }\n</div>\n",
|
|
350
|
+
styles: [".input-wrapper{position:relative;display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%}.input-label{display:block;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);margin-bottom:var(--spacing-1)}.input-label .required-indicator{color:var(--color-error-600);margin-inline-start:var(--spacing-1)}.input-container{position:relative;display:flex;align-items:center;width:100%;background-color:var(--color-surface-2);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease)}.input-container:hover:not(.input-disabled):not(.input-readonly){border-color:var(--color-text-secondary)}.input-container:focus-within{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.input-container.input-invalid{border-color:var(--color-error-600)}.input-container.input-invalid:focus-within{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.input-container.input-disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.input-container.input-readonly{background-color:var(--color-surface-muted)}.input-container.input-readonly-wrap{height:auto;min-height:var(--lc-input-height);align-items:stretch}.input-readonly-value{display:flex;align-items:center;min-width:0;white-space:normal;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.input-char-count-live{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.input-field{flex:1;width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background:transparent;border:none;outline:none}.input-field::placeholder{color:var(--color-text-secondary)}.input-field:disabled{cursor:not-allowed}.input-field:read-only{cursor:default}.input-field[type=number]::-webkit-inner-spin-button,.input-field[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.input-field[type=number]{-moz-appearance:textfield}.input-icon{display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary);pointer-events:none}.input-icon .icon{width:1.25rem;height:1.25rem}.input-icon.input-icon-before{margin-left:var(--spacing-3);margin-right:var(--spacing-2)}.input-icon.input-icon-after{margin-left:var(--spacing-2);margin-right:var(--spacing-3)}.input-xs{--lc-input-height: var(--size-interactive-xs-height);height:var(--lc-input-height)}.input-xs .input-field{padding:var(--size-interactive-xs-padding);font-size:var(--size-interactive-xs-font-size)}.input-xs .icon{width:1rem;height:1rem}.input-sm{--lc-input-height: var(--size-interactive-sm-height);height:var(--lc-input-height)}.input-sm .input-field{padding:var(--size-interactive-sm-padding);font-size:var(--size-interactive-sm-font-size)}.input-md{--lc-input-height: var(--size-interactive-md-height);height:var(--lc-input-height)}.input-md .input-field{padding:var(--size-interactive-md-padding);font-size:var(--size-interactive-md-font-size)}.input-lg{--lc-input-height: var(--size-interactive-lg-height);height:var(--lc-input-height)}.input-lg .input-field{padding:var(--size-interactive-lg-padding);font-size:var(--size-interactive-lg-font-size)}.input-lg .icon{width:1.5rem;height:1.5rem}.input-footer{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--lc-density-gap-sm, var(--spacing-2));min-height:1.25rem}.input-error{flex:1;font-size:var(--font-size-xs);color:var(--color-error-600);margin:0}.input-helper{flex:1;font-size:var(--font-size-xs);color:var(--color-text-secondary);margin:0}.char-count{font-size:var(--font-size-xs);color:var(--color-text-secondary);white-space:nowrap;margin:0}\n"],
|
|
330
351
|
dependencies: [{
|
|
331
352
|
kind: "component",
|
|
332
353
|
type: IconComponent,
|
|
@@ -360,8 +381,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
360
381
|
useExisting: forwardRef(() => InputComponent),
|
|
361
382
|
multi: true
|
|
362
383
|
}],
|
|
363
|
-
template: "<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}
|
|
364
|
-
styles: [".input-wrapper{position:relative;display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%}.input-label{display:block;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);margin-bottom:var(--spacing-1)}.input-label .required-indicator{color:var(--color-error-600);margin-
|
|
384
|
+
template: "<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <!-- No whitespace before the *: the gap is its margin, and it never wraps onto a line alone -->\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}@if (required() && requiredIndicator()) {<span class=\"required-indicator\" aria-hidden=\"true\">*</span>}\n </label>\n }\n\n <!-- Input Container -->\n <div\n class=\"input-container\"\n [class.input-xs]=\"size() === 'xs'\"\n [class.input-sm]=\"size() === 'sm'\"\n [class.input-md]=\"size() === 'md'\"\n [class.input-lg]=\"size() === 'lg'\"\n [class.input-invalid]=\"hasError\"\n [class.input-disabled]=\"isDisabled\"\n [class.input-readonly]=\"readonly()\"\n [class.input-readonly-wrap]=\"wrapsReadonlyValue()\"\n >\n <!-- Icon Before -->\n @if (iconBefore()) {\n <span class=\"input-icon input-icon-before\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconBefore()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n\n <!-- Read-only value that wraps (SI-10): a read-only textbox named by the label -->\n @if (wrapsReadonlyValue()) {\n <div\n #readonlyValueRef\n class=\"input-field input-readonly-value\"\n role=\"textbox\"\n aria-readonly=\"true\"\n tabindex=\"0\"\n [attr.aria-labelledby]=\"label() ? inputId + '-label' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n >{{ value() }}</div>\n }\n\n <!-- Input Element (hidden while the read-only value wraps; it keeps value, name and autocomplete) -->\n <input\n #inputRef\n [id]=\"inputId\"\n [type]=\"type()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [hidden]=\"wrapsReadonlyValue()\"\n [attr.maxlength]=\"maxLength() || null\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.name]=\"name() ?? null\"\n [attr.autocapitalize]=\"autocapitalize() ?? null\"\n [attr.spellcheck]=\"spellcheck() === undefined ? null : spellcheck() ? 'true' : 'false'\"\n [attr.enterkeyhint]=\"enterkeyhint() ?? null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-required]=\"required() || undefined\"\n [attr.aria-invalid]=\"hasError || undefined\"\n [attr.aria-describedby]=\"describedBy()\"\n class=\"input-field\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <!-- Icon After -->\n @if (iconAfter()) {\n <span class=\"input-icon input-icon-after\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconAfter()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n </div>\n\n <!-- Helper Text / Error Message / Character Count -->\n @if (error() || helperText() || (showCharCount() && maxLength())) {\n <div class=\"input-footer\">\n <!-- Error Message -->\n @if (error()) {\n <p [id]=\"inputId + '-error'\" class=\"input-error\" [attr.role]=\"announceError() ? 'alert' : null\">\n {{ error() }}\n </p>\n }\n\n <!-- Helper Text -->\n @if (helperText() && !error()) {\n <p [id]=\"inputId + '-helper'\" class=\"input-helper\">\n {{ helperText() }}\n </p>\n }\n\n <!-- Character Count: always visible; spoken only near the limit (live region below) -->\n @if (showCharCount() && maxLength()) {\n <p class=\"char-count\">\n {{ charCount }} / {{ maxLength() }}\n </p>\n }\n </div>\n }\n\n @if (showCharCount() && maxLength()) {\n <span class=\"input-char-count-live\" aria-live=\"polite\">{{ charCountAnnouncement() }}</span>\n }\n</div>\n",
|
|
385
|
+
styles: [".input-wrapper{position:relative;display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%}.input-label{display:block;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-primary);margin-bottom:var(--spacing-1)}.input-label .required-indicator{color:var(--color-error-600);margin-inline-start:var(--spacing-1)}.input-container{position:relative;display:flex;align-items:center;width:100%;background-color:var(--color-surface-2);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease)}.input-container:hover:not(.input-disabled):not(.input-readonly){border-color:var(--color-text-secondary)}.input-container:focus-within{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.input-container.input-invalid{border-color:var(--color-error-600)}.input-container.input-invalid:focus-within{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.input-container.input-disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.input-container.input-readonly{background-color:var(--color-surface-muted)}.input-container.input-readonly-wrap{height:auto;min-height:var(--lc-input-height);align-items:stretch}.input-readonly-value{display:flex;align-items:center;min-width:0;white-space:normal;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.input-char-count-live{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.input-field{flex:1;width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background:transparent;border:none;outline:none}.input-field::placeholder{color:var(--color-text-secondary)}.input-field:disabled{cursor:not-allowed}.input-field:read-only{cursor:default}.input-field[type=number]::-webkit-inner-spin-button,.input-field[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.input-field[type=number]{-moz-appearance:textfield}.input-icon{display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary);pointer-events:none}.input-icon .icon{width:1.25rem;height:1.25rem}.input-icon.input-icon-before{margin-left:var(--spacing-3);margin-right:var(--spacing-2)}.input-icon.input-icon-after{margin-left:var(--spacing-2);margin-right:var(--spacing-3)}.input-xs{--lc-input-height: var(--size-interactive-xs-height);height:var(--lc-input-height)}.input-xs .input-field{padding:var(--size-interactive-xs-padding);font-size:var(--size-interactive-xs-font-size)}.input-xs .icon{width:1rem;height:1rem}.input-sm{--lc-input-height: var(--size-interactive-sm-height);height:var(--lc-input-height)}.input-sm .input-field{padding:var(--size-interactive-sm-padding);font-size:var(--size-interactive-sm-font-size)}.input-md{--lc-input-height: var(--size-interactive-md-height);height:var(--lc-input-height)}.input-md .input-field{padding:var(--size-interactive-md-padding);font-size:var(--size-interactive-md-font-size)}.input-lg{--lc-input-height: var(--size-interactive-lg-height);height:var(--lc-input-height)}.input-lg .input-field{padding:var(--size-interactive-lg-padding);font-size:var(--size-interactive-lg-font-size)}.input-lg .icon{width:1.5rem;height:1.5rem}.input-footer{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--lc-density-gap-sm, var(--spacing-2));min-height:1.25rem}.input-error{flex:1;font-size:var(--font-size-xs);color:var(--color-error-600);margin:0}.input-helper{flex:1;font-size:var(--font-size-xs);color:var(--color-text-secondary);margin:0}.char-count{font-size:var(--font-size-xs);color:var(--color-text-secondary);white-space:nowrap;margin:0}\n"]
|
|
365
386
|
}]
|
|
366
387
|
}],
|
|
367
388
|
propDecorators: {
|
|
@@ -557,6 +578,22 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
557
578
|
required: false
|
|
558
579
|
}]
|
|
559
580
|
}],
|
|
581
|
+
controlId: [{
|
|
582
|
+
type: i0.Input,
|
|
583
|
+
args: [{
|
|
584
|
+
isSignal: true,
|
|
585
|
+
alias: "controlId",
|
|
586
|
+
required: false
|
|
587
|
+
}]
|
|
588
|
+
}],
|
|
589
|
+
announceError: [{
|
|
590
|
+
type: i0.Input,
|
|
591
|
+
args: [{
|
|
592
|
+
isSignal: true,
|
|
593
|
+
alias: "announceError",
|
|
594
|
+
required: false
|
|
595
|
+
}]
|
|
596
|
+
}],
|
|
560
597
|
value: [{
|
|
561
598
|
type: i0.Input,
|
|
562
599
|
args: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-input.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/input/input.component.ts","../../../../libs/angular-ui-kit/src/lib/input/input.component.html"],"sourcesContent":["/* eslint-disable @typescript-eslint/member-ordering */\nimport {\n Component,\n computed,\n input,\n model,\n output,\n signal,\n viewChild,\n ElementRef,\n ChangeDetectionStrategy,\n forwardRef,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\n\n/** Values of the native `autocapitalize` attribute. */\nexport type InputAutocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';\n\n/** Values of the native `enterkeyhint` attribute (label of the on-screen keyboard's Enter key). */\nexport type InputEnterKeyHint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';\n\n/**\n * Input component for single-line text form data entry.\n *\n * Features:\n * - Type variants (text, email, password, number, tel, url)\n * - Size presets (xs, sm, md, lg)\n * - Leading and trailing icon support\n * - Character count display with maxLength (announced only near the limit)\n * - Validation error message display\n * - Helper text support\n * - Disabled and readonly states (read-only values can wrap: `readonlyWrap`)\n * - Input purpose and keyboard hints: `autocomplete`, `name`, `autocapitalize`,\n * `spellcheck`, `enterkeyhint`\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-input label=\"Name\" autocomplete=\"name\" autocapitalize=\"words\" [spellcheck]=\"false\" [(ngModel)]=\"name\" />\n * ```\n */\n@Component({\n selector: 'lc-input',\n imports: [IconComponent],\n templateUrl: './input.component.html',\n styleUrl: './input.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => InputComponent),\n multi: true,\n },\n ],\n})\nexport class InputComponent implements ControlValueAccessor {\n // Input Properties\n /**\n * Input label (displayed above input)\n */\n readonly label = input<string>();\n\n /**\n * Placeholder text\n * @default ''\n */\n readonly placeholder = input<string>('');\n\n /**\n * Input type\n * @default 'text'\n */\n readonly type = input<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>('text');\n\n /**\n * Size of the input\n * @default 'md'\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the input is disabled\n * @default false\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the input is read-only\n * @default false\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Read-only values wrap onto more lines instead of being clipped (WCAG 1.4.10):\n * the value is shown as text (a read-only textbox named by the label), and a\n * hidden native input keeps the value, `name` and `autocomplete` for forms and\n * password managers. Only applies while `readonly` is set.\n * @default false\n */\n readonly readonlyWrap = input<boolean>(false);\n\n /**\n * Whether the input is required\n * @default false\n */\n readonly required = input<boolean>(false);\n\n /**\n * Show the `*` after the label of a `required` field. `false` keeps the\n * required semantics (`required`, `aria-required`) without the asterisk —\n * for forms where every field is required.\n * @default true\n */\n readonly requiredIndicator = input<boolean>(true);\n\n /**\n * Error message to display (if validation fails)\n */\n readonly error = input<string>();\n\n /**\n * Helper text to display below input\n */\n readonly helperText = input<string>();\n\n /**\n * Icon to display before input text (Tabler icon name)\n * @example 'envelope'\n */\n readonly iconBefore = input<string>();\n\n /**\n * Icon to display after input text (Tabler icon name)\n * @example 'eye'\n */\n readonly iconAfter = input<string>();\n\n /**\n * Maximum number of characters\n */\n readonly maxLength = input<number>();\n\n /**\n * Whether to show character count\n * @default false\n */\n readonly showCharCount = input<boolean>(false);\n\n /**\n * Screen-reader announcement of the character count near the limit;\n * `{remaining}` is replaced.\n * @default 'Characters remaining: {remaining}'\n */\n readonly charCountRemainingLabel = input('Characters remaining: {remaining}');\n\n /**\n * Remaining characters from which the count is announced (the visible count\n * is always shown). Unset = the last 10 % of `maxLength` (at least 1).\n */\n readonly charCountAnnounceThreshold = input<number>();\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string>();\n\n /**\n * Native `autocomplete` — the input purpose (WCAG 1.3.5), so browsers and\n * password managers fill the field: `name`, `email`, `username`,\n * `username webauthn` (offers passkeys in the field), `current-password`,\n * `new-password`, `one-time-code`, `tel`, `off` … Unset = no attribute.\n */\n readonly autocomplete = input<string>();\n\n /** Native `name` of the inner `<input>` (form posts, password managers). Unset = no attribute. */\n readonly name = input<string>();\n\n /**\n * Native `autocapitalize` for on-screen keyboards: `off` for addresses,\n * user names and codes, `words` for names. Unset = no attribute.\n */\n readonly autocapitalize = input<InputAutocapitalize>();\n\n /** Native `spellcheck`: `false` for names, addresses and codes. Unset = no attribute. */\n readonly spellcheck = input<boolean>();\n\n /** Native `enterkeyhint`: the label of the on-screen keyboard's Enter key. Unset = no attribute. */\n readonly enterkeyhint = input<InputEnterKeyHint>();\n\n /** Accessible name of the `*` marker shown for `required` fields. */\n readonly requiredAriaLabel = input('required');\n\n /**\n * Current value (two-way bindable: `[value]` / `[(value)]`). Emits\n * `valueChange` whenever it changes — once per user keystroke, on `clear()`\n * and when a bound form control writes a value.\n */\n readonly value = model<string>('');\n\n // Output Events\n /**\n * Emitted when input receives focus\n */\n readonly focused = output<void>();\n\n /**\n * Emitted when input loses focus\n */\n readonly blurred = output<void>();\n\n /**\n * Emitted when Enter key is pressed\n */\n readonly enterPressed = output<void>();\n\n // Internal state\n readonly inputId = `lc-input-${Math.random().toString(36).substr(2, 9)}`;\n\n // ViewChild reference\n private readonly inputElement = viewChild<ElementRef<HTMLInputElement>>('inputRef');\n private readonly readonlyValueElement = viewChild<ElementRef<HTMLElement>>('readonlyValueRef');\n\n // Internal disabled state (for ControlValueAccessor)\n private readonly _formDisabled = signal<boolean>(false);\n\n // ControlValueAccessor callbacks\n private onChange: (value: string) => void = () => { /* set by registerOnChange */ };\n private onTouched: () => void = () => { /* set by registerOnTouched */ };\n\n /** The read-only value is shown as wrapping text (SI-10). */\n protected readonly wrapsReadonlyValue = computed(() => this.readonly() && this.readonlyWrap());\n\n /** `aria-describedby`: only the texts that are rendered (the error replaces the helper text). */\n protected readonly describedBy = computed(() => {\n if (this.error()) return `${this.inputId}-error`;\n if (this.helperText()) return `${this.inputId}-helper`;\n return null;\n });\n\n /** Screen-reader text of the character count: empty until the limit is near. */\n protected readonly charCountAnnouncement = computed(() => {\n const max = this.maxLength();\n if (!this.showCharCount() || !max) return '';\n const remaining = Math.max(0, max - this.value().length);\n const threshold = this.charCountAnnounceThreshold() ?? Math.max(1, Math.ceil(max * 0.1));\n if (remaining > threshold) return '';\n return this.charCountRemainingLabel().replace('{remaining}', String(remaining));\n });\n\n /**\n * Computed disabled state from both input and form control\n */\n protected get isDisabled(): boolean {\n return this.disabled() || this._formDisabled();\n }\n\n /**\n * Gets current character count\n */\n protected get charCount(): number {\n return this.value().length;\n }\n\n /**\n * Determines if error state should be shown\n */\n protected get hasError(): boolean {\n return !!this.error();\n }\n\n /**\n * Programmatically focus the input (the visible value while `readonlyWrap` applies)\n */\n public focus(): void {\n if (this.wrapsReadonlyValue()) {\n this.readonlyValueElement()?.nativeElement.focus();\n return;\n }\n this.inputElement()?.nativeElement.focus();\n }\n\n /**\n * Programmatically select input text\n */\n public select(): void {\n const shown = this.wrapsReadonlyValue() ? this.readonlyValueElement()?.nativeElement : undefined;\n if (shown) {\n const selection = shown.ownerDocument.getSelection();\n const range = shown.ownerDocument.createRange();\n range.selectNodeContents(shown);\n selection?.removeAllRanges();\n selection?.addRange(range);\n return;\n }\n this.inputElement()?.nativeElement.select();\n }\n\n /**\n * Clear the input value\n */\n public clear(): void {\n this.value.set('');\n this.onChange('');\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n this.value.set(value || '');\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._formDisabled.set(isDisabled);\n }\n\n /**\n * Handles input value changes\n */\n protected onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n const newValue = target.value;\n // model.set() emits `valueChange` exactly once per actual change\n this.value.set(newValue);\n this.onChange(newValue);\n }\n\n /**\n * Handles input focus\n */\n protected onFocus(): void {\n this.focused.emit();\n }\n\n /**\n * Handles input blur\n */\n protected onBlur(): void {\n this.onTouched();\n this.blurred.emit();\n }\n\n /**\n * Handles keydown events\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.enterPressed.emit();\n }\n }\n}\n","<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}\n @if (required() && requiredIndicator()) {\n <span class=\"required-indicator\" [attr.aria-label]=\"requiredAriaLabel()\">*</span>\n }\n </label>\n }\n\n <!-- Input Container -->\n <div\n class=\"input-container\"\n [class.input-xs]=\"size() === 'xs'\"\n [class.input-sm]=\"size() === 'sm'\"\n [class.input-md]=\"size() === 'md'\"\n [class.input-lg]=\"size() === 'lg'\"\n [class.input-error]=\"hasError\"\n [class.input-disabled]=\"isDisabled\"\n [class.input-readonly]=\"readonly()\"\n [class.input-readonly-wrap]=\"wrapsReadonlyValue()\"\n >\n <!-- Icon Before -->\n @if (iconBefore()) {\n <span class=\"input-icon input-icon-before\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconBefore()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n\n <!-- Read-only value that wraps (SI-10): a read-only textbox named by the label -->\n @if (wrapsReadonlyValue()) {\n <div\n #readonlyValueRef\n class=\"input-field input-readonly-value\"\n role=\"textbox\"\n aria-readonly=\"true\"\n tabindex=\"0\"\n [attr.aria-labelledby]=\"label() ? inputId + '-label' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n >{{ value() }}</div>\n }\n\n <!-- Input Element (hidden while the read-only value wraps; it keeps value, name and autocomplete) -->\n <input\n #inputRef\n [id]=\"inputId\"\n [type]=\"type()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [hidden]=\"wrapsReadonlyValue()\"\n [attr.maxlength]=\"maxLength() || null\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.name]=\"name() ?? null\"\n [attr.autocapitalize]=\"autocapitalize() ?? null\"\n [attr.spellcheck]=\"spellcheck() === undefined ? null : spellcheck() ? 'true' : 'false'\"\n [attr.enterkeyhint]=\"enterkeyhint() ?? null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-required]=\"required() || undefined\"\n [attr.aria-invalid]=\"hasError || undefined\"\n [attr.aria-describedby]=\"describedBy()\"\n class=\"input-field\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <!-- Icon After -->\n @if (iconAfter()) {\n <span class=\"input-icon input-icon-after\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconAfter()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n </div>\n\n <!-- Helper Text / Error Message / Character Count -->\n @if (error() || helperText() || (showCharCount() && maxLength())) {\n <div class=\"input-footer\">\n <!-- Error Message -->\n @if (error()) {\n <p [id]=\"inputId + '-error'\" class=\"input-error\" role=\"alert\">\n {{ error() }}\n </p>\n }\n\n <!-- Helper Text -->\n @if (helperText() && !error()) {\n <p [id]=\"inputId + '-helper'\" class=\"input-helper\">\n {{ helperText() }}\n </p>\n }\n\n <!-- Character Count: always visible; spoken only near the limit (live region below) -->\n @if (showCharCount() && maxLength()) {\n <p class=\"char-count\">\n {{ charCount }} / {{ maxLength() }}\n </p>\n }\n </div>\n }\n\n @if (showCharCount() && maxLength()) {\n <span class=\"input-char-count-live\" aria-live=\"polite\">{{ charCountAnnouncement() }}</span>\n }\n</div>\n"],"mappings":";;;;AAwDA,IAAa,iBAAb,MAAa,eAAc;CAKhB,QAAQ,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAMvB,cAAc,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAM/B,OAAO,MAAgE,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAM9E,OAAO,MAAiC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAM7C,WAAW,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAMhC,WAAW,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAShC,eAAe,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAMpC,WAAW,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAQhC,oBAAoB,MAAe,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAKxC,QAAQ,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAKvB,aAAa,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAM5B,aAAa,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAM5B,YAAY,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAK3B,YAAY,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAM3B,gBAAgB,MAAe,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAOrC,0BAA0B,MAAM,qCAAoC,GAAA,YAAA,CAAA,EAAA,WAAA,0BAAA,CAAA,+BAAA,CAAA,CAAA;CAMpE,6BAA6B,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,6BAAA,CAAA,+BAAA,CAAA,CAAA;CAK5C,YAAY,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAQ3B,eAAe,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAG9B,OAAO,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAMtB,iBAAiB,MAA4B,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAG7C,aAAa,MAAgB,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAG7B,eAAe,MAA0B,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAGzC,oBAAoB,MAAM,YAAW,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAOrC,QAAQ,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAMzB,UAAU,OAAM;CAKhB,UAAU,OAAM;CAKhB,eAAe,OAAM;CAGrB,UAAU,YAAY,KAAK,OAAM,CAAE,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;CAGpD,eAAe,UAAwC,YAAW,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAClE,uBAAuB,UAAmC,oBAAmB,GAAA,YAAA,CAAA,EAAA,WAAA,uBAAA,CAAA,+BAAA,CAAA,CAAA;CAG7E,gBAAgB,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAG/C,iBAAyC,CAAiC;CAC1E,kBAA6B,CAAkC;CAGpD,qBAAqB,eAAe,KAAK,SAAQ,KAAM,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CAG3E,cAAc,eAAc;EAC7C,IAAI,KAAK,MAAK,GAAI,OAAO,GAAG,KAAK,QAAO;EACxC,IAAI,KAAK,WAAU,GAAI,OAAO,GAAG,KAAK,QAAO;EAC7C,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAGiB,wBAAwB,eAAc;EACvD,MAAM,MAAM,KAAK,UAAS;EAC1B,IAAI,CAAC,KAAK,cAAa,KAAM,CAAC,KAAK,OAAO;EAC1C,MAAM,YAAY,KAAK,IAAI,GAAG,MAAM,KAAK,MAAK,CAAE,CAAC,MAAM;EAEvD,IAAI,aADc,KAAK,2BAA0B,KAAM,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,EAAG,CAAC,IAC5D,OAAO;EAClC,OAAO,KAAK,wBAAuB,CAAE,CAAC,QAAQ,eAAe,OAAO,SAAS,CAAC;CAChF,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,wBAAA,CAAA,+BAAA,CAAA,CAAA;CAKF,IAAc,aAAU;EACtB,OAAO,KAAK,SAAQ,KAAM,KAAK,cAAa;CAC9C;CAKA,IAAc,YAAS;EACrB,OAAO,KAAK,MAAK,CAAE,CAAC;CACtB;CAKA,IAAc,WAAQ;EACpB,OAAO,CAAC,CAAC,KAAK,MAAK;CACrB;CAKO,QAAK;EACV,IAAI,KAAK,mBAAkB,GAAI;GAC7B,KAAK,qBAAoB,CAAE,EAAE,cAAc,MAAK;GAChD;EACF;EACA,KAAK,aAAY,CAAE,EAAE,cAAc,MAAK;CAC1C;CAKO,SAAM;EACX,MAAM,QAAQ,KAAK,mBAAkB,IAAK,KAAK,qBAAoB,CAAE,EAAE,gBAAgB;EACvF,IAAI,OAAO;GACT,MAAM,YAAY,MAAM,cAAc,aAAY;GAClD,MAAM,QAAQ,MAAM,cAAc,YAAW;GAC7C,MAAM,mBAAmB,KAAK;GAC9B,WAAW,gBAAe;GAC1B,WAAW,SAAS,KAAK;GACzB;EACF;EACA,KAAK,aAAY,CAAE,EAAE,cAAc,OAAM;CAC3C;CAKO,QAAK;EACV,KAAK,MAAM,IAAI,EAAE;EACjB,KAAK,SAAS,EAAE;CAClB;CAGA,WAAW,OAAoB;EAC7B,KAAK,MAAM,IAAI,SAAS,EAAE;CAC5B;CAEA,iBAAiB,IAA2B;EAC1C,KAAK,WAAW;CAClB;CAEA,kBAAkB,IAAc;EAC9B,KAAK,YAAY;CACnB;CAEA,iBAAiB,YAAmB;EAClC,KAAK,cAAc,IAAI,UAAU;CACnC;CAKU,QAAQ,OAAY;EAE5B,MAAM,WADS,MAAM,OACG;EAExB,KAAK,MAAM,IAAI,QAAQ;EACvB,KAAK,SAAS,QAAQ;CACxB;CAKU,UAAO;EACf,KAAK,QAAQ,KAAI;CACnB;CAKU,SAAM;EACd,KAAK,UAAS;EACd,KAAK,QAAQ,KAAI;CACnB;CAKU,UAAU,OAAoB;EACtC,IAAI,MAAM,QAAQ,SAChB,KAAK,aAAa,KAAI;CAE1B;CA5SW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAc,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,mBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,eAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,yBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,4BAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,WAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,MAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,gBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,cAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,mBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA;GAAA,OAAA;GAAA,SAAA;GAAA,SAAA;GAAA,cAAA;EAAA;EAAA,WARd,CACT;GACE,SAAS;GACT,aAAa,iBAAiB,cAAc;GAC5C,OAAO;EACR,CACF;EAAA,aAAA,CAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,UAAA;GAAA,aAAA;GAAA,UAAA;EAAA,GAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,kBAAA;GAAA,aAAA;GAAA,UAAA;EAAA,CAAA;EAAA,UAAA;EAAA,UCtDH;EAgHA,QAAA,CAAA,m1HAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDpEY;GAAa,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAYZ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAd1B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAU,SACX,CAAC,aAAa;GAAC,iBAGP,wBAAwB;GAAM,WACpC,CACT;IACE,SAAS;IACT,aAAa,iBAAgB,cAAe;IAC5C,OAAO;GACR,CACF;GAAA,UAAA;GAAA,QAAA,CAAA,m1HAAA;EAAA,CAAA;CAsKuE,CAAA;CAAA,gBAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,mBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,eAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,yBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,4BAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,gBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,mBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,GAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,aAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,SAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,SAAA;EAAA,CAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,cAAA;EAAA,CAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,YAAU,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,sBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CACP,oBAAkB,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-input.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/input/input.component.ts","../../../../libs/angular-ui-kit/src/lib/input/input.component.html"],"sourcesContent":["/* eslint-disable @typescript-eslint/member-ordering */\nimport {\n Component,\n computed,\n input,\n model,\n output,\n signal,\n viewChild,\n ElementRef,\n ChangeDetectionStrategy,\n forwardRef,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\n\n/** Values of the native `autocapitalize` attribute. */\nexport type InputAutocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';\n\n/** Values of the native `enterkeyhint` attribute (label of the on-screen keyboard's Enter key). */\nexport type InputEnterKeyHint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';\n\n/** Counter for generated ids: they follow creation order, so prerendered HTML is the same in every build. */\nlet nextUniqueId = 0;\n\n/**\n * Input component for single-line text form data entry.\n *\n * Features:\n * - Type variants (text, email, password, number, tel, url)\n * - Size presets (xs, sm, md, lg)\n * - Leading and trailing icon support\n * - Character count display with maxLength (announced only near the limit)\n * - Validation error message display\n * - Helper text support\n * - Disabled and readonly states (read-only values can wrap: `readonlyWrap`)\n * - Input purpose and keyboard hints: `autocomplete`, `name`, `autocapitalize`,\n * `spellcheck`, `enterkeyhint`\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-input label=\"Name\" autocomplete=\"name\" autocapitalize=\"words\" [spellcheck]=\"false\" [(ngModel)]=\"name\" />\n * ```\n */\n@Component({\n selector: 'lc-input',\n imports: [IconComponent],\n templateUrl: './input.component.html',\n styleUrl: './input.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => InputComponent),\n multi: true,\n },\n ],\n})\nexport class InputComponent implements ControlValueAccessor {\n // Input Properties\n /**\n * Input label (displayed above input)\n */\n readonly label = input<string>();\n\n /**\n * Placeholder text\n * @default ''\n */\n readonly placeholder = input<string>('');\n\n /**\n * Input type\n * @default 'text'\n */\n readonly type = input<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>('text');\n\n /**\n * Size of the input\n * @default 'md'\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the input is disabled\n * @default false\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the input is read-only\n * @default false\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Read-only values wrap onto more lines instead of being clipped (WCAG 1.4.10):\n * the value is shown as text (a read-only textbox named by the label), and a\n * hidden native input keeps the value, `name` and `autocomplete` for forms and\n * password managers. Only applies while `readonly` is set.\n * @default false\n */\n readonly readonlyWrap = input<boolean>(false);\n\n /**\n * Whether the input is required\n * @default false\n */\n readonly required = input<boolean>(false);\n\n /**\n * Show the `*` after the label of a `required` field. `false` keeps the\n * required semantics (`required`, `aria-required`) without the asterisk —\n * for forms where every field is required.\n * @default true\n */\n readonly requiredIndicator = input<boolean>(true);\n\n /**\n * Error message to display (if validation fails). While it is set, the field\n * container carries the class `input-invalid` and the message renders as\n * `<p class=\"input-error\">`. Before 3.13 the container also carried\n * `input-error` (G-WL3).\n * @default undefined\n */\n readonly error = input<string>();\n\n /**\n * Helper text to display below input\n */\n readonly helperText = input<string>();\n\n /**\n * Icon to display before input text (Tabler icon name)\n * @example 'envelope'\n */\n readonly iconBefore = input<string>();\n\n /**\n * Icon to display after input text (Tabler icon name)\n * @example 'eye'\n */\n readonly iconAfter = input<string>();\n\n /**\n * Maximum number of characters\n */\n readonly maxLength = input<number>();\n\n /**\n * Whether to show character count\n * @default false\n */\n readonly showCharCount = input<boolean>(false);\n\n /**\n * Screen-reader announcement of the character count near the limit;\n * `{remaining}` is replaced.\n * @default 'Characters remaining: {remaining}'\n */\n readonly charCountRemainingLabel = input('Characters remaining: {remaining}');\n\n /**\n * Remaining characters from which the count is announced (the visible count\n * is always shown). Unset = the last 10 % of `maxLength` (at least 1).\n */\n readonly charCountAnnounceThreshold = input<number>();\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string>();\n\n /**\n * Native `autocomplete` — the input purpose (WCAG 1.3.5), so browsers and\n * password managers fill the field: `name`, `email`, `username`,\n * `username webauthn` (offers passkeys in the field), `current-password`,\n * `new-password`, `one-time-code`, `tel`, `off` … Unset = no attribute.\n */\n readonly autocomplete = input<string>();\n\n /** Native `name` of the inner `<input>` (form posts, password managers). Unset = no attribute. */\n readonly name = input<string>();\n\n /**\n * Native `autocapitalize` for on-screen keyboards: `off` for addresses,\n * user names and codes, `words` for names. Unset = no attribute.\n */\n readonly autocapitalize = input<InputAutocapitalize>();\n\n /** Native `spellcheck`: `false` for names, addresses and codes. Unset = no attribute. */\n readonly spellcheck = input<boolean>();\n\n /** Native `enterkeyhint`: the label of the on-screen keyboard's Enter key. Unset = no attribute. */\n readonly enterkeyhint = input<InputEnterKeyHint>();\n\n /**\n * Deprecated, no effect since 3.12. The `*` is decorative and hidden from\n * assistive technology, because the native `required` state is announced\n * already, in the screen reader's language; a name on the `*` made the field\n * say \"required\" twice. Kept so existing bindings compile.\n * @deprecated No effect since 3.12: the native `required` state is announced instead.\n * @default 'required'\n */\n readonly requiredAriaLabel = input('required');\n\n /**\n * Id of the native `<input>`. The label's `for`, the error (`<id>-error`),\n * the helper text (`<id>-helper`), the label id (`<id>-label`) and\n * `aria-describedby` derive from it, so an error summary can link to the\n * field (`<a href=\"#contact-email\">`) and prerendered HTML is the same in\n * every build. Unique in the document, no spaces. Unset (or empty) = a\n * generated `lc-input-<n>`, which follows creation order (on the server it\n * keeps counting across prerendered routes): set it on prerendered pages.\n * @default generated (lc-input-<n>)\n */\n readonly controlId = input<string | undefined>(undefined);\n\n /**\n * Announce the error message the moment it appears (`role=\"alert\"` on the\n * message). Set `false` when an `lc-alert` error summary above the form\n * already announces the errors (a page re-rendered after a failed submit,\n * e.g. 422), so they aren't read twice. The message stays visible, stays\n * linked through `aria-describedby` (read with the field), and the control\n * keeps `aria-invalid`.\n * @default true\n */\n readonly announceError = input<boolean>(true);\n\n /**\n * Current value (two-way bindable: `[value]` / `[(value)]`). Emits\n * `valueChange` whenever it changes — once per user keystroke, on `clear()`\n * and when a bound form control writes a value.\n */\n readonly value = model<string>('');\n\n // Output Events\n /**\n * Emitted when input receives focus\n */\n readonly focused = output<void>();\n\n /**\n * Emitted when input loses focus\n */\n readonly blurred = output<void>();\n\n /**\n * Emitted when Enter key is pressed\n */\n readonly enterPressed = output<void>();\n\n // Internal state\n /** Generated id, taken once per instance (also with `controlId`), so later ids don't shift. */\n private readonly generatedId = `lc-input-${nextUniqueId++}`;\n\n private readonly resolvedId = computed(() => this.controlId() || this.generatedId);\n\n /**\n * Resolved id of the native control: `controlId`, or the generated\n * `lc-input-<n>`. Read-only, same meaning as before 3.12.\n */\n get inputId(): string {\n return this.resolvedId();\n }\n\n // ViewChild reference\n private readonly inputElement = viewChild<ElementRef<HTMLInputElement>>('inputRef');\n private readonly readonlyValueElement = viewChild<ElementRef<HTMLElement>>('readonlyValueRef');\n\n // Internal disabled state (for ControlValueAccessor)\n private readonly _formDisabled = signal<boolean>(false);\n\n // ControlValueAccessor callbacks\n private onChange: (value: string) => void = () => { /* set by registerOnChange */ };\n private onTouched: () => void = () => { /* set by registerOnTouched */ };\n\n /** The read-only value is shown as wrapping text (SI-10). */\n protected readonly wrapsReadonlyValue = computed(() => this.readonly() && this.readonlyWrap());\n\n /** `aria-describedby`: only the texts that are rendered (the error replaces the helper text). */\n protected readonly describedBy = computed(() => {\n if (this.error()) return `${this.inputId}-error`;\n if (this.helperText()) return `${this.inputId}-helper`;\n return null;\n });\n\n /** Screen-reader text of the character count: empty until the limit is near. */\n protected readonly charCountAnnouncement = computed(() => {\n const max = this.maxLength();\n if (!this.showCharCount() || !max) return '';\n const remaining = Math.max(0, max - this.value().length);\n const threshold = this.charCountAnnounceThreshold() ?? Math.max(1, Math.ceil(max * 0.1));\n if (remaining > threshold) return '';\n return this.charCountRemainingLabel().replace('{remaining}', String(remaining));\n });\n\n /**\n * Computed disabled state from both input and form control\n */\n protected get isDisabled(): boolean {\n return this.disabled() || this._formDisabled();\n }\n\n /**\n * Gets current character count\n */\n protected get charCount(): number {\n return this.value().length;\n }\n\n /**\n * Determines if error state should be shown\n */\n protected get hasError(): boolean {\n return !!this.error();\n }\n\n /**\n * Programmatically focus the input (the visible value while `readonlyWrap` applies)\n */\n public focus(): void {\n if (this.wrapsReadonlyValue()) {\n this.readonlyValueElement()?.nativeElement.focus();\n return;\n }\n this.inputElement()?.nativeElement.focus();\n }\n\n /**\n * Programmatically select input text\n */\n public select(): void {\n const shown = this.wrapsReadonlyValue() ? this.readonlyValueElement()?.nativeElement : undefined;\n if (shown) {\n const selection = shown.ownerDocument.getSelection();\n const range = shown.ownerDocument.createRange();\n range.selectNodeContents(shown);\n selection?.removeAllRanges();\n selection?.addRange(range);\n return;\n }\n this.inputElement()?.nativeElement.select();\n }\n\n /**\n * Clear the input value\n */\n public clear(): void {\n this.value.set('');\n this.onChange('');\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n this.value.set(value || '');\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._formDisabled.set(isDisabled);\n }\n\n /**\n * Handles input value changes\n */\n protected onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n const newValue = target.value;\n // model.set() emits `valueChange` exactly once per actual change\n this.value.set(newValue);\n this.onChange(newValue);\n }\n\n /**\n * Handles input focus\n */\n protected onFocus(): void {\n this.focused.emit();\n }\n\n /**\n * Handles input blur\n */\n protected onBlur(): void {\n this.onTouched();\n this.blurred.emit();\n }\n\n /**\n * Handles keydown events\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.enterPressed.emit();\n }\n }\n}\n","<div class=\"input-wrapper\">\n <!-- Label -->\n @if (label()) {\n <!-- No whitespace before the *: the gap is its margin, and it never wraps onto a line alone -->\n <label [id]=\"inputId + '-label'\" [attr.for]=\"wrapsReadonlyValue() ? null : inputId\" class=\"input-label\">\n {{ label() }}@if (required() && requiredIndicator()) {<span class=\"required-indicator\" aria-hidden=\"true\">*</span>}\n </label>\n }\n\n <!-- Input Container -->\n <div\n class=\"input-container\"\n [class.input-xs]=\"size() === 'xs'\"\n [class.input-sm]=\"size() === 'sm'\"\n [class.input-md]=\"size() === 'md'\"\n [class.input-lg]=\"size() === 'lg'\"\n [class.input-invalid]=\"hasError\"\n [class.input-disabled]=\"isDisabled\"\n [class.input-readonly]=\"readonly()\"\n [class.input-readonly-wrap]=\"wrapsReadonlyValue()\"\n >\n <!-- Icon Before -->\n @if (iconBefore()) {\n <span class=\"input-icon input-icon-before\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconBefore()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n\n <!-- Read-only value that wraps (SI-10): a read-only textbox named by the label -->\n @if (wrapsReadonlyValue()) {\n <div\n #readonlyValueRef\n class=\"input-field input-readonly-value\"\n role=\"textbox\"\n aria-readonly=\"true\"\n tabindex=\"0\"\n [attr.aria-labelledby]=\"label() ? inputId + '-label' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n >{{ value() }}</div>\n }\n\n <!-- Input Element (hidden while the read-only value wraps; it keeps value, name and autocomplete) -->\n <input\n #inputRef\n [id]=\"inputId\"\n [type]=\"type()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [hidden]=\"wrapsReadonlyValue()\"\n [attr.maxlength]=\"maxLength() || null\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.name]=\"name() ?? null\"\n [attr.autocapitalize]=\"autocapitalize() ?? null\"\n [attr.spellcheck]=\"spellcheck() === undefined ? null : spellcheck() ? 'true' : 'false'\"\n [attr.enterkeyhint]=\"enterkeyhint() ?? null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-required]=\"required() || undefined\"\n [attr.aria-invalid]=\"hasError || undefined\"\n [attr.aria-describedby]=\"describedBy()\"\n class=\"input-field\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <!-- Icon After -->\n @if (iconAfter()) {\n <span class=\"input-icon input-icon-after\" aria-hidden=\"true\">\n <lc-icon [name]=\"iconAfter()!\" size=\"sm\" [decorative]=\"true\" />\n </span>\n }\n </div>\n\n <!-- Helper Text / Error Message / Character Count -->\n @if (error() || helperText() || (showCharCount() && maxLength())) {\n <div class=\"input-footer\">\n <!-- Error Message -->\n @if (error()) {\n <p [id]=\"inputId + '-error'\" class=\"input-error\" [attr.role]=\"announceError() ? 'alert' : null\">\n {{ error() }}\n </p>\n }\n\n <!-- Helper Text -->\n @if (helperText() && !error()) {\n <p [id]=\"inputId + '-helper'\" class=\"input-helper\">\n {{ helperText() }}\n </p>\n }\n\n <!-- Character Count: always visible; spoken only near the limit (live region below) -->\n @if (showCharCount() && maxLength()) {\n <p class=\"char-count\">\n {{ charCount }} / {{ maxLength() }}\n </p>\n }\n </div>\n }\n\n @if (showCharCount() && maxLength()) {\n <span class=\"input-char-count-live\" aria-live=\"polite\">{{ charCountAnnouncement() }}</span>\n }\n</div>\n"],"mappings":"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"}
|