AppLayoutDropdown.tsx 2.1 KB

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