Skip to content

Commit

Permalink
✨ Use objects with media values in props
Browse files Browse the repository at this point in the history
  • Loading branch information
exah committed Nov 24, 2018
1 parent e30ebcb commit b3f918b
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 51 deletions.
13 changes: 12 additions & 1 deletion src/core/create-prop-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {

import {
wrapIfMedia,
handlePropStyle
handlePropStyle,
hasMediaKeys
} from '../utils/helpers'

import {
Expand Down Expand Up @@ -130,6 +131,16 @@ const createPropStyles = (
propValue(props, mediaKey, style)
)
} else {
// like: { default: 0, M: 1 }
if (hasMediaKeys(mediaKeys, propValue)) {
return reduceObj((subAcc, key, value) => subAcc.concat(
wrapIfMedia(
media[key],
handlePropStyle(style, value, props, key)
) || []
), propValue, [])
}

return wrapIfMedia(
mediaQuery,
handlePropStyle(style, propValue, props, mediaKey)
Expand Down
10 changes: 8 additions & 2 deletions src/utils/helpers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isFn, isNum, isStr, toObj, curryN } from '@exah/utils'
import { isFn, isNum, isStr, isPlainObj, toObj, curryN } from '@exah/utils'

const toCssRule = (cssProps, toPx) => (val) => val != null
? toObj(cssProps, (name) => {
Expand Down Expand Up @@ -55,12 +55,18 @@ const skipPropValue = (...styles) => (value, ...rest) => (
styles.map((s) => s(...rest))
)

const hasMediaKeys = (mediaKeys, value = {}) => (
isPlainObj(value) &&
Object.keys(value).some((key) => mediaKeys.includes(key))
)

export {
toCssRule,
wrap,
wrapIfMedia,
handlePropStyle,
sizeValue,
spaceValue,
skipPropValue
skipPropValue,
hasMediaKeys
}
22 changes: 19 additions & 3 deletions test/css-prop.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test('props: css', (t) => {
})

test('props: css (responsive)', (t) => {
const result = cssProp({
const result1 = cssProp({
theme,
css: {
backgroundColor: 'blue'
Expand All @@ -37,13 +37,29 @@ test('props: css (responsive)', (t) => {
}
})

t.deepEqual(toStyles(result), {
const result2 = cssProp({
theme,
css: {
default: {
backgroundColor: 'blue'
},
M: {
backgroundColor: 'red',
display: 'flex'
}
}
})

const expected = {
backgroundColor: 'blue',
'@media (max-width: 600px)': {
backgroundColor: 'red',
display: 'flex'
}
})
}

t.deepEqual(toStyles(result1), expected)
t.deepEqual(toStyles(result2), expected)
})

test('props: css (callback)', (t) => {
Expand Down
48 changes: 27 additions & 21 deletions test/position.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,49 @@ const theme = {
}

test('props: position', (t) => {
const result = positionPropStyles({
const result1 = positionPropStyles({
theme,
position: 'relative',
positionM: 'static',
top: true,
bottom: false,
left: 1 / 2,
right: 0,
zIndex: 100,
zIndex: 50,
zIndexM: 100
})

t.deepEqual(toStyles(result), {
const result2 = positionPropStyles({
theme,
position: {
default: 'relative',
M: 'static'
},
top: true,
bottom: false,
left: 1 / 2,
right: 0,
zIndex: {
default: 50,
M: 100
}
})

const expected = {
position: 'relative',
top: 0,
bottom: 'auto',
left: '50%',
right: 0,
zIndex: 100,
'@media (max-width: 600px)': {
zIndex: 50,
[`@media ${theme.media.M}`]: {
position: 'static',
zIndex: 100
}
})
}

t.deepEqual(toStyles(result1), expected)
t.deepEqual(toStyles(result2), expected)
})

test('props: position (compat)', (t) => {
Expand All @@ -59,25 +78,12 @@ test('props: position (compat)', (t) => {
left: '50%',
right: 0,
zIndex: 100,
'@media (min-width: 601px) and (max-width: 1024px)': {
[`@media ${theme.media.T}`]: {
position: 'static'
},
'@media (max-width: 600px)': {
[`@media ${theme.media.M}`]: {
position: 'static',
zIndex: 100
}
})
})

test('props: z-index (compat)', (t) => {
const zIndexFalse = positionPropStyles({ theme, zi: false })
const zIndexTrue = positionPropStyles({ theme, zi: true })

t.deepEqual(toStyles(zIndexFalse), {
zIndex: 'auto'
})

t.deepEqual(toStyles(zIndexTrue), {
zIndex: 1
})
})
16 changes: 13 additions & 3 deletions test/prop-styles-in-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,24 @@ test('prop → customStyles → media style', (t) => {
})

test('prop → customStyles → media M style', (t) => {
const result = toStyles(customProps({
const result1 = toStyles(customProps({
theme,
kindM: 'small'
}))

t.deepEqual(result, {
const result2 = toStyles(customProps({
theme,
kind: {
M: 'small'
}
}))

const expected = {
[`@media ${theme.media.M}`]: theme.customStyles.small.M
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('flags → customStyles', (t) => {
Expand Down
37 changes: 31 additions & 6 deletions test/sizes.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,36 +69,61 @@ test('props -> sizes path from theme', (t) => {
})

test('props -> sizes theme values', (t) => {
const result = toStyles(sizesPropStyles({
const result1 = toStyles(sizesPropStyles({
theme,
minWd: 'nudge',
maxWdM: 'xl'
}))

t.deepEqual(result, {
const result2 = toStyles(sizesPropStyles({
theme,
minWd: 'nudge',
maxWd: {
M: 'xl'
}
}))

const expected = {
minWidth: '2px',
'@media (max-width: 600px)': {
minWidth: '1px',
maxWidth: '100px'
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('props -> sizes custom values', (t) => {
const result = toStyles(sizesPropStyles({
const result1 = toStyles(sizesPropStyles({
theme,
ht: '100px',
wdM: '20px',
minHtM: '300px'
}))

t.deepEqual(result, {
const result2 = toStyles(sizesPropStyles({
theme,
ht: '100px',
wd: {
M: '20px'
},
minHt: {
M: '300px'
}
}))

const expected = {
height: '100px',
'@media (max-width: 600px)': {
width: '20px',
minHeight: '300px'
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('style -> set height', (t) => {
Expand Down
20 changes: 14 additions & 6 deletions test/space-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,34 @@ test('props -> set one step space', (t) => {
})

test('props -> set bool space value', (t) => {
const result = toStyles(marginPropStyles({ theme, mg: true, mgxM: false }))
const result1 = toStyles(marginPropStyles({ theme, mg: true, mgxM: false }))
const result2 = toStyles(marginPropStyles({ theme, mg: true, mgx: { M: false } }))

t.deepEqual(result, {
const expected = {
margin: '10px',
'@media (max-width: 600px)': {
marginLeft: 0,
marginRight: 0
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('props -> override one step space on mobile and tablet', (t) => {
const result = toStyles(marginPropStyles({ theme, mg: 1, mglM: 3, mgxT: 0 }))
const result1 = toStyles(marginPropStyles({ theme, mg: 1, mglM: 3, mgxT: 0 }))
const result2 = toStyles(marginPropStyles({ theme, mg: 1, mgl: { M: 3 }, mgx: { T: 0 } }))

t.deepEqual(result, {
const expected = {
margin: '10px',
'@media (max-width: 600px)': { marginLeft: '3rem' },
'@media (min-width: 601px) and (max-width: 1024px)': {
marginLeft: 0,
marginRight: 0
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})
30 changes: 21 additions & 9 deletions test/space.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,37 @@ test('props -> set one step space for every media', (t) => {
})

test('props -> set bool space value', (t) => {
const result = toStyles(marginPropStyles({ theme, mg: true, mgxM: false }))
const result1 = toStyles(marginPropStyles({ theme, mg: true, mgxM: false }))
const result2 = toStyles(marginPropStyles({ theme, mg: true, mgx: { M: false } }))

t.deepEqual(result, {
const expected = {
margin: '10px',
'@media (max-width: 600px)': {
margin: '5px',
marginLeft: 0,
marginRight: 0
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('props -> override one step space on mobile and tablet', (t) => {
const result = toStyles(marginPropStyles({ theme, mg: 1, mglM: 3, mgxT: 0 }))
const result1 = toStyles(marginPropStyles({ theme, mg: 1, mglM: 3, mgxT: 0 }))
const result2 = toStyles(marginPropStyles({ theme, mg: 1, mgl: { M: 3 }, mgx: { T: 0 } }))

t.deepEqual(result, {
const expected = {
margin: '10px',
'@media (max-width: 600px)': { margin: '5px', marginLeft: '2rem' },
'@media (min-width: 601px) and (max-width: 1024px)': {
marginLeft: 0,
marginRight: 0
}
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('props -> set margin to sizes responsive "nudge" value', (t) => {
Expand All @@ -90,12 +98,16 @@ test('props -> set margin to "auto"', (t) => {
})

test('props -> set margin to "30px" on mobile', (t) => {
const result = toStyles(marginPropStyles({ theme, mg: '10px', mgM: '30px' }))
const result1 = toStyles(marginPropStyles({ theme, mg: '10px', mgM: '30px' }))
const result2 = toStyles(marginPropStyles({ theme, mg: { default: '10px', M: '30px' } }))

t.deepEqual(result, {
const expected = {
margin: '10px',
'@media (max-width: 600px)': { margin: '30px' }
})
}

t.deepEqual(result1, expected)
t.deepEqual(result2, expected)
})

test('style -> padding', (t) => {
Expand Down

0 comments on commit b3f918b

Please sign in to comment.