Skip to content

Working With React

esr360 edited this page Jun 15, 2019 · 6 revisions

Polymorph is essentially a JavaScript tool for styling DOM elements, and React is essentially a JavaScript tool for rendering DOM elements. Thus, Polymorph can be used to style React components so long as your React components render markup that follows the Synergy naming convention (including BEM).

The most simple way to conceptualise the Polymorph API is:

polymorph(Element, styles);

...where Element is the parent DOM node rendered by the React component, and styles is the styles object/function to apply. The way to do this with React is by using refs.

Examples:

Class Component with ComponentDidMount/ComponentDidUpdate

const styles = {...};

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    polymorph(this.myRef.current, styles);
  }

  componentDidUpdate() {
    this.myRef.current.repaint();
  }

  render() {
    return (
      <div className='accordion' ref={this.myRef}>
        ...
      </div>
    );
  }
}

Function Component with UseEffect Hook

const styles = {...};

const MyComponent = () => {
  const myRef = React.createRef();

  useEffect(() => {
    polymorph(myRef.current, styles);
      
    myRef.current.repaint && myRef.current.repaint();
  });

  return (
    <div className='accordion' ref={myRef}>
      ...
    </div>
  );
}

Using Lucid To Render BEM DOM Elements

Lucid is a set of higher-order React components for rendering Synergy modules/BEM DOM Elements

Lucid and Polymorph were built in tandem as part of the Synergy framework, so go hand-in-hand together.

Example

This example is adapted from the Lucid wiki and shows a complete accordion using Lucid for rendering, Polymorph for styling and React Hooks for functionality

const styles = {...};

const Accordion = ({ name = 'accordion', panels, modifiers }) => {
  const [activePanel, setActivePanel] = useState(0);

  return (
    <Module name={name} modifiers={modifiers} styles={styles}>
      {panels.map(({ title, content }, index) => {
        const isActive = (activePanel === index);

        return (
          <Component name='panel' modifiers={[isActive ? 'active' : '']}>
            <Component name='title' onClick={() => setActivePanel(index)}>
              {title}
            </Component>

            <Component name='content'>
              {content}
            </Component>
          </Component>
        )
      })}
    </Module>
  )
};