@xui/numeric-input 2.0.0-alpha.19 → 2.0.0-alpha.21
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.
|
@@ -45,19 +45,39 @@ class XuiNumericInput {
|
|
|
45
45
|
/** The user-defined classes on the wrapper. Merged last so they win. */
|
|
46
46
|
class = input('', /* @ts-ignore */
|
|
47
47
|
...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
48
|
+
/** Control height, from the shared control scale. Also scales the stepper icons. */
|
|
48
49
|
size = input(this.config.size, /* @ts-ignore */
|
|
49
50
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
51
|
+
/** Where the stepper buttons sit, or `none` to drop them and leave a plain numeric field. */
|
|
50
52
|
buttonPosition = input(this.config.buttonPosition, /* @ts-ignore */
|
|
51
53
|
...(ngDevMode ? [{ debugName: "buttonPosition" }] : /* istanbul ignore next */ []));
|
|
54
|
+
/** Text shown while the field is empty. */
|
|
52
55
|
placeholder = input(null, /* @ts-ignore */
|
|
53
56
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
57
|
+
/** Accessible name for the field, when no `<label>` points at it. */
|
|
54
58
|
ariaLabel = input(null, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
59
|
+
/**
|
|
60
|
+
* Lower bound. Reported as `aria-valuemin` and enforced when stepping; typed values are only clamped if
|
|
61
|
+
* `clampValueOnBlur` is set.
|
|
62
|
+
*/
|
|
55
63
|
min = input(undefined, { ...(ngDevMode ? { debugName: "min" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
64
|
+
/**
|
|
65
|
+
* Upper bound. Reported as `aria-valuemax` and enforced when stepping; typed values are only clamped if
|
|
66
|
+
* `clampValueOnBlur` is set.
|
|
67
|
+
*/
|
|
56
68
|
max = input(undefined, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
69
|
+
/** How much one step changes the value — a button press, or an arrow key with no modifier. */
|
|
57
70
|
stepSize = input(this.config.stepSize, { ...(ngDevMode ? { debugName: "stepSize" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
71
|
+
/** Step used while Shift is held, for coarse adjustment. */
|
|
58
72
|
majorStepSize = input(this.config.majorStepSize, { ...(ngDevMode ? { debugName: "majorStepSize" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
73
|
+
/** Step used while Alt is held, for fine adjustment. */
|
|
59
74
|
minorStepSize = input(this.config.minorStepSize, { ...(ngDevMode ? { debugName: "minorStepSize" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
75
|
+
/**
|
|
76
|
+
* Pull a typed value back inside `min`/`max` when the field loses focus. Off by default, so an out-of-range entry
|
|
77
|
+
* stays visible to be corrected.
|
|
78
|
+
*/
|
|
60
79
|
clampValueOnBlur = input(this.config.clampValueOnBlur, { ...(ngDevMode ? { debugName: "clampValueOnBlur" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
80
|
+
/** Block interaction and dim the field and its steppers. */
|
|
61
81
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
62
82
|
cva = createXValueAccessor({
|
|
63
83
|
onWrite: value => {
|
|
@@ -70,6 +90,7 @@ class XuiNumericInput {
|
|
|
70
90
|
// Aliased so the writable `value` linkedSignal below can own the public name.
|
|
71
91
|
// Coerce so `value="5"` (a string attribute) becomes the number 5, not the
|
|
72
92
|
// string "5" that would then concatenate under `+ stepSize`.
|
|
93
|
+
/** The value, or `null` when empty. Two-way bindable as `[(value)]`; a string attribute is coerced to a number. */
|
|
73
94
|
valueInput = input(null, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}),
|
|
74
95
|
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
75
96
|
alias: 'value',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xui-numeric-input.mjs","sources":["../../../../../../libs/ui/numeric-input/xui/src/lib/numeric-input.token.ts","../../../../../../libs/ui/numeric-input/xui/src/lib/numeric-input.ts","../../../../../../libs/ui/numeric-input/xui/src/index.ts","../../../../../../libs/ui/numeric-input/xui/src/xui-numeric-input.ts"],"sourcesContent":["import { createXConfigToken } from '@xui/core';\n\nexport type XuiNumericInputSize = 'md' | 'sm';\n/** Where the stepper buttons sit. */\nexport type XuiNumericButtonPosition = 'right' | 'left' | 'none';\n\nexport interface XuiNumericInputConfig {\n size: XuiNumericInputSize;\n buttonPosition: XuiNumericButtonPosition;\n /** Step applied by a click or ArrowUp/Down. */\n stepSize: number;\n /** Step when Shift is held — the coarse jump. */\n majorStepSize: number;\n /** Step when Alt is held — the fine nudge. */\n minorStepSize: number;\n /** Snap an out-of-range value back into [min, max] when focus leaves. */\n clampValueOnBlur: boolean;\n}\n\n/** Application-wide defaults for XuiNumericInput. */\nexport const [injectXuiNumericInputConfig, provideXuiNumericInputConfig] = createXConfigToken<XuiNumericInputConfig>(\n 'XuiNumericInputConfig',\n {\n size: 'md',\n buttonPosition: 'right',\n stepSize: 1,\n majorStepSize: 10,\n minorStepSize: 0.1,\n clampValueOnBlur: true\n }\n);\n","import type { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n forwardRef,\n input,\n linkedSignal,\n numberAttribute,\n signal,\n type Signal\n} from '@angular/core';\nimport { ControlValueAccessor, type NgControl } from '@angular/forms';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { matKeyboardArrowDownRound, matKeyboardArrowUpRound } from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { uniqueId } from '@xui/core/a11y';\nimport { XFormFieldControl } from '@xui/core/form-field';\nimport { createXErrorState, createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { XuiIcon, type XuiIconSize } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport {\n injectXuiNumericInputConfig,\n type XuiNumericButtonPosition,\n type XuiNumericInputSize\n} from './numeric-input.token';\n\n/**\n * A number field with stepper buttons and keyboard increment.\n *\n * ```html\n * <xui-numeric-input [(ngModel)]=\"quantity\" [min]=\"0\" [max]=\"99\" />\n * ```\n *\n * The value is a `number | null` (empty is `null`, not `0`, so \"no answer\" is\n * distinct from zero). ArrowUp/Down step by `stepSize`; Shift steps by\n * `majorStepSize`, Alt by `minorStepSize`. It is a `ControlValueAccessor`, so\n * forms bind to it directly, and it clamps into `[min, max]` on blur.\n */\n@Component({\n selector: 'xui-numeric-input',\n imports: [NgTemplateOutlet, NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matKeyboardArrowUpRound, matKeyboardArrowDownRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n provideXValueAccessor(() => XuiNumericInput),\n {\n provide: XFormFieldControl,\n useExisting: forwardRef(() => XuiNumericInput)\n }\n ],\n template: `\n @if (buttonPosition() === 'left') {\n <ng-container [ngTemplateOutlet]=\"steppers\" />\n }\n\n <input\n #field\n [id]=\"fieldId\"\n type=\"text\"\n inputmode=\"decimal\"\n [class]=\"fieldClass()\"\n [value]=\"display()\"\n [disabled]=\"isDisabled()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n role=\"spinbutton\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"min() ?? null\"\n [attr.aria-valuemax]=\"max() ?? null\"\n (input)=\"onInput(field.value)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (buttonPosition() === 'right') {\n <ng-container [ngTemplateOutlet]=\"steppers\" />\n }\n\n <ng-template #steppers>\n <div [class]=\"stepperColumnClass()\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Increment\"\n [class]=\"stepperClass()\"\n [disabled]=\"!canIncrement()\"\n (click)=\"step(stepSize())\"\n >\n <ng-icon xui [size]=\"stepperIconSize()\" name=\"matKeyboardArrowUpRound\" />\n </button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Decrement\"\n [class]=\"stepperClass()\"\n [disabled]=\"!canDecrement()\"\n (click)=\"step(-stepSize())\"\n >\n <ng-icon xui [size]=\"stepperIconSize()\" name=\"matKeyboardArrowDownRound\" />\n </button>\n </div>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n }\n})\nexport class XuiNumericInput implements ControlValueAccessor, XFormFieldControl {\n private readonly config = injectXuiNumericInputConfig();\n private readonly formState = createXErrorState();\n protected readonly fieldId = uniqueId('xui-numeric-input');\n\n /** Error state for `xui-form-field`, derived from the optional bound form control. */\n readonly errorState = this.formState.errorState;\n\n /** Points the form field's `<label for>` at the inner text field, not the host. */\n readonly controlId: Signal<string | null> = signal(this.fieldId).asReadonly();\n\n get ngControl(): NgControl | null {\n return this.formState.ngControl();\n }\n\n /** The user-defined classes on the wrapper. Merged last so they win. */\n readonly class = input<ClassValue>('');\n readonly size = input<XuiNumericInputSize>(this.config.size);\n readonly buttonPosition = input<XuiNumericButtonPosition>(this.config.buttonPosition);\n\n readonly placeholder = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });\n\n readonly min = input<number | undefined, NumberInput>(undefined, { transform: numberAttribute });\n readonly max = input<number | undefined, NumberInput>(undefined, { transform: numberAttribute });\n readonly stepSize = input<number, NumberInput>(this.config.stepSize, { transform: numberAttribute });\n readonly majorStepSize = input<number, NumberInput>(this.config.majorStepSize, { transform: numberAttribute });\n readonly minorStepSize = input<number, NumberInput>(this.config.minorStepSize, { transform: numberAttribute });\n readonly clampValueOnBlur = input<boolean, BooleanInput>(this.config.clampValueOnBlur, {\n transform: booleanAttribute\n });\n\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n protected readonly cva = createXValueAccessor<number | null>({\n onWrite: value => {\n this.value.set(value ?? null);\n this.text.set(value == null ? '' : String(value));\n },\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n // Aliased so the writable `value` linkedSignal below can own the public name.\n // Coerce so `value=\"5\"` (a string attribute) becomes the number 5, not the\n // string \"5\" that would then concatenate under `+ stepSize`.\n readonly valueInput = input<number | null, number | string | null | undefined>(null, {\n // eslint-disable-next-line @angular-eslint/no-input-rename\n alias: 'value',\n transform: raw => (raw == null || raw === '' ? null : Number(raw))\n });\n /** The current numeric value, or `null` when empty. Two-way via `value`. */\n readonly value = linkedSignal(this.valueInput);\n\n // The text the field shows. Kept separate from `value` so a half-typed entry\n // (\"-\", \"1.\") is preserved while the parsed value stays null/last-valid.\n private readonly text = signal<string>('');\n protected readonly display = computed(() => {\n const value = this.value();\n\n // Do not overwrite what the user is mid-typing with a formatted number.\n return this.text() !== '' || value == null ? this.text() : String(value);\n });\n\n protected readonly canIncrement = computed(() => !this.isDisabled() && !this.atMax(this.value()));\n protected readonly canDecrement = computed(() => !this.isDisabled() && !this.atMin(this.value()));\n\n protected readonly computedClass = computed(() =>\n xui(\n 'border-border bg-surface-inset focus-within:border-focus inline-flex items-stretch overflow-hidden rounded-lg border transition-colors',\n // The wrapper carries the control height so the stepper column cannot stretch the field\n // past the shared scale.\n this.size() === 'sm' ? 'h-(--control-height-sm)' : 'h-(--control-height-md)',\n this.isDisabled() && 'cursor-not-allowed opacity-50',\n this.class()\n )\n );\n protected readonly fieldClass = computed(() =>\n xui(\n 'text-foreground placeholder:text-foreground-subtle w-full min-w-0 bg-transparent tabular-nums outline-none',\n this.size() === 'sm' ? 'px-(--control-padding-sm) text-xs' : 'px-(--control-padding-md) text-sm'\n )\n );\n protected readonly stepperColumnClass = computed(() =>\n xui(\n 'border-border flex shrink-0 flex-col',\n // The rule divides the steppers from the field, so it belongs on whichever edge faces it —\n // on the outer edge it would just double up on the wrapper's own border.\n this.buttonPosition() === 'left' ? 'border-e' : 'border-s'\n )\n );\n\n /**\n * The two steppers split the control height between them, so a glyph sized off the icon scale\n * (`sm` is 16px) makes the column taller than the field — and the wrapper clips the overflow,\n * taking the bottom arrow with it. Size to the row instead: half of 24px or 30px, less a hair.\n */\n protected readonly stepperIconSize = computed<XuiIconSize>(() => (this.size() === 'sm' ? '10px' : '12px'));\n /**\n * A disabled stepper keeps its pointer events so the cursor can say it is unavailable — an\n * element that receives none contributes no cursor either. The native `disabled` swallows the\n * click, and `enabled:` keeps the hover lift off a stepper that cannot be pressed.\n */\n protected readonly stepperClass = computed(\n () =>\n 'text-foreground-muted enabled:hover:bg-hover-overlay enabled:hover:text-foreground flex flex-1 items-center justify-center px-1.5 disabled:cursor-not-allowed disabled:opacity-40'\n );\n\n protected onInput(raw: string): void {\n this.text.set(raw);\n\n const parsed = this.parse(raw);\n this.value.set(parsed);\n this.cva.notifyChange(parsed);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') {\n return;\n }\n\n event.preventDefault();\n const magnitude = event.shiftKey ? this.majorStepSize() : event.altKey ? this.minorStepSize() : this.stepSize();\n this.step(event.key === 'ArrowUp' ? magnitude : -magnitude);\n }\n\n protected onBlur(): void {\n if (this.clampValueOnBlur()) {\n this.commit(this.clamp(this.value()));\n }\n\n // Re-sync the text with the committed value, dropping a half-typed entry.\n this.text.set(this.value() == null ? '' : String(this.value()));\n this.cva.markTouched();\n }\n\n step(delta: number): void {\n if (this.isDisabled()) {\n return;\n }\n\n const base = this.value() ?? 0;\n // Round to the step grid so 0.1 + 0.2 does not drift to 0.30000000000000004.\n const next = this.clamp(this.round(base + delta));\n this.commit(next);\n this.text.set(next == null ? '' : String(next));\n }\n\n private commit(value: number | null): void {\n this.value.set(value);\n this.cva.notifyChange(value);\n }\n\n private parse(raw: string): number | null {\n const trimmed = raw.trim();\n\n if (trimmed === '' || trimmed === '-' || trimmed === '.' || trimmed === '-.') {\n return null;\n }\n\n const parsed = Number(trimmed);\n\n return Number.isFinite(parsed) ? parsed : this.value();\n }\n\n private clamp(value: number | null): number | null {\n if (value == null) {\n return null;\n }\n\n const min = this.min();\n const max = this.max();\n\n return Math.min(max ?? Infinity, Math.max(min ?? -Infinity, value));\n }\n\n private round(value: number): number {\n // Keep a sane number of decimals so step math stays exact.\n return Math.round(value * 1e10) / 1e10;\n }\n\n private atMax(value: number | null): boolean {\n return value != null && this.max() != null && value >= this.max()!;\n }\n\n private atMin(value: number | null): boolean {\n return value != null && this.min() != null && value <= this.min()!;\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiNumericInput } from './lib/numeric-input';\n\nexport * from './lib/numeric-input';\nexport * from './lib/numeric-input.token';\n\nexport const XuiNumericInputImports = [XuiNumericInput] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xui-numeric-input.mjs","sources":["../../../../../../libs/ui/numeric-input/xui/src/lib/numeric-input.token.ts","../../../../../../libs/ui/numeric-input/xui/src/lib/numeric-input.ts","../../../../../../libs/ui/numeric-input/xui/src/index.ts","../../../../../../libs/ui/numeric-input/xui/src/xui-numeric-input.ts"],"sourcesContent":["import { createXConfigToken } from '@xui/core';\n\nexport type XuiNumericInputSize = 'md' | 'sm';\n/** Where the stepper buttons sit. */\nexport type XuiNumericButtonPosition = 'right' | 'left' | 'none';\n\nexport interface XuiNumericInputConfig {\n size: XuiNumericInputSize;\n buttonPosition: XuiNumericButtonPosition;\n /** Step applied by a click or ArrowUp/Down. */\n stepSize: number;\n /** Step when Shift is held — the coarse jump. */\n majorStepSize: number;\n /** Step when Alt is held — the fine nudge. */\n minorStepSize: number;\n /** Snap an out-of-range value back into [min, max] when focus leaves. */\n clampValueOnBlur: boolean;\n}\n\n/** Application-wide defaults for XuiNumericInput. */\nexport const [injectXuiNumericInputConfig, provideXuiNumericInputConfig] = createXConfigToken<XuiNumericInputConfig>(\n 'XuiNumericInputConfig',\n {\n size: 'md',\n buttonPosition: 'right',\n stepSize: 1,\n majorStepSize: 10,\n minorStepSize: 0.1,\n clampValueOnBlur: true\n }\n);\n","import type { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n forwardRef,\n input,\n linkedSignal,\n numberAttribute,\n signal,\n type Signal\n} from '@angular/core';\nimport { ControlValueAccessor, type NgControl } from '@angular/forms';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { matKeyboardArrowDownRound, matKeyboardArrowUpRound } from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { uniqueId } from '@xui/core/a11y';\nimport { XFormFieldControl } from '@xui/core/form-field';\nimport { createXErrorState, createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { XuiIcon, type XuiIconSize } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport {\n injectXuiNumericInputConfig,\n type XuiNumericButtonPosition,\n type XuiNumericInputSize\n} from './numeric-input.token';\n\n/**\n * A number field with stepper buttons and keyboard increment.\n *\n * ```html\n * <xui-numeric-input [(ngModel)]=\"quantity\" [min]=\"0\" [max]=\"99\" />\n * ```\n *\n * The value is a `number | null` (empty is `null`, not `0`, so \"no answer\" is\n * distinct from zero). ArrowUp/Down step by `stepSize`; Shift steps by\n * `majorStepSize`, Alt by `minorStepSize`. It is a `ControlValueAccessor`, so\n * forms bind to it directly, and it clamps into `[min, max]` on blur.\n */\n@Component({\n selector: 'xui-numeric-input',\n imports: [NgTemplateOutlet, NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matKeyboardArrowUpRound, matKeyboardArrowDownRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n provideXValueAccessor(() => XuiNumericInput),\n {\n provide: XFormFieldControl,\n useExisting: forwardRef(() => XuiNumericInput)\n }\n ],\n template: `\n @if (buttonPosition() === 'left') {\n <ng-container [ngTemplateOutlet]=\"steppers\" />\n }\n\n <input\n #field\n [id]=\"fieldId\"\n type=\"text\"\n inputmode=\"decimal\"\n [class]=\"fieldClass()\"\n [value]=\"display()\"\n [disabled]=\"isDisabled()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"ariaLabel()\"\n role=\"spinbutton\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"min() ?? null\"\n [attr.aria-valuemax]=\"max() ?? null\"\n (input)=\"onInput(field.value)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (buttonPosition() === 'right') {\n <ng-container [ngTemplateOutlet]=\"steppers\" />\n }\n\n <ng-template #steppers>\n <div [class]=\"stepperColumnClass()\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Increment\"\n [class]=\"stepperClass()\"\n [disabled]=\"!canIncrement()\"\n (click)=\"step(stepSize())\"\n >\n <ng-icon xui [size]=\"stepperIconSize()\" name=\"matKeyboardArrowUpRound\" />\n </button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Decrement\"\n [class]=\"stepperClass()\"\n [disabled]=\"!canDecrement()\"\n (click)=\"step(-stepSize())\"\n >\n <ng-icon xui [size]=\"stepperIconSize()\" name=\"matKeyboardArrowDownRound\" />\n </button>\n </div>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n }\n})\nexport class XuiNumericInput implements ControlValueAccessor, XFormFieldControl {\n private readonly config = injectXuiNumericInputConfig();\n private readonly formState = createXErrorState();\n protected readonly fieldId = uniqueId('xui-numeric-input');\n\n /** Error state for `xui-form-field`, derived from the optional bound form control. */\n readonly errorState = this.formState.errorState;\n\n /** Points the form field's `<label for>` at the inner text field, not the host. */\n readonly controlId: Signal<string | null> = signal(this.fieldId).asReadonly();\n\n get ngControl(): NgControl | null {\n return this.formState.ngControl();\n }\n\n /** The user-defined classes on the wrapper. Merged last so they win. */\n readonly class = input<ClassValue>('');\n /** Control height, from the shared control scale. Also scales the stepper icons. */\n readonly size = input<XuiNumericInputSize>(this.config.size);\n /** Where the stepper buttons sit, or `none` to drop them and leave a plain numeric field. */\n readonly buttonPosition = input<XuiNumericButtonPosition>(this.config.buttonPosition);\n\n /** Text shown while the field is empty. */\n readonly placeholder = input<string | null>(null);\n /** Accessible name for the field, when no `<label>` points at it. */\n readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });\n\n /**\n * Lower bound. Reported as `aria-valuemin` and enforced when stepping; typed values are only clamped if\n * `clampValueOnBlur` is set.\n */\n readonly min = input<number | undefined, NumberInput>(undefined, { transform: numberAttribute });\n /**\n * Upper bound. Reported as `aria-valuemax` and enforced when stepping; typed values are only clamped if\n * `clampValueOnBlur` is set.\n */\n readonly max = input<number | undefined, NumberInput>(undefined, { transform: numberAttribute });\n /** How much one step changes the value — a button press, or an arrow key with no modifier. */\n readonly stepSize = input<number, NumberInput>(this.config.stepSize, { transform: numberAttribute });\n /** Step used while Shift is held, for coarse adjustment. */\n readonly majorStepSize = input<number, NumberInput>(this.config.majorStepSize, { transform: numberAttribute });\n /** Step used while Alt is held, for fine adjustment. */\n readonly minorStepSize = input<number, NumberInput>(this.config.minorStepSize, { transform: numberAttribute });\n /**\n * Pull a typed value back inside `min`/`max` when the field loses focus. Off by default, so an out-of-range entry\n * stays visible to be corrected.\n */\n readonly clampValueOnBlur = input<boolean, BooleanInput>(this.config.clampValueOnBlur, {\n transform: booleanAttribute\n });\n\n /** Block interaction and dim the field and its steppers. */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n protected readonly cva = createXValueAccessor<number | null>({\n onWrite: value => {\n this.value.set(value ?? null);\n this.text.set(value == null ? '' : String(value));\n },\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n // Aliased so the writable `value` linkedSignal below can own the public name.\n // Coerce so `value=\"5\"` (a string attribute) becomes the number 5, not the\n // string \"5\" that would then concatenate under `+ stepSize`.\n /** The value, or `null` when empty. Two-way bindable as `[(value)]`; a string attribute is coerced to a number. */\n readonly valueInput = input<number | null, number | string | null | undefined>(null, {\n // eslint-disable-next-line @angular-eslint/no-input-rename\n alias: 'value',\n transform: raw => (raw == null || raw === '' ? null : Number(raw))\n });\n /** The current numeric value, or `null` when empty. Two-way via `value`. */\n readonly value = linkedSignal(this.valueInput);\n\n // The text the field shows. Kept separate from `value` so a half-typed entry\n // (\"-\", \"1.\") is preserved while the parsed value stays null/last-valid.\n private readonly text = signal<string>('');\n protected readonly display = computed(() => {\n const value = this.value();\n\n // Do not overwrite what the user is mid-typing with a formatted number.\n return this.text() !== '' || value == null ? this.text() : String(value);\n });\n\n protected readonly canIncrement = computed(() => !this.isDisabled() && !this.atMax(this.value()));\n protected readonly canDecrement = computed(() => !this.isDisabled() && !this.atMin(this.value()));\n\n protected readonly computedClass = computed(() =>\n xui(\n 'border-border bg-surface-inset focus-within:border-focus inline-flex items-stretch overflow-hidden rounded-lg border transition-colors',\n // The wrapper carries the control height so the stepper column cannot stretch the field\n // past the shared scale.\n this.size() === 'sm' ? 'h-(--control-height-sm)' : 'h-(--control-height-md)',\n this.isDisabled() && 'cursor-not-allowed opacity-50',\n this.class()\n )\n );\n protected readonly fieldClass = computed(() =>\n xui(\n 'text-foreground placeholder:text-foreground-subtle w-full min-w-0 bg-transparent tabular-nums outline-none',\n this.size() === 'sm' ? 'px-(--control-padding-sm) text-xs' : 'px-(--control-padding-md) text-sm'\n )\n );\n protected readonly stepperColumnClass = computed(() =>\n xui(\n 'border-border flex shrink-0 flex-col',\n // The rule divides the steppers from the field, so it belongs on whichever edge faces it —\n // on the outer edge it would just double up on the wrapper's own border.\n this.buttonPosition() === 'left' ? 'border-e' : 'border-s'\n )\n );\n\n /**\n * The two steppers split the control height between them, so a glyph sized off the icon scale\n * (`sm` is 16px) makes the column taller than the field — and the wrapper clips the overflow,\n * taking the bottom arrow with it. Size to the row instead: half of 24px or 30px, less a hair.\n */\n protected readonly stepperIconSize = computed<XuiIconSize>(() => (this.size() === 'sm' ? '10px' : '12px'));\n /**\n * A disabled stepper keeps its pointer events so the cursor can say it is unavailable — an\n * element that receives none contributes no cursor either. The native `disabled` swallows the\n * click, and `enabled:` keeps the hover lift off a stepper that cannot be pressed.\n */\n protected readonly stepperClass = computed(\n () =>\n 'text-foreground-muted enabled:hover:bg-hover-overlay enabled:hover:text-foreground flex flex-1 items-center justify-center px-1.5 disabled:cursor-not-allowed disabled:opacity-40'\n );\n\n protected onInput(raw: string): void {\n this.text.set(raw);\n\n const parsed = this.parse(raw);\n this.value.set(parsed);\n this.cva.notifyChange(parsed);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') {\n return;\n }\n\n event.preventDefault();\n const magnitude = event.shiftKey ? this.majorStepSize() : event.altKey ? this.minorStepSize() : this.stepSize();\n this.step(event.key === 'ArrowUp' ? magnitude : -magnitude);\n }\n\n protected onBlur(): void {\n if (this.clampValueOnBlur()) {\n this.commit(this.clamp(this.value()));\n }\n\n // Re-sync the text with the committed value, dropping a half-typed entry.\n this.text.set(this.value() == null ? '' : String(this.value()));\n this.cva.markTouched();\n }\n\n step(delta: number): void {\n if (this.isDisabled()) {\n return;\n }\n\n const base = this.value() ?? 0;\n // Round to the step grid so 0.1 + 0.2 does not drift to 0.30000000000000004.\n const next = this.clamp(this.round(base + delta));\n this.commit(next);\n this.text.set(next == null ? '' : String(next));\n }\n\n private commit(value: number | null): void {\n this.value.set(value);\n this.cva.notifyChange(value);\n }\n\n private parse(raw: string): number | null {\n const trimmed = raw.trim();\n\n if (trimmed === '' || trimmed === '-' || trimmed === '.' || trimmed === '-.') {\n return null;\n }\n\n const parsed = Number(trimmed);\n\n return Number.isFinite(parsed) ? parsed : this.value();\n }\n\n private clamp(value: number | null): number | null {\n if (value == null) {\n return null;\n }\n\n const min = this.min();\n const max = this.max();\n\n return Math.min(max ?? Infinity, Math.max(min ?? -Infinity, value));\n }\n\n private round(value: number): number {\n // Keep a sane number of decimals so step math stays exact.\n return Math.round(value * 1e10) / 1e10;\n }\n\n private atMax(value: number | null): boolean {\n return value != null && this.max() != null && value >= this.max()!;\n }\n\n private atMin(value: number | null): boolean {\n return value != null && this.min() != null && value <= this.min()!;\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiNumericInput } from './lib/numeric-input';\n\nexport * from './lib/numeric-input';\nexport * from './lib/numeric-input.token';\n\nexport const XuiNumericInputImports = [XuiNumericInput] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;AAmBA;AACO,MAAM,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,GAAG,kBAAkB,CAC3F,uBAAuB,EACvB;AACE,IAAA,IAAI,EAAE,IAAI;AACV,IAAA,cAAc,EAAE,OAAO;AACvB,IAAA,QAAQ,EAAE,CAAC;AACX,IAAA,aAAa,EAAE,EAAE;AACjB,IAAA,aAAa,EAAE,GAAG;AAClB,IAAA,gBAAgB,EAAE;AACnB,CAAA;;ACCH;;;;;;;;;;;AAWG;MAuEU,eAAe,CAAA;IACT,MAAM,GAAG,2BAA2B,EAAE;IACtC,SAAS,GAAG,iBAAiB,EAAE;AAC7B,IAAA,OAAO,GAAG,QAAQ,CAAC,mBAAmB,CAAC;;AAGjD,IAAA,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU;;IAGtC,SAAS,GAA0B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE;AAE7E,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;IACnC;;IAGS,KAAK,GAAG,KAAK,CAAa,EAAE;8EAAC;;AAE7B,IAAA,IAAI,GAAG,KAAK,CAAsB,IAAI,CAAC,MAAM,CAAC,IAAI;6EAAC;;AAEnD,IAAA,cAAc,GAAG,KAAK,CAA2B,IAAI,CAAC,MAAM,CAAC,cAAc;uFAAC;;IAG5E,WAAW,GAAG,KAAK,CAAgB,IAAI;oFAAC;;IAExC,SAAS,GAAG,KAAK,CAAgB,IAAI,iFAAI,KAAK,EAAE,YAAY,EAAA,CAAG;AAExE;;;AAGG;IACM,GAAG,GAAG,KAAK,CAAkC,SAAS,2EAAI,SAAS,EAAE,eAAe,EAAA,CAAG;AAChG;;;AAGG;IACM,GAAG,GAAG,KAAK,CAAkC,SAAS,2EAAI,SAAS,EAAE,eAAe,EAAA,CAAG;;AAEvF,IAAA,QAAQ,GAAG,KAAK,CAAsB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,eAAe,GAAG;;AAE3F,IAAA,aAAa,GAAG,KAAK,CAAsB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,eAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,eAAe,GAAG;;AAErG,IAAA,aAAa,GAAG,KAAK,CAAsB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,eAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,eAAe,GAAG;AAC9G;;;AAGG;AACM,IAAA,gBAAgB,GAAG,KAAK,CAAwB,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,8BAAA,EAAA,CAAA,EACnF,SAAS,EAAE,gBAAgB,GAC3B;;IAGO,QAAQ,GAAG,KAAK,CAAwB,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAErE,GAAG,GAAG,oBAAoB,CAAgB;QAC3D,OAAO,EAAE,KAAK,IAAG;YACf,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC;QACD,QAAQ,EAAE,IAAI,CAAC;AAChB,KAAA,CAAC;AACiB,IAAA,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ;;;;;IAMxC,UAAU,GAAG,KAAK,CAAoD,IAAI,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,YAAA,EAAA,8BAAA,EAAA,CAAA;;AAEjF,QAAA,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,GAAG,KAAK,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE,GAAG,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAA,CAClE;;AAEO,IAAA,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU;8EAAC;;;IAI7B,IAAI,GAAG,MAAM,CAAS,EAAE;6EAAC;AACvB,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;;QAG1B,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IAC1E,CAAC;gFAAC;IAEiB,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;qFAAC;IAC9E,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;qFAAC;IAE9E,aAAa,GAAG,QAAQ,CAAC,MAC1C,GAAG,CACD,wIAAwI;;;IAGxI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,yBAAyB,GAAG,yBAAyB,EAC5E,IAAI,CAAC,UAAU,EAAE,IAAI,+BAA+B,EACpD,IAAI,CAAC,KAAK,EAAE,CACb;sFACF;IACkB,UAAU,GAAG,QAAQ,CAAC,MACvC,GAAG,CACD,4GAA4G,EAC5G,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,mCAAmC,GAAG,mCAAmC,CACjG;mFACF;IACkB,kBAAkB,GAAG,QAAQ,CAAC,MAC/C,GAAG,CACD,sCAAsC;;;AAGtC,IAAA,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,GAAG,UAAU,GAAG,UAAU,CAC3D;2FACF;AAED;;;;AAIG;IACgB,eAAe,GAAG,QAAQ,CAAc,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;wFAAC;AAC1G;;;;AAIG;AACgB,IAAA,YAAY,GAAG,QAAQ,CACxC,MACE,mLAAmL;qFACtL;AAES,IAAA,OAAO,CAAC,GAAW,EAAA;AAC3B,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAElB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAC9B,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACtB,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC;IAC/B;AAEU,IAAA,SAAS,CAAC,KAAoB,EAAA;AACtC,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE;YACxD;QACF;QAEA,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC/G,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,SAAS,GAAG,CAAC,SAAS,CAAC;IAC7D;IAEU,MAAM,GAAA;AACd,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;AAC3B,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACvC;;QAGA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAC/D,QAAA,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;IACxB;AAEA,IAAA,IAAI,CAAC,KAAa,EAAA;AAChB,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;YACrB;QACF;QAEA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;;AAE9B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD;AAEQ,IAAA,MAAM,CAAC,KAAoB,EAAA;AACjC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC;IAC9B;AAEQ,IAAA,KAAK,CAAC,GAAW,EAAA;AACvB,QAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAE1B,QAAA,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,EAAE;AAC5E,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;AAE9B,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE;IACxD;AAEQ,IAAA,KAAK,CAAC,KAAoB,EAAA;AAChC,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACjB,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AACtB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QAEtB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrE;AAEQ,IAAA,KAAK,CAAC,KAAa,EAAA;;QAEzB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI;IACxC;AAEQ,IAAA,KAAK,CAAC,KAAoB,EAAA;AAChC,QAAA,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,EAAG;IACpE;AAEQ,IAAA,KAAK,CAAC,KAAoB,EAAA;AAChC,QAAA,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,EAAG;IACpE;AAES,IAAA,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU;AAChC,IAAA,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB;AAC5C,IAAA,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB;AAC9C,IAAA,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB;0HArN1C,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,uBAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,SAAA,EAhEf;AACT,YAAA,qBAAqB,EAAC,MAAM,eAAe,EAAC;AAC5C,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,UAAU,EAAC,MAAM,eAAe;AAC9C;SACF,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA/DS,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,aAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,OAAO,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAC5B,CAAC,YAAY,CAAC,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,CAAC,CAAC,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAmE1E,eAAe,EAAA,UAAA,EAAA,CAAA;kBAtE3B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,OAAO,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;oBAC5C,aAAa,EAAE,CAAC,YAAY,CAAC,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,CAAC,CAAC;oBACrF,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,SAAS,EAAE;AACT,wBAAA,qBAAqB,EAAC,MAAK,eAAgB,EAAC;AAC5C,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAE,UAAU,EAAC,qBAAqB;AAC9C;AACF,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDT,EAAA,CAAA;AACD,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE;AACZ;AACF,iBAAA;;;AC1GM,MAAM,sBAAsB,GAAG,CAAC,eAAe;;ACLtD;;AAEG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xui/numeric-input",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.21",
|
|
4
4
|
"description": "Modern Angular 22 UI Library based on TailwindCSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@angular/forms": "22",
|
|
43
43
|
"@ng-icons/core": "34",
|
|
44
44
|
"@ng-icons/material-icons": "34",
|
|
45
|
-
"@xui/core": "2.0.0-alpha.
|
|
46
|
-
"@xui/icon": "2.0.0-alpha.
|
|
45
|
+
"@xui/core": "2.0.0-alpha.21",
|
|
46
|
+
"@xui/icon": "2.0.0-alpha.21",
|
|
47
47
|
"clsx": "^2.1.1"
|
|
48
48
|
},
|
|
49
49
|
"publishConfig": {
|
|
@@ -49,19 +49,40 @@ declare class XuiNumericInput implements ControlValueAccessor, XFormFieldControl
|
|
|
49
49
|
get ngControl(): NgControl | null;
|
|
50
50
|
/** The user-defined classes on the wrapper. Merged last so they win. */
|
|
51
51
|
readonly class: _angular_core.InputSignal<ClassValue>;
|
|
52
|
+
/** Control height, from the shared control scale. Also scales the stepper icons. */
|
|
52
53
|
readonly size: _angular_core.InputSignal<XuiNumericInputSize>;
|
|
54
|
+
/** Where the stepper buttons sit, or `none` to drop them and leave a plain numeric field. */
|
|
53
55
|
readonly buttonPosition: _angular_core.InputSignal<XuiNumericButtonPosition>;
|
|
56
|
+
/** Text shown while the field is empty. */
|
|
54
57
|
readonly placeholder: _angular_core.InputSignal<string | null>;
|
|
58
|
+
/** Accessible name for the field, when no `<label>` points at it. */
|
|
55
59
|
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Lower bound. Reported as `aria-valuemin` and enforced when stepping; typed values are only clamped if
|
|
62
|
+
* `clampValueOnBlur` is set.
|
|
63
|
+
*/
|
|
56
64
|
readonly min: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
|
|
65
|
+
/**
|
|
66
|
+
* Upper bound. Reported as `aria-valuemax` and enforced when stepping; typed values are only clamped if
|
|
67
|
+
* `clampValueOnBlur` is set.
|
|
68
|
+
*/
|
|
57
69
|
readonly max: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
|
|
70
|
+
/** How much one step changes the value — a button press, or an arrow key with no modifier. */
|
|
58
71
|
readonly stepSize: _angular_core.InputSignalWithTransform<number, NumberInput>;
|
|
72
|
+
/** Step used while Shift is held, for coarse adjustment. */
|
|
59
73
|
readonly majorStepSize: _angular_core.InputSignalWithTransform<number, NumberInput>;
|
|
74
|
+
/** Step used while Alt is held, for fine adjustment. */
|
|
60
75
|
readonly minorStepSize: _angular_core.InputSignalWithTransform<number, NumberInput>;
|
|
76
|
+
/**
|
|
77
|
+
* Pull a typed value back inside `min`/`max` when the field loses focus. Off by default, so an out-of-range entry
|
|
78
|
+
* stays visible to be corrected.
|
|
79
|
+
*/
|
|
61
80
|
readonly clampValueOnBlur: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
|
|
81
|
+
/** Block interaction and dim the field and its steppers. */
|
|
62
82
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
|
|
63
83
|
protected readonly cva: _xui_core_forms.XValueAccessor<number | null>;
|
|
64
84
|
protected readonly isDisabled: Signal<boolean>;
|
|
85
|
+
/** The value, or `null` when empty. Two-way bindable as `[(value)]`; a string attribute is coerced to a number. */
|
|
65
86
|
readonly valueInput: _angular_core.InputSignalWithTransform<number | null, string | number | null | undefined>;
|
|
66
87
|
/** The current numeric value, or `null` when empty. Two-way via `value`. */
|
|
67
88
|
readonly value: _angular_core.WritableSignal<number | null>;
|