Skip to content

Modules, Components and Modifiers

esr360 edited this page Feb 29, 2020 · 9 revisions

Synergy is just a practical application of certain theories and philosophies. One of the main philosophies includes the way UI elements are viewed. In a world of HTML and CSS, this could equate to something as simple as a "naming convention" (e.g. BEM), but in a world of abstract UI Modules, an idea with more depth is needed.

Put simply, the way Synergy views a UI is a series of Modules that are composed of Components, both of which can have Modifiers.

See the Synergy Values page for more information

A Synergy Module may resemble the following structure:

|-- modules
|   |-- Accordion
|   |   |-- index.jsx
|   |   |-- config.js
|   |   |-- styles.js

Elements

In Synergy terms, an Element is the encompassing term for both Modules and Components (i.e Modules and Components are examples of Elements).

Modules

Modules are the core building blocks that your system's UI is made of.

  • Modules, along with Components, are considered Elements
  • Modules can have modifiers
  • Modules can contain child Elements (for example, an Accordion Module could contain child Panel Components and/or a child Heading Module)
  • Modules can be nested within other Elements (for example, a Header module could contain a Button module, or a Header Navigation Component could contain an Icon Module) - generally, a Module nested within another Element can also be considered a Component of the containing Element

Some common UI Modules for an app might include:

Accordion Alert-Bar Billboard
Blockquote Breadcrumb Button
Card Carousel Container
Dropdown Footer Form
Header Image List
Logo Modal Navigation
Overlay Preloader Progress-Bar
Table Tabs Tooltip
Scroll-Top Search Side-Nav

If your list of Modules becomes too much, it may be worth considering looking at ways to categorise them.

View a complete example of a Module

Components

Components typically belong to a parent Module

Components are the optional building blocks that your Modules are made of (simple Modules may not require the use of Components). A Component is any Element within a Module that has a direct relationship to the Module.

Not to be confused with React Components

  • Components, along with Modules, are considered Elements
  • Components can have modifiers
  • An Element can simultaneously be a Module and a Component (for example, a Header CTA Component could also be a Button Module) - generally, Modules nested within other Elements can also be thought of as Components of the containing Element
  • Components can be nested within other Components without requiring a direct visual relationship with the containing Component (for example, a Header Navigation Component may contain a Header CTA Component, whose styles should be consistent with other CTAs within the Header, and whose styles have no relationship with the Navigation)

Examples

<Module name='accordion'>
  <Component name='panel'>
    <Component name='title' />
    <Component name='content' />
  </Component>

  <Component name='panel'>
    <Component name='title' />
    <Component name='content' />
  </Component>
</Module>
<Module name='modal'>
  <Component name='title' />
  <Component name='content' />
  <Component name='close' />
</Module>

Sub-Components

Where possible it is recommended to avoid using Sub-Components and stick to regular Components

A Sub-Component is an element that has a direct relationship to a parent Component or parent Sub-Component.

  • Sub-Components are still considered Components for all intents and purposes (and hence also considered Elements)
  • Sub-Components can contain nested Sub-Components (this REALLY should be avoided - e.g. Header Navigation Item Link)
  • Sub-Components can contain regular Components and other Modules without the nested Components/Modules having any visual relationship with the containing Sub-Component (for example, a Heaver Navigation Item Sub-Component could contain a a Header Link Component, whose styles should be consistent with other Links within the Header, and whose styles have no relationship with the Navigation Items)

Example

<Module name='header'>
  <Component name='navigation'>
    <SubComponent name='item'>...</SubComponent>
    ...
  </Component>
</Module>

Which could equate to the following HTML:

<div class="header">
  <div class="header_navigation">
    <div class="header_navigation_item">...</div>
    ...
  </div>
</div>

This is a good use-case for Sub-Components as using <Component> instead would render:

<div class="header">
  <div class="header_navigation">
    <div class="header_item">...</div>
    ...
  </div>
</div>

...which is semantically less meaningful. Using SubComponent in the above example saves from having to do something like:

<Module name='header'>
  <Component name='navigation'>
    <Component name='navItem' />
    ...
  </Component>
</Module>

Since it's recommended to avoid using Sub-Components, the above example should ideally be refactored to make navigation its own Module:

<Module name='header'>
  <Module name='navigation'>
    <Component name='item' />
    ...
  </Module>
</Module>

When to Use

It can be tempting to use Sub-Components, and whilst they do have their legitimate use-cases, always ask yourself if a regular Component would be better. Using too many Sub-Components within a Module can be a sign that your Modules aren't generic enough (which can lead to issues with scalability and maintainability). Consider the following HTML rendered by a hypothetical Accordion Synergy Module:

<div class="accordion">
  <div class="accordion_panel">
    <div class="accordion_panel_title">foo</div>
    <div class="accordion_content">bar</div>
  </div>
  <div class="accordion_panel">
    <div class="accordion_panel_title">fizz</div>
    <div class="accordion_panel_content">buzz</div>
  </div>
</div>

Here accordion_panel_title and accordion_panel_content are Sub-Components, but do they really need to be? The following HTML makes arguably just as much sense:

<div class="accordion-foo-bar">
  <div class="accordion_panel">
    <div class="accordion_title">foo</div>
    <div class="accordion_content">bar</div>
  </div>
  <div class="accordion_panel">
    <div class="accordion_title">fizz</div>
    <div class="accordion_content">buzz</div>
  </div>
</div>

...having replaced the Sub-Components with regular Components. Unfortunately there is no hard way to determine which is more appropriate, as you may feasibly have the following HTML for an accordion:

<div class="accordion">
  <div class="accordion_title">title</div>

  <div class="accordion_panels">
    <div class="accordion_panel">
      <div class="accordion_panel_title">foo</div>
      <div class="accordion_content">bar</div>
    </div>
    <div class="accordion_panel">
      <div class="accordion_panel_title">fizz</div>
      <div class="accordion_panel_content">buzz</div>
    </div>
  </div>
</div>

...in which case you have no better choice than to use Sub-Components as there are two layers of title elements (one for the accordion as a whole, and one for each panel). Consider that this may be a sign that the Module isn't generic enough (will all accordions really require their own title? Could the title instead be abstracted to a higher-order Component?). One thing can be said for sure and that is that the above is certainly better than:

<div class="accordion">
  <div class="accordion_title">title</div>
  <div class="accordion_panels">
    <div class="accordion_panels_panel">
      <div class="accordion_panels_panel_title">foo</div>
      <div class="accordion_panels_content">bar</div>
    </div>
    <div class="accordion_panels_panel">
      <div class="accordion_panels_panel_title">fizz</div>
      <div class="accordion_panels_panel_content">buzz</div>
    </div>
  </div>
</div>

It's absolutely unnecessary to make each panel a Sub-Component of panels, and this goes for any singular/plural combination (item and items, feature and features, article and articles etc...).

Modifiers

A modifier can be applied to both Modules and Components, and allow for variants of the Module to be used. Modifiers are useful for changing things like appearance, behaviour and state. There is no limit to the number of modifiers that can be applied to a Module or Component.

Example

<Button>Button</Button>
<Button large>Button</Button>
<Button primary>Button</Button>
<Button large primary>Button</Button>