Lambert Lambert - 2 months ago 30
React JSX Question

Accordion and Dialog components for Material Design Lite

Are there any accordion and modal dialog components available and actually work that are compatible with my environment of:

Google's Material Design Lite version 1.06

Facebook's ReactJS 0.14.2

Microsoft's TypeScript and Visual Studio 2015 (for typescript bundling)

I am trying to avoid JavaScript library bloat and Material Design Lite is missing these essential widgets. I'm not using Node.js since I'm on a Windows platform so Material-UI is not an option. MaterializeCSS bloats my Visual Studio project and makes it really slow and unusable.

Answer

Update Sep 28,2016

It looks like there is now an open-source library for doing just this: https://github.com/fiffty/react-treeview-mui


Self Implementation

This answer serves as an example for an Accordion dropdown built using React, though not styled as Material Design. You would need to do that yourself.

This setup requires a hierarchy object of parent > child objects/arrays. This base class should be able to handle very deep depths just fine. It uses recursion for its structure setup. I'll also be using ES6 syntax for preference, as it helps setup the recursion easier for me.

Accordion Class:

// Accordian Class
// Dynamic/Recursive
// a parent>child>child... relationship is required
// the whole object can be named however you like,
// but each child object needs to be identified as "children"
class Accordian extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      openLevelRow: "", // this is the current open level row in an accordian (starts out with none being open)
      selfLevelObject: props.newLevel // the current level object containing all rows and their data/children
    };
  }

  // This is our toggle open/close method
  // if row is already open, close it
  // uniqueSelector is unique per row, and also a key
  // in the selfLevelObject (could be a name, id)
  toggleOpenClose(uniqueSelector) {
    // simple ternary assignment
    this.setState({
      openLevelRow: this.state.openLevelRow != uniqueSelector ? uniqueSelector : ""
    });
  }

  render () {  
    // deconstruct assignment from state
    const { selfLevelObject, openLevelRow } = this.state

    return (
      <div>
          {selfLevelObject.map((row, i) =>
              {/* Collectively where all children of the same hierchy level are listed*/}
              <div className="accordian-hold-self-level" key={i} >
                {/* This is an individual collapsable Row */}
                <div onClick={this.toggleOpenClose.bind(this, row.uniqueSelector)} className="accordian-title-row">
                  <p className='accordian-title'> {row.title}</p>
                </div>
                {/* 
                    When iterating the list, find out if a row has been opened
                */}
                {this.state.openLevelRow != row.uniqueSelector ? <span></span> : 
                    /* 
                      This code block is called if the current row is opened
                      now we to need to find out if there are children,
                      if not, then we are at the bottom, do what ever 
                      you'd like with the bottom row
                    */
                    selfLevelObject[uniqueSelector].children != undefined ? 
                      <Accordian newLevel={selfLevelObject[uniqueSelector].children} /> 
                      : // else
                    // TODO - whatever you want with bottom row
                }
              </div> 
          )}
        </div>
    );
  }
}

Accordian.propTypes = {
    newLevel: React.PropTypes.object
}