An open API service indexing awesome lists of open source software.

https://github.com/one-nexus/cell

Style BEM DOM elements using Sass
https://github.com/one-nexus/cell

bem modules sass stylesheets styling synergy ui-components

Last synced: 6 months ago
JSON representation

Style BEM DOM elements using Sass

Awesome Lists containing this project

README

          

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/One-Nexus/Cell/blob/master/LICENSE)
[![Build Status](https://travis-ci.com/One-Nexus/Cell.svg?branch=master)](https://travis-ci.com/One-Nexus/Cell)
[![npm version](https://badge.fury.io/js/%40onenexus%2Fcell.svg)]((https://www.npmjs.com/package/@onenexus/cell))
[![npm downloads](https://img.shields.io/npm/dm/@onenexus/cell.svg)](https://www.npmjs.com/package/@onenexus/cell)

> Style BEM DOM elements using Sass [[View SassDocs](https://one-nexus.github.io/Cell/sass/)]

* [Overview](#overview)
* [Installation & Setup](#installation--setup)
* [Creating a Module](https://github.com/One-Nexus/Cell/wiki/Creating-a-Module)
* [Mixins](#mixins)
* [Utility Functions](#utilities)



CodeSandbox Demos




Standard Demo
JavaScript Demo
React Demo
Basic Sass-Only Demo

## Overview

Cell is used for styling DOM elements that follow the [Cell naming convention](https://github.com/One-Nexus/Cell/wiki/Cell-Naming-Convention) (which is almost identical to [BEM](http://getbem.com/)).

> [Learn how to integrate with React components](#using-with-react)

* Cell is used for creating modular, configurable and scalable Sass components
* Works with any Sass implementation (Ruby, Dart, Node...)
* Requires Sass 3.4+ (4.9+ if using Node-Sass)
* [Import themes/configuration into your Sass/Cell components as JavaScript/JSON](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration#usage)
* Built for the [Synergy framework](https://github.com/One-Nexus/Synergy)
* [Compatible with Cell Query](https://github.com/One-Nexus/Synergy-Front-End-Guides/wiki/Cell-Query)

### Example

Given the following markup for an accordion with an active panel component:

> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--basic-p55bc)

> Unlike traditional BEM, you do not need separate classes for modifiers

```html



foo

bar



fizz

buzz



```

This can be styled with Cell like so:

```scss
@include module('accordion') {
@include component('panel') {
...

@include is('active') {
@include component('content') {
display: block;
}
}
}

@include component('title') {
...
}

@include component('content') {
...
display: none;
}
}
```

### Using `context()`

The above examples use the traditional _cascading_ paradigm to apply styles under certain conditions. You can see that to _show_ the `content` component above, the `display` property is applied in a cascading fashion _inside_ the `panel` component.

Cell allows you to go about this in a dfferent way, allowing you to keep all styles pertaining to a single component in one place, thanks to the [`context()`](https://github.com/One-Nexus/Cell/wiki/Context()) mixin, as seen in this example (this will produce identical CSS to the previous example):

```scss
@include module('accordion') {
@include component('panel') {
...
}

@include component('title') {
...
}

@include component('content') {
...
display: none;

@include context(($this, 'panel'), 'active') {
display: block;
}
}
}
```

### Using [Cell Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)

> [Learn more about Cell Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)

Continuing from the previous example, the `display` Atom can instead be used to handle the `display` property:

```scss
@include module('accordion') {
@include component('panel') {
...
}

@include component('title') {
...
}

@include component('content') {
...
@include display((($this, 'panel'), 'active'), block, none);
}
}
```

### Using [Cell Query (CQ)](https://github.com/One-Nexus/Synergy-Front-End-Guides/wiki/Cell-Query)

Cell can interpret and parse CQ by passing a CQ compatible Sass map as the second parameter to the `module()` mixin, allowing the `accordion` example to be re-written as:

```scss
@include module('accordion', (
'panel': (
...
),

'title': (
...
),

'content': (
...
'display': none,

'panel-is-active': (
'display': block
)
)
));
```

> [Learn more about Cell and Cell Query (CQ)](https://github.com/One-Nexus/Cell/wiki/Cell-Query)

## Installation & Setup

```
npm install --save @onenexus/cell
```

```scss
// this path will vary depending on where the library is being imported
@import '../../node_modules/@onenexus/cell/dist/cell';
```

If you are using Node Sass, you can import the library anywhere using:

```scss
@import '~@onenexus/cell/dist/cell';
```

> See the [JavaScript Configuration](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration) page for instructions on how to use JavaScript/JSON configuration

## Using with JavaScript

Cell can be used with JavaScript for things like [theming](https://github.com/One-Nexus/Cell/wiki/Theming) and [module configuration](https://github.com/One-Nexus/Cell/wiki/Module-Configuration).

> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--js-iklx3)

> [Using React?](#using-with-react)

### Example

```
modules/
|--myModule/
| |--config.js
| |--styles.scss
themes/
|--myTheme.js
app.scss
```

###### themes/myTheme.js

```js
export default {
colors: {
primary: '#00d4ff',
secondary: '#58ed02'
},
breakpoints: {
small: '720px',
large: '1400px'
}
}
```

###### modules/myModule/config.js

```js
export default (theme) => ({
name: 'myModule',
background: theme.colors.primary,
gutter: '1em'
});
```

###### modules/myModule/styles.scss

```scss
@import 'config.js';

@include module {
display: block;
margin-top: this('gutter');

@media (min-width: theme('breakpoints', 'small')) {
display: inline-block;
}
}
```

###### app.scss

```scss
@import '~@onenexus/cell/dist/cell';
@import 'themes/myTheme.js';
@import 'modules/myModule/styles';
```

###### CSS Output

```css
.myModule, [class*="myModule--"] {
background: #00d4ff;
display: block;
margin-top: 1em;
}

@media (min-width: 720px) {
.myModule, [class*="myModule--"] {
display: inline-block;
}
}
```

> Note that the `background` property is output to CSS despite not being hard-coded inside `styles.scss` - this is because configuration properties that correspond to CSS properties can be automatically parsed as CSS - read the [Cell Query page](https://github.com/One-Nexus/Cell/wiki/Cell-Query) to learn more

> Read the [JavaScript Configuration page](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration) for setup instructions and more information

## Using with React

Using Cell with React can be as simple as configuring your Webpack to use [Sass-Loader](https://github.com/webpack-contrib/sass-loader). See how the below React accordion component can be styled by importing its corresponding Cell module (`styles.scss`):

> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--react-hygf9)

###### modules/Accordion/index.js

```jsx
import React, { useState } from 'react';
import './styles.scss';

const Accordion = ({ panels, ...props }) => {
const [activeIndex, toggle] = useState(0);

return (


{panels.map(({ heading, content }, index) => (

toggle(index)}>
{title}


{content}


))}

);
}

export default Accordion;
```

### Using with Lucid (React Library)

[Lucid](https://github.com/One-Nexus/Lucid) is a React library for working with the Cell/BEM naming convention. If using Lucid, the above React component could be rewritten as:

```jsx
import React, { useState } from 'react';
import { Module, Component } from '@onenexus/lucid';
import './styles';

const Accordion = ({ panels, ...props }) => {
const [activeIndex, toggle] = useState(0);

return (

{panels.map(({ heading, content }, index) => (

toggle(index)}>
{heading}


{content}


))}

);
}

export default Accordion;
```

This solution offers all the practical benefits of scoped styling (thanks to the underlying Cell/BEM naming convention) without any of the uglyness that BEM usually brings, and without any of the overhead that CSS-in-JS techniques (and actual *scoping*) bring, keeping everything clean and tidy.

## Useful Wiki Pages

* [Creating a Cell Module](https://github.com/One-Nexus/Cell/wiki/Creating-a-Module)
* [Module Configuration](https://github.com/One-Nexus/Cell/wiki/Module-Configuration)
* [Theming](https://github.com/One-Nexus/Cell/wiki/Theming)
* [Cell Query (CQ)](https://github.com/One-Nexus/Cell/wiki/Cell-Query)
* [Using with JavaScript](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration)
* [Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)

## Mixins

Cell comes with the following mixins to help create and structure your modules in the most efficient way possible:

* [Module](https://github.com/One-Nexus/Cell/wiki/Module())
* [Component](https://github.com/One-Nexus/Cell/wiki/Component())
* [Modifier](https://github.com/One-Nexus/Cell/wiki/Modifier())
* [Option](https://github.com/One-Nexus/Cell/wiki/Option())
* [Value](https://github.com/One-Nexus/Cell/wiki/Value())
* [Extend](https://github.com/One-Nexus/Cell/wiki/Extend())
* [Context](https://github.com/One-Nexus/Cell/wiki/Context())
* [Pseudo-State](https://github.com/One-Nexus/Cell/wiki/Pseudo-State())
* [Wrapper](https://github.com/One-Nexus/Cell/wiki/Wrapper())

## Utility Functions

* [Create Config](https://github.com/One-Nexus/Cell/wiki/utilities#create-config)
* [Enabled](https://github.com/One-Nexus/Cell/wiki/utilities#enabled)
* [Value Enabled](https://github.com/One-Nexus/Cell/wiki/utilities#value-enabled)
* [Option](https://github.com/One-Nexus/Cell/wiki/utilities#option)
* [Setting](https://github.com/One-Nexus/Cell/wiki/utilities#setting)
* [This](https://github.com/One-Nexus/Cell/wiki/utilities#this)
* [Theme](https://github.com/One-Nexus/Cell/wiki/utilities#theme)

## BEM Inspired Motivation

The initial motiviation behind creating Cell is twofold:

* Address the uglyness of BEM
* Address the practical implementation of BEM using Sass

BEM solves very real problems like no other solution due to [its inherent nature](https://itnext.io/thinking-of-bem-as-a-ui-philosophy-instead-of-a-css-naming-convention-9727e2cf9328), however it is [often considered quite ugly](https://hackernoon.com/bem-should-not-exist-6414005765d6); the `__` and `--` thrown into your HTML along with [repeated keywords when using modifiers](https://stackoverflow.com/questions/32052836/sass-bem-avoid-modifier-duplication-when-element-is-inside-a-modifier) (`block__component block__component--modifier-1 block__component--modifier-2`) make the HTML extremely jarring to look at. Cell solves these issues by abstracting the logic into mixins and making use of CSS's [wildcard attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).

Since the initial conception, Cell has evolved to become a fully-fledged framework for writing scalable and maintainable CSS.

---