@kinetixui/angular 0.24.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.
@@ -0,0 +1,801 @@
1
+ import * as i0 from '@angular/core';
2
+ import { ElementRef } from '@angular/core';
3
+ import { ControlValueAccessor } from '@angular/forms';
4
+
5
+ /**
6
+ * The shared design contract, in Angular's type system.
7
+ *
8
+ * These unions are the same variant and size names the React, SwiftUI, Jetpack Compose and Flutter
9
+ * implementations use. That is what "parity" means in KinetixUI: the contract and the tokens are shared, the
10
+ * implementation is idiomatic per platform. Renaming one of these values is a cross-platform change, not an
11
+ * Angular one.
12
+ */
13
+ /** Button fills. Capitalised to match the design source's own Variant property, as every other platform does. */
14
+ type KxButtonVariant = 'Primary' | 'Secondary' | 'Outline' | 'Destructive' | 'Ghost' | 'Link';
15
+ type KxButtonSize = 'sm' | 'md' | 'lg' | 'icon';
16
+ /** Corner style — matches the design source's Corners property. */
17
+ type KxCorners = 'sharp' | 'default' | 'pill';
18
+ type KxBadgeVariant = 'default' | 'secondary' | 'outline' | 'destructive' | 'success' | 'warning';
19
+ type KxAlertVariant = 'default' | 'destructive' | 'success' | 'warning' | 'info';
20
+ type KxOrientation = 'horizontal' | 'vertical';
21
+ type KxSpinnerSize = 'sm' | 'md' | 'lg';
22
+ type KxSpinnerVariant = 'default' | 'muted' | 'onColor';
23
+ type KxTagVariant = 'default' | 'secondary' | 'destructive' | 'warning' | 'outline';
24
+ /** Direction of change on a metric. `neutral` is "measured, and flat" — not "unknown". */
25
+ type KxTrend = 'up' | 'down' | 'neutral';
26
+ type KxEmptyMediaVariant = 'default' | 'icon';
27
+ type KxToggleVariant = 'default' | 'outline';
28
+ type KxToggleSize = 'sm' | 'md' | 'lg';
29
+ /** Tone of the text under a field. `error` is the only one that also sets `aria-invalid` on the control. */
30
+ type KxFieldMessageVariant = 'error' | 'success' | 'warning' | 'info';
31
+
32
+ /**
33
+ * KinetixUI button.
34
+ *
35
+ * <button kxButton>Save</button>
36
+ * <button kxButton variant="Outline" size="lg">Cancel</button>
37
+ * <a kxButton variant="Link" href="/docs">Docs</a>
38
+ *
39
+ * A directive on a real `<button>` or `<a>`, not a `<kx-button>` wrapper. That is the idiomatic Angular choice
40
+ * and the accessible one: the element keeps its own role, its `type`, `disabled`, form submission, focus order
41
+ * and the browser's own activation behaviour, so none of it has to be re-implemented with ARIA. §28 of the
42
+ * house rules — native semantics before ARIA — is the reason, not convenience.
43
+ *
44
+ * A disabled anchor is not a thing in HTML, so the anchor form is disabled with `aria-disabled` plus the
45
+ * stylesheet's `pointer-events: none`; callers should also drop `href`. The directive does not silently rewrite
46
+ * an anchor into a button.
47
+ */
48
+ declare class KxButton {
49
+ readonly variant: i0.InputSignal<KxButtonVariant>;
50
+ readonly size: i0.InputSignal<KxButtonSize>;
51
+ readonly corners: i0.InputSignal<KxCorners>;
52
+ protected readonly classes: i0.Signal<string>;
53
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxButton, never>;
54
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxButton, "button[kxButton], a[kxButton]", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "corners": { "alias": "corners"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
55
+ }
56
+
57
+ /**
58
+ * The presentational primitives: badge, card family, label, input, separator, progress and alert.
59
+ *
60
+ * Each is either a directive on the element HTML already has for the job (label, input) or a component that
61
+ * renders one (badge, card, alert). Nothing here invents a role the platform already provides.
62
+ */
63
+ /**
64
+ * <kx-badge>New</kx-badge>
65
+ * <kx-badge variant="success">Synced</kx-badge>
66
+ *
67
+ * Presentational by default. A badge that conveys a status change the user must be told about should be given
68
+ * a live region by the caller — this does not guess, because a wrong `aria-live` is worse than none.
69
+ */
70
+ declare class KxBadge {
71
+ readonly variant: i0.InputSignal<KxBadgeVariant>;
72
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxBadge, never>;
73
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxBadge, "kx-badge", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
74
+ }
75
+ declare class KxCard {
76
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCard, never>;
77
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCard, "kx-card", never, {}, {}, never, ["*"], true, never>;
78
+ }
79
+ declare class KxCardHeader {
80
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCardHeader, never>;
81
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCardHeader, "kx-card-header", never, {}, {}, never, ["*"], true, never>;
82
+ }
83
+ /**
84
+ * A real heading, at a level the page chooses. `level` exists because a card's title is only an `<h3>` in the
85
+ * example — in a page that already has an `<h3>` the right level is whatever keeps the document outline
86
+ * correct, and a component that hard-codes one produces broken heading structure at scale.
87
+ *
88
+ * The level is carried by `role="heading"` + `aria-level` on the host rather than by switching between `<h1>`
89
+ * … `<h6>` tags. That is not a shortcut: `<ng-content>` projects its content exactly once, so a template with
90
+ * a heading tag per branch silently renders an empty heading for every branch after the first. Between a real
91
+ * tag that loses its text and an ARIA heading that keeps it, the accessible answer is the one with the text in
92
+ * it — and `role="heading"` with an explicit level is fully supported.
93
+ */
94
+ declare class KxCardTitle {
95
+ readonly level: i0.InputSignal<1 | 2 | 3 | 4 | 5 | 6>;
96
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCardTitle, never>;
97
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCardTitle, "kx-card-title", never, { "level": { "alias": "level"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
98
+ }
99
+ declare class KxCardDescription {
100
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCardDescription, never>;
101
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCardDescription, "kx-card-description", never, {}, {}, never, ["*"], true, never>;
102
+ }
103
+ declare class KxCardContent {
104
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCardContent, never>;
105
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCardContent, "kx-card-content", never, {}, {}, never, ["*"], true, never>;
106
+ }
107
+ declare class KxCardFooter {
108
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCardFooter, never>;
109
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCardFooter, "kx-card-footer", never, {}, {}, never, ["*"], true, never>;
110
+ }
111
+ /**
112
+ * <label kxLabel for="email">Email</label>
113
+ *
114
+ * A directive on a real `<label>`, so `for`/`id` association and click-to-focus are the browser's, not ours.
115
+ */
116
+ declare class KxLabel {
117
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxLabel, never>;
118
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxLabel, "label[kxLabel]", never, {}, {}, never, never, true, never>;
119
+ }
120
+ /**
121
+ * <input kxInput type="email" [(ngModel)]="email" />
122
+ *
123
+ * A directive, so `type`, `required`, `disabled`, autofill, the browser's own validation and every Angular
124
+ * forms directive keep working untouched. The error state is read from `aria-invalid`, which means the
125
+ * semantics drive the styling rather than a parallel `invalid` input that could disagree with them.
126
+ *
127
+ * Multi-line fields are `kxTextarea`, not this: a textarea has its own minimum height and resize affordance,
128
+ * and the React package splits them for the same reason.
129
+ */
130
+ declare class KxInput {
131
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxInput, never>;
132
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxInput, "input[kxInput]", never, {}, {}, never, never, true, never>;
133
+ }
134
+ /**
135
+ * <kx-separator />
136
+ * <kx-separator orientation="vertical" />
137
+ *
138
+ * Decorative by default and therefore hidden from assistive technology, which is what a rule between two
139
+ * visually grouped things usually is. Set `[decorative]="false"` to expose it as a real `separator`.
140
+ */
141
+ declare class KxSeparator {
142
+ readonly orientation: i0.InputSignal<KxOrientation>;
143
+ readonly decorative: i0.InputSignal<boolean>;
144
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSeparator, never>;
145
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSeparator, "kx-separator", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "decorative": { "alias": "decorative"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
146
+ }
147
+ /**
148
+ * <kx-progress [value]="62" />
149
+ * <kx-progress [value]="null" /> <!-- indeterminate -->
150
+ *
151
+ * A real `progressbar`. `value` is null for indeterminate, which drops `aria-valuenow` — the correct way to
152
+ * say "in progress, amount unknown", rather than reporting a fake 0.
153
+ */
154
+ declare class KxProgress {
155
+ readonly value: i0.InputSignal<number>;
156
+ readonly max: i0.InputSignal<number>;
157
+ /** Announced instead of the raw percentage when the number alone would not mean anything ("3 of 7 files"). */
158
+ readonly valueText: i0.InputSignal<string>;
159
+ protected readonly percent: i0.Signal<number>;
160
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxProgress, never>;
161
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxProgress, "kx-progress", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
162
+ }
163
+ /**
164
+ * <kx-alert variant="destructive">
165
+ * <kx-alert-title>Payment failed</kx-alert-title>
166
+ * <kx-alert-description>Your card was declined.</kx-alert-description>
167
+ * </kx-alert>
168
+ *
169
+ * `role` defaults to `alert` only for the variants that carry urgency. A neutral informational panel announced
170
+ * as an assertive live region interrupts a screen-reader user for no reason, so `default` and `info` render as
171
+ * a plain region and the caller can opt in.
172
+ */
173
+ declare class KxAlert {
174
+ readonly variant: i0.InputSignal<KxAlertVariant>;
175
+ protected readonly role: i0.Signal<"alert" | "note">;
176
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAlert, never>;
177
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAlert, "kx-alert", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
178
+ }
179
+ declare class KxAlertTitle {
180
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAlertTitle, never>;
181
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAlertTitle, "kx-alert-title", never, {}, {}, never, ["*"], true, never>;
182
+ }
183
+ declare class KxAlertDescription {
184
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAlertDescription, never>;
185
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAlertDescription, "kx-alert-description", never, {}, {}, never, ["*"], true, never>;
186
+ }
187
+
188
+ /**
189
+ * Checkbox and Switch — the two binary controls, and the package's forms architecture in miniature.
190
+ *
191
+ * Both implement `ControlValueAccessor`, so they work with `[(ngModel)]`, `formControlName` and
192
+ * `formControl` exactly like a native input, including `disabled` driven by the form model
193
+ * (`setDisabledState`) rather than only by an attribute. Both also expose a plain `[(checked)]` model for
194
+ * applications that are not using Angular forms; the two paths write through the same setter so they cannot
195
+ * disagree.
196
+ *
197
+ * Both render a real `<button>` carrying the ARIA role rather than a visually-hidden `<input>`. A button is
198
+ * already focusable, already activates on Space and Enter, and already reports `disabled` to assistive
199
+ * technology — so the role is the only thing ARIA has to add. The trade-off is deliberate and worth stating:
200
+ * a `<button role="checkbox">` submits no value in a native (non-Angular) form post. Angular forms carry the
201
+ * value in the form model, which is how these are meant to be used.
202
+ */
203
+ /**
204
+ * Shared CVA plumbing: the parts that would otherwise be copied verbatim into both controls.
205
+ *
206
+ * `@Directive()` with no selector, not a plain class — `input()`, `model()` and `output()` are only legal on a
207
+ * class Angular's compiler knows about, so an undecorated base would fail the build with NG8110.
208
+ */
209
+ declare abstract class KxToggleBase implements ControlValueAccessor {
210
+ readonly checked: i0.ModelSignal<boolean>;
211
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
212
+ /**
213
+ * Emits only on real user interaction. `checkedChange` (from the model) also fires when a form or a parent
214
+ * writes the value in, which is usually not what a caller reacting to "the user flipped this" wants.
215
+ */
216
+ readonly toggled: i0.OutputEmitterRef<boolean>;
217
+ /** `disabled` can come from the input OR from the form model — either one disables the control. */
218
+ protected readonly formDisabled: i0.WritableSignal<boolean>;
219
+ protected isDisabled(): boolean;
220
+ private onChange;
221
+ private onTouched;
222
+ protected toggle(): void;
223
+ writeValue(value: boolean): void;
224
+ registerOnChange(fn: (value: boolean) => void): void;
225
+ registerOnTouched(fn: () => void): void;
226
+ setDisabledState(isDisabled: boolean): void;
227
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxToggleBase, never>;
228
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxToggleBase, never, never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "toggled": "toggled"; }, never, never, true, never>;
229
+ }
230
+ /**
231
+ * <kx-checkbox [(ngModel)]="remember" />
232
+ * <kx-checkbox [(checked)]="remember" (toggled)="save($event)" />
233
+ *
234
+ * `indeterminate` renders `aria-checked="mixed"` — the tri-state a "select all" header needs. It is display
235
+ * only: activating an indeterminate checkbox resolves it to checked, as it does everywhere else.
236
+ */
237
+ declare class KxCheckbox extends KxToggleBase {
238
+ readonly indeterminate: i0.InputSignalWithTransform<boolean, unknown>;
239
+ /** One of these is required when no visible `<label for>` points at the control. */
240
+ readonly ariaLabel: i0.InputSignal<string>;
241
+ readonly ariaLabelledby: i0.InputSignal<string>;
242
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxCheckbox, never>;
243
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxCheckbox, "kx-checkbox", never, { "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
244
+ }
245
+ /**
246
+ * <kx-switch [(ngModel)]="notifications" aria-label="Notifications" />
247
+ *
248
+ * `role="switch"` rather than a checkbox: it reports "on/off" instead of "checked", which is what an
249
+ * immediately-applied setting is.
250
+ */
251
+ declare class KxSwitch extends KxToggleBase {
252
+ readonly ariaLabel: i0.InputSignal<string>;
253
+ readonly ariaLabelledby: i0.InputSignal<string>;
254
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSwitch, never>;
255
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSwitch, "kx-switch", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
256
+ }
257
+ /**
258
+ * <button kxToggle [(pressed)]="bold" aria-label="Bold">B</button>
259
+ *
260
+ * A directive on a real `<button>` that carries `aria-pressed` — the ARIA pattern for a two-state button,
261
+ * and the one thing ARIA has to add to a button that already has focus, activation and disabled handling.
262
+ */
263
+ declare class KxToggle {
264
+ readonly pressed: i0.ModelSignal<boolean>;
265
+ readonly variant: i0.InputSignal<KxToggleVariant>;
266
+ readonly size: i0.InputSignal<KxToggleSize>;
267
+ readonly toggled: i0.OutputEmitterRef<boolean>;
268
+ protected press(): void;
269
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxToggle, never>;
270
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxToggle, "button[kxToggle]", never, { "pressed": { "alias": "pressed"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "pressed": "pressedChange"; "toggled": "toggled"; }, never, never, true, never>;
271
+ }
272
+ /**
273
+ * <kx-toggle-group [(value)]="marks" aria-label="Text style">
274
+ * <kx-toggle-group-item value="bold">B</kx-toggle-group-item>
275
+ * </kx-toggle-group>
276
+ *
277
+ * Multiple-select by default: each item is an independent `aria-pressed` button inside a `role="group"`, so
278
+ * every one is its own tab stop and its own announcement — which is what a formatting toolbar is.
279
+ *
280
+ * `type="single"` is a different control, and is rendered as one: a `radiogroup` of real `<input
281
+ * type="radio">` elements, so arrow-key selection and the single tab stop come from the browser. Sharing a
282
+ * template between the two would mean re-implementing radio behaviour with ARIA, which is exactly the
283
+ * trade this package refuses elsewhere.
284
+ */
285
+ declare class KxToggleGroup {
286
+ readonly type: i0.InputSignal<"single" | "multiple">;
287
+ /** A string for `single`, an array for `multiple`. */
288
+ readonly value: i0.ModelSignal<string | string[]>;
289
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
290
+ readonly name: i0.InputSignal<string>;
291
+ isOn(value: string): boolean;
292
+ toggle(value: string): void;
293
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxToggleGroup, never>;
294
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxToggleGroup, "kx-toggle-group", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, ["*"], true, never>;
295
+ }
296
+ declare class KxToggleGroupItem {
297
+ protected readonly group: KxToggleGroup;
298
+ readonly value: i0.InputSignal<string>;
299
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
300
+ readonly id: i0.InputSignal<string>;
301
+ constructor(group: KxToggleGroup);
302
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxToggleGroupItem, never>;
303
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxToggleGroupItem, "kx-toggle-group-item", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, ["*", "*"], true, never>;
304
+ }
305
+ /**
306
+ * <kx-segmented-control [(value)]="range" aria-label="Range">
307
+ * <kx-segment value="7d">7 days</kx-segment>
308
+ * <kx-segment value="30d">30 days</kx-segment>
309
+ * </kx-segmented-control>
310
+ *
311
+ * A single-choice control shown as one connected track — iOS's segmented control, on the web. It is a real
312
+ * `radiogroup` of real radio inputs for the same reason the radio group is: arrow keys, one tab stop and the
313
+ * "exactly one is chosen" semantics are the browser's.
314
+ *
315
+ * Unlike a toggle group, a segment cannot be turned off by clicking it again: a segmented control with
316
+ * nothing selected has no meaning.
317
+ */
318
+ declare class KxSegmentedControl {
319
+ readonly value: i0.ModelSignal<string>;
320
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
321
+ readonly name: i0.InputSignal<string>;
322
+ readonly selected: i0.OutputEmitterRef<string>;
323
+ select(next: string): void;
324
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSegmentedControl, never>;
325
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSegmentedControl, "kx-segmented-control", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "selected": "selected"; }, never, ["*"], true, never>;
326
+ }
327
+ declare class KxSegment {
328
+ protected readonly control: KxSegmentedControl;
329
+ readonly value: i0.InputSignal<string>;
330
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
331
+ readonly id: i0.InputSignal<string>;
332
+ constructor(control: KxSegmentedControl);
333
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSegment, never>;
334
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSegment, "kx-segment", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
335
+ }
336
+
337
+ /**
338
+ * The display primitives: avatar, aspect ratio, keyboard glyphs, skeleton, spinner, tag, quote, metric and the
339
+ * empty-state family.
340
+ *
341
+ * Nothing here holds application state. Each is either a directive on the element HTML already has for the
342
+ * job, or a component that renders that element — the same rule the rest of the package follows.
343
+ */
344
+ /**
345
+ * <kx-aspect-ratio [ratio]="16 / 9"><img src="cover.jpg" alt="" /></kx-aspect-ratio>
346
+ *
347
+ * The CSS `aspect-ratio` property, which every target browser has had for years. There is no padding-top
348
+ * percentage hack here and no ResizeObserver: the platform does this now, and a component that re-implemented
349
+ * it would be slower and would fight the container.
350
+ */
351
+ declare class KxAspectRatio {
352
+ readonly ratio: i0.InputSignal<number>;
353
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAspectRatio, never>;
354
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAspectRatio, "kx-aspect-ratio", never, { "ratio": { "alias": "ratio"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
355
+ }
356
+ /**
357
+ * <kx-avatar>
358
+ * <img kxAvatarImage src="/ada.jpg" alt="Ada Lovelace" />
359
+ * <kx-avatar-fallback>AL</kx-avatar-fallback>
360
+ * </kx-avatar>
361
+ *
362
+ * The fallback shows until the image reports `load`, and comes back if it reports `error`. That is the whole
363
+ * reason this is a component rather than a styled `<img>`: a broken avatar that leaves a blank circle is the
364
+ * failure users actually hit, and `alt` text alone does not fill the space.
365
+ *
366
+ * The image carries the accessible name. The fallback initials are decorative — announcing "AL" as well would
367
+ * read the person's name twice, so `aria-hidden` is set on it and the caller keeps `alt` meaningful.
368
+ */
369
+ declare class KxAvatar {
370
+ /** Set by KxAvatarImage as the image loads or fails; the fallback reads it. */
371
+ readonly imageLoaded: i0.WritableSignal<boolean>;
372
+ /** Set by KxAvatarGroup on the avatars past its `max`. Not an input: the group owns it, not the caller. */
373
+ readonly collapsed: i0.WritableSignal<boolean>;
374
+ protected readonly classes: i0.Signal<"kx-avatar" | "kx-avatar kx-avatar--collapsed">;
375
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAvatar, never>;
376
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAvatar, "kx-avatar", never, {}, {}, never, ["*"], true, never>;
377
+ }
378
+ /**
379
+ * A directive on a real `<img>`, so `src`, `srcset`, `loading="lazy"`, `alt` and the browser's own decoding
380
+ * are untouched. It only reports load state up to the avatar and hides itself until then.
381
+ */
382
+ declare class KxAvatarImage {
383
+ protected readonly avatar: KxAvatar;
384
+ constructor(avatar: KxAvatar);
385
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAvatarImage, never>;
386
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxAvatarImage, "img[kxAvatarImage]", never, {}, {}, never, never, true, never>;
387
+ }
388
+ declare class KxAvatarFallback {
389
+ protected readonly avatar: KxAvatar;
390
+ constructor(avatar: KxAvatar);
391
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAvatarFallback, never>;
392
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAvatarFallback, "kx-avatar-fallback", never, {}, {}, never, ["*"], true, never>;
393
+ }
394
+ /**
395
+ * <kx-avatar-group [max]="3">
396
+ * <kx-avatar>…</kx-avatar>
397
+ * …
398
+ * </kx-avatar-group>
399
+ *
400
+ * Stacked, overlapping avatars with a "+N" marker for the rest. The group counts its projected avatars with a
401
+ * content query and tells the ones past `max` to collapse; it does not re-wrap or re-render them, because a
402
+ * projected node can only be rendered where it was projected.
403
+ *
404
+ * The overflow marker is announced ("and 4 more") rather than left as the bare glyph, which reads as "plus
405
+ * four" out of context.
406
+ */
407
+ declare class KxAvatarGroup {
408
+ /** Visible avatars before the rest fold into the marker. Null (the default) shows every one. */
409
+ readonly max: i0.InputSignal<number>;
410
+ private readonly avatars;
411
+ protected readonly overflow: i0.Signal<number>;
412
+ constructor();
413
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxAvatarGroup, never>;
414
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxAvatarGroup, "kx-avatar-group", never, { "max": { "alias": "max"; "required": false; "isSignal": true; }; }, {}, ["avatars"], ["*"], true, never>;
415
+ }
416
+ /**
417
+ * <kbd kxKbdGroup><kbd kxKbd>Ctrl</kbd><kbd kxKbd>K</kbd></kbd>
418
+ *
419
+ * Directives on real `<kbd>` elements. `<kbd>` already means "keyboard input" to assistive technology and to
420
+ * every reader of the markup, so there is nothing for a wrapper component to add.
421
+ */
422
+ declare class KxKbd {
423
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxKbd, never>;
424
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxKbd, "kbd[kxKbd]", never, {}, {}, never, never, true, never>;
425
+ }
426
+ declare class KxKbdGroup {
427
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxKbdGroup, never>;
428
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxKbdGroup, "kbd[kxKbdGroup]", never, {}, {}, never, never, true, never>;
429
+ }
430
+ /**
431
+ * <kx-skeleton style="block-size: 1rem; inline-size: 60%" />
432
+ *
433
+ * A loading placeholder, sized by the caller because only the caller knows the shape of the content it stands
434
+ * in for. Hidden from assistive technology: the meaningful announcement is the "loading" state on the region
435
+ * that owns it, not a stack of grey rectangles.
436
+ *
437
+ * The shimmer is a CSS animation wrapped in `prefers-reduced-motion`, so it stops for users who ask it to.
438
+ */
439
+ declare class KxSkeleton {
440
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSkeleton, never>;
441
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSkeleton, "kx-skeleton", never, {}, {}, never, never, true, never>;
442
+ }
443
+ /**
444
+ * <kx-spinner />
445
+ * <kx-spinner size="lg" variant="muted" label="Saving…" />
446
+ *
447
+ * A `role="status"` live region carrying its own label, so a screen reader is told that something is in
448
+ * progress instead of being shown a spinning border it cannot perceive. The ring is a CSS border animation —
449
+ * no icon dependency, and it degrades to a static ring under reduced motion rather than disappearing.
450
+ */
451
+ declare class KxSpinner {
452
+ readonly size: i0.InputSignal<KxSpinnerSize>;
453
+ readonly variant: i0.InputSignal<KxSpinnerVariant>;
454
+ readonly label: i0.InputSignal<string>;
455
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSpinner, never>;
456
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSpinner, "kx-spinner", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
457
+ }
458
+ /**
459
+ * <kx-tag>Design</kx-tag>
460
+ * <kx-tag variant="outline" removable (removed)="drop('design')">Design</kx-tag>
461
+ *
462
+ * A container-tinted chip, distinct from Badge (a solid pill). The dismiss button is opt-in and carries an
463
+ * accessible name built from the tag's own text, so a list of them does not announce "Remove, Remove,
464
+ * Remove" — `removeLabel` overrides it where the text is not the right name.
465
+ */
466
+ declare class KxTag {
467
+ readonly variant: i0.InputSignal<KxTagVariant>;
468
+ readonly removable: i0.InputSignalWithTransform<boolean, unknown>;
469
+ readonly removeLabel: i0.InputSignal<string>;
470
+ readonly removed: i0.OutputEmitterRef<void>;
471
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTag, never>;
472
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxTag, "kx-tag", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; }, { "removed": "removed"; }, never, ["*"], true, never>;
473
+ }
474
+ /**
475
+ * <kx-quote author="Ada Lovelace" authorTitle="Mathematician">
476
+ * The Analytical Engine weaves algebraic patterns.
477
+ * </kx-quote>
478
+ *
479
+ * A real `<figure>` / `<blockquote>` / `<figcaption>`, which is the markup a quotation with an attribution
480
+ * already has in HTML. The curly quotation marks are decorative punctuation and are hidden from assistive
481
+ * technology — a screen reader announces a blockquote as one already.
482
+ */
483
+ declare class KxQuote {
484
+ readonly author: i0.InputSignal<string>;
485
+ readonly authorTitle: i0.InputSignal<string>;
486
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxQuote, never>;
487
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxQuote, "kx-quote", never, { "author": { "alias": "author"; "required": false; "isSignal": true; }; "authorTitle": { "alias": "authorTitle"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[kxQuoteAvatar]"], true, never>;
488
+ }
489
+ /**
490
+ * <kx-metric label="Revenue" value="$48,120" trend="up" change="+12.4%" />
491
+ *
492
+ * A stat tile. The trend arrow is decorative — the direction is already in the `change` text, and an arrow
493
+ * announced as "up" next to "+12.4%" is noise. Colour is not the only carrier of meaning here for the same
494
+ * reason: the sign is in the text.
495
+ */
496
+ declare class KxMetric {
497
+ readonly label: i0.InputSignal<string>;
498
+ readonly value: i0.InputSignal<string>;
499
+ readonly trend: i0.InputSignal<KxTrend>;
500
+ readonly change: i0.InputSignal<string>;
501
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxMetric, never>;
502
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxMetric, "kx-metric", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "trend": { "alias": "trend"; "required": false; "isSignal": true; }; "change": { "alias": "change"; "required": false; "isSignal": true; }; }, {}, never, ["[kxMetricIcon]", "[kxMetricChart]"], true, never>;
503
+ }
504
+ /**
505
+ * <kx-empty>
506
+ * <kx-empty-header>
507
+ * <kx-empty-media variant="icon">…</kx-empty-media>
508
+ * <kx-empty-title>No projects yet</kx-empty-title>
509
+ * <kx-empty-description>Create one to get started.</kx-empty-description>
510
+ * </kx-empty-header>
511
+ * <kx-empty-content><button kxButton>New project</button></kx-empty-content>
512
+ * </kx-empty>
513
+ *
514
+ * Composed rather than prop-driven, like Card, so it drops into whatever already has a border — a table cell,
515
+ * a card, a bare section — without forcing its own.
516
+ */
517
+ declare class KxEmpty {
518
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmpty, never>;
519
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmpty, "kx-empty", never, {}, {}, never, ["*"], true, never>;
520
+ }
521
+ declare class KxEmptyHeader {
522
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmptyHeader, never>;
523
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmptyHeader, "kx-empty-header", never, {}, {}, never, ["*"], true, never>;
524
+ }
525
+ declare class KxEmptyMedia {
526
+ readonly variant: i0.InputSignal<KxEmptyMediaVariant>;
527
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmptyMedia, never>;
528
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmptyMedia, "kx-empty-media", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
529
+ }
530
+ declare class KxEmptyTitle {
531
+ readonly level: i0.InputSignal<1 | 2 | 3 | 4 | 5 | 6>;
532
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmptyTitle, never>;
533
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmptyTitle, "kx-empty-title", never, { "level": { "alias": "level"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
534
+ }
535
+ declare class KxEmptyDescription {
536
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmptyDescription, never>;
537
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmptyDescription, "kx-empty-description", never, {}, {}, never, ["*"], true, never>;
538
+ }
539
+ declare class KxEmptyContent {
540
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxEmptyContent, never>;
541
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxEmptyContent, "kx-empty-content", never, {}, {}, never, ["*"], true, never>;
542
+ }
543
+
544
+ /**
545
+ * The form controls beyond checkbox and switch: textarea, native select, radio group, slider, number input,
546
+ * password input, and the field wrapper that labels and describes any of them.
547
+ *
548
+ * The rule this file follows, and the reason it is short: where HTML already has the control, KinetixUI is a
549
+ * directive on it. A `<input type="range">` already has arrow-key stepping, Home/End, `aria-valuenow`, RTL
550
+ * awareness and a form value. A `role="slider"` div has none of that, and every re-implementation of it in
551
+ * this industry has shipped with at least one of those missing. The same argument decides radio (a real
552
+ * `<input type="radio">` group gives roving focus and arrow-key selection for free) and number input.
553
+ *
554
+ * Every control that carries a value implements `ControlValueAccessor`, so `[(ngModel)]`, `formControl` and
555
+ * `formControlName` all work, including `setDisabledState` from the form model.
556
+ */
557
+ /**
558
+ * `@Directive()` with no selector rather than a plain class: `input()`, `model()` and `output()` are only
559
+ * legal on a class the Angular compiler knows about, and an undecorated base fails the build with NG8110.
560
+ */
561
+ declare abstract class KxValueBase<T> implements ControlValueAccessor {
562
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
563
+ protected readonly formDisabled: i0.WritableSignal<boolean>;
564
+ protected isDisabled(): boolean;
565
+ protected onChange: (value: T) => void;
566
+ protected onTouched: () => void;
567
+ abstract writeValue(value: T): void;
568
+ registerOnChange(fn: (value: T) => void): void;
569
+ registerOnTouched(fn: () => void): void;
570
+ setDisabledState(isDisabled: boolean): void;
571
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxValueBase<any>, never>;
572
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxValueBase<any>, never, never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
573
+ }
574
+ /**
575
+ * <textarea kxTextarea rows="4" [(ngModel)]="notes"></textarea>
576
+ *
577
+ * A directive on a real `<textarea>`: `rows`, `maxlength`, `required`, the browser's own validation and every
578
+ * Angular forms directive keep working untouched. Separate from `kxInput` because the two have different
579
+ * metrics (a minimum height and a resize affordance), matching the React package's Input/Textarea split.
580
+ *
581
+ * The error state is read from `aria-invalid`, so the semantics drive the styling instead of a parallel
582
+ * `invalid` input that could disagree with them.
583
+ */
584
+ declare class KxTextarea {
585
+ /** `vertical` (the default) or `none`. Horizontal resize breaks the column it sits in, so it is not offered. */
586
+ readonly resize: i0.InputSignal<"vertical" | "none">;
587
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTextarea, never>;
588
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxTextarea, "textarea[kxTextarea]", never, { "resize": { "alias": "resize"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
589
+ }
590
+ /**
591
+ * <select kxNativeSelect [(ngModel)]="country">
592
+ * <option value="pt">Portugal</option>
593
+ * </select>
594
+ *
595
+ * A directive on the browser's own `<select>`, which on a phone opens the platform picker and on a desktop
596
+ * opens the OS listbox. That is the whole point of it — where a designed listbox is wanted, that is a
597
+ * different component. Nothing here re-implements the popup, so nothing here can get it wrong.
598
+ */
599
+ declare class KxNativeSelect {
600
+ readonly corners: i0.InputSignal<KxCorners | "rounded">;
601
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxNativeSelect, never>;
602
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxNativeSelect, "select[kxNativeSelect]", never, { "corners": { "alias": "corners"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
603
+ }
604
+ /**
605
+ * <kx-radio-group name="plan" [(ngModel)]="plan" aria-label="Plan">
606
+ * <kx-radio value="free">Free</kx-radio>
607
+ * <kx-radio value="pro">Pro</kx-radio>
608
+ * </kx-radio-group>
609
+ *
610
+ * The radios are real `<input type="radio">` elements sharing a `name`, so arrow-key selection, roving focus,
611
+ * the "one tab stop per group" behaviour and the group's own form semantics are the browser's. An ARIA
612
+ * re-implementation of a radio group has to rebuild all four, and usually rebuilds three.
613
+ *
614
+ * The group is the `ControlValueAccessor`; the radios read and write through it.
615
+ */
616
+ declare class KxRadioGroup extends KxValueBase<string | null> {
617
+ /** Shared `name` for the underlying inputs. Defaults to a per-instance name so two groups never merge. */
618
+ readonly name: i0.InputSignal<string>;
619
+ readonly value: i0.ModelSignal<string>;
620
+ readonly orientation: i0.InputSignal<"horizontal" | "vertical">;
621
+ /** Emits only on user selection — `valueChange` also fires when a form writes the value in. */
622
+ readonly selected: i0.OutputEmitterRef<string>;
623
+ /** Called by a child radio. Public because the radio is a separate component, not because callers should. */
624
+ select(next: string): void;
625
+ groupDisabled(): boolean;
626
+ /** A radio lost focus — mark the group touched so `ng-touched` and validation messages behave. */
627
+ touch(): void;
628
+ writeValue(value: string | null): void;
629
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxRadioGroup, never>;
630
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxRadioGroup, "kx-radio-group", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "selected": "selected"; }, never, ["*"], true, never>;
631
+ }
632
+ /**
633
+ * <kx-radio value="pro">Pro</kx-radio>
634
+ *
635
+ * Renders `<input type="radio">` + `<label>`, associated by id, so the whole row is a click target and the
636
+ * label is the accessible name without any `aria-label` guessing.
637
+ */
638
+ declare class KxRadio {
639
+ protected readonly group: KxRadioGroup;
640
+ readonly value: i0.InputSignal<string>;
641
+ readonly disabled: i0.InputSignalWithTransform<boolean, unknown>;
642
+ readonly id: i0.InputSignal<string>;
643
+ constructor(group: KxRadioGroup);
644
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxRadio, never>;
645
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxRadio, "kx-radio", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
646
+ }
647
+ /**
648
+ * <kx-slider [(ngModel)]="volume" [min]="0" [max]="100" [step]="5" aria-label="Volume" />
649
+ *
650
+ * A real `<input type="range">`. Arrow keys, Page Up/Down, Home/End, `aria-valuenow`/`valuemin`/`valuemax`,
651
+ * the RTL direction flip and touch dragging are all the browser's, and all of them are things hand-rolled
652
+ * sliders routinely lose. The filled track is drawn with a CSS custom property set from the value, so the
653
+ * visual follows the real control rather than the other way round.
654
+ */
655
+ declare class KxSlider extends KxValueBase<number> {
656
+ readonly value: i0.ModelSignal<number>;
657
+ readonly min: i0.InputSignal<number>;
658
+ readonly max: i0.InputSignal<number>;
659
+ readonly step: i0.InputSignal<number>;
660
+ /** Announced instead of the raw number where the number alone means nothing ("Medium", "3 of 7"). */
661
+ readonly valueText: i0.InputSignal<string>;
662
+ readonly ariaLabel: i0.InputSignal<string>;
663
+ readonly ariaLabelledby: i0.InputSignal<string>;
664
+ readonly changed: i0.OutputEmitterRef<number>;
665
+ protected readonly fill: i0.Signal<number>;
666
+ protected commit(next: number): void;
667
+ writeValue(value: number): void;
668
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxSlider, never>;
669
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxSlider, "kx-slider", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "changed": "changed"; }, never, never, true, never>;
670
+ }
671
+ /**
672
+ * <kx-number-input [(ngModel)]="quantity" [min]="1" [max]="99" aria-label="Quantity" />
673
+ *
674
+ * A real `<input type="number">` with explicit step buttons beside it. The input keeps the numeric keypad on
675
+ * touch, the browser's own arrow-key stepping and `valueAsNumber`; the buttons exist because the native
676
+ * spinners are tiny, inconsistent between browsers, and in several of them not reachable by keyboard at all.
677
+ *
678
+ * The buttons are `aria-hidden` and `tabindex="-1"`: they duplicate keyboard behaviour the input already has,
679
+ * so exposing them adds two stops to the tab order that do nothing new.
680
+ */
681
+ declare class KxNumberInput extends KxValueBase<number | null> {
682
+ readonly value: i0.ModelSignal<number>;
683
+ readonly min: i0.InputSignal<number>;
684
+ readonly max: i0.InputSignal<number>;
685
+ readonly step: i0.InputSignal<number>;
686
+ readonly ariaLabel: i0.InputSignal<string>;
687
+ readonly ariaLabelledby: i0.InputSignal<string>;
688
+ readonly changed: i0.OutputEmitterRef<number>;
689
+ protected nudge(direction: 1 | -1): void;
690
+ protected commit(next: number): void;
691
+ private clamp;
692
+ writeValue(value: number | null): void;
693
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxNumberInput, never>;
694
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxNumberInput, "kx-number-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "changed": "changed"; }, never, never, true, never>;
695
+ }
696
+ /**
697
+ * <kx-password-input [(ngModel)]="password" aria-label="Password" />
698
+ *
699
+ * A real password field with a reveal toggle. The toggle is a real `<button>` carrying `aria-pressed`, so its
700
+ * state is announced; the field keeps `autocomplete="current-password"` by default so password managers still
701
+ * recognise it, and `[autocomplete]` switches it to `new-password` on a sign-up form.
702
+ */
703
+ declare class KxPasswordInput extends KxValueBase<string> {
704
+ readonly value: i0.ModelSignal<string>;
705
+ readonly autocomplete: i0.InputSignal<"current-password" | "new-password">;
706
+ readonly ariaLabel: i0.InputSignal<string>;
707
+ readonly ariaLabelledby: i0.InputSignal<string>;
708
+ protected readonly revealed: i0.WritableSignal<boolean>;
709
+ protected commit(next: string): void;
710
+ writeValue(value: string): void;
711
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxPasswordInput, never>;
712
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxPasswordInput, "kx-password-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
713
+ }
714
+ /**
715
+ * <kx-field>
716
+ * <label kxFieldLabel for="email">Email</label>
717
+ * <input kxInput id="email" aria-describedby="email-hint" />
718
+ * <p kxFieldDescription id="email-hint">We only use this to sign you in.</p>
719
+ * <kx-field-message variant="error">Enter a valid address.</kx-field-message>
720
+ * </kx-field>
721
+ *
722
+ * Layout and type for a labelled control, and nothing else. It deliberately does not generate ids or wire
723
+ * `aria-describedby` for you: a wrapper that guesses those has to guess which of several descriptions is the
724
+ * error, and gets it wrong on the form where it matters. The ids are the caller's, and they are three
725
+ * characters each.
726
+ *
727
+ * An error message is a live region, so a validation message that appears after submit is announced rather
728
+ * than silently rendered below the field.
729
+ */
730
+ declare class KxField {
731
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxField, never>;
732
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxField, "kx-field", never, {}, {}, never, ["*"], true, never>;
733
+ }
734
+ declare class KxFieldLabel {
735
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxFieldLabel, never>;
736
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxFieldLabel, "label[kxFieldLabel]", never, {}, {}, never, never, true, never>;
737
+ }
738
+ declare class KxFieldDescription {
739
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxFieldDescription, never>;
740
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxFieldDescription, "[kxFieldDescription]", never, {}, {}, never, never, true, never>;
741
+ }
742
+ declare class KxFieldMessage {
743
+ readonly variant: i0.InputSignal<KxFieldMessageVariant>;
744
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxFieldMessage, never>;
745
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxFieldMessage, "kx-field-message", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
746
+ }
747
+
748
+ declare class KxTab {
749
+ readonly tabs: KxTabs;
750
+ readonly el: ElementRef<HTMLButtonElement>;
751
+ readonly value: i0.InputSignal<string>;
752
+ readonly disabled: i0.InputSignal<boolean>;
753
+ readonly id: string;
754
+ readonly panelId: string;
755
+ selected(): boolean;
756
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTab, never>;
757
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KxTab, "button[kxTab]", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
758
+ }
759
+ declare class KxTabList {
760
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTabList, never>;
761
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxTabList, "kx-tab-list", never, {}, {}, never, ["*"], true, never>;
762
+ }
763
+ /**
764
+ * The panel is focusable (`tabindex="0"`) because after Tab moves out of the tab list the next stop must be
765
+ * the panel itself — otherwise a keyboard user lands past the content the tab just revealed. Hidden panels are
766
+ * removed from the DOM rather than merely hidden, so nothing inside them is reachable or announced.
767
+ */
768
+ declare class KxTabPanel {
769
+ private readonly tabs;
770
+ readonly value: i0.InputSignal<string>;
771
+ active(): boolean;
772
+ labelledBy(): string | null;
773
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTabPanel, never>;
774
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxTabPanel, "kx-tab-panel", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; }, {}, never, ["*"], true, never>;
775
+ }
776
+ declare class KxTabs {
777
+ /** Two-way: `[(value)]` for a controlled tab strip, or leave it and let the first tab win. */
778
+ readonly value: i0.ModelSignal<string>;
779
+ private readonly tabs;
780
+ private readonly initialised;
781
+ tabFor(value: string): KxTab | undefined;
782
+ select(value: string): void;
783
+ /** Falls back to the first enabled tab when nothing is selected, so an uncontrolled strip still works. */
784
+ constructor();
785
+ onKeydown(event: KeyboardEvent): void;
786
+ private readonly el;
787
+ /**
788
+ * The document's own direction, read at the moment of the keypress rather than taken as an input — an
789
+ * application that flips `dir` at runtime keeps working with no extra wiring.
790
+ *
791
+ * The nearest `[dir]` ancestor is checked before the computed style. Computed direction is the more correct
792
+ * answer when direction comes from CSS, but it is also the one a DOM implementation is free not to inherit,
793
+ * so relying on it alone makes the behaviour depend on the environment rather than on the markup.
794
+ */
795
+ private isRtl;
796
+ static ɵfac: i0.ɵɵFactoryDeclaration<KxTabs, never>;
797
+ static ɵcmp: i0.ɵɵComponentDeclaration<KxTabs, "kx-tabs", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, ["tabs"], ["*"], true, never>;
798
+ }
799
+
800
+ export { KxAlert, KxAlertDescription, KxAlertTitle, KxAspectRatio, KxAvatar, KxAvatarFallback, KxAvatarGroup, KxAvatarImage, KxBadge, KxButton, KxCard, KxCardContent, KxCardDescription, KxCardFooter, KxCardHeader, KxCardTitle, KxCheckbox, KxEmpty, KxEmptyContent, KxEmptyDescription, KxEmptyHeader, KxEmptyMedia, KxEmptyTitle, KxField, KxFieldDescription, KxFieldLabel, KxFieldMessage, KxInput, KxKbd, KxKbdGroup, KxLabel, KxMetric, KxNativeSelect, KxNumberInput, KxPasswordInput, KxProgress, KxQuote, KxRadio, KxRadioGroup, KxSegment, KxSegmentedControl, KxSeparator, KxSkeleton, KxSlider, KxSpinner, KxSwitch, KxTab, KxTabList, KxTabPanel, KxTabs, KxTag, KxTextarea, KxToggle, KxToggleGroup, KxToggleGroupItem };
801
+ export type { KxAlertVariant, KxBadgeVariant, KxButtonSize, KxButtonVariant, KxCorners, KxEmptyMediaVariant, KxFieldMessageVariant, KxOrientation, KxSpinnerSize, KxSpinnerVariant, KxTagVariant, KxToggleSize, KxToggleVariant, KxTrend };