shadcn.io is an independent project built on shadcn/ui
package.json and index.tsx sit under Recent with a clock icon. README.md, tsconfig.json, and App.tsx follow under All Files. A rule separates the two.
Use it for file pickers and switchers, where people return to the same few files. A starred list, rather than a recent one, is the same pattern on a Combobox. In Vue, Ark UI does not track what was opened.
Installation
Anatomy

Usage
<Combobox
:collection="collection"
@input-value-change="handleInputValueChange"
@value-change="handleValueChange"
:positioning="{ getAnchorElement: () => triggerRef }"
selectionBehavior="clear"
:value="value"
>
<ComboboxTrigger
:class='cn(
buttonVariants({ variant: "outline" }),
"w-[250px] justify-between"
)'
ref="triggerRef"
>
{{ selected ? selected.label : "Select file..." }}
</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput class="w-full" placeholder="Search files..." :showTrigger="false" />
<ComboboxEmpty>No file found.</ComboboxEmpty>
<ComboboxList>
<template v-for="([group, items], index) in groups" :key="group">
<ComboboxGroup :heading="group">
<ComboboxItem v-for="item in items" class="gap-2" :item="item" :key="item.value">
<ClockIcon v-if='item.group === "Recent"' aria-hidden="true" class="size-3 opacity-50" />{{ item.label }}
</ComboboxItem>
</ComboboxGroup>
<ComboboxSeparator v-if="index < groups.length - 1" />FAQ
How are the two sections built?
Two ComboboxGroups, Recent and All Files, with a ComboboxSeparator between them.
groupBy in useListCollection splits the files, and heading names each group.
How is the clock drawn?
A ClockIcon at size-3 opacity-50, only in the Recent rows and hidden from screen readers.
Why aren't recent files listed twice?
All Files leaves out the recent ones, so each file has one row and one value.
Does Recent update when I pick a file?
Not in this demo: the list is fixed. Store the last few picks, newest first, and build the Recent group from them to make it live.
API Reference
Combobox
Sets collection="collection", input-value-change="handleInputValueChange", value-change="handleValueChange", positioning, getAnchorElement and class. The rest is on the Combobox page.





