Files
cadence-ui/packages/ui/src/components/dropdown-menu.tsx
T

232 lines
6.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import {
forwardRef,
type ComponentPropsWithoutRef,
type ElementRef,
type HTMLAttributes
} from "react";
import {
dropdownMenuContentVariants,
dropdownMenuItemVariants,
dropdownMenuLabelVariants,
dropdownMenuSeparatorVariants
} from "./dropdown-menu.variants";
import { cn } from "../lib/cn";
import type { VariantProps } from "../lib/cva";
import { createDataAttributes, createSlot } from "../lib/contracts";
export const DropdownMenu = DropdownMenuPrimitive.Root;
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
export const DropdownMenuGroup = DropdownMenuPrimitive.Group;
export const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
export const DropdownMenuSub = DropdownMenuPrimitive.Sub;
export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
export type DropdownMenuContentProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> &
VariantProps<typeof dropdownMenuContentVariants>;
export const DropdownMenuContent = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Content>,
DropdownMenuContentProps
>(function DropdownMenuContent(
{ className, sideOffset = 8, size, ...props },
ref
) {
return (
<DropdownMenuPortal>
<DropdownMenuPrimitive.Content
{...props}
{...createSlot("content")}
{...createDataAttributes({ size })}
className={cn(dropdownMenuContentVariants({ size }), className)}
ref={ref}
sideOffset={sideOffset}
/>
</DropdownMenuPortal>
);
});
export type DropdownMenuSubContentProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> &
VariantProps<typeof dropdownMenuContentVariants>;
export const DropdownMenuSubContent = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.SubContent>,
DropdownMenuSubContentProps
>(function DropdownMenuSubContent(
{ className, sideOffset = 10, size, ...props },
ref
) {
return (
<DropdownMenuPortal>
<DropdownMenuPrimitive.SubContent
{...props}
{...createSlot("content")}
{...createDataAttributes({ size })}
className={cn(dropdownMenuContentVariants({ size }), className)}
ref={ref}
sideOffset={sideOffset}
/>
</DropdownMenuPortal>
);
});
export type DropdownMenuItemProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> &
VariantProps<typeof dropdownMenuItemVariants>;
export const DropdownMenuItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Item>,
DropdownMenuItemProps
>(function DropdownMenuItem(
{ className, inset, variant, ...props },
ref
) {
return (
<DropdownMenuPrimitive.Item
{...props}
{...createSlot("item")}
{...createDataAttributes({ inset, variant })}
className={cn(dropdownMenuItemVariants({ inset, variant }), className)}
ref={ref}
/>
);
});
export type DropdownMenuCheckboxItemProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> &
VariantProps<typeof dropdownMenuItemVariants>;
export const DropdownMenuCheckboxItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
DropdownMenuCheckboxItemProps
>(function DropdownMenuCheckboxItem(
{ checked, children, className, inset = true, variant, ...props },
ref
) {
return (
<DropdownMenuPrimitive.CheckboxItem
{...props}
checked={checked}
{...createSlot("item")}
{...createDataAttributes({ checked: checked === true, inset, variant })}
className={cn(dropdownMenuItemVariants({ inset, variant }), className)}
ref={ref}
>
<span
{...createSlot("icon")}
className="absolute left-2.5 inline-flex size-4 items-center justify-center text-xs"
>
<DropdownMenuPrimitive.ItemIndicator></DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
);
});
export type DropdownMenuRadioItemProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> &
VariantProps<typeof dropdownMenuItemVariants>;
export const DropdownMenuRadioItem = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
DropdownMenuRadioItemProps
>(function DropdownMenuRadioItem(
{ children, className, inset = true, variant, ...props },
ref
) {
return (
<DropdownMenuPrimitive.RadioItem
{...props}
{...createSlot("item")}
{...createDataAttributes({ inset, variant })}
className={cn(dropdownMenuItemVariants({ inset, variant }), className)}
ref={ref}
>
<span
{...createSlot("icon")}
className="absolute left-2.5 inline-flex size-4 items-center justify-center text-xs"
>
<DropdownMenuPrimitive.ItemIndicator></DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
);
});
export type DropdownMenuLabelProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> &
VariantProps<typeof dropdownMenuLabelVariants>;
export const DropdownMenuLabel = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Label>,
DropdownMenuLabelProps
>(function DropdownMenuLabel({ className, inset, ...props }, ref) {
return (
<DropdownMenuPrimitive.Label
{...props}
{...createSlot("label")}
{...createDataAttributes({ inset })}
className={cn(dropdownMenuLabelVariants({ inset }), className)}
ref={ref}
/>
);
});
export const DropdownMenuSeparator = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.Separator>,
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(function DropdownMenuSeparator({ className, ...props }, ref) {
return (
<DropdownMenuPrimitive.Separator
{...props}
{...createSlot("separator")}
className={cn(dropdownMenuSeparatorVariants(), className)}
ref={ref}
/>
);
});
export type DropdownMenuSubTriggerProps =
ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> &
VariantProps<typeof dropdownMenuItemVariants>;
export const DropdownMenuSubTrigger = forwardRef<
ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
DropdownMenuSubTriggerProps
>(function DropdownMenuSubTrigger(
{ children, className, inset, variant, ...props },
ref
) {
return (
<DropdownMenuPrimitive.SubTrigger
{...props}
{...createSlot("trigger")}
{...createDataAttributes({ inset, variant })}
className={cn(dropdownMenuItemVariants({ inset, variant }), className)}
ref={ref}
>
{children}
<span className="ml-auto text-xs text-[var(--color-muted-foreground)]"></span>
</DropdownMenuPrimitive.SubTrigger>
);
});
export function DropdownMenuShortcut({
className,
...props
}: HTMLAttributes<HTMLSpanElement>) {
return (
<span
{...props}
{...createSlot("shortcut")}
className={cn(
"ml-auto text-xs uppercase tracking-[var(--tracking-caps)] text-[var(--color-muted-foreground)]",
className
)}
/>
);
}