Skip to content

Select

A select component with support for generated options, custom option markup, icons, validation states, and alternate label styles.

Basic Usage

blade
<x-basekit-ui::select
    name="country"
    label="Country"
    placeholder="Select a country"
    :options="[
        'us' => 'United States',
        'ca' => 'Canada',
        'uk' => 'United Kingdom',
    ]"
/>

Props

PropTypeDefaultDescription
optionsarray[]Value-label option pairs
valuemixednullSelected value
variantstring'secondary'Visual style: primary, secondary, success, warning, info, ghost
sizestring'md'Control size: sm, md, lg
labelstringnullLabel text
errorstringnullError message shown below the field
hintstringnullHelper text shown below the field
reserves-messagesbooltrueKeep the reserved message slot below the field
iconstringnullHeroicon name rendered inside the field
placeholderstringnullPlaceholder option text
corner-hintstringnullTop-right label row hint
is-disabledboolfalseDisable the select
allow-emptyboolfalseInclude an explicit empty option (value="") that users can select
empty-labelstringnullLabel text for the empty option when allow-empty is enabled
label-stylestring'default'Label placement: default, inset, overlap
control-stylestring'default'Control style: default, pill, underline
borderstringnullCustom border color.
hover-borderstringnullCustom hover border color.
colorstringnullQuick color shortcut — sets the border, hover border and focus ring colors only (never the background or text). Accepts Tailwind v4 color names or raw CSS colors.
backgroundstringnullCustom background color.
textstringnullCustom text color.
hover-backgroundstringnullCustom hover background color.
hover-textstringnullCustom hover text color.
wrapper-classstringnullAdditional classes for the outer wrapper div
container-classstringnullAdditional classes for the inner container div

Standard select attributes such as name, multiple, and disabled can also be passed through.

Slots

SlotDescription
defaultCustom <option> and <optgroup> markup
labelCustom label markup
errorCustom error markup
hintCustom helper text
iconCustom icon markup

Variants

Supported variants: primary, secondary, success, warning, info, ghost.

blade
@php
$options =[
    'active' => 'Active',
    'inactive' => 'Inactive',
];
@endphp

<x-basekit-ui::select name="variant-primary" variant="primary" :options="$options" />
<x-basekit-ui::select name="variant-secondary" variant="secondary" :options="$options" />
<x-basekit-ui::select name="variant-success" variant="success" :options="$options" />
<x-basekit-ui::select name="variant-warning" variant="warning" :options="$options" />
<x-basekit-ui::select name="variant-info" variant="info" :options="$options" />
<x-basekit-ui::select name="variant-ghost" variant="ghost" :options="$options" />

Sizes

Supported sizes: sm,md,lg.

blade
@php
$options =[
    'small' => 'Small',
    'medium' => 'Medium',
    'large' => 'Large',
];
@endphp

<x-basekit-ui::select name="size-sm" size="sm" :options="$options" value="small" />
<x-basekit-ui::select name="size-md" size="md" :options="$options" value="medium" />
<x-basekit-ui::select name="size-lg" size="lg" :options="$options" value="large" />

With Icon

With Heroicon

Pass any Heroicon name via the icon prop:

blade
<x-basekit-ui::select
    name="country"
    label="Country"
    icon="globe-alt"
    :options="[
        'hu' => 'Hungary',
        'de' => 'Germany',
        'fr' => 'France',
    ]"
/>

Using Icon Slot

blade

<x-basekit-ui::select name="custom-icon" label="Custom Icon" :options="[
    'ny' => 'New York',
    'ldn' => 'London',
    'bud' => 'Budapest',
]">
    <x-slot:icon>
        <x-heroicon-o-map-pin class="w-4 h-4" />
    </x-slot:icon>
</x-basekit-ui::select>

Generated Options

blade
<x-basekit-ui::select
    name="role"
    label="Role"
    :value="old('role')"
    :options="[
        'admin' => 'Admin',
        'editor' => 'Editor',
        'viewer' => 'Viewer',
    ]"
/>

Custom Option Markup

