Data input
Number Input
A number input with − and + buttons that step its value within its minimum and maximum.
| Class name | Type | Description |
|---|---|---|
joinplf:join | Component | Joins the input and its buttons |
join-itemplf:join-item | Part | The input and each button |
<div class="field">
<label class="field-label" for="number-gpus">Number of GPUs</label>
<div class="join">
<input class="input join-item w-20" id="number-gpus" name="gpus" type="number" value="8" min="1" max="99">
<button class="btn btn-outline btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div><div class="plf:field">
<label class="plf:field-label" for="number-gpus">Number of GPUs</label>
<div class="plf:join">
<input class="plf:input plf:join-item plf:w-20" id="number-gpus" name="gpus" type="number" value="8" min="1" max="99">
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>import { Field, NumberInput } from '@pelatform/react';
export function Example() {
return (
<Field label="Number of GPUs">
<NumberInput className="w-20" name="gpus" defaultValue={8} min={1} max={99} />
</Field>
);
}import { Field, NumberInput } from '@pelatform/react/prefixed';
export function Example() {
return (
<Field label="Number of GPUs">
<NumberInput className="plf:w-20" name="gpus" defaultValue={8} min={1} max={99} />
</Field>
);
}<div class="field">
<label class="field-label" for="number-seats">Seats</label>
<div class="join">
<button class="btn btn-outline btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<input class="input join-item w-20 text-center" id="number-seats" name="seats" type="number" value="5" min="1" max="50">
<button class="btn btn-outline btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div><div class="plf:field">
<label class="plf:field-label" for="number-seats">Seats</label>
<div class="plf:join">
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<input class="plf:input plf:join-item plf:w-20 plf:text-center" id="number-seats" name="seats" type="number" value="5" min="1" max="50">
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>import { Field, NumberInput } from '@pelatform/react';
export function Example() {
return (
<Field label="Seats">
<NumberInput buttons="around" className="w-20 text-center" name="seats" defaultValue={5} min={1} max={50} />
</Field>
);
}import { Field, NumberInput } from '@pelatform/react/prefixed';
export function Example() {
return (
<Field label="Seats">
<NumberInput buttons="around" className="plf:w-20 plf:text-center" name="seats" defaultValue={5} min={1} max={50} />
</Field>
);
}<div class="field">
<label class="field-label" for="number-hours">Hours per day</label>
<div class="join">
<input class="input join-item w-20" id="number-hours" name="hours" type="number" value="7.5" min="0.5" max="24" step="0.5">
<button class="btn btn-outline btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div><div class="plf:field">
<label class="plf:field-label" for="number-hours">Hours per day</label>
<div class="plf:join">
<input class="plf:input plf:join-item plf:w-20" id="number-hours" name="hours" type="number" value="7.5" min="0.5" max="24" step="0.5">
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>import { Field, NumberInput } from '@pelatform/react';
export function Example() {
return (
<Field label="Hours per day">
<NumberInput className="w-20" name="hours" defaultValue={7.5} min={0.5} max={24} step={0.5} />
</Field>
);
}import { Field, NumberInput } from '@pelatform/react/prefixed';
export function Example() {
return (
<Field label="Hours per day">
<NumberInput className="plf:w-20" name="hours" defaultValue={7.5} min={0.5} max={24} step={0.5} />
</Field>
);
}<div class="field">
<label class="field-label" for="number-small">Small</label>
<div class="join">
<input class="input input-sm join-item w-20" id="number-small" type="number" value="1" min="0">
<button class="btn btn-outline btn-sm btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-sm btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div>
<div class="field">
<label class="field-label" for="number-large">Large</label>
<div class="join">
<input class="input input-lg join-item w-24" id="number-large" type="number" value="1" min="0">
<button class="btn btn-outline btn-lg btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-lg btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div><div class="plf:field">
<label class="plf:field-label" for="number-small">Small</label>
<div class="plf:join">
<input class="plf:input plf:input-sm plf:join-item plf:w-20" id="number-small" type="number" value="1" min="0">
<button class="plf:btn plf:btn-outline plf:btn-sm plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-sm plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>
<div class="plf:field">
<label class="plf:field-label" for="number-large">Large</label>
<div class="plf:join">
<input class="plf:input plf:input-lg plf:join-item plf:w-24" id="number-large" type="number" value="1" min="0">
<button class="plf:btn plf:btn-outline plf:btn-lg plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-lg plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>import { Field, NumberInput } from '@pelatform/react';
export function Example() {
return (
<>
<Field label="Small">
<NumberInput size="sm" className="w-20" defaultValue={1} min={0} />
</Field>
<Field label="Large">
<NumberInput size="lg" className="w-24" defaultValue={1} min={0} />
</Field>
</>
);
}import { Field, NumberInput } from '@pelatform/react/prefixed';
export function Example() {
return (
<>
<Field label="Small">
<NumberInput size="sm" className="plf:w-20" defaultValue={1} min={0} />
</Field>
<Field label="Large">
<NumberInput size="lg" className="plf:w-24" defaultValue={1} min={0} />
</Field>
</>
);
}Disabled and read-only
The script disables the buttons of a disabled or readonly input; a read-only value still submits.
<div class="field">
<label class="field-label" for="number-disabled">Disabled</label>
<div class="join">
<input class="input join-item w-20" id="number-disabled" name="retries" type="number" value="3" min="0" disabled>
<button class="btn btn-outline btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div>
<div class="field">
<label class="field-label" for="number-readonly">Read-only</label>
<div class="join">
<input class="input join-item w-20" id="number-readonly" name="included-seats" type="number" value="10" readonly>
<button class="btn btn-outline btn-square join-item" data-plf-decrement hidden>
<span class="icon icon-minus"></span>
</button>
<button class="btn btn-outline btn-square join-item" data-plf-increment hidden>
<span class="icon icon-plus"></span>
</button>
</div>
</div><div class="plf:field">
<label class="plf:field-label" for="number-disabled">Disabled</label>
<div class="plf:join">
<input class="plf:input plf:join-item plf:w-20" id="number-disabled" name="retries" type="number" value="3" min="0" disabled>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>
<div class="plf:field">
<label class="plf:field-label" for="number-readonly">Read-only</label>
<div class="plf:join">
<input class="plf:input plf:join-item plf:w-20" id="number-readonly" name="included-seats" type="number" value="10" readonly>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-decrement hidden>
<span class="plf:icon plf:icon-minus"></span>
</button>
<button class="plf:btn plf:btn-outline plf:btn-square plf:join-item" data-plf-increment hidden>
<span class="plf:icon plf:icon-plus"></span>
</button>
</div>
</div>import { Field, NumberInput } from '@pelatform/react';
export function Example() {
return (
<>
<Field label="Disabled">
<NumberInput className="w-20" name="retries" defaultValue={3} min={0} disabled />
</Field>
<Field label="Read-only">
<NumberInput className="w-20" name="included-seats" defaultValue={10} readOnly />
</Field>
</>
);
}import { Field, NumberInput } from '@pelatform/react/prefixed';
export function Example() {
return (
<>
<Field label="Disabled">
<NumberInput className="plf:w-20" name="retries" defaultValue={3} min={0} disabled />
</Field>
<Field label="Read-only">
<NumberInput className="plf:w-20" name="included-seats" defaultValue={10} readOnly />
</Field>
</>
);
}JavaScript
The − and + buttons need JavaScript, so author them hidden; without it the native input still steps with its arrow keys. The Full script (pelatform-ui.min.js) starts every component on page load, with no code of your own; with ESM imports, call init() yourself, as in Installation. For markup you add later, see Dynamic content.
<link rel="stylesheet" href="pelatform-ui.min.css">
<link rel="stylesheet" href="icons/icons.min.css">
<script src="pelatform-ui.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.min.css">
<link rel="stylesheet" href="components/button.min.css">
<link rel="stylesheet" href="components/form.min.css">
<link rel="stylesheet" href="components/button-group.min.css">
<link rel="stylesheet" href="icons/icons.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/number-input.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script><link rel="stylesheet" href="pelatform-ui.prefixed.min.css">
<link rel="stylesheet" href="icons/icons.prefixed.min.css">
<script src="pelatform-ui.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.prefixed.min.css">
<link rel="stylesheet" href="components/button.prefixed.min.css">
<link rel="stylesheet" href="components/form.prefixed.min.css">
<link rel="stylesheet" href="components/button-group.prefixed.min.css">
<link rel="stylesheet" href="icons/icons.prefixed.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/number-input.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script>| Attribute | Purpose |
|---|---|
data-plf-decrement, data-plf-increment |
On a button beside one <input type="number">: steps its value down or up within the input’s min, max and step, then sends input and change. The script shows the button, takes it out of the Tab order and disables it at the limit and while the input is disabled or read-only. Named Decrease or Increase unless it has a name; in a form, write type="button" so it does not submit |
min, max, step |
On the input, natively; step="any" cannot be stepped by a button |
| Method | Behavior |
|---|---|
PLF. |
Returns the button’s instance, creating it for valid markup |
PLF. |
Returns the instance or null |
instance. |
Removes listeners and what the script added, so the button is hidden again; the input keeps its value |
With ESM, import NumberInput from @pelatform/ui/components/number-input. Number Input fires no events of its own: listen to the input’s native input and change. After setting the value in code, dispatch an input event so the buttons follow.
Keyboard
| Key | Action |
|---|---|
| Tab, Shift+Tab | Move to and from the input; the buttons are not tab stops |
| Arrow Up, Arrow Down | Step the value, natively |
| Digits | Type a value, natively |
React
NumberInput from @pelatform/react renders the input with its − and + buttons, which step the value as the script’s do; inside a Field the input takes the field’s label, help and error.
| Prop | Values | Default |
|---|---|---|
size |
sm, lg, for the input and its buttons |
The default size |
buttons |
after, around (the − button before the input) |
after |
value |
A number, or null when empty, which the application changes in onValueChange |
Its own state |
defaultValue |
The number it starts with when the application does not set value |
Empty |
onValueChange |
(value), called with the number, or null when empty, when typing or a button changes it |
None |
decrementLabel |
The − button’s name | Decrease |
incrementLabel |
The + button’s name | Increase |
The other props are the native input’s, className and ref included; step is a number, and a button’s step reaches onChange as typing does.
CSS variables
The input takes Input’s variables and the buttons Button’s; joined to the input, an outline button’s border follows --plf-input-border.