{{-- ShiftBridge Select Component Usage: Props: - name: string (required) - options: array (required) - format: [['value' => 'us', 'label' => 'United States', 'disabled' => false, 'icon' => 'flag']] - label: string - placeholder: string - value: string|array (for multiple) - helper: string - error: string - state: string (default, error, success) - size: string (sm, md, lg) - disabled: boolean - required: boolean - multiple: boolean - searchable: boolean - clearable: boolean - icon: string (Lucide icon name) - iconPosition: string (left, right) - id: string (defaults to name) --}} @props([ 'name' => null, 'options' => [], 'label' => null, 'placeholder' => 'Select an option', 'value' => null, 'helper' => null, 'error' => null, 'state' => 'default', 'size' => 'md', 'disabled' => false, 'required' => false, 'multiple' => false, 'searchable' => false, 'clearable' => false, 'icon' => null, 'iconPosition' => 'left', 'id' => null, ]) @php // Auto-detect error state from $error prop or $errors bag $hasError = $error || ($name && $errors && $errors->has($name)); if ($hasError) { $state = 'error'; } // ID defaults to name $inputId = $id ?? $name; // Handle value as array for multiple select $selectedValues = $multiple && !is_array($value) ? ($value ? [$value] : []) : ($value ?? []); if (!is_array($selectedValues)) { $selectedValues = [$selectedValues]; } // Normalize options to consistent format $normalizedOptions = []; foreach ($options as $key => $option) { if (is_array($option)) { $normalizedOptions[] = [ 'value' => $option['value'] ?? $option['id'] ?? $key, 'label' => $option['label'] ?? $option['name'] ?? $option['text'] ?? '', 'disabled' => $option['disabled'] ?? false, 'icon' => $option['icon'] ?? null, ]; } else { $normalizedOptions[] = [ 'value' => $key, 'label' => $option, 'disabled' => false, 'icon' => null, ]; } } // Size classes $sizeClasses = match($size) { 'sm' => 'px-2.5 py-1.5 text-sm', 'md' => 'px-3 py-2 text-sm', 'lg' => 'px-4 py-3 text-base', default => 'px-3 py-2 text-sm', }; // State classes $stateClasses = match($state) { 'error' => 'border-red-500 focus:border-red-500 focus:ring-red-500/20 bg-white text-red-900', 'success' => 'border-green-500 focus:border-green-500 focus:ring-green-500/20 bg-white text-green-900', default => 'border-[var(--sb-border)] focus:border-[var(--sb-primary)] focus:ring-[var(--sb-primary)]/20 bg-white text-[var(--sb-text-primary)]', }; // Icon sizing $iconSize = match($size) { 'sm' => 'w-4 h-4', 'md' => 'w-5 h-5', 'lg' => 'w-5 h-5', default => 'w-5 h-5', }; // Icon padding adjustment $iconPadding = match($size) { 'sm' => $iconPosition === 'left' ? 'pl-8' : 'pr-8', 'md' => $iconPosition === 'left' ? 'pl-10' : 'pr-10', 'lg' => $iconPosition === 'left' ? 'pl-11' : 'pr-11', default => $iconPosition === 'left' ? 'pl-10' : 'pr-10', }; // Icon positioning classes $iconPositionClasses = match($size) { 'sm' => $iconPosition === 'left' ? 'left-2.5' : 'right-2.5', 'md' => $iconPosition === 'left' ? 'left-3' : 'right-3', 'lg' => $iconPosition === 'left' ? 'left-3.5' : 'right-3.5', default => $iconPosition === 'left' ? 'left-3' : 'right-3', }; // Base select classes $selectClasses = implode(' ', [ 'block w-full rounded-md transition-all duration-150', 'border focus:outline-none focus:ring-2 appearance-none', 'disabled:opacity-60 disabled:cursor-not-allowed disabled:bg-slate-100', $sizeClasses, $stateClasses, $icon ? $iconPadding : '', ]); // Label classes $labelClasses = 'block text-sm font-medium text-[var(--sb-text-secondary)] mb-1.5'; // Helper text classes $helperClasses = 'mt-1.5 text-xs text-[var(--sb-text-secondary)]'; // Error text classes $errorClasses = 'mt-1.5 text-xs text-red-600 flex items-center gap-1'; // Chevron icon for dropdown indicator $chevronIcon = ''; // Icon SVG mapping $iconSvg = match($icon) { 'search' => '', 'map-pin' => '', 'flag' => '', 'user' => '', 'building' => '', 'briefcase' => '', 'layers' => '', 'tag' => '', 'filter' => '', 'list' => '', 'check' => '', default => null, }; @endphp
merge(['class' => 'w-full']) }}> {{-- Label --}} @if($label) @endif {{-- Select wrapper --}}
{{-- Left Icon --}} @if($icon && $iconPosition === 'left')
{!! $iconSvg !!}
@endif {{-- Select element --}} {{-- Right Icon --}} @if($icon && $iconPosition === 'right')
{!! $iconSvg !!}
@endif {{-- Dropdown chevron (always visible on right) --}}
{!! $chevronIcon !!}
{{-- Helper text --}} @if($helper && !$hasError)

{{ $helper }}

@endif {{-- Error message --}} @if($hasError)

{{ $error ?? ($errors && $name ? $errors->first($name) : '') }}

@endif {{-- Clearable button (JavaScript enhancement placeholder) --}} @if($clearable && !$disabled) @endif