-
-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[account] [docs] Add <Account />
in sidebarFooter
#4255
Changes from 76 commits
38ecc17
7fea561
01c7fa6
49d756a
8098608
6c1c073
f5edc05
43a0978
7277cbf
129b679
f909067
e337ac0
2e321ba
1086869
7938e3f
6807254
c2703a7
884ad56
d76eebf
840362c
c71f5ba
6e34be8
a80df48
882b07b
0b2e4f8
77d8eb7
cb9debf
986298c
eee948a
b93270a
cd6a2a0
81e5304
b94774f
67b83fd
2dc6584
cf1276f
cc743e5
28b71d5
3c01cde
0aff5f9
0363c00
ce95f41
83cd903
96c760c
2ff572d
86fa603
879f7a7
868eb6e
429b3dc
ad12efc
5be7914
637d637
a941719
bdc8e4f
a6b4ba9
1c8523d
7334340
73590d7
07d48a8
4e7fdc8
fcd1025
86a84d9
2a1d6d5
d21ac77
6107c53
58f14d6
3eead4a
4b5f4de
6f1499c
ef3f403
d8fa6be
8603a43
fd826b3
7b86697
299eb7f
81f6346
2aa87b7
64acd1d
5b21e45
01194bc
45f0499
cbe1024
d64ffae
c7949d3
f9a5297
7dd2eb3
1615ae1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
import * as React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Box from '@mui/material/Box'; | ||
import Typography from '@mui/material/Typography'; | ||
import Stack from '@mui/material/Stack'; | ||
import MenuList from '@mui/material/MenuList'; | ||
import MenuItem from '@mui/material/MenuItem'; | ||
import ListItemText from '@mui/material/ListItemText'; | ||
import ListItemIcon from '@mui/material/ListItemIcon'; | ||
import Avatar from '@mui/material/Avatar'; | ||
import Divider from '@mui/material/Divider'; | ||
import { createTheme } from '@mui/material/styles'; | ||
import DashboardIcon from '@mui/icons-material/Dashboard'; | ||
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; | ||
import { AppProvider } from '@toolpad/core/AppProvider'; | ||
import { DashboardLayout } from '@toolpad/core/DashboardLayout'; | ||
import { | ||
Account, | ||
AccountPreview, | ||
AccountPopoverFooter, | ||
SignOutButton, | ||
} from '@toolpad/core/Account'; | ||
|
||
const NAVIGATION = [ | ||
{ | ||
kind: 'header', | ||
title: 'Main items', | ||
}, | ||
{ | ||
segment: 'dashboard', | ||
title: 'Dashboard', | ||
icon: <DashboardIcon />, | ||
}, | ||
{ | ||
segment: 'orders', | ||
title: 'Orders', | ||
icon: <ShoppingCartIcon />, | ||
}, | ||
]; | ||
|
||
const demoTheme = createTheme({ | ||
cssVariables: { | ||
colorSchemeSelector: 'data-toolpad-color-scheme', | ||
}, | ||
colorSchemes: { light: true, dark: true }, | ||
breakpoints: { | ||
values: { | ||
xs: 0, | ||
sm: 600, | ||
md: 600, | ||
lg: 1200, | ||
xl: 1536, | ||
}, | ||
}, | ||
}); | ||
|
||
function DemoPageContent({ pathname }) { | ||
return ( | ||
<Box | ||
sx={{ | ||
py: 4, | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
textAlign: 'center', | ||
}} | ||
> | ||
<Typography>Dashboard content for {pathname}</Typography> | ||
</Box> | ||
); | ||
} | ||
|
||
DemoPageContent.propTypes = { | ||
pathname: PropTypes.string.isRequired, | ||
}; | ||
|
||
function AccountSidebarPreview(props) { | ||
const { handleClick, open } = props; | ||
return ( | ||
<Stack direction="column"> | ||
<Divider /> | ||
<AccountPreview variant="expanded" handleClick={handleClick} open={open} /> | ||
</Stack> | ||
); | ||
} | ||
|
||
AccountSidebarPreview.propTypes = { | ||
/** | ||
* The handler used when the preview is expanded | ||
*/ | ||
handleClick: PropTypes.func, | ||
/** | ||
* The state of the Account popover | ||
* @default false | ||
*/ | ||
open: PropTypes.bool, | ||
}; | ||
|
||
const accounts = [ | ||
{ | ||
id: 1, | ||
name: 'Bharat Kashyap', | ||
email: '[email protected]', | ||
image: 'https://avatars.githubusercontent.com/u/19550456', | ||
projects: [ | ||
{ | ||
id: 3, | ||
title: 'Project X', | ||
}, | ||
], | ||
}, | ||
{ | ||
id: 2, | ||
name: 'Bharat MUI', | ||
email: '[email protected]', | ||
color: '#8B4513', // Brown color | ||
projects: [{ id: 4, title: 'Project A' }], | ||
}, | ||
]; | ||
|
||
function SidebarFooterAccountPopover() { | ||
return ( | ||
<Stack direction="column"> | ||
<Typography variant="body2" mx={2} mt={1}> | ||
Accounts | ||
</Typography> | ||
<MenuList> | ||
{accounts.map((account) => ( | ||
<MenuItem | ||
key={account.id} | ||
component="button" | ||
sx={{ | ||
justifyContent: 'flex-start', | ||
width: '100%', | ||
columnGap: 2, | ||
}} | ||
> | ||
<ListItemIcon> | ||
<Avatar | ||
sx={{ | ||
width: 32, | ||
height: 32, | ||
fontSize: '0.95rem', | ||
bgcolor: account.color, | ||
}} | ||
src={account.image ?? ''} | ||
alt={account.name ?? ''} | ||
> | ||
{account.name[0]} | ||
</Avatar> | ||
</ListItemIcon> | ||
<ListItemText | ||
sx={{ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'flex-start', | ||
width: '100%', | ||
}} | ||
primary={account.name} | ||
secondary={account.email} | ||
primaryTypographyProps={{ variant: 'body2' }} | ||
secondaryTypographyProps={{ variant: 'caption' }} | ||
/> | ||
</MenuItem> | ||
))} | ||
</MenuList> | ||
<AccountPopoverFooter> | ||
<SignOutButton /> | ||
</AccountPopoverFooter> | ||
</Stack> | ||
); | ||
} | ||
|
||
function SidebarFooterAccount() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs some logic to handle the mini-drawer variant, not to overflow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed that! I've modified the demo to be able to handle the |
||
return ( | ||
<Account | ||
slots={{ | ||
preview: AccountSidebarPreview, | ||
popoverContent: SidebarFooterAccountPopover, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In these docs demos, opening and closing the popover automatically scrolls unless they have the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great find! I've added There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I'm not 100% sure if we'd need it in a normal app though, maybe it's just a problem in the demo iframes. |
||
}} | ||
/> | ||
); | ||
} | ||
|
||
const demoSession = { | ||
user: { | ||
name: 'Bharat Kashyap', | ||
email: '[email protected]', | ||
image: 'https://avatars.githubusercontent.com/u/19550456', | ||
}, | ||
}; | ||
|
||
function DashboardLayoutAccountSidebar(props) { | ||
const { window } = props; | ||
|
||
const [pathname, setPathname] = React.useState('/dashboard'); | ||
|
||
const router = React.useMemo(() => { | ||
return { | ||
pathname, | ||
searchParams: new URLSearchParams(), | ||
navigate: (path) => setPathname(String(path)), | ||
}; | ||
}, [pathname]); | ||
|
||
// Remove this const when copying and pasting into your project. | ||
const demoWindow = window !== undefined ? window() : undefined; | ||
|
||
const [session, setSession] = React.useState(demoSession); | ||
const authentication = React.useMemo(() => { | ||
return { | ||
signIn: () => { | ||
setSession(demoSession); | ||
}, | ||
signOut: () => { | ||
setSession(null); | ||
}, | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<AppProvider | ||
navigation={NAVIGATION} | ||
router={router} | ||
theme={demoTheme} | ||
window={demoWindow} | ||
authentication={authentication} | ||
session={session} | ||
> | ||
<DashboardLayout | ||
slots={{ toolbarAccount: () => null, sidebarFooter: SidebarFooterAccount }} | ||
> | ||
<DemoPageContent pathname={pathname} /> | ||
</DashboardLayout> | ||
</AppProvider> | ||
); | ||
} | ||
|
||
DashboardLayoutAccountSidebar.propTypes = { | ||
/** | ||
* Injected by the documentation to work in an iframe. | ||
* Remove this when copying and pasting into your project. | ||
*/ | ||
window: PropTypes.func, | ||
}; | ||
|
||
export default DashboardLayoutAccountSidebar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 3 dots icon doesn't seem vertically centered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the popover isn't pointing to / coming from the 3 dots icon, I guess it should?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I've tweaked the demo to reflect this in both states:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the
expanded
variant, could there be an option to choose whether the popup appears on the right or the top side?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to customize the popover's position (as well as the placement of the arrow) using the
slotProps
- the demo on the docs will showcase this using thetransformOrigin
andanchorOrigin
props