A wider screen, please

This page features interactive demos and side-by-side code samples that need at least 340 pixels of horizontal space. Please widen your browser window, or rotate your device, to continue.

Morpheus v0.1.0
v0.1.0

Text input#

Component <neo-textinput> is a wrapper around a native <input> with live formatting: mask, format="number", and composable transforms like numeric-only and case="upper". Reach for it when the displayed value should differ from the typed one; a bare <input> is the right answer otherwise. The native field lives in the element's shadow root, so the light DOM stays empty and a server can re-render the host without disturbing the live field. Slot <neo-option> children to add server-driven autocomplete suggestions with built-in keyboard navigation.

Default
Card-style mask
Mixed mask
Phone
Date
Number
Number (EU)
Disabled
Deactivate Rename Duplicate
Delete
New state Toggle autoplay
HTML CSS

The selected state's markup and its scoped CSS. The CSS is wrapped in <style>@scope { ... }</style> and applies to the preview only. Edits change the preview above, applied live while Sync is on, or when you click Patch or Replace. Patch morphs the preview; Replace swaps it outright.

Replace Patch

Signals

Datastar signals declared in the selected state's markup. Change a value to drive the preview, applied live while Sync is on, or when you click Patch.

Patch

Reference#

Attributes #

NameTypeDefaultDescription
namestringnoneForm field name.
typestring observed"text"Standard <input> type.
valuestring observednoneCurrent value. For format="number", reads and writes the canonical numeric string (sign + digits + .); thousands separators and the localized decimal mark are presentation only.
placeholderstring observednoneHint text shown when empty.
disabledboolean observedfalseNon-interactive state.
readonlyboolean observedfalseValue cannot be edited but stays focusable and submittable.
requiredboolean observedfalseForm validation requires a non-empty value.
size"sm" | "lg"noneControl-size step: sm compact, lg large. Omit for the default size.
maskstring observednoneStatic template: # digit, U letter→upper, l letter→lower, A alnum→upper, a alnum→lower, X alnum (case preserved), * any char. Other chars are literal. Cased slots accept either case and coerce on insert.
format"number" observednoneRight-anchored thousands grouping for numeric input.
prefixstring reflected observednoneLeading literal preserved across clears.
decimal-placesnumber observed-1Decimal-place cap for format="number"; -1 unbounded.
decimal-mark"." | "," observed"."Decimal separator character.
thousands-separatorstring observed","Grouping separator inserted every three digits.
numeric-onlyboolean observedfalseDrop non-digit input.
case"upper" | "lower" observed""Force the displayed value to the given case. Free-form only; ignored when mask is set; use cased mask letters (U, A, l, a) instead. An unsupported value is ignored with a console warning.
submit-rawboolean observedfalseForm submission uses the unformatted value. Always on for format="number"; thousands separators never appear in the submitted value.
openboolean reflected observedfalseSuggestions popover state using the shared command contract: open="true" opens, open="false" closes, and an omitted attribute leaves client state unchanged. Client-open state is reflected as bare open, so a fat morph that omits the attribute does not close the popover.
placementstring observed"bottom-start"Suggestion popover placement relative to the field. The popover honors the same positioning surface as <neo-select> (placement, screen-offset, follow-scroll, clamp-placement, min-fit-height/min-fit-width, min-open-height/min-open-width, popover-fit-content) plus the --neo-popover-* custom properties. Applies only when the suggestions slot is in use.
popover-fit-contentbooleanfalseThe suggestions panel tracks the field width by default; set this to size the panel to the suggestion rows instead. Capped by --neo-popover-max-width and the viewport. Applies only when the suggestions slot is in use.
liststring observednoneReferences a shared <neo-datalist> by its id (like native <input list>) to source the autocomplete suggestions. Inline suggestion options take precedence.

Slots #

NameDescription
suggestionsSlotted <neo-option> children turn the field into an autocomplete: a listbox of suggestions. The field stays free text: the value is whatever's typed; options are hints. Bare <neo-option> children are assigned to this slot automatically. Same option API as <neo-select> (value, label, disabled, rich content). A [data-neo-empty-results] child is a non-selectable status row that keeps the popover open with zero options (same contract as <neo-combobox>). The server may patch the slot at any time; patching it empty (no options and no status row) closes the popover. The field gains role="combobox" whenever suggestions exist or the popover is open; focus never leaves it (ArrowDown/Up move aria-activedescendant). Alternatively, set list to source these options from a shared datalist.

Events #

NameDetailBubblesDescription
input noneyesStandard input event.
change noneyesStandard change event.
neo-textinput-input{ value: string, rawValue: string }yesMirrors input with both formatted and raw values in detail.
neo-textinput-change{ value: string, rawValue: string }yesMirrors change.
neo-textinput-select{ value: string, label: string }yesA suggestion was committed (click or Enter). value is the option's value, label its visible text.

Examples#

Card-style mask#

In mask, # is a digit slot and the spaces between groups are literal delimiters.

  • Spaces appear at the right positions as you type.
  • Backspace at a delimiter deletes the preceding digit, so the literal never has to be skipped manually.

Mixed mask#

A mask can mix letter, digit, and literal slots. Cased slots (U, l, A, a) accept either case and coerce on insert; use X to keep the typed case.

Phone#

Parentheses, space, and dash are all literals in the mask.

Date#

A ##/##/#### mask shapes the digits but doesn't validate calendar logic (Feb 30 is accepted); pair it with the native pattern attribute when stricter checks are needed.

Number#

format="number" applies right-anchored thousands grouping with optional decimals. The prefix attribute pins a literal at the start.

Number (EU)#

European notation from the same number format: decimal-mark="," with a period thousands-separator.

Disabled#

disabled and readonly pass through to the inner field: disabled fades the host and blocks all interaction; readonly leaves the value selectable but immutable.

Examples: Datastar#

Suggestion states#

Slotted suggestions are server state: a Datastar morph can swap the set at any time and the field reconciles in place. Switch states to compare.

  • Initial has no suggestions; Suggestions, Disabled, and Rich morph rows in: plain, with disabled rows, then rich rows (icon plus a short description). The typed value is untouched.
  • No results shows a non-selectable [data-neo-empty-results] status row, keeping the popover open with zero options instead of closing.
  • The open attribute forces the popover open so each state shows without focusing the preview; normally suggestions appear on focus.
Initial
Suggestions
Disabled
Rich
No results
Deactivate Rename Duplicate
Delete
New state Toggle autoplay
HTML CSS

The selected state's markup and its scoped CSS. The CSS is wrapped in <style>@scope { ... }</style> and applies to the preview only. Edits change the preview above, applied live while Sync is on, or when you click Patch or Replace. Patch morphs the preview; Replace swaps it outright.

Replace Patch

Signals

Datastar signals declared in the selected state's markup. Change a value to drive the preview, applied live while Sync is on, or when you click Patch.

Patch

Autocomplete#

Slot <neo-option> children to turn the field into an autocomplete: free text the user can submit as typed, with server-supplied suggestions and built-in keyboard navigation.

  • Each debounced keystroke posts the query; the server morphs matching <neo-option> rows into the suggestions slot, a [data-neo-empty-results] row when nothing matches, or nothing to close the popover.
  • Focus stays in the field; ArrowDown / ArrowUp move the highlight, Enter or click fills it, Escape closes. Options keep the <neo-option> API: value, label, disabled, rich content.
  • Constrain the value to a fixed set instead? Combobox is the constrained-selection version.

Loading states only show with simulated delay. Raise network latency or handler delay in the Settings panel.

Settings

Theme

Default Sunshine Ocean Matrix Rose

Accessibility

Playgrounds

Server Simulator