shadcn, restyled · @jengacore/command
Command
cmdk primitives restyled: mono group headings, mint active row, scope chip and CommandFooter.
Install
terminal
npx shadcn@latest add @jengacore/commandWithout the namespace configured: npx shadcn@latest add https://ui.jengacore.com/r/<new-york-v4|base-nova>/command.json
Registry dependencies
npm packages
cmdklucide-react
Source
components/ui/command.tsx
"use client"
import * as React from "react"
import { Command as CommandPrimitive } from "cmdk"
import { SearchIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog"
/**
* Command palette primitives (cmdk): mono group headings, mint active row, kbd hints on the right.
* For the full product palette (Records → Actions → Go to → Appearance) use jc/command-palette.
*/
function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
return (
<CommandPrimitive
data-slot="command"
className={cn("flex size-full flex-col overflow-hidden rounded-lg bg-popover text-popover-foreground", className)}
{...props}
/>
)
}
function CommandDialog({
title = "Command palette",
description = "Search pages, records and actions",
children,
className,
showCloseButton = false,
shouldFilter,
filter,
...props
}: Omit<React.ComponentProps<typeof Dialog>, "children"> &
Pick<React.ComponentProps<typeof CommandPrimitive>, "shouldFilter" | "filter"> & {
title?: string
description?: string
className?: string
showCloseButton?: boolean
children: React.ReactNode
}) {
return (
<Dialog {...props}>
<DialogContent
showCloseButton={showCloseButton}
className={cn(
"top-[14vh] w-[min(640px,calc(100vw-32px))] max-w-none translate-y-0 gap-0 overflow-hidden rounded-[10px] p-0 sm:max-w-none",
className
)}
>
<DialogTitle className="sr-only">{title}</DialogTitle>
<DialogDescription className="sr-only">{description}</DialogDescription>
<Command loop shouldFilter={shouldFilter} filter={filter}>
{children}
</Command>
</DialogContent>
</Dialog>
)
}
function CommandInput({
className,
scope,
...props
}: React.ComponentProps<typeof CommandPrimitive.Input> & {
/** Optional mono chip before the field, e.g. the product being searched. */
scope?: string
}) {
return (
<div data-slot="command-input-wrapper" className="flex h-14 items-center gap-3 border-b border-border px-4">
<SearchIcon className="size-[18px] shrink-0 stroke-[1.75] text-muted-foreground" aria-hidden />
{scope ? (
<span className="rounded-sm bg-secondary px-2 py-0.5 font-mono text-[11px] font-medium tracking-[0.1em] text-secondary-foreground uppercase">
{scope}
</span>
) : null}
<CommandPrimitive.Input
data-slot="command-input"
className={cn(
"h-full flex-1 bg-transparent text-[15px] text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
/>
<kbd className="rounded-[3px] border border-border bg-muted px-1.5 font-mono text-[10.5px] leading-4 text-muted-foreground">Esc</kbd>
</div>
)
}
function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
return (
<CommandPrimitive.List
data-slot="command-list"
className={cn("max-h-[420px] scroll-py-2 overflow-x-hidden overflow-y-auto p-2 outline-none", className)}
{...props}
/>
)
}
function CommandEmpty({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
return <CommandPrimitive.Empty data-slot="command-empty" className={cn("px-4 py-10 text-center text-sm text-muted-foreground", className)} {...props} />
}
function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {
return (
<CommandPrimitive.Group
data-slot="command-group"
className={cn(
"overflow-hidden pb-1 text-foreground",
"**:[[cmdk-group-heading]]:px-2.5 **:[[cmdk-group-heading]]:pt-2.5 **:[[cmdk-group-heading]]:pb-1.5",
"**:[[cmdk-group-heading]]:font-mono **:[[cmdk-group-heading]]:text-[10.5px] **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:tracking-[0.14em] **:[[cmdk-group-heading]]:text-muted-foreground **:[[cmdk-group-heading]]:uppercase",
className
)}
{...props}
/>
)
}
function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
return <CommandPrimitive.Separator data-slot="command-separator" className={cn("-mx-2 my-1 h-px bg-border", className)} {...props} />
}
function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
return (
<CommandPrimitive.Item
data-slot="command-item"
className={cn(
"group/command-item relative flex min-h-10 cursor-pointer items-center gap-3 rounded-md px-2.5 text-sm outline-none select-none",
"data-[selected=true]:bg-secondary data-[selected=true]:text-secondary-foreground",
"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:stroke-[1.75] [&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground data-[selected=true]:[&_svg]:text-secondary-foreground",
className
)}
{...props}
/>
)
}
function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) {
return <span data-slot="command-shortcut" className={cn("ml-auto flex gap-1 font-mono text-[11px] text-muted-foreground", className)} {...props} />
}
/** Footer that always shows the keys: ↑↓ move, ↵ open, ⌘K toggle. */
function CommandFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="command-footer"
className={cn("flex items-center gap-4 border-t border-border bg-muted px-4 py-2 font-mono text-[11px] text-muted-foreground", className)}
{...props}
/>
)
}
export {
Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, CommandFooter,
}