magnostic
TypeScript icon, indicating that this package has built-in type declarations

0.0.10 • Public • Published

magnostic 🧲

status npm minified gzip size dependency count license

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 a css paradigm which requires a Babel plugin
  • monad-ui has @emotion/core, React and React DOM as peer dependencies [9]
  • jss [10] , aphrodite [11] and many others don't support template literals
  • goober does have convenient extractCss method [12] but its css 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 :

  • npm run build — Use tsup and esbuild to bundle library and generate typings
  • npm run test — Build then run tests with uvu
  • npm run lint — Run linting checks with xo and fix common issues

Package Sidebar

Install

npm i magnostic

Weekly Downloads

3

Version

0.0.10

License

MIT

Unpacked Size

22.9 kB

Total Files

26

Last publish

Collaborators

  • tommywalkie