Something went wrong. Try again.
leaflet fork for copy edit / bug fixes forked from leaflet.pub/leaflet
Something went wrong. Try again.
5.8 kB · 188 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189"use client";import * as DropdownMenu from "@radix-ui/react-dropdown-menu";import { theme } from "tailwind.config";import { NestedCardThemeProvider } from "./ThemeManager/ThemeProvider";import { PopoverArrow } from "./Icons/PopoverArrow";import { CheckboxChecked } from "./Icons/CheckboxChecked";import { CheckboxEmpty } from "./Icons/CheckboxEmpty";import { CheckboxIndeterminate } from "./Icons/CheckboxIndeterminate";import { PopoverOpenContext } from "./Popover/PopoverContext";import { useState } from "react";import { useCardBorderHidden } from "components/Pages/useCardBorderHidden";
export const Menu = (props: { open?: boolean; trigger: React.ReactNode; children: React.ReactNode; align?: "start" | "end" | "center" | undefined; alignOffset?: number; side?: "top" | "bottom" | "right" | "left" | undefined; background?: string; border?: string; className?: string; onOpenChange?: (o: boolean) => void; asChild?: boolean;}) => { let [open, setOpen] = useState(props.open || false); let cardBorderHidden = useCardBorderHidden();
return ( <DropdownMenu.Root onOpenChange={(o) => { setOpen(o); props.onOpenChange?.(o); }} open={props.open} > <PopoverOpenContext value={open}> <DropdownMenu.Trigger asChild={props.asChild}> {props.trigger} </DropdownMenu.Trigger> <DropdownMenu.Portal> <NestedCardThemeProvider> <DropdownMenu.Content side={props.side ? props.side : "bottom"} align={props.align ? props.align : "center"} alignOffset={props.alignOffset ? props.alignOffset : undefined} sideOffset={4} collisionPadding={16} className={` dropdownMenu portalStyles z-20 p-1 flex flex-col gap-0.5 border border-border rounded-md shadow-md ${props.className} ${cardBorderHidden ? "light-container" : "bg-bg-page"}`} > {props.children} <DropdownMenu.Arrow asChild width={16} height={8} viewBox="0 0 16 8" > <PopoverArrow arrowFill={ props.background ? props.background : cardBorderHidden ? "color-mix(in oklab, rgb(var(--primary)), rgb(var(--bg-page)) 95%)" : theme.colors["bg-page"] } arrowStroke={ props.border ? props.border : theme.colors["border"] } /> </DropdownMenu.Arrow> </DropdownMenu.Content> </NestedCardThemeProvider> </DropdownMenu.Portal> </PopoverOpenContext> </DropdownMenu.Root> );};
export const RadioMenuGroup = (props: { value: string; onValueChange?: (value: string) => void; children: React.ReactNode;}) => { return ( <DropdownMenu.RadioGroup className="flex flex-col gap-0.5" value={props.value} onValueChange={props.onValueChange} > {props.children} </DropdownMenu.RadioGroup> );};
export const RadioMenuItem = (props: { value: string; children?: React.ReactNode; className?: string; onSelect?: (e: Event) => void; selected?: boolean;}) => { return ( <DropdownMenu.RadioItem value={props.value} onSelect={props.onSelect} className={` menuItem ${props.selected && "bg-[var(--accent-light)]! text-accent-contrast! "} ${props.className} `} > {props.children} </DropdownMenu.RadioItem> );};
export const CheckboxMenuItem = (props: { children?: React.ReactNode; className?: string; onSelect?: (e: Event) => void; checked?: boolean; // Renders as a Checkbox — a box in the margin and plain type — rather than // the filled pill, for dense multi-select lists like filters. compact?: boolean; // A parent whose children are only partly checked. Selecting it reports // unchecked, so callers select the whole group. indeterminate?: boolean;}) => { let indeterminate = !props.checked && !!props.indeterminate; let marked = props.checked || indeterminate; let iconClassName = `shrink-0 mt-1 ${marked ? "text-accent-contrast" : "text-tertiary"}`; return ( <DropdownMenu.CheckboxItem checked={indeterminate ? "indeterminate" : !!props.checked} onSelect={props.onSelect} className={ props.compact ? `menuItem items-start text-sm py-0! ${marked ? "text-primary! font-bold!" : "text-tertiary! font-normal!"} ${props.className}` : `menuItem ${props.checked && "bg-[var(--accent-light)]! border-accent-contrast! text-accent-contrast!"} ${props.className}` } > {props.compact && (indeterminate ? ( <CheckboxIndeterminate className={iconClassName} /> ) : props.checked ? ( <CheckboxChecked className={iconClassName} /> ) : ( <CheckboxEmpty className={iconClassName} /> ))} {props.children} </DropdownMenu.CheckboxItem> );};
export const MenuSeparator = () => { return ( <DropdownMenu.Separator className="border-border-light w-full border-b my-0.5" /> );};export const MenuItem = (props: { children?: React.ReactNode; className?: string; onSelect: (e: Event) => void; id?: string;}) => { return ( <DropdownMenu.Item id={props.id} onSelect={(event) => { props.onSelect(event); }} className={` menuItem ${props.className} `} > {props.children} </DropdownMenu.Item> );};