Command palette (Ctrl+K)
Recherche globale + nav rapide via cmdk — Ctrl+K / Cmd+K, items filtrés par rôle, items dynamiques pour le thème et la déconnexion.
Une command palette globale, montée dans le <RootLayout>, accessible
partout via Ctrl+K (ou Cmd+K sur Mac). Pattern Linear / Vercel —
search instantanée + actions clavier-friendly.
Lib utilisée
cmdk — composant léger, search fuzzy intégré, gère les keys (arrows,
enter, esc) automatiquement.
Architecture
components/ui/command.tsx— wrapper bas niveau autour decmdk, styles shadcn/ui (Input, List, Group, Item)components/shared/command-palette.tsx— la palette elle-même, avec les items + handlers- Mountée dans
app/layout.tsx(<CommandPalette />)
Items
Définis statiquement dans le tableau items du component. Chaque item :
{
id: "users",
group: "Admin",
label: "Utilisateurs",
icon: Users, // lucide-react
href: "/admin/users",
adminOnly: true, // filtré si l'user n'est pas ADMIN
shortcut: "⌘U", // optionnel — affiché à droite
action: () => ..., // alternative à href (theme switch, logout, etc.)
}Groupes par défaut : Navigation, Compte (authed), Admin (role=ADMIN), Apparence, Aide.
Étendre
Pour ajouter un item, édite items dans command-palette.tsx. Pas de
registry runtime — tout est statique pour la simplicité et le search
instantané. Si tu veux du dynamique (ex. lister tous les users en DB),
fais un fetch séparé et inject les résultats sous un nouveau <CommandGroup>.
Filtres
value={...}sur<CommandItem>est ce que cmdk match — tu peux y injecter des keywords ("Utilisateurs admins membres équipe") pour trouver l'item via plusieurs termes.- Items
adminOnlycachés sisession.user.role !== "ADMIN". - Items
Comptecachés si pas authentifié.
Actions vs liens
href→router.push()action→ callback (theme, signOut, dialog…)
Les deux ferment la palette automatiquement avec un délai de 50ms (laisse le dialog se fermer avant la nav, sinon le focus revient mal).
i18n
Les libellés sont en dur français pour l'instant. Pour i18n :
- Move les labels vers
messages/<locale>.jsonsouscommandPalette const t = useTranslations("commandPalette")dans le composant- Map
items→{ label: t(it.id) }
Voir i18n.