npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

systemthing

v1.74.0

Published

Responsive, theme-based style props for building design systems

Downloads

13

Readme

A System Thing

Responsive, theme-based style props for building design systems in ~~React~~ JavaScript

Build Status Version size MIT License

npm i systemthing

This repository is a fork of the styled-system.

As with styled-system, this fork presents a collection of css-style yielding functions that support the development of responsive and theme-based design systems in JavaScript.

Unlike styled-system, this implementation is geared to also work with virtual dom libraries other than React.

Features

This fork provides the same core functionality found in the orignal styled-system libary,

plus:

minus:

  • Social proof, i. e. not used in Rebass et al.

Table of Contents

Notable differences

While this implementation tries to stay as close as possible to styled-system's original API, the following changes were made:

non-contextual theming

Style yielding functions can be called with a custom theme by passing a theme-object as a second argument.

import { space, fontSize, color } from 'systemthing'

const theme = {
 breakpoints: [ '32em', '48em', '64em' ],
 space: [ 0, 6, 12, 18, 24 ],
 fontSizes: [ 12, 16, 18, 24, 36, 72 ],
 radii: [ 2, 4 ],
 colors: {
   blue: '#07c',
   green: '#1c0',
   gray: ['#ccc', '#555']
 }
}
                       
// aliases
theme.space.big = 64
theme.fontSizes.big = 128

const blue = color({ color: 'blue' }, theme) // yields { color: '07c' }
const big = fontSize({ fontSize: 'big' }, theme) // yields { fontSize: '128px' }
const butAlso = space({ padding: 'big', theme }) // yields { padding: '64px' }

Passing a theme as 2nd argument bypasses React context and allows this implementation to work in concert with any virtual DOM based view layer.

It is still possible however to also use theme as a prop on the first argument. Prop based themes take precedence. styled-system's original theming mechanism remains intact.

No prop abbreviations

Mapping of popular style prop abbreviations to corresponding css properties (e. g. mt to marginTop) is delegated downstream. The only exceptions are mx, my, px and py within the space function. For there are no css equivalents to these props.

Default values

It is possible to directly instrument style yielding functions with default values as a fallback in case no corresponding style props are present at call time.

import { space } from 'systemthing'

const spaceWithDefaults = space.withDefaults({ padding: '1em' })

const spaced = spaceWithDefaults({ foo: 'bar' }) // { padding: '1em' }

Responsive default styles may be useful for defining components that do not require expensive style re-computations down the line.

Prop bundling

To minimize the number of downstream function calls, style props are bundled into a single function where possible.

import { flexbox } from 'systemthing'

const flexing = flexbox({
  display: 'flex',
  justifyContent: 'center',
  flexDirection: 'row-reverse'
})

The following prop bundles are available:

1. backgrounds

bundled props: background, backgroundImage, backgroundPosition, backgroundRepeat, backgroundSize

2. borders

bundled props: border, borderTop, borderRight, borderBottom, borderLeft

3. color

bundled props: color, backgroundColor

4. direction

bundled props: top, right, bottom, left

5. flexbox

bundled props: display, alignContent, alignSelf, justifyContent, justifyItems, justifySelf, flex, flexBasis, flexDirection, flexWrap, order

6. gridLayout

bundled props: gridArea, gridAutoColumns, gridAutoFlo', gridAutoRows, gridRow, gridRowGap, gridTemplateAreas, gridTemplateColumns, gridTemplateRows

7. gridGaps

bundled props: gridColumnGap, gridGap, gridRow, gridRowGap,

8. space

bundled props: margin, marginTop, marginRight, marginBottom, marginLeft, mx, my, padding, paddingTop, paddingRight, paddingBottom, paddingLeft, px, py

No PropTypes

Facebook's prop-types has been removed. Instead type declaration is delegated downstream. Users of this fork have to be prepared to properly type out components themselves, if necessary. This fork ships without external dependencies.

Width fit & fill

The width style yielding function accepts two additional prop values:

  • { width: 'fit' } - Make an element shrink wrap its content with flex-basis.
  • { width: 'fill' } - Make an element fill the remaining space. Distribute space evenly on multiple elements.

low level changes

get

The get utility function accepts excactly two arguments obj :: Object and path :: Array. get's path argument is not being destructured.

Hence, instead of writing:

// wrong
let bingo = get({ path: { in: { obj: 'Bingo' } } }, 'path', 'in', 'obj')

you'd have to write:

// correct
let bingo = get({ path: { in: { obj: 'Bingo' } } }, [ 'path', 'in', 'obj' ])

Secondly, dot notation in path strings is not supported out of the box. The following statement will fail to produce the desired result:

// wont work
let bingo = get({ path: { in: { obj: 'Bingo' } } }, [ 'path.in.obj' ])

Note: Refactoring the get function apparently resulted in significant performance improvements for some style functions.

num

The num utility is renamed to isNum.

px

The px transformation utility is renamed to addPx.

cloneFunc

The cloneFunc utility has been removed together with the prop-types dependency.

merge

The merge utility is renamed to mergeStyles.

compose

The compose utility is renamed to composeStyleFns. (may be removed entirely, as it is only used in a benchmarking script right now)

