
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
systemthing
Advanced tools
Responsive, theme-based style props for building design systems in React JavaScript
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.
This fork provides the same core functionality found in the orignal styled-system libary,
plus:
minus:
While this implementation tries to stay as close as possible to styled-system's original API, the following changes were made:
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.
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.
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.
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:
backgroundsbundled props:
background,
backgroundImage,
backgroundPosition,
backgroundRepeat,
backgroundSize
bordersbundled props:
border,
borderTop,
borderRight,
borderBottom,
borderLeft
colorbundled props:
color,
backgroundColor
directionbundled props:
top,
right,
bottom,
left
flexboxbundled props:
display,
alignContent,
alignSelf,
justifyContent,
justifyItems,
justifySelf,
flex,
flexBasis,
flexDirection,
flexWrap,
order
gridLayoutbundled props:
gridArea,
gridAutoColumns,
gridAutoFlo',
gridAutoRows,
gridRow,
gridRowGap,
gridTemplateAreas,
gridTemplateColumns,
gridTemplateRows
gridGapsbundled props:
gridColumnGap,
gridGap,
gridRow,
gridRowGap,
spacebundled props:
margin,
marginTop,
marginRight,
marginBottom,
marginLeft,
mx,
my,
padding,
paddingTop,
paddingRight,
paddingBottom,
paddingLeft,
px,
py
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.
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.getThe 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.
numThe num utility is renamed to isNum.
pxThe px transformation utility is renamed to addPx.
cloneFuncThe cloneFunc utility has been removed together with the prop-types dependency.
mergeThe merge utility is renamed to mergeStyles.
composeThe compose utility is renamed to composeStyleFns. (may be removed entirely, as it is only used in a benchmarking script right now)
styleThe 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' })
mixedThe mixed utility has been removed entirely.
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 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..
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.
TODO
FAQs
Responsive, theme-based style props for building design systems
We found that systemthing 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
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.