The Combobox component allows users to filter and select options from a list. It combines the flexibility of an input with the convenience of a dropdown, making it ideal for searchable selects.
<?php
use Lib\PHPXUI\{Popover, PopoverTrigger, PopoverContent};
use Lib\PHPXUI\{Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem};
use Lib\PHPXUI\Button;
use Lib\PPIcons\{ChevronsUpDown, Check};
?>
<div class="grid gap-2 place-items-center h-screen w-screen">
<div>
<h2 class="text-md font-semibold">Combobox</h2>
<Popover open="{openFrameworks}" onOpenChange="{setOpenFrameworks}" resetOnOpen="true">
<PopoverTrigger asChild="true">
<Button
variant="outline"
role="combobox"
aria-expanded="{openFrameworks}"
class="w-[200px] justify-between"
type="button"
>
<span hidden="{selectedFrameworkValue !== ''}">Select framework...</span>
<template pp-for="fw in frameworks">
<span hidden="{selectedFrameworkValue !== fw.value}" key="{fw.id}">{fw.label}</span>
</template>
<ChevronsUpDown class="opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search framework..." class="h-9" />
<CommandList>
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
<template pp-for="fw in frameworks">
<CommandItem
class="flex items-center justify-between gap-2"
value="{fw.value}"
key="{fw.id}"
onselect="setSelectedFrameworkValue(selectedFrameworkValue === fw.value ? '' : fw.value); setOpenFrameworks(false);"
>
<span>{fw.label}</span>
<span class="ml-auto" hidden="{selectedFrameworkValue !== fw.value}">
<Check />
</span>
</CommandItem>
</template>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
</div>
<script>
const [openFrameworks, setOpenFrameworks] = pp.state(false);
const [selectedFrameworkValue, setSelectedFrameworkValue] = pp.state('');
const [frameworks, setFrameworks] = pp.state([
{
id: 1,
value: 'next.js',
label: 'Next.js',
},
{
id: 2,
value: 'sveltekit',
label: 'SvelteKit',
},
{
id: 3,
value: 'nuxt.js',
label: 'Nuxt.js',
},
{
id: 4,
value: 'remix',
label: 'Remix',
},
{
id: 5,
value: 'astro',
label: 'Astro',
},
]);
</script>
Installation
The Combobox is built using a composition of the
<Popover />
and the
<Command />
components.
See installation instructions for the Popover and the Command components.
Usage
php
<?php
use Lib\PHPXUI\{Popover, PopoverTrigger, PopoverContent};
use Lib\PHPXUI\{Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem};
use Lib\PHPXUI\Button;
use Lib\PPIcons\{ChevronsUpDown, Check};
?>
<div class="grid gap-2 place-items-center h-screen w-screen">
<div>
<h2 class="text-md font-semibold">Combobox</h2>
<Popover open="{openFrameworks}" onOpenChange="{setOpenFrameworks}" resetOnOpen="true">
<PopoverTrigger asChild="true">
<Button
variant="outline"
role="combobox"
aria-expanded="{openFrameworks}"
class="w-[200px] justify-between"
type="button"
>
<span hidden="{selectedFrameworkValue !== ''}">Select framework...</span>
<template pp-for="fw in frameworks">
<span hidden="{selectedFrameworkValue !== fw.value}" key="{fw.id}">{fw.label}</span>
</template>
<ChevronsUpDown class="opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent class="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search framework..." class="h-9" />
<CommandList>
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
<template pp-for="fw in frameworks">
<CommandItem
class="flex items-center justify-between gap-2"
value="{fw.value}"
key="{fw.id}"
onselect="setSelectedFrameworkValue(selectedFrameworkValue === fw.value ? '' : fw.value); setOpenFrameworks(false);"
>
<span>{fw.label}</span>
<span class="ml-auto" hidden="{selectedFrameworkValue !== fw.value}">
<Check />
</span>
</CommandItem>
</template>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
</div>
<script>
const [openFrameworks, setOpenFrameworks] = pp.state(false);
const [selectedFrameworkValue, setSelectedFrameworkValue] = pp.state('');
const [frameworks, setFrameworks] = pp.state([
{
id: 1,
value: 'next.js',
label: 'Next.js',
},
{
id: 2,
value: 'sveltekit',
label: 'SvelteKit',
},
{
id: 3,
value: 'nuxt.js',
label: 'Nuxt.js',
},
{
id: 4,
value: 'remix',
label: 'Remix',
},
{
id: 5,
value: 'astro',
label: 'Astro',
},
]);
</script>