sendou.ink/app/components/elements/Menu.tsx
Kalle dd1adad94b
Some checks are pending
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
BIome v2 upgrade
2025-06-22 16:49:27 +03:00

81 lines
1.6 KiB
TypeScript

import clsx from "clsx";
import {
Menu,
MenuItem,
type MenuItemProps,
MenuTrigger,
Popover,
} from "react-aria-components";
import { Image } from "../Image";
import styles from "./Menu.module.css";
interface SendouMenuProps {
trigger: React.ReactNode;
scrolling?: boolean;
opensLeft?: boolean;
children: React.ReactNode;
}
export function SendouMenu({
children,
trigger,
opensLeft,
scrolling,
}: SendouMenuProps) {
return (
<MenuTrigger>
{trigger}
<Popover
className={clsx(styles.itemsContainer, {
[styles.scrolling]: scrolling,
[styles.itemsContainerOpensLeft]: !opensLeft,
})}
>
<Menu>{children}</Menu>
</Popover>
</MenuTrigger>
);
}
export interface SendouMenuItemProps extends MenuItemProps {
icon?: React.ReactNode;
imagePath?: string;
isActive?: boolean;
}
export function SendouMenuItem(props: SendouMenuItemProps) {
const textValue =
props.textValue ??
(typeof props.children === "string" ? props.children : undefined);
return (
<MenuItem
{...props}
textValue={textValue}
className={({ isSelected, isDisabled }) =>
clsx(styles.item, {
[styles.itemSelected]: isSelected,
[styles.itemDisabled]: isDisabled,
[styles.itemActive]: props.isActive,
})
}
>
{/** biome-ignore lint/complexity/noUselessFragments: Biome v2 migration */}
<>
{props.icon ? (
<span className={styles.itemIcon}>{props.icon}</span>
) : null}
{props.imagePath ? (
<Image
path={props.imagePath}
alt=""
width={24}
height={24}
className={styles.itemImg}
/>
) : null}
{props.children}
</>
</MenuItem>
);
}