Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "css-to-react-native",
"version": "2.3.0",
"version": "2.3.1",
"description": "Convert CSS text to a React Native stylesheet object",
"main": "index.js",
"scripts": {
Expand Down
8 changes: 8 additions & 0 deletions src/__tests__/border.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import transformCss from '..'

it('transforms border none', () => {
expect(transformCss([['border', 'none']])).toEqual({
borderWidth: 0,
borderColor: 'black',
borderStyle: 'solid',
})
})

it('transforms border shorthand', () => {
expect(transformCss([['border', '2px dashed #f00']])).toEqual({
borderWidth: 2,
Expand Down
8 changes: 3 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,11 @@ const transformShorthandValue =

export const getStylesForProperty = (propName, inputValue, allowShorthand) => {
const isRawValue = allowShorthand === false || !(propName in transforms)
const propValue = isRawValue
? transformRawValue(inputValue)
const propValues = isRawValue
? { [propName]: transformRawValue(inputValue) }
: transformShorthandValue(propName, inputValue.trim())

return propValue && propValue.$merge
? propValue.$merge
: { [propName]: propValue }
return propValues
}

export const getPropertyName = propName => {
Expand Down
48 changes: 48 additions & 0 deletions src/transforms/border.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { regExpToken, tokens } from '../tokenTypes'

const { NONE, COLOR, LENGTH, UNSUPPORTED_LENGTH_UNIT, SPACE } = tokens

const BORDER_STYLE = regExpToken(/^(solid|dashed|dotted)$/)

const defaultBorderWidth = 1
const defaultBorderColor = 'black'
const defaultBorderStyle = 'solid'

export default tokenStream => {
let borderWidth
let borderColor
let borderStyle

if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty()
return { borderWidth: 0, borderColor: 'black', borderStyle: 'solid' }
}

let partsParsed = 0
while (partsParsed < 3 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE)

if (
(borderWidth === undefined && tokenStream.matches(LENGTH)) ||
tokenStream.matches(UNSUPPORTED_LENGTH_UNIT)
) {
borderWidth = tokenStream.lastValue
} else if (borderColor === undefined && tokenStream.matches(COLOR)) {
borderColor = tokenStream.lastValue
} else if (borderStyle === undefined && tokenStream.matches(BORDER_STYLE)) {
borderStyle = tokenStream.lastValue
} else {
tokenStream.throw()
}

partsParsed += 1
}

tokenStream.expectEmpty()

if (borderWidth === undefined) borderWidth = defaultBorderWidth
if (borderColor === undefined) borderColor = defaultBorderColor
if (borderStyle === undefined) borderStyle = defaultBorderStyle

return { borderWidth, borderColor, borderStyle }
}
10 changes: 4 additions & 6 deletions src/transforms/boxShadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import { parseShadow } from './util'
export default tokenStream => {
const { offset, radius, color } = parseShadow(tokenStream)
return {
$merge: {
shadowOffset: offset,
shadowRadius: radius,
shadowColor: color,
shadowOpacity: 1,
},
shadowOffset: offset,
shadowRadius: radius,
shadowColor: color,
shadowOpacity: 1,
}
}
6 changes: 3 additions & 3 deletions src/transforms/flex.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ export default tokenStream => {

if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty()
return { $merge: { flexGrow: 0, flexShrink: 0, flexBasis: 'auto' } }
return { flexGrow: 0, flexShrink: 0, flexBasis: 'auto' }
}

tokenStream.saveRewindPoint()
if (tokenStream.matches(AUTO) && !tokenStream.hasTokens()) {
return { $merge: { flexGrow: 1, flexShrink: 1, flexBasis: 'auto' } }
return { flexGrow: 1, flexShrink: 1, flexBasis: 'auto' }
}
tokenStream.rewind()

Expand Down Expand Up @@ -52,5 +52,5 @@ export default tokenStream => {
if (flexShrink === undefined) flexShrink = defaultFlexShrink
if (flexBasis === undefined) flexBasis = defaultFlexBasis

return { $merge: { flexGrow, flexShrink, flexBasis } }
return { flexGrow, flexShrink, flexBasis }
}
39 changes: 39 additions & 0 deletions src/transforms/flexFlow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { regExpToken, tokens } from '../tokenTypes'

const { SPACE } = tokens

const FLEX_WRAP = regExpToken(/(nowrap|wrap|wrap-reverse)/)
const FLEX_DIRECTION = regExpToken(/(row|row-reverse|column|column-reverse)/)

const defaultFlexWrap = 'nowrap'
const defaultFlexDirection = 'row'

export default tokenStream => {
let flexWrap
let flexDirection

let partsParsed = 0
while (partsParsed < 2 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE)

if (flexWrap === undefined && tokenStream.matches(FLEX_WRAP)) {
flexWrap = tokenStream.lastValue
} else if (
flexDirection === undefined &&
tokenStream.matches(FLEX_DIRECTION)
) {
flexDirection = tokenStream.lastValue
} else {
tokenStream.throw()
}

partsParsed += 1
}

tokenStream.expectEmpty()

if (flexWrap === undefined) flexWrap = defaultFlexWrap
if (flexDirection === undefined) flexDirection = defaultFlexDirection

return { flexWrap, flexDirection }
}
4 changes: 2 additions & 2 deletions src/transforms/font.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default tokenStream => {

tokenStream.expect(SPACE)

const fontFamily = parseFontFamily(tokenStream)
const { fontFamily } = parseFontFamily(tokenStream)

if (fontStyle === undefined) fontStyle = defaultFontStyle
if (fontWeight === undefined) fontWeight = defaultFontWeight
Expand All @@ -58,5 +58,5 @@ export default tokenStream => {
const out = { fontStyle, fontWeight, fontVariant, fontSize, fontFamily }
if (lineHeight !== undefined) out.lineHeight = lineHeight

return { $merge: out }
return out
}
2 changes: 1 addition & 1 deletion src/transforms/fontFamily.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export default tokenStream => {

tokenStream.expectEmpty()

return fontFamily
return { fontFamily }
}
46 changes: 16 additions & 30 deletions src/transforms/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { regExpToken, tokens } from '../tokenTypes'
import { tokens } from '../tokenTypes'
import border from './border'
import boxShadow from './boxShadow'
import flex from './flex'
import flexFlow from './flexFlow'
import font from './font'
import fontFamily from './fontFamily'
import textShadow from './textShadow'
import textDecoration from './textDecoration'
import textDecorationLine from './textDecorationLine'
import transform from './transform'
import { directionFactory, anyOrderFactory, shadowOffsetFactory } from './util'
import { directionFactory, parseShadowOffset } from './util'

const {
IDENT,
Expand All @@ -20,21 +22,7 @@ const {
} = tokens

const background = tokenStream => ({
$merge: { backgroundColor: tokenStream.expect(COLOR) },
})
const border = anyOrderFactory({
borderWidth: {
tokens: [LENGTH, UNSUPPORTED_LENGTH_UNIT],
default: 1,
},
borderColor: {
tokens: [COLOR],
default: 'black',
},
borderStyle: {
tokens: [regExpToken(/^(solid|dashed|dotted)$/)],
default: 'solid',
},
backgroundColor: tokenStream.expect(COLOR),
})
const borderColor = directionFactory({
types: [WORD],
Expand All @@ -52,20 +40,18 @@ const margin = directionFactory({
prefix: 'margin',
})
const padding = directionFactory({ prefix: 'padding' })
const flexFlow = anyOrderFactory({
flexWrap: {
tokens: [regExpToken(/(nowrap|wrap|wrap-reverse)/)],
default: 'nowrap',
},
flexDirection: {
tokens: [regExpToken(/(row|row-reverse|column|column-reverse)/)],
default: 'row',
},
const fontVariant = tokenStream => ({
fontVariant: [tokenStream.expect(IDENT)],
})
const fontWeight = tokenStream => ({
fontWeight: tokenStream.expect(WORD), // Also match numbers as strings
})
const shadowOffset = tokenStream => ({
shadowOffset: parseShadowOffset(tokenStream),
})
const textShadowOffset = tokenStream => ({
textShadowOffset: parseShadowOffset(tokenStream),
})
const fontVariant = tokenStream => [tokenStream.expect(IDENT)]
const fontWeight = tokenStream => tokenStream.expect(WORD) // Also match numbers as strings
const shadowOffset = shadowOffsetFactory()
const textShadowOffset = shadowOffsetFactory()

export default {
background,
Expand Down
3 changes: 1 addition & 2 deletions src/transforms/textDecoration.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@ export default tokenStream => {
didParseFirst = true
}

const $merge = {
return {
textDecorationLine: line !== undefined ? line : defaultTextDecorationLine,
textDecorationColor:
color !== undefined ? color : defaultTextDecorationColor,
textDecorationStyle:
style !== undefined ? style : defaultTextDecorationStyle,
}
return { $merge }
}
2 changes: 1 addition & 1 deletion src/transforms/textDecorationLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ export default tokenStream => {

lines.sort().reverse()

return lines.join(' ')
return { textDecorationLine: lines.join(' ') }
}
8 changes: 3 additions & 5 deletions src/transforms/textShadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { parseShadow } from './util'
export default tokenStream => {
const { offset, radius, color } = parseShadow(tokenStream)
return {
$merge: {
textShadowOffset: offset,
textShadowRadius: radius,
textShadowColor: color,
},
textShadowOffset: offset,
textShadowRadius: radius,
textShadowColor: color,
}
}
2 changes: 1 addition & 1 deletion src/transforms/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ export default tokenStream => {
didParseFirst = true
}

return transforms
return { transform: transforms }
}
44 changes: 2 additions & 42 deletions src/transforms/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,55 +24,15 @@ export const directionFactory = ({

const keyFor = n => `${prefix}${directions[n]}${suffix}`

const output = {
return {
[keyFor(0)]: top,
[keyFor(1)]: right,
[keyFor(2)]: bottom,
[keyFor(3)]: left,
}

return { $merge: output }
}

export const anyOrderFactory = (properties, delim = SPACE) => tokenStream => {
const propertyNames = Object.keys(properties)
const values = propertyNames.reduce((accum, propertyName) => {
accum[propertyName] === undefined // eslint-disable-line
return accum
}, {})

let numParsed = 0
while (numParsed < propertyNames.length && tokenStream.hasTokens()) {
if (numParsed) tokenStream.expect(delim)

const matchedPropertyName = propertyNames.find(
propertyName =>
values[propertyName] === undefined &&
properties[propertyName].tokens.some(token =>
tokenStream.matches(token)
)
)

if (!matchedPropertyName) {
tokenStream.throw()
} else {
values[matchedPropertyName] = tokenStream.lastValue
}

numParsed += 1
}

tokenStream.expectEmpty()

propertyNames.forEach(propertyName => {
if (values[propertyName] === undefined)
values[propertyName] = properties[propertyName].default
})

return { $merge: values }
}

export const shadowOffsetFactory = () => tokenStream => {
export const parseShadowOffset = tokenStream => {
const width = tokenStream.expect(LENGTH)
const height = tokenStream.matches(SPACE) ? tokenStream.expect(LENGTH) : width
tokenStream.expectEmpty()
Expand Down