This package has been deprecated

Author message:

@haijindev/o-css is deprecated, in favor of o-stylist. Please, migrate to o-stylist

@haijindev/o-css

1.0.6 • Public • Published

@haijindev/o-css

Javascript css builder

Documentation

http://o-programming-language.org/

What does @haijindev/o-css do?

Historically the workflow of the css styles of an application consisted in

  • define or read a pseudo-css input file on the server side
  • process it to generate a standard css file that a browser understands. For example replace variables by values, mix css classes o compile nested selectors
  • expect the client to request for the compiled css file
  • respond the css file to the client

Frameworks like React can dramatically change the workflow with a more dynamic, light and adaptable one.

This library provides a javascript DSL to declare css styles and implement the workflow that follows

  • declare the styles the app uses in regular javascript sintax
  • send to the client the declared styles as a regular js module in your React application
  • make the client application to process the declared styles and convert them to the css the browser understands
  • load the css compiled client side in the browser

It is also possible to use this DSL to compile the css server side using regular function calls in Node.

Installation

npm install @haijindev/o-css

Usage

First define one or more styles to load.

Each style is a regular js class with a method call injectInto(css)

class AppStyle {
  injectInto(css) {
    // styles definition goes here
  }
}

The parameter css is the css compiler and supports the following protocol

class AppStyle {
  injectInto(css) {
    // Define the given cssSelector
    css.selector(
      '.row', {
        // ... css attributes
      }
    )

    // Define the given styles as children of the given cssSelector
    css.namespace('#container', () => {
      // child styles
    })

    // Append the styles defined in the given styleClass
    css.inject(anotherStyleClass)

    // Merge the styles defined in the given styleClass in the given cssSelector
    css.selector(
      '.row', {
        _import: anotherStyleClass,
        // ...
      }
    )

    // Merge the styles defined in the given styleClasses in the given cssSelector
    css.selector(
      '.row', {
        _import: [anotherStyleClass1, anotherStyleClass2],
        // ...
      }
    )
  }
}

Once you have a style object the application must load it into the DOM document using any of the following methods

const {Css} = require('@haijindev/o-css')
const AppStyle = require('./AppStyle')

const style = new AppStyle()
Css.insertStyle({ style, document, element: document.head })

// And load the app like usual
ReactDOM.render(
  <MainComponent />,
  document.getElementById('root')
)

or first compile the styles to a css string and then load the string

const {Css} = require('@haijindev/o-css')
const AppStyle = require('./AppStyle')

const cssString = Css.fromStyle(style)
Css.insertCss({ cssString, document, element: document.head })

// And load the app like usual
ReactDOM.render(
  <MainComponent app={ app } />,
  document.getElementById('root')
)

The styles can also be compiled to a file server side with

const {Css} = require('@haijindev/o-css')
const fs = require('fs')
const AppStyle = require('./AppStyle')

const style = new AppStyle()
const cssString = Css.fromStyle(style)

fs.writeFileSync('public/main.css', cssString)

Css definition

Define the class with the css definitions

class AComponentStyle {
  injectInto(css) {
  }
}

module.exports = AComponentStyle

Then use any of the following definitions

Define attributes to a css selector

class AComponentStyle {
  injectInto(css) {
    css.selector('.btn', {
      'width': '10px',
      'height': '10px'
    })
  }
}

module.exports = AComponentStyle

Define attributes to many css selectors

class AComponentStyle {
  injectInto(css) {
    css.selector('.btn', {
      'width': '10px',
      'height': '10px'
    })

    css.selector('.btn:hover', {
      'height': '10px'
    })
  }
}

module.exports = AComponentStyle

Define nested selectors

class AComponentStyle {
  injectInto(css) {
    css.selector('.row', {
      'width': '10px'
    })

    css.selector('.row .col', {
      'height': '10px'
    })
  }
}

module.exports = AComponentStyle

Define nested selectors using namespaces

Useful to override selectors for a specific element

class AComponentStyle {
  injectInto(css) {
    css.namespace('#main', () => {
      css.selector('.row', {
        'width': '10px'
      })
    })
  }
}

module.exports = AComponentStyle

Import (merge) attributes from another Style

Useful to reuse css values in different elements

class CommonStyle {
  injectInto(css) {
    css.selector('common', {
      'color': 'blue'
    })
  }
}

module.exports = CommonStyle
const CommonStyle = require('./CommonStyle')

class AComponentStyle {
  injectInto(css) {
    css.selector('.row', {
      _import: new CommonStyle(),
      'width': '10px'
    })
  }
}

module.exports = AComponentStyle

Import (merge) attributes from many other Styles

const CommonStyle1 = require('./CommonStyle1')
const CommonStyle2 = require('./CommonStyle2')

class AComponentStyle {
  injectInto(css) {
    css.selector('.row', {
      _import: [new CommonStyle1(), new CommonStyle2()],
      'width': '10px'
    })
  }
}

module.exports = AComponentStyle

Bundle many Styles into a single Style

Useful to export and load a single Style class

class Style1 {
  injectInto(css) {
    css.selector('.row', {
      'width': '10px'
    })
  }
}

module.exports = Style1
class Style2 {
  injectInto(css) {
    css.selector('.btn', {
      'height': '10px'
    })
  }
}

module.exports = Style2
const Style1 = require('./Style1')
const Style2 = require('./Style2')

class MainStyle {
  injectInto(css) {
    new Style1().injectInto(css)
    new Style2().injectInto(css)
  }
}

module.exports = MainStyle

Dynamic css values

const width = 10

class Style2 {
  injectInto(css) {
    css.selector('.btn', {
      'width': `${width}px`,
      'height': `${width/3}px`
    })
  }
}

module.exports = Style2

Css parametrised values

class Style {
  constructor({color}) {
    this.color = color
  }

  injectInto(css) {
    css.selector('.btn', {
      'width': `${width}px`,
      'color': this.color
    })
  }
}

module.exports = Style
new Style({color: 'blue'})

Themed styles

const theme = {
  color: 'blue'
}
module.exports = theme
class Component1 {
  constructor(theme) {
    this.theme = theme
  }
  injectInto(css) {
    css.selector('#id1', {
      'color': this.theme.color
    })
  }
}

module.exports = Component1
class Component2 {
  constructor(theme) {
    this.theme = theme
  }
  injectInto(css) {
    css.selector('#id2', {
      'color': this.theme.color
    })
  }
}

module.exports = Component2
const theme = require('./theme')
const Component1 = require('./Component1')
const Component2 = require('./Component2')

class MainStyle {
  injectInto(css) {
    new Component1(theme).injectInto(css)
    new Component2(theme).injectInto(css)
  }
}

module.exports = MainStyle

Change the application theme on the fly

const {Css} = require('@haijindev/o-css')
const MainStyle = require('./MainStyle')

function updateStyles(selectedTheme) {
  const styleElement = document.querySelector('head style')
  if (styleElement) { styleElement.remove() }

  const newStyle = new MainStyle(selectedTheme)
  Css.insertStyle({newStyle, document, element: document.head })
}

updateStyles(newTheme)

Readme

Keywords

Package Sidebar

Install

npm i @haijindev/o-css

Weekly Downloads

1

Version

1.0.6

License

ISC

Unpacked Size

12 kB

Total Files

8

Last publish

Collaborators

  • haijindev