KQ-1166 · SLUG/FIELD

Slug Field

A title and the URL slug that follows it: each new slug letter drops out of the title as a ghost of the character as typed, capital or accent and all, and becomes the lowercase letter as it lands in its cell on the flick spring, while characters a slug cannot hold fall away before they arrive and later letters slide to their new cells on the glide spring. Typing in the slug itself folds the text the same way and unlinks it from the title, snapping the tether and chain beside the label on the snap spring, and the Follow title toggle relinks it with the letters dropping in again. An availability check marks a taken slug and offers the first free numbered one; both fields are real inputs with the platform's own caret, selection and undo, reached with Tab, and every control is a button pressed with Enter or Space.

KQ-1166 · SLUG/FIELD
fernworks.journal/posts/
Checking…
11/48

Lowercase letters, numbers and dashes.

Checking.

fernworks.journal/posts/autumn-menu · follows the title

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/slug-field

Props

title / defaultTitle
string
default ""
The title the slug follows. Controlled or uncontrolled.
onTitleChange
(title: string) => void
default —
Fires as the title is typed.
titleLabel
string
default "Title"
The title field's visible label.
titleName
string
default —
Form field name for the title input.
titlePlaceholder
string
default —
Placeholder for an empty title.
value / defaultValue
string
default —
The slug. Controlled or uncontrolled; uncontrolled, it defaults to the title's slug.
onValueChange
(slug: string) => void
default —
Fires from the keystroke, press or offer that changed the slug, including a title keystroke while it is linked.
label
string
default "URL"
The slug field's visible label.
name
string
default —
Form field name for the slug input.
prefix
string
default —
What comes before the slug, shown in the box and truncated first when space is short, such as "fernworks.journal/posts/".
linked / defaultLinked
boolean
default true
Whether the slug follows the title. Uncontrolled, it starts unlinked when `defaultValue` differs from the title's slug.
onLinkedChange
(linked: boolean) => void
default —
Fires when a hand edit unlinks the slug or the toggle links or unlinks it.
separator
"-" | "_"
default "-"
The character between words.
max
number
default 48
The longest slug the title makes, cut on a word boundary; hand typing past it is flagged, never blocked.
check
boolean
default true
Check the slug with `isTaken` once it has stood still for 300 ms, and offer a numbered one when it is taken.
isTaken
(slug: string) => boolean | Promise<boolean>
default —
The host's availability check, synchronous or not.
hint
string
default —
Guidance under the slug. Defaults to what a slug may contain.
error
string
default —
An error from the host, shown under the slug and announced once.
required
boolean
default false
Marks the slug input required.
disabled
boolean
default false
Disables both inputs and every control.
sound
boolean
default false
A tick as each letter lands and a pop when the slug relinks or takes a numbered offer. Only ever in answer to the visitor.
className
string
default —
Classes for the field's root.