Input

Text input allows users to enter and edit text. Supports labels, validation, helper text, and reactive state binding.

Basic Examples

Simple inputs with various configurations

await import('/components/data-input/input.js');
const { tags, $ } = Lightview;
const { div, Input } = tags;

// 1. Basic input
const basic = Input({ 
    placeholder: 'Basic input' 
});

// 2. Input with label and helper
const withLabel = Input({ 
    label: 'Email Address',
    type: 'email',
    placeholder: 'you@example.com',
    helper: 'We will never share your email.'
});

// 3. Input with color
const withColor = Input({ 
    label: 'Primary Color',
    placeholder: 'Styled input',
    color: 'primary'
});

// 4. Required input
const requiredInput = Input({ 
    label: 'Username',
    placeholder: 'Enter username',
    required: true
});

// Insert all examples
$('#example').content(
    div({ style: 'display: flex; flex-direction: column; gap: 1rem;' }, basic, withLabel, withColor, requiredInput)
);
await import('/components/data-input/input.js');
const { $, tags } = Lightview;
const { Input, div } = tags;

const basic = {
    tag: Input,
    attributes: { placeholder: 'Basic input' }
};

const withLabel = {
    tag: Input,
    attributes: {
        label: 'Email Address',
        type: 'email',
        placeholder: 'you@example.com',
        helper: 'We will never share your email.'
    }
};

const withColor = {
    tag: Input,
    attributes: {
        label: 'Primary Color',
        placeholder: 'Styled input',
        color: 'primary'
    }
};

const requiredInput = {
    tag: Input,
    attributes: {
        label: 'Username',
        placeholder: 'Enter username',
        required: true
    }
};

$('#example').content({
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem;' },
    children: [basic, withLabel, withColor, requiredInput]
});
await import('/components/data-input/input.js');
const { $ } = Lightview;

const demo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem;',
        children: [
            { Input: { placeholder: 'Basic input' } },
            { 
                Input: { 
                    label: 'Email Address',
                    type: 'email',
                    placeholder: 'you@example.com',
                    helper: 'We will never share your email.'
                } 
            },
            { 
                Input: { 
                    label: 'Primary Color',
                    placeholder: 'Styled input',
                    color: 'primary'
                } 
            },
            { 
                Input: { 
                    label: 'Username',
                    placeholder: 'Enter username',
                    required: true
                } 
            }
        ]
    }
};

$('#example').content(demo);
<!-- Import the component (registers lv-input) -->
<script type="module" src="/components/data-input/input.js"></script>

<div style="display: flex; flex-direction: column; gap: 1rem;">
    <lv-input placeholder="Basic input"></lv-input>
    <lv-input label="Email Address" type="email" placeholder="you@example.com" helper="We'll never share your email."></lv-input>
    <lv-input label="Primary Color" placeholder="Styled input" color="primary"></lv-input>
    <lv-input label="Username" placeholder="Enter username" required></lv-input>
</div>

Reactive Example

Two-way binding with signals and live validation

await import('/components/data-input/input.js');
const { signal, tags, $ } = Lightview;
const { div, p, span, Input } = tags;

// Signal for two-way binding
const username = signal('');

// Validation function
const validateUsername = (val) => {
    if (!val) return 'Username is required';
    if (val.length < 3) return 'Username must be at least 3 characters';
    if (!/^[a-zA-Z0-9_]+$/.test(val)) return 'Only letters, numbers, and underscores allowed';
    return null;
};

// Reactive input with validation
const reactiveDemo = div({ style: 'display: flex; flex-direction: column; gap: 1rem;' },
    Input({ 
        label: 'Username',
        placeholder: 'Enter your username...',
        value: username,
        validate: validateUsername,
        required: true
    }),
    p({ style: 'font-size: 0.875rem;' }, 
        span({ style: 'opacity: 0.7;' }, 'Current value: '),
        span({ style: 'font-family: monospace; color: oklch(var(--p));' }, () => username.value || '(empty)')
    ),
    p({ style: 'font-size: 0.875rem;' }, 
        () => {
            const error = validateUsername(username.value);
            return error 
                ? span({ style: 'color: oklch(var(--er));' }, '✗ ' + error)
                : span({ style: 'color: oklch(var(--su));' }, '✓ Username is valid!');
        }
    )
);

