67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
// Path: Frontend/src/components/shell/MobileBottomNav/MobileBottomNav.tsx
|
|
|
|
import { For, type JSX } from "solid-js";
|
|
import { useAppShellData } from "../data/app-shell.context";
|
|
import { mobileBottomNavItems, type MobileBottomNavItem } from "../data/shell.data";
|
|
import styles from "./MobileBottomNav.module.scss";
|
|
|
|
type MobileBottomNavProps = {
|
|
isBrowseOpen: boolean;
|
|
onBrowseToggle: VoidFunction;
|
|
};
|
|
|
|
const MobileNavEntry = (props: {
|
|
item: MobileBottomNavItem;
|
|
isActive: boolean;
|
|
onSelect?: VoidFunction;
|
|
}): JSX.Element => {
|
|
const Icon = props.item.icon;
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={() => props.onSelect?.()}
|
|
classList={{
|
|
[styles.navButton]: true,
|
|
[styles.navButtonActive]: props.isActive,
|
|
}}
|
|
aria-current={props.isActive ? "page" : undefined}
|
|
aria-expanded={props.item.id === "browse" ? props.isActive : undefined}
|
|
aria-label={props.item.label}
|
|
title={props.item.label}
|
|
>
|
|
<span class={styles.iconWrap} aria-hidden="true">
|
|
<Icon size={18} strokeWidth={2} />
|
|
</span>
|
|
|
|
<span class={styles.label}>{props.item.label}</span>
|
|
</button>
|
|
);
|
|
};
|
|
|
|
export const MobileBottomNav = (props: MobileBottomNavProps): JSX.Element => {
|
|
const appShellData = useAppShellData();
|
|
|
|
return (
|
|
<nav class={styles.mobileNav} aria-label="Mobile workspace navigation">
|
|
<div class={styles.contextBar}>
|
|
<span class={styles.contextServer}>{appShellData.activeServer().name}</span>
|
|
<span class={styles.contextDivider}>/</span>
|
|
<span class={styles.contextProject}>{appShellData.activeProject().name}</span>
|
|
</div>
|
|
|
|
<div class={styles.navGrid}>
|
|
<For each={mobileBottomNavItems}>
|
|
{(item): JSX.Element => (
|
|
<MobileNavEntry
|
|
item={item}
|
|
isActive={item.id === "browse" ? props.isBrowseOpen : (item.active ?? false) && !props.isBrowseOpen}
|
|
onSelect={item.id === "browse" ? props.onBrowseToggle : undefined}
|
|
/>
|
|
)}
|
|
</For>
|
|
</div>
|
|
</nav>
|
|
);
|
|
};
|