API Reference

Complete documentation for segmented-input. For interactive examples of every preset, see the live demos.

Built-in presets

KeyExample valueDescriptioninputmodeautocapitalize
ipv4192.168.1.1Four 0-255 octetsnumeric
ipv62001:0db8:85a3:0000:0000:8a2e:0370:7334Eight 16-bit hex groupstextcharacters
mac00:1A:2B:3C:4D:5ESix hex bytestextcharacters
date2024-03-15YYYY-MM-DDnumeric
dateWithPicker2024-03-15 ⏱︎Date + action segment (wire up onClick yourself)numeric
dateRange2024-01-01 → 2024-12-31Start date → end datenumeric
time14:30:00HH:MM:SS (24-hour)numeric
duration01:30:00HH:MM:SS (hours unbounded)numeric
rgbargba(125, 125, 125, 0.5)r/g/b ∈ [0,255], a ∈ [0,1]decimal
hslahsla(180, 50%, 75%, 1)h 0-360, s/l 0-100%, a 0-1decimal
uuid550e8400-e29b-41d4-a716-446655440000Five hex groups (8-4-4-4-12)textcharacters
semver2.14.3MAJOR.MINOR.PATCHnumeric
creditCard4111 1111 1111 1111Four groups of four digitsnumeric
expiryDate12/28MM/YYnumeric
phone(555) 867-5309US area code · exchange · subscribertel
price$19.99Dollars · centsdecimal
currency€12.50Symbol (↑/↓ or type) · dollars · centsdecimal
mathExpr(6 + 4) / 2Three operandsnumeric
calc3 * 4Operand · operator · operand
fullNameJane DoeFirst · last text segmentstextwords

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

PropertyTypeDescription
valuestringDefault/initial value for this segment.
placeholderstringPlaceholder text shown when the segment is empty.
minnumberMinimum numeric value (clamps on ↑/↓).
maxnumberMaximum numeric value (clamps on ↑/↓).
stepnumberAmount to increment/decrement per keypress. Default 1.
maxLengthnumberMaximum number of characters the user can type into this segment.
patternRegExpOnly characters matching this pattern are accepted when typing.
type'text' | 'action'Set to 'action' for non-editable icon/button segments.
selectablebooleanWhen true (action segments), ↑/↓ cycles through options.
optionsstring[]List of values a selectable action segment can cycle through.
onClick(instance, option?) => voidCalled 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)
ParameterTypeDescription
inputElementHTMLInputElementThe <input> to enhance.
options.segmentsSegmentDef[]One entry per segment (see segment properties above).
options.format(values: string[]) => stringBuild 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.invalidMessagestringMessage for setCustomValidity() when segments are incomplete. Defaults to 'Please fill in all fields.'.
options.…anystringAny 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.actionActiveClassstringCSS class added to the <input> when a selectable action segment is active. Defaults to 'si-action-active'.

Instance methods

MethodReturnsDescription
focusSegment(index)voidHighlight the segment at index (clamped to valid range).
getSegmentValue(index)stringReturn the current string value of segment index.
setSegmentValue(index, value)voidOverwrite a segment value and reformat. Fires input + change events.
increment()voidIncrement the active segment by its step.
decrement()voidDecrement the active segment by its step.
getSegmentRanges(){start, end, value}[]Character ranges for all segments in the current value string.
destroy()voidRemove 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:

EventDetailDescription
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'
FunctionDescription
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.