mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-12 21:29:20 +00:00
79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import { ComponentPropsWithRef, ElementType, ReactNode, Ref } from "react";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export type MenuProps = {
|
|
children: ReactNode;
|
|
className?: string;
|
|
};
|
|
|
|
export const Menu = ({ children, className }: MenuProps): JSX.Element => {
|
|
return <ul className={twMerge("p-2", className)}>{children}</ul>;
|
|
};
|
|
|
|
export type MenuItemProps<T extends ElementType> = {
|
|
// Kudos to https://itnext.io/react-polymorphic-components-with-typescript-f7ce72ea7af2
|
|
as?: T;
|
|
children?: ReactNode;
|
|
leftIcon?: ReactNode;
|
|
description?: ReactNode;
|
|
isDisabled?: boolean;
|
|
isSelected?: boolean;
|
|
className?: string;
|
|
inputRef?: Ref<T>;
|
|
};
|
|
|
|
export const MenuItem = <T extends ElementType = "button">({
|
|
children,
|
|
leftIcon,
|
|
iconMode,
|
|
className,
|
|
isDisabled,
|
|
isSelected,
|
|
as: Item = "div",
|
|
description,
|
|
// wrapping in forward ref with generic component causes the loss of ts definitions on props
|
|
inputRef,
|
|
variant,
|
|
...props
|
|
}: MenuItemProps<T> &
|
|
ComponentPropsWithRef<T> & { variant?: "project" | "namespace" | "org" }): JSX.Element => {
|
|
return (
|
|
<Item
|
|
type="button"
|
|
role="menuitem"
|
|
className={twMerge(
|
|
"group relative mt-0.5 box-border flex w-full cursor-pointer items-center rounded-[2px] border-l-2 border-transparent px-2 py-2 font-inter text-sm text-bunker-100 transition-all duration-50 hover:bg-mineshaft-700",
|
|
isSelected && "bg-mineshaft-600 hover:bg-mineshaft-600",
|
|
isDisabled && "cursor-not-allowed hover:bg-transparent",
|
|
isSelected && variant === "org" && "border-org-v1",
|
|
isSelected && variant === "namespace" && "border-namespace-v1",
|
|
isSelected && variant === "project" && "border-primary",
|
|
className
|
|
)}
|
|
ref={inputRef}
|
|
{...props}
|
|
>
|
|
{leftIcon}
|
|
{children && <span className="grow text-left whitespace-nowrap">{children}</span>}
|
|
{description && <span className="mt-2 text-xs">{description}</span>}
|
|
</Item>
|
|
);
|
|
};
|
|
|
|
MenuItem.displayName = "MenuItem";
|
|
|
|
export type MenuGroupProps = {
|
|
children: ReactNode;
|
|
title: ReactNode;
|
|
className?: string;
|
|
};
|
|
|
|
export const MenuGroup = ({ children, title, className }: MenuGroupProps): JSX.Element => (
|
|
<>
|
|
<li className={twMerge("px-2 pt-3 text-xs font-medium text-gray-400 uppercase", className)}>
|
|
{title}
|
|
</li>
|
|
{children}
|
|
</>
|
|
);
|