Introduction
Accordion
Badge
Button
Card
Checkbox
Counter
Dialog
Dropdown
Input
Select
Switch
Tabs
Toast
Tooltip
Controlled Input
Field Arrays
Submit
Validation

Controlled Input

Demonstrates Signal ↔ input value synchronization patterns for two-way data binding.

See interactive examples below.

1import { createSignal } from '@barefootjs/dom'2import { Input } from '@/components/ui/input'34const [text, setText] = createSignal('')56<Input7  inputValue={text()}8  onInput={(e) => setText(e.target.value)}9  inputPlaceholder="Type something..."10/>11<p>Current value: {text()}</p>

#Pattern Overview

The controlled input pattern uses value={signal()} combined with onInput to create two-way binding between a signal and an input element. This pattern enables real-time synchronization and derived computations.

1import { createSignal } from '@barefootjs/dom'2import { Input } from '@/components/ui/input'34const [text, setText] = createSignal('')56<Input7  inputValue={text()}8  onInput={(e) => setText(e.target.value)}9  inputPlaceholder="Type something..."10/>11<p>Current value: {text()}</p>

#Examples

#Basic Two-Way Binding

Current value:

1import { createSignal } from '@barefootjs/dom'2import { Input } from '@/components/ui/input'34const [text, setText] = createSignal('')56<Input7  inputValue={text()}8  onInput={(e) => setText(e.target.value)}9  inputPlaceholder="Type something..."10/>11<p>Current value: {text()}</p>

#Character Count

Characters: 0100 remaining
1import { createSignal, createMemo } from '@barefootjs/dom'23const [text, setText] = createSignal('')4const charCount = createMemo(() => text().length)5const remaining = createMemo(() => 100 - text().length)67<Input8  inputValue={text()}9  onInput={(e) => setText(e.target.value)}10/>11<p>Characters: {charCount()}</p>12<p>{remaining()} remaining</p>

#Live Preview

Uppercase:

Word count: 0

1import { createSignal, createMemo } from '@barefootjs/dom'23const [text, setText] = createSignal('')4const uppercase = createMemo(() => text().toUpperCase())5const wordCount = createMemo(() => {6  const trimmed = text().trim()7  return trimmed === '' ? 0 : trimmed.split(/\s+/).length8})910<Input11  inputValue={text()}12  onInput={(e) => setText(e.target.value)}13/>14<p>Uppercase: {uppercase()}</p>15<p>Word count: {wordCount()}</p>

#Multi-Input Sync

Shared value:

1import { createSignal } from '@barefootjs/dom'23const [text, setText] = createSignal('')45// Both inputs share the same signal6<Input inputValue={text()} onInput={(e) => setText(e.target.value)} />7<Input inputValue={text()} onInput={(e) => setText(e.target.value)} />8<p>Shared value: {text()}</p>

#Key Points

Pattern Structure

  • inputValue={signal()} - Binds signal value to input
  • onInput={(e) => setSignal(e.target.value)} - Updates signal on input
  • Use createMemo for derived values (character count, transformations)

Use Cases

  • Form validation with real-time feedback
  • Character/word counters
  • Live search/filter
  • Synced inputs (e.g., mirrored text fields)