README
Style Synergy modules/BEM DOM elements using JavaScript
- Overview
- Installation & Setup
- Synergy Modules/Components
- polymorph()
- API
- Use With sQuery
- Use With Lucid
Overview
Polymorph is used for styling DOM elements that follow the Synergy naming convention.
Example Module Markup
<div class="accordion">
<div class="accordion_panel">
<div class="accordion_title">foo</div>
<div class="accordion_content">bar</div>
</div>
<div class="accordion_panel-active">
<div class="accordion_title">fizz</div>
<div class="accordion_content">buzz</div>
</div>
</div>
accordion
modules
Style all document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
'position': 'relative'
});
});
panel
components
Style document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: {
'display': 'block'
}
});
});
panel
components with active
modifier
Style document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: {
'color': 'white',
'modifier(active)': {
'color': 'blue'
}
}
}
});
Alternatively
document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: panel => ({
'color': panel.matches('.accordion_panel-active') ? 'blue' : 'white'
})
}
});
modifier
Method
Using In-Built This ensures no class names are hard coded
Learn more about the
modifier
method
document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: panel => ({
'color': polymorph.modifier(panel, 'active') ? 'blue' : 'white'
})
}
});
sQuery
(Recommended)
Using sQuery('accordion', element => {
polymorph(element, {
panel: panel => ({
'color': panel.modifier('active') ? 'blue' : 'white'
})
}
});
title
components when parent panel
component has active
modifier
Style document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: {
'modifier(active)': {
title: {
'color': 'red'
}
}
},
title: {
'color': 'blue'
}
}
});
Alternatively
document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
title: title => ({
'color': title.closest('.accordion_panel-active') ? 'red' : 'blue'
})
}
});
Using sQuery
sQuery('accordion', element => {
polymorph(element, {
title: title => ({
'color': title.parent('panel').is('active') ? 'red' : 'blue'
})
}
});
Installation & Setup
npm install --save @onenexus/polymorph
import 'polymorph' from '@onenexus/polymorph';
polymorph(document.getElementById('someElement'), someConfigurationObject);
Using BEM? Checkout the Working With BEM page
API
Polymorph.modifier()
Determine if an HTML element has the specified modifier
polymorph.modifier(element, modifier)
Param | Type | Info |
---|---|---|
element |
HTMLElement |
The HTML element of interest |
modifier |
String |
The modifier of interest |
Example
<div class="accordion">
<div class="accordion_panel">
<div class="accordion_title">foo</div>
<div class="accordion_content">bar</div>
</div>
<div class="accordion_panel-active">
<div class="accordion_title">fizz</div>
<div class="accordion_content">buzz</div>
</div>
</div>
document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
panel: panel => ({
'color': polymorph.modifier(panel, 'active') ? 'blue' : 'white'
})
}
});
Result
<div class="accordion">
<div class="accordion_panel" style="color: white;">
...
</div>
<div class="accordion_panel-active" style="color: blue;">
...
</div>
</div>
Element.repaint()
Repaint the module by re-applying the style rules
element.repaint()
This method is attached directly to the DOM element after the initial
polymorph
call
This is useful for updating the styles after an event that modifies the DOM, such as a click event which adds an active
modifier to an element. In order to repaint the element, you should call the repaint()
method in the same place you handle the event.
Example
<div class="accordion" id="alpha">
<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>
polymorph(document.getElementById('alpha'), {
panel: {
'background': 'red';
'modifier(active)': {
'background': 'blue'
}
}
});
// `#alpha` element and all targeted child components
// will now have a `repaint()` method
document.querySelectorAll('.accordion').forEach(accordion => {
accordion.querySelectorAll('.accordion_panel').forEach(panel => {
panel.querySelector('.accordion_title').addEventListener('click', () => {
// do event handling...
panel.classList.toggle('accordion_panel-active');
// repaint the accordion panel
panel.repaint();
});
}
});
sQuery
UsingsQuery('accordion').getComponents('panel').forEach(PANEL => {
sQuery(PANEL).getComponent('title').addEventListener('click', () => {
// the `repaint` method is called automatically
// when using the sQuery API
sQuery(PANEL).toggleModifier('visible');
});
});
Lucid
Using// By passing a styles function/object to the `styles` prop of `<Module>`,
// `repaint()` will be called on the approprate rendered DOM elements
// in the `componentDidUpdate` lifecycle method
<Module name='myModule' styles={styles}>...</Module>
Use With sQuery
sQuery is a JavaScript library for interacting with Synergy modules
sQuery is perfect for interacting with Polymorph
, and isn't included by default to keep bundle size down (as it isn't strictly required for functionality).
Once installed, you can use sQuery to style your modules and components much more easily using the provided API.
Without sQuery
document.querySelectorAll('.accordion').forEach(element => {
polymorph(element, {
title: title => ({
'color': title.closest('.accordion_panel-active') ? 'red' : 'blue'
})
}
});
With sQuery
sQuery('accordion', element => polymorph(element, {
title: title => ({
'color': title.parent('panel').is('active') ? 'red' : 'blue'
})
}));
Use With Lucid
Lucid is a set of higher-order React components for rendering Synergy modules
Lucid and Polymorph were built in tandem as part of the Synergy
framework, so go hand-in-hand together. If you are using Lucid, the easiest way to use Polymorph as the styleParser
function is to attach it to the window.Synergy.styleParser
property:
import { Module, Component } from '@onenexus/lucid';
import Polymorph from '@onenexus/polymorph';
window.Synergy = {
styleParser: Polymorph
}
// start using Lucid components (Module, Component)...