@tailng-ui/components 0.16.0 → 0.17.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/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailng-ui/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/tailng/tailng-ui"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@tailng-ui/primitives": "^0.
|
|
10
|
+
"@tailng-ui/primitives": "^0.19.0"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@angular/core": "^21.1.0",
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { ControlValueAccessor } from '@angular/forms';
|
|
1
|
+
import type { ControlValueAccessor } from '@angular/forms';
|
|
2
2
|
import { type TngInputType } from '@tailng-ui/primitives';
|
|
3
3
|
import { type TngFormFieldAppearance, type TngFormFieldSize, type TngFormFieldTone } from '../form-field/tng-form-field.component';
|
|
4
4
|
type NullableBooleanInput = boolean | null | string | undefined;
|
|
5
|
-
export declare function readTngInputEventValue(event: unknown): string | null;
|
|
6
5
|
export declare class TngInputComponent implements ControlValueAccessor {
|
|
7
6
|
readonly appearance: import("@angular/core").InputSignal<TngFormFieldAppearance>;
|
|
8
7
|
readonly size: import("@angular/core").InputSignal<TngFormFieldSize>;
|
|
@@ -21,13 +20,17 @@ export declare class TngInputComponent implements ControlValueAccessor {
|
|
|
21
20
|
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
|
|
22
21
|
readonly required: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
|
|
23
22
|
readonly type: import("@angular/core").InputSignal<TngInputType>;
|
|
23
|
+
/**
|
|
24
|
+
* Controlled value input (only used when NOT using CVA).
|
|
25
|
+
* If you bind [value], you should also listen to (valueChange) (or use signals).
|
|
26
|
+
*/
|
|
24
27
|
readonly value: import("@angular/core").InputSignal<string | null>;
|
|
25
28
|
readonly valueChange: import("@angular/core").OutputEmitterRef<string>;
|
|
26
29
|
readonly inputEvent: import("@angular/core").OutputEmitterRef<Event>;
|
|
27
30
|
readonly blurEvent: import("@angular/core").OutputEmitterRef<FocusEvent>;
|
|
31
|
+
private usingCva;
|
|
28
32
|
private cvaValue;
|
|
29
33
|
private cvaDisabled;
|
|
30
|
-
private usingCva;
|
|
31
34
|
private onChange;
|
|
32
35
|
private onTouched;
|
|
33
36
|
protected readonly dataSlot: "input-component";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-input.component.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/components/src/lib/form/input/tng-input.component.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"tng-input.component.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/components/src/lib/form/input/tng-input.component.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAG1D,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,wCAAwC,CAAC;AAEhD,KAAK,oBAAoB,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAehE,qBAca,iBAAkB,YAAW,oBAAoB;IAE5D,SAAgB,UAAU,8DAA4C;IACtE,SAAgB,IAAI,wDAAiC;IACrD,SAAgB,IAAI,wDAAsC;IAC1D,SAAgB,SAAS,8EAEtB;IAGH,SAAgB,eAAe,qDAA8B;IAC7D,SAAgB,WAAW,yFAExB;IACH,SAAgB,SAAS,qDAA8B;IACvD,SAAgB,cAAc,qDAA8B;IAC5D,SAAgB,YAAY,yFAEzB;IAEH,SAAgB,YAAY,qDAA8B;IAC1D,SAAgB,QAAQ,8EAErB;IACH,SAAgB,EAAE,qDAA8B;IAChD,SAAgB,IAAI,qDAA8B;IAClD,SAAgB,WAAW,qDAA8B;IACzD,SAAgB,QAAQ,8EAErB;IACH,SAAgB,QAAQ,8EAErB;IACH,SAAgB,IAAI,oDAA+B;IAEnD;;;OAGG;IACH,SAAgB,KAAK,qDAA8B;IAGnD,SAAgB,WAAW,mDAAoB;IAC/C,SAAgB,UAAU,kDAAqC;IAC/D,SAAgB,SAAS,uDAAyC;IAGlE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,SAAS,CAA+B;IAIhD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,iBAAiB,CAAU;IAGzD,SAAS,KAAK,cAAc,IAAI,sBAAsB,CAErD;IAGD,SAAS,KAAK,QAAQ,IAAI,gBAAgB,CAEzC;IAGD,SAAS,KAAK,QAAQ,IAAI,gBAAgB,CAEzC;IAGD,SAAS,KAAK,aAAa,IAAI,EAAE,GAAG,IAAI,CAEvC;IAGD,SAAS,KAAK,cAAc,IAAI,MAAM,CAGrC;IAED,SAAS,KAAK,iBAAiB,IAAI,OAAO,CAEzC;IAGM,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAUhC,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAInD,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IAIvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAK3C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IA0B7B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKtC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;CAG9E"}
|
|
@@ -4,29 +4,29 @@ import { booleanAttribute } from '@angular/core';
|
|
|
4
4
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
5
|
import { coerceTngInputNullableBoolean, TngInput, } from '@tailng-ui/primitives';
|
|
6
6
|
import { TngFormFieldComponent, } from '../form-field/tng-form-field.component';
|
|
7
|
-
function
|
|
8
|
-
if (value === undefined || value === null)
|
|
7
|
+
function normalizeAttr(value) {
|
|
8
|
+
if (value === undefined || value === null)
|
|
9
9
|
return null;
|
|
10
|
-
|
|
11
|
-
return
|
|
10
|
+
const v = value.trim();
|
|
11
|
+
return v.length > 0 ? v : null;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
if (!(event instanceof Event))
|
|
13
|
+
function readInputValue(event) {
|
|
14
|
+
if (!(event instanceof Event))
|
|
15
15
|
return null;
|
|
16
|
-
}
|
|
17
16
|
const target = event.target;
|
|
18
|
-
if (!(target instanceof HTMLInputElement))
|
|
17
|
+
if (!(target instanceof HTMLInputElement))
|
|
19
18
|
return null;
|
|
20
|
-
}
|
|
21
19
|
return target.value;
|
|
22
20
|
}
|
|
23
21
|
let TngInputComponent = class TngInputComponent {
|
|
22
|
+
// ---- Wrapper (form-field) appearance knobs ----
|
|
24
23
|
appearance = input('outline');
|
|
25
24
|
size = input('md');
|
|
26
25
|
tone = input('neutral');
|
|
27
26
|
fullWidth = input(true, {
|
|
28
27
|
transform: booleanAttribute,
|
|
29
28
|
});
|
|
29
|
+
// ---- Input API passthrough ----
|
|
30
30
|
ariaDescribedBy = input(null);
|
|
31
31
|
ariaInvalid = input(null, {
|
|
32
32
|
transform: coerceTngInputNullableBoolean,
|
|
@@ -50,15 +50,22 @@ let TngInputComponent = class TngInputComponent {
|
|
|
50
50
|
transform: booleanAttribute,
|
|
51
51
|
});
|
|
52
52
|
type = input('text');
|
|
53
|
+
/**
|
|
54
|
+
* Controlled value input (only used when NOT using CVA).
|
|
55
|
+
* If you bind [value], you should also listen to (valueChange) (or use signals).
|
|
56
|
+
*/
|
|
53
57
|
value = input(null);
|
|
58
|
+
// ---- Outputs ----
|
|
54
59
|
valueChange = output();
|
|
55
60
|
inputEvent = output({ alias: 'input' });
|
|
56
61
|
blurEvent = output({ alias: 'blur' });
|
|
62
|
+
// ---- CVA state ----
|
|
63
|
+
usingCva = false;
|
|
57
64
|
cvaValue = null;
|
|
58
65
|
cvaDisabled = false;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
onChange = () => undefined;
|
|
67
|
+
onTouched = () => undefined;
|
|
68
|
+
// ---- Host attrs (optional, useful for styling/debug) ----
|
|
62
69
|
dataSlot = 'input-component';
|
|
63
70
|
get dataAppearance() {
|
|
64
71
|
return this.appearance();
|
|
@@ -72,16 +79,23 @@ let TngInputComponent = class TngInputComponent {
|
|
|
72
79
|
get dataFullWidth() {
|
|
73
80
|
return this.fullWidth() ? '' : null;
|
|
74
81
|
}
|
|
82
|
+
// ---- Derived values for template ----
|
|
75
83
|
get effectiveValue() {
|
|
76
|
-
const
|
|
77
|
-
return
|
|
84
|
+
const v = this.usingCva ? this.cvaValue : this.value();
|
|
85
|
+
return v ?? '';
|
|
78
86
|
}
|
|
79
87
|
get effectiveDisabled() {
|
|
80
88
|
return this.cvaDisabled || this.disabled();
|
|
81
89
|
}
|
|
90
|
+
// ---- CVA ----
|
|
82
91
|
writeValue(value) {
|
|
83
92
|
this.usingCva = true;
|
|
84
|
-
this.cvaValue =
|
|
93
|
+
this.cvaValue =
|
|
94
|
+
typeof value === 'string'
|
|
95
|
+
? value
|
|
96
|
+
: value == null
|
|
97
|
+
? null
|
|
98
|
+
: String(value);
|
|
85
99
|
}
|
|
86
100
|
registerOnChange(fn) {
|
|
87
101
|
this.onChange = fn;
|
|
@@ -92,16 +106,27 @@ let TngInputComponent = class TngInputComponent {
|
|
|
92
106
|
setDisabledState(isDisabled) {
|
|
93
107
|
this.cvaDisabled = isDisabled;
|
|
94
108
|
}
|
|
109
|
+
// ---- DOM handlers ----
|
|
95
110
|
onInput(event) {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
111
|
+
const next = readInputValue(event);
|
|
112
|
+
if (next === null)
|
|
98
113
|
return;
|
|
99
|
-
|
|
114
|
+
// If disabled, ignore (optional safety)
|
|
115
|
+
if (this.effectiveDisabled)
|
|
116
|
+
return;
|
|
117
|
+
// Keep CVA in sync when used
|
|
100
118
|
if (this.usingCva) {
|
|
101
|
-
this.cvaValue
|
|
119
|
+
if (this.cvaValue === next) {
|
|
120
|
+
// Still forward the raw event output if you want:
|
|
121
|
+
if (event instanceof Event)
|
|
122
|
+
this.inputEvent.emit(event);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
this.cvaValue = next;
|
|
126
|
+
this.onChange(next);
|
|
102
127
|
}
|
|
103
|
-
|
|
104
|
-
this.valueChange.emit(
|
|
128
|
+
// For controlled-input usage, emit valueChange always
|
|
129
|
+
this.valueChange.emit(next);
|
|
105
130
|
if (event instanceof Event) {
|
|
106
131
|
this.inputEvent.emit(event);
|
|
107
132
|
}
|
|
@@ -111,7 +136,7 @@ let TngInputComponent = class TngInputComponent {
|
|
|
111
136
|
this.blurEvent.emit(event);
|
|
112
137
|
}
|
|
113
138
|
normalizeAttrValue(value) {
|
|
114
|
-
return
|
|
139
|
+
return normalizeAttr(value);
|
|
115
140
|
}
|
|
116
141
|
};
|
|
117
142
|
__decorate([
|
|
@@ -132,6 +157,7 @@ __decorate([
|
|
|
132
157
|
TngInputComponent = __decorate([
|
|
133
158
|
Component({
|
|
134
159
|
selector: 'tng-input',
|
|
160
|
+
standalone: true,
|
|
135
161
|
imports: [TngFormFieldComponent, TngInput],
|
|
136
162
|
templateUrl: './tng-input.component.html',
|
|
137
163
|
styleUrl: './tng-input.component.css',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-input.component.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/components/src/lib/form/input/tng-input.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n forwardRef,\n HostBinding,\n input,\n output,\n} from '@angular/core';\nimport { booleanAttribute } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport {\n coerceTngInputNullableBoolean,\n TngInput,\n type TngInputType,\n} from '@tailng-ui/primitives';\nimport {\n TngFormFieldComponent,\n type TngFormFieldAppearance,\n type TngFormFieldSize,\n type TngFormFieldTone,\n} from '../form-field/tng-form-field.component';\n\ntype NullableBooleanInput = boolean | null | string | undefined;\n\nfunction normalizeStringValue(value: string | null | undefined): string | null {\n if (value === undefined || value === null) {\n return null;\n }\n\n return value;\n}\n\nexport function readTngInputEventValue(event: unknown): string | null {\n if (!(event instanceof Event)) {\n return null;\n }\n\n const target = event.target;\n if (!(target instanceof HTMLInputElement)) {\n return null;\n }\n\n return target.value;\n}\n\n@Component({\n selector: 'tng-input',\n imports: [TngFormFieldComponent, TngInput],\n templateUrl: './tng-input.component.html',\n styleUrl: './tng-input.component.css',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => TngInputComponent),\n multi: true,\n },\n ],\n})\nexport class TngInputComponent implements ControlValueAccessor {\n public readonly appearance = input<TngFormFieldAppearance>('outline');\n public readonly size = input<TngFormFieldSize>('md');\n public readonly tone = input<TngFormFieldTone>('neutral');\n public readonly fullWidth = input<boolean, boolean | string>(true, {\n transform: booleanAttribute,\n });\n\n public readonly ariaDescribedBy = input<string | null>(null);\n public readonly ariaInvalid = input<boolean | null, NullableBooleanInput>(null, {\n transform: coerceTngInputNullableBoolean,\n });\n public readonly ariaLabel = input<string | null>(null);\n public readonly ariaLabelledby = input<string | null>(null);\n public readonly ariaRequired = input<boolean | null, NullableBooleanInput>(null, {\n transform: coerceTngInputNullableBoolean,\n });\n public readonly autocomplete = input<string | null>(null);\n public readonly disabled = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly id = input<string | null>(null);\n public readonly name = input<string | null>(null);\n public readonly placeholder = input<string | null>(null);\n public readonly readonly = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly required = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly type = input<TngInputType>('text');\n public readonly value = input<string | null>(null);\n\n public readonly valueChange = output<string>();\n public readonly inputEvent = output<Event>({ alias: 'input' });\n public readonly blurEvent = output<FocusEvent>({ alias: 'blur' });\n\n private cvaValue: string | null = null;\n private cvaDisabled = false;\n private usingCva = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'input-component' as const;\n\n @HostBinding('attr.data-appearance')\n protected get dataAppearance(): TngFormFieldAppearance {\n return this.appearance();\n }\n\n @HostBinding('attr.data-size')\n protected get dataSize(): TngFormFieldSize {\n return this.size();\n }\n\n @HostBinding('attr.data-tone')\n protected get dataTone(): TngFormFieldTone {\n return this.tone();\n }\n\n @HostBinding('attr.data-full-width')\n protected get dataFullWidth(): '' | null {\n return this.fullWidth() ? '' : null;\n }\n\n protected get effectiveValue(): string {\n const value = this.usingCva ? this.cvaValue : this.value();\n return value ?? '';\n }\n\n protected get effectiveDisabled(): boolean {\n return this.cvaDisabled || this.disabled();\n }\n\n public writeValue(value: unknown): void {\n this.usingCva = true;\n this.cvaValue = typeof value === 'string' ? value : value == null ? null : String(value);\n }\n\n public registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled = isDisabled;\n }\n\n public onInput(event: unknown): void {\n const value = readTngInputEventValue(event);\n if (value === null) {\n return;\n }\n\n if (this.usingCva) {\n this.cvaValue = value;\n }\n\n this.onChange(value);\n this.valueChange.emit(value);\n if (event instanceof Event) {\n this.inputEvent.emit(event);\n }\n }\n\n public onBlur(event: FocusEvent): void {\n this.onTouched();\n this.blurEvent.emit(event);\n }\n\n protected normalizeAttrValue(value: string | null | undefined): string | null {\n return normalizeStringValue(value);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tng-input.component.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/components/src/lib/form/input/tng-input.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n forwardRef,\n HostBinding,\n input,\n output,\n} from '@angular/core';\nimport { booleanAttribute } from '@angular/core';\nimport type { ControlValueAccessor} from '@angular/forms';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport {\n coerceTngInputNullableBoolean,\n TngInput,\n type TngInputType,\n} from '@tailng-ui/primitives';\n\nimport {\n TngFormFieldComponent,\n type TngFormFieldAppearance,\n type TngFormFieldSize,\n type TngFormFieldTone,\n} from '../form-field/tng-form-field.component';\n\ntype NullableBooleanInput = boolean | null | string | undefined;\n\nfunction normalizeAttr(value: string | null | undefined): string | null {\n if (value === undefined || value === null) return null;\n const v = value.trim();\n return v.length > 0 ? v : null;\n}\n\nfunction readInputValue(event: unknown): string | null {\n if (!(event instanceof Event)) return null;\n const target = event.target;\n if (!(target instanceof HTMLInputElement)) return null;\n return target.value;\n}\n\n@Component({\n selector: 'tng-input',\n standalone: true,\n imports: [TngFormFieldComponent, TngInput],\n templateUrl: './tng-input.component.html',\n styleUrl: './tng-input.component.css',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => TngInputComponent),\n multi: true,\n },\n ],\n})\nexport class TngInputComponent implements ControlValueAccessor {\n // ---- Wrapper (form-field) appearance knobs ----\n public readonly appearance = input<TngFormFieldAppearance>('outline');\n public readonly size = input<TngFormFieldSize>('md');\n public readonly tone = input<TngFormFieldTone>('neutral');\n public readonly fullWidth = input<boolean, boolean | string>(true, {\n transform: booleanAttribute,\n });\n\n // ---- Input API passthrough ----\n public readonly ariaDescribedBy = input<string | null>(null);\n public readonly ariaInvalid = input<boolean | null, NullableBooleanInput>(null, {\n transform: coerceTngInputNullableBoolean,\n });\n public readonly ariaLabel = input<string | null>(null);\n public readonly ariaLabelledby = input<string | null>(null);\n public readonly ariaRequired = input<boolean | null, NullableBooleanInput>(null, {\n transform: coerceTngInputNullableBoolean,\n });\n\n public readonly autocomplete = input<string | null>(null);\n public readonly disabled = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly id = input<string | null>(null);\n public readonly name = input<string | null>(null);\n public readonly placeholder = input<string | null>(null);\n public readonly readonly = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly required = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n public readonly type = input<TngInputType>('text');\n\n /**\n * Controlled value input (only used when NOT using CVA).\n * If you bind [value], you should also listen to (valueChange) (or use signals).\n */\n public readonly value = input<string | null>(null);\n\n // ---- Outputs ----\n public readonly valueChange = output<string>();\n public readonly inputEvent = output<Event>({ alias: 'input' });\n public readonly blurEvent = output<FocusEvent>({ alias: 'blur' });\n\n // ---- CVA state ----\n private usingCva = false;\n private cvaValue: string | null = null;\n private cvaDisabled = false;\n\n private onChange: (value: string) => void = () => undefined;\n private onTouched: () => void = () => undefined;\n\n // ---- Host attrs (optional, useful for styling/debug) ----\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'input-component' as const;\n\n @HostBinding('attr.data-appearance')\n protected get dataAppearance(): TngFormFieldAppearance {\n return this.appearance();\n }\n\n @HostBinding('attr.data-size')\n protected get dataSize(): TngFormFieldSize {\n return this.size();\n }\n\n @HostBinding('attr.data-tone')\n protected get dataTone(): TngFormFieldTone {\n return this.tone();\n }\n\n @HostBinding('attr.data-full-width')\n protected get dataFullWidth(): '' | null {\n return this.fullWidth() ? '' : null;\n }\n\n // ---- Derived values for template ----\n protected get effectiveValue(): string {\n const v = this.usingCva ? this.cvaValue : this.value();\n return v ?? '';\n }\n\n protected get effectiveDisabled(): boolean {\n return this.cvaDisabled || this.disabled();\n }\n\n // ---- CVA ----\n public writeValue(value: unknown): void {\n this.usingCva = true;\n this.cvaValue =\n typeof value === 'string'\n ? value\n : value == null\n ? null\n : String(value);\n }\n\n public registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled = isDisabled;\n }\n\n // ---- DOM handlers ----\n public onInput(event: unknown): void {\n const next = readInputValue(event);\n if (next === null) return;\n\n // If disabled, ignore (optional safety)\n if (this.effectiveDisabled) return;\n\n // Keep CVA in sync when used\n if (this.usingCva) {\n if (this.cvaValue === next) {\n // Still forward the raw event output if you want:\n if (event instanceof Event) this.inputEvent.emit(event);\n return;\n }\n this.cvaValue = next;\n this.onChange(next);\n }\n\n // For controlled-input usage, emit valueChange always\n this.valueChange.emit(next);\n\n if (event instanceof Event) {\n this.inputEvent.emit(event);\n }\n }\n\n public onBlur(event: FocusEvent): void {\n this.onTouched();\n this.blurEvent.emit(event);\n }\n\n protected normalizeAttrValue(value: string | null | undefined): string | null {\n return normalizeAttr(value);\n }\n}"]}
|