New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dynamic value support for extract static in the styled function. #279
Changes from 6 commits
4ead519
a956255
2f4aac0
770cfcb
cfdb9ab
ce74835
0e84412
5fb003a
4c8eee7
07be9ea
e330c97
3a701db
503ecb6
5b3f20e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,21 +144,40 @@ const getComponentId = (state, prefix: string = 'css') => { | |
export function buildStyledCallExpression(identifier, tag, path, state, t) { | ||
const identifierName = getIdentifierName(path, t) | ||
|
||
if (state.extractStatic && !path.node.quasi.expressions.length) { | ||
if (state.extractStatic) { | ||
const { name, hash, src } = inline( | ||
path.node.quasi, | ||
identifierName, | ||
'styled' // we don't want these styles to be merged in css`` | ||
) | ||
|
||
const cssText = `.${name}-${hash} { ${src} }` | ||
const { staticCSSRules } = parseCSS(cssText, true, getFilename(path)) | ||
const { staticCSSRules, composesCount } = parseCSS( | ||
cssText, | ||
true, | ||
getFilename(path) | ||
) | ||
|
||
// Help Needed: | ||
// We should read the browser preferences for postcss | ||
// and turn this on only if css vars are supported in their browser targets. | ||
const objs = path.node.quasi.expressions.slice(0, composesCount) | ||
|
||
if (objs.length) { | ||
throw new Error('Cannot use composes in extractStatic mode.') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tkh44 Do you think we should just go to inline mode instead of throwing an error. We also need to check if there are any interpolations in other places before going to extract. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that might be a good idea. |
||
} | ||
|
||
state.insertStaticRules(staticCSSRules) | ||
const vars = path.node.quasi.expressions.slice(composesCount) | ||
state.insertStaticRules( | ||
staticCSSRules.map(ruleText => | ||
ruleText.replace(/xxx(\d+)xxx/gm, `var(--${name}-${hash}-$1)`) | ||
) | ||
) | ||
return t.callExpression(identifier, [ | ||
tag, | ||
t.stringLiteral(getComponentId(state, name)), | ||
t.arrayExpression([t.stringLiteral(`${name}-${hash}`)]) | ||
t.arrayExpression([t.stringLiteral(`${name}-${hash}`)]), | ||
t.arrayExpression(vars) | ||
]) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import { | |
clean, | ||
createMarkupForStyles, | ||
hashString as hash, | ||
hashArray, | ||
hashObject | ||
} from 'emotion-utils' | ||
|
||
|
@@ -82,7 +83,38 @@ export function css(objs: any, vars: Array<any>, content: () => Array<any>) { | |
return computedClassName.trim() | ||
} | ||
|
||
function insertRawRule(css: string) { | ||
type inputVar = string | number | ||
|
||
export function customProperties(baseClassName: string, vars: Array<inputVar>) { | ||
const hash = hashArray([baseClassName, ...vars]) | ||
const varCls = `css-vars-${hash}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did this so that users could SSR and extract the custom property values, but I'm not sure if it will trip up in other places. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to write a test for it but I think we have to do something different to get SSR to work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wrong! it works right now! 🎉 |
||
if (inserted[hash]) { | ||
return varCls | ||
} | ||
|
||
let src = '' | ||
forEach(vars, (val: inputVar, i: number) => { | ||
src && (src += '; ') | ||
src += `--${baseClassName}-${i}: ${val}` | ||
}) | ||
|
||
let spec = { | ||
id: hash, | ||
css: `.${varCls} {${src}}`, | ||
type: 'raw' | ||
} | ||
|
||
register(spec) | ||
|
||
if (!inserted[spec.id]) { | ||
sheet.insert(spec.css) | ||
inserted[spec.id] = true | ||
} | ||
|
||
return varCls | ||
} | ||
|
||
export function insertRawRule(css: string) { | ||
let spec = { | ||
id: hash(css), | ||
css, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/ai/browserslist https://github.com/ben-eb/caniuse-lite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detection:
It will detect IE and IE mobile.