-
Notifications
You must be signed in to change notification settings - Fork 262
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 support for plugins #190
Changes from all commits
b69a2a9
56b647d
4611d68
afed145
83ae637
0a21257
2fdb857
e7327b9
df90cc5
dbe522a
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 |
---|---|---|
|
@@ -42,12 +42,18 @@ export default () => ( | |
) | ||
``` | ||
|
||
### Options | ||
|
||
* `sourceMaps` generates source maps (default: `false`) | ||
* `vendorPrefix` turn on/off automatic vendor prefixing (default: `true`) | ||
|
||
## Features | ||
|
||
- Full CSS support, no tradeoffs in power | ||
- Runtime size of just **2kb** (gzipped, from 6kb) | ||
- Complete isolation: Selectors, animations, keyframes | ||
- Built-in CSS vendor prefixing | ||
- CSS Preprocessing via Plugins | ||
- Very fast, minimal and efficient transpilation (see below) | ||
- High-performance runtime-CSS-injection when not server-rendering | ||
- Future-proof: Equivalent to server-renderable "Shadow CSS" | ||
|
@@ -113,6 +119,82 @@ module.exports = `div { color: green; }` | |
// module.exports = { styles: `div { color: green; }` } | ||
``` | ||
|
||
### CSS Preprocessing via Plugins | ||
|
||
Styles can be preprocessed via plugins. | ||
|
||
Plugins are regular JavaScript modules that export a simple function with the following signature: | ||
|
||
```js | ||
(css: string, settings: Object) => string | ||
``` | ||
|
||
Basically they accept a CSS string in input, optionally modify it and finally return it. | ||
|
||
Plugins make it possible to use popular preprocessors like SASS, Less, Stylus, PostCSS or apply custom transformations to the styles. | ||
|
||
To register a plugin add an option `plugins` for `styled-jsx/babel` to your `.babelrc`. `plugins` must be an array of module names or *full* paths for local plugins. | ||
|
||
```json | ||
{ | ||
"plugins": [ | ||
[ | ||
"styled-jsx/babel", | ||
{ "plugins": ["my-styled-jsx-plugin-package", "/full/path/to/local/plugin"] } | ||
] | ||
] | ||
} | ||
``` | ||
|
||
In order to resolve local plugins paths you can use NodeJS' [require.resolve](https://nodejs.org/api/globals.html#globals_require_resolve). | ||
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. It would be nice if we could find a way to magically resolve paths internally. |
||
|
||
Plugins are applied in definition order left to right before styles are scoped. | ||
|
||
N.B. when applying the plugins styled-jsx replaces template literals expressions with placeholders e.g. `%%styledjsxexpression_ExprNumber%%` because otherwise CSS parsers would get invalid CSS. | ||
|
||
#### Plugin options and settings | ||
|
||
Users can set plugin options by registering a plugin as an array that contains | ||
the plugin path and an options object. | ||
|
||
```json | ||
{ | ||
"plugins": [ | ||
[ | ||
"styled-jsx/babel", | ||
{ | ||
"plugins": [ | ||
["my-styled-jsx-plugin-package", { "exampleOption": true }] | ||
], | ||
"sourceMaps": true | ||
} | ||
] | ||
] | ||
} | ||
``` | ||
|
||
Each plugin receives a `settings` object as second argument which contains | ||
the babel and user options: | ||
|
||
```js | ||
(css, settings) => { /* ... */ } | ||
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. Does it support async operations ? 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. no it doesn't because of the sync nature of babel 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. fwiw in styled-jsx-postcss I use a super hack to make async code work (syncronously) https://github.com/giuseppeg/styled-jsx-postcss/blob/master/src/babel.js#L98-L107 |
||
``` | ||
|
||
The `settings` object has the following shape: | ||
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. this object could as well be renamed to {
// user options
exampleOption: true,
// babel options
babel: { // or env
sourceMaps: true,
vendorPrefix: true,
}
} |
||
|
||
```js | ||
{ | ||
// babel options | ||
sourceMaps: true, | ||
vendorPrefix: true, | ||
|
||
// user options | ||
options: { | ||
exampleOption: true | ||
} | ||
} | ||
``` | ||
|
||
### Targeting The Root | ||
|
||
Notice that the parent `<div>` above also gets a `data-jsx` attribute. We do this so that | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`applies plugins 1`] = ` | ||
"import _JSXStyle from 'styled-jsx/style'; | ||
import styles from './styles'; | ||
const color = 'red'; | ||
|
||
export default (() => <div data-jsx={4216192053} data-jsx-ext={styles.__scopedHash}> | ||
<p data-jsx={4216192053} data-jsx-ext={styles.__scopedHash}>test</p> | ||
<_JSXStyle styleId={4216192053} css={\`span.\${color}[data-jsx=\\"4216192053\\"]{color:\${otherColor}}\`} /> | ||
<_JSXStyle styleId={styles.__scopedHash} css={styles.__scoped} /> | ||
</div>);" | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default css => css.replace(/div/g, 'span') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default 'invalid' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default (css, settings) => settings.options.test |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default css => `TEST (${css}) EOTEST` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import styles from './styles' | ||
const color = 'red' | ||
|
||
export default () => ( | ||
<div> | ||
<p>test</p> | ||
<style jsx>{`div.${color} { color: ${otherColor} }`}</style> | ||
<style jsx>{styles}</style> | ||
</div> | ||
) |
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.
should this be a noun/plural?
vendorPrefixes