API Reference
Complete documentation for segmented-input. For interactive examples of every preset, see the live demos.
Built-in presets
| Key | Example value | Description | inputmode | autocapitalize |
|---|---|---|---|---|
ipv4 | 192.168.1.1 | Four 0-255 octets | numeric | — |
ipv6 | 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | Eight 16-bit hex groups | text | characters |
mac | 00:1A:2B:3C:4D:5E | Six hex bytes | text | characters |
date | 2024-03-15 | YYYY-MM-DD | numeric | — |
dateWithPicker | 2024-03-15 ⏱︎ | Date + action segment (wire up onClick yourself) | numeric | — |
dateRange | 2024-01-01 → 2024-12-31 | Start date → end date | numeric | — |
time | 14:30:00 | HH:MM:SS (24-hour) | numeric | — |
duration | 01:30:00 | HH:MM:SS (hours unbounded) | numeric | — |
rgba | rgba(125, 125, 125, 0.5) | r/g/b ∈ [0,255], a ∈ [0,1] | decimal | — |
hsla | hsla(180, 50%, 75%, 1) | h 0-360, s/l 0-100%, a 0-1 | decimal | — |
uuid | 550e8400-e29b-41d4-a716-446655440000 | Five hex groups (8-4-4-4-12) | text | characters |
semver | 2.14.3 | MAJOR.MINOR.PATCH | numeric | — |
creditCard | 4111 1111 1111 1111 | Four groups of four digits | numeric | — |
expiryDate | 12/28 | MM/YY | numeric | — |
phone | (555) 867-5309 | US area code · exchange · subscriber | tel | — |
price | $19.99 | Dollars · cents | decimal | — |
currency | €12.50 | Symbol (↑/↓ or type) · dollars · cents | decimal | — |
mathExpr | (6 + 4) / 2 | Three operands | numeric | — |
calc | 3 * 4 | Operand · operator · operand | — | — |
fullName | Jane Doe | First · last text segments | text | words |
Usage
import { SegmentedInput } from 'segmented-input/src/segmented-input.js'
import * as presets from 'segmented-input/src/presets.js'
new SegmentedInput(el, presets.ipv4)
new SegmentedInput(el, presets.rgba)
new SegmentedInput(el, presets.duration)
// … any key from the table above
Custom format
Supply a segments array (one entry per segment), a format function
(array → display string), and a parse function (display string → array):
new SegmentedInput(el, {
segments: [
{ value: '125', min: 0, max: 255, step: 1 }, // r
{ value: '125', min: 0, max: 255, step: 1 }, // g
{ value: '125', min: 0, max: 255, step: 1 }, // b
{ value: '0.5', min: 0, max: 1, step: 0.1 }, // a
],
format: (v) => `rgba(${v[0]}, ${v[1]}, ${v[2]}, ${v[3]})`,
parse: (s) => {
const m = s.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
return m ? [m[1], m[2], m[3], m[4] ?? '1'] : ['0', '0', '0', '1']
},
})
Segment properties
| Property | Type | Description |
|---|---|---|
value | string | Default/initial value for this segment. |
placeholder | string | Placeholder text shown when the segment is empty. |
min | number | Minimum numeric value (clamps on ↑/↓). |
max | number | Maximum numeric value (clamps on ↑/↓). |
step | number | Amount to increment/decrement per keypress. Default 1. |
maxLength | number | Maximum number of characters the user can type into this segment. |
pattern | RegExp | Only characters matching this pattern are accepted when typing. |
type | 'text' | 'action' | Set to 'action' for non-editable icon/button segments. |
selectable | boolean | When true (action segments), ↑/↓ cycles through options. |
options | string[] | List of values a selectable action segment can cycle through. |
onClick | (instance, option?) => void | Called when an action segment is clicked or Enter is pressed on it. |
Action segments
Action segments are non-editable "button" segments embedded in the input value — useful for
"clear", "today", geolocation, or toggle icons. The library adds the si-action-active
class to the input when an action segment is focused, letting you style the amber selection:
new SegmentedInput(el, {
segments: [
{ value: '2024', placeholder: 'yyyy', min: 1, max: 9999, step: 1 },
{ value: '06', placeholder: 'mm', min: 1, max: 12, step: 1 },
{ value: '15', placeholder: 'dd', min: 1, max: 31, step: 1 },
{ value: '⏱︎', placeholder: '⏱︎', type: 'action', onClick(instance) {
const t = new Date()
instance.setSegmentValue(0, `${t.getFullYear()}`)
instance.setSegmentValue(1, `${t.getMonth() + 1)}`.padStart(2, '0'))
instance.setSegmentValue(2, `${t.getDate()}`.padStart(2, '0'))
},
},
],
format: (v) => `${v[0]}-${v[1]}-${v[2]} ${v[3]}`,
parse: (s) => { /* … */ },
})
/* Highlight the action segment in amber when focused */
input.si-action-active::selection {
background: #f0ad4e;
color: #000;
}
Constructor
const instance = new SegmentedInput(inputElement, options)
| Parameter | Type | Description |
|---|---|---|
inputElement | HTMLInputElement | The <input> to enhance. |
options.segments | SegmentDef[] | One entry per segment (see segment properties above). |
options.format | (values: string[]) => string | Build the display string from segment values. |
options.parse | (str: string) => string[] | Split the display string back into segment values. Must return the same number of elements as segments. |
options.invalidMessage | string | Message for setCustomValidity() when segments are incomplete. Defaults to 'Please fill in all fields.'. |
options.…any | string | Any other property (e.g. inputmode, autocapitalize, autocomplete, autofocus, id, class) is forwarded to the <input> as an HTML attribute via setAttribute. Ignored when the attribute is already present on the element. Event-handler attributes (on*) are intentionally skipped. |
options.actionActiveClass | string | CSS class added to the <input> when a selectable action segment is active. Defaults to 'si-action-active'. |
Instance methods
| Method | Returns | Description |
|---|---|---|
focusSegment(index) | void | Highlight the segment at index (clamped to valid range). |
getSegmentValue(index) | string | Return the current string value of segment index. |
setSegmentValue(index, value) | void | Overwrite a segment value and reformat. Fires input + change events. |
increment() | void | Increment the active segment by its step. |
decrement() | void | Decrement the active segment by its step. |
getSegmentRanges() | {start, end, value}[] | Character ranges for all segments in the current value string. |
destroy() | void | Remove all event listeners. Call when removing the element. |
Reading the value
For inputs without action segments, read input.value as normal.
For inputs with action segments (icons embedded in the value string),
use the instance's value getter, which strips the icon segments:
const inst = new SegmentedInput(input, optionsWithActionSegments)
// ✅ Clean value, icons stripped
console.log(inst.value)
// ⚠️ Raw value — includes icon characters when action segments are present
console.log(input.value)
Instance events
The underlying <input> element dispatches these custom events:
| Event | Detail | Description |
|---|---|---|
segmentfocus | { index: number } | Fired when a segment becomes active (focused/clicked). |
segmentblur | { index: number } | Fired when the active segment loses focus. |
segmentchange | { index: number, value: string } | Fired when a segment's value changes. |
const inst = new SegmentedInput(input, presets.date)
inst.addEventListener('segmentfocus', evt => {
console.log('focused segment', evt.detail.index)
})
inst.addEventListener('segmentchange', evt => {
console.log('segment', evt.detail.index, 'changed to', evt.detail.value)
})
Low-level helpers
These utilities are exported separately for advanced use cases:
import {
getSegmentRanges,
getCursorSegment,
highlightSegment,
} from 'segmented-input'
| Function | Description |
|---|---|
getSegmentRanges(value, parse, format) | Compute {start, end, value}[] character ranges for each segment in value. |
getCursorSegment(cursorPos, segmentRanges) | Return the index of the segment the cursor position falls within. |
highlightSegment(input, index, segmentRanges) | Call setSelectionRange to visually select/highlight a segment. |