styled-system
Advanced tools
Comparing version 1.0.0-15 to 1.0.0
@@ -5,10 +5,12 @@ 'use strict'; | ||
var _require = require('./util'), | ||
breaks = _require.breaks, | ||
idx = _require.idx, | ||
merge = _require.merge, | ||
arr = _require.arr, | ||
dec = _require.dec, | ||
media = _require.media; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
var _require2 = require('./util'), | ||
breaks = _require2.breaks, | ||
merge = _require2.merge, | ||
arr = _require2.arr, | ||
dec = _require2.dec, | ||
media = _require2.media; | ||
var REG = /^color|bg$/; | ||
@@ -21,3 +23,3 @@ | ||
var bp = breaks(props); | ||
var palette = idx(['theme', 'colors'], props) || {}; | ||
var palette = get(props, 'theme.colors', {}); | ||
@@ -38,8 +40,5 @@ return keys.map(function (key) { | ||
return function (n) { | ||
return idx(getKeys(n), obj) || n; | ||
return get(obj, n + '', n); | ||
}; | ||
}; | ||
var getKeys = function getKeys(n) { | ||
return typeof n === 'string' ? n.split('.') : [n]; | ||
}; | ||
@@ -46,0 +45,0 @@ var properties = { |
'use strict'; | ||
var _require = require('./util'), | ||
is = _require.is, | ||
idx = _require.idx, | ||
arr = _require.arr, | ||
num = _require.num, | ||
px = _require.px, | ||
breaks = _require.breaks, | ||
dec = _require.dec, | ||
media = _require.media, | ||
merge = _require.merge; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
var _require2 = require('./constants'), | ||
fontSizes = _require2.fontSizes; | ||
var _require2 = require('./util'), | ||
is = _require2.is, | ||
arr = _require2.arr, | ||
num = _require2.num, | ||
px = _require2.px, | ||
breaks = _require2.breaks, | ||
dec = _require2.dec, | ||
media = _require2.media, | ||
merge = _require2.merge; | ||
var _require3 = require('./constants'), | ||
fontSizes = _require3.fontSizes; | ||
module.exports = function (props) { | ||
@@ -21,3 +23,3 @@ var n = is(props.fontSize) ? props.fontSize : props.fontSize || props.f; | ||
var scale = idx(['theme', 'fontSizes'], props) || fontSizes; | ||
var scale = get(props, 'theme.fontSizes', fontSizes); | ||
@@ -24,0 +26,0 @@ if (!Array.isArray(n)) { |
'use strict'; | ||
// core | ||
var space = require('./space'); | ||
@@ -7,4 +8,28 @@ var width = require('./width'); | ||
var color = require('./color'); | ||
// low-level style function creators | ||
var style = require('./style'); | ||
var responsiveStyle = require('./responsive-style'); | ||
var pseudoStyle = require('./pseudo-style'); | ||
// extras | ||
var textAlign = require('./text-align'); | ||
var fontWeight = require('./font-weight'); | ||
var alignItems = require('./align-items'); | ||
var justifyContent = require('./justify-content'); | ||
var flexWrap = require('./flex-wrap'); | ||
var flexDirection = require('./flex-direction'); | ||
var flex = require('./flex'); | ||
var alignSelf = require('./align-self'); | ||
var borderRadius = require('./border-radius'); | ||
var borderColor = require('./border-color'); | ||
var borderWidth = require('./border-width'); | ||
var boxShadow = require('./box-shadow'); | ||
var hover = require('./hover'); | ||
var focus = require('./focus'); | ||
var active = require('./active'); | ||
var disabled = require('./disabled'); | ||
// other | ||
var theme = require('./theme'); | ||
var removeProps = require('./remove-props'); | ||
@@ -21,2 +46,20 @@ var util = require('./util'); | ||
responsiveStyle: responsiveStyle, | ||
pseudoStyle: pseudoStyle, | ||
textAlign: textAlign, | ||
fontWeight: fontWeight, | ||
alignItems: alignItems, | ||
justifyContent: justifyContent, | ||
flexWrap: flexWrap, | ||
flexDirection: flexDirection, | ||
flex: flex, | ||
alignSelf: alignSelf, | ||
borderRadius: borderRadius, | ||
borderColor: borderColor, | ||
borderWidth: borderWidth, | ||
boxShadow: boxShadow, | ||
hover: hover, | ||
focus: focus, | ||
active: active, | ||
disabled: disabled, | ||
theme: theme, | ||
removeProps: removeProps, | ||
@@ -23,0 +66,0 @@ util: util, |
@@ -5,16 +5,33 @@ 'use strict'; | ||
var _require = require('./util'), | ||
is = _require.is, | ||
idx = _require.idx, | ||
arr = _require.arr, | ||
num = _require.num, | ||
px = _require.px, | ||
breaks = _require.breaks, | ||
dec = _require.dec, | ||
media = _require.media, | ||
merge = _require.merge; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
module.exports = function (key, prop, boolValue) { | ||
var _require2 = require('./util'), | ||
is = _require2.is, | ||
arr = _require2.arr, | ||
num = _require2.num, | ||
px = _require2.px, | ||
breaks = _require2.breaks, | ||
dec = _require2.dec, | ||
media = _require2.media, | ||
merge = _require2.merge; | ||
module.exports = function () { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return function (props) { | ||
prop = prop || key; | ||
// support for legacy API | ||
var arg = args[0], | ||
_prop = args[1], | ||
_bool = args[2]; | ||
var _ref = typeof arg === 'string' ? { cssProperty: arg, prop: _prop, boolValue: _bool } : arg, | ||
cssProperty = _ref.cssProperty, | ||
prop = _ref.prop, | ||
boolValue = _ref.boolValue, | ||
key = _ref.key; | ||
prop = prop || cssProperty; | ||
var n = props[prop]; | ||
@@ -24,10 +41,10 @@ if (!is(n)) return null; | ||
var bp = breaks(props); | ||
var scale = idx(['theme', prop], props) || {}; | ||
var scale = get(props, ['theme', key || prop].join('.'), {}); | ||
if (!Array.isArray(n)) { | ||
return _defineProperty({}, key, sx(scale)(bool(boolValue)(n))); | ||
return _defineProperty({}, cssProperty, sx(scale)(bool(boolValue)(n))); | ||
} | ||
var val = arr(n); | ||
return val.map(bool(boolValue)).map(sx(scale)).map(dec(key)).map(media(bp)).reduce(merge, {}); | ||
return val.map(bool(boolValue)).map(sx(scale)).map(dec(cssProperty)).map(media(bp)).reduce(merge, {}); | ||
}; | ||
@@ -34,0 +51,0 @@ }; |
@@ -7,16 +7,18 @@ 'use strict'; | ||
var _require = require('./util'), | ||
arr = _require.arr, | ||
idx = _require.idx, | ||
px = _require.px, | ||
neg = _require.neg, | ||
num = _require.num, | ||
breaks = _require.breaks, | ||
dec = _require.dec, | ||
media = _require.media, | ||
merge = _require.merge; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
var _require2 = require('./constants'), | ||
space = _require2.space; | ||
var _require2 = require('./util'), | ||
arr = _require2.arr, | ||
px = _require2.px, | ||
neg = _require2.neg, | ||
num = _require2.num, | ||
breaks = _require2.breaks, | ||
dec = _require2.dec, | ||
media = _require2.media, | ||
merge = _require2.merge; | ||
var _require3 = require('./constants'), | ||
space = _require3.space; | ||
var REG = /^[mp][trblxy]?$/; | ||
@@ -29,3 +31,3 @@ | ||
var bp = breaks(props); | ||
var sc = idx(['theme', 'space'], props) || space; | ||
var sc = get(props, 'theme.space', space); | ||
@@ -32,0 +34,0 @@ return keys.map(function (key) { |
@@ -5,6 +5,8 @@ 'use strict'; | ||
var _require = require('./util'), | ||
is = _require.is, | ||
idx = _require.idx; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
var _require2 = require('./util'), | ||
is = _require2.is; | ||
module.exports = function (_ref) { | ||
@@ -17,3 +19,3 @@ var key = _ref.key, | ||
if (!is(n)) return null; | ||
var scale = idx(['theme', key], props) || {}; | ||
var scale = get(props, ['theme', key].join('.'), {}); | ||
var val = scale[n] || n; | ||
@@ -20,0 +22,0 @@ |
@@ -9,5 +9,8 @@ 'use strict'; | ||
var _require = require('./constants'), | ||
breakpoints = _require.breakpoints; | ||
var _require = require('dot-prop'), | ||
get = _require.get; | ||
var _require2 = require('./constants'), | ||
breakpoints = _require2.breakpoints; | ||
var is = function is(n) { | ||
@@ -31,6 +34,6 @@ return n !== undefined && n !== null; | ||
}; | ||
var idx = function idx(p, obj) { | ||
return p.reduce(function (a, b) { | ||
return a && a[b] ? a[b] : null; | ||
}, obj); | ||
// keeping for backwards-compatibility only | ||
var idx = function idx(keys, obj) { | ||
return get(obj, keys.join('.')) || null; | ||
}; | ||
@@ -43,3 +46,3 @@ | ||
var breaks = function breaks(props) { | ||
return [null].concat(_toConsumableArray((idx(['theme', 'breakpoints'], props) || breakpoints).map(mq))); | ||
return [null].concat(_toConsumableArray(get(props, 'theme.breakpoints', breakpoints).map(mq))); | ||
}; | ||
@@ -46,0 +49,0 @@ |
{ | ||
"name": "styled-system", | ||
"version": "1.0.0-15", | ||
"version": "1.0.0", | ||
"description": "Design system utilities for styled-components, glamorous, and other css-in-js libraries", | ||
@@ -56,3 +56,5 @@ "main": "dist/index.js", | ||
"bundlesize": [ | ||
{ "path": "dist/*.js" } | ||
{ | ||
"path": "dist/*.js" | ||
} | ||
], | ||
@@ -62,3 +64,6 @@ "repository": { | ||
"url": "git+https://github.com/jxnblk/styled-system.git" | ||
}, | ||
"dependencies": { | ||
"dot-prop": "^4.2.0" | ||
} | ||
} |
394
README.md
# styled-system | ||
Design system utilities for styled-components, glamorous, and other css-in-js libraries | ||
Design system utilities for [styled-components][sc] and other css-in-js libraries | ||
@@ -17,9 +17,27 @@ [![Build Status][build-badge]][build] | ||
## Features | ||
- Add style props that hook into your own theme | ||
- Influenced by constraint-based design system principles | ||
- Typographic scale | ||
- Spacing scale for margin and padding | ||
- Default 8px grid | ||
- Works with any color palette | ||
- Responsive prop values for quickly setting responsive font-size, margin, padding, width, and more | ||
- Works with most css-in-js libraries, including [styled-components][sc], [glamorous][glamorous], [emotion][emotion], [fela][fela], and [cxs][cxs] | ||
> "The future of css-in-js is going to look something like styled-system with its responsive values."<br/> | ||
> – [Kye Hohenberger](https://mobile.twitter.com/tkh44/status/905474043729416192) | ||
> "Coming from @tachyons_css, the styled-system utilities from @jxnblk is the missing link I’ve been looking for."<br/> | ||
> – [Nathan Young](https://mobile.twitter.com/nathanyoung/status/891353221880360960) | ||
## Usage | ||
```jsx | ||
// With styled-components | ||
// Example uses styled-components, but works with most other css-in-js libraries as well | ||
import styled from 'styled-components' | ||
import { space, width, fontSize, color } from 'styled-system' | ||
// Add styled-system functions to your component | ||
const Box = styled.div` | ||
@@ -33,10 +51,7 @@ ${space} | ||
```jsx | ||
// Or with glamorous | ||
import glamorous from 'glamorous' | ||
import { space, width, fontSize, color } from 'styled-system' | ||
Each style function exposes its own set of props that style | ||
elements based on values defined in a theme. | ||
Some props allow an array value to be passed to set styles | ||
responsively per-breakpoint. | ||
const Box = glamorous.div(space, width, fontSize, color) | ||
``` | ||
```jsx | ||
@@ -75,30 +90,40 @@ // width: 50% | ||
## width | ||
## API | ||
```js | ||
import { width } from 'styled-system' | ||
``` | ||
- [**Core**](#core) | ||
- [space](#space-responsive) (margins & paddings) | ||
- [width](#width-responsive) | ||
- [fontSize](#fontSize-responsive) | ||
- [color](#color-responsive) (and background-color) | ||
- [Responsive Styles](#responsive-styles) | ||
- [**Extras**](#extras) | ||
- [textAlign](#textAlign-responsive) | ||
- [fontWeight](#fontWeight) | ||
- [alignItems](#alignItems) | ||
- [justifyContent](#justifyContent) | ||
- [flexWrap](#flexWrap) | ||
- [flexDirection](#flexDirection) | ||
- [flex](#flex) | ||
- [alignSelf](#alignSelf) | ||
- [borderRadius](#borderRadius) | ||
- [borderColor](#borderColor) | ||
- [borderWidth](#borderWidth) | ||
- [boxShadow](#boxShadow) | ||
- [hover](#hover) | ||
- [focus](#focus) | ||
- [active](#active) | ||
- [disabled](#disabled) | ||
- [**Utilities**](#utilities) | ||
- [theme](#theme) | ||
- [removeProps](#removeProps) | ||
- [**Low-level**](#Low-level-style-functions) | ||
- [style](#style) | ||
- [responsiveStyle](#responsiveStyle) | ||
- [pseudoStyle](#pseudoStyle) | ||
The width utility parses a component's `width` prop and converts it into a CSS width declaration. | ||
## Core | ||
Numbers from 0-1 are converted to percentage widths. | ||
Numbers greater than 1 are converted to pixel values. | ||
String values are passed as raw CSS values. | ||
And arrays are converted to [responsive width styles](#responsive-styles). | ||
### space (responsive) | ||
## fontSize | ||
```js | ||
import { fontSize } from 'styled-system' | ||
``` | ||
The fontSize utility parses a component's `fontSize` prop and converts it into a CSS font-size declaration. | ||
Numbers from 0-8 are converted to values on the [font size scale](#font-size-scale). | ||
Numbers greater than 8 are converted to raw pixel values. | ||
String values are passed as raw CSS values. | ||
And array values are converted into [responsive values](#responsive-styles). | ||
## space | ||
```js | ||
import { space } from 'styled-system' | ||
@@ -111,3 +136,3 @@ ``` | ||
Numbers greater than 4 are converted to raw pixel values. | ||
String values are converted passed as raw CSS values. | ||
String values are passed as raw CSS values. | ||
And array values are converted into [responsive values](#responsive-styles). | ||
@@ -132,5 +157,30 @@ | ||
## color | ||
### width (responsive) | ||
```js | ||
import { width } from 'styled-system' | ||
``` | ||
The width utility parses a component's `width` prop and converts it into a CSS width declaration. | ||
- Numbers from 0-1 are converted to percentage widths. | ||
- Numbers greater than 1 are converted to pixel values. | ||
- String values are passed as raw CSS values. | ||
- And arrays are converted to [responsive width styles](#responsive-styles). | ||
### fontSize (responsive) | ||
```js | ||
import { fontSize } from 'styled-system' | ||
``` | ||
The fontSize utility parses a component's `fontSize` prop and converts it into a CSS font-size declaration. | ||
Numbers from 0-8 are converted to values on the [font size scale](#font-size-scale). | ||
Numbers greater than 8 are converted to raw pixel values. | ||
String values are passed as raw CSS values. | ||
And array values are converted into [responsive values](#responsive-styles). | ||
### color (responsive) | ||
```js | ||
import { color } from 'styled-system' | ||
@@ -144,6 +194,7 @@ ``` | ||
--- | ||
## Responsive Styles | ||
### Responsive Styles | ||
All props accept arrays as values for mobile-first responsive styles. | ||
All core function props accept arrays as values for mobile-first responsive styles. | ||
@@ -166,26 +217,156 @@ ```jsx | ||
## responsiveStyle | ||
--- | ||
The `responsiveStyle` utility can be used to handle array-based responsive style props for other CSS properties. | ||
## Extras | ||
These functions are for adding other theme-based style props to a component. | ||
For practical reasons, some props do not accept arrays for responsive styles. | ||
### textAlign (responsive) | ||
```js | ||
import styled from 'styled-components' | ||
import { responsiveStyle } from 'styled-system' | ||
import { textAlign } from 'styled-system' | ||
// <Text align='center' /> | ||
``` | ||
// Usage | ||
// responsiveStyle(cssProperty[, propName][, booleanValue]) | ||
### fontWeight | ||
const Flex = styled.div` | ||
display: flex; | ||
${responsiveStyle('flex-direction', 'direction')} | ||
` | ||
```js | ||
import { fontWeight } from 'styled-system' | ||
// <Text weight='bold' /> | ||
// props.theme.fontWeights.bold | ||
``` | ||
const App = props => ( | ||
<Flex direction={[ 'column', 'row' ]}> | ||
<div>Responsive</div> | ||
<div>Direction</div> | ||
</Flex> | ||
) | ||
### alignItems (responsive) | ||
```js | ||
import { alignItems } from 'styled-system' | ||
// <Flex alignItems='center' /> | ||
``` | ||
### justifyContent (responsive) | ||
```js | ||
import { justifyContent } from 'styled-system' | ||
// <Flex justifyContent='center' /> | ||
``` | ||
### flexWrap (responsive) | ||
```js | ||
import { flexWrap } from 'styled-system' | ||
// <Flex flexWrap /> | ||
``` | ||
### flexDirection (responsive) | ||
```js | ||
import { flexDirection } from 'styled-system' | ||
// <Flex flexDirection='column' /> | ||
``` | ||
### flex (responsive) | ||
```js | ||
import { flex } from 'styled-system' | ||
// <Box flex='none' /> | ||
``` | ||
### alignSelf (responsive) | ||
```js | ||
import { alignSelf } from 'styled-system' | ||
// <Box alignSelf='baseline' /> | ||
``` | ||
### borderRadius | ||
```js | ||
import { borderRadius } from 'styled-system' | ||
// <Box borderRadius={1} /> | ||
// props.theme.radii[1] | ||
``` | ||
### borderColor | ||
```js | ||
import { borderColor } from 'styled-system' | ||
// <Box borderColor='blue' /> | ||
// props.theme.colors.blue | ||
``` | ||
### borderWidth | ||
```js | ||
import { borderWidth } from 'styled-system' | ||
// <Box borderWidth={1} /> | ||
// props.theme.borderWidths | ||
``` | ||
```js | ||
// Only apply border in one direction | ||
<Box borderWidth={1} borderBottom /> | ||
// Or in multiple directions | ||
<Box borderWidth={1} borderTop borderBottom /> | ||
``` | ||
### boxShadow | ||
```js | ||
import { boxShadow } from 'styled-system' | ||
// <Box boxShadow={1} /> | ||
// props.theme.shadows[1] | ||
``` | ||
### hover | ||
```js | ||
import { hover } from 'styled-system' | ||
// <Box hover={{ color: 'blue' }} /> | ||
// props.theme.colors.blue | ||
``` | ||
### focus | ||
```js | ||
import { focus } from 'styled-system' | ||
// <Box focus={{ color: 'blue' }} /> | ||
// props.theme.colors.blue | ||
``` | ||
### active | ||
```js | ||
import { active } from 'styled-system' | ||
// <Box active={{ color: 'navy' }} /> | ||
// props.theme.colors.navy | ||
``` | ||
### disabled | ||
```js | ||
import { disabled } from 'styled-system' | ||
// <Box disabledStyle={{ color: 'gray' }} /> | ||
// props.theme.colors.gray | ||
``` | ||
--- | ||
## Utilities | ||
### theme | ||
The theme function can be used in any style declaration to get a value | ||
from your theme, with support for fallback values. | ||
```js | ||
import styled from 'styled-components' | ||
import { theme } from 'styled-system' | ||
const Box = styled.div` | ||
border-radius: ${theme('radii.small')}; | ||
` | ||
``` | ||
## Remove Props | ||
@@ -222,2 +403,95 @@ | ||
--- | ||
## Low-level style functions | ||
To convert other CSS properties into styled-system props, | ||
use the following low-level utility functions. | ||
### style | ||
Sets non-responsive styles using thematic values, based on props. | ||
```js | ||
import styled from 'styled-components' | ||
import { style } from 'styled-system' | ||
const textShadow = style({ | ||
// React prop name | ||
prop: 'shadow', | ||
// The corresponding CSS property | ||
cssProperty: 'textShadow', | ||
// set a key to find values from `props.theme` | ||
key: 'shadows' | ||
}) | ||
const ShadowText = styled(Text)` | ||
${textShadow} | ||
` | ||
// with a `theme.shadows` array | ||
const App = props => ( | ||
<ShadowText shadow={0}> | ||
Shady | ||
</ShadowText> | ||
) | ||
``` | ||
### responsiveStyle | ||
The `responsiveStyle` utility can be used to handle array-based responsive style props for other CSS properties. | ||
```js | ||
import styled from 'styled-components' | ||
import { responsiveStyle } from 'styled-system' | ||
const flexDirection = responsiveStyle({ | ||
prop: 'direction', | ||
cssProperty: 'flexDirection' | ||
}) | ||
const Flex = styled.div` | ||
display: flex; | ||
${flexDirection} | ||
` | ||
const App = props => ( | ||
<Flex direction={[ 'column', 'row' ]}> | ||
<div>Responsive</div> | ||
<div>Direction</div> | ||
</Flex> | ||
) | ||
``` | ||
### pseudoStyle | ||
Adds style props for pseudoclasses like `hover`, `focus`, `active`, etc. | ||
```js | ||
import styled from 'styled-components' | ||
import { pseudoStyle } from 'styled-system' | ||
const checkedStyle = pseudoStyle('checked', 'checkedSyle')({ | ||
// keys for theme-based values | ||
color: 'colors', | ||
backgroundColor: 'colors', | ||
}) | ||
const FancyCheckbox = styled.input` | ||
/* ...base styles */ | ||
${checkedStyle} | ||
` | ||
FancyCheckbox.defaultProps = { | ||
type: 'checkbox' | ||
} | ||
// <FancyCheckbox checkedStyle={{ backgroundColor: 'blue' }} /> | ||
``` | ||
--- | ||
## Default Theme | ||
If no theme is provided, styled-system uses smart defaults for breakpoints, the typographic scale, and the spacing scale. | ||
## Breakpoints | ||
@@ -266,3 +540,3 @@ | ||
styled-system can be configured with styled-components' | ||
styled-system can be configured with styled-components' (or other library's) | ||
[ThemeProvider](https://www.styled-components.com/docs/advanced#theming) | ||
@@ -275,3 +549,2 @@ | ||
import { ThemeProvider } from 'styled-components' | ||
// or import { ThemeProvider } from 'glamorous' | ||
import MyComponent from './MyComponent' | ||
@@ -310,6 +583,15 @@ | ||
- [Rebass](http://jxnblk.com/rebass) | ||
- [styled-components](https://github.com/styled-components/styled-components) | ||
- [glamorous](https://github.com/paypal/glamorous) | ||
- [styled-components][sc] | ||
- [glamorous][glamorous] | ||
- [emotion][emotion] | ||
- [fela][fela] | ||
- [cxs][cxs] | ||
[sc]: https://github.com/styled-components/styled-components | ||
[glamorous]: https://github.com/paypal/glamorous | ||
[emotion]: https://github.com/emotion-js/emotion | ||
[fela]: https://github.com/rofrischmann/fela | ||
[cxs]: https://github.com/jxnblk/cxs | ||
MIT License | ||
@@ -1,2 +0,3 @@ | ||
const { breaks, idx, merge, arr, dec, media } = require('./util') | ||
const { get } = require('dot-prop') | ||
const { breaks, merge, arr, dec, media } = require('./util') | ||
@@ -8,3 +9,3 @@ const REG = /^color|bg$/ | ||
const bp = breaks(props) | ||
const palette = idx([ 'theme', 'colors' ], props) || {} | ||
const palette = get(props, 'theme.colors', {}) | ||
@@ -29,4 +30,3 @@ return keys.map(key => { | ||
const cx = obj => n => idx(getKeys(n), obj) || n | ||
const getKeys = n => typeof n === 'string' ? n.split('.') : [ n ] | ||
const cx = obj => n => get(obj, n + '', n) | ||
@@ -33,0 +33,0 @@ const properties = { |
@@ -1,2 +0,3 @@ | ||
const { is, idx, arr, num, px, breaks, dec, media, merge } = require('./util') | ||
const { get } = require('dot-prop') | ||
const { is, arr, num, px, breaks, dec, media, merge } = require('./util') | ||
const { fontSizes } = require('./constants') | ||
@@ -8,3 +9,3 @@ | ||
const scale = idx([ 'theme', 'fontSizes' ], props) || fontSizes | ||
const scale = get(props, 'theme.fontSizes', fontSizes) | ||
@@ -11,0 +12,0 @@ if (!Array.isArray(n)) { |
@@ -0,1 +1,3 @@ | ||
// core | ||
const space = require('./space') | ||
@@ -5,4 +7,28 @@ const width = require('./width') | ||
const color = require('./color') | ||
// low-level style function creators | ||
const style = require('./style') | ||
const responsiveStyle = require('./responsive-style') | ||
const pseudoStyle = require('./pseudo-style') | ||
// extras | ||
const textAlign = require('./text-align') | ||
const fontWeight = require('./font-weight') | ||
const alignItems = require('./align-items') | ||
const justifyContent = require('./justify-content') | ||
const flexWrap = require('./flex-wrap') | ||
const flexDirection = require('./flex-direction') | ||
const flex = require('./flex') | ||
const alignSelf = require('./align-self') | ||
const borderRadius = require('./border-radius') | ||
const borderColor = require('./border-color') | ||
const borderWidth = require('./border-width') | ||
const boxShadow = require('./box-shadow') | ||
const hover = require('./hover') | ||
const focus = require('./focus') | ||
const active = require('./active') | ||
const disabled = require('./disabled') | ||
// other | ||
const theme = require('./theme') | ||
const removeProps = require('./remove-props') | ||
@@ -19,2 +45,20 @@ const util = require('./util') | ||
responsiveStyle, | ||
pseudoStyle, | ||
textAlign, | ||
fontWeight, | ||
alignItems, | ||
justifyContent, | ||
flexWrap, | ||
flexDirection, | ||
flex, | ||
alignSelf, | ||
borderRadius, | ||
borderColor, | ||
borderWidth, | ||
boxShadow, | ||
hover, | ||
focus, | ||
active, | ||
disabled, | ||
theme, | ||
removeProps, | ||
@@ -21,0 +65,0 @@ util, |
@@ -1,5 +0,12 @@ | ||
const { is, idx, arr, num, px, breaks, dec, media, merge } = require('./util') | ||
const { get } = require('dot-prop') | ||
const { is, arr, num, px, breaks, dec, media, merge } = require('./util') | ||
module.exports = (key, prop, boolValue) => props => { | ||
prop = prop || key | ||
module.exports = (...args) => props => { | ||
// support for legacy API | ||
const [ arg, _prop, _bool ] = args | ||
let { cssProperty, prop, boolValue, key } = typeof arg === 'string' | ||
? { cssProperty: arg, prop: _prop, boolValue: _bool } | ||
: arg | ||
prop = prop || cssProperty | ||
const n = props[prop] | ||
@@ -9,7 +16,7 @@ if (!is(n)) return null | ||
const bp = breaks(props) | ||
const scale = idx([ 'theme', prop ], props) || {} | ||
const scale = get(props, [ 'theme', key || prop ].join('.'), {}) | ||
if (!Array.isArray(n)) { | ||
return { | ||
[key]: sx(scale)( | ||
[cssProperty]: sx(scale)( | ||
bool(boolValue)(n) | ||
@@ -24,3 +31,3 @@ ) | ||
.map(sx(scale)) | ||
.map(dec(key)) | ||
.map(dec(cssProperty)) | ||
.map(media(bp)) | ||
@@ -27,0 +34,0 @@ .reduce(merge, {}) |
@@ -0,4 +1,4 @@ | ||
const { get } = require('dot-prop') | ||
const { | ||
arr, | ||
idx, | ||
px, | ||
@@ -21,3 +21,3 @@ neg, | ||
const bp = breaks(props) | ||
const sc = idx([ 'theme', 'space' ], props) || space | ||
const sc = get(props, 'theme.space', space) | ||
@@ -24,0 +24,0 @@ return keys.map(key => { |
@@ -1,2 +0,3 @@ | ||
const { is, idx } = require('./util') | ||
const { get } = require('dot-prop') | ||
const { is } = require('./util') | ||
@@ -10,3 +11,3 @@ module.exports = ({ | ||
if (!is(n)) return null | ||
const scale = idx([ 'theme', key ], props) || {} | ||
const scale = get(props, [ 'theme', key ].join('.'), {}) | ||
const val = scale[n] || n | ||
@@ -13,0 +14,0 @@ |
@@ -0,1 +1,2 @@ | ||
const { get } = require('dot-prop') | ||
const { breakpoints } = require('./constants') | ||
@@ -9,4 +10,6 @@ | ||
const arr = n => Array.isArray(n) ? n : [ n ] | ||
const idx = (p, obj) => p.reduce((a, b) => (a && a[b]) ? a[b] : null, obj) | ||
// keeping for backwards-compatibility only | ||
const idx = (keys, obj) => get(obj, keys.join('.')) || null | ||
const mq = n => `@media screen and (min-width: ${em(n)})` | ||
@@ -16,3 +19,3 @@ | ||
null, | ||
...(idx([ 'theme', 'breakpoints' ], props) || breakpoints).map(mq) | ||
...get(props, 'theme.breakpoints', breakpoints).map(mq) | ||
] | ||
@@ -19,0 +22,0 @@ |
358
test.js
import test from 'ava' | ||
import palx from 'palx' | ||
import { | ||
import system, { | ||
space, | ||
@@ -10,4 +10,21 @@ width, | ||
responsiveStyle, | ||
pseudoStyle, | ||
removeProps, | ||
util | ||
util, | ||
textAlign, | ||
fontWeight, | ||
alignItems, | ||
justifyContent, | ||
flexWrap, | ||
flexDirection, | ||
flex, | ||
alignSelf, | ||
borderRadius, | ||
borderColor, | ||
borderWidth, | ||
boxShadow, | ||
hover, | ||
focus, | ||
active, | ||
disabled, | ||
} from './src' | ||
@@ -33,2 +50,7 @@ | ||
test('system.theme gets theme values', t => { | ||
const a = system.theme('colors.blue')({ theme }) | ||
t.is(a, theme.colors.blue) | ||
}) | ||
// util | ||
@@ -580,2 +602,54 @@ test('util.is checks for non null values', t => { | ||
test('responsiveStyle accepts and object argument', t => { | ||
const direction = responsiveStyle({ | ||
cssProperty: 'flexDirection', | ||
prop: 'direction' | ||
}) | ||
const a = direction({ direction: [ 'column', 'row' ] }) | ||
t.deepEqual(a, { | ||
'flexDirection': 'column', | ||
'@media screen and (min-width: 40em)': { | ||
'flexDirection': 'row' | ||
} | ||
}) | ||
}) | ||
test('psuedoStyle returns a function', t => { | ||
const hover = pseudoStyle('hover') | ||
const hoverStyle = pseudoStyle('hover')() | ||
t.is(typeof hover, 'function') | ||
t.is(typeof hoverStyle, 'function') | ||
}) | ||
test('pseudoStyle returns a style object', t => { | ||
const hoverStyle = pseudoStyle('hover')({}) | ||
const a = hoverStyle({ | ||
hover: { | ||
color: 'tomato' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:hover': { | ||
color: 'tomato' | ||
} | ||
}) | ||
}) | ||
test('pseudoStyle uses theme values', t => { | ||
const hoverStyle = pseudoStyle('hover')({ | ||
color: 'colors' | ||
}) | ||
const a = hoverStyle({ | ||
theme, | ||
hover: { | ||
color: 'blue' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:hover': { | ||
color: theme.colors.blue | ||
} | ||
}) | ||
}) | ||
// theme | ||
@@ -621,1 +695,281 @@ test('breakpoints can be configured with a theme', t => { | ||
}) | ||
// textAlign | ||
test('textAlign returns text-align', t => { | ||
const a = textAlign({ align: 'center' }) | ||
t.deepEqual(a, { textAlign: 'center' }) | ||
}) | ||
// textAlign | ||
test('textAlign returns text-align', t => { | ||
const a = textAlign({ align: 'center' }) | ||
t.deepEqual(a, { textAlign: 'center' }) | ||
}) | ||
test('textAlign returns responsive text-align', t => { | ||
const a = textAlign({ align: [ 'center', 'left' ] }) | ||
t.deepEqual(a, { | ||
textAlign: 'center', | ||
'@media screen and (min-width: 40em)': { | ||
textAlign: 'left', | ||
} | ||
}) | ||
}) | ||
// fontWeight | ||
test('fontWeight returns fontWeight', t => { | ||
const a = fontWeight({ fontWeight: 'bold' }) | ||
t.deepEqual(a, { fontWeight: 'bold' }) | ||
}) | ||
test('fontWeight returns a scalar style', t => { | ||
const a = fontWeight({ | ||
theme: { | ||
fontWeights: [ | ||
400, 600, 800 | ||
] | ||
}, | ||
fontWeight: 2 | ||
}) | ||
t.deepEqual(a, { fontWeight: 800 }) | ||
}) | ||
test('alignItems returns a style', t => { | ||
const a = alignItems({ align: 'center' }) | ||
t.deepEqual(a, { alignItems: 'center' }) | ||
}) | ||
test('justifyContent returns a style', t => { | ||
const a = justifyContent({ justify: 'center' }) | ||
t.deepEqual(a, { justifyContent: 'center' }) | ||
}) | ||
test('flexWrap returns a style', t => { | ||
const a = flexWrap({ wrap: true }) | ||
t.deepEqual(a, { flexWrap: 'wrap' }) | ||
}) | ||
test('flexDirection returns a style', t => { | ||
const a = flexDirection({ flexDirection: 'column' }) | ||
t.deepEqual(a, { flexDirection: 'column' }) | ||
}) | ||
test('flex returns a style', t => { | ||
const a = flex({ flex: 'none' }) | ||
t.deepEqual(a, { flex: 'none' }) | ||
}) | ||
test('alignSelf returns a style', t => { | ||
const a = alignSelf({ alignSelf: 'center' }) | ||
t.deepEqual(a, { alignSelf: 'center' }) | ||
}) | ||
test('borderRadius returns borderRadius', t => { | ||
const a = borderRadius({ borderRadius: '4px' }) | ||
t.deepEqual(a, { borderRadius: '4px' }) | ||
}) | ||
test('borderColor returns borderColor', t => { | ||
const a = borderColor({ borderColor: 'blue' }) | ||
t.deepEqual(a, { borderColor: 'blue' }) | ||
}) | ||
test('borderColor returns borderColor', t => { | ||
const a = borderColor({ borderColor: 'blue' }) | ||
t.deepEqual(a, { borderColor: 'blue' }) | ||
}) | ||
test('borderWidth returns borderWidth and borderStyle', t => { | ||
const a = borderWidth({ borderWidth: '2px' }) | ||
t.deepEqual(a, { | ||
borderWidth: '2px', | ||
borderStyle: 'solid' | ||
}) | ||
}) | ||
test('borderWidth returns null', t => { | ||
const a = borderWidth({}) | ||
t.is(a, null) | ||
}) | ||
test('borderWidth returns borderTopWidth and borderTopStyle', t => { | ||
const a = borderWidth({ borderWidth: '2px', borderTop: true }) | ||
t.deepEqual(a, { | ||
borderTopWidth: '2px', | ||
borderTopStyle: 'solid' | ||
}) | ||
}) | ||
test('borderWidth returns borderRightWidth and borderRightStyle', t => { | ||
const a = borderWidth({ borderWidth: '2px', borderRight: true }) | ||
t.deepEqual(a, { | ||
borderRightWidth: '2px', | ||
borderRightStyle: 'solid' | ||
}) | ||
}) | ||
test('borderWidth returns borderBottomWidth and borderBottomWidth', t => { | ||
const a = borderWidth({ borderWidth: '2px', borderBottom: true }) | ||
t.deepEqual(a, { | ||
borderBottomWidth: '2px', | ||
borderBottomStyle: 'solid' | ||
}) | ||
}) | ||
test('borderWidth returns borderLeftWidth and borderLeftStyle', t => { | ||
const a = borderWidth({ borderWidth: '2px', borderLeft: true }) | ||
t.deepEqual(a, { | ||
borderLeftWidth: '2px', | ||
borderLeftStyle: 'solid' | ||
}) | ||
}) | ||
test('borderWidth returns multiple directions', t => { | ||
const a = borderWidth({ | ||
borderWidth: '2px', | ||
borderLeft: true, | ||
borderRight: true, | ||
}) | ||
t.deepEqual(a, { | ||
borderLeftWidth: '2px', | ||
borderLeftStyle: 'solid', | ||
borderRightWidth: '2px', | ||
borderRightStyle: 'solid' | ||
}) | ||
}) | ||
test('boxShadow returns box-shadow styles', t => { | ||
const a = boxShadow({ boxShadow: '0 0 8px rgba(0, 0, 0, .125)' }) | ||
t.deepEqual(a, { boxShadow: '0 0 8px rgba(0, 0, 0, .125)' }) | ||
}) | ||
test('boxShadow returns theme value', t => { | ||
const a = boxShadow({ | ||
theme: { | ||
shadows: [ | ||
'0 0 4px rgba(0, 0, 0, .125)', | ||
'0 0 8px rgba(0, 0, 0, .125)', | ||
] | ||
}, | ||
boxShadow: 1 | ||
}) | ||
t.deepEqual(a, { boxShadow: '0 0 8px rgba(0, 0, 0, .125)' }) | ||
}) | ||
test('hover returns a style object', t => { | ||
const a = hover({ | ||
hover: { | ||
color: 'tomato' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:hover': { | ||
color: 'tomato' | ||
} | ||
}) | ||
}) | ||
test('hover uses theme values', t => { | ||
const a = hover({ | ||
theme, | ||
hover: { | ||
color: 'blue', | ||
backgroundColor: 'green' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:hover': { | ||
color: theme.colors.blue, | ||
backgroundColor: theme.colors.green, | ||
} | ||
}) | ||
}) | ||
test('focus returns a style object', t => { | ||
const a = focus({ | ||
focus: { | ||
color: 'tomato' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:focus': { | ||
color: 'tomato' | ||
} | ||
}) | ||
}) | ||
test('focus uses theme values', t => { | ||
const a = focus({ | ||
theme, | ||
focus: { | ||
color: 'blue', | ||
backgroundColor: 'green' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:focus': { | ||
color: theme.colors.blue, | ||
backgroundColor: theme.colors.green, | ||
} | ||
}) | ||
}) | ||
test('active returns a style object', t => { | ||
const a = active({ | ||
active: { | ||
color: 'tomato' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:active': { | ||
color: 'tomato' | ||
} | ||
}) | ||
}) | ||
test('active uses theme values', t => { | ||
const a = active({ | ||
theme, | ||
active: { | ||
color: 'blue', | ||
backgroundColor: 'green' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:active': { | ||
color: theme.colors.blue, | ||
backgroundColor: theme.colors.green, | ||
} | ||
}) | ||
}) | ||
test('disabled returns a style object', t => { | ||
const a = disabled({ | ||
disabledStyle: { | ||
color: 'tomato' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:disabled': { | ||
color: 'tomato' | ||
} | ||
}) | ||
}) | ||
test('disabled uses theme values', t => { | ||
const a = disabled({ | ||
theme, | ||
disabledStyle: { | ||
color: 'blue', | ||
backgroundColor: 'green' | ||
} | ||
}) | ||
t.deepEqual(a, { | ||
'&:disabled': { | ||
color: theme.colors.blue, | ||
backgroundColor: theme.colors.green, | ||
} | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
66120
64
1865
1
587
1
+ Addeddot-prop@^4.2.0
+ Addeddot-prop@4.2.1(transitive)
+ Addedis-obj@1.0.1(transitive)