@material-ui/icons#ExpandLess TypeScript Examples
The following examples show how to use
@material-ui/icons#ExpandLess.
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: DiscloseSlippageSelector.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
function Component({
className,
value,
...selectorProps
}: DiscloseSlippageSelectorProps) {
const [{ open }, setOpen] = useLocalStorage<{ open: boolean }>(
'__anchor_slippage__',
{ open: false },
);
return (
<details className={className} {...(open ? { open: true } : {})}>
<summary
onClick={(event) => {
event.preventDefault();
setOpen({ open: !open });
}}
>
{open ? <ExpandLess /> : <ExpandMore />}
<IconSpan>
Slippage Tolerance{' '}
<InfoTooltip>
The transaction will revert if the price changes by more than the
defined percentage.{' '}
</InfoTooltip>
: {big(value).mul(100).toFixed()}%
</IconSpan>
</summary>
<SlippageSelector value={value} {...selectorProps} className="selector" />
</details>
);
}
Example #2
Source File: ExpandableElement.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function ExpandableElement({ children, expandable, defaultOpen }: Props): ReactElement | null {
const classes = useStyles()
const [open, setOpen] = useState<boolean>(Boolean(defaultOpen))
const handleClick = () => {
setOpen(!open)
}
return (
<div className={`${classes.root} ${classes.rootLevel2}`}>
<ListItem button onClick={handleClick} className={classes.header}>
{children}
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<div className={classes.contentLevel12}>{expandable}</div>
</Collapse>
</div>
)
}
Example #3
Source File: MoreMenu.tsx From anchor-web-app with Apache License 2.0 | 5 votes |
function MoreMenuBase({ children, className }: MoreMenuProps) {
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
return (
<>
<MoreButton
onClick={(event: MouseEvent<HTMLButtonElement>) =>
setAnchorEl(event.currentTarget)
}
>
More {anchorEl ? <ExpandLess /> : <ExpandMore />}
</MoreButton>
<Popover
open={!!anchorEl}
anchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
className={className}
>
<MenuList variant="menu">
{Children.map(children, (child) => {
return cloneElement(child, {
children: (
<IconSpan>
{child.props.children} <ChevronRightRounded />
</IconSpan>
),
});
})}
</MenuList>
</Popover>
</>
);
}
Example #4
Source File: GovBanner.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 5 votes |
GovBanner: React.FC = () => {
const classes = useStyles();
const [expanded, setExpanded] = useState(false);
return (
<>
<div className={classes.root}>
<div className={classes.inner}>
<img src={flagIcon} alt="usa flag" className={classes.flag} />
<div className={classes.textWrap}>
<div className={classes.text}>
An official website of the United States government
</div>
<button
className={clsx(classes.text, classes.btn, classes.btnExpand)}
onClick={() => setExpanded((exp) => !exp)}
>
Here's how you know{' '}
{expanded ? (
<ExpandLess fontSize="small" />
) : (
<ExpandMore fontSize="small" />
)}
</button>
</div>
</div>
</div>
{expanded && (
<div className={classes.root}>
<div className={clsx(classes.inner, classes.infoInner)}>
<div className={classes.info}>
<div className={classes.infoIcon}>
<img src={govIcon} alt="Dot Gov" />
</div>
<div className={classes.infoText}>
<p>
<strong>The .gov means it’s official.</strong>
<br />
Federal government websites often end in .gov or .mil. Before
sharing sensitive information, make sure you’re on a federal
government site.
</p>
</div>
</div>
<div className={classes.info}>
<div className={classes.infoIcon}>
<img src={httpsIcon} alt="HTTPS" />
</div>
<div className={classes.infoText}>
<p>
<strong>This site is secure.</strong>
<br />
The <strong>https://</strong> ensures that you are connecting
to the official website and that any information you provide
is encrypted and transmitted securely.
</p>
</div>
</div>
</div>
</div>
)}
</>
);
}
Example #5
Source File: ExpandableList.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 5 votes |
export default function ExpandableList({ children, label, level, defaultOpen, info }: Props): ReactElement | null {
const classes = useStyles()
const [open, setOpen] = useState<boolean>(Boolean(defaultOpen))
const handleClick = () => {
setOpen(!open)
}
let rootLevelClass = ''
let typographyVariant: 'h1' | 'h2' | 'h3' = 'h1'
let contentLevelClass = classes.contentLevel0
if (level === 1) {
rootLevelClass = classes.rootLevel1
typographyVariant = 'h2'
contentLevelClass = classes.contentLevel12
} else if (level === 2) {
rootLevelClass = classes.rootLevel2
typographyVariant = 'h3'
contentLevelClass = classes.contentLevel12
}
return (
<div className={`${classes.root} ${rootLevelClass}`}>
<ListItem button onClick={handleClick} className={classes.header}>
<ListItemText primary={<Typography variant={typographyVariant}>{label}</Typography>} />
<div style={{ display: 'flex' }}>
{!open && (
<Typography variant="body2" className={classes.infoText}>
{info}
</Typography>
)}
{open ? <ExpandLess /> : <ExpandMore />}
</div>
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<div className={contentLevelClass}>{children}</div>
</Collapse>
</div>
)
}
Example #6
Source File: Scores.tsx From dashboard with Apache License 2.0 | 5 votes |
Scores = ({ score, nested }: ScoreProps) => {
const [show, setShow] = useState(false)
const { palette } = useTheme()
let { op_name, operands, value, ref_id, description } = score
if (!op_name && !operands && !value) {
return <></>
}
const toggleShow = () => {
setShow((prev) => !prev)
}
const canToggle = operands && operands.length > 0
return (
<div style={{ paddingLeft: nested ? "10px" : "0px" }}>
<ListItem button={canToggle} onClick={toggleShow}>
<Grid container>
<Grid item xs={4}>
<Box paddingTop="0.75rem">
<Typography noWrap fontSize="1.25rem">
{score.value || "0.12341234"}
</Typography>
</Box>
</Grid>
<Grid item xs={7}>
<Box>
<Typography noWrap>{op_name}</Typography>
<Typography noWrap color={palette.grey[500]}>
{description}
</Typography>
</Box>
</Grid>
</Grid>
{canToggle && (
<ListItemSecondaryAction>
({operands?.length}){show ? <ExpandLess /> : <ExpandMore />}
</ListItemSecondaryAction>
)}
</ListItem>
{operands && (
<div>
<Collapse in={show}>
<List>
{operands.map((operand, index) => (
<Scores score={operand} key={`${index}-${ref_id}`} nested />
))}
</List>
</Collapse>
</div>
)}
</div>
)
}
Example #7
Source File: SwaggerView.tsx From dashboard with Apache License 2.0 | 5 votes |
SwaggerView = () => {
const [show, setShow] = useState(false)
const [host, setHost] = useState(getInitialHostAndPort().host)
const [port, setPort] = useState(getInitialHostAndPort().port)
const [endpoint, setEndpoint] = useState(DEFAULT_ENDPOINT)
const [url, setURL] = useState(formatURL(host, port, endpoint))
const updateURL = () => {
setURL(formatURL(host, port, endpoint))
}
const toggleShow = () => {
setShow((prev) => !prev)
}
return (
<Container data-name="debuggingTool">
<Box textAlign="right">
<Button onClick={toggleShow}>
endpoint settings {show ? <ExpandLess /> : <ExpandMore />}
</Button>
</Box>
<Collapse in={show}>
<Box paddingTop="2.5em">
<Grid container spacing={2}>
<Grid item xs={4}>
<TextInput
label="Host"
variant="outlined"
value={host}
onChange={(e) => setHost(e.target.value)}
/>
</Grid>
<Grid item xs={2}>
<TextInput
label="Port"
variant="outlined"
value={port}
onChange={(e) => setPort(e.target.value)}
/>
</Grid>
<Grid item xs={4}>
<TextInput
label="OpenAPI Schema"
variant="outlined"
value={endpoint}
onChange={(e) => setEndpoint(e.target.value)}
/>
</Grid>
<Grid item xs={2}>
<FullSizeButton onClick={updateURL} variant="contained">
Set
</FullSizeButton>
</Grid>
</Grid>
</Box>
</Collapse>
<SwaggerUIReact
url={url}
presets={[WrappedComponents]}
requestInterceptor={(r) => console.log("request:", r)}
responseInterceptor={(r) => console.log("response:", r)}
/>
</Container>
)
}
Example #8
Source File: Facets.tsx From cognitive-search-static-web-apps-sample-ui with MIT License | 5 votes |
render(): JSX.Element {
const state = this.props.state;
return (<FacetList component="nav">
{state.facets.map(facetState => {
var facetComponent: JSX.Element = null;
switch (facetState.facetType) {
case FacetTypeEnum.BooleanFacet:
facetComponent = (<BooleanFacet state={facetState.state as BooleanFacetState} inProgress={this.props.inProgress} />);
break;
case FacetTypeEnum.NumericFacet:
facetComponent = (<NumericFacet state={facetState.state as NumericFacetState} inProgress={this.props.inProgress} />);
break;
case FacetTypeEnum.DateFacet:
facetComponent = (<DateFacet state={facetState.state as DateFacetState} inProgress={this.props.inProgress} />);
break;
case FacetTypeEnum.StringFacet:
facetComponent = (<StringFacet state={facetState.state as StringFacetState} inProgress={this.props.inProgress} />);
break;
case FacetTypeEnum.StringCollectionFacet:
facetComponent = (<StringCollectionFacet state={facetState.state as StringCollectionFacetState} inProgress={this.props.inProgress} />);
break;
}
// Getting reference to a proper getHintText method in this a bit unusual and not very strongly typed way
const getHintTextFunc = facetComponent?.type.getHintText;
return (<div key={facetState.displayName}>
<FacetListItem disableRipple={true} button onClick={() => state.toggleExpand(facetState.fieldName)}>
<ListItemText
primary={facetState.displayName}
secondary={getHintTextFunc ? getHintTextFunc(facetState.state) : ''}
/>
{!!facetState.isExpanded ? <ExpandLess /> : <ExpandMore />}
</FacetListItem>
<Collapse in={facetState.isExpanded} timeout={200} unmountOnExit>
{facetComponent}
</Collapse>
</div>);
})}
</FacetList>);
}
Example #9
Source File: ModTableRow.tsx From ow-mod-manager with MIT License | 4 votes |
ModTableRow: React.FunctionComponent<Props> = ({ mod }) => {
const styles = useStyles();
const theme = useTheme();
const missingDependencyNames = useRecoilValue(missingDependencyIdsState(mod));
const isModOutdated = isOutdated(mod);
const isModBroken = isBroken(mod);
const addonMods = useRecoilValue(addonModList);
const [isAddonsExpanded, setIsAddonsExpanded] = useState(false);
const isAddon = mod.parent && !mod.localVersion;
const enabledMods = useRecoilValue(enabledModList);
const forceExpandAddons = useRecoilValue(isFiltering);
const shouldExpandAddons = forceExpandAddons || isAddonsExpanded;
const rowRef = useRef<HTMLTableRowElement>(null);
const isLoading = useRecoilValue(modIsLoadingState(mod.uniqueName));
useEffect(() => {
if (!isLoading || !rowRef.current) return;
rowRef.current.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest',
});
}, [isLoading]);
const addons = useMemo(
() => addonMods.filter((addon) => addon.parent === mod.uniqueName),
[addonMods, mod.uniqueName]
);
const conflictingMods = useMemo(
() =>
mod.conflicts && mod.conflicts.length > 0
? enabledMods
.filter((enabledMod) =>
mod.conflicts?.includes(enabledMod.uniqueName)
)
.map((enabledMod) => enabledMod.name)
: [],
[enabledMods, mod.conflicts]
);
const isModConflicting = mod.isEnabled && conflictingMods.length > 0;
const handleExpandClick = () =>
setIsAddonsExpanded((isExpanded) => !isExpanded);
const getVersionColor = () => {
if (isModBroken) {
return 'default';
}
if (isModOutdated) {
return 'secondary';
}
if (isInstalled(mod)) {
return 'primary';
}
return 'default';
};
const getVersion = () => {
if (isInstalled(mod)) {
return mod.localVersion;
}
if (mod.remoteVersion) {
return mod.remoteVersion;
}
return modsText.versionNotAvailable;
};
const getClassName = () => {
let className = styles.tableRow;
if (isModBroken || isModConflicting) {
className += ` ${styles.brokenRow}`;
} else if (isLoading) {
className += ` ${styles.loading}`;
} else if (missingDependencyNames.length > 0) {
className += ` ${styles.missingDependencyRow}`;
} else if (isAddon) {
className += ` ${styles.addonRow}`;
}
return className;
};
const getModText = () => {
if (isModBroken) {
return modsText.modLoadError(mod.errors);
}
if (missingDependencyNames.length > 0) {
return modsText.missingDependencyWarning(
missingDependencyNames.join(', ')
);
}
if (isModConflicting) {
return modsText.conflictingModWarning(conflictingMods.join(', '));
}
return mod.description;
};
return (
<>
<TableRow className={getClassName()} key={mod.uniqueName} ref={rowRef}>
<TableCell className={styles.tableCell}>
<Box display="flex">
{isAddon && (
<Box
bgcolor={theme.palette.background.paper}
width="8px"
minWidth="8px"
marginRight={2}
marginLeft={1}
borderRadius="8px"
/>
)}
<Box width="100%">
<Typography variant="subtitle1">
<Box display="inline-block" mr={2}>
{mod.name}
</Box>
<Typography className={styles.modAuthor} variant="caption">
{' by '}
{mod.author}
</Typography>
<Typography variant="caption" />
</Typography>
<Box
color={
isModBroken || isModConflicting
? theme.palette.secondary.light
: theme.palette.text.secondary
}
>
<Typography className={styles.modText} variant="caption">
{getModText()}
</Typography>
</Box>
{addons.length > 0 && !forceExpandAddons && (
<ButtonBase
className={styles.addonExpander}
onClick={handleExpandClick}
>
<Box
display="flex"
alignItems="center"
borderRadius={theme.shape.borderRadius}
maxWidth="100%"
>
{shouldExpandAddons ? <ExpandLess /> : <ExpandMore />}
<Typography variant="caption" noWrap>
{addons.length}
{' addons available: '}
{addons.map((addon) => addon.name).join(', ')}
</Typography>
</Box>
</ButtonBase>
)}
</Box>
</Box>
</TableCell>
<TableCell className={styles.tableCell} align="right">
{mod.downloadCount || '-'}
</TableCell>
<TableCell className={styles.tableCell}>
<Chip
color={getVersionColor()}
label={getVersion()}
className={styles.versionChip}
/>
{!isModBroken && isModOutdated && (
<div className={styles.outdatedChip}>{modsText.outdated}</div>
)}
</TableCell>
<TableCell className={styles.tableCell}>
<ModActions mod={mod} />
</TableCell>
</TableRow>
{shouldExpandAddons &&
addons.map((addon) => (
<ModTableRow key={addon.uniqueName} mod={addon} />
))}
</>
);
}
Example #10
Source File: DomainDetails.tsx From crossfeed with Creative Commons Zero v1.0 Universal | 4 votes |
DomainDetails: React.FC<Props> = (props) => {
const { domainId } = props;
const { getDomain } = useDomainApi(false);
const { user } = useAuthContext();
const [domain, setDomain] = useState<Domain>();
const classes = useStyles();
const history = useHistory();
const fetchDomain = useCallback(async () => {
try {
setDomain(undefined);
const result = await getDomain(domainId);
setDomain(result);
} catch (e) {
console.error(e);
}
}, [domainId, getDomain]);
useEffect(() => {
fetchDomain();
}, [fetchDomain]);
const webInfo = useMemo(() => {
if (!domain) {
return [];
}
const categoriesToProducts: Record<string, Set<string>> = {};
for (const service of domain.services) {
for (const product of service.products) {
const version = product.version ? ` ${product.version}` : '';
const value = product.name + version;
const name =
product.tags && product.tags.length > 0 ? product.tags[0] : 'Misc';
if (!categoriesToProducts[name]) {
categoriesToProducts[name] = new Set();
}
categoriesToProducts[name].add(value);
}
}
return Object.entries(categoriesToProducts).reduce(
(acc, [name, value]) => [
...acc,
{
label: name,
value: Array.from(value).join(', ')
}
],
[] as any
);
}, [domain]);
const overviewInfo = useMemo(() => {
if (!domain) {
return [];
}
const ret = [];
if (domain.ip) {
ret.push({
label: 'IP',
value: domain.ip
});
}
ret.push({
label: 'First Seen',
value: `${differenceInCalendarDays(
Date.now(),
parseISO(domain.createdAt)
)} days ago`
});
ret.push({
label: 'Last Seen',
value: `${differenceInCalendarDays(
Date.now(),
parseISO(domain.updatedAt)
)} days ago`
});
if (domain.country) {
ret.push({
label: 'Country',
value: domain.country
});
}
if (domain.cloudHosted) {
ret.push({
label: 'Cloud Hosted',
value: 'Yes'
});
}
ret.push({
label: 'Organization',
value: domain.organization.name
});
return ret;
}, [domain]);
const [hiddenRows, setHiddenRows] = React.useState<{
[key: string]: boolean;
}>({});
const formatBytes = (bytes: number, decimals = 2): string => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
};
const generateWebpageList = (tree: any, prefix = '') => {
return (
<List
className={`${classes.listRoot}${prefix ? ' ' + classes.nested : ''}`}
>
{Object.keys(tree).map((key) => {
const isWebpage =
'url' in tree[key] && typeof tree[key]['url'] === 'string';
if (!isWebpage) {
const newPrefix = prefix + '/' + key;
return (
<>
<ListItem
button
onClick={() => {
setHiddenRows((hiddenRows: any) => {
hiddenRows[newPrefix] =
newPrefix in hiddenRows ? !hiddenRows[newPrefix] : true;
return { ...hiddenRows };
});
}}
key={newPrefix}
>
<ListItemText primary={(prefix ? '' : '/') + key + '/'} />
{hiddenRows[newPrefix] ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
in={!hiddenRows[newPrefix]}
timeout="auto"
unmountOnExit
>
{generateWebpageList(tree[key], newPrefix)}
</Collapse>
</>
);
}
const page = tree[key] as Webpage;
const parsed = new URL(page.url);
const split = parsed.pathname
.replace(/\/$/, '') // Remove trailing slash
.split('/');
return (
<ListItem
button
divider={true}
key={page.url}
onClick={() => window.open(page.url, '_blank')}
>
<ListItemText
primary={(prefix ? '' : '/') + split.pop()}
secondary={
page.status + ' • ' + formatBytes(page.responseSize ?? 0, 1)
}
></ListItemText>
</ListItem>
);
})}
</List>
);
};
if (!domain) {
return null;
}
const url =
(domain.services.find((service) => service.port === 443)
? 'https://'
: 'http://') + domain.name;
const { webpages = [] } = domain;
webpages.sort((a, b) => (a.url > b.url ? 1 : -1));
const webpageTree = generateWebpageTree(webpages);
const webpageList = generateWebpageList(webpageTree);
return (
<Paper classes={{ root: classes.root }}>
<div className={classes.title}>
<h4>
<Link to={`/inventory/domain/${domain.id}`}>{domain.name}</Link>
</h4>
<a href={url} target="_blank" rel="noopener noreferrer">
<LinkOffIcon />
</a>
</div>
<div className={classes.inner}>
{overviewInfo.length > 0 && (
<div className={classes.section}>
<h4 className={classes.subtitle}>Overview</h4>
<DefinitionList items={overviewInfo} />
</div>
)}
{webInfo.length > 0 && (
<div className={classes.section}>
<h4 className={classes.subtitle}>Known Products</h4>
<DefinitionList items={webInfo} />
</div>
)}
{domain.vulnerabilities.length > 0 && (
<div className={classes.section}>
<h4 className={classes.subtitle}>Vulnerabilities</h4>
<Accordion className={classes.accordionHeaderRow} disabled>
<AccordionSummary>
<Typography className={classes.accordionHeading}>
Title
</Typography>
<Typography className={classes.vulnDescription}>
Serverity
</Typography>
<Typography className={classes.vulnDescription}>
State
</Typography>
<Typography className={classes.vulnDescription}>
Created
</Typography>
</AccordionSummary>
</Accordion>
{domain.vulnerabilities.map((vuln) => (
<Accordion
className={classes.accordion}
key={vuln.id}
onClick={(event) => {
event.stopPropagation();
history.push('/inventory/vulnerability/' + vuln.id);
}}
>
<AccordionSummary>
<Typography className={classes.accordionHeading}>
{vuln.title}
</Typography>
<Typography className={classes.vulnDescription}>
{vuln.severity}
</Typography>
<Typography className={classes.vulnDescription}>
{vuln.state}
</Typography>
<Typography className={classes.vulnDescription}>
{vuln.createdAt
? `${differenceInCalendarDays(
Date.now(),
parseISO(vuln.createdAt)
)} days ago`
: ''}
</Typography>
</AccordionSummary>
</Accordion>
))}
</div>
)}
{domain.services.length > 0 && (
<div className={classes.section}>
<h4 className={classes.subtitle}>Ports</h4>
<Accordion className={classes.accordionHeaderRow} disabled>
<AccordionSummary expandIcon={<ExpandMore />}>
<Typography className={classes.accordionHeading}>
Port
</Typography>
<Typography className={classes.accordionHeading}>
Products
</Typography>
<Typography className={classes.lastSeen}>Last Seen</Typography>
</AccordionSummary>
</Accordion>
{domain.services.map((service) => {
const products = service.products
.map(
(product) =>
product.name +
(product.version ? ` ${product.version}` : '')
)
.join(', ');
return (
<Accordion className={classes.accordion} key={service.id}>
<AccordionSummary expandIcon={<ExpandMore />}>
<Typography className={classes.accordionHeading}>
{service.port}
</Typography>
<Typography className={classes.accordionHeading}>
{products}
</Typography>
<Typography className={classes.lastSeen}>
{service.lastSeen
? `${differenceInCalendarDays(
Date.now(),
parseISO(service.lastSeen)
)} days ago`
: ''}
</Typography>
</AccordionSummary>
{service.products.length > 0 && (
<AccordionDetails>
<DefinitionList
items={[
{
label: 'Products',
value: products
},
{
label: 'Banner',
value:
(user?.userType === 'globalView' ||
user?.userType === 'globalAdmin') &&
service.banner
? service.banner
: 'None'
}
]}
/>
</AccordionDetails>
)}
</Accordion>
);
})}
</div>
)}
{domain.webpages?.length > 0 && (
<div className={classes.section}>
<h4 className={classes.subtitle}>Site Map</h4>
{webpageList}
</div>
)}
</div>
</Paper>
);
}
Example #11
Source File: FlowChartNodes.tsx From dashboard with Apache License 2.0 | 4 votes |
PropertyListItem = ({
itemKey,
itemValue,
nested,
}: {
itemKey: string
itemValue: any
nested?: boolean
}) => {
const [show, setShow] = useState(false)
const { palette } = useTheme()
const toggleShow = () => {
setShow((prev) => !prev)
}
let isObject = false
if (typeof itemValue === "object" && itemValue !== null) {
isObject = true
}
if (isObject && isEmpty(itemValue)) return null
if (
itemValue === 0 ||
itemValue === "unset" ||
itemValue === null ||
itemValue === "" ||
itemValue === {}
)
return null
return (
<div
style={{
marginLeft: nested ? "2em" : "0px",
borderLeft: `1px solid ${palette.grey[500]}`,
backgroundColor: show
? isObject
? `${palette.grey[100]}80`
: palette.grey[200]
: "inherit",
}}
>
<ListItem button onClick={toggleShow} style={{ paddingLeft: "0px" }}>
<Grid container>
<Grid item xs={6}>
<Typography noWrap>
<ListMarker color={palette.grey[500]} />
{itemKey}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography noWrap>
{isObject ? (
<LightText color={palette.grey[500]}>Object</LightText>
) : (
String(itemValue)
)}
</Typography>
</Grid>
</Grid>
<ListItemSecondaryAction>
{isObject && <>({Object.keys(itemValue).length})</>}
{show ? <ExpandLess /> : <ExpandMore />}
</ListItemSecondaryAction>
</ListItem>
<Collapse in={show}>
{isObject ? (
Object.keys(itemValue).length ? (
show && <PropertyList data={itemValue} nested />
) : (
<ListItem>
<WrappedText>This Object is empty</WrappedText>
</ListItem>
)
) : (
<ListItem>
<WrappedText>
<div>
<b>key: </b>
{itemKey}
</div>
<div>
<b>value: </b>
{itemValue}
</div>
</WrappedText>
</ListItem>
)}
</Collapse>
</div>
)
}