@material-ui/core#Badge TypeScript Examples
The following examples show how to use
@material-ui/core#Badge.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TabBar.tsx From Demae with MIT License | 6 votes |
CartIcon = () => {
const [cart] = useContext(CartContext)
const items = cart?.items() || []
const badgeContent = items.reduce((prev, current) => {
return current.quantity + prev
}, 0)
return (
<Badge badgeContent={badgeContent} color="secondary">
<ShoppingCartIcon />
</Badge>
)
}
Example #2
Source File: ServerListItemSingle.tsx From shadowsocks-electron with GNU General Public License v3.0 | 6 votes |
StyledBadge = withStyles((theme: Theme) =>
createStyles({
badge: {
right: -20,
top: 12,
borderRadius: 3,
padding: '0 5',
border: `solid 1px #8f8f8f`,
backgroundColor: 'inherit',
color: '#8f8f8f'
},
}),
)(Badge)
Example #3
Source File: StatusBarConnection.tsx From shadowsocks-electron with GNU General Public License v3.0 | 6 votes |
StyledBadge = withStyles((theme: Theme) =>
createStyles({
badge: {
left: -8,
bottom: 8,
color: grey[500],
backgroundColor: green[400]
}
}),
)(Badge)
Example #4
Source File: ReportHelpModal.tsx From neodash with Apache License 2.0 | 6 votes |
NeoReportHelpModal = ({ open, handleClose }) => {
return (
<Dialog maxWidth={"lg"} open={open == true} onClose={handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">
About Reports
<IconButton onClick={handleClose} style={{ padding: "3px", float: "right" }}>
<Badge badgeContent={""} >
<CloseIcon />
</Badge>
</IconButton>
</DialogTitle>
<DialogContent style={{ width: "1000px" }}>
<DialogContentText> A report is the smallest building block of your dashboard.
Each report runs a single Cypher query that loads data from your database.
By changing the report type, different visualizations can be created for the data.
See the <a href="https://github.com/neo4j-labs/neodash/wiki/Reports">Documentation</a> for more on reports.
<br></br><br></br>
<table>
<tr>
<td>
<b>Moving Reports</b>
<img src='movereport.gif' style={{ width: "100%" }}></img>
</td>
<td>
<b>Resizing Reports</b>
<img src='resizereport.gif' style={{ width: "100%" }}></img>
</td>
</tr>
</table>
</DialogContentText>
</DialogContent>
</Dialog>
);
}
Example #5
Source File: ActionItems.tsx From backstage with Apache License 2.0 | 6 votes |
AlertStatusButton = ({ title, amount, icon, onClick, ...buttonProps }: AlertStatusButtonProps) => ( <Tooltip title={title}> <IconButton onClick={onClick} role="button" aria-hidden={false} {...buttonProps} > <Badge badgeContent={amount}>{icon}</Badge> </IconButton> </Tooltip> )
Example #6
Source File: NotificationButton.tsx From clearflask with Apache License 2.0 | 6 votes |
render() {
if (!this.props.isLoggedIn) return null;
return (
<Collapse
in={!!this.props.notifications?.length}
className={this.props.className}
>
<IconButton
aria-label='Notifications'
onClick={e => this.setState({ notificationAnchorEl: !!this.state.notificationAnchorEl ? undefined : e.currentTarget })}
>
<Badge
badgeContent={this.props.notifications ? this.props.notifications.length : 0}
color='secondary'
variant={this.props.showCount ? 'standard' : 'dot'}
max={999}
>
<NotificationsIcon fontSize='inherit' />
<NotificationPopup
server={this.props.server}
anchorEl={this.state.notificationAnchorEl}
onClose={() => this.setState({ notificationAnchorEl: undefined })}
/>
</Badge>
</IconButton>
</Collapse>
);
}
Example #7
Source File: AttendeeChip.tsx From backstage with Apache License 2.0 | 6 votes |
AttendeeChip = ({ user }: AttendeeChipProps) => {
const classes = useStyles({ responseStatus: user.responseStatus });
return (
<Badge
classes={{
root: classes.responseStatus,
badge: classes.badge,
}}
badgeContent={<ResponseIcon responseStatus={user.responseStatus} />}
>
<Chip
size="small"
variant="outlined"
label={user.email}
color="primary"
/>
</Badge>
);
}
Example #8
Source File: Topbar.tsx From knests with MIT License | 5 votes |
Topbar = (props) => {
const { className, onSidebarOpen, ...rest } = props;
const classes = useStyles();
const [notifications] = useState([]);
const router = useRouter();
const handleSignOut = () => {
router.push('/login');
localStorage.removeItem('token');
};
return (
<AppBar
{...rest}
className={clsx(classes.root, className)}
>
<Toolbar>
<Link href="/">
<a >
<img
alt="Logo"
src="/images/logos/logo--white.svg"
/>
</a>
</Link>
<div className={classes.flexGrow} />
<Hidden mdDown>
<IconButton color="inherit">
<Badge
badgeContent={notifications.length}
color="primary"
variant="dot"
>
<NotificationsIcon />
</Badge>
</IconButton>
<IconButton
className={classes.signOutButton}
color="inherit"
onClick={handleSignOut}
>
<InputIcon />
</IconButton>
</Hidden>
<Hidden lgUp>
<IconButton
color="inherit"
onClick={onSidebarOpen}
>
<MenuIcon />
</IconButton>
</Hidden>
</Toolbar>
</AppBar>
);
}
Example #9
Source File: DashboardHeaderTitleBar.tsx From neodash with Apache License 2.0 | 5 votes |
NeoDashboardHeaderTitleBar = ({ dashboardTitle, downloadImageEnabled, onDownloadImage, open, setDashboardTitle, connection, editable, standalone, handleDrawerOpen, onConnectionModalOpen }) => {
const [dashboardTitleText, setDashboardTitleText] = React.useState(dashboardTitle);
const debouncedDashboardTitleUpdate = useCallback(
debounce(setDashboardTitle, 250),
[],
);
useEffect(() => {
// Reset text to the dashboard state when the page gets reorganized.
if (dashboardTitle !== dashboardTitleText) {
setDashboardTitleText(dashboardTitle);
}
}, [dashboardTitle])
const content = <Toolbar key={1} style={{ paddingRight: 24, minHeight: "64px", background: '#0B297D', zIndex: 1201 }}>
{!standalone ? <IconButton
edge="start"
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
style={
(open) ? {
display: 'none',
} : {
marginRight: 36,
marginLeft: -19,
}
}
>
<MenuIcon />
</IconButton> : <></>}
<InputBase
id="center-aligned"
style={{ textAlign: 'center', fontSize: "22px", flexGrow: 1, color: "white" }}
placeholder="Dashboard Name..."
fullWidth
maxRows={4}
value={dashboardTitleText}
onChange={(event) => {
if (editable) {
setDashboardTitleText(event.target.value);
debouncedDashboardTitleUpdate(event.target.value);
}
}}
/>
{downloadImageEnabled ? <Tooltip title={"Download Dashboard as Image"}>
<IconButton style={{background: "#ffffff22", padding: "3px", marginRight: "3px"}} onClick={(e) => onDownloadImage()}>
<ImageIcon style={{ padding: 6, color: "#ffffffdd", width: "36px", height: "36px", fontSize: "1.3rem", zIndex: 5 }} fontSize="small">
</ImageIcon>
</IconButton>
</Tooltip> : <></>}
<Tooltip title={connection.protocol + "://" + connection.url + ":" + connection.port} placement="left" aria-label="host">
<IconButton style={{ background: "#ffffff22", padding: "3px" }} onClick={(e) => {
if (!standalone) {
onConnectionModalOpen();
}
}}>
<Badge badgeContent={""} >
<img style={{ width: "36px", height: "36px" }} src="neo4j-icon.png" />
</Badge>
</IconButton>
</Tooltip>
</Toolbar>;
return content;
}
Example #10
Source File: Menu.tsx From ra-enterprise-demo with MIT License | 5 votes |
StyledBadgeForText = withStyles(theme => ({
badge: {
top: 13,
right: 13,
border: `1px solid ${theme.palette.background.paper}`,
padding: '0 4px',
},
}))(Badge)
Example #11
Source File: CostInsightsNavigation.tsx From backstage with Apache License 2.0 | 5 votes |
CostInsightsNavigation = React.memo(
({ alerts, products }: CostInsightsNavigationProps) => {
const classes = useStyles();
const { icons } = useConfig();
const [isOpen, setOpen] = useState(false);
const defaultNavigationItems = getDefaultNavigationItems(alerts);
const productNavigationItems: NavigationItem[] =
products?.map(product => ({
title: product.name,
navigation: product.kind,
icon: findAlways(icons, i => i.kind === product.kind).component,
})) ?? [];
useEffect(
function toggleProductMenuItems() {
if (products?.length) {
setOpen(true);
} else {
setOpen(false);
}
},
[products],
);
return (
<MenuList className={classes.menuList}>
{defaultNavigationItems.map(item => (
<NavigationMenuItem
key={`navigation-menu-item-${item.navigation}`}
navigation={item.navigation}
title={item.title}
icon={
item.navigation === DefaultNavigation.AlertInsightsHeader ? (
<Badge badgeContent={alerts} color="secondary">
{React.cloneElement(item.icon, {
className: classes.navigationIcon,
})}
</Badge>
) : (
React.cloneElement(item.icon, {
className: classes.navigationIcon,
})
)
}
/>
))}
<Collapse in={isOpen} timeout={850}>
{productNavigationItems.map((item: NavigationItem) => (
<NavigationMenuItem
key={`navigation-menu-item-${item.navigation}`}
navigation={item.navigation}
icon={React.cloneElement(item.icon, {
className: classes.navigationIcon,
})}
title={item.title}
/>
))}
</Collapse>
</MenuList>
);
},
)
Example #12
Source File: Header.tsx From storefront with MIT License | 5 votes |
Header: React.VFC = () => {
const styles = useStyles();
const { settings } = useSettings();
const [open, toggleOpen] = useToggle(false);
const { data: menu } = useMenuQuery({
variables: { location: MenuLocationEnum.PRIMARY_NAVIGATION },
});
const { data: { cart } = { cart: undefined } } = useCartQuery({
fetchPolicy: 'no-cache',
ssr: false,
});
return (
<AppBar color="default" position="relative">
<Toolbar
className={styles.toolbar}
sx={{
minHeight: { xs: 60, md: 110 },
mx: 'auto',
width: '100%',
}}
>
<Box sx={{ display: { md: 'none' }, flexGrow: 1 }}>
<IconButton aria-label="Menu" onClick={toggleOpen}>
<Menu />
</IconButton>
</Box>
<Link href="/" underline="none">
<Logo className={styles.logo} aria-label={settings.title} />
</Link>
<Box
sx={{
alignItems: 'center',
alignSelf: 'stretch',
display: 'flex',
flexGrow: 1,
justifyContent: 'flex-end',
}}
>
<Box sx={{ display: { xs: 'none', md: 'flex' }, height: '100%' }}>
<HeaderMenu menu={menu} />
</Box>
<IconButton href="/cart" color="inherit" aria-label="Cart">
<Badge badgeContent={cart?.contents?.itemCount}>
<Cart />
</Badge>
</IconButton>
</Box>
</Toolbar>
<Collapse unmountOnExit in={open} timeout="auto">
<HeaderMenu menu={menu} />
</Collapse>
</AppBar>
);
}
Example #13
Source File: CommentsPopper.tsx From frontend with Apache License 2.0 | 5 votes |
CommentsPopper: React.FunctionComponent<IProps> = ({
text,
onSave,
}) => {
const classes = useStyles();
const popupState = usePopupState({
variant: "popper",
popupId: "commentPopper",
});
const [comment, setComment] = React.useState("");
React.useEffect(() => setComment(text ? text : ""), [text]);
return (
<React.Fragment>
<Badge
color="secondary"
variant="dot"
badgeContent=" "
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
invisible={!comment || comment === ""}
>
<Button {...bindToggle(popupState)} color="primary">
Comments
</Button>
</Badge>
<Popper
{...bindPopper(popupState)}
transition
disablePortal
className={classes.popperContainer}
>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<Paper className={classes.contentContainer}>
<React.Fragment>
<TextField
id="comment"
name="comment"
variant="outlined"
value={comment}
placeholder={"Add any additional data here"}
multiline
rows={4}
rowsMax={10}
fullWidth
onChange={(event) =>
setComment((event.target as HTMLInputElement).value)
}
inputProps={{
"data-testid": "comment",
}}
/>
<Button
onClick={() => {
onSave(comment).then(() => popupState.close());
}}
>
Save
</Button>
</React.Fragment>
</Paper>
</Fade>
)}
</Popper>
</React.Fragment>
);
}
Example #14
Source File: TransactionItem.tsx From End-to-End-Web-Testing-with-Cypress with MIT License | 5 votes |
TransactionItem: React.FC<TransactionProps> = ({ transaction }) => {
const classes = useStyles();
const history = useHistory();
const showTransactionDetail = (transactionId: string) => {
history.push(`/transaction/${transactionId}`);
};
return (
<ListItem
data-test={`transaction-item-${transaction.id}`}
alignItems="flex-start"
onClick={() => showTransactionDetail(transaction.id)}
>
<Paper className={classes.paper} elevation={0}>
<Grid container spacing={2}>
<Grid item>
<ListItemAvatar>
<Badge
overlap="circle"
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar src={transaction.receiverAvatar} />}
>
<Avatar src={transaction.senderAvatar} />
</Badge>
</ListItemAvatar>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<TransactionTitle transaction={transaction} />
<Typography variant="body2" color="textSecondary" gutterBottom>
{transaction.description}
</Typography>
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
spacing={1}
className={classes.socialStats}
>
<Grid item>
<LikeIcon className={classes.countIcons} />
</Grid>
<Grid item>
<Typography data-test="transaction-like-count" className={classes.countText}>
{transaction.likes.length}
</Typography>
</Grid>
<Grid item>
<CommentIcon className={classes.countIcons} />
</Grid>
<Grid item>
<Typography data-test="transaction-comment-count" className={classes.countText}>
{transaction.comments.length}
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<TransactionAmount transaction={transaction} />
</Grid>
</Grid>
</Grid>
</Paper>
</ListItem>
);
}
Example #15
Source File: PlayersContainer.tsx From cards-against-formality-pwa with BSD 2-Clause "Simplified" License | 5 votes |
MobilePlayer = ({ player, isHost, isCzar, onPlayerKick, isCurrentUserHost }: any) => {
const anchorEl = useRef<any>();
const [isOpen, setIsOpen] = useState(false);
if (!player) {
return null;
}
function renderKick() {
if (isHost || !isCurrentUserHost) {
return null;
}
return <List>
<ListItem style={{ padding: 0 }}>
<Button size="small" color="secondary" onClick={() => { onPlayerKick(player?._id) }}>Kick</Button>
</ListItem>
</List>;
}
return <>
<div className={`player ${isCzar ? 'special' : ''}`} ref={anchorEl} onClick={() => setIsOpen(prev => !prev)}>
<Badge badgeContent={player.score} color="error">
{player?.username}
</Badge>
</div>
<Popover
anchorEl={anchorEl.current}
open={isHost || !isCurrentUserHost ? false : isOpen}
onClose={() => setIsOpen(false)}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
>
{renderKick()}
</Popover>
</>
}
Example #16
Source File: index.tsx From firetable with Apache License 2.0 | 5 votes |
Notification = () => {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(
null
);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
const notifications: Notification[] = [
{
title: "a",
subtitle: "a",
variant: "error",
link:
"https://console.cloud.google.com/cloud-build/builds;region=global/f7b8fd9b-eb6e-401f-a889-73c4bf75f232?project=antler-vc",
},
];
const notificationsCount = notifications.length;
return (
<>
<IconButton onClick={handleClick}>
<Badge
color={"primary"}
variant="standard"
badgeContent={notificationsCount}
>
<BellIcon />
</Badge>
</IconButton>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
>
<List>
{notifications.map((notification) => (
<ListItem>
<ListItemAvatar>
<Avatar>
<ErrorIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={notification.title}
secondary={notification.subtitle}
/>
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
))}
</List>
</Popover>
</>
);
}
Example #17
Source File: Header.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const isLanding = !!this.props.page?.landing;
var menu;
if (this.props.config?.style.templates?.menu) {
menu = (
<TemplateLiquid
template={this.props.config.style.templates.menu}
customPageSlug={this.props.pageSlug}
/>
);
} else if (this.props.config && this.props.config.layout.menu.length > 0) {
var currentTabValue = this.props.page
? this.props.page.slug
: false;
var tabs;
tabs = this.props.config.layout.menu.map(menu => {
if (!menu.pageIds || menu.pageIds.length === 0) return null;
if (menu.pageIds.length === 1) {
const page = this.props.config!.layout.pages.find(p => p.pageId === menu.pageIds[0]);
if (page === undefined) return null;
const icon = menu.icon || page.icon;
return (
<Tab
key={page.slug}
className={this.props.classes.tab}
component={Link}
to={`/${page.slug}`}
value={page.slug}
disableRipple
label={(
<>
{!!icon && (
<DynamicMuiIcon name={icon} />
)}
{this.props.t(menu.name || page.name as any)}
</>
)}
classes={{
root: this.props.classes.tabRoot,
wrapper: this.props.classes.tabWrapper,
}}
/>
);
}
const dropdownItems = menu.pageIds.map(pageId => {
const page = this.props.config!.layout.pages.find(p => p.pageId === pageId);
if (!page) {
return undefined;
}
if (this.props.page && this.props.page.pageId === page.pageId) {
currentTabValue = menu.menuId;
}
return {
name: this.props.t(page.name as any),
val: page.slug,
icon: page.icon,
};
})
.filter(notEmpty);
return (
<DropdownTab
key={menu.menuId}
className={this.props.classes.tab}
value={menu.menuId}
selectedValue={this.props.page && this.props.page.slug}
label={menu.name}
icon={!menu.icon ? undefined : (<DynamicMuiIcon name={menu.icon} />)}
links={dropdownItems}
onDropdownTabSelect={value => this.props.pageChanged(value)}
/>
);
});
menu = (
<div className={this.props.classes.menu}>
<Collapse in={!isLanding}>
<Tabs
// centered
variant='standard'
scrollButtons='off'
classes={{
flexContainer: this.props.classes.tabsFlexContainer,
indicator: this.props.classes.indicator,
}}
value={currentTabValue}
onChange={(event, value) => this.props.pageChanged(value)}
indicatorColor="primary"
textColor="primary"
// Shorten indicator size
// TabIndicatorProps={{ children: <span /> }}
>
{tabs}
</Tabs>
</Collapse>
</div>
);
}
var header;
if (this.props.config?.style.templates?.header) {
header = (
<TemplateLiquid
template={this.props.config.style.templates.header}
customPageSlug={this.props.pageSlug}
/>
);
} else {
const languageSelect = this.props.config?.langWhitelist?.langs.length === 0 ? undefined : (
<LanguageSelect noFade whitelist={this.props.config?.langWhitelist?.langs} />
);
var rightSide;
if (this.props.config && this.props.loggedInUser) {
rightSide = (
<div className={this.props.classes.actions}>
<Collapse classes={{ wrapperInner: this.props.classes.actions }} in={!isLanding}>
<NotificationButton
className={this.props.classes.actionButton}
server={this.props.server}
/>
<IconButton
className={this.props.classes.actionButton}
aria-label='Account'
component={Link}
to='/account'
>
<Badge
color='secondary'
invisible={!!this.props.loggedInUser.isExternal || !!this.props.loggedInUser.name}
variant='dot'
>
<AccountIcon fontSize='inherit' />
</Badge>
</IconButton>
</Collapse>
{languageSelect}
</div>
);
} else if (this.props.config && !this.props.loggedInUser) {
rightSide = (
<div className={this.props.classes.actions}>
<IconButton
className={this.props.classes.actionButton}
aria-label='Account'
onClick={() => this.setState({ logInOpen: true })}
>
<AccountIcon fontSize='inherit' />
</IconButton>
<LogIn
server={this.props.server}
open={this.state.logInOpen}
onClose={() => this.setState({ logInOpen: false })}
onLoggedInAndClose={() => this.setState({ logInOpen: false })}
/>
{/* {// TODO this should only show when Admin logged in, not mod
this.props.server.isModOrAdminLoggedIn() && (
<IconButton
className={this.props.classes.actionButton}
aria-label='Dashboard'
onClick={() => !windowIso.isSsr && windowIso.open(`https://${windowIso.parentDomain}/dashboard?projectId=${this.props.server.getProjectId()}`, '_self')}
>
<SettingsIcon fontSize='inherit' />
</IconButton>
)} */}
{languageSelect}
</div>
);
}
rightSide = (
<div className={this.props.classes.actionsContainer}>
{rightSide}
</div>
);
header = (
<div className={this.props.classes.headerSpacing}>
<div className={this.props.classes.header}>
<div className={this.props.classes.logoAndMenu}>
<HeaderLogo config={this.props.config} large={isLanding} />
{menu}
</div>
{rightSide}
</div>
{/* <Divider className={classNames(
this.props.classes.menuDivider,
isLanding && this.props.classes.menuDividerLanding,
)} /> */}
</div>
);
}
return (
<InViewObserver ref={this.inViewObserverRef} disabled={!this.props.settings.demoMenuAnimate}>
{header}
</InViewObserver>
);
}
Example #18
Source File: AvatarDisplay.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const userName = DisplayUserName(this.props.user);
const size = this.props.size || 25;
var avatar;
switch (this.props.user?.pic ? 'image' : this.props.type) {
default:
case 'beam':
avatar = (
<BoringAvatar
name={userName.replace(/ /g, '')}
variant='beam'
size={size}
colors={[
darken(this.props.theme.palette.primary.main, 0.6),
darken(this.props.theme.palette.primary.main, 0.3),
this.props.theme.palette.primary.main,
lighten(this.props.theme.palette.primary.main, 0.3),
lighten(this.props.theme.palette.primary.main, 0.6),
]}
/>
);
break;
case 'bauhaus':
avatar = (
<BoringAvatar
name={userName.replace(/ /g, '')}
variant='bauhaus'
size={size}
colors={[
this.props.theme.palette.primary.dark,
this.props.theme.palette.primary.light,
lighten(this.props.theme.palette.primary.main, 0.6),
lighten(this.props.theme.palette.primary.main, 0.8),
]}
/>
);
break;
case 'image':
case 'initials':
var backgroundColor;
if (!this.props.user?.pic) {
backgroundColor = DeterministicColorFromUser(this.props.user);
backgroundColor = !backgroundColor ? undefined
: (this.props.theme.palette.type === 'dark'
? darken(backgroundColor, 0.5)
: lighten(backgroundColor, 0.5));
}
avatar = (
<MuiAvatar
variant='circle'
className={classNames(this.props.classes.muiAvatar)}
style={{
width: size,
height: size,
backgroundColor: backgroundColor,
}}
alt={userName}
src={this.props.user?.pic}
>{Initial(this.props.user)}</MuiAvatar>
);
break;
}
if (this.props.user?.isMod) {
const modSize = size * 0.5;
const starSize = size * 0.6;
avatar = (
<Badge
classes={{
root: this.props.classes.backgroundColor,
badge: classNames(this.props.classes.badge, this.props.classes.backgroundColor),
}}
overlap='circle'
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
badgeContent={(
<MuiAvatar alt='Moderator' className={classNames(this.props.classes.backgroundColor)} style={{
width: modSize,
height: modSize,
fontSize: starSize,
}}>
<StarIcon className={this.props.classes.modAvatar} fontSize='inherit' color='primary' />
</MuiAvatar>
)}
>
{avatar}
</Badge>
);
}
return avatar;
}
Example #19
Source File: Menu.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const activeSlug = [this.props.activePath, ...this.props.activeSubPath].join('/');
return (
<List dense component='nav' style={{ padding: '0px' }}>
{this.props.items.map((item, index) => {
if (item.type === 'item') {
var component;
var componentProps = {};
if (item.slug !== undefined) {
component = Link;
componentProps = {
to: `/dashboard/${item.slug}`,
};
} else if (item.ext) {
component = MuiLink;
componentProps = {
href: item.ext,
target: '_blank',
};
}
const isSelected = item.slug === activeSlug;
return (
<ListItem
key={`${index}-${item.slug || item.ext || 'empty'}`}
button
disabled={item.disabled}
// selected={isSelected}
onClick={this.props.onAnyClick}
className={classNames(
this.props.classes.link,
this.props.classes.menuItem,
isSelected && this.props.classes.isSelected,
)}
component={component}
{...componentProps}
>
<ListItemText style={paddingForLevel(item.offset)} primary={(
<>
<span>{item.name}</span>
<Badge
color='primary'
variant='dot'
invisible={!item.hasNotification}
>
</Badge>
</>
)} />
</ListItem>
);
} else if (item.type === 'project') {
const activePath = !activeSlug.startsWith(item.slug) ? undefined
: activeSlug.slice(item.slug.length)
.split('/')
.filter(value => value !== '')
.map(value => /^\d+$/.test(value) ? parseInt(value) : value);
return (
<MenuPage
key={`${index}-${item.page.key}`}
overrideName={item.name}
offset={item.offset}
page={item.page}
hasUnsavedChanges={item.hasUnsavedChanges}
activePath={activePath}
slug={item.slug}
onAnyClick={this.props.onAnyClick}
/>
);
} else if (item.type === 'heading') {
return (
<ListItem
key={`${index}-${item.text}`}
disabled
className={this.props.classes.menuItem}
>
<ListItemText style={paddingForLevel(item.offset)} primary={(
<>
{item.text}
<Badge
color='primary'
variant='dot'
invisible={!item.hasUnsavedChanges}
>
</Badge>
</>
)} />
</ListItem>
);
} else {
return null;
}
})}
</List>
);
}
Example #20
Source File: Menu.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const hasChildren = this.props.page.getChildren().pages.filter(p => !p.hide).some(p => !!p.value)
|| this.props.page.getChildren().groups.filter(p => !p.hide).some(p => !!p.value);
const autoExpandLevel = 0; // Disabled for now
const expandedDontShow = !hasChildren || this.props.page.path.length < autoExpandLevel;
const expanded = expandedDontShow
|| (this.state.expanded !== undefined
? this.state.expanded
: this.isSelectedOrParent(this.props.page.path));
const padding = paddingForLevel(this.props.offset || 0);
const color = this.props.page.getColor();
const { classes, ...menuProps } = this.props;
const isSelected = this.isSelected(this.props.page.path);
return (
<Collapse in={this.props.page.required || this.props.page.value === true} timeout="auto" mountOnEnter unmountOnExit>
<ListItem
// selected={isSelected}
className={classNames(
this.props.classes.menuItem,
isSelected && this.props.classes.isSelected,
)}
button
component={Link}
to={`/dashboard/${[this.props.slug, ...this.props.page.path].join('/')}`}
onClick={() => {
this.props.onAnyClick && this.props.onAnyClick();
if (!this.state.expanded) {
this.setState({ expanded: true });
}
}}
>
<ListItemText style={padding} primary={(
<>
<span className={this.props.classes.text} style={{ color }}>
{!expandedDontShow && (
<ExpandIcon
IconButtonProps={{
className: this.props.classes.expandButton,
onClick: e => {
e.preventDefault();
e.stopPropagation();
this.setState({ expanded: !this.state.expanded });
},
}}
IconProps={{
fontSize: 'inherit',
}}
expanded={expanded}
/>
)}
{this.props.overrideName !== undefined ? this.props.overrideName : this.props.t(this.props.page.getDynamicName() as any)}
</span>
{this.props.hasUnsavedChanges && (
<Badge
variant='dot'
color='primary'
>
</Badge>
)}
</>
)} />
</ListItem>
<Collapse in={expanded} timeout="auto" mountOnEnter unmountOnExit>
{this.props.page.getChildren().all
.map(child => {
if (child.hide) return null;
switch (child.type) {
case ConfigEditor.PageType:
return (<MenuPage
{...menuProps}
key={child.key}
offset={(this.props.offset || 0) + 1}
overrideName={undefined}
hasUnsavedChanges={false}
page={child}
/>);
case ConfigEditor.PageGroupType:
return (<MenuPageGroup
{...menuProps}
key={child.key}
offset={(this.props.offset || 0) + 1}
pageGroup={child}
/>);
default:
return null;
}
})}
</Collapse>
</Collapse>
);
}
Example #21
Source File: index.tsx From uno-game with MIT License | 4 votes |
Chat: React.FC = () => {
const classes = useStyles()
const socket = useSocket()
const socketStore = useSocketStore()
const backButton = useBackButton()
const [drawerOpened, setDrawerOpened] = useState(false)
const [content, setContent] = useState("")
const [notSeenMessagesCount, setNotSeenMessagesCount] = useState(0)
const messageContainerRef = useRef<HTMLElement>(null)
const chatId = socketStore.game?.chatId
const chat = socket.getChat(chatId)
const scrollChatToBottom = () => {
if (messageContainerRef.current) {
messageContainerRef.current.scroll(0, messageContainerRef.current?.scrollHeight)
}
}
const resetNotSeenMessagesCount = () => {
setNotSeenMessagesCount(0)
}
const handleCloseChat = () => {
resetNotSeenMessagesCount()
setDrawerOpened(false)
}
const handleOpenChat = () => {
setDrawerOpened(true)
/**
* Workaround to delay this function calling,
* in order to make it to be called after the drawer opens
*/
setTimeout(() => scrollChatToBottom(), 0)
if (DeviceUtil.isMobile) {
backButton.handleBackButton(
() => handleCloseChat(),
)
}
}
const handleSendChatMessage = () => {
if (!content || !chatId) {
return
}
socket.sendChatMessage(chatId, content)
setContent("")
}
const increaseNotSeenMessagesCount = (amount: number) => {
setNotSeenMessagesCount(lastState => lastState + amount)
}
const handleNewChatMessage = () => {
scrollChatToBottom()
increaseNotSeenMessagesCount(+1)
}
const onNewChatMessage = () => {
socket.onNewChatMessage(() => handleNewChatMessage())
}
const handleChangeContent = (value: string) => {
setContent(value)
}
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault()
handleSendChatMessage()
}
const onInputFocus = () => {
backButton.setActive(false)
}
const onInputBlur = () => {
backButton.setActive(true)
}
useDidMount(() => {
onNewChatMessage()
})
return (
<>
{chat && (
<Grid
className={classes.openChatButtonContainer}
>
<IconButton
onClick={handleOpenChat}
className={classes.chatIcon}
>
<Badge
badgeContent={notSeenMessagesCount}
color="primary"
>
<ChatIcon />
</Badge>
</IconButton>
</Grid>
)}
<Drawer
open={drawerOpened}
onClose={handleCloseChat}
anchor="right"
PaperProps={{
className: classes.drawerPaper,
}}
className={classes.drawer}
>
<Grid
container
alignItems="center"
className={classes.drawerHeaderContainer}
>
<IconButton
onClick={handleCloseChat}
size="medium"
color="primary"
>
<GoBackIcon />
</IconButton>
<Typography
variant="h6"
>
Chat
</Typography>
</Grid>
<Grid
className={classes.drawerBodyContainer}
innerRef={messageContainerRef}
>
{chat?.messages?.map((message, index) => (
<React.Fragment key={index}>
<Typography
variant="body1"
>
<b>{message.playerName}:</b> {message.content}
</Typography>
<Divider orientation="horizontal" size={1} />
</React.Fragment>
))}
</Grid>
<Grid
component="form"
container
alignItems="center"
className={classes.drawerFooterContainer}
onSubmit={handleSubmit}
>
<TextField
value={content}
onChange={({ target }) => handleChangeContent(target.value)}
placeholder="Type something..."
variant="outlined"
className={classes.messageInput}
size="small"
onFocus={() => onInputFocus()}
onBlur={() => onInputBlur()}
/>
<IconButton
size="medium"
onClick={handleSendChatMessage}
color="primary"
>
<SendIcon />
</IconButton>
</Grid>
</Drawer>
</>
)
}
Example #22
Source File: UserMenu.tsx From firetable with Apache License 2.0 | 4 votes |
export default function UserMenu(props: IconButtonProps) {
const classes = useStyles();
const anchorEl = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState(false);
const [themeSubMenu, setThemeSubMenu] = useState<EventTarget | null>(null);
const [latestUpdate] = useLatestUpdateState<null | Record<string, any>>();
const {
currentUser,
userDoc,
theme,
themeOverridden,
setTheme,
setThemeOverridden,
} = useAppContext();
if (!currentUser || !userDoc || !userDoc?.state?.doc)
return <div className={classes.spacer} />;
const displayName = userDoc?.state?.doc?.user?.displayName;
const avatarUrl = userDoc?.state?.doc?.user?.photoURL;
const email = userDoc?.state?.doc?.user?.email;
const avatar = avatarUrl ? (
<Avatar src={avatarUrl} className={classes.avatar} />
) : (
<AccountCircleIcon color="secondary" />
);
const changeTheme = (option: "system" | "light" | "dark") => {
switch (option) {
case "system":
setThemeOverridden(false);
return;
case "light":
setTheme("light");
break;
case "dark":
setTheme("dark");
break;
default:
break;
}
setThemeOverridden(true);
};
return (
<>
<IconButton
aria-label="Open user menu"
aria-controls="user-menu"
aria-haspopup="true"
edge="end"
{...props}
ref={anchorEl}
onClick={() => setOpen(true)}
className={classes.iconButton}
>
{latestUpdate?.tag_name > "v" + meta.version ? (
<Badge color="primary" overlap="circular" variant="dot">
{avatar}
</Badge>
) : (
avatar
)}
</IconButton>
<Menu
anchorEl={anchorEl.current}
id="user-menu"
keepMounted
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
getContentAnchorEl={null}
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={open}
onClose={() => setOpen(false)}
classes={{ paper: classes.paper }}
>
<MenuItem
component="a"
href={`https://console.firebase.google.com/project/${projectId}/firestore/data/~2F_FT_USERS~2F${currentUser.uid}`}
target="_blank"
rel="noopener"
>
<ListItemAvatar>{avatar}</ListItemAvatar>
<ListItemText primary={displayName} secondary={email} />
</MenuItem>
<Divider className={classes.divider} />
<MenuItem onClick={(e) => setThemeSubMenu(e.target)}>
Theme
<ListItemSecondaryAction className={classes.secondaryAction}>
<ArrowRightIcon className={classes.secondaryIcon} />
</ListItemSecondaryAction>
</MenuItem>
{themeSubMenu && (
<Menu
anchorEl={themeSubMenu as any}
id="theme-sub-menu"
anchorOrigin={{ vertical: "top", horizontal: "left" }}
getContentAnchorEl={null}
transformOrigin={{ vertical: "top", horizontal: "right" }}
open
onClose={() => setThemeSubMenu(null)}
classes={{ paper: classes.subMenu }}
>
<MenuItem onClick={() => changeTheme("system")}>
<ListItemIcon>{!themeOverridden && <CheckIcon />}</ListItemIcon>
System
</MenuItem>
<MenuItem onClick={() => changeTheme("light")}>
<ListItemIcon>
{themeOverridden && theme === "light" && <CheckIcon />}
</ListItemIcon>
Light
</MenuItem>
<MenuItem onClick={() => changeTheme("dark")}>
<ListItemIcon>
{themeOverridden && theme === "dark" && <CheckIcon />}
</ListItemIcon>
Dark
</MenuItem>
</Menu>
)}
<MenuItem component={Link} to={routes.signOut}>
Sign out
</MenuItem>
<Divider className={classes.divider} />
<UpdateChecker />
</Menu>
</>
);
}