magnostic v0.0.10
magnostic 🧲
magnostic is an opinionated bundler-agnostic lightweight CSS-in-JS utility using css paradigm.
Install
npm install magnosticWhy another CSS-in-JS library ?
I'm using Emotion on a daily basis in professional and hobby React, Svelte and Vue projects.
CSS-in-JS is a great tool, and I enjoy using framework-agnostic css paradigm since it can be used in basically any framework. But once you start using Server-Side Rendering, it becomes a mess, especially if not using Babel or React.
Some issues with existing libraries
Notice: Following mentionned snippets are subject to change.
- Emotion API is quite confusing [1] [2], there are currently two
cssparadigms (emotion[3] and@emotion/css[4]) which don't do the same thing. Emotion 11 is on the way [5] with lots of API reworks but I'll remain cautious linariahas Babel as a peer dependency [6] and is mostly designed to be used with this tool [7]styled-componentshas React and React DOM as peer dependencies [8] and has acssparadigm which requires a Babel pluginmonad-uihas@emotion/core, React and React DOM as peer dependencies [9]jss[10] ,aphrodite[11] and many others don't support template literalsgooberdoes have convenientextractCssmethod [12] but itscssparadigm lacks testing and features like composition [13]picostyleonly supports frameworks with JSX pragmas [14]
Features
- Similar Emotion API (nesting, composition, etc.)
- Bundler-agnostic
- Framework-agnostic
- Debugging
- Isolated stores
- Media queries (
@media) - Extract CSS
- Keyframes (
@keyframes)
To be implemented
- Merge duplicate/overwritten styles
- Object styles
- Convert tagged templates ⬌ object styles
API
css(template,...props)
@returns {MagnosticStyle}Style object with unique identifier
The default css method expects a tagged template literal as input, which may include variables or other magnostic styles passed via placeholders ${}.
import {css} from 'magnostic'
const style = css`
color: blue;
`
console.log(`${style}`) // 🠚 'css-ds3r7jufak'
console.log(style)
/**
* 🠚 [Function: MagnosticStyle] : {
* type: 'style'
* className: 'css-ds3r7jufak',
* template: [ '\n color: blue;\n' ],
* styles: '.css-ds3r7jufak{color:blue;}',
* toString: [Function]
* }
*/Compared to Emotion, magnostic makes no assumption and still let users have control and visibility upon generated styles if explicitly asked to, using a regular console.log for example.
// Using Emotion
import {css} from 'emotion'
const style = css`
color: blue;
`
console.log(`${style}`) // 🠚 'css-de54d5'
console.log(style) // 🠚 'css-de54d5'keyframes(template,...props)
@returns {MagnosticKeyframes} Keyframes object with unique identifier
Similar to Emotion's keyframes method, the default keyframes method allows to explicitly register a CSS animation with an unique identifier, using a template literal as input.
import {css, keyframes, extractCss} from 'magnostic'
const slideIn = keyframes`
from {
left: 100%;
}
to {
left: 0%;
}
`
console.log(`${slideIn}`) // 🠚 'anim-yttaxx0b79'Then, the animation can be used as a style rule.
const slidingText = css`
animation: ${slideIn} 1s ease infinite;
`
console.log(extractCss())
/**
* 🠚 '@keyframes anim-yttaxx0b79{from{left:100%;}to{left:0%;}}
* .css-71cew5o9e7{animation: anim-yttaxx0b79 1s ease infinite;}'
*/extractCss()
@returns {string}Returns the generated CSS code
Similar to goober's extractCss method, this outputs generated CSS from all previous default css and keyframes method calls.
import {css, extractCss} from 'magnostic'
const blueText = css`
color: blue;
`
const cyanText = css`
color: cyan;
`
console.log(extractCss())
// 🠚 '.css-jutyrr209v{color:blue;}.css-l76dzjb8ke{color:cyan;}'createStore()
@returns {MagnosticStore}Returns the generated store, including various methods
magnostic does provide a default css method which pushes any generated style to a global store, but still allows anyone to create their own stores, which all provide isolated methods (css, extractCss, keyframes, etc.). This is particularly useful when creating view-specific style rules and/or when trying to reduce bundle sizes.
import {createStore} from 'magnostic'
// Let's create a first store
const someStore = createStore()
const { css, extractCss } = someStore
const blueText = css`
color: blue;
`
// Now let's create another store
const anotherStore = createStore()
const { css: css2, extractCss: extractCss2 } = anotherStore
const centerAlignedText = css2`
text-align: center;
`
console.log(extractCss()) // 🠚 '.css-9lo91vqws3{color:blue;}'
console.log(extractCss2()) // 🠚 '.css-leg65ywf68{text-align:center;}'Contributing
magnostic is based on stylis (like Emotion) and has a TypeScript codebase, there are some useful npm scripts :