Command Menu
Command Menu empowers users to swiftly execute searches on any page, thereby streamlining their workflow.
Installation
Install the following dependencies:
npm install cmdk @radix-ui/react-dialogThis component is used with the Modal component.
Refer to the Modal documentation for setup instructions before using this component.
Create a command-menu.tsx file and paste the following code into it.
// CoreUI CommandMenu v0.0.0'use client';import * as React from 'react';import { type DialogProps } from '@radix-ui/react-dialog';import { Command } from 'cmdk';import * as Modal from '@/components/ui/modal';import { cn } from '@/utils/cn';import { PolymorphicComponentProps } from '@/utils/polymorphic';import { tv, type VariantProps } from '@/utils/tv';const CommandDialogTitle = Modal.Title;const CommandDialogDescription = Modal.Description;const CommandDialog = ({ children, className, overlayClassName, ...rest}: DialogProps & { className?: string; overlayClassName?: string;}) => { return ( <Modal.Root {...rest}> <Modal.Content overlayClassName={cn('justify-start pt-20', overlayClassName)} showClose={false} className={cn( 'flex max-h-full max-w-180 flex-col overflow-hidden rounded-2xl', className, )} > <Command className={cn( 'divide-y divide-stroke-soft-200', 'grid min-h-0 auto-cols-auto grid-flow-row', '[&>[cmdk-label]+*]:!border-t-0', )} > {children} </Command> </Modal.Content> </Modal.Root> );};const CommandInput = React.forwardRef< React.ComponentRef<typeof Command.Input>, React.ComponentPropsWithoutRef<typeof Command.Input>>(({ className, ...rest }, forwardedRef) => { return ( <Command.Input ref={forwardedRef} className={cn( // base 'w-full bg-transparent text-paragraph-sm text-text-strong-950 outline-none', 'transition duration-200 ease-out', // placeholder 'placeholder:[transition:inherit]', 'placeholder:text-text-soft-400', // hover 'group-hover/cmd-input:placeholder:text-text-sub-600', // focus 'focus:outline-none', className, )} {...rest} /> );});CommandInput.displayName = 'CommandInput';const CommandList = React.forwardRef< React.ComponentRef<typeof Command.List>, React.ComponentPropsWithoutRef<typeof Command.List>>(({ className, ...rest }, forwardedRef) => { return ( <Command.List ref={forwardedRef} className={cn( 'flex max-h-min min-h-0 flex-1 flex-col', '[&>[cmdk-list-sizer]]:divide-y [&>[cmdk-list-sizer]]:divide-stroke-soft-200', '[&>[cmdk-list-sizer]]:overflow-auto', className, )} {...rest} /> );});CommandList.displayName = 'CommandList';const CommandGroup = React.forwardRef< React.ComponentRef<typeof Command.Group>, React.ComponentPropsWithoutRef<typeof Command.Group>>(({ className, ...rest }, forwardedRef) => { return ( <Command.Group ref={forwardedRef} className={cn( 'relative px-2 py-3', // heading '[&>[cmdk-group-heading]]:text-label-xs [&>[cmdk-group-heading]]:text-text-sub-600', '[&>[cmdk-group-heading]]:mb-2 [&>[cmdk-group-heading]]:px-3 [&>[cmdk-group-heading]]:pt-1', className, )} {...rest} /> );});CommandGroup.displayName = 'CommandGroup';const commandItemVariants = tv({ base: [ 'flex items-center gap-3 rounded-10 bg-bg-white-0', 'cursor-pointer text-paragraph-sm text-text-strong-950', 'transition duration-200 ease-out', // hover/selected 'data-[selected=true]:bg-bg-weak-50', ], variants: { size: { small: 'px-3 py-2.5', medium: 'px-3 py-3', }, }, defaultVariants: { size: 'small', },});type CommandItemProps = VariantProps<typeof commandItemVariants> & React.ComponentPropsWithoutRef<typeof Command.Item>;const CommandItem = React.forwardRef< React.ComponentRef<typeof Command.Item>, CommandItemProps>(({ className, size, ...rest }, forwardedRef) => { return ( <Command.Item ref={forwardedRef} className={commandItemVariants({ size, class: className })} {...rest} /> );});CommandItem.displayName = 'CommandItem';function CommandItemIcon<T extends React.ElementType>({ className, as, ...rest}: PolymorphicComponentProps<T>) { const Component = as || 'div'; return ( <Component className={cn('size-5 shrink-0 text-text-sub-600', className)} {...rest} /> );}function CommandFooter({ className, ...rest}: React.HTMLAttributes<HTMLDivElement>) { return ( <div className={cn( 'flex h-12 items-center justify-between gap-3 px-5', className, )} {...rest} /> );}function CommandFooterKeyBox({ className, ...rest}: React.HTMLAttributes<HTMLDivElement>) { return ( <div className={cn( 'flex size-5 shrink-0 items-center justify-center rounded bg-bg-weak-50 text-text-sub-600 ring-1 ring-inset ring-stroke-soft-200', className, )} {...rest} /> );}export { CommandDialog as Dialog, CommandDialogTitle as DialogTitle, CommandDialogDescription as DialogDescription, CommandInput as Input, CommandList as List, CommandGroup as Group, CommandItem as Item, CommandItemIcon as ItemIcon, CommandFooter as Footer, CommandFooterKeyBox as FooterKeyBox,};API Reference
This component is based on the cmdk package. Refer to their documentation for the API reference.
CommandMenu.Dialog
The CommandMenu.Dialog component is based on cmdk Command primitive. Wrapped by Modal Content.
CommandMenu.Input
The CommandMenu.Input component is based on cmdk Input primitive.
CommandMenu.Group
The CommandMenu.Group component is based on cmdk Group primitive.
CommandMenu.List
The CommandMenu.List component is based on cmdk List primitive.
CommandMenu.Item
The CommandMenu.Item component is based on cmdk Item primitive. And adds:
| Prop | Type | Default |
|---|---|---|
size | "small" | "medium" | "small" |
CommandMenu.ItemIcon
The CommandMenu.ItemIcon component is polymorphic, allowing you to change the underlying HTML element using the as prop.
| Prop | Type | Default |
|---|---|---|
as | React.ElementType | div |
CommandMenu.Footer
A footer section for the command dialog. This component is based on the <div> element and supports all of its props.
CommandMenu.FooterKeyBox
Used within the CommandMenu.Footer to display key information or buttons. This component is based on the <div> element and supports all of its props.