mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: add dropdown menu component
This commit is contained in:
parent
40ec773425
commit
2c1c3e3c98
4 changed files with 463 additions and 6 deletions
69
src/renderer/src/components/dropdown-menu/dropdown-menu.scss
Normal file
69
src/renderer/src/components/dropdown-menu/dropdown-menu.scss
Normal file
|
@ -0,0 +1,69 @@
|
|||
@use "../../scss/globals.scss";
|
||||
|
||||
.dropdown-menu {
|
||||
|
||||
&__content {
|
||||
background-color: globals.$dark-background-color;
|
||||
border: 1px solid globals.$border-color;
|
||||
border-radius: 4px;
|
||||
min-width: 200px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__group {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
&__title-bar {
|
||||
width: 100%;
|
||||
padding: 4px 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: globals.$muted-color;
|
||||
}
|
||||
|
||||
&__separator {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: globals.$border-color;
|
||||
}
|
||||
|
||||
&__item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 8px;
|
||||
border-radius: 4px;
|
||||
padding: 5px 12px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&__item--disabled {
|
||||
cursor: default;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&:not(&__item--disabled) &__item:hover {
|
||||
background-color: globals.$background-color;
|
||||
color: globals.$muted-color;
|
||||
}
|
||||
|
||||
&__item:focus {
|
||||
background-color: globals.$background-color;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&__item-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
78
src/renderer/src/components/dropdown-menu/dropdown-menu.tsx
Normal file
78
src/renderer/src/components/dropdown-menu/dropdown-menu.tsx
Normal file
|
@ -0,0 +1,78 @@
|
|||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||
import "./dropdown-menu.scss";
|
||||
|
||||
export interface DropdownMenuItem {
|
||||
icon?: React.ReactNode;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
show?: boolean;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
interface DropdownMenuProps {
|
||||
children: React.ReactNode;
|
||||
title?: string;
|
||||
loop?: boolean;
|
||||
items: DropdownMenuItem[];
|
||||
sideOffset?: number;
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
align?: "start" | "center" | "end";
|
||||
alignOffset?: number;
|
||||
}
|
||||
|
||||
export default ({
|
||||
children,
|
||||
title,
|
||||
items,
|
||||
sideOffset = 5,
|
||||
side = "bottom",
|
||||
loop = true,
|
||||
align = "center",
|
||||
alignOffset = 0,
|
||||
}: DropdownMenuProps) => (
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button aria-label={title}>{children}</button>
|
||||
</DropdownMenu.Trigger>
|
||||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content
|
||||
sideOffset={sideOffset}
|
||||
side={side}
|
||||
loop={loop}
|
||||
align={align}
|
||||
alignOffset={alignOffset}
|
||||
className="dropdown-menu__content"
|
||||
>
|
||||
{title && (
|
||||
<DropdownMenu.Group className="dropdown-menu__group">
|
||||
<div className="dropdown-menu__title-bar">
|
||||
{title}
|
||||
</div>
|
||||
</DropdownMenu.Group>
|
||||
)}
|
||||
|
||||
<DropdownMenu.Separator className="dropdown-menu__separator" />
|
||||
|
||||
<DropdownMenu.Group className="dropdown-menu__group">
|
||||
{items.map((item) =>
|
||||
item.show !== false && (
|
||||
<DropdownMenu.Item
|
||||
key={item.label}
|
||||
aria-label={item.label}
|
||||
onSelect={item.onClick}
|
||||
className={`dropdown-menu__item ${item.disabled ? "dropdown-menu__item--disabled" : ""}`}
|
||||
disabled={item.disabled}
|
||||
>
|
||||
{item.icon && (
|
||||
<div className="dropdown-menu__item-icon">{item.icon}</div>
|
||||
)}
|
||||
{item.label}
|
||||
</DropdownMenu.Item>
|
||||
)
|
||||
)}
|
||||
</DropdownMenu.Group>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu.Root>
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue