Skip to content

Presets Reference

All presets are imported from @vp-tw/nanostores-qs/presets. Every preset is a function that accepts an options object.

import * as presets from "@vp-tw/nanostores-qs/presets";

All built-in presets accept these options:

Option Type Description
optional true Value becomes T | undefined (no defaultValue)
default T Override the type’s inherent default
array true Array variant using multiple same-name params
maxItems number Cap on array items (only with array: true)

These options are mutually exclusive — pass exactly one of optional, default, or array (or none for the base variant).

presets.integer() and presets.float() support { numInput: true, default: n }. In this mode:

  • $value holds a string (bindable to <input>)
  • $resolved holds a number (parsed + validated, falls back to default on invalid input)
  • Clearing the input sets $value to "", and $resolved maps it to the default

This is useful for number inputs where the raw string must be preserved during editing (e.g., typing "19." should not immediately normalize to "19").

Call Value Type Default
presets.string() string ""
presets.string({ optional: true }) string | undefined undefined
presets.string({ default: "all" }) string "all"
presets.string({ array: true }) Array<string> []
Option Type Default Description
maxLength number — Maximum string length
outOfRange "clamp" | "reject" "clamp" Truncate or reject strings exceeding max
$values
{
  base: '',
  maxLen: '',
  optional: undefined
}
URL
(empty)
Call Value Type Default
presets.integer() number NaN
presets.integer({ optional: true }) number | undefined undefined
presets.integer({ default: 1 }) number 1
presets.integer({ array: true }) Array<number> []
presets.integer({ numInput: true, default: 1 }) NumInputResult ""
Option Type Default Description
round "round" | "ceil" | "floor" | "parse" "round" Rounding mode ("parse" uses parseInt)
min number Number.MIN_SAFE_INTEGER Minimum allowed value
max number Number.MAX_SAFE_INTEGER Maximum allowed value
outOfRange "clamp" | "reject" "clamp" Clamp to range or reject out-of-range values
numInput true — Input binding mode: $value is string, $resolved is number. Requires default

When outOfRange is "reject":

  • Decode (URL → store): out-of-range values throw → falls back to defaultValue (or undefined for optional)
  • Encode (store → URL): out-of-range values throw → parameter is removed from URL
integer() — round
integer({ round: "ceil" })
integer({ round: "parse" })
integer({ min: 0, max: 100 }) — clamp
integer({ ..., outOfRange: "reject" })
Input URL
(empty)
$values (decoded)
{
  round: NaN,
  ceil: NaN,
  parse: NaN,
  clamped: NaN,
  reject: NaN
}
Output URL
(empty)
Call Value Type Default
presets.float() number NaN
presets.float({ optional: true }) number | undefined undefined
presets.float({ default: 0 }) number 0
presets.float({ array: true }) Array<number> []
presets.float({ numInput: true, default: 0 }) NumInputResult ""
Option Type Default Description
fixed number — Decimal places (uses toFixed(n))
min number -Infinity Minimum allowed value
max number Infinity Maximum allowed value
outOfRange "clamp" | "reject" "clamp" Clamp to range or reject out-of-range values
numInput true — Input binding mode: $value is string, $resolved is number. Requires default
float()
float({ fixed: 2 })
float({ fixed: 2, min: 0, max: 1 })
Input URL
(empty)
$values (decoded)
{
  base: NaN,
  fixed2: NaN,
  clamped: NaN
}
Output URL
(empty)
Call Value Type Default
presets.boolean() boolean false
presets.boolean({ optional: true }) boolean | undefined undefined
presets.boolean({ default: true }) boolean true
presets.boolean({ array: true }) Array<boolean> []

All variants use strict decode: only "true" and "false" are accepted. Any other value throws and falls back to defaultValue (or undefined for optional, filtered out for array).

  • Base (boolean()): default is false. Invalid → fallback to false. Encode omits value when it equals defaultValue.
  • boolean({ default: true }): default is true. Invalid → fallback to true. Encode omits true (the default), so false appears in URL — the encode logic flips compared to boolean().
  • Optional (boolean({ optional: true })): Invalid → fallback to undefined. Both "true" and "false" appear in URL; omitted means undefined.
$values
{
  base: false,
  defTrue: true,
  opt: undefined
}
URL
(empty)
Call Value Type Default
presets.enum(sortOptions) "newest" | "oldest" | "popular" "newest"
presets.enum(sortOptions, { optional: true }) ... | undefined undefined
presets.enum(sortOptions, { default: "popular" }) same union "popular"
presets.enum(sortOptions, { array: true }) Array<...> []

The first element of enumArray is the inherent default. Invalid values throw (fall back to default in base, filtered out in array).

$values
{
  base: 'newest',
  optional: undefined,
  array: []
}
URL
(empty)
Call Value Type Default
presets.date() Date new Date(NaN)
presets.date({ optional: true }) Date | undefined undefined
presets.date({ default: d }) Date d
presets.date({ array: true }) Array<Date> []

Decode: new Date(String(value)), throws if getTime() is NaN. Encode: value.toISOString(). Guards against Invalid Date — returns undefined if the date is invalid, preventing RangeError from toISOString().

date()
date({ optional: true })
Input URL
(empty)
$values (decoded)
{
  base: Invalid Date,
  optional: undefined
}
Output URL
(empty)
Call Value Type Default
presets.ymd() string "0000-00-00"
presets.ymd({ optional: true }) string | undefined undefined
presets.ymd({ array: true }) Array<string> []

Format: YYYY-MM-DD. Validates both format and semantic correctness — rejects values like "2024-13-01" or "2024-02-30" that aren’t real calendar dates.

The default value "0000-00-00" is an intentional sentinel (like NaN for integer) — it signals “no date selected”. Use { optional: true } if you prefer undefined.

$values
{
  base: '0000-00-00',
  optional: undefined
}
URL
(empty)
Call Value Type Default
presets.hms() string "00:00:00"
presets.hms({ optional: true }) string | undefined undefined
presets.hms({ array: true }) Array<string> []

Format: HH:mm:ss. Validates hour 00-23, minute/second 00-59.

$values
{
  base: '00:00:00',
  optional: undefined
}
URL
(empty)

Combines multiple preset configs into a single array parameter. No optional, default, or array modifiers. Decode: each element decoded independently with its config. If an element throws, only that element falls back to its own defaultValue — other elements are unaffected.

tuple([float()]) — single
tuple([float(), float()]) — pair
tuple([string(), integer({ numInput, default: 0 }), boolean()]) — mixed with resolve
Input URL
(empty)
$value (decoded)
scale:  [ NaN ]
coord:  [ NaN, NaN ]
filter: [ '', '', false ]
$resolved (filter)
[ '', 0, false ]
Output URL
scale:  (empty)
coord:  (empty)
filter: (empty)

Use createPreset to build your own preset function with the same options API. See Custom Presets for live examples with enum validation and decimal.js.