Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

2017.10.11 MDL or MDC

Endre Bock edited this page Oct 12, 2017 · 1 revision

MDL or MDC? This is the question!

Ok, I want to do a Google like Application.
So the first search lead into MDL. But as I wrote in my blog before, the MDL has some issue, which is coming from the dynamic changing HTML(Document).

First I thought is came from the [Live JSX] loader. But later on I realized, that the app of course changing often the document. So each time to downgrade the whole document and then to upgrade seems not the right way. I feared to strong, that will lead into heavy lags on screen.

So I searched around and took a look in the HTML of the Google Cloud Console.
I found here the AngularJS Material. Of course it's Google ;) But I don't want create a Angular App (yet). So my seach continued...

...and lead me to the Material Design. Ahh, Google again... so I dived into the Guidelines, Icons and Components.
In the Architecture Overview I found what I way searching for. The Google look and feel together with components.

Now I decide to use the MDC now.
As next I searched for React connection, but found many uncomplete libraries. I wondered a bit and try to do my own connection with Drawer component. The result surprised my a bit:

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import * as MDC from '@material/drawer';

/**
 * MDC drawer implementation.
 */
class Drawer extends React.Component {
  /**
   * Supported property types.
   */
  static get propTypes() {
    return {
      className: PropTypes.string.isRequired,
      onOpen:    PropTypes.func,
      onClose:   PropTypes.func,
      open:      PropTypes.bool
    };
  }

  /**
   * Proxy open event, if bound.
   * @param event
   */
  onOpen(event) {
    if (this.props.onOpen) {
      this.props.onOpen(event);
    }
  }

  /**
   * Proxy close event, if bound.
   * @param event
   */
  onClose(event) {
    if (this.props.onClose) {
      this.props.onClose(event);
    }
  }

  /**
   * Connect MDC after mount.
   */
  componentDidMount() {
    this.domNode = ReactDOM.findDOMNode(this);
    switch (this.props.className) {
      case 'mdc-persistent-drawer':
        this.drawer = new MDC.MDCPersistentDrawer(this.domNode);
        this.domNode.addEventListener('MDCPersistentDrawer:open', this.onOpen.bind(this));
        this.domNode.addEventListener('MDCPersistentDrawer:close', this.onClose.bind(this));
        break;
      case 'mdc-temporary-drawer':
        this.drawer = new MDC.MDCTemporaryDrawer(this.domNode);
        this.domNode.addEventListener('MDCTemporaryDrawer:open', this.onOpen.bind(this));
        this.domNode.addEventListener('MDCTemporaryDrawer:close', this.onClose.bind(this));
        break;
      default: break;
    }

    if (this.drawer) {
      this.drawer.open = this.props.open;
    }
  }

  /**
   * Destroy drawer on unmount.
   */
  componentWillUnmount() {
    if (this.drawer) {
      this.drawer.destroy();
    }
  }

  /**
   * Update props on drawer component if exists.
   */
  componentDidUpdate()
  {
    if (this.drawer) {
      this.drawer.open = this.props.open;
    }
  }

  /**
   * Generate the output.
   */
  render() {
    // No special adding into dom tree, passing children as own level.
    return this.props.children;
  }
}

export default Drawer;

That seems very simple. My methodology here is, not to rebuild the whole MDC. I just will cover the "Using the JS Component" area. The HTML block I still let in the HTML Template. So I'm able to change the display, if needed, without recode my component or the "connection to Rect" code.