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";Common options
Section titled “Common options”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).
numInput mode (integer / float only)
Section titled “numInput mode (integer / float only)”presets.integer() and presets.float() support { numInput: true, default: n }. In this mode:
$valueholds a string (bindable to<input>)$resolvedholds a number (parsed + validated, falls back todefaulton invalid input)- Clearing the input sets
$valueto"", and$resolvedmaps 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").
presets.string(options?)
Section titled “presets.string(options?)”| 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> | [] |
String-specific options
Section titled “String-specific options”| Option | Type | Default | Description |
|---|---|---|---|
maxLength | number | — | Maximum string length |
outOfRange | "clamp" | "reject" | "clamp" | Truncate or reject strings exceeding max |
{
base: '',
maxLen: '',
optional: undefined
}(empty)
presets.integer(options?)
Section titled “presets.integer(options?)”| 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 | "" |
Integer-specific options
Section titled “Integer-specific options”| 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(orundefinedfor optional) - Encode (store → URL): out-of-range values throw → parameter is removed from URL
(empty)
{
round: NaN,
ceil: NaN,
parse: NaN,
clamped: NaN,
reject: NaN
}(empty)
presets.float(options?)
Section titled “presets.float(options?)”| 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 | "" |
Float-specific options
Section titled “Float-specific options”| 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 |
(empty)
{
base: NaN,
fixed2: NaN,
clamped: NaN
}(empty)
presets.boolean(options?)
Section titled “presets.boolean(options?)”| 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> | [] |
Decode / encode behavior
Section titled “Decode / encode behavior”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 isfalse. Invalid → fallback tofalse. Encode omits value when it equalsdefaultValue. boolean({ default: true }): default istrue. Invalid → fallback totrue. Encode omitstrue(the default), sofalseappears in URL — the encode logic flips compared toboolean().- Optional (
boolean({ optional: true })): Invalid → fallback toundefined. Both"true"and"false"appear in URL; omitted meansundefined.
{
base: false,
defTrue: true,
opt: undefined
}(empty)
presets.enum(enumArray, options?)
Section titled “presets.enum(enumArray, options?)”| 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).
{
base: 'newest',
optional: undefined,
array: []
}(empty)
presets.date(options?)
Section titled “presets.date(options?)”| 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().
(empty)
{
base: Invalid Date,
optional: undefined
}(empty)
presets.ymd(options?)
Section titled “presets.ymd(options?)”| 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.
{
base: '0000-00-00',
optional: undefined
}(empty)
presets.hms(options?)
Section titled “presets.hms(options?)”| 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.
{
base: '00:00:00',
optional: undefined
}(empty)
presets.tuple(configs)
Section titled “presets.tuple(configs)”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.
(empty)
scale: [ NaN ] coord: [ NaN, NaN ] filter: [ '', '', false ]
[ '', 0, false ]
scale: (empty) coord: (empty) filter: (empty)
Creating custom presets
Section titled “Creating custom presets”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.