Search code examples
javascriptreactjsmaterial-uimui-x-data-grid

How to change background color of all elements before the element I clicked in a grid


enter image description here

I want to achieve something like this, when I click on 20 numbered block, everything before that changes to light orange. I have this attached sandbox code, if anyone can guide what to add in the handleClick function would be grateful https://codesandbox.io/s/adoring-cherry-by6u9b?file=/demo.tsx


Solution

  • Made some changes in your playground: codesandbox.io

    Basic idea is that you need to save the current clicked index and then to pass the custom backgroundColor property to your styled component if the element's index is smaller than the clicked index.

    const Item = styled(Paper)(({ theme, customBackground }) => ({
      backgroundColor: customBackground
        ? customBackground
        : theme.palette.mode === "dark"
        ? "#1A2027"
        : "#fff",
      ...theme.typography.body2,
      padding: theme.spacing(2),
      textAlign: "center",
      color: theme.palette.text.secondary
    }));
    
    export default function ResponsiveGrid() {
      const [selectedIndex, setSelectedIndex] = React.useState(null);
    
      const handleClick = React.useCallback((e, index) => {
        setSelectedIndex(index);
      }, []);
    
      return (
        <Box sx={{ flexGrow: 1 }}>
          <Grid container spacing={{ xs: 0.5 }} columns={{ xs: 8 }}>
            {Array.from(Array(102)).map((_, index) => (
              <Grid xs={2} key={index}>
                <Item
                  customBackground={
                    index < selectedIndex
                      ? "orange"
                      : index === selectedIndex
                      ? "darkorange"
                      : "white"
                  }
                  onClick={(e) => handleClick(e, index)}
                >
                  {index + 1}
                </Item>
              </Grid>
            ))}
          </Grid>
        </Box>
      );
    }