blade
<x-basekit-ui::select name="category" label="Category">
    <option value="">Select category</option>
    <optgroup label="Fruits">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
    </optgroup>
    <optgroup label="Vegetables">
        <option value="carrot">Carrot</option>
        <option value="broccoli">Broccoli</option>
    </optgroup>
</x-basekit-ui::select>

Label Styles

blade
@php
$options =[
    'active' => 'Active',
    'inactive' => 'Inactive',
];
@endphp

<x-basekit-ui::select name="department" label="Department" label-style="inset" :options="$options" />
<x-basekit-ui::select name="role" label="Role" label-style="overlap" :options="$options" />
<x-basekit-ui::select name="status" control-style="pill" :options="$options" />
<x-basekit-ui::select name="plan" label="Plan" control-style="underline" :options="$options" />

Allow Empty Option

Use allow-empty to add an explicit empty option (value="") at the top of the list. This lets users deselect a previously chosen value.

blade
@php
$options = [
    'admin'  => 'Admin',
    'editor' => 'Editor',
    'viewer' => 'Viewer',
];
@endphp

<x-basekit-ui::select
    name="role"
    label="Role"
    allow-empty
    :options="$options"
/>

With Custom Empty Label

By default the empty option shows (em dash). Use empty-label to replace that text:

blade
<x-basekit-ui::select
    name="priority"
    label="Priority"
    allow-empty
    empty-label="No priority"
    :options="[
        'low'    => 'Low',
        'medium' => 'Medium',
        'high'   => 'High',
    ]"
/>

Using Placeholder as Empty Label

When allow-empty is set and no empty-label is given, the placeholder text is used as the empty option label:

blade
<x-basekit-ui::select
    name="status"
    label="Status"
    placeholder="Any status"
    allow-empty
    :options="[
        'active'   => 'Active',
        'inactive' => 'Inactive',
    ]"
/>

Validation State

blade
<x-basekit-ui::select
    name="type"
    label="Type"
    error="Please select a type"
    :options="['a' => 'Type A', 'b' => 'Type B']"
/>

Custom Classes

Override or extend styles with the class attribute:

blade
<x-basekit-ui::select
    name="custom-type"
    label="Type"
    :options="[
        'feature' => 'Feature',
        'bugfix' => 'Bugfix',
        'chore' => 'Chore',
    ]"
    class="mt-2"
/>

Custom Colors

Override the component's default border and focus ring colors using the color shortcut prop or granular border and hover-border props.

The color prop accepts Tailwind v4 color names (e.g., indigo-500, pink-200, emerald-700) or any raw CSS color value (hex, rgb, hsl, named colors). When using color, the focus-within ring automatically matches the chosen color.

With Tailwind Colors

blade
<x-basekit-ui::select
    name="country"
    label="Country"
    color="indigo-500"
    :options="['us' => 'US', 'ca' => 'Canada']"
/>

With Raw CSS Colors

blade
<x-basekit-ui::select
    name="country"
    label="Country"
    border="#C7D2FE"
    :options="['us' => 'US', 'ca' => 'Canada']"
/>

Granular Control

blade
<x-basekit-ui::select
    name="country"
    label="Country"
    border="indigo-500"
    hover-border="indigo-600"
    :options="['us' => 'US', 'ca' => 'Canada']"
/>

CSS Variables

Customize select appearance via CSS variables:

