
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@haijindev/o-css
Advanced tools
Javascript css builder
http://o-programming-language.org/
@haijindev/o-css do?Historically the workflow of the css styles of an application consisted in
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
React applicationIt is also possible to use this DSL to compile the css server side using regular function calls in Node.
npm install @haijindev/o-css
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)
Define the class with the css definitions
class AComponentStyle {
injectInto(css) {
}
}
module.exports = AComponentStyle
Then use any of the following definitions
class AComponentStyle {
injectInto(css) {
css.selector('.btn', {
'width': '10px',
'height': '10px'
})
}
}
module.exports = AComponentStyle
class AComponentStyle {
injectInto(css) {
css.selector('.btn', {
'width': '10px',
'height': '10px'
})
css.selector('.btn:hover', {
'height': '10px'
})
}
}
module.exports = AComponentStyle
class AComponentStyle {
injectInto(css) {
css.selector('.row', {
'width': '10px'
})
css.selector('.row .col', {
'height': '10px'
})
}
}
module.exports = AComponentStyle
Useful to override selectors for a specific element
class AComponentStyle {
injectInto(css) {
css.namespace('#main', () => {
css.selector('.row', {
'width': '10px'
})
})
}
}
module.exports = AComponentStyle
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
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
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
const width = 10
class Style2 {
injectInto(css) {
css.selector('.btn', {
'width': `${width}px`,
'height': `${width/3}px`
})
}
}
module.exports = Style2
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'})
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
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)
FAQs
Client side css compiler
We found that @haijindev/o-css demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.