76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import { For, type JSX } from "solid-js";
|
|
import { User } from "../../../lib/icons";
|
|
import { activeUserProfile, profileMenuSections } from "../data/shell.data";
|
|
import styles from "./ProfileMenu.module.scss";
|
|
|
|
type ProfileMenuProps = {
|
|
id: string;
|
|
menuRef?: (element: HTMLDivElement) => void;
|
|
onSelect: () => void;
|
|
variant?: "popover" | "workspace";
|
|
};
|
|
|
|
export const ProfileMenu = (props: ProfileMenuProps): JSX.Element => {
|
|
const variant = props.variant ?? "popover";
|
|
|
|
return (
|
|
<div
|
|
id={props.id}
|
|
classList={{
|
|
[styles.menu]: true,
|
|
[styles.menuWorkspace]: variant === "workspace",
|
|
}}
|
|
role="menu"
|
|
aria-label="Profile menu"
|
|
ref={props.menuRef}
|
|
>
|
|
<div class={styles.summary}>
|
|
<div class={styles.avatar} aria-hidden="true">
|
|
<span class={styles.avatarRing} />
|
|
<span class={styles.avatarCore}>
|
|
<User size={16} strokeWidth={2} />
|
|
</span>
|
|
</div>
|
|
|
|
<div class={styles.summaryCopy}>
|
|
<strong class={styles.name}>{activeUserProfile.name}</strong>
|
|
<span class={styles.email}>{activeUserProfile.email}</span>
|
|
<span class={styles.role}>{activeUserProfile.roleLabel}</span>
|
|
<span class={styles.context}>{activeUserProfile.contextLabel}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class={styles.sections}>
|
|
<For each={profileMenuSections}>
|
|
{(section): JSX.Element => (
|
|
<div class={styles.section}>
|
|
<For each={section.items}>
|
|
{(item): JSX.Element => {
|
|
const Icon = item.icon;
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
role="menuitem"
|
|
classList={{
|
|
[styles.item]: true,
|
|
[styles.itemDanger]: item.tone === "danger",
|
|
}}
|
|
onClick={props.onSelect}
|
|
>
|
|
<span class={styles.itemIcon} aria-hidden="true">
|
|
<Icon size={16} strokeWidth={2} />
|
|
</span>
|
|
<span class={styles.itemLabel}>{item.label}</span>
|
|
</button>
|
|
);
|
|
}}
|
|
</For>
|
|
</div>
|
|
)}
|
|
</For>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|