# Input Number

Level: atom.

## Purpose and use

Enter a non-negative integer with increment/decrement controls. Use Input for signed/decimal values, formatted money or an identifier that must not be numerically stepped.

## Anatomy and behavior

Text, optional side content and clear action precede a fixed stepper. Input strips nondigits; a negative prefix becomes zero, maxLength truncates and max clamps. ArrowUp/ArrowDown and buttons step by one within zero/max bounds; clear emits empty and restores focus; Escape blurs. Values and emitted changes are strings, preserving leading zeros until stepping.

## Accessibility and content

The native input has role spinbutton with min zero, optional max and current value when nonempty. Label/description and invalid states are wired to it. Disabled blocks field and steppers. Increase/decrease/clear labels are currently fixed English strings. required is a decorative marker, not native required validation.

## Open Questions

Supply finite, safe numeric bounds. Arbitrary-precision values, decimal steps, localized stepper labels and required semantics are not implemented.

## Local component contract

This is the current owned contract for `component.input-number`. Behavior above was checked
against the local implementation, template and focused tests listed below.
Historical migration evidence does not override these current sources.

### Public type values

Size: `L | M | S`; state: `default | active | disabled`; validation: `default | warning | error` (shared Input types). value/valueChange are strings; max/maxLength are number|null. max is truncated to a non-negative integer.

### Classes and selectors

- `WblInputNumberComponent` — `wbl-input-number` (src/app/design-system/primitives/input-number/input-number.component.ts).

### Inputs

- `WblInputNumberComponent.size = input<WblInputSize>('L')`
- `WblInputNumberComponent.state = input<WblInputState>('default')`
- `WblInputNumberComponent.validation = input<WblInputValidation>('default')`
- `WblInputNumberComponent.ariaLabel = input<string | null>(null)`
- `WblInputNumberComponent.showLabel = input(true)`
- `WblInputNumberComponent.labelText = input('Label')`
- `WblInputNumberComponent.required = input(false)`
- `WblInputNumberComponent.showPlaceholder = input(true)`
- `WblInputNumberComponent.placeholderText = input('Placeholder')`
- `WblInputNumberComponent.value = input('')`
- `WblInputNumberComponent.maxLength = input<number | null>(null)`
- `WblInputNumberComponent.max = input<number | null>(null)`
- `WblInputNumberComponent.leftContent = input(false)`
- `WblInputNumberComponent.leftIcon = input(false)`
- `WblInputNumberComponent.leftIconName = input<WblIconName>('spark')`
- `WblInputNumberComponent.rightContent = input(false)`
- `WblInputNumberComponent.rightIcon = input(false)`
- `WblInputNumberComponent.rightIconName = input<WblIconName>('spark')`
- `WblInputNumberComponent.clear = input(false)`
- `WblInputNumberComponent.chevron = input(false)`
- `WblInputNumberComponent.showDescription = input(false)`
- `WblInputNumberComponent.descriptionText = input('Description')`

### Models

- None.

### Outputs

- `WblInputNumberComponent.valueChange = output<string>()`

### Slots and projection markers

- The exact template has no Angular content-projection slot.

### Local evidence

- Behavior/template: `src/app/design-system/primitives/input-number/input-number.component.html` (reviewed in D-025, 2026-09-05).

- Code: `src/app/design-system/primitives/input-number/input-number.component.ts`.
- Focused test: `src/app/design-system/primitives/input-number/input-number.component.spec.ts`.
- Public export: `export * from './primitives/input-number/input-number.component';` in `src/app/design-system/index.ts`.
- Storybook: `storybook/stories/input-number.stories.ts` (`Design System/Primitives/wbl-input-number`).

## Figma status

This runtime contract does not infer a Figma owner. Assembly evidence, when
verified, is maintained separately through the inventory-linked sidecar.

## Provenance

The archived source-document copy is historical evidence only. The active
resolver is local code/test/export and the exact Storybook story above.
