import * as _angular_core from '@angular/core'; import { InjectionToken, Signal, Provider } from '@angular/core'; import { FormValueControl } from '@angular/forms/signals'; import { FormUiControlBase } from 'forty-cdk/core'; import * as forty_cdk_number_input from 'forty-cdk/number-input'; /** * The coordination surface a `[forNumberInput]` exposes to its siblings. The * auxiliary `[forNumberInputIncrement]` / `[forNumberInputDecrement]` buttons * read it (through the group) to step the value, to mark the control touched, * and to reflect their disabled state at the min / max bound. */ interface ForNumberInputContext { /** Current numeric value, or `null` while the field is empty. */ readonly value: Signal; /** * The spinbutton's effective disabled — its own `disabled` input OR'd with a * surrounding disabled `[forFieldset]`. The increment / decrement buttons read * this so a disabled fieldset also disables stepping. */ readonly effectiveDisabled: Signal; /** Whether the spinbutton is read-only. */ readonly readonly: Signal; /** `true` when the value sits at (or below) `min`. */ readonly atMin: Signal; /** `true` when the value sits at (or above) `max`. */ readonly atMax: Signal; /** * Increase the value by `by` (defaults to `step`), snapping to the * `min ?? 0` ± k·`step` grid and clamping to `[min, max]`. No-op while * disabled or read-only. */ increment(by?: number): void; /** * Decrease the value by `by` (defaults to `step`), snapping to the * `min ?? 0` ± k·`step` grid and clamping to `[min, max]`. No-op while * disabled or read-only. */ decrement(by?: number): void; /** * Flip the `touched` model and emit the `touch` output. Called by the * increment / decrement buttons on click: they are `tabindex="-1"`, so a * pointer-only user never focuses the spinbutton and its `(blur)` handler * never runs. Fires on every touch-producing interaction, so a gesture that * blurs the spinbutton and then clicks a button emits `touch` twice; it is * never once-guarded. */ markTouched(): void; } /** * The single coordination surface `[forNumberInputGroup]` exposes. A * `[forNumberInput]` nested under the group registers itself, and the * auxiliary `[forNumberInputIncrement]` / `[forNumberInputDecrement]` buttons * read the registered spinbutton through `field()` to step the value and * reflect their min / max disabled state. Coordination flows through this * registry — not the DOM — because the focusable spinbutton lives on a void * `` that can't contain the sibling buttons as descendants. */ interface ForNumberInputGroupContext { /** The registered spinbutton, or `null` while none is mounted. */ readonly field: Signal; /** Register the spinbutton the group coordinates. */ register(field: ForNumberInputContext): void; /** Remove a previously registered spinbutton. */ unregister(field: ForNumberInputContext): void; } /** * Injection token for the `[forNumberInputGroup]` coordination surface. The * spinbutton joins it via `register`; the buttons read the registered field * through `field()`. */ declare const FOR_NUMBER_INPUT_GROUP: InjectionToken; /** * Resolve the surrounding `[forNumberInputGroup]`, or throw a descriptive * error. The increment / decrement buttons are only meaningful inside a * `[forNumberInputGroup]` that wraps a `[forNumberInput]`. */ declare function injectNumberInputGroup(piece: string): ForNumberInputGroupContext; /** * Headless implementation of the * [WAI-ARIA Spinbutton pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/) * and Angular's `FormValueControl` from `@angular/forms/signals`, * so it auto-wires with `[formField]` and auto-associates inside a `[forField]` * (label / description / error) with no extra markup. * * Apply on a `` — not `type="number"`, * whose native UI is unstylable and locale-quirky. The directive owns parsing, * clamping to `[min, max]`, the full Spinbutton keyboard map, and optional * `Intl.NumberFormat`-based display formatting. The focusable spinbutton input * itself is the `FormValueControl`; the `[forNumberInputIncrement]` / * `[forNumberInputDecrement]` buttons are auxiliary pointer affordances. * * Because the displayed (formatted) text can differ from the submitted value, * the directive mounts a hidden `` carrying the raw number for native * form submission when `name` is set — unlike `ForInput`, whose * visible element is itself the submittable field. The visible spinbutton's own * `name` attribute is suppressed (`[attr.name]="null"`), so a consumer-set * static `name` feeds only the hidden input and never double-submits its * formatted display text alongside the raw value. * * The host gets `data-empty` (while the value is `null`), `data-disabled`, and * `data-readonly` for CSS hooks, plus `data-touched` / `data-dirty` / * `data-pending` / `data-invalid` from the shared form-control reflection. * * @example * ```html * * * * * *
* * *
* ``` */ declare class ForNumberInput extends FormUiControlBase implements FormValueControl, ForNumberInputContext { #private; /** * Two-way bindable numeric value. Required by `FormValueControl`. * `null` represents the empty input (reflected as `data-empty`); a parsed * number otherwise. */ readonly value: _angular_core.ModelSignal; /** * Minimum value. Typed `number | undefined` to satisfy `FormUiControl.min` * (Signal Forms passes `undefined` when no `min` validator is bound). When * unset there is no lower bound. */ readonly min: _angular_core.InputSignal; /** * Maximum value. Typed `number | undefined` to satisfy `FormUiControl.max`. * When unset there is no upper bound. */ readonly max: _angular_core.InputSignal; /** * Increment applied by ArrowUp / ArrowDown and the inc/dec buttons. Values * snap to the `min ?? 0` ± k·`step` grid: a value already on the grid moves a * full step, an off-grid value lands on the adjacent grid point. */ readonly step: _angular_core.InputSignal; /** * Multiplier applied to `step` for `PageUp` / `PageDown`. Defaults to the * value from `provideForNumberInputDefaults` for the surrounding scope (10). * It applies only from a value already on the `min ?? 0` ± k·`step` grid — * from an off-grid value the key lands on the adjacent grid point instead, * matching the platform `stepUp()` / `stepDown()` rule. */ readonly stepMultiplier: _angular_core.InputSignal; /** * `Intl.NumberFormat` options for the displayed text and `aria-valuetext`. * When `null` (default) the raw number is shown and no `aria-valuetext` is * emitted (the numeric `aria-valuenow` already conveys the value). * * With `style: 'percent'` the model value stays the fraction Intl formats * from (`0.5` displays as `"50%"`); parsing divides typed input back by 100 so * the round-trip is loss-free (editing `"50%"` to `"51%"` yields `0.51`, not * `51`). `min` / `max` are therefore also expressed in that fractional scale. */ readonly formatOptions: _angular_core.InputSignal; /** BCP 47 locale for parsing and formatting. Defaults to the runtime locale. */ readonly locale: _angular_core.InputSignal; /** * Human-readable value for `aria-valuetext`. Only emitted when * `formatOptions` is set (the formatted text differs from `aria-valuenow`); * `null` otherwise so screen readers fall back to the numeric value. */ readonly valueText: _angular_core.Signal; /** * Derived keyboard mode: `decimal` when fractional values are possible, else * `numeric`. Reads the formatter's *resolved* options so currency / percent * styles (which imply fraction digits the consumer never spelled out, e.g. 2 * for most currencies) report their effective `maximumFractionDigits` rather * than the raw, un-resolved options object where those keys are absent. */ readonly inputmode: _angular_core.Signal<"decimal" | "numeric">; /** `true` when the value sits at (or below) `min`. */ readonly atMin: _angular_core.Signal; /** `true` when the value sits at (or above) `max`. */ readonly atMax: _angular_core.Signal; constructor(); /** * Increase the value by `by` (defaults to `step`). From empty, lands on the * clamped baseline (`min ?? 0`). Stepping follows the shared grid-snap rule: * a value already on the `min ?? 0` ± k·`step` grid advances a full `by` (so a * caller-supplied `by` finer than `step` — `increment(0.25)` with `step=0.1` — * keeps its own precision), while an off-grid value lands on the next grid * point above it (ArrowUp from `0.55` with `step=1` gives `1`, not `1.55`). * Clamps to `[min, max]`. */ increment(by?: number): void; /** * Decrease the value by `by` (defaults to `step`). From empty, lands on the * clamped baseline (`min ?? 0`). Follows the same grid-snap rule as * {@link increment}, travelling downward. Clamps to `[min, max]`. */ decrement(by?: number): void; /** * Widened to `public` so `ForNumberInputContext` consumers — the * `[forNumberInputIncrement]` / `[forNumberInputDecrement]` buttons — can mark * the control touched on a pointer commit; the behaviour is the base's. Fires * on every touch-producing interaction (a stepper click, and focus leaving the * spinbutton), so a gesture that does both emits `touch` twice. `touched` / * `data-touched` / `(touchedChange)` only change on the first, and Signal * Forms' `markAsTouched()` is idempotent. */ markTouched(): void; /** Live-parse the typed text into the value (unclamped — clamping waits for commit). */ protected onInput(event: Event): void; protected onKeyDown(event: KeyboardEvent): void; /** Clamp the live value to `[min, max]` and reformat the displayed text. */ protected commit(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Optional coordination wrapper for a `[forNumberInput]` and its * `[forNumberInputIncrement]` / `[forNumberInputDecrement]` buttons. It renders * nothing and imposes no role or layout — its only job is to bridge the buttons * to the spinbutton. * * It is required _only_ when you use the stepper buttons: a `` is a void * element and can't contain the buttons as DOM descendants, so the buttons * can't inject the spinbutton's context directly. The group registers the * `[forNumberInput]` beneath it and exposes it via `field()`, which the buttons * read. A standalone `[forNumberInput]` (keyboard / `[(value)]` only) needs no * group. * * @example * ```html *
* * * *
* ``` */ declare class ForNumberInputGroup implements ForNumberInputGroupContext { #private; /** The registered spinbutton field, or `null` while none is mounted. */ readonly field: Signal; /** Register the spinbutton field the group coordinates. */ register(field: ForNumberInputContext): void; /** Remove a previously registered spinbutton field. */ unregister(field: ForNumberInputContext): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Auxiliary "step up" button for a `[forNumberInput]`. Apply on a ` * ``` */ declare class ForNumberInputIncrement { protected readonly buttonType: _angular_core.Signal; protected readonly group: forty_cdk_number_input.ForNumberInputGroupContext; /** Accessible name for the button. Emits `aria-label` only when truthy. */ readonly ariaLabel: _angular_core.InputSignal; protected readonly resolvedAriaLabel: _angular_core.Signal; protected readonly isDisabled: _angular_core.Signal; constructor(); protected step(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Auxiliary "step down" button for a `[forNumberInput]`. Apply on a ` * * ``` */ declare class ForNumberInputDecrement { protected readonly buttonType: _angular_core.Signal; protected readonly group: forty_cdk_number_input.ForNumberInputGroupContext; /** Accessible name for the button. Emits `aria-label` only when truthy. */ readonly ariaLabel: _angular_core.InputSignal; protected readonly resolvedAriaLabel: _angular_core.Signal; protected readonly isDisabled: _angular_core.Signal; constructor(); protected step(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Defaults inherited by descendant `[forNumberInput]` controls in the * surrounding injector scope. Configure with `provideForNumberInputDefaults` * either at the application root or in any component's `providers` array; * partial overrides merge with the parent scope. */ interface ForNumberInputDefaults { /** * Multiplier applied to `step` for `PageUp` / `PageDown`. Defaults to `10`, * so a step of `1` pages by `10`. */ stepMultiplier: number; } /** Token holding the resolved number-input defaults for the current scope. */ declare const FOR_NUMBER_INPUT_DEFAULTS: _angular_core.InjectionToken; /** * Configures forty-cdk number-input defaults for this injector scope. Partial * overrides inherit unspecified keys from the parent scope (or library * defaults at the root). */ declare function provideForNumberInputDefaults(defaults?: Partial): Provider[]; /** * Exact public names of every `ForNumberInput` input, its models included. Spread it into the * `inputs` array of a `hostDirectives` entry so a wrapper component re-exposes the * primitive's full surface — the Signal Forms members `[formField]` binds among them — * without hand-maintaining the list. Always spread into an inline object literal as shown * below: the literal is what keeps the entry statically analyzable for consumers compiling * against the published package. An anti-drift spec fails when this list no longer matches * the directive's actual API. See `docs/wrapping-form-primitives.md` for both supported * wrapping patterns. * * @example * ```ts * @Component({ * selector: 'input[myNumberInput]', * template: '', * hostDirectives: [ * { * directive: ForNumberInput, * inputs: [...FOR_NUMBER_INPUT_HOST_DIRECTIVE_INPUTS], * outputs: [...FOR_NUMBER_INPUT_HOST_DIRECTIVE_OUTPUTS], * }, * ], * }) * export class MyNumberInput {} * ``` */ declare const FOR_NUMBER_INPUT_HOST_DIRECTIVE_INPUTS: readonly ["value", "dirty", "disabled", "errors", "formatOptions", "invalid", "locale", "max", "min", "name", "pending", "readonly", "required", "step", "stepMultiplier", "touched"]; /** * Exact public names of every `ForNumberInput` output, the Signal Forms `touch` output * included. Spread it into the `outputs` array of the same `hostDirectives` entry as * {@link FOR_NUMBER_INPUT_HOST_DIRECTIVE_INPUTS}. */ declare const FOR_NUMBER_INPUT_HOST_DIRECTIVE_OUTPUTS: readonly ["valueChange", "touchedChange", "touch"]; export { FOR_NUMBER_INPUT_DEFAULTS, FOR_NUMBER_INPUT_GROUP, FOR_NUMBER_INPUT_HOST_DIRECTIVE_INPUTS, FOR_NUMBER_INPUT_HOST_DIRECTIVE_OUTPUTS, ForNumberInput, ForNumberInputDecrement, ForNumberInputGroup, ForNumberInputIncrement, injectNumberInputGroup, provideForNumberInputDefaults }; export type { ForNumberInputContext, ForNumberInputDefaults, ForNumberInputGroupContext };