Im working on a image carousel in my react project, I got it all to work but im struggling to get the side buttons to center vertically. I've put the three elements in a flexbox with both alignContent:"center", and justifyContent:"center" but the buttons wont seem to move. The image however centers as normal. Please help!
I've included the full code of the component aswell as a screenshot of the slider.
import { Box, IconButton, Button } from "#mui/material";
import React, { useState } from "react";
import NavigateNextIcon from "#mui/icons-material/NavigateNext";
import NavigateBeforeIcon from "#mui/icons-material/NavigateBefore";
const slides = [
{
name: "search",
img: "https://cdn.pixabay.com/photo/2022/04/24/16/52/animal-7154059_960_720.jpg",
},
{
name: "sales",
img: "https://cdn.pixabay.com/photo/2022/06/26/12/48/animal-7285343_960_720.jpg",
},
{
name: "about",
img: "https://cdn.pixabay.com/photo/2022/07/22/19/42/marmot-7338831_960_720.jpg",
},
];
function Slider() {
const [currSlide, setCurrSlide] = useState(0);
function handleSlide(e) {
if (currSlide === slides.length - 1 && e === "next") {
setCurrSlide(0);
console.log(currSlide);
} else if (currSlide === 0 && e === "previous") {
setCurrSlide(slides.length - 1);
console.log(currSlide);
} else {
if (e === "next") {
setCurrSlide(currSlide + 1);
console.log(currSlide);
} else {
setCurrSlide(currSlide - 1);
console.log(currSlide);
}
}
}
return (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignContent: "center",
width: "100%",
height: "auto",
}}
>
<Button
onClick={() => handleSlide("previous")}
sx={{
color: "primary",
height: 50,
width: 50,
}}
>
<NavigateBeforeIcon fontSize="large" />
</Button>
<Box
component="img"
sx={{
height: "auto",
width: "80%",
objectFit: "contain",
}}
src={slides[currSlide]["img"]}
/>
<Button
onClick={() => handleSlide("next")}
sx={{
color: "primary",
height: 50,
width: 50,
}}
>
<NavigateNextIcon fontSize="large" />
</Button>
</Box>
);
}
export default Slider;
Slider
Instead of alignContent: "center" use alignItems: "center". This will align all three elements to the center.
Related
I want to make a progress bar in image with Material UI in React like this:
I tried with a customProgress bar, something like:
export const CustomLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 35,
borderRadius: 3,
[`&.${ linearProgressClasses.colorPrimary }`]: {
backgroundColor: '#00b4e559',
},
[`&.${ linearProgressClasses.bar }`]: {
borderRadius: 3,
backgroundColor: "#00B4E5"
},
}));
but it doesn't work.
You can use MUI's CircularProgress component and add a label for the progress percent inside it.
import * as React from "react";
import CircularProgress, {
CircularProgressProps,
} from "#mui/material/CircularProgress";
import Typography from "#mui/material/Typography";
import Box from "#mui/material/Box";
function CircularProgressWithLabel(
props: CircularProgressProps & { value: number }
) {
return (
<Box sx={{ position: "relative", display: "inline-flex" }}>
<CircularProgress
variant="determinate"
size={150}
thickness={5}
{...props}
/>
<Box
sx={{
top: 0,
left: 0,
bottom: 0,
right: 0,
position: "absolute",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Typography
variant="caption"
component="div"
color="text.secondary"
>{`${Math.round(props.value)}%`}</Typography>
</Box>
</Box>
);
}
export default function CircularStatic() {
const [progress, setProgress] = React.useState(10);
React.useEffect(() => {
const timer = setInterval(() => {
setProgress((prevProgress) =>
prevProgress >= 100 ? 0 : prevProgress + 10
);
}, 800);
return () => {
clearInterval(timer);
};
}, []);
return <CircularProgressWithLabel value={progress} />;
}
Change size and thickness props to achieve the style you want.
Learn more ways to control your circular progress in it's API page.
I've been digging around and can't find a method to modify/contain the width of an imported Material UI Drawer Swipeable edge.My idea was that this be of type Bottom but not take up the entire width of the screen.
I was able to change the width of the top with the use of sx. But when it continues to expand, it continues to occupy the entire screen.
Drawer Expanded and unexpanded
Here is the component code:
import "../sheets/Drawer3.module.css";
import "../sheets/Drawer3.css";
import * as React from 'react';
import PropTypes from 'prop-types';
import { Global } from '#emotion/react';
import { styled } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline';
import { grey } from '#mui/material/colors';
import Button from '#mui/material/Button';
import Box from '#mui/material/Box';
import Typography from '#mui/material/Typography';
import SwipeableDrawer from '#mui/material/SwipeableDrawer';
const drawerBleeding = 56;
const Root = styled('div')(({ theme }) => ({
height: '100%',
backgroundColor:
theme.palette.mode === 'light' ? grey[100] : theme.palette.background.default,
}));
const StyledBox = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'light' ? '#fff' : grey[800],
}));
const Puller = styled(Box)(({ theme }) => ({
width: 30,
height: 6,
backgroundColor: theme.palette.mode === 'light' ? grey[300] : grey[900],
borderRadius: 3,
position: 'absolute',
top: 8,
left: 'calc(50% - 15px)',
}));
function Drawer3(props) {
const { window } = props;
const [open, setOpen] = React.useState(false);
const toggleDrawer = (newOpen) => () => {
setOpen(newOpen);
};
// This is used only for the example
const container = window !== undefined ? () => window().document.body : undefined;
return (
<div>
<Root >
<CssBaseline />
<Global
styles={{
'.MuiDrawer-root > .MuiPaper-root': {
height: `calc(50% - ${drawerBleeding}px)`,
overflow: 'visible',
},
}}
/>
<Box sx={{ textAlign: 'center', pt: 1 }}>
<Button onClick={toggleDrawer(true)}>Open</Button>
</Box>
<SwipeableDrawer
container={container}
anchor="bottom"
open={open}
onClose={toggleDrawer(false)}
onOpen={toggleDrawer(true)}
swipeAreaWidth={drawerBleeding}
disableSwipeToOpen={false}
ModalProps={{
keepMounted: true,
}}
>
<StyledBox
sx={{
position: 'absolute',
top: -drawerBleeding,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
visibility: 'visible',
right: 0,
left: 0,
margin: "auto",
width: 350,
}}
>
<Puller />
<Typography sx={{ p: 2, color: 'text.secondary' }}>51 results</Typography>
</StyledBox>
</SwipeableDrawer>
</Root>
</div>
);
}
Drawer3.propTypes = {
window: PropTypes.func,
};
export default Drawer3;
I've looked through the Material Ui documentation and didn't find any props that modify the width. Thank you in advance for your attention.
Add width and left property inside Global as per below code.
<Global
styles={{
'.MuiDrawer-root > .MuiPaper-root': {
height: `calc(50% - ${drawerBleeding}px)`,
width:350,
left: `calc(50% - 175px)`,
overflow: 'visible',
},
}}
/>
I added swipeable drawer based on the documentation:
Swipeable You can make the drawer swipeable with the SwipeableDrawer
component.
This component comes with a 2 kB gzipped payload overhead. Some
low-end mobile devices won't be able to follow the fingers at 60 FPS.
You can use the disableBackdropTransition prop to help.
{(['left', 'right', 'top', 'bottom'] as const).map((anchor) => (
<React.Fragment key={anchor}>
<Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button>
<SwipeableDrawer
anchor={anchor}
open={state[anchor]}
onClose={toggleDrawer(anchor, false)}
onOpen={toggleDrawer(anchor, true)}
>
{list(anchor)}
</SwipeableDrawer>
</React.Fragment>
))}
The problem with this is that it's only draggable on mobile device. Is it possible to make it draggable on desktop?
Like the user clicks on the edge with the cursor and drags the drawer to close or open it.
Especially, by adding an edge that the user can click on with the cursor:
Swipeable edge You can configure the SwipeableDrawer to have a visible
edge when closed.
If you are on a desktop, you can toggle the drawer with the "OPEN"
button. If you are on mobile, you can open the demo in CodeSandbox
("edit" icon) and swipe.
import * as React from 'react';
import PropTypes from 'prop-types';
import { Global } from '#emotion/react';
import { styled } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline';
import { grey } from '#mui/material/colors';
import Button from '#mui/material/Button';
import Box from '#mui/material/Box';
import Skeleton from '#mui/material/Skeleton';
import Typography from '#mui/material/Typography';
import SwipeableDrawer from '#mui/material/SwipeableDrawer';
const drawerBleeding = 56;
const Root = styled('div')(({ theme }) => ({
height: '100%',
backgroundColor:
theme.palette.mode === 'light' ? grey[100] : theme.palette.background.default,
}));
const StyledBox = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'light' ? '#fff' : grey[800],
}));
const Puller = styled(Box)(({ theme }) => ({
width: 30,
height: 6,
backgroundColor: theme.palette.mode === 'light' ? grey[300] : grey[900],
borderRadius: 3,
position: 'absolute',
top: 8,
left: 'calc(50% - 15px)',
}));
function SwipeableEdgeDrawer(props) {
const { window } = props;
const [open, setOpen] = React.useState(false);
const toggleDrawer = (newOpen) => () => {
setOpen(newOpen);
};
// This is used only for the example
const container = window !== undefined ? () => window().document.body : undefined;
return (
<Root>
<CssBaseline />
<Global
styles={{
'.MuiDrawer-root > .MuiPaper-root': {
height: `calc(50% - ${drawerBleeding}px)`,
overflow: 'visible',
},
}}
/>
<Box sx={{ textAlign: 'center', pt: 1 }}>
<Button onClick={toggleDrawer(true)}>Open</Button>
</Box>
<SwipeableDrawer
container={container}
anchor="bottom"
open={open}
onClose={toggleDrawer(false)}
onOpen={toggleDrawer(true)}
swipeAreaWidth={drawerBleeding}
disableSwipeToOpen={false}
ModalProps={{
keepMounted: true,
}}
>
<StyledBox
sx={{
position: 'absolute',
top: -drawerBleeding,
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
visibility: 'visible',
right: 0,
left: 0,
}}
>
<Puller />
<Typography sx={{ p: 2, color: 'text.secondary' }}>51 results</Typography>
</StyledBox>
<StyledBox
sx={{
px: 2,
pb: 2,
height: '100%',
overflow: 'auto',
}}
>
<Skeleton variant="rectangular" height="100%" />
</StyledBox>
</SwipeableDrawer>
</Root>
);
}
SwipeableEdgeDrawer.propTypes = {
/**
* Injected by the documentation to work in an iframe.
* You won't need it on your project.
*/
window: PropTypes.func,
};
export default SwipeableEdgeDrawer;
I am new to typeScript and I am using this materialUI premium theme OnePirate and I am using the Footer component and it is working perfectly fine in the js but when I am moving the same Footer component to my project and rename the component to .tsx It throws errors saying "No Overload matches this call"
Here is the code:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Grid from "#material-ui/core/Grid";
import Link from "#material-ui/core/Link";
import Container from "#material-ui/core/Container";
import Typography from "./materialUi/Typography";
import TextField from "./materialUi/TextField";
import fbicon from "./static/themes/onepirate/appFooterFacebook.png";
import twicon from "./static/themes/onepirate/appFooterTwitter.png";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
backgroundColor: theme.palette.secondary.light,
},
container: {
marginTop: theme.spacing(8),
marginBottom: theme.spacing(8),
display: "flex",
},
iconsWrapper: {
height: 120,
},
icons: {
display: "flex",
},
icon: {
width: 48,
height: 48,
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: theme.palette.warning.main,
marginRight: theme.spacing(1),
"&:hover": {
backgroundColor: theme.palette.warning.dark,
},
},
list: {
margin: 0,
listStyle: "none",
paddingLeft: 0,
},
listItem: {
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
},
language: {
marginTop: theme.spacing(1),
width: 150,
},
}));
const LANGUAGES = [
{
code: "en-US",
name: "English",
},
{
code: "fr-FR",
name: "Français",
},
];
function Footer() {
const classes = useStyles();
return (
<Typography component="footer" className={classes.root}>
<Container className={classes.container}>
<Grid container spacing={5}>
<Grid item xs={6} sm={4} md={3}>
<Grid
container
direction="column"
justify="flex-end"
className={classes.iconsWrapper}
spacing={2}
>
<Grid item className={classes.icons}>
<a href="https://material-ui.com/" className={classes.icon}>
<img src={fbicon} alt="Facebook" />
</a>
<a
href="https://twitter.com/MaterialUI"
className={classes.icon}
>
<img src={twicon} alt="Twitter" />
</a>
</Grid>
<Grid item>© 2019 Onepirate</Grid>
</Grid>
</Grid>
<Grid item xs={6} sm={4} md={2}>
<Typography variant="h6" marked="left" gutterBottom>
Legal
</Typography>
<ul className={classes.list}>
<li className={classes.listItem}>
<Link href="/premium-themes/onepirate/terms/">Terms</Link>
</li>
<li className={classes.listItem}>
<Link href="/premium-themes/onepirate/privacy/">Privacy</Link>
</li>
</ul>
</Grid>
<Grid item xs={6} sm={8} md={4}>
<Typography variant="h6" marked="left" gutterBottom>
Language
</Typography>
<TextField
select
SelectProps={{
native: true,
}}
className={classes.language}
>
{LANGUAGES.map((language) => (
<option value={language.code} key={language.code}>
{language.name}
</option>
))}
</TextField>
</Grid>
<Grid item>
<Typography variant="caption">
{"Icons made by "}
<Link
href="https://www.freepik.com"
rel="nofollow"
title="Freepik"
>
Freepik
</Link>
{" from "}
<Link
href="https://www.flaticon.com"
rel="nofollow"
title="Flaticon"
>
www.flaticon.com
</Link>
{" is licensed by "}
<Link
href="https://creativecommons.org/licenses/by/3.0/"
title="Creative Commons BY 3.0"
target="_blank"
rel="noopener noreferrer"
>
CC 3.0 BY
</Link>
</Typography>
</Grid>
</Grid>
</Container>
</Typography>
);
}
export default Footer;
This is the Typography code if I don't import from material UI
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import { capitalize } from "#material-ui/core/utils";
import MuiTypography from "#material-ui/core/Typography";
const styles = (theme) => ({
markedH2Center: {
height: 4,
width: 73,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH3Center: {
height: 4,
width: 55,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH4Center: {
height: 4,
width: 55,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH6Left: {
height: 2,
width: 28,
display: "block",
marginTop: theme.spacing(0.5),
background: "currentColor",
},
});
const variantMapping = {
h1: "h1",
h2: "h1",
h3: "h1",
h4: "h1",
h5: "h3",
h6: "h2",
subtitle1: "h3",
};
function Typography(props) {
const { children, classes, marked = false, variant, ...other } = props;
return (
<MuiTypography variantMapping={variantMapping} variant={variant} {...other}>
{children}
{marked ? (
<span
className={
classes[`marked${capitalize(variant) + capitalize(marked)}`]
}
/>
) : null}
</MuiTypography>
);
}
Typography.propTypes = {
children: PropTypes.node,
classes: PropTypes.object.isRequired,
marked: PropTypes.oneOf([false, "center", "left"]),
variant: PropTypes.string,
};
export default withStyles(styles)(Typography);
This is the error now:
TL;DR: I've open sourced my implementation of onepirate in Typescript so you can just use that: https://github.com/rothbart/onepirate-typescript
This is a great question. Onepirate is a great resource but as you've noticed it isn't really built in a way that's Typescript friendly.
Your problem here is that the Typography implementation in onepirate isn't doing a great job of specifying which properties it expects, and is relying on the fact that vanilla JS will mostly just pass everything through to the underlying MuiTypography component.
Here's a much cleaner Typography implementation that preserves the underline effect in onepirate works with Typescript:
import React from "react";
import PropTypes, { InferProps } from "prop-types";
import {
withStyles,
WithStyles,
createStyles,
Theme,
} from "#material-ui/core/styles";
import MuiTypography, { TypographyProps } from "#material-ui/core/Typography";
const styles = (theme: Theme) =>
createStyles({
markedH2Center: {
height: 4,
width: 73,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH3Center: {
height: 4,
width: 55,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH4Center: {
height: 4,
width: 55,
display: "block",
margin: `${theme.spacing(1)}px auto 0`,
backgroundColor: theme.palette.secondary.main,
},
markedH6Left: {
height: 2,
width: 28,
display: "block",
marginTop: theme.spacing(0.5),
background: "currentColor",
},
});
function getMarkedClassName(variant: string) {
switch (variant) {
case "h2":
return "markedH2Center";
case "h3":
return "markedH3Center";
case "h4":
return "markedH4Center";
}
return "markedH6Left";
}
const variantMapping = {
h1: "h1",
h2: "h1",
h3: "h1",
h4: "h1",
h5: "h3",
h6: "h2",
subtitle1: "h3",
};
function Typography<C extends React.ElementType>(
props: TypographyProps<C, { component?: C }> &
WithStyles<typeof styles> &
InferProps<typeof Typography.propTypes>
) {
const { children, variant, classes, marked, ...other } = props;
return (
<MuiTypography variantMapping={variantMapping} variant={variant} {...other}>
{children}
{marked ? (
<span className={classes[getMarkedClassName(variant as string)]} />
) : null}
</MuiTypography>
);
}
Typography.propTypes = {
marked: PropTypes.oneOf([false, "center", "left"]),
};
Typography.defaultProps = {
marked: false,
};
export default withStyles(styles)(Typography);
Just a heads up that will run into this same problem with other onepirate components as well (I just finished re-implementing most of them in Typescript so I could use them in my own web app). If you're trying to reverse engineer how I did this I'd pay particular attention to how I took advantage of MuiTypography props and then just added the one new property I needed (marked).
TypographyProps<C, { component?: C }> &
WithStyles<typeof styles> &
InferProps<typeof Typography.propTypes>
I'd also highly recommend reading over https://material-ui.com/guides/typescript/ if you haven't already, it's a super helpful guide for understanding some of the Typescript gotchas in Material-UI.
I'd like to create multilevel nested list to display the menu on the left side - - very similar as on oficial site: https://material-ui-next.com/.
data source is in JSON where for each item there's also information about parent item and some other data - - this is the example:
{
"task_number": 1201092,
"task": "Monthly Cash Flow from Deliveries",
"task_parent_number": 1201090,
"task_parent": "Wholesale Cash Flow"
},
{
"task_number": 1201095,
"task": "Monthly Cash Flow from Fix Amounts",
"task_parent_number": 1201090,
"task_parent": "Wholesale Cash Flow"
},
{
"task_number": 1201100,
"task": "Wholesale Positions",
"task_parent_number": 1200007,
"task_parent": "Wholesale Contract Portfolio"
},
{
"task_number": 1201200,
"task": "All Wholesale Positions",
"task_parent_number": 1201100,
"task_parent": "Wholesale Positions"
}
I'am able to create an object with various nested elements - children - if they exist with followin function:
function getNestedChildren(arr, parent) {
var out = [];
for (var i in arr) {
if (arr[i].task_parent_number == parent) {
//console.log(i, arr[i].task_parent_number, arr[i].task_number);
var children = getNestedChildren(arr, arr[i].task_number);
if (children.length) {
arr[i].children = children;
}
out.push(arr[i]);
}
}
return out;
}
I've been following instructions for creating a nested list and importing it here: https://material-ui-next.com/demos/lists/#nested-list
..but I am not able to create a menu with nested elements as desired . . if someone can point me in the right direction would be great..
OK, i got this to work combining these 2 parts:
React example recursive render: https://gist.github.com/nkvenom/bf7b1adfe982cb47dee3
Material List guide here - https://medium.com/#ali.atwa/getting-started-with-material-ui-for-react-59c82d9ffd93
There is mui component.
I add recursion to the last example.
import type { SvgIconProps } from '#mui/material/SvgIcon';
import * as React from 'react';
import { styled } from '#mui/material/styles';
import Box from '#mui/material/Box';
import TreeView, { TreeViewProps } from '#mui/lab/TreeView';
import TreeItem, { TreeItemProps, treeItemClasses } from '#mui/lab/TreeItem';
import Typography from '#mui/material/Typography';
// import DeleteIcon from '#mui/icons-material/Delete';
// import Label from '#mui/icons-material/Label';
// import SupervisorAccountIcon from '#mui/icons-material/SupervisorAccount';
// import InfoIcon from '#mui/icons-material/Info';
// import ForumIcon from '#mui/icons-material/Forum';
// import LocalOfferIcon from '#mui/icons-material/LocalOffer';
import ArrowDropDownIcon from '#mui/icons-material/ArrowDropDown';
import ArrowRightIcon from '#mui/icons-material/ArrowRight';
declare module 'react' {
interface CSSProperties {
'--tree-view-color'?: string;
'--tree-view-bg-color'?: string;
}
}
type StyledTreeItemProps = TreeItemProps & {
bgColor?: string;
color?: string;
labelIcon?: React.ElementType<SvgIconProps>;
labelInfo?: React.ReactNode;
labelText: string;
};
type RecursiveStyledTreeItemProps = StyledTreeItemProps & {
childrenProps?: RecursiveStyledTreeItemProps[]
}
const StyledTreeItemRoot = styled(TreeItem)(({ theme }) => ({
color: theme.palette.text.secondary,
[`& .${treeItemClasses.content}`]: {
color: theme.palette.text.secondary,
borderTopRightRadius: theme.spacing(2),
borderBottomRightRadius: theme.spacing(2),
paddingRight: theme.spacing(1),
fontWeight: theme.typography.fontWeightMedium,
'&.Mui-expanded': {
fontWeight: theme.typography.fontWeightRegular,
},
'&:hover': {
backgroundColor: theme.palette.action.hover,
},
'&.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused': {
backgroundColor: `var(--tree-view-bg-color, ${theme.palette.action.selected})`,
color: 'var(--tree-view-color)',
},
[`& .${treeItemClasses.label}`]: {
fontWeight: 'inherit',
color: 'inherit',
},
},
[`& .${treeItemClasses.group}`]: {
marginLeft: 0,
[`& .${treeItemClasses.content}`]: {
paddingLeft: theme.spacing(2),
},
},
}));
const RecursiveStyledTreeItem = ({ childrenProps, ...p }: RecursiveStyledTreeItemProps) => childrenProps
? <RecursiveStyledTreeItem {...p}>
{
childrenProps.map(cP => <RecursiveStyledTreeItem
key={cP.nodeId}
{...cP}
/>)
}
</RecursiveStyledTreeItem>
: < StyledTreeItem {...p} />
function StyledTreeItem(props: StyledTreeItemProps) {
const {
bgColor,
color,
labelIcon: LabelIcon = null,
labelInfo = null,
labelText,
...other
} = props;
return (
<StyledTreeItemRoot
label={
<Box sx={{ display: 'flex', alignItems: 'center', p: 0.5, pr: 0 }}>
{
LabelIcon && <Box component={LabelIcon} color="inherit" sx={{ mr: 1 }} />
}
<Typography variant="body2" sx={{ fontWeight: 'inherit', flexGrow: 1 }}>
{labelText}
</Typography>
{
labelInfo && <Typography variant="caption" color="inherit">
{labelInfo}
</Typography>
}
</Box>
}
style={{
'--tree-view-color': color,
'--tree-view-bg-color': bgColor,
}}
{...other}
/>
);
}
export default function CustomTreeView({ treeViewProps, items }: {
treeViewProps: Partial<TreeViewProps>
items: RecursiveStyledTreeItemProps[]
}) {
return (
<TreeView
// defaultExpanded={['3']}
defaultCollapseIcon={<ArrowDropDownIcon />}
defaultExpandIcon={<ArrowRightIcon />}
defaultEndIcon={<div style={{ width: 24 }} />}
sx={{ height: 264, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
{...treeViewProps}
>
{items.map(item => <RecursiveStyledTreeItem
key={item.nodeId}
{...item}
/>)}
</TreeView>
);
}
There is mui-tree-select