-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from roginfarrer/improve-parsing-for-functions
- Loading branch information
Showing
10 changed files
with
232 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,25 @@ | ||
import { | ||
createSystem, | ||
space, | ||
color, | ||
typography, | ||
border, | ||
layout, | ||
createSystem, | ||
space, | ||
color, | ||
typography, | ||
border, | ||
layout, | ||
} from '../../dist'; | ||
import styled from '@emotion/styled'; | ||
|
||
const system = createSystem(); | ||
|
||
const Box = styled('div')( | ||
system({ | ||
...space, | ||
...color, | ||
...border, | ||
...typography, | ||
...layout, | ||
textAlign: true, | ||
textDecoration: true, | ||
}) | ||
system({ | ||
...space, | ||
...color, | ||
...border, | ||
...typography, | ||
...layout, | ||
textAlign: true, | ||
textDecoration: true, | ||
}) | ||
); | ||
|
||
export default Box; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { tokenizeValue } from '../tokenizeValue'; | ||
|
||
describe('Parse css values into token groups', () => { | ||
test('Will bail out early if giving a falsy value', () => { | ||
expect(tokenizeValue(undefined as any)).toEqual([[]]); | ||
}); | ||
test('Parse space separated values', () => { | ||
expect(tokenizeValue('solid red')).toEqual([['solid', 'red']]); | ||
}); | ||
test('Parse space separated values that contain units', () => { | ||
expect(tokenizeValue('1px 1px')).toEqual([['1px', '1px']]); | ||
}); | ||
test('Ignore useless whitespace', () => { | ||
expect(tokenizeValue(' 1px 1px ')).toEqual([['1px', '1px']]); | ||
}); | ||
|
||
test('Handles quoted strings', () => { | ||
expect(tokenizeValue('1.2em "Fira Sans"')).toEqual([['1.2em', '"Fira Sans"']]); | ||
}); | ||
|
||
test('Handles css functions', () => { | ||
expect(tokenizeValue('3s cubic-bezier(0.1, -0.6, 0.2, 0) 1s')).toEqual([ | ||
['3s', 'cubic-bezier(0.1, -0.6, 0.2, 0)', '1s'], | ||
]); | ||
}); | ||
|
||
test('Handles nested css functions', () => { | ||
expect(tokenizeValue('linear-gradient(red, hsla(120,100%,50%,0.3))')).toEqual([ | ||
['linear-gradient(red, hsla(120,100%,50%,0.3))'], | ||
]); | ||
}); | ||
|
||
test('Handles multiple groups', () => { | ||
expect(tokenizeValue('ease-in 1s slidein, ease-in 2s')).toEqual([ | ||
['ease-in', '1s', 'slidein'], | ||
['ease-in', '2s'], | ||
]); | ||
}); | ||
|
||
test('Handles multiple groups with css functions', () => { | ||
expect(tokenizeValue('linear-gradient(red, blue), red')).toEqual([['linear-gradient(red, blue)'], ['red']]); | ||
}); | ||
|
||
test('handles slashes', () => { | ||
expect(tokenizeValue('small-caps bold 24px/1 sans-serif')).toEqual([ | ||
['small-caps', 'bold', '24px/1', 'sans-serif'], | ||
]); | ||
expect(tokenizeValue('2em / 5em')).toEqual([['2em', '/', '5em']]); | ||
}); | ||
|
||
test('Handles nested css functions in multiple groups', () => { | ||
expect(tokenizeValue('linear-gradient(red, hsla(120,100%,50%,0.3)), red')).toEqual([ | ||
['linear-gradient(red, hsla(120,100%,50%,0.3))'], | ||
['red'], | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Full credit goes to modulz/stitches | ||
// Handles complex CSS values and functions like rgba, linear-gradient, | ||
// and other things with parenthesis | ||
// https://github.com/modulz/stitches/blob/1ea8656e849d48b08a9222b89cb919936b0f5f93/packages/core/src/shorthand-parser/value-tokenizer.ts | ||
|
||
const TOKEN_STRING = 1; | ||
const TOKEN_QUOTED_STRING = 2; | ||
const TOKEN_FUNCTION = 3; | ||
const TOKEN_BRACKET = 4; | ||
|
||
type TokenType = typeof TOKEN_STRING | typeof TOKEN_QUOTED_STRING | typeof TOKEN_FUNCTION | typeof TOKEN_BRACKET | 0; | ||
|
||
let currentType: TokenType; | ||
let currentToken = ''; | ||
let currentDepth = 0; | ||
let tokenGroups: string[][] = [[]]; | ||
|
||
export const tokenizeValue = (str: string) => { | ||
resetCurrentToken(); | ||
tokenGroups = [[]]; | ||
if (!str) { | ||
return tokenGroups; | ||
} | ||
const strLength = str.length; | ||
for (let i = 0; i < strLength; i++) { | ||
const char = str[i]; | ||
switch (char) { | ||
// whitespace | ||
case ' ': | ||
if (currentType === TOKEN_STRING) { | ||
addCurrentTokenToGroup(); | ||
} else if (currentType) { | ||
currentToken += char; | ||
} | ||
break; | ||
// new token group | ||
case ',': | ||
if (!currentDepth) { | ||
addCurrentTokenToGroup(); | ||
addNewTokenGroup(); | ||
} else { | ||
currentToken += char; | ||
} | ||
break; | ||
|
||
// Quoted string: | ||
case '"': | ||
currentToken += char; | ||
if (!currentDepth && !currentType) { | ||
currentType = TOKEN_QUOTED_STRING; | ||
currentDepth = 1; | ||
} else if (currentDepth === 1 && currentType === TOKEN_QUOTED_STRING) { | ||
currentDepth = 0; | ||
addCurrentTokenToGroup(); | ||
} | ||
break; | ||
|
||
// Css function: | ||
case '(': | ||
if (!currentDepth) currentType = TOKEN_FUNCTION; | ||
currentDepth++; | ||
currentToken += char; | ||
break; | ||
|
||
case ')': | ||
currentToken += char; | ||
currentDepth--; | ||
if (currentType === TOKEN_FUNCTION && !currentDepth) addCurrentTokenToGroup(); | ||
break; | ||
|
||
// Bracket values: | ||
case '[': | ||
if (!currentDepth) currentType = TOKEN_BRACKET; | ||
currentToken += char; | ||
currentDepth++; | ||
break; | ||
case ']': | ||
currentToken += char; | ||
currentDepth--; | ||
if (!currentDepth) addCurrentTokenToGroup(); | ||
break; | ||
|
||
default: | ||
if (!currentType) currentType = TOKEN_STRING; | ||
currentToken += char; | ||
} | ||
} | ||
if (currentToken) addCurrentTokenToGroup(); | ||
return tokenGroups; | ||
}; | ||
/** | ||
* UTILS: | ||
*/ | ||
|
||
/** | ||
* Resets the current token info | ||
*/ | ||
function resetCurrentToken() { | ||
currentDepth = currentType = 0; | ||
currentToken = ''; | ||
} | ||
/** | ||
* Adds current token to the stack then starts a new one | ||
*/ | ||
function addCurrentTokenToGroup() { | ||
if (currentType) tokenGroups[tokenGroups.length - 1].push(currentToken); | ||
resetCurrentToken(); | ||
} | ||
/** | ||
* Adds a new token group and requests a new one | ||
* For things like animations or box shadow where there might be multiple rules | ||
* applied to the same value | ||
*/ | ||
function addNewTokenGroup() { | ||
tokenGroups[tokenGroups.length] = []; | ||
resetCurrentToken(); | ||
} |
Oops, something went wrong.