@mui/material#Collapse TypeScript Examples
The following examples show how to use
@mui/material#Collapse.
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: GroupFilter.tsx From Tachidesk-WebUI with Mozilla Public License 2.0 | 6 votes |
export default function GroupFilter(props: Props) {
const {
state,
name,
position,
updateFilterValue,
update,
} = props;
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<>
<ListItemButton onClick={handleClick}>
<ListItemText primary={name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open}>
<List disablePadding>
<Options
sourceFilter={state}
group={position}
updateFilterValue={updateFilterValue}
update={update}
/>
</List>
</Collapse>
</>
);
}
Example #2
Source File: ErrorAlert.tsx From mui-toolpad with MIT License | 6 votes |
export default function ErrorAlert({ error }: ErrorAlertProps) {
const message: string =
typeof (error as any)?.message === 'string' ? (error as any).message : String(error);
const stack: string | null =
typeof (error as any)?.stack === 'string' ? (error as any).stack : null;
const [expanded, setExpanded] = React.useState(false);
const toggleExpanded = React.useCallback(() => setExpanded((actual) => !actual), []);
return (
<Alert
severity="error"
sx={{
// The content of the Alert doesn't overflow nicely
// TODO: does this need to go in core?
'& .MuiAlert-message': { minWidth: 0 },
}}
action={
stack ? (
<IconButton color="inherit" onClick={toggleExpanded}>
{expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</IconButton>
) : null
}
>
<AlertTitle>{message}</AlertTitle>
<Collapse in={expanded}>
<Box sx={{ overflow: 'auto' }}>
<pre>{stack}</pre>
</Box>
</Collapse>
</Alert>
);
}
Example #3
Source File: index.tsx From genshin-optimizer with MIT License | 6 votes |
function FeatureCard({ image, title, content, t }) {
const [expanded, setExpanded] = useState(false);
return <CardLight >
<CardContent sx={{ p: 1, pb: 0 }}>
<Box component="img" src={image} alt="test" sx={{ width: "100%", height: "auto" }} />
</CardContent>
<CardHeader
action={
<ExpandButton
expand={expanded}
onClick={() => setExpanded(!expanded)}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMore />
</ExpandButton>
}
titleTypographyProps={{ variant: "subtitle1" }}
title={title(t)}
/>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent sx={{ pt: 0 }}>
{content(t)}
</CardContent>
</Collapse>
</CardLight >
}
Example #4
Source File: index.tsx From genshin-optimizer with MIT License | 6 votes |
function FormulaCalcCard() {
const { t } = useTranslation("page_character")
const [expanded, setexpanded] = useState(false)
const toggle = useCallback(() => setexpanded(!expanded), [setexpanded, expanded])
return <CardLight>
<CardContent sx={{ display: "flex", gap: 1 }}>
<Grid container spacing={1}>
<Grid item><HitModeToggle size="small" /></Grid>
<Grid item><InfusionAuraDropdown /></Grid>
<Grid item><ReactionToggle size="small" /></Grid>
</Grid>
<Box display="flex" gap={1} >
<Box>
<Typography variant='subtitle2' >{t("formulas")} {"&"}</Typography>
<Typography variant='subtitle2' >{t("calculations")}</Typography>
</Box>
<ExpandButton
expand={expanded}
onClick={toggle}
aria-expanded={expanded}
aria-label="show more"
size="small"
sx={{ p: 0 }}
>
<ExpandMore />
</ExpandButton>
</Box>
</CardContent>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent sx={{ pt: 0 }}>
<CalculationDisplay />
</CardContent>
</Collapse>
</CardLight>
}
Example #5
Source File: Collapsible.tsx From GTAV-NativeDB with MIT License | 6 votes |
Collapsible: FunctionComponent<CollapsibleProps> = ({ children, label, variant, fullWidth }) => {
const [open, setOpen] = useState(false)
const toggle = useCallback(() => {
setOpen(!open)
}, [open, setOpen])
return (
<Fragment>
<Button
variant={variant}
fullWidth={fullWidth}
onClick={toggle}
>
{label}
</Button>
<Collapse in={open}>
{children}
</Collapse>
</Fragment>
)
}
Example #6
Source File: ExpandableListItem.tsx From frontend with MIT License | 6 votes |
ExpandableListItem = ({ header, content }: Props) => {
const [open, setOpen] = useState(false)
return (
<List
sx={{
my: 0,
mx: { xs: 0, md: 3 },
cursor: 'pointer',
}}>
<Paper elevation={1} sx={{ borderRadius: 2 }}>
<Box
sx={{ display: 'flex', alignItems: 'center', px: 3, py: 1 }}
onClick={() => setOpen(!open)}>
<ListItemText
primary={header}
primaryTypographyProps={{
variant: 'subtitle1',
color: `${withAccentColor(open)}`,
}}
/>
{open ? (
<ExpandLess sx={{ color: `${withAccentColor(open)}` }} />
) : (
<ExpandMore sx={{ color: `${withAccentColor(open)}` }} />
)}
</Box>
<Collapse in={open}>
<List>
<Box sx={{ pl: { xs: 3, md: 6 }, pb: 2, pr: 2 }}>{content}</Box>
</List>
</Collapse>
</Paper>
</List>
)
}
Example #7
Source File: CategoryItem.tsx From Cromwell with MIT License | 6 votes |
function TransitionComponent(props: TransitionProps & { children: React.ReactNode }) {
const style = useSpring({
from: { opacity: 0, transform: 'translate3d(20px,0,0)' },
to: { opacity: props.in ? 1 : 0, transform: `translate3d(${props.in ? 0 : 20}px,0,0)` },
});
return (
<animated.div style={style}>
<Collapse {...props} />
</animated.div>
);
}
Example #8
Source File: Settings.tsx From Cromwell with MIT License | 5 votes |
private makeCategory = (props: {
title: string;
component: (props: TTabProps) => JSX.Element;
icon: JSX.Element;
link?: string;
}) => {
const isExpanded = !!this.state.expandedItems[props.title];
return (
<div className={styles.category} key={props.title}>
<div className={styles.categoryHeaderWrapper}
onClick={() => this.setState(prevState => {
return {
expandedItems: {
...prevState.expandedItems,
[props.title]: !prevState.expandedItems[props.title],
}
}
})}
>
<div className={styles.categoryLeft}>
<IconButton
className={clsx(styles.expand, {
[styles.expandOpen]: isExpanded,
})}
aria-expanded={isExpanded}
>
<ExpandMoreIcon />
</IconButton>
<div className={styles.categoryIcon}>
{props.icon}
</div>
<p className={styles.categoryTitle}>{props.title}</p>
</div>
<div>
{props.link && (
<Tooltip title="Documentation">
<IconButton
onClick={() => window.open(props.link, '_blank')}>
<HelpOutlineIcon />
</IconButton>
</Tooltip>
)}
</div>
</div>
<Collapse in={isExpanded} timeout="auto" unmountOnExit>
<div className={styles.categoryContent}>
<props.component
settings={this.state?.settings}
handleTextFieldChange={this.handleTextFieldChange}
changeSettings={this.changeSettings}
/>
</div>
</Collapse>
</div >
)
}
Example #9
Source File: WalletDialog.tsx From wallet-adapter with Apache License 2.0 | 5 votes |
WalletDialog: FC<WalletDialogProps> = ({
title = 'Select your wallet',
featuredWallets = 3,
onClose,
...props
}) => {
const { wallets, select } = useWallet();
const { open, setOpen } = useWalletDialog();
const [expanded, setExpanded] = useState(false);
const [featured, more] = useMemo(
() => [wallets.slice(0, featuredWallets), wallets.slice(featuredWallets)],
[wallets, featuredWallets]
);
const handleClose = useCallback(
(event: SyntheticEvent, reason?: 'backdropClick' | 'escapeKeyDown') => {
if (onClose) onClose(event, reason!);
if (!event.defaultPrevented) setOpen(false);
},
[setOpen, onClose]
);
const handleWalletClick = useCallback(
(event: SyntheticEvent, walletName: WalletName) => {
select(walletName);
handleClose(event);
},
[select, handleClose]
);
const handleExpandClick = useCallback(() => setExpanded(!expanded), [setExpanded, expanded]);
return (
<RootDialog open={open} onClose={handleClose} {...props}>
<DialogTitle>
{title}
<IconButton onClick={handleClose} size="large">
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
<List>
{featured.map((wallet) => (
<WalletListItem
key={wallet.adapter.name}
onClick={(event) => handleWalletClick(event, wallet.adapter.name)}
wallet={wallet}
/>
))}
{more.length ? (
<>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<List>
{more.map((wallet) => (
<WalletListItem
key={wallet.adapter.name}
onClick={(event) => handleWalletClick(event, wallet.adapter.name)}
wallet={wallet}
/>
))}
</List>
</Collapse>
<ListItem>
<Button onClick={handleExpandClick}>
{expanded ? 'Less' : 'More'} options
{expanded ? <CollapseIcon /> : <ExpandIcon />}
</Button>
</ListItem>
</>
) : null}
</List>
</DialogContent>
</RootDialog>
);
}
Example #10
Source File: SortFilter.tsx From Tachidesk-WebUI with Mozilla Public License 2.0 | 5 votes |
export default function SortFilter(props: Props) {
const {
values,
name,
state,
position,
group,
updateFilterValue,
update,
} = props;
const [val, setval] = React.useState(state);
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
if (values) {
const handleChange = (event:
React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
const tmp = val;
if (tmp.index === index) {
tmp.ascending = !tmp.ascending;
} else {
tmp.ascending = true;
}
tmp.index = index;
setval(tmp);
const upd = update.filter((e: {
position: number; group: number | undefined;
}) => !(position === e.position && group === e.group));
updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]);
};
const ret = (
<FormControl fullWidth>
<ListItemButton onClick={handleClick}>
<ListItemText primary={name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open}>
<List>
{values.map((value: string, index: number) => {
let icon;
if (val.index === index) {
icon = val.ascending ? (<ArrowUpwardIcon color="primary" />)
: (<ArrowDownwardIcon color="primary" />);
}
return (
<ListItem disablePadding key={`${name} ${value}`}>
<ListItemButton
onClick={(event) => handleChange(event, index)}
>
<ListItemIcon>
{icon}
</ListItemIcon>
<ListItemText primary={value} />
</ListItemButton>
</ListItem>
);
})}
</List>
</Collapse>
</FormControl>
);
return (
<Box key={name} sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
{ret}
</Box>
);
}
return (<></>);
}
Example #11
Source File: EnemyEditor.tsx From genshin-optimizer with MIT License | 5 votes |
export function EnemyExpandCard() {
const { data } = useContext(DataContext)
const [expanded, setexpanded] = useState(false)
const toggle = useCallback(() => setexpanded(!expanded), [setexpanded, expanded])
const eLvlNode = data.get(input.enemy.level)
const eDefRed = data.get(input.enemy.defRed)
const eDefIgn = data.get(input.enemy.defIgn)
return <CardLight>
<CardContent>
<Grid container>
<Grid item flexGrow={1} alignItems="center">
<Grid container spacing={1}>
<Grid item>
<Chip size="small" color="success" label={<span>{KeyMap.get(eLvlNode.info.key)} <strong>{eLvlNode.value}</strong></span>} />
</Grid>
{allElementsWithPhy.map(element => <Grid item key={element}>
<Typography key={element} ><EnemyResText element={element} /></Typography>
</Grid>)}
<Grid item>
<Typography>DEF Reduction {valueString(eDefRed.value, eDefRed.unit)}</Typography>
</Grid>
<Grid item>
<Typography>DEF Ignore {valueString(eDefIgn.value, eDefIgn.unit)}</Typography>
</Grid>
</Grid>
</Grid>
<Grid item>
<ExpandButton
expand={expanded}
onClick={toggle}
aria-expanded={expanded}
aria-label="show more"
size="small"
sx={{ p: 0 }}
>
<ExpandMore />
</ExpandButton>
</Grid>
</Grid>
</CardContent>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent sx={{ pt: 0 }}>
<EnemyEditor />
</CardContent>
</Collapse>
</CardLight>
}
Example #12
Source File: App.tsx From sapio-studio with Mozilla Public License 2.0 | 5 votes |
function ContractViewer(props: {
model: DiagramModel;
engine: DiagramEngine;
current_contract: ContractModel;
}) {
const dispatch = useDispatch();
const entity_id: EntityType = useSelector(selectEntityToView);
const show = useSelector(selectShouldViewEntity);
const theme = useTheme();
const timing_simulator_enabled = useSelector(selectSimIsShowing);
const details = entity_id[0] !== 'NULL' && show;
const { model, engine, current_contract } = props;
React.useEffect(() => {
if (entity_id[0] === 'TXN')
jump_to_entity(
model,
engine,
TXIDAndWTXIDMap.get_by_txid_s(
current_contract.txid_map,
entity_id[1]
) ?? null
);
else if (entity_id[0] === 'UTXO')
jump_to_entity(
model,
engine,
TXIDAndWTXIDMap.get_by_txid_s(
current_contract.txid_map,
entity_id[1].hash
)?.utxo_models[entity_id[1].nIn] ?? null
);
}, [entity_id]);
return (
<>
<div className="main-container">
<DemoCanvasWidget
engine={engine}
model={model}
background={theme.palette.background.paper}
color={theme.palette.divider}
>
<CanvasWidget engine={engine as any} key={'main'} />
</DemoCanvasWidget>
</div>
<Collapse in={details}>
<CurrentlyViewedEntity current_contract={current_contract} />
</Collapse>
<div className="area-overlays">
<Collapse in={timing_simulator_enabled}>
<SimulationController
contract={current_contract}
engine={engine}
hide={() => dispatch(toggle_showing())}
/>
</Collapse>
</div>
</>
);
}
Example #13
Source File: UpdateInfoCard.tsx From Cromwell with MIT License | 5 votes |
export default function UpdateInfoCard(props: {
updateInfo: TUpdateInfo;
currentVersion?: string;
onStartUpdate: () => void;
}) {
const { updateInfo, currentVersion } = props;
const [changelogCollapsed, setChangelogCollapsed] = useState(true);
const toggleChangelog = () => {
setChangelogCollapsed(!changelogCollapsed)
}
return (
<Grid item container xs={12} className={styles.update}>
<h3 className={styles.updateTitle}>
<UpdateIcon style={{ marginRight: '7px' }} />
Update available</h3>
<p>{currentVersion ?? ''} {'>'} {updateInfo.version}</p>
<div className={styles.changelogTitle}>
<p onClick={toggleChangelog}>See changelog</p>
<ExpandMoreIcon
className={clsx(styles.expand, !changelogCollapsed && styles.expandOpen)}
onClick={toggleChangelog}
/>
</div>
{updateInfo.onlyManualUpdate && (
<div className={styles.warning}>
<WarningRoundedIcon />
<p style={{ margin: '0 0 0 5px' }}>Cannot launch automatic update. Please update using
<span className={styles.command}>yarn upgrade @cromwell/cms@{updateInfo.packageVersion} --exact</span>
command and restart CMS</p>
</div>
)}
<Collapse in={!changelogCollapsed} timeout="auto" unmountOnExit>
<div className={styles.changelogList}
dangerouslySetInnerHTML={{ __html: updateInfo.changelog }}></div>
</Collapse>
<Button
disabled={updateInfo.onlyManualUpdate}
color="primary"
variant="contained"
onClick={props.onStartUpdate}
>Update</Button>
</Grid>
)
}
Example #14
Source File: Filter.tsx From Cromwell with MIT License | 5 votes |
private getFilterItem = (props: {
title: string;
key: string;
content: JSX.Element;
}) => {
const { collapsedItems } = this.state;
if (collapsedItems[props.key] === undefined) {
collapsedItems[props.key] = this.collapsedByDefault;
}
const isExpanded = !collapsedItems[props.key];
return (
<Card className="productFilter_card">
<div className="productFilter_headerWrapper"
onClick={() => this.setState(prev => ({
collapsedItems: {
...prev.collapsedItems,
[props.key]: !prev.collapsedItems[props.key]
}
}))}
>
<Typography gutterBottom style={{
fontSize: '14px',
margin: '0 0 0 15px'
}}>{props.title}</Typography>
<IconButton
className={clsx('productFilter_expand', {
'productFilter_expandOpen': isExpanded,
})}
aria-expanded={isExpanded}
aria-label={`Toggle ${props.title} filter visibility`}
>
<ExpandMoreIcon />
</IconButton>
</div>
<Collapse in={isExpanded} timeout="auto" unmountOnExit>
{props.content}
</Collapse>
</Card >
)
}
Example #15
Source File: More.tsx From NekoMaid with MIT License | 5 votes |
C: any = Collapse
Example #16
Source File: LoginForm.tsx From frontend with MIT License | 5 votes |
function LoginForm() {
const { t } = useTranslation('one-time-donation')
const formik = useFormikContext<OneTimeDonation>()
return (
<Collapse in={!formik.values.anonymousDonation} timeout="auto">
<Grid sx={{ marginBottom: theme.spacing(4) }} container rowSpacing={3}>
<Grid item xs={12}>
<Typography fontWeight={'bold'} fontSize={16} color="#343434">
{t('second-step.login')}
</Typography>
</Grid>
<Grid item xs={12}>
<FormTextField name="personsEmail" type="text" label="Email" fullWidth size="medium" />
</Grid>
<Grid item xs={12}>
<FormTextField
name="personsPassword"
type="password"
label={t('second-step.password')}
fullWidth
size="medium"
/>
</Grid>
<Box display={'flex'} justifyContent="space-between" width="100%" alignItems="center">
<FormControlLabel
control={<Checkbox />}
label={t('second-step.checkbox-label') as string}
/>
<Box sx={{ opacity: 0.85 }}>
<Typography display="inline" color="GrayText">
Don't have an account?
</Typography>{' '}
<Link color={theme.palette.primary.dark} href="#">
Sign up
</Link>
</Box>
</Box>
<Button color="info" variant="contained" fullWidth sx={{ marginTop: theme.spacing(3) }}>
{t('second-step.btn-login')}
</Button>
<Button
size="large"
color="primary"
variant="outlined"
fullWidth
sx={{ marginTop: theme.spacing(3) }}>
<Box display="inline-flex" alignItems="center" marginRight={theme.spacing(2)}>
<Google />
</Box>
Log in with Google
</Button>
</Grid>
</Collapse>
)
}
Example #17
Source File: AnonymousForm.tsx From frontend with MIT License | 5 votes |
export default function AnonymousForm() {
const [field] = useField('anonymousDonation')
const { t } = useTranslation('one-time-donation')
return (
<>
<CircleCheckboxField
label={
<Typography
fontSize={16}
display="inline-flex"
alignItems="center"
component="span"
color="#343434"
fontWeight="bold">
{t('anonymous-menu.checkbox-label')}
{field.value ? <ExpandLess /> : <ExpandMore />}
</Typography>
}
name="anonymousDonation"
/>
<Collapse in={field.value} timeout="auto" unmountOnExit>
<Grid container columnSpacing={3} rowSpacing={3}>
<Grid item xs={12} color="#343434" sx={{ opacity: 0.9 }}>
<Typography>{t('anonymous-menu.info-start')}</Typography>
</Grid>
<Grid item xs={12} md={6}>
<FormTextField
name="personsFirstName"
type="text"
label={t('anonymous-menu.firstName')}
fullWidth
/>
</Grid>
<Grid item xs={12} md={6}>
<FormTextField
name="personsLastName"
type="text"
label={t('anonymous-menu.lastName')}
fullWidth
/>
</Grid>
<Grid item xs={12} md={6}>
<FormTextField name="personsEmail" type="text" label="Email" fullWidth />
</Grid>
<Grid item xs={12} md={6}>
<FormTextField
name="personsPhone"
type="text"
label={t('anonymous-menu.phone')}
fullWidth
/>
</Grid>
<Grid item xs={12} color="GrayText">
<Typography>* {t('anonymous-menu.info-end')}</Typography>
</Grid>
</Grid>
</Collapse>
</>
)
}
Example #18
Source File: Worlds.tsx From NekoMaid with MIT License | 4 votes |
Worlds: React.FC = () => {
const plugin = usePlugin()
const globalData = useGlobalData()
const [worlds, setWorlds] = useState<World[]>([])
const [selected, setSelected] = useState('')
const [open, setOpen] = useState(false)
const update = () => plugin.emit('worlds:fetch', (data: World[]) => {
setWorlds(data)
if (data.length) setSelected(old => data.some(it => it.id === old) ? old : '')
})
useEffect(() => {
const offUpdate = plugin.on('worlds:update', update)
update()
return () => { offUpdate() }
}, [])
const sw = worlds.find(it => it.id === selected)
const getSwitch = (name: string, configId = name) => sw
? <ListItem
secondaryAction={<Switch disabled={!globalData.hasMultiverse} checked={(sw as any)[name]}
onChange={e => {
plugin.emit('worlds:set', sw.id, configId, e.target.checked.toString())
success()
}}
/>}><ListItemText primary={(lang.worlds as any)[name]} /></ListItem>
: null
return <Box sx={{ minHeight: '100%', py: 3 }}>
<Toolbar />
<Container maxWidth={false}>
<Grid container spacing={3}>
<Grid item lg={8} md={12} xl={9} xs={12}>
<Card>
<CardHeader title={lang.worlds.title} />
<Divider />
<Box sx={{ position: 'relative' }}>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell padding='checkbox' />
<TableCell>{lang.worlds.name}</TableCell>
{globalData.hasMultiverse && <TableCell>{lang.worlds.alias}</TableCell>}
<TableCell>{lang.worlds.players}</TableCell>
<TableCell>{lang.worlds.chunks}</TableCell>
<TableCell>{lang.worlds.entities}</TableCell>
<TableCell>{lang.worlds.tiles}</TableCell>
<TableCell>{lang.worlds.time}</TableCell>
<TableCell>{lang.worlds.weather}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{worlds.map(it => <TableRow key={it.id}>
<TableCell padding='checkbox'><Checkbox checked={selected === it.id} onClick={() => setSelected(it.id)} /></TableCell>
<TableCell><Tooltip title={it.id}><span>{it.name}</span></Tooltip></TableCell>
{globalData.hasMultiverse && <TableCell>{it.alias}
<IconButton size='small' onClick={() => dialog(lang.inputValue, lang.worlds.alias).then(res => {
if (res == null) return
plugin.emit('worlds:set', it.id, 'alias', res)
success()
})}><Edit fontSize='small' /></IconButton>
</TableCell>}
<TableCell>{it.players}</TableCell>
<TableCell>{it.chunks}</TableCell>
<TableCell>{it.entities}</TableCell>
<TableCell>{it.tiles}</TableCell>
<TableCell><Countdown time={it.time} max={24000} interval={50} /></TableCell>
<TableCell><IconButton size='small' onClick={() => {
plugin.emit('worlds:weather', it.id)
success()
}}>
{React.createElement((it.weather === 1 ? WeatherRainy : it.weather === 2 ? WeatherLightningRainy : WbSunny) as any)}
</IconButton></TableCell>
</TableRow>)}
</TableBody>
</Table>
</TableContainer>
</Box>
</Card>
</Grid>
<Grid item lg={4} md={6} xl={3} xs={12}>
<Card>
<CardHeader
title={lang.operations}
sx={{ position: 'relative' }}
action={<Tooltip title={lang.worlds.save} placement='left'>
<IconButton
size='small'
onClick={() => {
if (!sw) return
plugin.emit('worlds:save', sw.id)
success()
}}
sx={cardActionStyles}
><Save /></IconButton>
</Tooltip>}
/>
<Divider />
<Box sx={{ position: 'relative' }}>
{sw
? <List sx={{ width: '100%' }} component='nav'>
<ListItem secondaryAction={<ToggleButtonGroup
exclusive
color='primary'
size='small'
value={sw.difficulty}
onChange={(_, value) => {
plugin.emit('worlds:difficulty', sw.id, value)
success()
}}
>
{difficulties.map(it => <ToggleButton value={it.toUpperCase()} key={it}>{minecraft['options.difficulty.' + it]}</ToggleButton>)}
</ToggleButtonGroup>}><ListItemText primary={minecraft['options.difficulty']} /></ListItem>
<ListItem secondaryAction={<Switch checked={sw.pvp} onChange={e => {
plugin.emit('worlds:pvp', sw.id, e.target.checked)
success()
}} />}><ListItemText primary='PVP' /></ListItem>
{getSwitch('allowAnimals', 'spawning.animals.spawn')}
{getSwitch('allowMonsters', 'spawning.monsters.spawn')}
{globalData.hasMultiverse && <>
{getSwitch('allowFlight')}
{getSwitch('autoHeal')}
{getSwitch('hunger')}
</>}
<ListItem secondaryAction={globalData.canSetViewDistance
? <IconButton
onClick={() => dialog({
content: lang.inputValue,
input: {
error: true,
type: 'number',
helperText: lang.invalidValue,
validator: (it: string) => /^\d+$/.test(it) && +it > 1 && +it < 33
}
}).then(res => {
if (!res) return
plugin.emit('worlds:viewDistance', sw.id, parseInt(res as any))
success()
})}
><Edit /></IconButton>
: undefined}>
<ListItemText primary={lang.worlds.viewDistance + ': ' + sw.viewDistance} />
</ListItem>
<ListItem><ListItemText primary={minecraft['selectWorld.enterSeed']} secondary={sw.seed} /></ListItem>
<ListItemButton onClick={() => setOpen(!open)}>
<ListItemText primary={minecraft['selectWorld.gameRules']} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component='div' dense disablePadding>
{sw.rules.map(([key, value]) => {
const isTrue = value === 'true'
const isBoolean = isTrue || value === 'false'
const isNumber = /^\d+$/.test(value)
return <ListItem
key={key}
sx={{ pl: 4 }}
secondaryAction={isBoolean
? <Switch
checked={isTrue}
onChange={e => {
plugin.emit('worlds:rule', sw.id, key, e.target.checked.toString())
success()
}}
/>
: <IconButton
onClick={() => dialog({
content: lang.inputValue,
input: isNumber
? {
error: true,
type: 'number',
helperText: lang.invalidValue,
validator: (it: string) => /^\d+$/.test(it)
}
: { }
}).then(res => {
if (res == null) return
plugin.emit('worlds:rule', sw.id, key, res)
success()
})}
><Edit /></IconButton>}
>
<ListItemText primary={(minecraft['gamerule.' + key] || key) + (isBoolean ? '' : ': ' + value)} />
</ListItem>
})}
</List>
</Collapse>
</List>
: <CardContent><Empty /></CardContent>
}
</Box>
</Card>
</Grid>
</Grid>
</Container>
</Box>
}
Example #19
Source File: index.tsx From metaplex with Apache License 2.0 | 4 votes |
Settings = ({ narrow }: { narrow: boolean }) => {
const { disconnect, publicKey } = useWallet();
const { setEndpoint, env, endpoint } = useConnectionConfig();
const { setVisible } = useWalletModal();
const open = React.useCallback(() => setVisible(true), [setVisible]);
const { setModal } = useModal();
const theme = useTheme();
const colorModeCtx = useColorMode();
const handleConnect = React.useCallback(() => {
setModal(ModalEnum.WALLET);
setVisible(true);
}, [setModal, setVisible]);
const connectedActions = [
{
click: async () => {
if (publicKey) {
await navigator.clipboard.writeText(publicKey.toBase58());
notify({
message: 'Wallet update',
description: 'Address copied to clipboard',
});
}
},
innerNarrow: () =>
`Copy Address (${publicKey && shortenAddress(publicKey.toBase58())})`,
inner: function ConnectedWalletCopyC() {
return (
<React.Fragment>
<CopyOutlined />
{publicKey && shortenAddress(publicKey.toBase58())}
</React.Fragment>
);
},
},
{
click: open,
inner: () => 'Change\u00A0Wallet',
},
{
click: () => disconnect().catch(),
inner: () => `Disconnect\u00A0(${env})`,
expandedExtra: {
// these are interepreted as props. TODO: specific types
color: 'error' as any,
variant: 'contained' as any,
},
},
];
const [drawerOpen, setDrawerOpen] = React.useState(false);
const [envCollapseOpen, setEnvCollapseOpen] = React.useState(false);
const hackySkipSet = 'hackySkipSet';
const toggleDrawer = open => event => {
if (
event.type === 'keydown' &&
(event.key === 'Tab' || event.key === 'Shift')
) {
return;
}
if (event.target.classList.contains(hackySkipSet)) {
return;
}
setDrawerOpen(open);
};
const drawerC = inner => {
return (
<React.Fragment>
<Button onClick={toggleDrawer(true)}>
<AccountBalanceWalletIcon />
</Button>
<Drawer anchor="right" open={drawerOpen} onClose={toggleDrawer(false)}>
<Box
sx={{ width: 250 }}
role="presentation"
onClick={toggleDrawer(false)}
onKeyDown={toggleDrawer(false)}
>
{inner}
</Box>
</Drawer>
</React.Fragment>
);
};
const themeSwitch = (
<Button
sx={{ ml: 1 }}
onClick={colorModeCtx.toggleColorMode}
color="inherit"
>
{theme.palette.mode === 'dark' ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</Button>
);
if (narrow) {
const listHead = (
<ListItem>
<ListItemText
primary="Wallet"
primaryTypographyProps={{
fontSize: '1.2rem',
fontWeight: 'medium',
letterSpacing: 0,
}}
/>
</ListItem>
);
return (
<React.Fragment>
{!publicKey &&
drawerC(
<List>
{listHead}
<Divider />
<ListItemButton
onClick={() => setEnvCollapseOpen(!envCollapseOpen)}
className={hackySkipSet}
>
Change Network
{envCollapseOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={envCollapseOpen} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{ENDPOINTS.map(p => (
<ListItemButton
selected={endpoint === p.endpoint}
onClick={() => setEndpoint(p.endpoint)}
key={p.name}
sx={{ pl: 4 }}
className={hackySkipSet}
>
{p.name}
</ListItemButton>
))}
</List>
</Collapse>
<ListItemButton onClick={handleConnect}>Connect</ListItemButton>
</List>,
)}
{publicKey &&
drawerC(
<List>
{listHead}
<Divider />
{connectedActions.map((a, idx) => {
return (
<ListItemButton onClick={a.click} key={idx}>
{(a.innerNarrow && a.innerNarrow()) || a.inner()}
</ListItemButton>
);
})}
</List>,
)}
{themeSwitch}
</React.Fragment>
);
} else {
return (
<Stack
direction="row"
spacing={2}
sx={{
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
marginRight: '36px',
}}
>
{!publicKey && (
<React.Fragment>
<FormControl variant="standard" style={{ minWidth: '10ch' }}>
<Select
id="connected-env-select"
onChange={e => {
setEndpoint(e.target.value);
}}
value={endpoint}
>
{ENDPOINTS.map(({ name, endpoint }) => (
<MenuItem key={name} value={endpoint}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<Link underline="none">
<Button variant="contained" onClick={handleConnect}>
Connect
</Button>
</Link>
</React.Fragment>
)}
{publicKey &&
connectedActions.map((a, idx) => {
return (
<Button
key={idx}
variant="outlined"
onClick={a.click}
{...a.expandedExtra}
>
{a.inner()}
</Button>
);
})}
{themeSwitch}
</Stack>
);
}
}
Example #20
Source File: FirstStep.tsx From frontend with MIT License | 4 votes |
export default function FirstStep() {
const { data: prices } = useSinglePriceList()
const { t } = useTranslation('one-time-donation')
const mobile = useMediaQuery('(max-width:568px)')
const options = [
{ value: 'card', label: t('third-step.card') },
{ value: 'bank', label: t('third-step.bank-payment') },
]
const [paymentField] = useField('payment')
const [amount] = useField('amount')
const { campaign } = useContext(StepsContext)
const bankAccountInfo = {
owner: t('third-step.owner'),
bank: t('third-step.bank'),
iban: ibanNumber,
}
return (
<Root>
<Typography variant="h4">{t('third-step.title')}</Typography>
<Box marginTop={theme.spacing(4)}>
<RadioButtonGroup name="payment" options={options} />
</Box>
<Collapse in={paymentField.value === 'bank'} timeout="auto">
<List component="div" disablePadding>
<Typography marginTop={theme.spacing(8)} variant="h6">
{t('third-step.bank-details')}
</Typography>
<Divider className={classes.divider} />
<Grid container justifyContent="center">
<Grid my={2} item display="flex" justifyContent="space-between" xs={9}>
<Typography>{bankAccountInfo.owner}</Typography>
<CopyTextButton
label={t('third-step.btn-copy')}
text={bankAccountInfo.owner}
variant="contained"
size="small"
color="info"
/>
</Grid>
<Grid my={2} item display="flex" justifyContent="space-between" xs={9}>
<Typography>{bankAccountInfo.bank}</Typography>
<CopyTextButton
label={t('third-step.btn-copy')}
text={bankAccountInfo.bank}
variant="contained"
size="small"
color="info"
/>
</Grid>
<Grid my={2} item display="flex" justifyContent="space-between" xs={9}>
<Typography>{ibanNumber}</Typography>
<CopyTextButton
label={t('third-step.btn-copy')}
text={bankAccountInfo.iban}
variant="contained"
size="small"
color="info"
/>
</Grid>
</Grid>
<Typography my={2} variant="h6">
{t('third-step.reason-donation')}
</Typography>
<Divider className={classes.divider} />
<Grid container justifyContent="center">
<Grid my={3} item display="flex" justifyContent="space-between" xs={9}>
<Alert severity="warning">
<Typography fontWeight="bold">{campaign.bankHash}</Typography>
</Alert>
<CopyTextButton
text={campaign.title}
variant="contained"
color="info"
size="small"
label={t('third-step.btn-copy')}
/>
</Grid>
</Grid>
<Typography>{t('third-step.message-warning')}</Typography>
</List>
</Collapse>
<Collapse in={paymentField.value === 'card'} timeout="auto">
<Typography variant="h4" sx={{ marginTop: theme.spacing(8) }}>
{t('first-step.amount')}
</Typography>
<Box marginTop={theme.spacing(4)}>
<RadioButtonGroup
name="amount"
options={
prices
?.sort((a, b) => Number(a.unit_amount) - Number(b.unit_amount))
.map((v) => ({
label: money(Number(v.unit_amount)),
value: v.id,
}))
.concat({ label: 'Other', value: 'other' }) || []
}
/>
<Collapse in={amount.value === 'other'} timeout="auto">
<Grid
style={
!mobile
? {
float: 'right',
marginTop: theme.spacing(-10),
width: '49%',
}
: { marginTop: theme.spacing(2) }
}>
<FormTextField
name="otherAmount"
type="number"
label={t('first-step.amount')}
InputProps={{
style: { fontSize: 20, padding: 16 },
endAdornment: (
<InputAdornment variant="filled" position="end">
Лв.
</InputAdornment>
),
}}
/>
</Grid>
</Collapse>
</Box>
</Collapse>
</Root>
)
}
Example #21
Source File: WalletMultiButton.tsx From wallet-adapter with Apache License 2.0 | 4 votes |
WalletMultiButton: FC<ButtonProps> = ({
color = 'primary',
variant = 'contained',
type = 'button',
children,
...props
}) => {
const { publicKey, wallet, disconnect } = useWallet();
const { setOpen } = useWalletDialog();
const [anchor, setAnchor] = useState<HTMLElement>();
const base58 = useMemo(() => publicKey?.toBase58(), [publicKey]);
const content = useMemo(() => {
if (children) return children;
if (!wallet || !base58) return null;
return base58.slice(0, 4) + '..' + base58.slice(-4);
}, [children, wallet, base58]);
if (!wallet) {
return (
<WalletDialogButton color={color} variant={variant} type={type} {...props}>
{children}
</WalletDialogButton>
);
}
if (!base58) {
return (
<WalletConnectButton color={color} variant={variant} type={type} {...props}>
{children}
</WalletConnectButton>
);
}
return (
<>
<Button
color={color}
variant={variant}
type={type}
startIcon={<WalletIcon wallet={wallet} />}
onClick={(event) => setAnchor(event.currentTarget)}
aria-controls="wallet-menu"
aria-haspopup="true"
{...props}
>
{content}
</Button>
<StyledMenu
id="wallet-menu"
anchorEl={anchor}
open={!!anchor}
onClose={() => setAnchor(undefined)}
marginThreshold={0}
TransitionComponent={Fade}
transitionDuration={250}
keepMounted
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<WalletMenuItem onClick={() => setAnchor(undefined)}>
<Button
color={color}
variant={variant}
type={type}
startIcon={<WalletIcon wallet={wallet} />}
onClick={(event) => setAnchor(undefined)}
fullWidth
{...props}
>
{wallet.adapter.name}
</Button>
</WalletMenuItem>
<Collapse in={!!anchor}>
<WalletActionMenuItem
onClick={async () => {
setAnchor(undefined);
await navigator.clipboard.writeText(base58);
}}
>
<ListItemIcon>
<CopyIcon />
</ListItemIcon>
Copy address
</WalletActionMenuItem>
<WalletActionMenuItem
onClick={() => {
setAnchor(undefined);
setOpen(true);
}}
>
<ListItemIcon>
<SwitchIcon />
</ListItemIcon>
Change wallet
</WalletActionMenuItem>
<WalletActionMenuItem
onClick={() => {
setAnchor(undefined);
// eslint-disable-next-line @typescript-eslint/no-empty-function
disconnect().catch(() => {
// Silently catch because any errors are caught by the context `onError` handler
});
}}
>
<ListItemIcon>
<DisconnectIcon />
</ListItemIcon>
Disconnect
</WalletActionMenuItem>
</Collapse>
</StyledMenu>
</>
);
}
Example #22
Source File: ItemRow.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 4 votes |
ItemRow = <T extends GenericListItem>(props: ItemRowProps<T>) => { const [open, setOpen] = useState(false); const { item, index, headCells } = props; const labelId = `enhanced-table-checkbox-${index}`; const shouldCollapse = props.collapse !== undefined; const itemRow = headCells.map((headCell, headIndex) => { const itemRowKey = `${labelId}-${headIndex}`; const itemIdValue = headCell.id ? item[headCell.id] : ''; const position = { rowNumber: index + 1, columnNumber: headIndex + 1, }; const cellStyle = headCell.getStyle ? headCell.getStyle(item, position) : undefined; return ( <TableCell component="th" id={labelId} scope="row" padding="normal" key={itemRowKey} align={headCell.align} style={cellStyle} > {headCell.format ? headCell.format(item, itemIdValue, position) : itemIdValue} </TableCell> ); }); const collapseButton = shouldCollapse ? ( <TableCell component="th" id={`collapse-${index}`} scope="row" padding="normal" key={`collapse-${index}`} align="center" > <IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)} > {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />} </IconButton> </TableCell> ) : ( '' ); const collapseRow = shouldCollapse ? ( <TableRow> <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={headCells.length} > <Collapse in={open} timeout="auto" unmountOnExit> <Box margin={1}> {props.collapse ? props.collapse(index, item) : ''} </Box> </Collapse> </TableCell> </TableRow> ) : ( '' ); return ( <> <TableRow hover role="checkbox" tabIndex={-1} key={item.key} style={ props.getRowStyle ? props.getRowStyle(index, item) : undefined } > {collapseButton} {itemRow} </TableRow> {collapseRow} </> ); }
Example #23
Source File: PlayerList.tsx From NekoMaid with MIT License | 4 votes |
PlayerInfo: React.FC<{ name?: string }> = React.memo(({ name }) => {
const plugin = usePlugin()
const globalData = useGlobalData()
const [open, setOpen] = useState(false)
const [info, setInfo] = useState<IPlayerInfo | undefined>()
const refresh = () => plugin.emit('playerList:query', setInfo, name)
useEffect(() => {
setInfo(undefined)
if (name) refresh()
}, [name])
return name && info
? <>
<Divider />
<List
sx={{ width: '100%' }}
component='nav'
subheader={<ListSubheader component='div' sx={{ backgroundColor: 'inherit' }}>{lang.playerList.details}</ListSubheader>}
>
<ListItem>
<ListItemIcon><AssignmentInd /></ListItemIcon>
<ListItemText primary={globalData.onlineMode
? <Link underline='hover' rel='noopener' target='_blank' href={'https://namemc.com/profile/' + info.id}>{info.id}</Link>
: info.id
} />
</ListItem>
{!info.hasPlayedBefore && <ListItem>
<ListItemIcon><ErrorOutline color='error' /></ListItemIcon>
<ListItemText primary={lang.playerList.hasNotPlayed} />
</ListItem>}
{info.ban != null && <ListItem>
<ListItemIcon><Block color='error' /></ListItemIcon>
<ListItemText primary={lang.playerList.banned + (info.ban ? ': ' + info.ban : '')} />
</ListItem>}
{info.whitelisted && <ListItem>
<ListItemIcon><Star color='warning' /></ListItemIcon>
<ListItemText primary={lang.playerList.whitelisted} />
</ListItem>}
{info.isOP && <ListItem>
<ListItemIcon><Security color='primary' /></ListItemIcon>
<ListItemText primary={lang.playerList.op} />
</ListItem>}
{info.hasPlayedBefore && <>
<ListItemButton onClick={() => setOpen(!open)}>
<ListItemIcon><Equalizer /></ListItemIcon>
<ListItemText primary={minecraft['gui.stats']} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component='div' dense disablePadding>
{[
minecraft['stat.minecraft.play_time'] + ': ' + dayjs.duration(info.playTime / 20, 'seconds').humanize(),
lang.playerList.firstPlay + ': ' + dayjs(info.firstPlay).fromNow(),
lang.playerList.lastPlay + ': ' + dayjs(info.lastOnline).fromNow(),
minecraft['stat.minecraft.leave_game'] + ': ' + info.quit,
minecraft['stat.minecraft.deaths'] + ': ' + info.death,
minecraft['stat.minecraft.player_kills'] + ': ' + info.playerKill,
minecraft['stat.minecraft.mob_kills'] + ': ' + info.entityKill,
lang.playerList.tnt + ': ' + info.tnt
].map((it, i) => <ListItem key={i} sx={{ pl: 4 }}>
<ListItemIcon>{icons[i]}</ListItemIcon>
<ListItemText primary={it} />
</ListItem>)}
</List>
</Collapse>
</>}
</List>
<CardActions disableSpacing sx={{ justifyContent: 'flex-end' }}>
<Tooltip title={lang.playerList[info.whitelisted ? 'clickToRemoveWhitelist' : 'clickToAddWhitelist']}>
<IconButton onClick={() => whitelist(name, plugin, refresh, !info.whitelisted)}>
{info.whitelisted ? <Star color='warning' /> : <StarBorder />}
</IconButton>
</Tooltip>
<Tooltip title={lang.playerList[info.ban == null ? 'clickToBan' : 'clickToPardon']}>
<IconButton onClick={() => banPlayer(name, plugin, refresh, info.ban == null)}>
<Block color={info.ban == null ? undefined : 'error'} />
</IconButton>
</Tooltip>
</CardActions>
</>
: <></>
})
Example #24
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>
}
})
Example #25
Source File: ComponentCatalog.tsx From mui-toolpad with MIT License | 4 votes |
export default function ComponentCatalog({ className }: ComponentCatalogProps) {
const api = usePageEditorApi();
const dom = useDom();
const [openStart, setOpenStart] = React.useState(0);
const closeTimeoutRef = React.useRef<NodeJS.Timeout>();
const openDrawer = React.useCallback(() => {
if (closeTimeoutRef.current) {
clearTimeout(closeTimeoutRef.current);
}
setOpenStart(Date.now());
}, []);
const closeDrawer = React.useCallback(
(delay?: number) => {
const timeOpen = Date.now() - openStart;
const defaultDelay = timeOpen > 750 ? 500 : 0;
closeTimeoutRef.current = setTimeout(() => setOpenStart(0), delay ?? defaultDelay);
},
[openStart],
);
const handleDragStart = (componentType: string) => (event: React.DragEvent<HTMLElement>) => {
event.dataTransfer.dropEffect = 'copy';
const newNode = appDom.createElement(dom, componentType, {});
api.deselect();
api.newNodeDragStart(newNode);
closeDrawer(0);
};
const toolpadComponents = useToolpadComponents(dom);
const handleMouseEnter = React.useCallback(() => openDrawer(), [openDrawer]);
const handleMouseLeave = React.useCallback(() => closeDrawer(), [closeDrawer]);
return (
<ComponentCatalogRoot
className={className}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
position: 'absolute',
top: 0,
bottom: 0,
backgroundColor: 'background.default',
borderRight: 1,
borderColor: 'divider',
}}
>
<Collapse in={!!openStart} orientation="horizontal" timeout={200} sx={{ height: '100%' }}>
<Box sx={{ width: 300, height: '100%', overflow: 'auto' }}>
<Box display="grid" gridTemplateColumns="1fr" gap={1} padding={1}>
{Object.entries(toolpadComponents)
.filter(([componentId]) => componentId !== PAGE_ROW_COMPONENT_ID)
.map(([componentId, componentType]) => {
if (!componentType) {
throw new Error(
`Invariant: Component definition for "${componentId}" is undefined`,
);
}
return (
<ComponentCatalogItem
key={componentId}
draggable
onDragStart={handleDragStart(componentId)}
>
<DragIndicatorIcon color="inherit" />
{componentType.displayName}
</ComponentCatalogItem>
);
})}
</Box>
</Box>
</Collapse>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
width: WIDTH_COLLAPSED,
}}
>
<Box sx={{ mt: 2 }}>{openStart ? <ChevronLeftIcon /> : <ChevronRightIcon />}</Box>
<Box position="relative">
<Typography
sx={{
position: 'absolute',
top: 0,
display: 'flex',
alignItems: 'center',
fontSize: 20,
transform: 'rotate(90deg) translate(-10px, 0)',
transformOrigin: '0 50%',
}}
>
Components
</Typography>
</Box>
</Box>
</Box>
</ComponentCatalogRoot>
);
}
Example #26
Source File: MenuItem.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
MenuItem = ({
page,
stateClsName = "",
onExpand,
selectedMenuItem,
pathValue = "",
expandedGroup = "",
setSelectedMenuItem,
id = `${Math.random()}`,
setPreviewMenuGroup,
previewMenuGroup,
}: {
page: any;
stateClsName?: string;
setSelectedMenuItem: (value: string) => void;
selectedMenuItem?: any;
pathValue?: string;
onExpand: (id: any) => void;
expandedGroup?: string;
id?: string;
setPreviewMenuGroup: (value: string) => void;
previewMenuGroup: string;
}) => {
const childrenMenuList = page?.children?.filter(
(item: any) =>
((item.customPermissionFnc
? item.customPermissionFnc()
: hasPermission(CONSOLE_UI_RESOURCE, IAM_PAGES_PERMISSIONS[item.to])) ||
item.forceDisplay) &&
!item.fsHidden
);
let hasChildren = childrenMenuList?.length;
const expandCollapseHandler = useCallback(
(e: any) => {
e.preventDefault();
if (previewMenuGroup === page.id) {
setPreviewMenuGroup("");
} else if (page.id !== selectedMenuItem) {
setPreviewMenuGroup(page.id);
onExpand("");
}
if (page.id === selectedMenuItem && selectedMenuItem === expandedGroup) {
onExpand(null);
} else if (page.id === selectedMenuItem) {
onExpand(selectedMenuItem);
setPreviewMenuGroup("");
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[page, selectedMenuItem, previewMenuGroup, expandedGroup]
);
const selectMenuHandler = useCallback(
(e: any) => {
onExpand(page.id);
setSelectedMenuItem(page.id);
page.onClick && page.onClick(e);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[page]
);
const onClickHandler = hasChildren
? expandCollapseHandler
: selectMenuHandler;
const isActiveGroup = expandedGroup === page.id;
const activeClsName =
pathValue.includes(selectedMenuItem) && page.id === selectedMenuItem
? "active"
: "";
return (
<React.Fragment>
<ListItem
key={page.to}
button
onClick={(e: any) => {
onClickHandler(e);
setSelectedMenuItem(selectedMenuItem);
}}
component={page.component}
to={page.to}
id={id}
className={`${activeClsName} ${stateClsName} main-menu-item `}
disableRipple
sx={{
...menuItemContainerStyles,
marginTop: "5px",
...menuItemMiniStyles,
"& .expanded-icon": {
border: "1px solid #35393c",
},
}}
>
{page.icon && (
<Tooltip title={`${page.name}`} placement="right">
<ListItemIcon
sx={{ ...menuItemIconStyles }}
className={`${
isActiveGroup && hasChildren ? "expanded-icon" : ""
}`}
>
<Suspense fallback={<div>...</div>}>
<page.icon />
</Suspense>
</ListItemIcon>
</Tooltip>
)}
{page.name && (
<ListItemText
className={stateClsName}
sx={{ ...menuItemTextStyles }}
primary={page.name}
/>
)}
{hasChildren ? (
isActiveGroup || previewMenuGroup === page.id ? (
<MenuCollapsedIcon
height={15}
width={15}
className="group-icon"
style={{ color: "white" }}
/>
) : (
<MenuExpandedIcon
height={15}
width={15}
className="group-icon"
style={{ color: "white" }}
/>
)
) : null}
</ListItem>
{(isActiveGroup || previewMenuGroup === page.id) && hasChildren ? (
<Collapse
key={page.id}
id={`${page.id}-children`}
in={true}
timeout="auto"
unmountOnExit
>
<List
component="div"
disablePadding
key={page.id}
sx={{
marginLeft: "15px",
"&.mini": {
marginLeft: "0px",
},
}}
className={`${stateClsName}`}
>
{childrenMenuList.map((item: any) => {
return (
<ListItem
key={item.to}
button
component={item.component}
to={item.to}
onClick={(e: any) => {
if (page.id) {
setPreviewMenuGroup("");
setSelectedMenuItem(page.id);
}
}}
disableRipple
sx={{
...menuItemStyle,
...menuItemMiniStyles,
}}
className={`${stateClsName}`}
>
{item.icon && (
<Tooltip title={`${item.name}`} placement="right">
<ListItemIcon
sx={{
background: "#00274D",
display: "flex",
alignItems: "center",
justifyContent: "center",
"& svg": {
fill: "#fff",
minWidth: "12px",
maxWidth: "12px",
},
}}
className="menu-icon"
>
<Suspense fallback={<div>...</div>}>
<item.icon />
</Suspense>
</ListItemIcon>
</Tooltip>
)}
{item.name && (
<ListItemText
className={stateClsName}
sx={{ ...menuItemTextStyles, marginLeft: "16px" }}
primary={item.name}
/>
)}
</ListItem>
);
})}
</List>
</Collapse>
) : null}
</React.Fragment>
);
}
Example #27
Source File: MenuItem.tsx From Cromwell with MIT License | 4 votes |
Item = (props: {
data: TMainMenuItem;
itemProps?: {
items: TMainMenuItem[];
canReorder: boolean;
refreshList: () => void;
}
}) => {
const { refreshList, items, canReorder } = props.itemProps ?? {};
const item = props.data;
const forceUpdate = useForceUpdate();
const classes = useStyles();
const [_expanded, setExpanded] = React.useState(false);
const expanded = _expanded && !canReorder;
if (!item) return null;
const handleExpandClick = () => {
if (canReorder) return;
setExpanded(!_expanded);
};
const handleChange = (prop: keyof TMainMenuItem, val: string) => {
(item as any)[prop] = val;
forceUpdate();
}
const handleRemove = (event) => {
event.stopPropagation();
if (items) {
items.splice(items.indexOf(item), 1);
refreshList?.();
}
}
return (
<div className={`${classes.card} PluginMainMenu-paper`}>
<CardActionArea
className={classes.cardHeader}
onClick={handleExpandClick}
>
<p className={classes.cardTitle}>{item.title}</p>
<CardActions disableSpacing className={classes.cardActions}>
{!canReorder && (
<IconButton
className={clsx(classes.expand, {
[classes.expandOpen]: expanded,
})}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</IconButton>
)}
<IconButton onClick={handleRemove}>
<HighlightOffIcon />
</IconButton>
</CardActions>
</CardActionArea>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<div className={classes.cardContent}>
<TextField label="Title" variant="outlined"
value={item.title}
className={classes.field}
onChange={(e) => { handleChange('title', e.target.value) }}
/>
<TextField label="Link" variant="outlined"
value={item.href}
className={classes.field}
onChange={(e) => { handleChange('href', e.target.value) }}
/>
<TextField label="Columns" variant="outlined"
value={item.sublinkCols}
className={classes.field}
onChange={(e) => { handleChange('sublinkCols', e.target.value) }}
/>
<TextField label="Width in px" variant="outlined"
value={item.width}
className={classes.field}
onChange={(e) => { handleChange('width', e.target.value) }}
/>
<TextField
value={item.html}
label="Custom HTML"
multiline
rows={4}
variant="outlined"
className={classes.field}
onChange={(e) => { handleChange('html', e.target.value) }}
/>
<div className={classes.sublinksList}>
<h3 className={classes.sublinksTitle}>Sublinks</h3>
{item.sublinks && item.sublinks.map((sl, slIndex) => {
return (
<div className={`${classes.sublinkItem} PluginMainMenu-paper`} >
<TextField label="Sublink title" variant="outlined"
value={sl.title}
className={classes.subField}
onChange={(e) => { if (item.sublinks) item.sublinks[slIndex].title = e.target.value; forceUpdate(); }}
/>
<TextField label="Sublink href" variant="outlined"
value={sl.href}
className={classes.subField}
onChange={(e) => { if (item.sublinks) item.sublinks[slIndex].href = e.target.value; forceUpdate(); }}
/>
<IconButton onClick={(e) => {
e.stopPropagation();
if (item.sublinks) item.sublinks.splice(slIndex, 1);
refreshList?.();
}}>
<HighlightOffIcon />
</IconButton>
</div>
)
})}
<div className={`PluginMainMenu-paper ${classes.card}`}>
<MenuItem
className={classes.addBtn}
onClick={() => {
if (!item.sublinks) item.sublinks = [];
item.sublinks.push({});
forceUpdate();
}}>
<AddIcon />
</MenuItem>
</div>
</div>
</div>
</Collapse>
</div>
)
}
Example #28
Source File: ChartCard.tsx From genshin-optimizer with MIT License | 4 votes |
export default function ChartCard({ chartData, plotBase, setPlotBase, disabled = false }: ChartCardProps) {
const [showDownload, setshowDownload] = useState(false)
const [showMin, setshowMin] = useState(true)
const { data } = useContext(DataContext)
const statKeys = ["atk", "hp", "def", "eleMas", "critRate_", "critDMG_", "heal_", "enerRech_"]
if (data.get(input.weaponType).value !== "catalyst") statKeys.push("physical_dmg_")
statKeys.push(`${data.get(input.charEle).value}_dmg_`)
const { displayData, downloadData } = useMemo(() => {
if (!chartData) return { displayData: null, downloadData: null }
const points = chartData.data.map(({ value: y, plot: x }) => ({ x, y })) as Point[]
const increasingX: Point[] = points.sort((a, b) => a.x - b.x)
const minimumData: Point[] = []
for (const point of increasingX) {
let last: Point | undefined
while ((last = minimumData.pop())) {
if (last.y > point.y) {
minimumData.push(last)
break
}
}
minimumData.push(point)
}
// Note:
// We can also just use `minimumData` if the plotter supports multiple data sources.
// It could be faster too since there're no empty entries in `minimumData`.
if (minimumData[0]?.x !== increasingX[0]?.x)
increasingX[0].min = minimumData[0].y
minimumData.forEach(x => { x.min = x.y })
const downloadData = {
minimum: minimumData.map(({ x, y }) => [x, y]),
allData: increasingX.map(({ x, y }) => [x, y]),
}
return { displayData: increasingX, downloadData }
}, [chartData])
return <CardLight>
<CardContent>
<Grid container spacing={1} alignItems="center">
<Grid item>
<Typography variant="h6" >Optimization Target vs</Typography>
</Grid>
<Grid item>
<DropdownButton title={plotBase ? KeyMap.get(plotBase) : "Not Selected"}
color={plotBase ? "success" : "primary"}
disabled={disabled}
>
<MenuItem onClick={() => { setPlotBase("") }}>Unselect</MenuItem>
<Divider />
{statKeys.map(sKey => <MenuItem key={sKey} onClick={() => { setPlotBase(sKey as any) }}>{KeyMap.get(sKey)}</MenuItem>)}
</DropdownButton>
</Grid>
<Grid item flexGrow={1}>
<Tooltip placement="top" title="Using data from the builder, this will generate a graph to visualize Optimization Target vs. a selected stat. The graph will show the maximum Optimization Target value per 0.01 of the selected stat.">
<Info />
</Tooltip>
</Grid>
{!!downloadData && <Grid item>
<Button startIcon={showMin ? <CheckBox /> : <CheckBoxOutlineBlank />}
color={showMin ? "success" : "secondary"}
onClick={() => setshowMin(!showMin)}>Show Min Stat Threshold</Button>
</Grid>}
{!!downloadData && <Grid item>
<Button color="info" startIcon={<Download />} onClick={() => setshowDownload(!showDownload)}>Download Data</Button>
</Grid>}
</Grid>
</CardContent>
{!!displayData && <Divider />}
{chartData && !!displayData && <CardContent>
<Collapse in={!!downloadData && showDownload}>
<CardDark sx={{ mb: 2 }}>
<CardContent>
<Typography>Min Data</Typography>
<DataDisplay data={downloadData?.minimum} />
<Typography>All Data</Typography>
<DataDisplay data={downloadData?.allData} />
</CardContent>
</CardDark>
</Collapse>
<Chart displayData={displayData} plotNode={chartData.plotNode} valueNode={chartData.valueNode} showMin={showMin} />
</CardContent>}
</CardLight >
}
Example #29
Source File: latest-frontend-dependencies.tsx From Cromwell with MIT License | 4 votes |
export default function FrontendDependencies() {
const [expanded, setExpanded] = React.useState(false);
const [versionsLoading, setVersionsLoading] = React.useState(false);
const [cmsVersions, setCmsVersions] = React.useState<string[]>([]);
const [pickedVersion, setPickedVersion] = React.useState<string | undefined>();
const [dependencies, setDependencies] = useState<{
name: string;
version: string;
}[]>([]);
const handleExpandClick = () => {
setExpanded(!expanded);
};
useEffect(() => {
(async () => {
setVersionsLoading(true);
const versions = (await apiClient.getFrontendDependenciesBindings())
.filter(compareVersions.validate)
.sort(compareVersions).reverse();
setCmsVersions(versions);
const latest = versions[0];
setPickedVersion(latest);
await getDependencies(latest);
})();
}, []);
const getDependencies = async (version: string) => {
setVersionsLoading(true);
const deps = await apiClient.getFrontendDependenciesList(version);
setDependencies(Object.keys(deps?.latestVersions ?? {}).map(pckg => ({
name: pckg,
version: (deps?.latestVersions ?? {})[pckg],
})));
setVersionsLoading(false);
}
const getDepName = (option) => `${option.name}: "${option.version}"`;
const changeCmsVersion = async (version: string) => {
setPickedVersion(version);
setDependencies([]);
await getDependencies(version);
}
return (
<Layout
title='Hello from'
description=""
>
<div className={styles.content}>
<h1 className={styles.title}>Latest Frontend dependencies</h1>
<Link
style={{ marginBottom: '25px' }}
href="/docs/development/frontend-dependencies">Documentation</Link>
<div className={styles.searchBox} >
<Autocomplete
id="cms-versions"
options={cmsVersions ?? ['']}
value={pickedVersion ?? ''}
onChange={(event, value) => changeCmsVersion(value)}
getOptionLabel={ver => ver}
style={{ width: 300 }}
renderInput={(params) =>
<TextField {...params}
label="Pick CMS version"
variant="outlined"
/>}
/>
</div>
<div className={styles.searchBox}>
{versionsLoading ? (
<CircularProgress />
) : (
<Autocomplete
id="dependencies-versions"
options={dependencies}
getOptionLabel={getDepName}
style={{ width: 300 }}
renderInput={(params) =>
<TextField {...params}
label="Search dependencies..."
variant="outlined"
/>}
/>
)}
</div>
<div className={styles.listHeader} onClick={handleExpandClick}>
<h3 className={styles.expandTitle}>Expand all</h3>
<IconButton >
<ExpandMoreIcon
style={{ transform: expanded ? 'rotate(180deg)' : '' }}
/>
</IconButton>
</div>
<Collapse in={expanded} timeout="auto" unmountOnExit>
{dependencies.map(dep => {
return (
<div key={dep.name}>{getDepName(dep)}</div>
)
})}
</Collapse>
</div>
</Layout>
)
}