magnostic
v0.0.10
Published
Opinionated bundler-agnostic lightweight CSS-in-JS utility
Downloads
10
Maintainers
Readme
magnostic 🧲
magnostic is an opinionated bundler-agnostic lightweight CSS-in-JS utility using css
paradigm.
Install
npm install magnostic
Why 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
css
paradigms (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 linaria
has Babel as a peer dependency [6] and is mostly designed to be used with this tool [7]styled-components
has React and React DOM as peer dependencies [8] and has acss
paradigm which requires a Babel pluginmonad-ui
has@emotion/core
, React and React DOM as peer dependencies [9]jss
[10] ,aphrodite
[11] and many others don't support template literalsgoober
does have convenientextractCss
method [12] but itscss
paradigm lacks testing and features like composition [13]picostyle
only 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 :