AppLayoutDropdown.tsx72 lines · main
1import { AlertCircle, ChevronsUpDown } from 'lucide-react'
2import Link from 'next/link'
3import { forwardRef, type ReactNode } from 'react'
4import { Button, cn, Popover, PopoverContent, PopoverTrigger } from 'ui'
5
6interface AppLayoutDropdownErrorProps {
7 message: string
8}
9
10export function AppLayoutDropdownError({ message }: AppLayoutDropdownErrorProps) {
11 return (
12 <div className="flex items-center space-x-2 text-amber-900">
13 <AlertCircle size={16} strokeWidth={1.5} />
14 <p className="text-sm">{message}</p>
15 </div>
16 )
17}
18
19interface AppLayoutDropdownTriggerButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
20 className?: string
21}
22
23export const AppLayoutDropdownTriggerButton = forwardRef<
24 HTMLButtonElement,
25 AppLayoutDropdownTriggerButtonProps
26>(({ className, ...props }, ref) => (
27 <Button
28 ref={ref}
29 size="tiny"
30 className={cn('px-1.5 py-4 [&_svg]:w-5 [&_svg]:h-5 ml-1', className)}
31 iconRight={<ChevronsUpDown strokeWidth={1.5} />}
32 {...props}
33 type="text"
34 />
35))
36AppLayoutDropdownTriggerButton.displayName = 'AppLayoutDropdownTriggerButton'
37
38export interface AppLayoutDropdownWithPopoverProps {
39 linkHref: string
40 linkContent: ReactNode
41 linkClassName?: string
42 commandContent: ReactNode
43 open: boolean
44 onOpenChange: (open: boolean) => void
45 triggerButtonClassName?: string
46}
47
48export function AppLayoutDropdownWithPopover({
49 linkHref,
50 linkContent,
51 linkClassName = 'flex items-center gap-2 shrink-0 text-sm',
52 commandContent,
53 open,
54 onOpenChange,
55 triggerButtonClassName,
56}: AppLayoutDropdownWithPopoverProps) {
57 return (
58 <Popover open={open} onOpenChange={onOpenChange} modal={false}>
59 <div className="flex items-center shrink-0">
60 <Link href={linkHref} className={linkClassName}>
61 {linkContent}
62 </Link>
63 <PopoverTrigger asChild>
64 <AppLayoutDropdownTriggerButton className={triggerButtonClassName} />
65 </PopoverTrigger>
66 </div>
67 <PopoverContent className="p-0" side="bottom" align="start">
68 {commandContent}
69 </PopoverContent>
70 </Popover>
71 )
72}