npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@onenexus/cell

v1.0.0-beta.21

Published

Style BEM DOM elements using Sass

Downloads

69

Readme

GitHub license Build Status npm version npm downloads

Style BEM DOM elements using Sass [View SassDocs]

Overview

Cell is used for styling DOM elements that follow the Cell naming convention (which is almost identical to BEM).

Learn how to integrate with React components

Example

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

View CodeSandbox Demo

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

<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>

This can be styled with Cell like so:

@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() mixin, as seen in this example (this will produce identical CSS to the previous example):

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

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

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

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

Using Cell Atoms

Learn more about Cell Atoms

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

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

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

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

Installation & Setup

npm install --save @onenexus/cell
// 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:

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

See the 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 and module configuration.

View CodeSandbox Demo

Using React?

Example

modules/
|--myModule/
|  |--config.js
|  |--styles.scss
themes/
|--myTheme.js
app.scss
themes/myTheme.js
export default {
  colors: {
    primary: '#00d4ff',
    secondary: '#58ed02'
  },
  breakpoints: {
    small: '720px',
    large: '1400px'
  }
}
modules/myModule/config.js
export default (theme) => ({
  name: 'myModule',
  background: theme.colors.primary,
  gutter: '1em'
});
modules/myModule/styles.scss
@import 'config.js';

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

  @media (min-width: theme('breakpoints', 'small')) {
    display: inline-block;
  }
}
app.scss
@import '~@onenexus/cell/dist/cell';
@import 'themes/myTheme.js';
@import 'modules/myModule/styles';
CSS Output
.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 Draft page to learn more

Read the JavaScript Configuration page 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. See how the below React accordion component can be styled by importing its corresponding Cell module (styles.scss):

View CodeSandbox Demo

modules/Accordion/index.js
import React, { useState } from 'react';
import './styles.scss';

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

  return (
    <div className='accordion' { ...props }>
      {panels.map(({ heading, content }, index) => (
        <div className={`accordion__panel${index === activeIndex ? '--active':''}`}>
          <div className='accordion__title' onClick={() => toggle(index)}>
            {title}
          </div>

          <div className='accordion__content'>
            {content}
          </div>
        </div>
      ))}
    </div>
  );
}

export default Accordion;

Using with Lucid (React Library)

Lucid is a React library for working with the Cell/BEM naming convention. If using Lucid, the above React component could be rewritten as:

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

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

  return (
    <Module name='accordion' { ...props }>
      {panels.map(({ heading, content }, index) => (
        <Component name='panel' active={index === activeIndex}>
          <Component name='heading' onClick={() => toggle(index)}>
            {heading}
          </Component>

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

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

Mixins

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

Utility Functions

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, however it is often considered quite ugly; the __ and -- thrown into your HTML along with repeated keywords when using modifiers (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.

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