@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.16.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.16.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,EAAqB,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAC/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;AAUhE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWpE;AAED,qBAaa,iBAAkB,YAAW,oBAAoB;IAC5D,SAAgB,UAAU,8DAA4C;IACtE,SAAgB,IAAI,wDAAiC;IACrD,SAAgB,IAAI,wDAAsC;IAC1D,SAAgB,SAAS,8EAEtB;IAEH,SAAgB,eAAe,qDAA8B;IAC7D,SAAgB,WAAW,yFAExB;IACH,SAAgB,SAAS,qDAA8B;IACvD,SAAgB,cAAc,qDAA8B;IAC5D,SAAgB,YAAY,yFAEzB;IACH,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;IACnD,SAAgB,KAAK,qDAA8B;IAEnD,SAAgB,WAAW,mDAAoB;IAC/C,SAAgB,UAAU,kDAAqC;IAC/D,SAAgB,SAAS,uDAAyC;IAElE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,SAAS,CAAwB;IAGzC,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;IAED,SAAS,KAAK,cAAc,IAAI,MAAM,CAGrC;IAED,SAAS,KAAK,iBAAiB,IAAI,OAAO,CAEzC;IAEM,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKhC,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;IAI3C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAiB7B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKtC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;CAG9E"}
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 normalizeStringValue(value) {
8
- if (value === undefined || value === null) {
7
+ function normalizeAttr(value) {
8
+ if (value === undefined || value === null)
9
9
  return null;
10
- }
11
- return value;
10
+ const v = value.trim();
11
+ return v.length > 0 ? v : null;
12
12
  }
13
- export function readTngInputEventValue(event) {
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
- usingCva = false;
60
- onChange = () => { };
61
- onTouched = () => { };
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 value = this.usingCva ? this.cvaValue : this.value();
77
- return value ?? '';
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 = typeof value === 'string' ? value : value == null ? null : String(value);
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 value = readTngInputEventValue(event);
97
- if (value === null) {
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 = value;
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
- this.onChange(value);
104
- this.valueChange.emit(value);
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 normalizeStringValue(value);
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}"]}