style

The style utility function is renamed to createStyleFn. The original function was refactored to also process arrays when passed as prop and cssProptery arguments. This enables the prop bundling functionality described above.

import { util } from 'systemthing'

const custom = util.createStyleFn({
  prop: [ 'display', 'overflow', 'opacity' ]
})

const result = custom({ display: 'none', overflow: 'hidden' })

mixed

The mixed utility has been removed entirely.

Usage

This implementation maintains most of styled-system's original API.

Here is an idiomatic usage example:

// Usage in tandem with compatible css-in-js lib is recommended
// Example uses bss, but systemthing works with most other css-in-js libraries as well
import b from 'bss'
import { color, fontSize, util } from 'systemthing'

// custom theme
const theme = {
 breakpoints: [ '32em', '48em', '64em' ],
 space: [ 0, 6, 12, 18, 24 ],
 fontSizes: [ 12, 16, 18, 24, 36, 72 ],
 colors: {
   blue: '#07c',
   green: '#1c0',
   grays: [ '#ccc', '#555', '#ddd' ]
 }
}

// define style props
const props = {
  // responsive background-color (theme.colors)
  backgroundColor: [ 'blue', 'green', 'grays.1', 'grays.2' ],
  // responsive font-size of 24px, 36px or 72px (theme.fontSizes)
  fontSize: [ 3, 4, 5 ],
  // theme passed as prop
  theme
}

// pass style props into the style functions and merge their return values
const result = util.mergeStyles(color(props), fontSize(props))

// result is a responsively themed css style object that
// can then be processed downstream by many css-in-js libraries
const classy = b(result).class

document.body.classList.add(classy)
document.body.appendChild(
  document.createTextNode(
    'Responsively themed! (resize the window!)'))

A live version of this script is available on flems.

Usage within the React ecosystem

Usage in combination with React and React-focused css-in-js libraries such as styled-components or emotion should work as advertised in styled-stystem's documentation (not tested, YMMV).

// Example uses react and styled-components, but systemthing works with most other vdom and css-in-js libraries as well
import React from 'react'
import ReactDOM from 'react-dom' // virtual DOM libary
import styled from 'styled-components' // css-in-js layer / component factory
import { space, width, fontSize, color } from 'systemthing'

// custom theme
const theme = {
 breakpoints: [ '32em', '48em', '64em' ],
 space: [ 0, 6, 12, 18, 24 ],
 fontSizes: [ 12, 16, 18, 24, 36, 72 ],
 colors: {
   blue: '#07c',
   green: '#1c0',
   grays: ['#ccc', '#555']
 }
}

// Add style yielding functions to your component
const Box = styled.div`
  ${space}
  ${width}
  ${fontSize}
  ${color}`

ReactDOM.render(  
  <Box
    // width: 50%
    width={1 / 2}
    // responsive font-size of 24px, 36px or 72px (theme.fontSizes)
    fontSize={[ 3, 4, 5 ]}
    // margin: 12px (theme.space[2])
    margin={2}
    // padding: 18px (theme.space[3])
    padding={3}
    // color: #ccc (theme.colors.grays[0])
    color='grays.0'
    // responsive background-color (theme.colors)
    backgroundColor={[ 'blue', 'green', 'grays.0', 'grays.1' ]}
    // theme passed as prop
    theme={theme}>Hello React!</Box>
, document.body)

A live version of the script is available on flems..

Usage with other vdom libaries

This fork definitely also works well in concert with the more exotic bss and stylething utilities, as well as vdom libaries other than React.

// Example illustrates usage with mithril, bss and stylething 
import m from 'mithril' // virtual DOM libary
import b from 'bss' // css-in-js layer
import { createStyler } from 'stylething' // component factory
import { space, width, fontSize, color } from 'systemthing'

// custom theme
const theme = {
 breakpoints: [ '32em', '48em', '64em' ],
 space: [ 0, 6, 12, 18, 24 ],
 fontSizes: [ 12, 16, 18, 24, 36, 72 ],
 colors: {
   blue: '#07c',
   green: '#1c0',
   grays: [ '#ccc', '#555', '#ddd' ]
 }
}

// instrument stylething's component factory with the vdom lib and bss css-in-js package
// note custom theme passed as a config option
const styled = createStyler(m, b, { mode: 'mithril', output: 'class', theme })

// Add a custom class name and style yielding functions to your component
const Box = styled('.Box', space, width, fontSize, color)

m.mount(document.body, {
 view: () =>
  m(Box, {
    // widthL 50%
    width: 1 / 2,
    // responsive font-size of 24px, 36px or 72px (theme.fontSizes)
    fontSize: [ 3, 4, 5 ],
    // margin: 12px (theme.space[2])
    margin: 2,
    // padding: 18px (theme.space[3])
    padding: 3,
    // color: #ccc (theme.colors.grays[0])
    color: 'grays.0',
    // responsive background-color (theme.colors)
    backgroundColor: [ 'blue', 'green', 'grays.1', 'grays.2' ]
  }, 'Hello Mithril!')
})

A live version of this script is available on flems.

Docs

TODO

Related

MIT License