@mui/material#ListItemAvatar TypeScript Examples
The following examples show how to use
@mui/material#ListItemAvatar.
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: AccountClearingListEntry.tsx From abrechnung with GNU Affero General Public License v3.0 | 6 votes |
export default function AccountClearingListEntry({ group, account, accountID }) {
const balances = useRecoilValue(accountBalances(group.id));
return (
<ListItemLink to={`/groups/${group.id}/accounts/${account.id}`}>
<ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
<Tooltip title="Clearing Account">
<ClearingAccountIcon color="primary" />
</Tooltip>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="body1" component="span">
{account.name}
</Typography>
}
secondary={account.description}
/>
<ListItemText>
<Typography align="right" variant="body2">
<Typography
component="span"
sx={{
color: (theme) => balanceColor(balances[account.id].clearingResolution[accountID], theme),
}}
>
{balances[account.id].clearingResolution[accountID].toFixed(2)} {group.currency_symbol}
</Typography>
<br />
<Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
last changed: {DateTime.fromISO(account.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
</Typography>
</Typography>
</ListItemText>
</ListItemLink>
);
}
Example #2
Source File: FileList.tsx From frontend with MIT License | 6 votes |
function FileList({ files, onDelete }: Props) {
return (
<List dense>
{files.map((file, key) => (
<ListItem
key={key}
secondaryAction={
<IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
<Delete />
</IconButton>
}>
<ListItemAvatar>
<Avatar>
<UploadFile />
</Avatar>
</ListItemAvatar>
<ListItemText primary={file.type} />
<ListItemText primary={file.name} />
</ListItem>
))}
</List>
)
}
Example #3
Source File: AccountTransactionListEntry.tsx From abrechnung with GNU Affero General Public License v3.0 | 5 votes |
export default function AccountTransactionListEntry({ group, transaction, accountID }) {
return (
<ListItemLink to={`/groups/${group.id}/transactions/${transaction.id}`}>
<ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
{transaction.type === "purchase" ? (
<Tooltip title="Purchase">
<PurchaseIcon color="primary" />
</Tooltip>
) : transaction.type === "transfer" ? (
<Tooltip title="Money Transfer">
<TransferIcon color="primary" />
</Tooltip>
) : (
<Tooltip title="Unknown Transaction Type">
<HelpOutline color="primary" />
</Tooltip>
)}
</ListItemAvatar>
<ListItemText
primary={
<>
{transaction.is_wip && (
<Chip color="info" variant="outlined" label="WIP" size="small" sx={{ mr: 3 }} />
)}
<Typography variant="body1" component="span">
{transaction.description}
</Typography>
</>
}
secondary={DateTime.fromISO(transaction.billed_at).toLocaleString(DateTime.DATE_FULL)}
/>
<ListItemText>
<Typography align="right" variant="body2">
<Typography
component="span"
sx={{ color: (theme) => balanceColor(transaction.account_balances[accountID].total, theme) }}
>
{transaction.account_balances[accountID].total.toFixed(2)} {group.currency_symbol}
</Typography>
<br />
<Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
last changed:{" "}
{DateTime.fromISO(transaction.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
</Typography>
</Typography>
</ListItemText>
</ListItemLink>
);
}
Example #4
Source File: TransactionListEntry.tsx From abrechnung with GNU Affero General Public License v3.0 | 5 votes |
export function TransactionListEntry({ group, transaction }) {
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const accountNamesFromShares = (shares) => {
return shares.map((s) => accounts.find((a) => a.id === parseInt(s))?.name).join(", ");
};
return (
<>
<ListItemLink to={`/groups/${group.id}/transactions/${transaction.id}`}>
<ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
{transaction.type === "purchase" ? (
<Tooltip title="Purchase">
<PurchaseIcon color="primary" />
</Tooltip>
) : transaction.type === "transfer" ? (
<Tooltip title="Money Transfer">
<TransferIcon color="primary" />
</Tooltip>
) : (
<Tooltip title="Unknown Transaction Type">
<HelpOutline color="primary" />
</Tooltip>
)}
</ListItemAvatar>
<ListItemText
primary={
<>
{transaction.is_wip && (
<Chip color="info" variant="outlined" label="WIP" size="small" sx={{ mr: 1 }} />
)}
<Typography variant="body1" component="span">
{transaction.description}
</Typography>
</>
}
secondary={
<>
<Typography variant="body2" component="span" sx={{ color: "text.primary" }}>
by {accountNamesFromShares(Object.keys(transaction.creditor_shares))}, for{" "}
{accountNamesFromShares(Object.keys(transaction.debitor_shares))}
</Typography>
<br />
{DateTime.fromISO(transaction.billed_at).toLocaleString(DateTime.DATE_FULL)}
</>
}
/>
<ListItemText>
<Typography align="right" variant="body2">
{transaction.value.toFixed(2)} {transaction.currency_symbol}
<br />
<Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
last changed:{" "}
{DateTime.fromISO(transaction.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
</Typography>
</Typography>
</ListItemText>
</ListItemLink>
<Divider sx={{ display: { lg: "none" } }} component="li" />
</>
);
}
Example #5
Source File: ListConversation.tsx From airmessage-web with Apache License 2.0 | 5 votes |
export default function ListConversation(props: {conversation: Conversation, selected?: boolean, highlighted?: boolean, onSelected: () => void, flippedProps?: Record<string, unknown>}) {
//Getting the conversation title
const [title, setConversationTitle] = useState(ConversationUtils.getFallbackTitle(props.conversation));
useEffect(() => {
//Updating the conversation's name if it has one
if(props.conversation.name) {
setConversationTitle(props.conversation.name);
return;
}
//Building the conversation title
ConversationUtils.getMemberTitle(props.conversation.members).then((title) => setConversationTitle(title));
}, [props.conversation.name, props.conversation.members]);
const primaryStyle: TypographyProps = props.highlighted ? {
color: "primary",
sx: {
fontSize: "1rem",
fontWeight: "bold"
}
} : {
sx: {
fontSize: "1rem",
fontWeight: 500
}
};
const secondaryStyle: TypographyProps = props.highlighted ? {
color: "textPrimary",
sx: {
fontWeight: "bold"
}
} : {};
return (
<div className={styles.containerOuter} {...props.flippedProps}>
<ListItemButton
className={styles.containerInner}
key={props.conversation.localID}
onClick={props.onSelected}
selected={props.selected}
sx={{
"&&.Mui-selected, &&.Mui-selected:hover": {
backgroundColor: "action.selected"
},
"&&:hover": {
backgroundColor: "action.hover"
}
}}>
<ListItemAvatar>
<GroupAvatar members={props.conversation.members} />
</ListItemAvatar>
<ListItemText className={styles.textPreview} primary={title} primaryTypographyProps={primaryStyle} secondary={previewString(props.conversation.preview)} secondaryTypographyProps={secondaryStyle} />
<Typography className={styles.textTime} variant="body2" color="textSecondary">{getLastUpdateStatusTime(props.conversation.preview.date)}</Typography>
</ListItemButton>
</div>
);
}
Example #6
Source File: TLSCertificate.tsx From console with GNU Affero General Public License v3.0 | 5 votes |
TLSCertificate = ({
classes,
certificateInfo,
onDelete = () => {},
}: ITLSCertificate) => {
const certificates = certificateInfo.domains || [];
return (
<Chip
key={certificateInfo.name}
variant="outlined"
color="primary"
className={classes.certificateWrapper}
label={
<Container>
<Grid item xs={1} className={classes.certificateIcon}>
<CertificateIcon />
</Grid>
<Grid item xs={11} className={classes.certificateInfo}>
<Typography variant="subtitle1" display="block" gutterBottom>
{certificateInfo.name}
</Typography>
<Box className={classes.certificateExpiry}>
<EventBusyIcon color="inherit" fontSize="small" />
<span className={"label"}>Expiry: </span>
<span>
<Moment format="YYYY/MM/DD">{certificateInfo.expiry}</Moment>
</span>
</Box>
<Divider />
<br />
<Box className={classes.certificateDomains}>
<span className="label">{`${certificates.length} Domain (s):`}</span>
</Box>
<List className={classes.certificatesList}>
{certificates.map((dom) => (
<ListItem className={classes.certificatesListItem}>
<ListItemAvatar>
<LanguageIcon />
</ListItemAvatar>
<ListItemText primary={dom} />
</ListItem>
))}
</List>
</Grid>
</Container>
}
onDelete={onDelete}
/>
);
}
Example #7
Source File: Loading.tsx From NekoMaid with MIT License | 5 votes |
LoadingList: React.FC<{ count?: number }> = ({ count = 3 }) => <>{Array.from({ length: count }, (_, i) => <ListItem key={i}>
<ListItemAvatar><Skeleton animation='wave' variant='circular' width={40} height={40} /></ListItemAvatar>
<ListItemText primary={<Skeleton animation='wave' />} />
</ListItem>)}</>
Example #8
Source File: Dashboard.tsx From NekoMaid with MIT License | 5 votes |
Players: React.FC<{ players?: CurrentStatus['players'] }> = React.memo(({ players }) => {
const his = useHistory()
const plugin = usePlugin()
const globalData = useGlobalData()
const [page, setPage] = useState(1)
const [id, update] = useState(0)
return <Card>
<CardHeader title={lang.dashboard.onlinePlayers} />
<Divider />
<CardContent>
{players?.length === 0
? <Empty />
: <>
<List sx={{ paddingTop: 0 }}>
{players
? players.slice((page - 1) * 8, page * 8).map(p => {
const name = typeof p === 'string' ? p : p.name
return <Tooltip key={name} title={'IP: ' + ((p as any).ip || lang.unknown)}>
<ListItem
secondaryAction={<>
<IconButton
edge='end'
size='small'
onClick={() => dialog(lang.dashboard.confirmKick(<span className='bold'>{name}</span>), lang.reason)
.then(it => it != null && plugin.emit('dashboard:kick', (res: boolean) => {
action(res)
if (!players) return
players.splice(players.indexOf(it!), 1)
update(id + 1)
}, name, it || null))
}
><ExitToApp /></IconButton>
<IconButton edge='end' onClick={() => his.push('/NekoMaid/playerList/' + name)} size='small'><MoreHoriz /></IconButton>
</>
}
>
<ListItemAvatar>
<Avatar
src={getSkin(globalData, name, true)}
imgProps={{ crossOrigin: 'anonymous', onClick () { his.push('/NekoMaid/playerList/' + name) }, style: { width: 40, height: 40 } }}
sx={{ cursor: 'pointer' }}
variant='rounded'
/>
</ListItemAvatar>
<ListItemText primary={name} />
</ListItem>
</Tooltip>
})
: <LoadingList />
}
</List>
{players && <Pagination
page={page}
onChange={(_, it) => setPage(it)}
count={Math.max(Math.ceil(players.length / 8), 1)}
sx={{ display: 'flex', justifyContent: 'flex-end' }}
/>}
</>}
</CardContent>
</Card>
})
Example #9
Source File: FileList.tsx From frontend with MIT License | 5 votes |
function FileList({ files, onDelete, onSetFileRole, filesRole = [] }: Props) {
const setFileRole = (file: File) => {
return (event: SelectChangeEvent<CampaignFileRole>) => {
if (Object.values(CampaignFileRole).includes(event.target.value as CampaignFileRole)) {
onSetFileRole(file, event.target.value as CampaignFileRole)
}
}
}
return (
<List dense>
{files.map((file, key) => (
<ListItem
key={key}
secondaryAction={
<IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
<Delete />
</IconButton>
}>
<ListItemAvatar>
<Avatar>
<UploadFile />
</Avatar>
</ListItemAvatar>
<ListItemText primary={file.type} />
<ListItemText primary={file.name} />
<FormControl>
<InputLabel id="choose-type-label">{'Избери роля'}</InputLabel>
<Select<CampaignFileRole>
id="choose-type"
label="Избери роля"
labelId="choose-type-label"
value={
filesRole.find((f) => f.file === file.name)?.role ?? CampaignFileRole.background
}
onChange={setFileRole(file)}>
{Object.values(CampaignFileRole).map((role) => (
<MenuItem key={role} value={role}>
{role}
</MenuItem>
))}
</Select>
</FormControl>
</ListItem>
))}
</List>
)
}
Example #10
Source File: IrregularityFile.tsx From frontend with MIT License | 5 votes |
export default function IrregularityFile({ file, irregularityId }: Props) {
const { t } = useTranslation('irregularity')
const queryClient = useQueryClient()
const router = useRouter()
const mutation = useMutation<AxiosResponse<IrregularityFileResponse>, AxiosError<ApiErrors>>({
mutationFn: deleteIrregularityFile(file.id),
onError: () => AlertStore.show(t('admin.alerts.error'), 'error'),
onSuccess: () => {
AlertStore.show(t('admin.alerts.delete-file'), 'success')
queryClient.invalidateQueries(endpoints.irregularity.viewIrregularity(irregularityId).url)
router.push(routes.admin.irregularity.index)
},
})
const deleteFileHandler = () => {
mutation.mutate()
}
return (
<ListItem key={file.id}>
<ListItemAvatar>
<Avatar>
<FilePresentIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={file.filename} />
<></>
<Tooltip
title={
'Note: This link is public on the API side! Need to correct before official release!'
}>
<Button>
{/* TODO: to be discussed. Tracked in issue: https://github.com/podkrepi-bg/frontend/issues/811 */}
<a style={{ color: 'red' }} href={API_URL + `/irregularity-file/${file.id}`}>
{t('admin.cta.download') + '*'}
</a>
</Button>
</Tooltip>
<Button onClick={deleteFileHandler}>{t('admin.cta.delete')}</Button>
</ListItem>
)
}
Example #11
Source File: Config.tsx From NekoMaid with MIT License | 4 votes |
configs.push({
title: lang.config.serverConfig,
component () {
const plugin = usePlugin()
const globalData = useGlobalData()
const [flag, update] = useState(0)
const [info, setInfo] = useState<Record<string, string>>({ })
const [open, setOpen] = useState(false)
const [canGetData, setCanGetData] = useState(true)
const [loading, setLoading] = useState(false)
const setValue = (field: string, value: any, isGlobal = true) => {
plugin.emit('server:set', field, value)
success()
if (isGlobal) {
(globalData as any)[field] = value
update(flag + 1)
location.reload()
}
}
const createEditButtom = (field: string, isGlobal?: boolean, isInt = true) => <IconButton
onClick={() => dialog(
{
content: lang.inputValue,
input: isInt
? {
error: true,
type: 'number',
helperText: lang.invalidValue,
validator: (it: string) => /^\d+$/.test(it) && +it >= 0
}
: { }
}).then(res => res != null && setValue(field, isInt ? parseInt(res as any) : (res || null), isGlobal))}
><Edit /></IconButton>
const infoElm: JSX.Element[] = []
for (const key in info) {
const name = (lang.config as any)[key]
infoElm.push(<ListItem key={key} sx={{ pl: 4 }}>
<ListItemText
primary={key === 'isAikarFlags' ? <Link href='https://mcflags.emc.gs' target='_blank' rel='noopener'>{name}</Link> : name}
secondary={info[key].toString()}
/>
</ListItem>)
}
return <List>
<CircularLoading loading={loading} />
<ListItem secondaryAction={globalData.canSetMaxPlayers
? createEditButtom('maxPlayers')
: undefined}>
<ListItemText primary={lang.config.maxPlayers + ': ' + globalData.maxPlayers} />
</ListItem>
<ListItem secondaryAction={createEditButtom('spawnRadius')}>
<ListItemText primary={lang.config.spawnRadius + ': ' + globalData.spawnRadius} />
</ListItem>
<ListItem secondaryAction={createEditButtom('motd', false, false)}>
<ListItemText primary={lang.config.motd} />
</ListItem>
<ListItem secondaryAction={<Switch checked={globalData.hasWhitelist} onChange={e => setValue('hasWhitelist', e.target.checked)} />}>
<ListItemText primary={lang.config.whitelist} />
</ListItem>
{canGetData && <>
<ListItemButton onClick={() => {
if (infoElm.length) setOpen(!open)
else {
setLoading(true)
plugin.emit('server:fetchInfo', (data: any) => {
setLoading(false)
if (!data) {
failed(lang.unsupported)
setCanGetData(false)
return
}
setInfo(data)
setOpen(true)
})
}
}}>
<ListItemIcon><Equalizer /></ListItemIcon>
<ListItemText primary={lang.info} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout='auto' unmountOnExit>
<List component='div' dense disablePadding>{infoElm}</List>
</Collapse>
</>}
</List>
}
},
{
title: lang.history,
component () {
const [cur, update] = useState(0)
const list: ServerRecord[] = JSON.parse(localStorage.getItem('NekoMaid:servers') || '[]')
return <List>
{list.sort((a, b) => b.time - a.time).map(it => {
const i = it.address.indexOf('?')
return <ListItem
disablePadding
key={it.address}
secondaryAction={<IconButton edge='end' size='small' onClick={() => {
localStorage.setItem('NekoMaid:servers', JSON.stringify(list.filter(s => s.address !== it.address)))
success()
update(cur + 1)
}}><Delete /></IconButton>}
>
<ListItemButton onClick={() => {
location.hash = ''
location.search = it.address
}} dense>
<ListItemAvatar><Avatar src={it.icon} variant='rounded'><HelpOutline /></Avatar></ListItemAvatar>
<ListItemText primary={<Tooltip title={it.address.slice(i + 1)}>
<span>{it.address.slice(0, i)}</span></Tooltip>} secondary={dayjs(it.time).fromNow()} />
</ListItemButton>
</ListItem>
})}
</List>
}
},
{
title: lang.config.theme,
component () {
const color = localStorage.getItem('NekoMaid:color') || 'blue'
return <CardContent sx={{ textAlign: 'center' }}>
<Box>
<ToggleButtonGroup exclusive value={localStorage.getItem('NekoMaid:colorMode') || ''} onChange={(_, it) => {
localStorage.setItem('NekoMaid:colorMode', it)
location.reload()
}}>
<ToggleButton value='light'><Brightness7 /> {lang.config.light}</ToggleButton>
<ToggleButton value=''><SettingsBrightness /> {lang.config.system}</ToggleButton>
<ToggleButton value='dark'><Brightness4 /> {lang.config.dark}</ToggleButton>
</ToggleButtonGroup>
</Box>
<Paper sx={{ marginTop: 2, width: '176px', overflow: 'hidden', display: 'inline-block' }}>
{Object.keys(colors).slice(1, 17).map((key, i) => {
const checked = color === key
const elm = <Box
key={key}
onClick={() => {
localStorage.setItem('NekoMaid:color', key)
location.reload()
}}
sx={{
backgroundColor: (colors as any)[key][600],
width: '44px',
height: '44px',
display: 'inline-block',
cursor: 'pointer'
}}
><Check htmlColor='white' sx={{ top: '10px', position: 'relative', opacity: checked ? 1 : 0 }} /></Box>
return (i + 1) % 4 === 0 ? <React.Fragment key={key}>{elm}<br /></React.Fragment> : elm
})}
</Paper>
</CardContent>
}
})