Home > OS >  How to change the border of a specific button when it is clicked using useState in Material UI?
How to change the border of a specific button when it is clicked using useState in Material UI?

Time:08-12

I have three buttons. What I want to achieve is to emphasize an active button(right after it is clicked) by displaying its border color, while the unclicked buttons will remain neutral until they are clicked. Only one button out of the three should be highlighted right after it has been clicked. But currently I am having trouble since it doesn't seem to work on handling the event.

The goal appearance:

Goal appearance of buttons pic

source code:

import * as React from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";

export default function TestSample() {
  
    const [selectedIndex2, setSelectedIndex2] = React.useState("");

    const handleListItemClick2 = (event, index) => {
      setSelectedIndex2(index);
    };


return (
  <Stack spacing={2} direction="row" sx={{ mt: 3, ml: 5 }}>
    <Button
      variant="outlined"
      sx={{
        "&.Mui-selected": {
        
        },
        "&.Mui-focusVisible": {
       
          border: "3px solid #F2A42A",
        },
        ":hover": {
        
          border: "3px solid #F2A42A",
        },

        width: 131,
        textTransform: "none",
        height: 42,
        borderRadius: 3,
        fontFamily: "Barlow Condensed",
        fontSize: "22px",
     
      }}
      selected={selectedIndex2 === 0}
      onClick={(event) => handleListItemClick2(event, 0)}
    >
      Dine In
    </Button>
    <Button
      variant="outlined"
      sx={{
        "&.Mui-selected": {
       
          border: "3px solid #F2A42A",
        },
        "&.Mui-focusVisible": {
       
          border: "3px solid #F2A42A",
        },
        ":hover": {
       
          border: "3px solid #F2A42A",
        },
        width: 131,
        height: 42,
        textTransform: "none",
        borderRadius: 3,
        fontFamily: "Barlow Condensed",
        fontSize: "22px",
     
      }}
      selected={selectedIndex2 === 1}
      onClick={(event) => handleListItemClick2(event, 1)}
    >
      Pickup
    </Button>
    <Button
      variant="outlined"
      sx={{
        "&.Mui-selected": {
       
          border: "3px solid #F2A42A",
        },
        "&.Mui-focusVisible": {
        
          border: "3px solid #F2A42A",
        },
        ":hover": {
         
          border: "3px solid #F2A42A",
        },
        width: 131,
        height: 42,
        textTransform: "none",
        borderRadius: 3,
        fontFamily: "Barlow Condensed",
        fontSize: "22px",
     
      }}
      selected={selectedIndex2 === 2}
      onClick={(event) => handleListItemClick2(event, 2)}
    >
      Delivery
    </Button>
  </Stack>
);
}

A similar functionality can be found here(but it's React version is outdated compared to mine): https://codesandbox.io/s/white-rain-ye62u?fontsize=14&hidenavigation=1&theme=dark&file=/src/multipleButtons.js

Your responses would indeed help me a lot in my project that I am working, as I am also exploring MUI.

Thank you very much!

CodePudding user response:

Here is a solution using :focus instead of :hover

import "./styles.css";
import MultipleButtons from "./MultipleButtons";

export default function App() {
  return (
    <div className="App">
      <MultipleButtons />
    </div>
  );
}

I created a ButtonComponent so you don't have all that repeated styles

import * as React from "react";
import Button from "@mui/material/Button";

export default function ButtonComponent({ title }) {
  return (
    <Button
      variant="outlined"
      sx={{
        "&.Mui-selected": {},
        "&.Mui-focusVisible": {
          border: "3px solid #F2A42A"
        },
        ":focus": {
          border: "3px solid #F2A42A"
        },

        width: 131,
        textTransform: "none",
        height: 42,
        borderRadius: 3,
        fontFamily: "Barlow Condensed",
        fontSize: "22px"
      }}
    >
      {title}
    </Button>
  );
}

And in MultipleButtons

import * as React from "react";
import Stack from "@mui/material/Stack";
import ButtonComponent from "./ButtonComponent";

export default function MultipleButtons() {
  return (
    <Stack
      spacing={2}
      direction="row"
      justifyContent="space-evenly"
      sx={{ mt: 3, ml: 5, p: 3, background: "#1F1D2B" }}
    >
      <ButtonComponent title="Dine in" />
      <ButtonComponent title="Pick up" />
      <ButtonComponent title="Delivery" />
    </Stack>
  );
}
  • Related