$('#example').content(reactiveDemo);
await import('/components/data-input/input.js');
const { signal, $, tags } = Lightview;
const { Input, div, p, span } = tags;

const username = signal('');

const validateUsername = (val) => {
    if (!val) return 'Username is required';
    if (val.length < 3) return 'Username must be at least 3 characters';
    if (!/^[a-zA-Z0-9_]+$/.test(val)) return 'Only letters, numbers, and underscores allowed';
    return null;
};

const reactiveDemo = {
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem;' },
    children: [
        {
            tag: Input,
            attributes: {
                label: 'Username',
                placeholder: 'Enter your username...',
                value: username,
                validate: validateUsername,
                required: true
            }
        },
        {
            tag: p,
            attributes: { style: 'font-size: 0.875rem;' },
            children: [
                { tag: span, attributes: { style: 'opacity: 0.7;' }, children: ['Current value: '] },
                { tag: span, attributes: { style: 'font-family: monospace; color: oklch(var(--p));' }, children: [() => username.value || '(empty)'] }
            ]
        },
        {
            tag: p,
            attributes: { style: 'font-size: 0.875rem;' },
            children: [
                () => {
                    const error = validateUsername(username.value);
                    return error 
                        ? { tag: span, attributes: { style: 'color: oklch(var(--er));' }, children: ['✗ ' + error] }
                        : { tag: span, attributes: { style: 'color: oklch(var(--su));' }, children: ['✓ Username is valid!'] };
                }
            ]
        }
    ]
};

$('#example').content(reactiveDemo);
await import('/components/data-input/input.js');
const { signal, tags, $ } = Lightview;
const { Input, div, p, span } = tags;

const username = signal('');

const validateUsername = (val) => {
    if (!val) return 'Username is required';
    if (val.length < 3) return 'Username must be at least 3 characters';
    if (!/^[a-zA-Z0-9_]+$/.test(val)) return 'Only letters, numbers, and underscores allowed';
    return null;
};

const reactiveDemo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem;',
        children: [
            {
                Input: {
                    label: 'Username',
                    placeholder: 'Enter your username...',
                    value: username,
                    validate: validateUsername,
                    required: true
                }
            },
            {
                p: {
                    style: 'font-size: 0.875rem;',
                    children: [
                        { span: { style: 'opacity: 0.7;', children: ['Current value: '] } },
                        { span: { style: 'font-family: monospace; color: oklch(var(--p));', children: [() => username.value || '(empty)'] } }
                    ]
                }
            },
            {
                p: {
                    style: 'font-size: 0.875rem;',
                    children: [
                        () => {
                            const error = validateUsername(username.value);
                            return error 
                                ? { span: { style: 'color: oklch(var(--er));', children: ['✗ ' + error] } }
                                : { span: { style: 'color: oklch(var(--su));', children: ['✓ Username is valid!'] } };
                        }
                    ]
                }
            }
        ]
    }
};

$('#example').content(reactiveDemo);

Props

Prop Type Default Description
type string 'text' Input type (text, password, email, number, etc.)
value string | signal - Input value (reactive with signals)
defaultValue string '' Default value for uncontrolled mode
placeholder string - Placeholder text
label string - Label text displayed above input
helper string - Helper text displayed below the input
error string | function - Error message or reactive error function
validate function - Validation function: (value) => errorMessage | null
color string - 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
size string 'md' 'xs' | 'sm' | 'md' | 'lg'
ghost boolean false Ghost style (no background)
disabled boolean false Disable the input
required boolean false Mark as required field (shows asterisk)
onChange function - Callback when value changes: (value, event) => void
onBlur function - Callback when input loses focus
useShadow boolean * Render in Shadow DOM. *Follows global initComponents() setting

Input Gallery

Live examples using <lv-input> custom elements.

Sizes

Colors

Labels & Assistance

States