@uni-design-system/uni-angular 9.0.1 → 10.1.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.
@@ -25,9 +25,23 @@ declare function resolveFocusTarget(element: HTMLElement): HTMLElement;
25
25
  /**
26
26
  * Visually hides content while keeping it available to screen readers.
27
27
  * Use for text alternatives (e.g. badge counts, icon-only affordances).
28
+ *
29
+ * `fixed`, not `absolute`, and that is load-bearing. An absolutely positioned
30
+ * box resolves its containing block to the nearest *positioned* ancestor —
31
+ * which, since the controls emitting these spans are `position: static`, is
32
+ * whatever positioned box happens to be above them in the consumer's layout,
33
+ * often several scroll containers up. The span then skips every intervening
34
+ * `overflow: auto` and lands in that distant ancestor's scrollable overflow,
35
+ * turning 1x1 of invisible text into real scrollable distance in a box that
36
+ * never opted into scrolling. A fixed box's containing block is the viewport,
37
+ * so it joins no ancestor's scrollable overflow at all.
38
+ *
39
+ * Caveat: inside a `transform`ed (or `filter`ed/`contain`ed) ancestor a fixed
40
+ * box re-anchors to that ancestor. Harmless here — the element is 1x1 and
41
+ * clipped to nothing, so where it lands never matters, only what it overflows.
28
42
  */
