A front-end framework for creating modular, configurable and scalable UI components for the web
View SassDoc Documentation | View JSDoc Documentation
Synergy provides powerful tools to help you create configurable modules in Sass
, JavaScript
and/or React
:
- Use Synergy to create Sass components
- Use Synergy to create JavaScript components
- Use Synergy to create React components
Synergy also povides tools allowing you to combine the above aspects together to create a Synergy Module
. Each aspect can work independently and exists as a separate file with a specific role:
- Module Configuration (
.json
) - Module Styles (
.scss
) - Module Interactions (
.js
) - Module Rendering (
.jsx
)
|-- modules
| |-- accordion
| | |-- accordion.js
| | |-- accordion.json
| | |-- accordion.jsx
| | |-- accordion.scss
Synergy modules can be configured and scaled without having to touch the module's source code
A Synergy module is composed of Components
. Both Modules
and Components
can have Modifiers
.
<Module {modifiers}>
<Component {modifiers}>
{content}
</Component>
{content}
<Component {modifiers}>
{content}
</Component>
</Module>
Using Synergy, you can create themes and control your entire project's UI from a single JSON file by passing custom options and parameters to your modules.
Learn more about creating themes
Using Synergy to create a basic
accordion
module - Learn more about this example
|-- UI
| |-- modules
| | |-- accordion
| | | |-- accordion.js
| | | |-- accordion.json
| | | |-- accordion.jsx
| | | |-- accordion.scss
| |-- app.scss
| |-- app.{js|jsx}
Learn more about module styles
@import '../../node_modules/Synergy/dist/synergy';
@import 'accordion.json';
@mixin accordion($custom: ()) {
$accordion: config($accordion, $custom);
@include module {
@include component('panel') {
&:not(:last-child) {
margin-bottom: this('panel', 'vertical-rhythm');
}
}
@include component('title', (
'display': block,
'margin': 0,
'backface-visibility': hidden,
'font-weight': normal,
'line-height': 1,
'cursor: pointer',
active: (
component('toggle'): (
'transform': rotate(90deg) translateZ(0)
)
)
));
@include component('toggle', (
'float': right,
'line-height': 0.75
));
@include component('content', (
'display': none,
'margin': 0,
active: (
'display': block
)
));
}
}
Learn more about module interactions
import { Synergy } from 'Synergy';
import defaults from './accordion.json';
// Interaction Interface (used when not using React)
export default function accordion(custom) {
Synergy('accordion', (accordion, options) => {
accordion.component('panel', panel => {
panel.component('title', title => {
title.addEventListener('click', toggle.bind(panel), false);
});
});
}, defaults, custom);
}
// Toggle Interaction
export function toggle(panel) {
const panel = panel.target ? panel.target : this;
const operator = panel.modifier('active', 'isset') ? 'unset' : 'set';
panel.modifier('active', operator);
}
import React from 'react';
import ReactDOM from 'react-dom';
import { Synergize, Module, Component } from 'Synergy';
import defaults from './accordion.json';
import { toggle } from './accordion.js';
// Interaction Interface (used when not using raw DOM API)
export default class Accordion extends Synergize {
render() {
return (
<Module {...this.props}>
{this.props.panels.map(({ title, content }, index) => (
<Component name='panel' key={index}>
<Component name='title' onClick={toggle}>
<Component name='toggle' /> {title}
</Component>
<Component name='content'>{content}</Component>
</Component>
))}
</Module>
)
}
}
Accordion.defaultProps = {
name: defaults.accordion.name
};
Learn more about module configuration
{
"accordion": {
"name": "accordion",
"panel": {
"vertical-rhythm": 0
},
"title": {
"background": "transparent",
"color": "#444444",
"border": "1px solid rgba(black, 0.15)",
"border-radius": 0,
"padding": "1em",
"transition": "0.4s",
"hover": {
"background": "#2E3882",
"color": "white",
"component(toggle)": {
"color": "white"
}
},
"active": {
"background": "#2E3882",
"color": "white",
"border-color": "transparent",
"border-radius": 0,
"component(toggle)": {
"color": "white"
}
}
},
"content": {
"background": "white",
"color": "#444444",
"border": "1px solid rgba(black, 0.15)",
"border-radius": 0,
"padding": "1.5em"
},
"toggle": {
"color": "rgba(black, 0.4)",
"transition": "0.4s"
}
}
}
@import '/modules/accordion/accordion';
@include accordion();
// With custom options
@include accordion((
'panel': (
'vertical-rhythm': 2em
),
'title': (
'background': #06d2ff,
'color': white
)
));
<div class="accordion">
<div class="accordion_panel">
<div class="accordion_title">
<div class="accordion_toggle"></div> foo
</div>
<div class="accordion_content">bar</div>
</div>
<div class="accordion_panel">
<div class="accordion_title">
<div class="accordion_toggle"></div> fizz
</div>
<div class="accordion_content">buzz</div>
</div>
</div>
import accordion from './modules/accordion/accordion.js';
accordion();
// With custom options (whilst this example doesn't make use
// of these values in the JS, it still has access to them)
accordion('accordion', {
panel: {
'vertical-rhythm': 0
},
title: {
background: '#06d2ff',
color: 'white'
}
})
<div id="demo"></div>
import React from 'react';
import ReactDOM from 'react-dom';
import Accordion from './modules/accordion/accordion.jsx';
ReactDOM.render(
<Accordion panels={[
{title: 'foo', content: 'bar'},
{title: 'fizz', content: 'buzz'},
]} />,
document.getElementById('demo')
);
Released: 29th May 2018
- Allowing
<Component>
's to accept event handlers as props - Allow passing of custom HTML tag to
<Module>
- Set module modifiers by passing as empty prop
- Adding
<Wrapper>
and<Group>
components - Specify list of CSS classes to add via empty prop
- Allow passing of CSS through Sass map istead of through
@content
- Adding
sub-component
Sass mixin - Adding
pseudo-state
Sass mixin - Dynamically fetch
<Component>
onClick event from window.UI object - Set
<Module>
as another module by passing module name as prop - Dynamically set
tag
prop on module ifname
prop is valid HTML tag - Get HTML attributes from props
- Sets
initialised
in module config when initialised - Allow passing of data-attributes to module
- Append content before/after module through
before
andafter
props - Removing Bower
- General refactoring and bug fixes
Released: 13th January 2018
- Fixing bug where only first modifier in module.jsx was parsed
Released: 11th January 2018
- Exporting transpiled module instead of ES6