Files
cal.diy/packages/coss-ui/src/components/command.tsx
T
950f9555ee fix(ui): update coss ui components (#26989)
* fix(ui): update coss ui components

* fix(sidebar): remove redundant overflow-auto from SidebarContent

ScrollArea already provides the scroll container, so keeping overflow-auto
on the child creates a nested scroll area and prevents scrollFade from
reflecting actual overflow.

Addresses Cubic AI review feedback with confidence 9/10.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 09:45:20 +00:00

265 lines
7.0 KiB
TypeScript

"use client";
import { Dialog as CommandDialogPrimitive } from "@base-ui/react/dialog";
import { SearchIcon } from "lucide-react";
import type * as React from "react";
import { cn } from "@coss/ui/lib/utils";
import {
Autocomplete,
AutocompleteCollection,
AutocompleteEmpty,
AutocompleteGroup,
AutocompleteGroupLabel,
AutocompleteInput,
AutocompleteItem,
AutocompleteList,
AutocompleteSeparator,
} from "@coss/ui/components/autocomplete";
const CommandDialog = CommandDialogPrimitive.Root;
const CommandDialogPortal = CommandDialogPrimitive.Portal;
const CommandCreateHandle = CommandDialogPrimitive.createHandle;
function CommandDialogTrigger(props: CommandDialogPrimitive.Trigger.Props) {
return (
<CommandDialogPrimitive.Trigger
data-slot="command-dialog-trigger"
{...props}
/>
);
}
function CommandDialogBackdrop({
className,
...props
}: CommandDialogPrimitive.Backdrop.Props) {
return (
<CommandDialogPrimitive.Backdrop
className={cn(
"fixed inset-0 z-50 bg-black/32 backdrop-blur-sm transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0",
className,
)}
data-slot="command-dialog-backdrop"
{...props}
/>
);
}
function CommandDialogViewport({
className,
...props
}: CommandDialogPrimitive.Viewport.Props) {
return (
<CommandDialogPrimitive.Viewport
className={cn(
"fixed inset-0 z-50 flex flex-col items-center px-4 py-[max(--spacing(4),4vh)] sm:py-[10vh]",
className,
)}
data-slot="command-dialog-viewport"
{...props}
/>
);
}
function CommandDialogPopup({
className,
children,
...props
}: CommandDialogPrimitive.Popup.Props) {
return (
<CommandDialogPortal>
<CommandDialogBackdrop />
<CommandDialogViewport>
<CommandDialogPrimitive.Popup
className={cn(
"-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-105 min-h-0 w-full min-w-0 max-w-xl scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border bg-popover not-dark:bg-clip-padding text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] shadow-lg/5 outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:bg-muted/72 before:shadow-[0_1px_--theme(--color-black/6%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=scroll-area-viewport]:data-has-overflow-y:pe-1 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
className,
)}
data-slot="command-dialog-popup"
{...props}
>
{children}
</CommandDialogPrimitive.Popup>
</CommandDialogViewport>
</CommandDialogPortal>
);
}
function Command({
autoHighlight = "always",
keepHighlight = true,
...props
}: React.ComponentProps<typeof Autocomplete>) {
return (
<Autocomplete
autoHighlight={autoHighlight}
inline
keepHighlight={keepHighlight}
open
{...props}
/>
);
}
function CommandInput({
className,
placeholder = undefined,
...props
}: React.ComponentProps<typeof AutocompleteInput>) {
return (
<div className="px-2.5 py-1.5">
<AutocompleteInput
autoFocus
className={cn(
"border-transparent! bg-transparent! shadow-none before:hidden has-focus-visible:ring-0",
className,
)}
placeholder={placeholder}
size="lg"
startAddon={<SearchIcon />}
{...props}
/>
</div>
);
}
function CommandList({
className,
...props
}: React.ComponentProps<typeof AutocompleteList>) {
return (
<AutocompleteList
className={cn("not-empty:scroll-py-2 not-empty:p-2", className)}
data-slot="command-list"
{...props}
/>
);
}
function CommandEmpty({
className,
...props
}: React.ComponentProps<typeof AutocompleteEmpty>) {
return (
<AutocompleteEmpty
className={cn("not-empty:py-6", className)}
data-slot="command-empty"
{...props}
/>
);
}
function CommandPanel({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
className="-mx-px not-has-[+[data-slot=command-footer]]:-mb-px relative min-h-0 rounded-t-xl not-has-[+[data-slot=command-footer]]:rounded-b-2xl border border-b-0 bg-popover not-dark:bg-clip-padding shadow-xs/5 [clip-path:inset(0_1px)] not-has-[+[data-slot=command-footer]]:[clip-path:inset(0_1px_1px_1px_round_0_0_calc(var(--radius-2xl)-1px)_calc(var(--radius-2xl)-1px))] before:pointer-events-none before:absolute before:inset-0 before:rounded-t-[calc(var(--radius-xl)-1px)] **:data-[slot=scroll-area-scrollbar]:mt-2 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]"
{...props}
/>
);
}
function CommandGroup({
className,
...props
}: React.ComponentProps<typeof AutocompleteGroup>) {
return (
<AutocompleteGroup
className={className}
data-slot="command-group"
{...props}
/>
);
}
function CommandGroupLabel({
className,
...props
}: React.ComponentProps<typeof AutocompleteGroupLabel>) {
return (
<AutocompleteGroupLabel
className={className}
data-slot="command-group-label"
{...props}
/>
);
}
function CommandCollection({
...props
}: React.ComponentProps<typeof AutocompleteCollection>) {
return <AutocompleteCollection data-slot="command-collection" {...props} />;
}
function CommandItem({
className,
...props
}: React.ComponentProps<typeof AutocompleteItem>) {
return (
<AutocompleteItem
className={cn("py-1.5", className)}
data-slot="command-item"
{...props}
/>
);
}
function CommandSeparator({
className,
...props
}: React.ComponentProps<typeof AutocompleteSeparator>) {
return (
<AutocompleteSeparator
className={cn("my-2", className)}
data-slot="command-separator"
{...props}
/>
);
}
function CommandShortcut({ className, ...props }: React.ComponentProps<"kbd">) {
return (
<kbd
className={cn(
"ms-auto font-medium font-sans text-muted-foreground/72 text-xs tracking-widest",
className,
)}
data-slot="command-shortcut"
{...props}
/>
);
}
function CommandFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
className={cn(
"flex items-center justify-between gap-2 rounded-b-[calc(var(--radius-2xl)-1px)] border-t px-5 py-3 text-muted-foreground text-xs",
className,
)}
data-slot="command-footer"
{...props}
/>
);
}
export {
CommandCreateHandle,
Command,
CommandCollection,
CommandDialog,
CommandDialogPopup,
CommandDialogTrigger,
CommandEmpty,
CommandFooter,
CommandGroup,
CommandGroupLabel,
CommandInput,
CommandItem,
CommandList,
CommandPanel,
CommandSeparator,
CommandShortcut,
};