Skip to content

Instantly share code, notes, and snippets.

@tlimpanont
Last active July 24, 2022 07:28
Show Gist options
  • Save tlimpanont/795bbe77cf0b21bda784fd3bfe3dba74 to your computer and use it in GitHub Desktop.
Save tlimpanont/795bbe77cf0b21bda784fd3bfe3dba74 to your computer and use it in GitHub Desktop.
custom appbar with (submenu) implementations 1) with fully flexible way of composing your own JSX elements 2) a mix of flexible way of composing menu items and opiniated slot properties to guarantee correct styling and lay-out placements.
/**
de eerste is dat in elke applicatie als je een appbar met menu nodig hebt je volledig JSX structuur
opnieuw moet opbouwen (wel super flexibel en vrij)
*/
import {
Box,
ButtonBase,
IconButton,
ListItem,
ListItemIcon,
ListItemText,
Stack,
Toolbar,
Typography,
} from "@mui/material";
import {
ArrowBack,
Close as CloseIcon,
Flag,
Image as ImageIcon,
Mail,
Menu as MenuIcon,
SupervisedUserCircle,
VerifiedUserRounded,
} from "@mui/icons-material";
import { AppBarMenuList } from "./AppBarMenuList";
import { AppBarListItem } from "./AppBarListItem";
import { AppBar } from "./AppBar";
import { useState } from "react";
import { AppBarMenu } from "./AppBarMenu";
import { AppBarSubMenu } from "./AppBarSubMenu";
import { Theme } from "@mui/material/styles";
function AppBarWithMenu() {
const [menuOpen, setMenuOpen] = useState(true);
const [subMenuOpen, setSubMenuOpen] = useState(false);
return (
<>
<AppBar menuOpen={menuOpen} subMenuOpen={subMenuOpen}>
{/*
Compose your regular MUI toolbar like: https://mui.com/material-ui/react-app-bar/#basic-app-bar
*/}
{/*=========================*/}
<Toolbar>
<IconButton>
<SupervisedUserCircle fontSize={"large"} />
</IconButton>
<Box flex={1} />
<Typography sx={{ flexGrow: 1 }} variant={"h5"} color={"primary"}>
Title
</Typography>
{menuOpen ? (
<IconButton
onClick={() => {
setMenuOpen(false);
setSubMenuOpen(false);
}}
>
<CloseIcon />
</IconButton>
) : (
<IconButton
onClick={() => {
setMenuOpen(true);
setSubMenuOpen(false);
}}
>
<MenuIcon />
</IconButton>
)}
</Toolbar>
{/*=========================*/}
{/*
Compose a AppBar SubMenu content with AppBarMenuList and AppBarListItem components
*/}
{/*=========================*/}
<AppBarSubMenu>
<AppBarMenuList>
<ButtonBase sx={{ mt: 1 }} onClick={() => setSubMenuOpen(false)}>
<ArrowBack />
<Typography variant={"h5"}>Back</Typography>
</ButtonBase>
<AppBarListItem>
<ListItemIcon>
<VerifiedUserRounded />
</ListItemIcon>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
</AppBarMenuList>
</AppBarSubMenu>
{/*=========================*/}
{/*
Compose a main AppBar Main Menu content with AppBarMenuList and AppBarListItem components
*/}
{/*=========================*/}
<AppBarMenu>
{/*=========================*/}
<AppBarMenuList>
<AppBarListItem>
<ListItemIcon>
<Mail />
</ListItemIcon>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
</AppBarMenuList>
{/*=========================*/}
{/*========================= SPACER BETWEEN TWO LIST ITEMS*/}
<Box mb={4} />
{/*=========================*/}
{/*=========================*/}
<AppBarMenuList
sx={{ flexGrow: 1 }}
subheader={<Typography variant={"h5"}>Account</Typography>}
>
<AppBarListItem>
<ListItemIcon>
<ImageIcon />
</ListItemIcon>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemIcon>
<Mail />
</ListItemIcon>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
<AppBarListItem>
<ListItemText primary={"item1"} />
</AppBarListItem>
</AppBarMenuList>
<ListItem
secondaryAction={
<ListItemText
primary={
<Typography
color={"gray"}
fontSize={"small"}
variant={"body1"}
>
versie 23243
</Typography>
}
/>
}
/>
<AppBarMenuList sx={{ bgcolor: "action.focus", mt: 4 }}>
<AppBarListItem
onClick={() => {
setSubMenuOpen(true);
}}
>
<ListItemIcon>
<Flag />
</ListItemIcon>
<ListItemText primary={"Open submenu"} />
</AppBarListItem>
</AppBarMenuList>
{/*=========================*/}
</AppBarMenu>
{/*=========================*/}
</AppBar>
{/*=========================*/}
</>
);
}
export default AppBarWithMenu;
/**
en aan de andere kant is het een mix van vrij zijn en geforceerd props invullen
(om uiteindelijk niet teveel zelf layouts te moeten maken en layout en stijl garantie te krijgen)
*/
import { FC, useState } from 'react'
import { Capacitor } from '@capacitor/core'
import { Box } from '@mui/material'
import {
AppBar as RfhAppBar,
AppBarList,
AppBarListItem,
AppBarNativeSelect,
} from '@rfh/ui/components/Layout/AppBar'
/*
* when we release a specific version we follow the rule of bumping up version number in package.json
* hence this version number is reliable number to communicate to stakeholders for verifying and testing purposes
* */
import packageJson from '../../package.json'
export const AppBar: FC<{ title: string }> = ({ title }) => {
const [menuOpen, setMenuOpen] = useState<boolean>(false)
const menuContent = (
<>
<AppBarList>
<AppBarListItem
text={'Uitgifte'}
onClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
/>
<AppBarListItem
text={'Inname'}
onClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
/>
<AppBarListItem
text={'Voorraadbeheer'}
onClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
/>
<AppBarListItem
text={'Transport'}
onClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
/>
<AppBarListItem
text={'Administratief'}
onClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
/>
</AppBarList>
<AppBarList subheader={'Account'}>
<AppBarListItem
text={'Mijn RFH Profiel'}
anchor={{ href: '@todo put here the correct url', target: '_blank' }}
/>
<AppBarListItem
text={
<AppBarNativeSelect>
{/*@todo get the list from ENUM */}
<option value={'Aalsmeer'}>Locatie: Aalsmeer</option>
<option value={'Rijnsburg'}>Locatie: Rijnsburg</option>
<option value={'Naaldwijk'}>Locatie: Naaldwijk</option>
</AppBarNativeSelect>
}
/>
</AppBarList>
</>
)
return (
<Box
sx={{
pt: 'env(safe-area-inset-top)',
pl: 'env(safe-area-inset-left)',
pr: 'env(safe-area-inset-right)',
}}
>
<Box>
<RfhAppBar
onMenuOpen={() => setMenuOpen(true)}
onMenuClose={() => setMenuOpen(false)}
menuOpen={menuOpen}
menuContent={menuContent}
onLogoClick={() => {
//@todo link to routing
setMenuOpen(false)
}}
title={title}
menuOpenTitle={'Menu'}
versionTag={
Capacitor.isNativePlatform() ? `versie ${packageJson.version}` : ''
}
/>
</Box>
</Box>
)
}
@tlimpanont
Copy link
Author

First example

screencast-override

Second example

l7IAfVU3F9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment