Skip to main content

Forms

Input code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/input.blade.php

@props([
    'type' => 'text',
    'size' => 'base',
    'icon' => null,
    'iconTrailing' => null,
    'invalid' => false,
    'disabled' => false,
])

@php
    /*
    | Text input with optional leading/trailing icons and error state.
    |
    | Usage:
    |   <x-ui.input type="email" placeholder="you@example.com" icon="envelope" />
    |   <x-ui.input :invalid="$errors->has('name')" />
    */
    $sizes = [
        'sm' => 'text-sm py-1.5',
        'base' => 'text-sm py-2.5',
        'lg' => 'text-base py-3',
    ];

    $pad = 'px-3.5';
    if ($icon) { $pad = 'ps-10 pe-3.5'; }
    if ($iconTrailing) { $pad = $icon ? 'px-10' : 'ps-3.5 pe-10'; }

    $ring = $invalid
        ? 'border-red-400 dark:border-red-500 focus:border-red-500 focus:ring-red-500'
        : 'border-gray-300 dark:border-gray-700 focus:border-brand-500 focus:ring-brand-500';

    $classes = implode(' ', [
        'block w-full rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 shadow-sm transition focus:ring-1 disabled:opacity-50 disabled:cursor-not-allowed',
        $sizes[$size] ?? $sizes['base'],
        $pad,
        $ring,
    ]);

    $providedId = $attributes->get('id');
    $providedAriaLabel = $attributes->get('aria-label');
    $providedAriaLabelledBy = $attributes->get('aria-labelledby');
    $providedName = $attributes->get('name');
    $normalizedName = $providedName
        ? trim((string) preg_replace('/[^A-Za-z0-9\-_:.]+/', '-', str_replace(['[', ']'], '', (string) $providedName)), '-')
        : null;
    $inputId = $providedId ?: $normalizedName;
    $fallbackLabel = null;

    if (! $providedAriaLabel && ! $providedAriaLabelledBy && ! $providedId) {
        $placeholder = $attributes->get('placeholder');
        $fallbackLabel = $placeholder
            ? rtrim((string) $placeholder, '. ')
            : ($providedName ? Str::headline(str_replace(['-', '_'], ' ', $normalizedName ?? (string) $providedName)) : null);
    }
@endphp

<div class="relative">
    @if ($icon)
        <span class="pointer-events-none absolute inset-y-0 start-0 flex items-center ps-3 text-gray-400 dark:text-gray-500">
            <x-ui.icon :name="$icon" size="base" />
        </span>
    @endif

    <input
        type="{{ $type }}"
        @disabled($disabled)
        @if ($inputId) id="{{ $inputId }}" @endif
        @if ($fallbackLabel) aria-label="{{ $fallbackLabel }}" @endif
        @if ($invalid) aria-invalid="true" @endif
        {{ $attributes->except(['id', 'aria-label'])->merge(['class' => $classes]) }}
    >

    @if ($iconTrailing)
        <span class="pointer-events-none absolute inset-y-0 end-0 flex items-center pe-3 text-gray-400 dark:text-gray-500">
            <x-ui.icon :name="$iconTrailing" size="base" />
        </span>
    @endif
</div>