Skip to main content

Spinbutton

Numeric input with increment/decrement buttons.

Usage

<w-spinbutton value="5" min="0" max="10" label="Quantity">
<w-slot down><button>-</button></w-slot>
<w-slot input><input type="text" /></w-slot>
<w-slot up><button>+</button></w-slot>
</w-spinbutton>

Props

PropTypeDefaultDescription
valuenumber0Current value
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Increment/decrement amount
labelstring""Accessible label
disabledbooleanfalseDisable input

Slots

SlotElementDescription
inputInputText input for the value
incrementButtonIncrease value button
decrementButtonDecrease value button

Events

EventDetailDescription
change{ value }Value changed

Keyboard

KeyAction
ArrowUpIncrement value
ArrowDownDecrement value
HomeSet to minimum
EndSet to maximum
PageUpIncrement by step * 10
PageDownDecrement by step * 10

Styling

The host is display: inline-flex with center alignment by default. The increment/decrement buttons get aria-disabled when at the bounds (unless wrap is set).

w-spinbutton {
border: 1px solid #ddd;
border-radius: 4px;
padding: 0.25rem;
}

w-spinbutton w-slot[input] > * {
width: 60px;
text-align: center;
border: none;
}
w-spinbutton w-slot[up] > *,
w-spinbutton w-slot[down] > * {
padding: 0.5rem 0.75rem;
cursor: pointer;
}

/* At-bound state */
w-spinbutton w-slot[up] > *[aria-disabled="true"],
w-spinbutton w-slot[down] > *[aria-disabled="true"] {
opacity: 0.4;
cursor: not-allowed;
}

/* Disabled */
w-spinbutton[disabled] {
opacity: 0.6;
pointer-events: none;
}
SelectorTargets
w-spinbutton[disabled]Disabled spinbutton
w-spinbutton w-slot[up] > *[aria-disabled="true"]Disabled increment (at max)
w-spinbutton w-slot[down] > *[aria-disabled="true"]Disabled decrement (at min)

Accessibility

  • Input has role="spinbutton"
  • aria-valuenow, aria-valuemin, aria-valuemax
  • aria-label from label prop
  • Buttons properly labeled