# Command

Fast, composable, command menu for your app.

- Install: `php artisan blatui:add command`
- Source: https://blatui.remix-it.com/r/command.json
- Composer: `composer require mallardduck/blade-lucide-icons gehrisandro/tailwind-merge-laravel`

## resources/views/components/ui/command.blade.php

```blade
<div
    data-slot="command"
    x-data="blatCommand()"
    x-id="['blat-command-list']"
    x-init="$nextTick(() => ensureActive()); $watch('query', () => $nextTick(() => ensureActive()))"
    {{ $attributes->twMerge('bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md') }}
>
    {{ $slot }}
</div>
```

## resources/views/components/ui/command-empty.blade.php

```blade
<div
    data-slot="command-empty"
    x-show="visibleCount === 0"
    x-cloak
    {{ $attributes->twMerge('py-6 text-center text-sm') }}
>{{ $slot }}</div>
```

## resources/views/components/ui/command-group.blade.php

```blade
@props(['heading' => null])

@php $headingId = $heading ? 'cmd-grp-'.\Illuminate\Support\Str::random(8) : null; @endphp

<div
    data-slot="command-group"
    role="group"
    @if ($heading) aria-labelledby="{{ $headingId }}" @endif
    {{ $attributes->twMerge('text-foreground overflow-hidden p-1') }}
>
    @if ($heading)
        <div data-slot="command-group-heading" id="{{ $headingId }}" aria-hidden="true" class="text-muted-foreground px-2 py-1.5 text-xs font-medium">{{ $heading }}</div>
    @endif
    {{ $slot }}
</div>
```

## resources/views/components/ui/command-input.blade.php

```blade
@props(['placeholder' => 'Type a command or search...'])

<div data-slot="command-input-wrapper" class="flex h-9 items-center gap-2 border-b px-3">
    <x-lucide-search class="size-4 shrink-0 opacity-50" aria-hidden="true" />
    <input
        x-model="query"
        data-slot="command-input"
        type="text"
        role="combobox"
        aria-expanded="true"
        aria-autocomplete="list"
        autocomplete="off"
        aria-label="{{ $placeholder }}"
        :aria-controls="$id('blat-command-list')"
        :aria-activedescendant="activeId"
        @keydown.down.prevent="move(1)"
        @keydown.up.prevent="move(-1)"
        @keydown.home.prevent="edge('first')"
        @keydown.end.prevent="edge('last')"
        @keydown.enter.prevent="selectActive()"
        placeholder="{{ $placeholder }}"
        {{ $attributes->twMerge('placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50') }}
    >
</div>
```

## resources/views/components/ui/command-item.blade.php

```blade
@props([
    'value' => null,
    'href' => null,
    'disabled' => false,
])

@php
    $kw = $value ?? trim(strip_tags($slot));
    $classes = "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
@endphp

@if ($href)
    <a
        href="{{ $href }}"
        role="option"
        data-slot="command-item"
        x-init="registerItem($el, @js($kw), @js($disabled))"
        x-show="matches(@js($kw))"
        :aria-selected="activeId === $el.id"
        :data-selected="activeId === $el.id"
        @mouseenter="activeId = $el.id"
        @if ($disabled) aria-disabled="true" data-disabled="true" @endif
        {{ $attributes->twMerge($classes) }}
    >{{ $slot }}</a>
@else
    <div
        role="option"
        data-slot="command-item"
        x-init="registerItem($el, @js($kw), @js($disabled))"
        x-show="matches(@js($kw))"
        :aria-selected="activeId === $el.id"
        :data-selected="activeId === $el.id"
        @mouseenter="activeId = $el.id"
        @if ($disabled) aria-disabled="true" data-disabled="true" @endif
        {{ $attributes->twMerge($classes) }}
    >{{ $slot }}</div>
@endif
```

## resources/views/components/ui/command-list.blade.php

```blade
<div
    data-slot="command-list"
    role="listbox"
    tabindex="-1"
    :id="$id('blat-command-list')"
    {{ $attributes->twMerge('max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto') }}
>
    {{ $slot }}
</div>
```

## resources/views/components/ui/command-separator.blade.php

```blade
{{-- Decorative divider: a real role=separator is not an allowed child of role=listbox,
     and the groups already convey structure, so this is hidden from assistive tech. --}}
<div data-slot="command-separator" aria-hidden="true" {{ $attributes->twMerge('bg-border -mx-1 h-px') }}></div>
```

## resources/views/components/ui/command-shortcut.blade.php

```blade
<span data-slot="command-shortcut" {{ $attributes->twMerge('text-muted-foreground ml-auto text-xs tracking-widest') }}>{{ $slot }}</span>
```
