teqo/src/components/ui/Command.tsx
Francisco Ignácio Fontoura Solla bcac665cb5 Ship /campanha nuclei MVP with RBAC, invites, and vote estimates.
Adds electoral nuclei, leaderships, updates, and WhatsApp invite flows behind campaign auth, plus the consolidated schema migration that Vercel applies on deploy.
2026-07-18 15:01:56 -03:00

165 lines
4.5 KiB
TypeScript

'use client'
import * as React from 'react'
import { Command as CommandPrimitive } from 'cmdk'
import { cn } from '@/lib/utils'
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { InputGroup, InputGroupAddon } from '@/components/ui/input-group'
import { SearchIcon, CheckIcon } from 'lucide-react'
const Command = ({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) => (
<CommandPrimitive
data-slot="command"
className={cn(
'flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground',
className,
)}
{...props}
/>
)
const CommandDialog = ({
title = 'Comandos',
description = 'Busque um comando para executar.',
children,
className,
showCloseButton = false,
...props
}: React.ComponentProps<typeof Dialog> & {
title?: string
description?: string
className?: string
showCloseButton?: boolean
}) => (
<Dialog {...props}>
<DialogHeader className="sr-only">
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
<DialogContent
className={cn('top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0', className)}
showCloseButton={showCloseButton}
>
{children}
</DialogContent>
</Dialog>
)
const CommandInput = ({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Input>) => (
<div data-slot="command-input-wrapper" className="p-1 pb-0">
<InputGroup className="h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!">
<CommandPrimitive.Input
data-slot="command-input"
className={cn(
'w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}
/>
<InputGroupAddon>
<SearchIcon className="size-4 shrink-0 opacity-50" />
</InputGroupAddon>
</InputGroup>
</div>
)
const CommandList = ({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.List>) => (
<CommandPrimitive.List
data-slot="command-list"
className={cn(
'no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none',
className,
)}
{...props}
/>
)
const CommandEmpty = ({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Empty>) => (
<CommandPrimitive.Empty
data-slot="command-empty"
className={cn('py-6 text-center text-sm', className)}
{...props}
/>
)
const CommandGroup = ({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Group>) => (
<CommandPrimitive.Group
data-slot="command-group"
className={cn(
'overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground',
className,
)}
{...props}
/>
)
const CommandSeparator = ({
className,
...props
}: React.ComponentProps<typeof CommandPrimitive.Separator>) => (
<CommandPrimitive.Separator
data-slot="command-separator"
className={cn('-mx-1 h-px bg-border', className)}
{...props}
/>
)
const CommandItem = ({
className,
children,
...props
}: React.ComponentProps<typeof CommandPrimitive.Item>) => (
<CommandPrimitive.Item
data-slot="command-item"
className={cn(
"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:*:[svg]:text-foreground",
className,
)}
{...props}
>
{children}
<CheckIcon className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
</CommandPrimitive.Item>
)
const CommandShortcut = ({ className, ...props }: React.ComponentProps<'span'>) => (
<span
data-slot="command-shortcut"
className={cn(
'ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground',
className,
)}
{...props}
/>
)
export {
Command,
CommandDialog,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
CommandSeparator,
}