Files
upstream-mirror 1416db152c
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped
snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
2026-09-15 22:44:43 +05:00

250 lines
5.6 KiB
TypeScript

"use client"
import * as React from "react"
import { cn } from "cn"
import {
Autocomplete,
Collection,
composeRenderProps,
Header,
Input,
Menu,
MenuItem,
MenuSection,
SearchField,
Separator,
useFilter,
type AutocompleteProps,
type InputProps,
type MenuItemProps,
type MenuProps,
type MenuSectionProps,
type SeparatorProps,
} from "react-aria-components"
import {
Dialog,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/registry/bases/aria/ui/dialog"
import {
InputGroup,
InputGroupAddon,
} from "@/registry/bases/aria/ui/input-group"
import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
function Command({
className,
dir,
style,
...props
}: Omit<AutocompleteProps, "className" | "style"> & {
className?: string
dir?: React.HTMLAttributes<HTMLDivElement>["dir"]
style?: React.CSSProperties
}) {
const { contains } = useFilter({ sensitivity: "base" })
return (
<div
data-slot="command"
dir={dir}
className={cn(
"cn-command flex size-full flex-col overflow-hidden",
className
)}
style={style}
>
<Autocomplete {...props} filter={props.filter || contains}>
{props.children}
</Autocomplete>
</div>
)
}
function CommandDialog({
title = "Command Palette",
description = "Search for a command to run...",
children,
open,
onOpenChange,
className,
showCloseButton = false,
...props
}: Omit<
React.ComponentProps<typeof Dialog>,
"children" | "className" | "isOpen" | "onOpenChange"
> & {
title?: string
description?: string
open?: boolean
onOpenChange?: (isOpen: boolean) => void
className?: string
showCloseButton?: boolean
children: React.ReactNode
}) {
return (
<Dialog
isOpen={open}
onOpenChange={onOpenChange}
className={cn(
"cn-command-dialog top-1/3 translate-y-0 overflow-hidden p-0",
className
)}
showCloseButton={showCloseButton}
isDismissable
{...props}
>
<DialogHeader className="sr-only">
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
{children}
</Dialog>
)
}
function CommandInput({ className, ...props }: InputProps) {
return (
<SearchField
autoFocus
aria-label={props.placeholder || "Search"}
data-slot="command-input-wrapper"
className="cn-command-input-wrapper"
>
<InputGroup className="cn-command-input-group">
<Input
{...props}
data-slot="command-input"
className={cn(
"cn-command-input outline-hidden disabled:cursor-not-allowed disabled:opacity-50 [&::-webkit-search-cancel-button]:hidden",
className
)}
/>
<InputGroupAddon>
<IconPlaceholder
lucide="SearchIcon"
tabler="IconSearch"
hugeicons="SearchIcon"
phosphor="MagnifyingGlassIcon"
remixicon="RiSearchLine"
className="cn-command-input-icon"
/>
</InputGroupAddon>
</InputGroup>
</SearchField>
)
}
function CommandList<T extends object>({ className, ...props }: MenuProps<T>) {
return (
<Menu
{...props}
data-slot="command-list"
className={cn(
"cn-command-list overflow-x-hidden overflow-y-auto",
className
)}
/>
)
}
function CommandEmpty({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="command-empty"
className={cn("cn-command-empty", className)}
{...props}
/>
)
}
function CommandGroup<T extends object>({
className,
children,
items,
heading,
...props
}: MenuSectionProps<T> & { heading?: string }) {
return (
<MenuSection
data-slot="command-group"
className={cn("cn-command-group", className)}
{...props}
>
{heading && <Header cmdk-group-heading="">{heading}</Header>}
<Collection items={items}>{children}</Collection>
</MenuSection>
)
}
function CommandSeparator({ className, ...props }: SeparatorProps) {
return (
<Separator
data-slot="command-separator"
className={cn("cn-command-separator", className)}
{...props}
/>
)
}
function CommandItem<T extends object>({
className,
children,
textValue,
...props
}: MenuItemProps<T>) {
return (
<MenuItem
{...props}
data-slot="command-item"
className={cn(
"cn-command-item cn-command-item-aria group/command-item data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
className
)}
textValue={
textValue || (typeof children === "string" ? children : undefined)
}
>
{composeRenderProps(children, (children) => (
<>
{children}
<IconPlaceholder
lucide="CheckIcon"
tabler="IconCheck"
hugeicons="Tick02Icon"
phosphor="CheckIcon"
remixicon="RiCheckLine"
className="cn-command-item-indicator ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100"
/>
</>
))}
</MenuItem>
)
}
function CommandShortcut({
className,
...props
}: React.ComponentProps<"span">) {
return (
<span
data-slot="command-shortcut"
className={cn("cn-command-shortcut cn-command-shortcut-aria", className)}
{...props}
/>
)
}
export {
Command,
CommandDialog,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
CommandSeparator,
}