Venkaiah Yepuri
Venkaiah Yepuri

Reputation: 1651

How can we customize @material ui <ExpansionPanelSummary> expandIcon with Add & Remove Icons?

I am very new to ReactJS and @Material UI & I tried different ways to workout but no luck yet. Can someone please guide me how I can override ExpandLess and ExpandMore icons with Add and Remove icons of expandIcon. Here is code https://stackblitz.com/edit/react-d2xrnq. And I also notice @Material UI <ExpansionPanel> component using defaultExpanded attribute to expand all Expansion Panel's by default. So, is there any way to collapse all expanded Expansion Panel's with single click?

Thank you so much in advance for your time.

Upvotes: 1

Views: 5742

Answers (1)

Thomas Hennes
Thomas Hennes

Reputation: 9939

  1. Using different icons is simply a case of importing them and using them in place of ExpandMoreIcon. In addition, we track every single panel's state (see point 2. below) and use a ternary to decide which icon to display depending on that state.
  <ExpansionPanelSummary
    expandIcon={
      this.state.expanded[statIndex]
      ? <Remove onClick={this.handleToggleOne(statIndex)} />
      : <Add onClick={this.handleToggleOne(statIndex)} />
    }
  >
    // panel contents
  </ExpansionPanelSummary>
  1. We keep track of individual panel states in the expanded array in state, and we also keep track off a 'grouped' toggle through expandAll boolean in state. expandAll is set to false by default, and the expanded array is initialized to all false values (as many as there are panels) when the panels are loaded.

Each collapsible panel's expanded prop is set to the corresponding expanded array value in state. This determines the state of the panel (collapsed if false, expanded if true).

We set up two handlers: handleToggleOne is curried with the panel's index, and attached to the expand/collapse icon for that panel. It individually sets the state of the panel at the stated index.

  handleToggleOne = (index) => () => {
    const { expanded } = this.state
    expanded[index] = !expanded[index]
    this.setState({ expanded })
  }

handleToggleAll is used to toggle all panels open or closed at once. We keep track and toggle the expandAll value in state, and set each element in the expanded array to that value. The handler is then attached to a global 'Toggle All' Button.

  handleToggleAll = () => {
    this.setState(state => ({ expandAll: !state.expandAll, expanded: state.expanded.map(e => !state.expandAll) }))
  }

You can find a working fork of your code here: https://react-wd5uxp.stackblitz.io

(code editor link: https://stackblitz.com/edit/react-wd5uxp)

Upvotes: 4

Related Questions