29
43
  declare const visuallyHidden: {
30
- readonly position: "absolute";
44
+ readonly position: "fixed";
31
45
  readonly width: 1;
32
46
  readonly height: 1;
33
47
  readonly padding: 0;
@@ -187,6 +201,391 @@ declare const splitDateTime: (value?: UniDateTime) => {
187
201
  /** One combined value only when both parts are present. */
188
202
  declare const joinDateTime: (date?: UniDate, time?: UniTime) => UniDateTime | undefined;
189
203
 
204
+ /**
205
+ * Canonical numeric value shapes shared by `uni-number-input`,
206
+ * `uni-quantity-stepper`, `uni-number-range-input` and `uni-slider`.
207
+ *
208
+ * The components' internal source of truth is a **canonical decimal string** —
209
+ * optional sign, digits, an optional `.`, no grouping and no affix:
210
+ * `'-1234.56'`. The bound `number` is its projection, emitted on commit.
211
+ *
212
+ * Nothing numeric passes through a float, because floats give wrong answers to
213
+ * questions people ask of money: `0.1 + 0.2` is `0.30000000000000004`, and
214
+ * `(1.15).toFixed(1)` is `'1.1'` — 1.15 is really 1.1499999999999999, so the
215
+ * platform rounds a tie that isn't there. See `decimal.helper.ts`.
216
+ */
217
+ /** A start–end numeric range. Either end alone is a valid value. */
218
+ interface UniNumberRange {
219
+ start?: number;
220
+ end?: number;
221
+ }
222
+ /**
223
+ * How a tie is resolved when rounding to a fraction-digit count.
224
+ *
225
+ * `half-up` is the invoice default (ties away from zero: `1.15` → `1.2`);
226
+ * `half-even` is banker's rounding, which removes the upward bias across a
227
+ * column of figures (`1.25` → `1.2`, `1.35` → `1.4`).
228
+ */
229
+ type UniRoundingMode = 'half-up' | 'half-even' | 'ceil' | 'floor' | 'trunc';
230
+ /** Format archetype. Supplies decimals, grouping, affix and `inputmode`. */
231
+ type UniNumberPreset = 'decimal' | 'integer' | 'currency' | 'percent';
232
+ /**
233
+ * Thousands-separator policy, mapped onto `Intl`'s `useGrouping`.
234
+ *
235
+ * `min2` — the default — groups only from five integer digits, so a year
236
+ * renders `2026` rather than `2,026` while a price still renders `10,000`.
237
+ */
238
+ type UniNumberGrouping = 'auto' | 'always' | 'min2' | false;
239
+ /** Why a typed commit was refused. The raw text stays in the field. */
240
+ type UniNumberRejectReason = 'unparseable' | 'min' | 'max' | 'step' | 'precision' | 'not-integer';
241
+ /** Fences and snap grid for `stepDecimal`. */
242
+ interface UniNumberStepConfig {
243
+ /** Grid spacing. Steps land on `origin + n · step`. Default `1`. */
244
+ step?: number | string;
245
+ min?: number | string;
246
+ max?: number | string;
247
+ /**
248
+ * Snap-grid anchor. `'min'` matches the platform's `<input type="number">`
249
+ * (a field with `min=5, step=10` steps 5 → 15 → 25); `'zero'` anchors the
250
+ * grid at 0 regardless of the fence.
251
+ */
252
+ stepOrigin?: 'min' | 'zero';
253
+ /**
254
+ * Cycle past a fence instead of stopping at it — for genuinely cyclic
255
+ * fields only (23 → 0 hours, 359 → 0 degrees). Needs both `min` and `max`.
256
+ */
257
+ wrap?: boolean;
258
+ }
259
+ /** The outcome of clamping a value to its fences. */
260
+ interface UniNumberClamp {
261
+ /** The clamped canonical decimal. */
262
+ value: string;
263
+ /** Which fence was hit, or `null` when the value was already in range. */
264
+ hit: 'min' | 'max' | null;
265
+ }
266
+ /**
267
+ * Separators, currency placement and fraction digits read out of `Intl` for a
268
+ * locale. Nothing here is hardcoded per language — `1.234,56` is German input,
269
+ * not malformed input, and only the locale knows that.
270
+ */
271
+ interface UniLocaleNumberParts {
272
+ /** Thousands separator: `','` (en), `'.'` (de), a narrow no-break space (fr). */
273
+ group: string;
274
+ /** Decimal separator: `'.'` (en), `','` (de). */
275
+ decimal: string;
276
+ /** Currency symbol, when a currency was given: `'$'`, `'€'`, `'¥'`. */
277
+ currencySymbol: string;
278
+ /** True when the locale writes the symbol before the number. */
279
+ currencyLeading: boolean;
280
+ /** Fraction digits `Intl` uses for the currency — JPY 0, USD 2. */
281
+ currencyDecimals: number;
282
+ }
283
+ /**
284
+ * What a component knows about its own formatting, before resolution. Mirrors
285
+ * the component inputs so a control can forward its signals almost verbatim.
286
+ */
287
+ interface UniNumberFormatConfig {
288
+ preset?: UniNumberPreset;
289
+ /** ISO 4217 code, e.g. `'USD'`. Implies the `currency` preset. */
290
+ currency?: string;
291
+ /** BCP 47 tag. Defaults to `'en-US'`; components pass the document's. */
292
+ locale?: string;
293
+ /** Fixed fraction digits, or `[min, max]`. Overrides the preset. */
294
+ decimals?: number | [min: number, max: number];
295
+ grouping?: UniNumberGrouping;
296
+ /** Static adornment, rendered outside the editable text. */
297
+ prefix?: string;
298
+ suffix?: string;
299
+ roundingMode?: UniRoundingMode;
300
+ /**
301
+ * The model is a fraction: `0.15` displays as `15`. Without it, a percent
302
+ * field displays `15` for `15` and never divides behind the user's back.
303
+ */
304
+ valueIsFraction?: boolean;
305
+ /** Escape hatch, merged over the preset. Only `notation` is read today. */
306
+ numberFormat?: Intl.NumberFormatOptions;
307
+ /** Read only to decide `inputmode` — a field that can go negative needs `-`. */
308
+ min?: number;
309
+ /** Spoken long form of an abbreviated suffix, for `aria-valuetext`. */
310
+ unitAnnouncement?: string;
311
+ }
312
+ /** A format config with every preset and locale default filled in. */
313
+ interface UniResolvedNumberFormat {
314
+ locale: string;
315
+ parts: UniLocaleNumberParts;
316
+ prefix: string;
317
+ suffix: string;
318
+ minimumFractionDigits: number;
319
+ maximumFractionDigits: number;
320
+ grouping: UniNumberGrouping;
321
+ /** `1.5k` in, `1.5K` out. */
322
+ compact: boolean;
323
+ /** Fraction entry is refused outright rather than rounded away. */
324
+ isInteger: boolean;
325
+ /** Display value is the model value × `10^shift`. */
326
+ shift: number;
327
+ roundingMode: UniRoundingMode;
328
+ /** `numeric` only when negatives and decimals are both impossible. */
329
+ inputMode: 'decimal' | 'numeric';
330
+ unitAnnouncement?: string;
331
+ }
332
+ /**
333
+ * The outcome of reading a user's text. Refused text is never swallowed: the
334
+ * caller keeps it in the field and flags it, so nobody loses their work to a
335
+ * silently emptied box.
336
+ */
337
+ type UniNumberParseResult = {
338
+ status: 'empty';
339
+ } | {
340
+ status: 'ok';
341
+ value: string;
342
+ viaExpression: boolean;
343
+ } | {
344
+ status: 'error';
345
+ reason: UniNumberRejectReason;
346
+ };
347
+
348
+ /**
349
+ * Exact decimal arithmetic over canonical decimal strings, using scaled
350
+ * `BigInt`s. No number library — `BigInt` is the platform's own exact integer
351
+ * type, and every operation here is integer arithmetic with a remembered
352
+ * decimal point.
353
+ *
354
+ * A **canonical decimal** is `/^-?\d+(\.\d+)?$/`: optional sign, digits, an
355
+ * optional fraction, no grouping, no affix, no exponent. Everything in this
356
+ * file takes and returns that shape.
357
+ *
358
+ * Why not floats, concretely:
359
+ *
360
+ * ```
361
+ * 0.1 + 0.2 → 0.30000000000000004 // IEEE 754
362
+ * scaled: 1n + 2n = 3n, ÷10 → '0.3' // here
363
+ *
364
+ * (1.15).toFixed(1) → '1.1' // 1.15 is really 1.1499999999999999,
365
+ * // so the platform breaks a tie that
366
+ * // does not exist in the decimal value
367
+ * roundDecimal('1.15', 1) → '1.2' // what an invoice expects
368
+ * ```
369
+ *
370
+ * The scale (fraction-digit count) is carried alongside the integer rather
371
+ * than inferred, so `'1.50'` and `'1.5'` compare equal but a value's own
372
+ * precision survives a round trip.
373
+ */
374
+
375
+ /** True when `text` is already a canonical decimal (leading/trailing space allowed). */
376
+ declare const isCanonicalDecimal: (text: string) => boolean;
377
+ /** Fraction-digit count. `'1.250'` → 3, `'12'` → 0, `'5.'` → 0. */
378
+ declare const decimalScale: (value: string) => number;
379
+ /**
380
+ * Canonical decimal → integer scaled by `10^scale`. Fraction digits beyond
381
+ * `scale` are truncated, so callers that must not lose them pass a `scale` at
382
+ * least `decimalScale(value)`.
383
+ */
384
+ declare const toScaled: (value: string, scale: number) => bigint;
385
+ /** Scaled integer → canonical decimal, with trailing fraction zeros trimmed. */
386
+ declare const fromScaled: (scaled: bigint, scale: number) => string;
387
+ /**
388
+ * Strip a leading `+`, leading zeros and trailing fraction zeros: `'+01.50'`
389
+ * → `'1.5'`. Requires a canonical decimal; guard with `isCanonicalDecimal`.
390
+ */
391
+ declare const normalizeDecimal: (value: string) => string;
392
+ /**
393
+ * Any numeric input → canonical decimal, expanding the exponential notation
394
+ * `String(number)` produces outside 1e-7…1e21. A `step` of `1e-7` would
395
+ * otherwise reach the arithmetic as the literal text `'1e-7'`.
396
+ *
397
+ * Throws on text that is not numeric at all — every caller here passes either
398
+ * a `number` input or text already cleared by the parser.
399
+ */
400
+ declare const toDecimal: (value: number | string) => string;
401
+ /** `-1` when `a < b`, `1` when `a > b`, `0` when equal. `'1.50'` equals `'1.5'`. */
402
+ declare const compareDecimal: (a: string, b: string) => -1 | 0 | 1;
403
+ /**
404
+ * Round to `fractionDigits`, breaking ties per `mode`. Exact where
405
+ * `Number.prototype.toFixed` is not — see the file header.
406
+ */
407
+ declare const roundDecimal: (value: string, fractionDigits: number, mode?: UniRoundingMode) => string;
408
+ /**
409
+ * Multiply by `10^places`, exactly. Used for the percent preset's
410
+ * fraction ⇄ display shift (`0.15` ⇄ `15`) and for deriving a default
411
+ * large step of `step × 10` without touching a float.
412
+ */
413
+ declare const shiftDecimal: (value: string, places: number) => string;
414
+ /**
415
+ * Hold a value inside its fences, reporting which one it hit so the caller can
416
+ * announce it. Clamping belongs on commit, never per keystroke: a `min=10`
417
+ * field that clamps live can never be typed into, because the `1` becomes `10`
418
+ * before the `5` arrives.
419
+ */
420
+ declare const clampDecimal: (value: string, min?: number | string, max?: number | string) => UniNumberClamp;
421
+ /**
422
+ * One step from `current`, in `direction` (`1` up, `-1` down).
423
+ *
424
+ * Steps land on the grid `origin + n · step`, where `origin` is `min` by
425
+ * default. A value that is *off* the grid snaps to the nearest grid point **in
426
+ * the direction of travel** rather than jumping past it: with `min=5, step=10`
427
+ * the grid is 5, 15, 25, and stepping up from 7 gives 15, not 17.
428
+ *
429
+ * Fences stop the value; they never wrap unless `wrap` is set and both bounds
430
+ * are defined. Returns `current` unchanged when `step` is zero.
431
+ */
432
+ declare const stepDecimal: (current: string, direction: 1 | -1, config?: UniNumberStepConfig) => string;
433
+
434
+ /**
435
+ * Locale separators plus, when a currency is given, its symbol, side and
436
+ * fraction digits. Memoized: constructing an `Intl.NumberFormat` is expensive
437
+ * and a field re-resolves this on every keystroke.
438
+ */
439
+ declare const localeNumberParts: (locale: string, currency?: string) => UniLocaleNumberParts;
440
+ /**
441
+ * Map localized digits and Arabic separators to ASCII, so `١٢٣٤٫٥` parses in
442
+ * `ar` and `१२३४.५` in `hi`.
443
+ */
444
+ declare const toAsciiDigits: (text: string) => string;
445
+ /**
446
+ * Evaluate `+ − × ÷ ( )` over decimal literals — shunting-yard, roughly thirty
447
+ * lines, and **never `eval`**. Returns a canonical decimal, or `null` when the
448
+ * text is not a well-formed expression.
449
+ *
450
+ * Floats are acceptable here in a way they are not elsewhere: this is a
451
+ * convenience path for spreadsheet muscle memory (`12*3`, `100/4+5`), and the
452
+ * result is settled to ten decimals before re-entering exact arithmetic.
453
+ * Division is the only operation that can produce a non-terminating decimal,
454
+ * and no exact representation would help there either.
455
+ */
456
+ declare const evaluateExpression: (text: string) => string | null;
457
+ /** Fill in every preset, locale and currency default. */
458
+ declare const resolveNumberFormat: (config?: UniNumberFormatConfig) => UniResolvedNumberFormat;
459
+ /**
460
+ * Read a user's text into a canonical decimal in **model units**.
461
+ *
462
+ * Accepted, in order: canonical/ASCII (always, whatever the locale — it is
463
+ * what agents and APIs write), locale-grouped, affixed, localized digits,
464
+ * compact (`1.5k`), accounting negatives (`(1,234.56)` → `-1234.56`), and
465
+ * expressions when `allowExpressions` is set.
466
+ */
467
+ declare const parseNumber: (raw: string, format: UniResolvedNumberFormat, options?: {
468
+ allowExpressions?: boolean;
469
+ currency?: string;
470
+ }) => UniNumberParseResult;
471
+ /**
472
+ * Canonical decimal (model units) → the display number, without affixes.
473
+ *
474
+ * `min2` grouping — the default — starts at five integer digits, so a year
475
+ * renders `2026` rather than `2,026` while a price still renders `10,000`.
476
+ */
477
+ declare const formatNumber: (canonical: string, format: UniResolvedNumberFormat) => string;
478
+ /**
479
+ * The plain text the field shows while focused: the display number with no
480
+ * grouping and no affixes, so the caret never has to walk over a separator
481
+ * that appears and vanishes mid-word.
482
+ */
483
+ declare const rawNumberText: (canonical: string, format: UniResolvedNumberFormat) => string;
484
+ /** Round a committed value to the field's precision, in model units. */
485
+ declare const settleNumber: (canonical: string, format: UniResolvedNumberFormat) => string;
486
+ /**
487
+ * The `aria-valuetext` string: the formatted number with its affixes spoken.
488
+ * `aria-valuenow` alone announces "1234.56", which is the one thing about a
489
+ * money field that is not the point. An empty field says "Empty" per APG.
490
+ */
491
+ declare const speakNumber: (canonical: string | null, format: UniResolvedNumberFormat, emptyText?: string) => string;
492
+ /** Model-units canonical decimal → the bound `number`. */
493
+ declare const toNumber: (canonical: string) => number;
494
+ /**
495
+ * True when a value cannot survive the trip through `number` — the reason the
496
+ * components also expose an exact `valueAsString` model, and the trigger for
497
+ * the dev-mode warning. Silent precision loss is the whole point of that
498
+ * second model, so it is worth saying out loud once.
499
+ *
500
+ * A `number` can only be checked for magnitude, since it has already lost
501
+ * whatever it was going to lose. A canonical string can be checked properly:
502
+ * `'9007199254740993'` comes back as `'9007199254740992'`.
503
+ */
504
+ declare const losesPrecision: (value: number | string) => boolean;
505
+
506
+ /**
507
+ * Hold-to-repeat for stepper buttons: press once to step once, hold to keep
508
+ * stepping, faster the longer you hold. Getting a quantity from 1 to 200 is
509
+ * otherwise 199 clicks.
510
+ *
511
+ * Like the other cdk helpers this owns **no DOM and attaches no listeners to
512
+ * an element** — the component's template hands it the events, which keeps the
513
+ * ARIA and the markup where they belong:
514
+ *
515
+ * ```html
516
+ * <button
517
+ * type="button"
518
+ * tabindex="-1"
519
+ * [disabled]="atMax()"
520
+ * (pointerdown)="increment.press($event)"
521
+ * (pointerup)="increment.release()"
522
+ * (pointercancel)="increment.cancel()"
523
+ * (lostpointercapture)="increment.release()"
524
+ * >
525
+ * ```
526
+ *
527
+ * It does register one `window` blur listener, because a hold that survives
528
+ * the window losing focus is a value that keeps climbing while the user is
529
+ * somewhere else. That listener is torn down with the injection context, so
530
+ * `createPressRepeat` must be called from one — a field initializer, as with
531
+ * `useTimer()`.
532
+ */
533
+
534
+ /** Repeat timings, normally sourced from a component's theme options. */
535
+ interface PressRepeatTiming {
536
+ delayMs?: number;
537
+ intervalMs?: number;
538
+ fastIntervalMs?: number;
539
+ rampMs?: number;
540
+ }
541
+ interface PressRepeatConfig {
542
+ /**
543
+ * Perform one step. `repeat` is `false` for the initial press and `true` for
544
+ * every automatic repeat, so a caller can stay silent during the run.
545
+ */
546
+ onStep: (repeat: boolean) => void;
547
+ /**
548
+ * The hold ended. `repeated` says whether it ever auto-repeated, which is
549
+ * the cue to announce the final value: a screen reader narrating two hundred
550
+ * intermediate values is a denial of service, so announcing belongs here and
551
+ * not in `onStep`.
552
+ */
553
+ onRelease?: (repeated: boolean) => void;
554
+ /** Consulted on press; a disabled button must not start a run. */
555
+ disabled?: () => boolean;
556
+ /**
557
+ * Put focus where it belongs for this control — normally its text field, the
558
+ * way a native spinner does. Called on press, because taking pointer capture
559
+ * means preventing the default, which would otherwise leave focus nowhere.
560
+ *
561
+ * Receives the pressed button, as a fallback for controls with no field to
562
+ * focus.
563
+ */
564
+ focus?: (button: HTMLElement | null) => void;
565
+ /**
566
+ * When this returns `false`, a press steps exactly once and the repeat timer
567
+ * is never armed — `onRelease` still fires, with `repeated: false`. Lets a
568
+ * caller turn hold-to-repeat off without a second set of event bindings.
569
+ */
570
+ repeat?: () => boolean;
571
+ timing?: () => PressRepeatTiming;
572
+ }
573
+ interface PressRepeat {
574
+ /** True while a press is in flight — bind it to the button's pressed state. */
575
+ readonly holding: Signal<boolean>;
576
+ /**
577
+ * Begin a hold and step once immediately. Given a pointer event, it also
578
+ * takes pointer capture, so sliding off the button mid-hold neither strands
579
+ * the repeat nor drops the release.
580
+ */
581
+ press(event?: PointerEvent): void;
582
+ /** End a hold normally, firing `onRelease`. */
583
+ release(): void;
584
+ /** End a hold without firing `onRelease` — for `Escape` and `pointercancel`. */
585
+ cancel(): void;
586
+ }
587
+ declare function createPressRepeat(config: PressRepeatConfig): PressRepeat;
588
+
190
589
  interface ListboxNavigationConfig {
191
590
  /** How many options are currently navigable. Read reactively. */
192
591
  count: () => number;
@@ -806,7 +1205,7 @@ declare class UniCheckboxComponent extends BaseComponent<UniCheckboxOptions> imp
806
1205
  readonly touched: _angular_core.ModelSignal<boolean>;
807
1206
  readonly invalid: _angular_core.InputSignal<boolean>;
808
1207
  readonly dirty: _angular_core.InputSignal<boolean>;
809
- /** Synced from required() validators by the Signal Forms [field] directive. */
1208
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
810
1209
  readonly required: _angular_core.InputSignal<boolean>;
811
1210
  /**
812
1211
  * Id(s) of external element(s) describing this control — typically your
@@ -1066,7 +1465,7 @@ declare class UniDateInputComponent extends BaseComponent<UniDateInputOptions> i
1066
1465
  maxDate: _angular_core.InputSignal<string>;
1067
1466
  disabledDates: _angular_core.InputSignal<string[] | ((date: UniDate) => boolean)>;
1068
1467
  markers: _angular_core.InputSignal<UniCalendarMarker[]>;
1069
- weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 6 | 5>;
1468
+ weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 5 | 6>;
1070
1469
  /** Popup shown. */
1071
1470
  opened: _angular_core.OutputEmitterRef<void>;
1072
1471
  /** Popup hidden. */
@@ -1160,7 +1559,7 @@ declare class UniDateTimeInputComponent extends BaseComponent<UniDateTimeInputOp
1160
1559
  slots: _angular_core.InputSignal<string[]>;
1161
1560
  minuteStep: _angular_core.InputSignal<number>;
1162
1561
  hour12: _angular_core.InputSignal<boolean>;
1163
- weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 6 | 5>;
1562
+ weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 5 | 6>;
1164
1563
  locale: _angular_core.InputSignal<string>;
1165
1564
  /** Scheduling: the day's available times. Gates the time part on a date. */
1166
1565
  slotsFor: _angular_core.InputSignal<(date: UniDate) => UniTime[]>;
@@ -1230,12 +1629,26 @@ declare class UniInputBoxComponent extends BaseComponent<UniInputBoxOptions> {
1230
1629
  width: _angular_core.InputSignal<string | number>;
1231
1630
  fullWidth: _angular_core.InputSignal<boolean>;
1232
1631
  grow: _angular_core.InputSignal<number>;
1632
+ /**
1633
+ * Stop applying the themed leading inset to the inner control, for fields
1634
+ * that place it themselves.
1635
+ *
1636
+ * The inset normally rides the `<input>`, which is right while the text is
1637
+ * the field's leading edge. It is wrong the moment an adornment sits in
1638
+ * front: a currency prefix would hug the border while the number it belongs
1639
+ * to is indented past it. A field with adornments takes the inset over and
1640
+ * puts it on whichever element is actually first.
1641
+ */
1642
+ managedInset: _angular_core.InputSignal<boolean>;
1643
+ /** Auto-height fields (tag input, textarea) still keep the themed height as
1644
+ a floor, so a single-line field lines up with every other input. */
1645
+ protected readonly minHeight: _angular_core.Signal<string | number>;
1233
1646
  protected readonly color: _angular_core.Signal<_uni_design_system_uni_core.ContainerColorToken>;
1234
1647
  protected readonly border: _angular_core.Signal<string>;
1235
1648
  protected readonly shadow: _angular_core.Signal<string>;
1236
1649
  protected readonly inputBoxClass: _angular_core.Signal<string>;
1237
1650
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniInputBoxComponent, never>;
1238
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniInputBoxComponent, "uni-input-box", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "minWidth": { "alias": "minWidth"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1651
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniInputBoxComponent, "uni-input-box", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "minWidth": { "alias": "minWidth"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; "managedInset": { "alias": "managedInset"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1239
1652
  }
1240
1653
 
1241
1654
  /**
@@ -1258,7 +1671,7 @@ declare class UniInputComponent implements FormValueControl<string> {
1258
1671
  readonly touched: _angular_core.ModelSignal<boolean>;
1259
1672
  readonly invalid: _angular_core.InputSignal<boolean>;
1260
1673
  readonly dirty: _angular_core.InputSignal<boolean>;
1261
- /** Synced from required() validators by the Signal Forms [field] directive. */
1674
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
1262
1675
  readonly required: _angular_core.InputSignal<boolean>;
1263
1676
  /**
1264
1677
  * Id(s) of external element(s) describing this control — typically your
@@ -1481,7 +1894,7 @@ declare class UniMultiSelectDropdownComponent<T = unknown> extends BaseComponent
1481
1894
  readonly touched: _angular_core.ModelSignal<boolean>;
1482
1895
  readonly invalid: _angular_core.InputSignal<boolean>;
1483
1896
  readonly dirty: _angular_core.InputSignal<boolean>;
1484
- /** Synced from required() validators by the Signal Forms [field] directive. */
1897
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
1485
1898
  readonly required: _angular_core.InputSignal<boolean>;
1486
1899
  /**
1487
1900
  * Id(s) of external element(s) describing this control — typically your
@@ -1596,7 +2009,7 @@ declare class UniRadioComponent extends BaseComponent<UniRadioOptions> implement
1596
2009
  readonly touched: _angular_core.ModelSignal<boolean>;
1597
2010
  readonly invalid: _angular_core.InputSignal<boolean>;
1598
2011
  readonly dirty: _angular_core.InputSignal<boolean>;
1599
- /** Synced from required() validators by the Signal Forms [field] directive. */
2012
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
1600
2013
  readonly required: _angular_core.InputSignal<boolean>;
1601
2014
  /**
1602
2015
  * Id(s) of external element(s) describing this control — typically your
@@ -1734,7 +2147,7 @@ declare class UniSelectComponent<T> implements FormValueControl<T | null> {
1734
2147
  readonly touched: _angular_core.ModelSignal<boolean>;
1735
2148
  readonly invalid: _angular_core.InputSignal<boolean>;
1736
2149
  readonly dirty: _angular_core.InputSignal<boolean>;
1737
- /** Synced from required() validators by the Signal Forms [field] directive. */
2150
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
1738
2151
  readonly required: _angular_core.InputSignal<boolean>;
1739
2152
  /**
1740
2153
  * Id(s) of external element(s) describing this control — typically your
@@ -1770,51 +2183,833 @@ declare class UniSelectComponent<T> implements FormValueControl<T | null> {
1770
2183
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniSelectComponent<any>, "uni-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "grow": { "alias": "grow"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, never, true, never>;
1771
2184
  }
1772
2185
 
1773
- /** Theme-level options for `uni-slider`, resolved by token name. */
2186
+ /** A labelled stop on the track. `label` folds into `aria-valuetext` at that value. */
2187
+ interface UniSliderMark {
2188
+ value: number;
2189
+ /** Shown under the track and spoken instead of the number, e.g. `'Medium'`. */
2190
+ label?: string;
2191
+ }
2192
+ /** Which thumb a range slider is reporting on. */
2193
+ type UniSliderThumb = 'start' | 'end';
2194
+ /**
2195
+ * Theme-level options for `uni-slider`.
2196
+ *
2197
+ * Fill and thumb colour are deliberately **not** here — they are the `variant`
2198
+ * role pair, the same rule every other component follows, so `variant="warn"`
2199
+ * recolours a slider without a theme edit. The track is a groove rather than an
2200
+ * accent, so it stays a token.
2201
+ */
1774
2202
  interface UniSliderOptions {
1775
- /** Fill and thumb color. */
1776
- color?: ColorKey;
1777
- /** Unfilled track color. */
1778
- trackColor?: ColorKey;
1779
- /** Track and thumb radius token. */
1780
- borderRadius?: Radius;
1781
- /** Track height in px. */
2203
+ /** Track thickness in px. */
1782
2204
  trackHeight?: number;
1783
- /** Thumb diameter in px. */
2205
+ /** Unfilled track colour. */
2206
+ trackColor?: ContainerColorToken;
2207
+ /** Track radius token. */
2208
+ borderRadius?: Radius;
2209
+ /** Visual thumb diameter in px. The hit area is padded to `minTouchTarget`. */
1784
2210
  thumbSize?: number;
2211
+ /** Thumb radius token. */
2212
+ thumbBorderRadius?: Radius;
2213
+ /**
2214
+ * Minimum pointer target for a thumb, in px — WCAG 2.2 SC 2.5.8 floor. The
2215
+ * visual dot stays `thumbSize`; the transparent hit area grows to this.
2216
+ */
2217
+ minTouchTarget?: number;
2218
+ /** Mark dot diameter in px. */
2219
+ markSize?: number;
2220
+ /** Mark dot colour. */
2221
+ markColor?: ColorKey;
2222
+ /** Typography role for the mark labels and the inline readout. */
2223
+ labelTypeface?: Typeface;
2224
+ /** Colour of the mark labels and inline readout. */
2225
+ labelColor?: ColorKey;
2226
+ /** Tooltip background, for `valueDisplay="tooltip"`. */
2227
+ tooltipColor?: ContainerColorToken;
2228
+ /** Tooltip text colour. */
2229
+ tooltipTextColor?: ColorKey;
2230
+ tooltipShadow?: Shadow;
2231
+ tooltipBorderRadius?: Radius;
2232
+ /**
2233
+ * Click-to-jump transition in ms. A drag is never animated — a transition on
2234
+ * a dragged thumb reads as lag — so this applies to keyboard and track
2235
+ * presses only.
2236
+ */
2237
+ transitionMs?: number;
2238
+ }
2239
+
2240
+ /** Index into the thumb pair. `0` is the `start` thumb, `1` the `end` thumb. */
2241
+ type ThumbIndex = 0 | 1;
2242
+ /**
2243
+ * Bounded numeric input by pointer, for values where the *position* is the
2244
+ * information: volume, opacity, weightings, price filters.
2245
+ *
2246
+ * Custom thumbs rather than `<input type="range">`, which the previous version
2247
+ * used: one native range input cannot carry two thumbs, marks or a tooltip, and
2248
+ * a second component for the range case would mean two keyboard maps to keep in
2249
+ * step. The step model and the keyboard map are the cdk's, shared with the
2250
+ * numeric fields, so nothing new is learned moving between them.
2251
+ *
2252
+ * All arithmetic on values runs through the cdk's exact decimal helpers —
2253
+ * stepping `0.1` never yields `0.30000000000000004`. Only pointer *positions*
2254
+ * use floats, and they are snapped to the grid before becoming a value.
2255
+ */
2256
+ declare class UniSliderComponent extends BaseComponent<UniSliderOptions> implements FormValueControl<number | UniNumberRange | null> {
2257
+ /** Shape follows `mode`: a number when `single`, a `UniNumberRange` when `range`. */
2258
+ readonly value: _angular_core.ModelSignal<number | UniNumberRange>;
2259
+ readonly disabled: _angular_core.InputSignal<boolean>;
2260
+ readonly touched: _angular_core.ModelSignal<boolean>;
2261
+ readonly invalid: _angular_core.InputSignal<boolean>;
2262
+ readonly dirty: _angular_core.InputSignal<boolean>;
2263
+ readonly required: _angular_core.InputSignal<boolean>;
2264
+ readonly ariaDescribedBy: _angular_core.InputSignal<string>;
2265
+ /** Accessible name, e.g. "Opacity". Names the group in range mode. */
2266
+ label: _angular_core.InputSignal<string>;
2267
+ mode: _angular_core.InputSignal<"range" | "single">;
2268
+ min: _angular_core.InputSignal<number>;
2269
+ max: _angular_core.InputSignal<number>;
2270
+ step: _angular_core.InputSignal<number>;
2271
+ /** `PageUp`/`PageDown` and `Shift+Arrow`. Default: a tenth of the range. */
2272
+ largeStep: _angular_core.InputSignal<number>;
2273
+ /** Fill anchor. Defaults to `min`; set `0` for a slider that spans ±. */
2274
+ origin: _angular_core.InputSignal<number>;
2275
+ marks: _angular_core.InputSignal<UniSliderMark[]>;
2276
+ /** Marks become the only valid stops — t-shirt sizing, Likert scales. */
2277
+ snapToMarks: _angular_core.InputSignal<boolean>;
2278
+ /**
2279
+ * Where the current value is shown. `tooltip` appears on hover, focus and
2280
+ * drag; `inline` sits at the trailing edge of the track; `input` seats a
2281
+ * compact `uni-number-input` there, two-way bound to the same value — drag
2282
+ * for the ballpark, type for the exact figure, which is the pairing that
2283
+ * makes bounded numeric input actually usable.
2284
+ *
2285
+ * `input` applies to `single` mode only; a range would need two fields, and
2286
+ * `inline` already reads well for two ends.
2287
+ */
2288
+ valueDisplay: _angular_core.InputSignal<"input" | "none" | "tooltip" | "inline">;
2289
+ /** Overrides how a value is rendered and spoken. */
2290
+ formatValue: _angular_core.InputSignal<(value: number) => string>;
2291
+ /** Enforced distance between the two ends, in range mode. */
2292
+ minGap: _angular_core.InputSignal<number>;
2293
+ variant: _angular_core.InputSignal<Variant>;
2294
+ /** Continuous, during a drag or a held key. Bind this for a live preview. */
2295
+ sliding: _angular_core.OutputEmitterRef<number | UniNumberRange>;
2296
+ /**
2297
+ * Committed — on pointer release and key-up. **A form should bind this**:
2298
+ * piping a 60 Hz stream into a model is how sliders get blamed for jank.
2299
+ */
2300
+ changed: _angular_core.OutputEmitterRef<number | UniNumberRange>;
2301
+ private readonly trackRef;
2302
+ private readonly thumbRefs;
2303
+ protected readonly srOnly: string;
2304
+ /** Fences and swaps only — `aria-valuetext` already narrates movement. */
2305
+ protected readonly announcer: _uni_design_system_uni_angular.Announcer;
2306
+ protected readonly groupId: string;
2307
+ /** True from pointerdown until release, to suppress the jump transition. */
2308
+ protected readonly dragging: _angular_core.WritableSignal<boolean>;
2309
+ private draggingThumb;
2310
+ /** Set by keydown, consumed by keyup, so one commit follows a key run. */
2311
+ private keyed;
2312
+ protected readonly isRange: _angular_core.Signal<boolean>;
2313
+ protected readonly resolvedMin: _angular_core.Signal<number>;
2314
+ protected readonly resolvedMax: _angular_core.Signal<number>;
2315
+ private derivePair;
2316
+ /**
2317
+ * The two thumb positions, by **identity** rather than by order: thumb 0 is
2318
+ * whichever thumb the user grabbed first, not necessarily the lower one.
2319
+ *
2320
+ * A `linkedSignal` so an external write to `value` resets them, while a drag
2321
+ * moves them without writing the model on every frame. The computation
2322
+ * deliberately keeps the existing order when the incoming value describes the
2323
+ * same two positions — a commit writes the range back *sorted*, and
2324
+ * re-deriving from that would un-cross a crossed pair and yank the dragged
2325
+ * thumb out from under the pointer mid-drag.
2326
+ */
2327
+ private readonly thumbs;
2328
+ protected readonly thumbIndexes: _angular_core.Signal<ThumbIndex[]>;
2329
+ protected readonly showError: _angular_core.Signal<boolean>;
2330
+ /** Default large step: a tenth of the range, snapped to the step grid. */
2331
+ private readonly resolvedLargeStep;
2332
+ private readonly numberFormat;
2333
+ protected formatted(value: number): string;
2334
+ /** A mark's label speaks for its value, so a marks-only slider says "Medium". */
2335
+ private markLabel;
2336
+ protected valueText(value: number): string;
2337
+ protected percentOf(value: number): number;
2338
+ protected readonly lowValue: _angular_core.Signal<number>;
2339
+ protected readonly highValue: _angular_core.Signal<number>;
2340
+ /** The fill spans between the ends in range mode, or origin → value. */
2341
+ protected readonly fillStart: _angular_core.Signal<number>;
2342
+ protected readonly fillEnd: _angular_core.Signal<number>;
2343
+ protected readonly hasMarkLabels: _angular_core.Signal<boolean>;
2344
+ /** The number-field readout only makes sense for a single value. */
2345
+ protected readonly showReadoutField: _angular_core.Signal<boolean>;
2346
+ /** Fraction digits the readout should accept, taken from the step. */
2347
+ protected readonly readoutDecimals: _angular_core.Signal<[number, number]>;
2348
+ /**
2349
+ * The readout drives the thumb. Guarded against the write-back cycle: the
2350
+ * field is fed from `value`, so a commit here would otherwise bounce.
2351
+ */
2352
+ protected onReadoutValue(next: number | null): void;
2353
+ protected thumbValue(index: ThumbIndex): number;
2354
+ /**
2355
+ * Each thumb's bound is the *other thumb's* position, so a screen-reader user
2356
+ * is told where the wall actually is rather than where the track ends.
2357
+ */
2358
+ protected thumbMin(index: ThumbIndex): number;
2359
+ protected thumbMax(index: ThumbIndex): number;
2360
+ /** Thumbs may cross; which one is "minimum" follows position, not identity. */
2361
+ private isLower;
2362
+ protected thumbLabel(index: ThumbIndex): string;
2363
+ private currentValue;
2364
+ /** Exact `min + n · step`, so a snapped position never carries float drift. */
2365
+ private snapToGrid;
2366
+ private clamp;
2367
+ /**
2368
+ * Move a thumb. `commit` writes the model and emits `changed`; without it the
2369
+ * move is visual and only emits `sliding`.
2370
+ */
2371
+ private setThumb;
2372
+ private commit;
2373
+ private announceValue;
2374
+ /** True when the track is laid out right-to-left. */
2375
+ private isRtl;
2376
+ /** Pointer x → a raw value. The track's visual direction flips in RTL; the value's does not. */
2377
+ private valueFromPointer;
2378
+ private nearestThumb;
2379
+ protected onTrackPointerDown(event: PointerEvent): void;
2380
+ protected onTrackPointerMove(event: PointerEvent): void;
2381
+ protected onTrackPointerUp(): void;
2382
+ /** Adjacent mark, when marks are the only stops. */
2383
+ private markStep;
2384
+ private stepFrom;
2385
+ protected onThumbKeydown(event: KeyboardEvent, index: ThumbIndex): void;
2386
+ /** One commit and one announcement per key run, not per repeat. */
2387
+ protected onThumbKeyup(index: ThumbIndex): void;
2388
+ protected onThumbBlur(): void;
2389
+ protected readonly className: _angular_core.Signal<string>;
2390
+ private readonly fillColor;
2391
+ protected readonly rootClass: _angular_core.Signal<string>;
2392
+ protected readonly rowClass: _angular_core.Signal<string>;
2393
+ protected readonly trackClass: _angular_core.Signal<string>;
2394
+ protected readonly fillClass: _angular_core.Signal<string>;
2395
+ protected readonly markClass: _angular_core.Signal<string>;
2396
+ protected readonly thumbClass: _angular_core.Signal<string>;
2397
+ protected readonly tooltipClass: _angular_core.Signal<string>;
2398
+ protected readonly labelsClass: _angular_core.Signal<string>;
2399
+ protected readonly labelClass: _angular_core.Signal<string>;
2400
+ /** Narrow enough that the track keeps most of the row. */
2401
+ protected readonly readoutFieldClass: _angular_core.Signal<string>;
2402
+ protected readonly readoutClass: _angular_core.Signal<string>;
2403
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniSliderComponent, never>;
2404
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniSliderComponent, "uni-slider, Slider", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "mode": { "alias": "mode"; "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; }; "largeStep": { "alias": "largeStep"; "required": false; "isSignal": true; }; "origin": { "alias": "origin"; "required": false; "isSignal": true; }; "marks": { "alias": "marks"; "required": false; "isSignal": true; }; "snapToMarks": { "alias": "snapToMarks"; "required": false; "isSignal": true; }; "valueDisplay": { "alias": "valueDisplay"; "required": false; "isSignal": true; }; "formatValue": { "alias": "formatValue"; "required": false; "isSignal": true; }; "minGap": { "alias": "minGap"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "sliding": "sliding"; "changed": "changed"; }, never, never, true, never>;
2405
+ }
2406
+
2407
+ /**
2408
+ * Where the stepper buttons sit.
2409
+ *
2410
+ * `stacked` is the dense desktop default; `split` (− … +) is the touch and
2411
+ * quantity language; `trailing` puts − and + together at the end; `none` hides
2412
+ * them, leaving the arrow keys as the only step route.
2413
+ */
2414
+ type UniStepperLayout = 'stacked' | 'split' | 'trailing' | 'none';
2415
+ /** A refused commit. The raw text stays in the field rather than being dropped. */
2416
+ interface UniNumberRejection {
2417
+ raw: string;
2418
+ reason: UniNumberRejectReason;
2419
+ }
2420
+ /** A committed step, for callers that need to distinguish it from typing. */
2421
+ interface UniNumberStepped {
2422
+ from: number | null;
2423
+ to: number;
2424
+ /** The signed amount applied, e.g. `-10` for a large step down. */
2425
+ by: number;
2426
+ }
2427
+ /**
2428
+ * Theme-level options for `uni-number-input`.
2429
+ *
2430
+ * Field chrome — colour, border, radius, focus outline — is **not** duplicated
2431
+ * here. It comes from the shared `input` options via `uni-input-box`, exactly
2432
+ * like tag-input, date-input and combobox, so a number field restyles with
2433
+ * every other field.
2434
+ */
2435
+ interface UniNumberInputOptions {
2436
+ stepperLayout?: UniStepperLayout;
2437
+ /** Glyph for the `+` button in the split and trailing layouts. */
2438
+ incrementIcon?: IconName;
2439
+ /** Glyph for the `−` button in the split and trailing layouts. */
2440
+ decrementIcon?: IconName;
2441
+ /** Glyph for the upper arrow in the stacked layout. */
2442
+ stepUpIcon?: IconName;
2443
+ /** Glyph for the lower arrow in the stacked layout. */
2444
+ stepDownIcon?: IconName;
2445
+ /** Width of a stepper column in px. */
2446
+ stepperWidth?: number;
2447
+ /**
2448
+ * Minimum pointer target for a stepper button, in px — WCAG 2.2 SC 2.5.8.
2449
+ * Applies to the `split` and `trailing` layouts; the two `stacked` arrows
2450
+ * share the field height instead, which is why a coarse pointer switches to
2451
+ * `split`.
2452
+ */
2453
+ minTouchTarget?: number;
2454
+ /** Colour of the prefix/suffix adornments. */
2455
+ affixColor?: ColorKey;
2456
+ /** Space between an adornment and the editable text. */
2457
+ affixGap?: NullableSize;
2458
+ /** Default text alignment; the `align` input overrides it per instance. */
2459
+ align?: 'start' | 'end' | 'center';
2460
+ /** `font-variant-numeric: tabular-nums`, so held stepping does not jitter. */
2461
+ tabularNumerals?: boolean;
2462
+ /** Hold this long before the stepper starts repeating. */
2463
+ repeatDelayMs?: number;
2464
+ /** Repeat period once it starts. */
2465
+ repeatIntervalMs?: number;
2466
+ /** Repeat period at full speed. */
2467
+ repeatFastIntervalMs?: number;
2468
+ /** Hold this long before the repeat begins accelerating. */
2469
+ repeatRampMs?: number;
1785
2470
  }
1786
2471
 
1787
2472
  /**
1788
- * Range slider on a native `<input type="range">` keyboard interaction and
1789
- * the ARIA slider contract come from the platform. Fill, track, thumb and
1790
- * radii resolve from `slider` theme tokens; the fill percentage rides a CSS
1791
- * custom property so dragging never regenerates styles.
2473
+ * Numeric field with locale-aware parsing, `Intl` formatting on commit,
2474
+ * prefix/suffix adornments and steppers that hold to repeat.
2475
+ *
2476
+ * Not `<input type="number">`, and the first reason is a data-loss bug: per the
2477
+ * HTML value sanitization algorithm, a number input whose text is not a valid
2478
+ * floating-point number reports `value === ''`. Type `12,50` as most of Europe
2479
+ * does, or paste `1,234.56` from a spreadsheet, and the app reads an empty
2480
+ * field. This is `type="text"` with `role="spinbutton"`, which is the only way
2481
+ * to keep the user's malformed text on screen and tell them about it.
2482
+ *
2483
+ * Chrome comes from `uni-input-box`, so error, disabled and focus states match
2484
+ * every other field. All arithmetic runs on the cdk's exact decimal helpers.
1792
2485
  */
1793
- declare class UniSliderComponent extends BaseComponent<UniSliderOptions> implements FormValueControl<number> {
2486
+ declare class UniNumberInputComponent extends BaseComponent<UniNumberInputOptions> implements FormValueControl<number | null> {
1794
2487
  readonly value: _angular_core.ModelSignal<number>;
1795
2488
  readonly disabled: _angular_core.InputSignal<boolean>;
1796
2489
  readonly touched: _angular_core.ModelSignal<boolean>;
1797
2490
  readonly invalid: _angular_core.InputSignal<boolean>;
1798
2491
  readonly dirty: _angular_core.InputSignal<boolean>;
1799
- /** Synced from required() validators by the Signal Forms [field] directive. */
1800
2492
  readonly required: _angular_core.InputSignal<boolean>;
2493
+ readonly ariaDescribedBy: _angular_core.InputSignal<string>;
1801
2494
  /**
1802
- * Id(s) of external element(s) describing this control typically your
1803
- * app-rendered value or error text exposed as aria-describedby.
2495
+ * Exact binding, as a canonical decimal string. Bind this instead of `value`
2496
+ * where a cent in the fifth decimal place matters; both stay in sync, so it
2497
+ * is a one-word change from the ordinary case.
2498
+ */
2499
+ readonly valueAsString: _angular_core.ModelSignal<string>;
2500
+ /** Accessible name, e.g. "Unit price". */
2501
+ label: _angular_core.InputSignal<string>;
2502
+ placeholder: _angular_core.InputSignal<string>;
2503
+ preset: _angular_core.InputSignal<UniNumberPreset>;
2504
+ /** ISO 4217 code, e.g. `'USD'`. Implies `preset="currency"`. */
2505
+ currency: _angular_core.InputSignal<string>;
2506
+ /** BCP 47 tag. Defaults to the document language, then the browser's. */
2507
+ locale: _angular_core.InputSignal<string>;
2508
+ /** Static adornment before the number, e.g. `'$'`. Never parseable input. */
2509
+ prefix: _angular_core.InputSignal<string>;
2510
+ /** Static adornment after the number, e.g. `'kg'`, `'/mo'`. */
2511
+ suffix: _angular_core.InputSignal<string>;
2512
+ decimals: _angular_core.InputSignal<number | [min: number, max: number]>;
2513
+ grouping: _angular_core.InputSignal<false | "auto" | "always" | "min2">;
2514
+ /** Escape hatch, merged over the preset. */
2515
+ numberFormat: _angular_core.InputSignal<Intl.NumberFormatOptions>;
2516
+ roundingMode: _angular_core.InputSignal<UniRoundingMode>;
2517
+ align: _angular_core.InputSignal<"center" | "start" | "end">;
2518
+ /** The model is a fraction: `0.15` displays as `15%`. */
2519
+ valueIsFraction: _angular_core.InputSignal<boolean>;
2520
+ /** Spoken long form of an abbreviated suffix, e.g. `'kilograms'` for `kg`. */
2521
+ unitAnnouncement: _angular_core.InputSignal<string>;
2522
+ readOnly: _angular_core.InputSignal<boolean>;
2523
+ /** Renders without its own input-box chrome, for composers like uni-slider. */
2524
+ embedded: _angular_core.InputSignal<boolean>;
2525
+ min: _angular_core.InputSignal<number>;
2526
+ max: _angular_core.InputSignal<number>;
2527
+ step: _angular_core.InputSignal<number>;
2528
+ /** `PageUp`/`PageDown` and `Shift+Arrow`. Default: `step × 10`. */
2529
+ largeStep: _angular_core.InputSignal<number>;
2530
+ /** `Alt+Arrow`, Figma's fine-nudge convention. Unset disables it. */
2531
+ smallStep: _angular_core.InputSignal<number>;
2532
+ stepOrigin: _angular_core.InputSignal<"min" | "zero">;
2533
+ /** Cyclic fields only — 23 → 0 hours, 359 → 0 degrees. */
2534
+ wrap: _angular_core.InputSignal<boolean>;
2535
+ /** `false` refuses an out-of-range commit instead of clamping it. */
2536
+ clampOnCommit: _angular_core.InputSignal<boolean>;
2537
+ /** What ↑ commits on an empty field. Default: `min ?? 0`. */
2538
+ emptyStepValue: _angular_core.InputSignal<number>;
2539
+ commitOnBlur: _angular_core.InputSignal<boolean>;
2540
+ selectOnFocus: _angular_core.InputSignal<boolean>;
2541
+ /** `12*3` → 36. Off by default: a parser in a form field is a real cost. */
2542
+ allowExpressions: _angular_core.InputSignal<boolean>;
2543
+ /** Scroll-to-step. Off by default — see `onWheel`. */
2544
+ wheel: _angular_core.InputSignal<boolean>;
2545
+ repeat: _angular_core.InputSignal<boolean>;
2546
+ /** Custom parser, replacing the built-in locale parsing. */
2547
+ parse: _angular_core.InputSignal<(raw: string, locale: string) => string | null>;
2548
+ /** Overrides the themed layout for this instance. */
2549
+ stepperLayout: _angular_core.InputSignal<_uni_design_system_uni_angular.UniStepperLayout>;
2550
+ stepped: _angular_core.OutputEmitterRef<UniNumberStepped>;
2551
+ /** A commit was refused; the raw text stays in the field. */
2552
+ rejected: _angular_core.OutputEmitterRef<UniNumberRejection>;
2553
+ private readonly inputRef;
2554
+ protected readonly srOnly: string;
2555
+ /** Clamps, fences, rejections and expression results are otherwise silent. */
2556
+ protected readonly announcer: _uni_design_system_uni_angular.Announcer;
2557
+ protected readonly hintId: string;
2558
+ /** Uncommitted text. `null` means "show the committed value". */
2559
+ private readonly draft;
2560
+ /** A commit that failed — styles the field until the text is edited. */
2561
+ protected readonly draftInvalid: _angular_core.WritableSignal<boolean>;
2562
+ protected readonly focused: _angular_core.WritableSignal<boolean>;
2563
+ /**
2564
+ * The canonical decimal behind both models — the field's source of truth.
2565
+ *
2566
+ * Two models that each accept writes need a rule for which one won, and
2567
+ * "whichever the app touched last" is the only one that does not surprise
2568
+ * somebody. A `linkedSignal` over both gives us that: the model whose value
2569
+ * differs from the previous source is the one that changed.
2570
+ *
2571
+ * The subtlety is the echo. Committing writes both models, and the `value`
2572
+ * projection of a 17-digit exact string is lossy — so on the next pass
2573
+ * `value` looks changed, and naively adopting it would clobber the very
2574
+ * precision `valueAsString` exists to keep. A changed `value` that already
2575
+ * matches `Number(exact)` is our own projection coming back, not a write.
2576
+ */
2577
+ private readonly canonical;
2578
+ constructor();
2579
+ protected readonly resolvedLocale: _angular_core.Signal<string>;
2580
+ protected readonly format: _angular_core.Signal<_uni_design_system_uni_angular.UniResolvedNumberFormat>;
2581
+ /**
2582
+ * Two stacked arrows cannot both be 24px tall inside a 32px field, so on a
2583
+ * coarse pointer the stacked layout becomes `split`, where each button is a
2584
+ * full-height square and clears the WCAG 2.2 SC 2.5.8 floor. Two 12px
2585
+ * targets under a fingertip is a coin toss.
2586
+ */
2587
+ private readonly coarsePointer;
2588
+ protected readonly layout: _angular_core.Signal<_uni_design_system_uni_angular.UniStepperLayout>;
2589
+ protected readonly showSteppers: _angular_core.Signal<boolean>;
2590
+ protected readonly showError: _angular_core.Signal<boolean>;
2591
+ /** Raw while focused, formatted once committed — no caret arithmetic ever. */
2592
+ protected readonly displayText: _angular_core.Signal<string>;
2593
+ protected readonly valueTextForAria: _angular_core.Signal<string>;
2594
+ /**
2595
+ * `aria-valuenow` is omitted entirely on an empty field, per APG — a
2596
+ * spinbutton reporting 0 for "nothing yet" is a wrong answer, not a missing
2597
+ * one. `aria-valuetext` carries the localized "Empty" instead.
2598
+ */
2599
+ protected readonly canonicalForAria: _angular_core.Signal<string>;
2600
+ protected readonly describedBy: _angular_core.Signal<string>;
2601
+ private atFence;
2602
+ protected readonly atMin: _angular_core.Signal<boolean>;
2603
+ protected readonly atMax: _angular_core.Signal<boolean>;
2604
+ /** Set the source of truth; the constructor's effect pushes it to both models. */
2605
+ private write;
2606
+ /**
2607
+ * Turn the draft into a value. Out-of-range either clamps (announced) or is
2608
+ * refused, per `clampOnCommit`; unreadable text stays in the field, flagged.
2609
+ */
2610
+ protected commitDraft(): void;
2611
+ private acceptValue;
2612
+ private reject;
2613
+ private rejectionMessage;
2614
+ private stepSize;
2615
+ /**
2616
+ * Apply one step. An empty field commits `emptyStepValue ?? min ?? 0`, so ↑
2617
+ * on a blank quantity gives 1 rather than NaN.
2618
+ */
2619
+ protected applyStep(direction: 1 | -1, magnitude?: 'small' | 'normal' | 'large', announce?: boolean): void;
2620
+ private announceValue;
2621
+ private announceFence;
2622
+ private readonly repeatTiming;
2623
+ /**
2624
+ * The live region announces on release only — a screen reader narrating two
2625
+ * hundred intermediate values is a denial of service.
2626
+ */
2627
+ protected readonly increment: _uni_design_system_uni_angular.PressRepeat;
2628
+ protected readonly decrement: _uni_design_system_uni_angular.PressRepeat;
2629
+ protected onInput(text: string): void;
2630
+ protected onFocus(): void;
2631
+ protected onBlur(): void;
2632
+ protected onKeydown(event: KeyboardEvent): void;
2633
+ /**
2634
+ * Scroll-to-step, off by default. A *focused* `<input type="number">` changes
2635
+ * value on the wheel, which silently corrupts forms people are merely
2636
+ * scrolling past. When enabled this needs focus **and** hover, and it only
2637
+ * calls `preventDefault` when the value actually moved, so a page does not
2638
+ * get scroll-trapped on a field sitting at its max.
2639
+ */
2640
+ protected onWheel(event: WheelEvent): void;
2641
+ protected readonly className: _angular_core.Signal<string>;
2642
+ protected readonly fieldRowClass: _angular_core.Signal<string>;
2643
+ /** The shared field inset, reused on the trailing side so the two match. */
2644
+ private readonly trailingInset;
2645
+ protected readonly inputClass: _angular_core.Signal<string>;
2646
+ /**
2647
+ * The shared field chrome, read from the `input` theme entry — the same entry
2648
+ * `uni-input-box` resolves. Not a duplicate token: the inset has to be the
2649
+ * one every other field uses, or a money field stops lining up with the text
2650
+ * field above it.
1804
2651
  */
2652
+ private readonly fieldChrome;
2653
+ /**
2654
+ * The leading inset for a prefix adornment. When there is a prefix the field
2655
+ * tells the box to stop insetting the `<input>` (`managedInset`) and puts the
2656
+ * inset here instead, so the `$` sits at the field's leading edge with the
2657
+ * number right after it. With no prefix the box keeps doing it — the text is
2658
+ * the leading edge then, and the box's rule outranks this class anyway.
2659
+ * `embedded` fields have no chrome, so they get no inset either.
2660
+ */
2661
+ private readonly leadingInset;
2662
+ private affixBase;
2663
+ /** Carries the field's leading inset, being the first thing in the row. */
2664
+ protected readonly prefixClass: _angular_core.Signal<string>;
2665
+ protected readonly suffixClass: _angular_core.Signal<string>;
2666
+ /** Shared chrome for every stepper button, in any layout. */
2667
+ private stepperButton;
2668
+ /** Split and trailing layouts: one square button per direction. */
2669
+ protected readonly stepperClass: _angular_core.Signal<string>;
2670
+ /** Stacked layout: two half-height arrows sharing one column. */
2671
+ protected readonly stackedColumnClass: _angular_core.Signal<string>;
2672
+ protected readonly stackedButtonClass: _angular_core.Signal<string>;
2673
+ protected readonly glyphSize: _angular_core.Signal<12 | 18>;
2674
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniNumberInputComponent, never>;
2675
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniNumberInputComponent, "uni-number-input, NumberInput", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "valueAsString": { "alias": "valueAsString"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "preset": { "alias": "preset"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "decimals": { "alias": "decimals"; "required": false; "isSignal": true; }; "grouping": { "alias": "grouping"; "required": false; "isSignal": true; }; "numberFormat": { "alias": "numberFormat"; "required": false; "isSignal": true; }; "roundingMode": { "alias": "roundingMode"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "valueIsFraction": { "alias": "valueIsFraction"; "required": false; "isSignal": true; }; "unitAnnouncement": { "alias": "unitAnnouncement"; "required": false; "isSignal": true; }; "readOnly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "embedded": { "alias": "embedded"; "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; }; "largeStep": { "alias": "largeStep"; "required": false; "isSignal": true; }; "smallStep": { "alias": "smallStep"; "required": false; "isSignal": true; }; "stepOrigin": { "alias": "stepOrigin"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "clampOnCommit": { "alias": "clampOnCommit"; "required": false; "isSignal": true; }; "emptyStepValue": { "alias": "emptyStepValue"; "required": false; "isSignal": true; }; "commitOnBlur": { "alias": "commitOnBlur"; "required": false; "isSignal": true; }; "selectOnFocus": { "alias": "selectOnFocus"; "required": false; "isSignal": true; }; "allowExpressions": { "alias": "allowExpressions"; "required": false; "isSignal": true; }; "wheel": { "alias": "wheel"; "required": false; "isSignal": true; }; "repeat": { "alias": "repeat"; "required": false; "isSignal": true; }; "parse": { "alias": "parse"; "required": false; "isSignal": true; }; "stepperLayout": { "alias": "stepperLayout"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "valueAsString": "valueAsStringChange"; "stepped": "stepped"; "rejected": "rejected"; }, never, never, true, never>;
2676
+ }
2677
+
2678
+ /** Which end of the range a rejection or a change came from. */
2679
+ type UniNumberRangePart = 'start' | 'end';
2680
+ /** A refused commit on one end. The raw text stays in that part. */
2681
+ interface UniNumberRangeRejection {
2682
+ part: UniNumberRangePart;
2683
+ raw: string;
2684
+ reason: 'unparseable' | 'not-integer';
2685
+ }
2686
+ /**
2687
+ * Theme-level options for `uni-number-range-input`.
2688
+ *
2689
+ * Field chrome — colour, border, radius, focus outline — is not duplicated
2690
+ * here; it comes from the shared `input` options via `uni-input-box`, so a
2691
+ * range field restyles with every other field. These are the composer's own.
2692
+ */
2693
+ interface UniNumberRangeInputOptions {
2694
+ /** Space between each part and the divider. */
2695
+ partGap?: NullableSize;
2696
+ /**
2697
+ * Text between the two ends. Literal punctuation, not an icon token — an en
2698
+ * dash between two numbers is not a glyph a theme swaps artwork for.
2699
+ */
2700
+ dividerText?: string;
2701
+ dividerColor?: ColorKey;
2702
+ /** Colour of each part's prefix/suffix adornment. */
2703
+ affixColor?: ColorKey;
2704
+ /** Space between an adornment and its number. */
2705
+ affixGap?: NullableSize;
2706
+ }
2707
+
2708
+ /**
2709
+ * Two linked numeric fields in one chrome, with one `{ start, end }` value —
2710
+ * price filters, thresholds, tolerances.
2711
+ *
2712
+ * `start`/`end` deliberately match `UniDateRange`, so the library has one range
2713
+ * vocabulary, and they avoid colliding with the `min`/`max` **inputs**, which
2714
+ * mean the fence rather than the value.
2715
+ *
2716
+ * It owns its commit path rather than nesting two `uni-number-input`s, because
2717
+ * the two behaviours the spec asks for need *different* bounds: a stepper must
2718
+ * be fenced at the other end, while a typed commit must reach the parent
2719
+ * un-clamped so a backwards range can be swapped instead of destroyed. A child
2720
+ * field applies one bound pair to both. The arithmetic, parsing and formatting
2721
+ * are still the cdk's, shared with every other numeric control.
2722
+ */
2723
+ declare class UniNumberRangeInputComponent extends BaseComponent<UniNumberRangeInputOptions> implements FormValueControl<UniNumberRange | null> {
2724
+ readonly value: _angular_core.ModelSignal<UniNumberRange>;
2725
+ readonly disabled: _angular_core.InputSignal<boolean>;
2726
+ readonly touched: _angular_core.ModelSignal<boolean>;
2727
+ readonly invalid: _angular_core.InputSignal<boolean>;
2728
+ readonly dirty: _angular_core.InputSignal<boolean>;
2729
+ readonly required: _angular_core.InputSignal<boolean>;
2730
+ readonly ariaDescribedBy: _angular_core.InputSignal<string>;
2731
+ /** Names the group, e.g. "Price range". */
2732
+ label: _angular_core.InputSignal<string>;
2733
+ startLabel: _angular_core.InputSignal<string>;
2734
+ endLabel: _angular_core.InputSignal<string>;
2735
+ preset: _angular_core.InputSignal<UniNumberPreset>;
2736
+ currency: _angular_core.InputSignal<string>;
2737
+ locale: _angular_core.InputSignal<string>;
2738
+ prefix: _angular_core.InputSignal<string>;
2739
+ suffix: _angular_core.InputSignal<string>;
2740
+ decimals: _angular_core.InputSignal<number | [min: number, max: number]>;
2741
+ grouping: _angular_core.InputSignal<false | "auto" | "always" | "min2">;
2742
+ roundingMode: _angular_core.InputSignal<UniRoundingMode>;
2743
+ placeholderStart: _angular_core.InputSignal<string>;
2744
+ placeholderEnd: _angular_core.InputSignal<string>;
2745
+ min: _angular_core.InputSignal<number>;
2746
+ max: _angular_core.InputSignal<number>;
2747
+ step: _angular_core.InputSignal<number>;
2748
+ /** Enforced distance between the two ends. */
2749
+ minGap: _angular_core.InputSignal<number>;
2750
+ /** The ends were entered backwards and have been exchanged. */
2751
+ swapped: _angular_core.OutputEmitterRef<UniNumberRange>;
2752
+ /** A typed commit on one end could not be read; its text stays in place. */
2753
+ rejected: _angular_core.OutputEmitterRef<UniNumberRangeRejection>;
2754
+ private readonly inputRefs;
2755
+ protected readonly srOnly: string;
2756
+ protected readonly announcer: _uni_design_system_uni_angular.Announcer;
2757
+ protected readonly hintId: string;
2758
+ protected readonly groupId: string;
2759
+ /** Uncommitted text per part. `null` means "show the committed value". */
2760
+ private readonly drafts;
2761
+ private readonly focusedPart;
2762
+ private readonly invalidPart;
2763
+ protected readonly parts: readonly UniNumberRangePart[];
2764
+ private readonly fieldChrome;
2765
+ protected readonly format: _angular_core.Signal<_uni_design_system_uni_angular.UniResolvedNumberFormat>;
2766
+ /** Form-level error, which belongs to both ends. */
2767
+ protected readonly formError: _angular_core.Signal<boolean>;
2768
+ /**
2769
+ * Box-level error. A refused draft in *one* end flags the shared chrome, but
2770
+ * must not flag the other end's input — that end is fine.
2771
+ */
2772
+ protected readonly showError: _angular_core.Signal<boolean>;
2773
+ protected readonly describedBy: _angular_core.Signal<string>;
2774
+ /** The committed canonical decimal for a part, or `null` when that end is open. */
2775
+ private canonicalOf;
2776
+ protected valueOf(part: UniNumberRangePart): number | null;
2777
+ protected displayText(part: UniNumberRangePart): string;
2778
+ protected partLabel(part: UniNumberRangePart): string;
2779
+ protected valueTextOf(part: UniNumberRangePart): string;
2780
+ protected isInvalid(part: UniNumberRangePart): boolean;
2781
+ /** Exact `a ± b` without a float, for the gap arithmetic. */
2782
+ private shiftBy;
2783
+ /**
2784
+ * The fence a part's **stepping** and its ARIA see: the other end, held off
2785
+ * by `minGap`, intersected with the outer bounds. This is deliberately
2786
+ * tighter than what a typed commit is measured against — the steppers must
2787
+ * not walk one end through the other, while typing a backwards range should
2788
+ * be swapped rather than clamped away.
2789
+ */
2790
+ protected stepFence(part: UniNumberRangePart): {
2791
+ min?: number;
2792
+ max?: number;
2793
+ };
2794
+ private writeRange;
2795
+ protected onInput(part: UniNumberRangePart, text: string): void;
2796
+ /**
2797
+ * Commit one part. Out-of-range clamps to the **outer** bounds only, so the
2798
+ * other end never destroys what was typed; the ends are then reconciled.
2799
+ */
2800
+ protected commitPart(part: UniNumberRangePart): void;
2801
+ /**
2802
+ * Put the two ends in order. A backwards pair is **swapped**, not refused —
2803
+ * the same rule `uni-calendar` applies to a backwards date range, because the
2804
+ * user pointed at the range they meant. Otherwise `minGap` is honoured by
2805
+ * pushing the end that was just edited back to the boundary, which is what
2806
+ * makes stepping behave as a fence rather than dragging the other end along.
2807
+ */
2808
+ private reconcile;
2809
+ protected applyStep(part: UniNumberRangePart, direction: 1 | -1, large?: boolean): void;
2810
+ private announceValue;
2811
+ protected onFocus(part: UniNumberRangePart): void;
2812
+ protected onBlur(part: UniNumberRangePart): void;
2813
+ protected onKeydown(event: KeyboardEvent, part: UniNumberRangePart): void;
2814
+ protected readonly className: _angular_core.Signal<string>;
2815
+ protected readonly rowClass: _angular_core.Signal<string>;
2816
+ /** Each end is its own `[prefix][number][suffix]` group. */
2817
+ protected readonly partWrapClass: _angular_core.Signal<string>;
2818
+ protected readonly affixClass: _angular_core.Signal<string>;
2819
+ protected readonly partClass: _angular_core.Signal<string>;
2820
+ private partBase;
2821
+ protected readonly invalidClass: _angular_core.Signal<string>;
2822
+ protected readonly dividerClass: _angular_core.Signal<string>;
2823
+ protected readonly dividerText: _angular_core.Signal<string>;
2824
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniNumberRangeInputComponent, never>;
2825
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniNumberRangeInputComponent, "uni-number-range-input, NumberRangeInput", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "startLabel": { "alias": "startLabel"; "required": false; "isSignal": true; }; "endLabel": { "alias": "endLabel"; "required": false; "isSignal": true; }; "preset": { "alias": "preset"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "decimals": { "alias": "decimals"; "required": false; "isSignal": true; }; "grouping": { "alias": "grouping"; "required": false; "isSignal": true; }; "roundingMode": { "alias": "roundingMode"; "required": false; "isSignal": true; }; "placeholderStart": { "alias": "placeholderStart"; "required": false; "isSignal": true; }; "placeholderEnd": { "alias": "placeholderEnd"; "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; }; "minGap": { "alias": "minGap"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "swapped": "swapped"; "rejected": "rejected"; }, never, never, true, never>;
2826
+ }
2827
+
2828
+ /**
2829
+ * Theme-level options for `uni-quantity-stepper`.
2830
+ *
2831
+ * It is not a field — no label, no error border, no `uni-input-box` — but it
2832
+ * sits beside fields in carts and table rows, so its container **defaults to
2833
+ * the shared `input` chrome**: colour, border, radius and the focus indicator
2834
+ * all follow whatever a theme does to its fields. The options below are
2835
+ * per-component overrides, for parting them deliberately.
2836
+ *
2837
+ * Height comes from the `sizes` block (`sm` 24 / `md` 32 / `lg` 40) rather than
2838
+ * an option, and it is the *outer* height, so an `md` stepper lines up with a
2839
+ * 32px field. The buttons are square at it: `md` and `lg` clear the 24×24
2840
+ * pointer target of WCAG 2.2 SC 2.5.8, while `sm` leaves 22px inside its border
2841
+ * and is therefore the dense desktop option.
2842
+ */
2843
+ interface UniQuantityStepperOptions {
2844
+ /** Container fill. Unset — the default — takes `input`'s. */
2845
+ color?: ContainerColorToken;
2846
+ /** Frame, and the rules either side of the value. Unset takes `input`'s. */
2847
+ border?: Border;
2848
+ /** Corner radius. Unset takes `input`'s. */
2849
+ borderRadius?: Radius;
2850
+ /**
2851
+ * Colour override for the rules between the buttons and the value. Unset —
2852
+ * the default — means they take `border`, so the frame reads as one weight
2853
+ * and the dividers follow the focus border. Set this only for a deliberately
2854
+ * distinct divider.
2855
+ */
2856
+ dividerColor?: ColorKey;
2857
+ incrementIcon?: IconName;
2858
+ decrementIcon?: IconName;
2859
+ /** Replaces the decrement glyph at `min` when `deleteAtMin` is set. */
2860
+ deleteIcon?: IconName;
2861
+ /** `font-variant-numeric: tabular-nums`, so held stepping does not jitter. */
2862
+ tabularNumerals?: boolean;
2863
+ /**
2864
+ * Floor for the value cell, e.g. `'3ch'` — headroom so stepping 9 → 10 does
2865
+ * not reflow the row. Beyond it the cell grows with the digits, because the
2866
+ * input is sized from its content rather than the browser's 20-character
2867
+ * default.
2868
+ */
2869
+ valueWidth?: string | number;
2870
+ }
2871
+
2872
+ /**
2873
+ * `− 3 +` for cart lines, table cells and seat counts: the numeric core with no
2874
+ * field chrome, no label and no room for either.
2875
+ *
2876
+ * A separate component rather than a `chrome="bare"` flag on
2877
+ * `uni-number-input`, because this control is defined by what it does *not*
2878
+ * have — presets, affixes, expressions, four stepper layouts — and eight inputs
2879
+ * are easier to write correctly than forty with a list of which ones to leave
2880
+ * alone. The arithmetic, parsing and hold-to-repeat are the cdk's, shared with
2881
+ * the field, so `1,200` and the keyboard map behave identically in both.
2882
+ *
2883
+ * The middle stays a real input by default: typing `12` beats tapping `+`
2884
+ * eleven times. `editable=false` is for read-mostly tables.
2885
+ */
2886
+ declare class UniQuantityStepperComponent extends BaseComponent<UniQuantityStepperOptions> implements FormValueControl<number | null> {
2887
+ readonly value: _angular_core.ModelSignal<number>;
2888
+ readonly disabled: _angular_core.InputSignal<boolean>;
2889
+ readonly touched: _angular_core.ModelSignal<boolean>;
2890
+ readonly invalid: _angular_core.InputSignal<boolean>;
2891
+ readonly dirty: _angular_core.InputSignal<boolean>;
2892
+ readonly required: _angular_core.InputSignal<boolean>;
1805
2893
  readonly ariaDescribedBy: _angular_core.InputSignal<string>;
2894
+ /**
2895
+ * Accessible name. Never visible and always needed — a cart with six of these
2896
+ * needs "Quantity, Blue T-shirt (M)", not six controls called "Quantity".
2897
+ */
1806
2898
  label: _angular_core.InputSignal<string>;
1807
2899
  min: _angular_core.InputSignal<number>;
1808
2900
  max: _angular_core.InputSignal<number>;
1809
2901
  step: _angular_core.InputSignal<number>;
2902
+ size: _angular_core.InputSignal<Size>;
2903
+ /** `false` renders the number as text: read-mostly tables. */
2904
+ editable: _angular_core.InputSignal<boolean>;
2905
+ /**
2906
+ * The cart pattern in one attribute: at `min` the decrement button becomes a
2907
+ * remove affordance and emits `removed` rather than stepping. Without it
2908
+ * every shop reimplements the same `value === 1 ? remove() : step(-1)` branch
2909
+ * outside the component.
2910
+ */
2911
+ deleteAtMin: _angular_core.InputSignal<boolean>;
2912
+ /**
2913
+ * The remove affordance was activated — the row should come out.
2914
+ *
2915
+ * Named `removed`, not the spec's `emptied`: that word is a native
2916
+ * `HTMLMediaElement` event, which `@angular-eslint/no-output-native` bans for
2917
+ * good reason, and `removed` is already what `uni-tag` calls this same
2918
+ * request.
2919
+ */
2920
+ removed: _angular_core.OutputEmitterRef<void>;
2921
+ private readonly inputRef;
2922
+ protected readonly srOnly: string;
2923
+ protected readonly announcer: _uni_design_system_uni_angular.Announcer;
2924
+ protected readonly hintId: string;
2925
+ /** Uncommitted text. `null` means "show the committed value". */
2926
+ private readonly draft;
2927
+ private readonly canonical;
2928
+ /** Quantities are plain numbers; precision follows the step. */
2929
+ protected readonly format: _angular_core.Signal<_uni_design_system_uni_angular.UniResolvedNumberFormat>;
2930
+ protected readonly displayText: _angular_core.Signal<string>;
2931
+ protected readonly showError: _angular_core.Signal<boolean>;
2932
+ protected readonly describedBy: _angular_core.Signal<string>;
2933
+ /** A quantity has a floor even when a validator has not supplied one. */
1810
2934
  protected readonly resolvedMin: _angular_core.Signal<number>;
1811
- protected readonly resolvedMax: _angular_core.Signal<number>;
1812
- markAsTouched(): void;
1813
- handleInput(event: Event): void;
1814
- protected readonly fillPercent: _angular_core.Signal<string>;
2935
+ protected readonly atMin: _angular_core.Signal<boolean>;
2936
+ protected readonly atMax: _angular_core.Signal<boolean>;
2937
+ /** At the floor with `deleteAtMin`, the − is a remove control instead. */
2938
+ protected readonly showDelete: _angular_core.Signal<boolean>;
2939
+ protected readonly decrementIcon: _angular_core.Signal<_uni_design_system_uni_core.IconName>;
2940
+ protected readonly decrementLabel: _angular_core.Signal<string>;
2941
+ protected onInput(text: string): void;
2942
+ /**
2943
+ * The same parse path as the field, so `1,200` commits as 1200 here too.
2944
+ * Unreadable text reverts rather than being kept: this control has no room to
2945
+ * show an error, and no `rejected` output to report one through.
2946
+ */
2947
+ protected commitDraft(): void;
2948
+ protected applyStep(direction: 1 | -1, announce?: boolean): void;
2949
+ /**
2950
+ * The decrement button has two jobs. Below the floor with `deleteAtMin` it is
2951
+ * a remove control — a single click, with nothing to hold and repeat — so the
2952
+ * press/repeat machinery is skipped entirely in that state.
2953
+ */
2954
+ protected onDecrementPress(event: PointerEvent): void;
2955
+ protected onDecrementClick(): void;
2956
+ private announceValue;
2957
+ private announceFence;
2958
+ /** Announced on release only; narrating every intermediate value is noise. */
2959
+ protected readonly increment: _uni_design_system_uni_angular.PressRepeat;
2960
+ protected readonly decrement: _uni_design_system_uni_angular.PressRepeat;
2961
+ protected onKeydown(event: KeyboardEvent): void;
2962
+ protected onBlur(): void;
2963
+ /**
2964
+ * Focus the field a stepper press should land in. With `editable=false` there
2965
+ * is no field and the buttons are the tab stops, so the pressed button takes
2966
+ * it instead.
2967
+ */
2968
+ protected focusField(fallback?: HTMLElement | null): void;
2969
+ protected readonly className: _angular_core.Signal<string>;
2970
+ /** Overall height, from the theme's `sizes` block. */
2971
+ private readonly height;
2972
+ /**
2973
+ * The shared field chrome, read from the same `input` theme entry
2974
+ * `uni-input-box` resolves. This control has its own container tokens, but the
2975
+ * **focus indicator** has to be the one every other field uses — a stepper
2976
+ * that highlights differently from the field beside it reads as a bug.
2977
+ */
2978
+ private readonly fieldChrome;
2979
+ protected readonly rootClass: _angular_core.Signal<string>;
2980
+ /** Square at the field height, so the pointer target is legal at every size. */
2981
+ protected readonly buttonClass: _angular_core.Signal<string>;
2982
+ /**
2983
+ * Container chrome, defaulting to the shared `input` entry rather than to
2984
+ * hardcoded tokens. It is not a field, but it sits beside them in carts and
2985
+ * table rows, so a theme that restyles `input` must carry it along — the
2986
+ * options below stay as per-component overrides for a deliberately different
2987
+ * look.
2988
+ */
2989
+ private readonly containerColor;
2990
+ private readonly containerBorder;
2991
+ private readonly containerRadius;
2992
+ /** The rules either side of the value, matching the frame around it. */
2993
+ private readonly dividerBorder;
2994
+ /**
2995
+ * Characters the value cell asks the browser to size itself for.
2996
+ *
2997
+ * Load-bearing: a bare `<input>` defaults to `size="20"`, and `flex-basis:
2998
+ * auto` resolves to that intrinsic width — so the control claimed ~230px
2999
+ * instead of the ~100px its buttons and `valueWidth` need, and stole track
3000
+ * width from anything beside it in a grid (`1fr` is `minmax(auto, 1fr)`, and
3001
+ * the `auto` floor includes this). Tracking the content keeps the cell honest
3002
+ * while still letting it grow with the digits, which a fixed `width` would
3003
+ * not. `valueWidth` remains the floor, via `min-width`.
3004
+ */
3005
+ protected readonly valueSize: _angular_core.Signal<number>;
3006
+ private valueBase;
1815
3007
  protected readonly inputClass: _angular_core.Signal<string>;
1816
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniSliderComponent, never>;
1817
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniSliderComponent, "uni-slider", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, never, true, never>;
3008
+ /** Read-only presentation: centred text on the same grid as the input. */
3009
+ protected readonly readoutClass: _angular_core.Signal<string>;
3010
+ protected readonly glyphSize: _angular_core.Signal<number>;
3011
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniQuantityStepperComponent, never>;
3012
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniQuantityStepperComponent, "uni-quantity-stepper, QuantityStepper", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "deleteAtMin": { "alias": "deleteAtMin"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "removed": "removed"; }, never, never, true, never>;
1818
3013
  }
1819
3014
 
1820
3015
  /**
@@ -1951,6 +3146,13 @@ declare class UniTagInputComponent extends BaseComponent<UniTagInputOptions> imp
1951
3146
  has the same geometry but is only the fallback's positioning context. */
1952
3147
  protected readonly className: _angular_core.Signal<string>;
1953
3148
  protected readonly wrapperClass: _angular_core.Signal<string>;
3149
+ /**
3150
+ * The shared field chrome, from the same `input` theme entry
3151
+ * `uni-input-box` resolves — not a duplicate token, because the inset has to
3152
+ * match every other field or a chip field stops lining up with the text
3153
+ * field above it.
3154
+ */
3155
+ private readonly fieldChrome;
1954
3156
  protected readonly fieldClass: _angular_core.Signal<string>;
1955
3157
  protected readonly inputClass: _angular_core.Signal<string>;
1956
3158
  protected readonly listClass: _angular_core.Signal<string>;
@@ -1997,7 +3199,7 @@ declare class UniTextareaComponent implements FormValueControl<string> {
1997
3199
  readonly touched: _angular_core.ModelSignal<boolean>;
1998
3200
  readonly invalid: _angular_core.InputSignal<boolean>;
1999
3201
  readonly dirty: _angular_core.InputSignal<boolean>;
2000
- /** Synced from required() validators by the Signal Forms [field] directive. */
3202
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
2001
3203
  readonly required: _angular_core.InputSignal<boolean>;
2002
3204
  /**
2003
3205
  * Id(s) of external element(s) describing this control — typically your
@@ -2138,13 +3340,26 @@ declare class UniTimeInputComponent extends BaseComponent<UniTimeInputOptions> i
2138
3340
 
2139
3341
  interface UniToggleOptions {
2140
3342
  /**
2141
- * The size of the toggle switch
3343
+ * @deprecated Track height in px, from before the toggle had a `sizes` block.
3344
+ * Still honoured — and still wins when set, since a theme carrying it opted
3345
+ * into the old derived-ratio geometry (width = 2x, knob = 0.8x) — but it
3346
+ * applies to every instance regardless of the `size` input. Prefer the
3347
+ * theme's `toggle.sizes` block, which gives each size token its own
3348
+ * `width` / `height` / `padding`.
2142
3349
  */
2143
3350
  size?: number;
2144
3351
  /** Off-state track color token. */
2145
3352
  trackColor?: ColorKey;
2146
3353
  /** Knob color token. */
2147
3354
  knobColor?: ColorKey;
3355
+ /**
3356
+ * Checked-state track color token. Falls back to the instance's `variant`,
3357
+ * which is where this color lived before it had a theme home. The matching
3358
+ * `checkedColor` input overrides it per instance.
3359
+ */
3360
+ checkedColor?: ColorKey;
3361
+ /** Motion token for the knob slide and track color change. */
3362
+ motion?: Motion;
2148
3363
  }
2149
3364
 
2150
3365
  declare class UniToggleComponent extends BaseComponent<UniToggleOptions> implements FormCheckboxControl {
@@ -2153,7 +3368,7 @@ declare class UniToggleComponent extends BaseComponent<UniToggleOptions> impleme
2153
3368
  readonly touched: _angular_core.ModelSignal<boolean>;
2154
3369
  readonly invalid: _angular_core.InputSignal<boolean>;
2155
3370
  readonly dirty: _angular_core.InputSignal<boolean>;
2156
- /** Synced from required() validators by the Signal Forms [field] directive. */
3371
+ /** Synced from required() validators by the Signal Forms [formField] directive. */
2157
3372
  readonly required: _angular_core.InputSignal<boolean>;
2158
3373
  /**
2159
3374
  * Id(s) of external element(s) describing this control — typically your
@@ -2161,15 +3376,37 @@ declare class UniToggleComponent extends BaseComponent<UniToggleOptions> impleme
2161
3376
  */
2162
3377
  readonly ariaDescribedBy: _angular_core.InputSignal<string>;
2163
3378
  readonly label: _angular_core.InputSignal<string>;
3379
+ /**
3380
+ * Checked-state track color token, overriding the theme's
3381
+ * `toggle.behavior.checkedColor`.
3382
+ *
3383
+ * This exists alongside the theme option because `variant` — where this color
3384
+ * used to live exclusively — defaults to `'primary'`, so the component cannot
3385
+ * tell "set to primary" from "not set". Without an input, a theme-level
3386
+ * `checkedColor` would silently make per-instance `variant` inert.
3387
+ */
3388
+ readonly checkedColor: _angular_core.InputSignal<string>;
2164
3389
  protected readonly showError: _angular_core.Signal<boolean>;
2165
3390
  markAsTouched(): void;
2166
3391
  handleChange(event: Event): void;
3392
+ /**
3393
+ * Track and knob geometry for the active `size`, read out of the theme's
3394
+ * `sizes` block as data — `width`, `height` and the knob's inset `padding`.
3395
+ *
3396
+ * Read rather than spread: `padding` must not reach the track as real CSS or
3397
+ * it would double up with the knob's own `top`/`left` offsets. `uni-calendar`
3398
+ * treats its size block the same way.
3399
+ */
2167
3400
  private readonly metrics;
3401
+ /** The resolved checked/accent color: input, then theme option, then variant. */
3402
+ private readonly accent;
3403
+ /** Knob slide and track color change, as a motion token — never `all`. */
3404
+ private readonly transitions;
2168
3405
  protected readonly toggleLabel: _angular_core.Signal<string>;
2169
3406
  protected readonly toggleInput: _angular_core.Signal<string>;
2170
3407
  getThemeColor(token: ColorToken): string;
2171
3408
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniToggleComponent, never>;
2172
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniToggleComponent, "uni-toggle", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "touched": "touchedChange"; }, never, never, true, never>;
3409
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniToggleComponent, "uni-toggle", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "checkedColor": { "alias": "checkedColor"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "touched": "touchedChange"; }, never, never, true, never>;
2173
3410
  }
2174
3411
 
2175
3412
  /**
@@ -2182,7 +3419,7 @@ declare class UniToggleComponent extends BaseComponent<UniToggleOptions> impleme
2182
3419
  */
2183
3420
  declare const UNI_LAYOUT: readonly [typeof UniBoxDirective, typeof UniRowDirective, typeof UniStackDirective, typeof UniCenterDirective, typeof UniWrapDirective, typeof UniGridDirective, typeof UniGridAreaDirective, typeof UniTextDirective];
2184
3421
  /** Every form control, for `imports: [...UNI_FORMS]`. */
2185
- declare const UNI_FORMS: readonly [typeof UniInputComponent, typeof UniInputBoxComponent, typeof UniTextareaComponent, typeof UniSelectComponent, typeof UniCheckboxComponent, typeof UniRadioComponent, typeof UniToggleComponent, typeof UniComboboxComponent, typeof UniMultiSelectComponent, typeof UniMultiSelectDropdownComponent, typeof UniSearchInputComponent, typeof UniTagInputComponent, typeof UniSliderComponent, typeof UniDateInputComponent, typeof UniTimeInputComponent, typeof UniDateTimeInputComponent];
3422
+ declare const UNI_FORMS: readonly [typeof UniInputComponent, typeof UniInputBoxComponent, typeof UniTextareaComponent, typeof UniSelectComponent, typeof UniCheckboxComponent, typeof UniRadioComponent, typeof UniToggleComponent, typeof UniComboboxComponent, typeof UniMultiSelectComponent, typeof UniMultiSelectDropdownComponent, typeof UniSearchInputComponent, typeof UniTagInputComponent, typeof UniNumberInputComponent, typeof UniNumberRangeInputComponent, typeof UniQuantityStepperComponent, typeof UniSliderComponent, typeof UniDateInputComponent, typeof UniTimeInputComponent, typeof UniDateTimeInputComponent];
2186
3423
 
2187
3424
  /** Theme-level options for `uni-app-bar`, resolved by token name. */
2188
3425
  interface UniAppBarOptions {
@@ -2448,7 +3685,7 @@ declare class UniCalendarComponent extends BaseComponent<UniCalendarOptions> imp
2448
3685
  /** BCP 47 tag; defaults to the document language, then the browser's. */
2449
3686
  locale: _angular_core.InputSignal<string>;
2450
3687
  /** First day of week, 0 = Sunday; defaults from the locale's week info. */
2451
- weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 6 | 5>;
3688
+ weekStart: _angular_core.InputSignal<0 | 1 | 2 | 3 | 4 | 5 | 6>;
2452
3689
  /** Names the grid when it stands alone (otherwise the heading names it). */
2453
3690
  ariaLabel: _angular_core.InputSignal<string>;
2454
3691
  /** Day geometry token; `sm`/`md`/`lg` map to the theme's `calendar` sizes. */
@@ -2934,10 +4171,147 @@ declare class UniDividerComponent {
2934
4171
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniDividerComponent, "uni-divider", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "border": { "alias": "border"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2935
4172
  }
2936
4173
 
4174
+ /**
4175
+ * Theme-level options for the drawer's pinned footer action row. Inputs on the
4176
+ * component override these per instance; the theme sets the default posture.
4177
+ *
4178
+ * Mirrors `UniDialogButtonsOptions` knob for knob, with a panel's posture
4179
+ * rather than a dialog's: trailing actions instead of centered ones, and a
4180
+ * divider against the scrolling body above.
4181
+ */
4182
+ interface UniDrawerButtonsOptions {
4183
+ /** Space between the action buttons, as a spacing token. */
4184
+ gap?: NullableSize;
4185
+ /** Padding around the row, as a spacing token. */
4186
+ padding?: NullableSize;
4187
+ justifyContent?: JustifyContent;
4188
+ confirmButtonVariant?: Variant;
4189
+ cancelButtonVariant?: Variant;
4190
+ /** Size passed to both buttons. */
4191
+ buttonSize?: Size;
4192
+ /** Rule separating the footer from the scrolling body, as a border primitive. */
4193
+ divider?: Border;
4194
+ /** When true the two actions share the full row width as equal halves. */
4195
+ stretch?: boolean;
4196
+ /** Render cancel before confirm (confirm ends up on the trailing edge). */
4197
+ reverseOrder?: boolean;
4198
+ }
4199
+
4200
+ /**
4201
+ * The drawer's pinned footer action row — the save bar of an editor panel.
4202
+ *
4203
+ * Sits outside the scrolling body, so the actions stay reachable however long
4204
+ * the form is. Mirrors `[dialog-buttons]`; the difference is posture, which
4205
+ * lives in the `drawerButtons` theme options rather than here.
4206
+ */
4207
+ declare class UniDrawerButtonsComponent extends BaseComponent<UniDrawerButtonsOptions> {
4208
+ private readonly drawer;
4209
+ confirmButtonText: _angular_core.InputSignal<string>;
4210
+ confirmButtonVariant: _angular_core.InputSignal<Variant>;
4211
+ cancelButtonText: _angular_core.InputSignal<string>;
4212
+ cancelButtonVariant: _angular_core.InputSignal<Variant>;
4213
+ disableConfirm: _angular_core.InputSignal<boolean>;
4214
+ padding: _angular_core.InputSignal<NullableSize>;
4215
+ justifyContent: _angular_core.InputSignal<JustifyContent>;
4216
+ confirmed: _angular_core.OutputEmitterRef<void>;
4217
+ protected confirmVariant: _angular_core.Signal<Variant>;
4218
+ protected cancelVariant: _angular_core.Signal<Variant>;
4219
+ protected paddingValue: _angular_core.Signal<NullableSize>;
4220
+ protected justifyContentValue: _angular_core.Signal<JustifyContent>;
4221
+ protected gapValue: _angular_core.Signal<NullableSize>;
4222
+ protected buttonSize: _angular_core.Signal<Size>;
4223
+ /** A pinned row, sized by its content rather than by the body beside it. */
4224
+ protected readonly hostClass: _angular_core.Signal<string>;
4225
+ protected readonly className: _angular_core.Signal<string>;
4226
+ /**
4227
+ * Cancel routes through the drawer's own close decision, so a panel with
4228
+ * unsaved changes can veto it exactly as it vetoes Escape.
4229
+ */
4230
+ protected closeDrawer(): void;
4231
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniDrawerButtonsComponent, never>;
4232
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniDrawerButtonsComponent, "[uni-drawer-buttons], [drawer-buttons]", never, { "confirmButtonText": { "alias": "confirmButtonText"; "required": false; "isSignal": true; }; "confirmButtonVariant": { "alias": "confirmButtonVariant"; "required": false; "isSignal": true; }; "cancelButtonText": { "alias": "cancelButtonText"; "required": false; "isSignal": true; }; "cancelButtonVariant": { "alias": "cancelButtonVariant"; "required": false; "isSignal": true; }; "disableConfirm": { "alias": "disableConfirm"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "justifyContent": { "alias": "justifyContent"; "required": false; "isSignal": true; }; }, { "confirmed": "confirmed"; }, never, never, true, never>;
4233
+ }
4234
+
4235
+ /**
4236
+ * Theme-level options for the drawer's pinned header row. Deliberately a
4237
+ * separate entry from `dialogHeader`: the two rows look alike but read
4238
+ * differently — a panel headline labels a region beside the page, where a
4239
+ * dialog's titles an interruption — so they want different defaults.
4240
+ */
4241
+ interface UniDrawerHeaderOptions {
4242
+ /** Row surface. Undefined inherits the drawer's own surface. */
4243
+ color?: ContainerColorToken;
4244
+ /** Fixed row height in px. */
4245
+ height?: number;
4246
+ /** Padding around the row, as a spacing token. */
4247
+ padding?: NullableSize;
4248
+ textRole?: TextRole;
4249
+ textColor?: ContentColorToken;
4250
+ textAlign?: 'left' | 'center' | 'right';
4251
+ /** Rule separating the header from the scrolling body, as a border primitive. */
4252
+ divider?: Border;
4253
+ closeButtonIcon?: IconName;
4254
+ closeButtonSymbol?: string;
4255
+ closeButtonSize?: Size;
4256
+ }
4257
+
4258
+ /**
4259
+ * The drawer's pinned header row: a title, and optionally a close button.
4260
+ *
4261
+ * Sits outside the scrolling body, so it stays put while the form beneath it
4262
+ * moves. Reached either by projecting it — `<div uni-drawer-header>` — or
4263
+ * implicitly, by giving `uni-drawer` a `headline`, in which case the drawer
4264
+ * renders one of these itself.
4265
+ */
4266
+ declare class UniDrawerHeaderComponent extends BaseComponent<UniDrawerHeaderOptions> {
4267
+ private readonly drawer;
4268
+ /** Title text. Falls back to the drawer's `headline`; projected content wins over both. */
4269
+ headline: _angular_core.InputSignal<string>;
4270
+ /** Attached to the title so the drawer is labelled by it. */
4271
+ protected readonly titleId: string;
4272
+ protected readonly title: _angular_core.Signal<string>;
4273
+ protected readonly showClose: _angular_core.Signal<boolean>;
4274
+ constructor();
4275
+ /** Never a bare close: the drawer decides, so a veto is honoured here too. */
4276
+ protected closeDrawer(): void;
4277
+ protected readonly className: _angular_core.Signal<string>;
4278
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniDrawerHeaderComponent, never>;
4279
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniDrawerHeaderComponent, "[uni-drawer-header]", never, { "headline": { "alias": "headline"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
4280
+ }
4281
+
2937
4282
  /** How the drawer coexists with page content. */
2938
4283
  type DrawerMode = 'side' | 'over';
2939
4284
  /** Which edge the drawer attaches to (logical: start = left in LTR). */
2940
4285
  type DrawerPosition = 'start' | 'end';
4286
+ /** Surface treatment of the panel behind its content. */
4287
+ type DrawerBackground = 'solid' | 'glass' | 'gradient';
4288
+ /** Why the drawer is asking to close. */
4289
+ type DrawerCloseReason = 'close-button' | 'escape' | 'backdrop';
4290
+ /**
4291
+ * Emitted by `closeRequest` before the drawer closes. The drawer is *asking*;
4292
+ * with `disableAutoClose` set it will not act on its own, leaving the consumer
4293
+ * free to run an async confirmation and set `open` when it resolves.
4294
+ */
4295
+ interface UniDrawerCloseRequest {
4296
+ reason: DrawerCloseReason;
4297
+ }
4298
+ /**
4299
+ * The slice of the drawer its header and footer rows need.
4300
+ *
4301
+ * A token rather than the component class on purpose: the drawer renders a
4302
+ * `[uni-drawer-header]` itself when given a `headline`, so importing the
4303
+ * component class in both directions would be a cycle.
4304
+ */
4305
+ interface UniDrawerPanel {
4306
+ readonly headline: Signal<string | undefined>;
4307
+ readonly defaultCloseButton: Signal<boolean>;
4308
+ readonly titleId: string;
4309
+ readonly hasHeader: {
4310
+ set(value: boolean): void;
4311
+ };
4312
+ requestClose(reason: DrawerCloseReason): void;
4313
+ }
4314
+ declare const DRAWER_PANEL: InjectionToken<UniDrawerPanel>;
2941
4315
  /** Theme-level options for `uni-drawer`, resolved by token name. */
2942
4316
  interface UniDrawerOptions {
2943
4317
  /** Panel surface color token (with its paired on-color). */
@@ -2946,16 +4320,27 @@ interface UniDrawerOptions {
2946
4320
  width?: number;
2947
4321
  /** Edge rule separating a side drawer from content, as a border primitive. */
2948
4322
  divider?: Border;
2949
- /** Elevation shadow token for the overlay mode. */
4323
+ /** Elevation shadow token. Overlay mode only see `background`. */
2950
4324
  elevation?: Elevation;
2951
- /** Inner padding, as a spacing token. */
4325
+ /**
4326
+ * Inner padding of the *body* row, as a spacing token. The panel itself is
4327
+ * unpadded so that header and footer rows can pin flush to its edges.
4328
+ */
2952
4329
  padding?: OptionalSize;
2953
- /** Backdrop styling for the overlay mode. */
4330
+ /** Backdrop styling for the overlay mode. Ignored when `scrim` is false. */
2954
4331
  backdrop?: StyleExpression;
4332
+ /**
4333
+ * Whether the overlay mode dims the page behind it. False leaves
4334
+ * `::backdrop` transparent — the drawer still traps focus and is still
4335
+ * modal, it simply does not darken what it covers.
4336
+ */
4337
+ scrim?: boolean;
4338
+ /** Surface treatment of the panel. */
4339
+ background?: DrawerBackground;
2955
4340
  }
2956
4341
 
2957
4342
  /**
2958
- * Navigation drawer with two modes sharing one content slot:
4343
+ * Drawer with two modes sharing one three-row layout:
2959
4344
  *
2960
4345
  * - `side` — an in-flow `<aside>` that pushes content (dashboard sidenav);
2961
4346
  * opening/closing animates its width, and the divider border primitive
@@ -2964,19 +4349,86 @@ interface UniDrawerOptions {
2964
4349
  * scrim backdrop come from the platform (same machinery as `uni-dialog`),
2965
4350
  * sliding in from its edge.
2966
4351
  *
2967
- * Surface, width, divider, elevation, padding and backdrop all resolve from
2968
- * `drawer` theme tokens.
4352
+ * **The panel is never the scroll container.** It is a flex column of three
4353
+ * rows — an optional `[uni-drawer-header]`, the projected body, an optional
4354
+ * `[uni-drawer-buttons]` — and only the body scrolls. The panel itself is
4355
+ * `overflow: clip` on both axes. That is what lets a header and a save bar pin
4356
+ * while a long form scrolls between them, and it is why the theme's `padding`
4357
+ * option lands on the body row rather than the panel: padding on a scrolling
4358
+ * box scrolls away with its content.
4359
+ *
4360
+ * Surface, width, divider, elevation, padding, backdrop, scrim and background
4361
+ * all resolve from `drawer` theme tokens.
2969
4362
  */
2970
4363
  declare class UniDrawerComponent extends BaseComponent<UniDrawerOptions> {
2971
4364
  /** Two-way bindable open state: [(open)]. */
2972
4365
  readonly open: _angular_core.ModelSignal<boolean>;
2973
4366
  mode: _angular_core.InputSignal<DrawerMode>;
2974
4367
  position: _angular_core.InputSignal<DrawerPosition>;
2975
- /** Accessible name for the overlay mode's dialog. */
4368
+ /**
4369
+ * Accessible name for the overlay mode. Only consulted when the drawer has
4370
+ * no header to be labelled by.
4371
+ *
4372
+ * There is deliberately no default. A drawer used as an editor panel that
4373
+ * inherited the literal "Navigation" would announce itself as something it
4374
+ * is not, and a wrong accessible name is worse than a missing one — the
4375
+ * missing one is at least caught by any audit.
4376
+ */
2976
4377
  ariaLabel: _angular_core.InputSignal<string>;
2977
- protected readonly contentTemplate: _angular_core.Signal<TemplateRef<unknown>>;
4378
+ /**
4379
+ * Title for the drawer's header row. Shorthand for projecting a
4380
+ * `[uni-drawer-header]`; project one instead when the header needs more
4381
+ * than a title (a record counter, prev/next navigation).
4382
+ */
4383
+ headline: _angular_core.InputSignal<string>;
4384
+ /** Whether the header row renders a close button. */
4385
+ defaultCloseButton: _angular_core.InputSignal<boolean>;
4386
+ /** Panel width in px, overriding the theme's `drawer.behavior.width`. */
4387
+ width: _angular_core.InputSignal<number>;
4388
+ /**
4389
+ * Whether the overlay dims the page behind it, overriding the theme's
4390
+ * `drawer.behavior.scrim`. False leaves the backdrop transparent so the page
4391
+ * stays legible while the panel is open — an editor panel beside a board the
4392
+ * user is still reading.
4393
+ *
4394
+ * This does not make the drawer non-modal: focus is still trapped and the
4395
+ * page behind is still inert. It is a visibility choice, not a modality one.
4396
+ */
4397
+ scrim: _angular_core.InputSignal<boolean>;
4398
+ /**
4399
+ * CSS selector for the element to focus when the overlay opens. The native
4400
+ * default is the first focusable element, which in an editor panel is
4401
+ * usually the close button rather than the first field.
4402
+ */
4403
+ initialFocus: _angular_core.InputSignal<string>;
4404
+ /**
4405
+ * The drawer is *asking* to close — Escape, the backdrop, or a close/cancel
4406
+ * button. Pair with `disableAutoClose` to hold the panel open while an async
4407
+ * confirmation runs.
4408
+ */
4409
+ closeRequest: _angular_core.OutputEmitterRef<UniDrawerCloseRequest>;
4410
+ /**
4411
+ * When true the drawer never closes itself; it only emits `closeRequest` and
4412
+ * waits for the consumer to set `open`. Off by default, so a drawer that
4413
+ * ignores `closeRequest` behaves exactly as it always has.
4414
+ */
4415
+ disableAutoClose: _angular_core.InputSignal<boolean>;
4416
+ /** Set by a projected `[uni-drawer-header]` so it can pin flush to the top. */
4417
+ readonly hasHeader: _angular_core.WritableSignal<boolean>;
4418
+ /** Id referenced by aria-labelledby; the header row attaches it to its title. */
4419
+ readonly titleId: string;
4420
+ protected readonly labelledBy: _angular_core.Signal<string>;
4421
+ protected readonly headerTemplate: _angular_core.Signal<TemplateRef<unknown>>;
4422
+ protected readonly bodyTemplate: _angular_core.Signal<TemplateRef<unknown>>;
4423
+ protected readonly footerTemplate: _angular_core.Signal<TemplateRef<unknown>>;
2978
4424
  private readonly overlay;
2979
4425
  constructor();
4426
+ /**
4427
+ * The one place a close is decided, so every route in — Escape, the
4428
+ * backdrop, the header's close button, the footer's cancel — behaves
4429
+ * identically and is equally vetoable.
4430
+ */
4431
+ requestClose(reason: DrawerCloseReason): void;
2980
4432
  protected onBackdropClick(event: Event): void;
2981
4433
  /** Route Escape through the animated close, keeping `open` in sync. */
2982
4434
  protected onCancel(event: Event): void;
@@ -2984,10 +4436,23 @@ declare class UniDrawerComponent extends BaseComponent<UniDrawerOptions> {
2984
4436
  private readonly edge;
2985
4437
  private readonly slideIn;
2986
4438
  private readonly slideOut;
4439
+ /** Input wins over the theme option; the literal is the last-resort default. */
4440
+ private readonly panelWidth;
4441
+ private readonly showScrim;
4442
+ /**
4443
+ * The panel's surface. `solid` is the plain color pair; `glass` and
4444
+ * `gradient` derive from it, so a theme swaps treatment without restating
4445
+ * the color.
4446
+ */
4447
+ private readonly surface;
4448
+ /** The shared flex column: three rows, and never a scroll container itself. */
4449
+ private readonly shell;
2987
4450
  protected readonly sideClass: _angular_core.Signal<string>;
2988
4451
  protected readonly overClass: _angular_core.Signal<string>;
4452
+ /** The only scrolling row, and the only padded one. */
4453
+ protected readonly bodyClass: _angular_core.Signal<string>;
2989
4454
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UniDrawerComponent, never>;
2990
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniDrawerComponent, "uni-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
4455
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UniDrawerComponent, "uni-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "headline": { "alias": "headline"; "required": false; "isSignal": true; }; "defaultCloseButton": { "alias": "defaultCloseButton"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "scrim": { "alias": "scrim"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; "disableAutoClose": { "alias": "disableAutoClose"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "closeRequest": "closeRequest"; }, never, ["[uni-drawer-header]", "[uni-drawer-buttons], [drawer-buttons]", "*"], true, never>;
2991
4456
  }
2992
4457
 
2993
4458
  interface UniDropdownOptions {
@@ -4456,5 +5921,5 @@ declare class DragAndDropDirective {
4456
5921
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DragAndDropDirective, "[uni-drag-n-drop], [dragAndDrop]", never, {}, { "fileDropped": "fileDropped"; }, never, never, true, never>;
4457
5922
  }
4458
5923
 
4459
- export { BodyRenderDirective, ConfirmationDialogComponent, DragAndDropDirective, FOCUSABLE_SELECTOR, ListboxNavigation, LocalStorageService, NotificationService, NotificationsComponent, RippleDirective, TRANSFORM_ORIGINS, ThemeService, UNI_FORMS, UNI_LAYOUT, UNI_THEMES, UniAlertComponent, UniAppBarComponent, UniAvatarComponent, UniAvatarGroupComponent, UniBackgroundComponent, UniBadgeComponent, UniBaseDatasource, UniBoxDirective, UniBreadcrumbComponent, UniButtonComponent, UniButtonGroupComponent, UniCalendarComponent, UniCalloutComponent, UniCardComponent, UniCardContentComponent, UniCardHeaderComponent, UniCenterDirective, UniCheckboxComponent, UniComboboxComponent, UniDataSearchComponent, UniDataTableComponent, UniDateInputComponent, UniDateTimeInputComponent, UniDebounceInputComponent, UniDialogButtonsComponent, UniDialogComponent, UniDialogHeaderComponent, UniDividerComponent, UniDrawerComponent, UniDropdownComponent, UniExpandAreaComponent, UniExpandComponent, UniExpandToggleComponent, UniFileDropZoneComponent, UniGridAreaDirective, UniGridDirective, UniIconButtonComponent, UniIconComponent, UniInputBoxComponent, UniInputComponent, UniJsonViewComponent, UniMenuComponent, UniMultiSelectComponent, UniMultiSelectDropdownComponent, UniNotificationBadgeComponent, UniPaginatorComponent, UniPopoverComponent, UniProgressBarComponent, UniProgressGaugeComponent, UniRadioComponent, UniRecordDatasource, UniRowDirective, UniScrollAreaComponent, UniSearchInputComponent, UniSelectComponent, UniServerSideDatasource, UniSkeletonComponent, UniSliderComponent, UniSnackbarComponent, UniSortHeaderComponent, UniStackDirective, UniStatComponent, UniSymbolComponent, UniTabComponent, UniTabsComponent, UniTagComponent, UniTagInputComponent, UniTextDirective, UniTextareaComponent, UniThemeBuilderComponent, UniThemeSwitchComponent, UniTimeInputComponent, UniToggleComponent, UniTooltipComponent, UniTourComponent, UniWrapDirective, acceptableFile, addDays, addMonths, anchorArrowStyles, anchorStyles, buildMonthGrid, clearAnchorName, createAnnouncer, createListboxNavigation, dayOfWeek, daysInMonth, discreteOverlayTransition, focusableElements, formatDate, formatMonthHeading, formatTime, getFileExtension, inclusiveDayCount, isDivider, isToggleOpen, isValidDate, isoDate, joinDateTime, listboxPopupAttr, listboxPopupStyles, localeDatePlaceholder, localeDefaultHour12, localeFieldOrder, localeMonthNames, localeWeekStart, monthOf, motionSafe, newAnchorName, newListboxAnchor, parseDateText, parseTimeText, promoteListboxPopup, resolveElement, resolveFocusTarget, restoreOverlayFocus, setAnchorName, splitDateTime, spotlightStyles, supportsAnchoredPopup, timeSlots, todayIso, transformOriginFor, uniqueId, useTimer, visuallyHidden, weekdayNames };
4460
- export type { Alert, AnchorOffset, AnchorRect, Announcer, BrandPaletteConfig, BreadcrumbItem, ButtonGroupConfig, ButtonGroupItem, ColumnDefinition, Confirmation, DataLoader, DrawerMode, DrawerPosition, ImagePosition, ListboxNavigationConfig, MenuDivider, MenuItem, MenuItemWithLabel, MenuItemWithTemplate, Option, Options, PageRequest, PageResponse, Placement, ScrollbarAppearance, SkeletonShape, SkeletonSweepDirection, Snackbar, Sort, SortDirection, SpotlightOptions, SpotlightStyles, UniAppBarOptions, UniAvatarGroupOptions, UniAvatarOptions, UniBreadcrumbOptions, UniCalendarMarker, UniCalendarMode, UniCalendarOptions, UniCalendarValue, UniCalloutDismissal, UniCalloutOptions, UniCheckboxOptions, UniComboboxOptions, UniComboboxRejection, UniDataSearchOptions, UniDataTableOptions, UniDatasource, UniDate, UniDateInputOptions, UniDateInputRejection, UniDateRange, UniDateTime, UniDateTimeInputOptions, UniDrawerOptions, UniExpandOptions, UniInputBoxOptions, UniInputMode, UniInputType, UniListboxPopupOptions, UniMenuItemOptions, UniMenuOptions, UniMonthGridCell, UniMultiSelectDropdownOptions, UniNotificationBadgeOptions, UniPaginatorOptions, UniPopoverOptions, UniRadioOption, UniRadioOptions, UniSearchInputOptions, UniSkeletonOptions, UniSliderOptions, UniStatOptions, UniTabsOptions, UniTagInputOptions, UniTagItem, UniTagOptions, UniTagRejection, UniTagSuggestion, UniTagValue, UniTextareaOptions, UniTime, UniTimeInputOptions, UniTimeInputRejection, UniToggleOptions, UniTourAdvance, UniTourOptions, UniTourStep, UniWeekdayName };
5924
+ export { BodyRenderDirective, ConfirmationDialogComponent, DRAWER_PANEL, DragAndDropDirective, FOCUSABLE_SELECTOR, ListboxNavigation, LocalStorageService, NotificationService, NotificationsComponent, RippleDirective, TRANSFORM_ORIGINS, ThemeService, UNI_FORMS, UNI_LAYOUT, UNI_THEMES, UniAlertComponent, UniAppBarComponent, UniAvatarComponent, UniAvatarGroupComponent, UniBackgroundComponent, UniBadgeComponent, UniBaseDatasource, UniBoxDirective, UniBreadcrumbComponent, UniButtonComponent, UniButtonGroupComponent, UniCalendarComponent, UniCalloutComponent, UniCardComponent, UniCardContentComponent, UniCardHeaderComponent, UniCenterDirective, UniCheckboxComponent, UniComboboxComponent, UniDataSearchComponent, UniDataTableComponent, UniDateInputComponent, UniDateTimeInputComponent, UniDebounceInputComponent, UniDialogButtonsComponent, UniDialogComponent, UniDialogHeaderComponent, UniDividerComponent, UniDrawerButtonsComponent, UniDrawerComponent, UniDrawerHeaderComponent, UniDropdownComponent, UniExpandAreaComponent, UniExpandComponent, UniExpandToggleComponent, UniFileDropZoneComponent, UniGridAreaDirective, UniGridDirective, UniIconButtonComponent, UniIconComponent, UniInputBoxComponent, UniInputComponent, UniJsonViewComponent, UniMenuComponent, UniMultiSelectComponent, UniMultiSelectDropdownComponent, UniNotificationBadgeComponent, UniNumberInputComponent, UniNumberRangeInputComponent, UniPaginatorComponent, UniPopoverComponent, UniProgressBarComponent, UniProgressGaugeComponent, UniQuantityStepperComponent, UniRadioComponent, UniRecordDatasource, UniRowDirective, UniScrollAreaComponent, UniSearchInputComponent, UniSelectComponent, UniServerSideDatasource, UniSkeletonComponent, UniSliderComponent, UniSnackbarComponent, UniSortHeaderComponent, UniStackDirective, UniStatComponent, UniSymbolComponent, UniTabComponent, UniTabsComponent, UniTagComponent, UniTagInputComponent, UniTextDirective, UniTextareaComponent, UniThemeBuilderComponent, UniThemeSwitchComponent, UniTimeInputComponent, UniToggleComponent, UniTooltipComponent, UniTourComponent, UniWrapDirective, acceptableFile, addDays, addMonths, anchorArrowStyles, anchorStyles, buildMonthGrid, clampDecimal, clearAnchorName, compareDecimal, createAnnouncer, createListboxNavigation, createPressRepeat, dayOfWeek, daysInMonth, decimalScale, discreteOverlayTransition, evaluateExpression, focusableElements, formatDate, formatMonthHeading, formatNumber, formatTime, fromScaled, getFileExtension, inclusiveDayCount, isCanonicalDecimal, isDivider, isToggleOpen, isValidDate, isoDate, joinDateTime, listboxPopupAttr, listboxPopupStyles, localeDatePlaceholder, localeDefaultHour12, localeFieldOrder, localeMonthNames, localeNumberParts, localeWeekStart, losesPrecision, monthOf, motionSafe, newAnchorName, newListboxAnchor, normalizeDecimal, parseDateText, parseNumber, parseTimeText, promoteListboxPopup, rawNumberText, resolveElement, resolveFocusTarget, resolveNumberFormat, restoreOverlayFocus, roundDecimal, setAnchorName, settleNumber, shiftDecimal, speakNumber, splitDateTime, spotlightStyles, stepDecimal, supportsAnchoredPopup, timeSlots, toAsciiDigits, toDecimal, toNumber, toScaled, todayIso, transformOriginFor, uniqueId, useTimer, visuallyHidden, weekdayNames };
5925
+ export type { Alert, AnchorOffset, AnchorRect, Announcer, BrandPaletteConfig, BreadcrumbItem, ButtonGroupConfig, ButtonGroupItem, ColumnDefinition, Confirmation, DataLoader, DrawerBackground, DrawerCloseReason, DrawerMode, DrawerPosition, ImagePosition, ListboxNavigationConfig, MenuDivider, MenuItem, MenuItemWithLabel, MenuItemWithTemplate, Option, Options, PageRequest, PageResponse, Placement, PressRepeat, PressRepeatConfig, PressRepeatTiming, ScrollbarAppearance, SkeletonShape, SkeletonSweepDirection, Snackbar, Sort, SortDirection, SpotlightOptions, SpotlightStyles, UniAppBarOptions, UniAvatarGroupOptions, UniAvatarOptions, UniBreadcrumbOptions, UniCalendarMarker, UniCalendarMode, UniCalendarOptions, UniCalendarValue, UniCalloutDismissal, UniCalloutOptions, UniCheckboxOptions, UniComboboxOptions, UniComboboxRejection, UniDataSearchOptions, UniDataTableOptions, UniDatasource, UniDate, UniDateInputOptions, UniDateInputRejection, UniDateRange, UniDateTime, UniDateTimeInputOptions, UniDrawerButtonsOptions, UniDrawerCloseRequest, UniDrawerHeaderOptions, UniDrawerOptions, UniDrawerPanel, UniExpandOptions, UniInputBoxOptions, UniInputMode, UniInputType, UniListboxPopupOptions, UniLocaleNumberParts, UniMenuItemOptions, UniMenuOptions, UniMonthGridCell, UniMultiSelectDropdownOptions, UniNotificationBadgeOptions, UniNumberClamp, UniNumberFormatConfig, UniNumberGrouping, UniNumberInputOptions, UniNumberParseResult, UniNumberPreset, UniNumberRange, UniNumberRangeInputOptions, UniNumberRangePart, UniNumberRangeRejection, UniNumberRejectReason, UniNumberRejection, UniNumberStepConfig, UniNumberStepped, UniPaginatorOptions, UniPopoverOptions, UniQuantityStepperOptions, UniRadioOption, UniRadioOptions, UniResolvedNumberFormat, UniRoundingMode, UniSearchInputOptions, UniSkeletonOptions, UniSliderMark, UniSliderOptions, UniSliderThumb, UniStatOptions, UniStepperLayout, UniTabsOptions, UniTagInputOptions, UniTagItem, UniTagOptions, UniTagRejection, UniTagSuggestion, UniTagValue, UniTextareaOptions, UniTime, UniTimeInputOptions, UniTimeInputRejection, UniToggleOptions, UniTourAdvance, UniTourOptions, UniTourStep, UniWeekdayName };