css
:root {
  /* Base */
  --select-color: var(--color-slate-900);
  --select-placeholder-color: var(--color-slate-400);
  --select-border-color: var(--color-slate-300);
  --select-border-radius: var(--radius-md, 0.375rem);
  --select-bg: var(--surface-base);
  --select-font-family: inherit;
  --select-line-height: 1.5;
  --select-transition:
    border-color var(--transition-fast) ease-in-out,
    box-shadow var(--transition-fast) ease-in-out;

  /* Interaction States */
  --select-hover-border-color: var(--color-slate-400);
  --select-focus-border-color: var(--color-primary-500);
  --select-focus-ring-color: var(--color-primary-100);
  --select-focus-ring-width: 2px;

  /* Disabled State */
  --select-disabled-bg: var(--color-slate-50);
  --select-disabled-color: var(--color-slate-500);
  --select-disabled-border-color: var(--color-slate-200);

  /* Variants */
  --select-primary-border-color: var(--color-primary-500);
  --select-primary-ring-color: var(--color-primary-100);
  --select-secondary-border-color: var(--color-slate-300);
  --select-secondary-ring-color: var(--color-slate-100);
  --select-error-border-color: var(--color-danger-500);
  --select-error-ring-color: var(--color-danger-100);
  --select-error-color: var(--color-danger-700);
  --select-success-border-color: var(--color-success-500);
  --select-success-ring-color: var(--color-success-100);
  --select-warning-border-color: var(--color-warning-500);
  --select-warning-ring-color: var(--color-warning-100);
  --select-danger-border-color: var(--color-danger-500);
  --select-danger-ring-color: var(--color-danger-100);
  --select-info-border-color: var(--color-info-500);
  --select-info-ring-color: var(--color-info-100);
  --select-ghost-border-color: transparent;
  --select-ghost-ring-color: var(--color-slate-100);
  --select-ghost-bg: transparent;

  /* Sizes */
  --select-py-sm: 0.375rem;
  --select-px-sm: 0.75rem;
  --select-fs-sm: 0.875rem;
  --select-py-md: 0.5rem;
  --select-px-md: 0.875rem;
  --select-fs-md: 0.9375rem;
  --select-py-lg: 0.75rem;
  --select-px-lg: 1rem;
  --select-fs-lg: 1rem;

  /* Dropdown Menu */
  --select-menu-bg: var(--surface-base);
}

Dark Mode

Dark mode overrides are applied automatically when a parent element has the .dark class:

css
.dark {
  --select-color: var(--color-slate-100);
  --select-placeholder-color: var(--color-slate-500);
  --select-border-color: var(--color-slate-600);
  --select-bg: var(--color-slate-800);
  --select-hover-border-color: var(--color-slate-500);
  --select-focus-border-color: var(--color-primary-400);
  --select-focus-ring-color: rgba(99, 102, 241, 0.25);

  --select-disabled-bg: var(--color-slate-900);
  --select-disabled-color: var(--color-slate-600);
  --select-disabled-border-color: var(--color-slate-800);

  /* Labels & helpers */
  --select-label-color: var(--color-slate-300);
  --select-hint-color: var(--color-slate-400);
  --select-icon-color: var(--color-slate-500);

  /* Options */
  --select-option-text: var(--color-slate-200);
  --select-option-selected-bg: var(--color-slate-700);
  --select-option-selected-text: var(--color-slate-100);

  --select-primary-border-color: var(--color-primary-500);
  --select-primary-ring-color: rgba(99, 102, 241, 0.25);

  --select-secondary-border-color: var(--color-slate-600);
  --select-secondary-ring-color: rgba(148, 163, 184, 0.2);

  --select-error-border-color: var(--color-danger-500);
  --select-error-ring-color: rgba(239, 68, 68, 0.2);
  --select-error-color: var(--color-danger-400);

  --select-success-border-color: var(--color-success-500);
  --select-success-ring-color: rgba(34, 197, 94, 0.2);

  --select-warning-border-color: var(--color-warning-500);
  --select-warning-ring-color: rgba(245, 158, 11, 0.2);

  --select-danger-border-color: var(--color-danger-500);
  --select-danger-ring-color: rgba(239, 68, 68, 0.2);

  --select-info-border-color: var(--color-info-500);
  --select-info-ring-color: rgba(59, 130, 246, 0.2);

  --select-ghost-ring-color: rgba(148, 163, 184, 0.15);

  --select-menu-bg: var(--color-slate-800);
  --select-menu-border: var(--color-slate-700);
  --select-menu-shadow: 0 10px 20px rgb(0 0 0 / 0.3);
  --select-option-hover: var(--color-slate-700);
}

For dark mode token details, see Theming — Dark Mode.

Configuration

Configure defaults in config/basekit-laravel-ui.php:

php
'select' => [
    'enabled' => true,
    'variants' => ['primary', 'secondary', 'success', 'warning', 'info', 'ghost'],
    'sizes' => ['sm', 'md', 'lg'],
    'default_variant' => 'secondary',
    'default_size' => 'md',
],

Released under the MIT License.