├── .editorconfig
├── .eslintrc
├── .gitignore
├── .jsbeautifyrc
├── README.md
├── gulpfile.js
├── package.json
└── src
├── __tests__
├── CreateClassComponent.jsx
├── ES6ClassComponent.jsx
├── ES6ClassDecorator.jsx
├── ES6ClassDecoratorWithPrefix.jsx
├── Keyframes.jsx
└── index.jsx
└── index.jsx
/.editorconfig:
--------------------------------------------------------------------------------
1 | root=true
2 | [*]
3 | end_of_line = lf
4 | insert_final_newline = true
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "ecmaFeatures": {
3 | "binaryLiterals": false,
4 | "blockBindings": true,
5 | "defaultParams": true,
6 | "forOf": true,
7 | "generators": true,
8 | "objectLiteralComputedProperties": true,
9 | "objectLiteralDuplicateProperties": false,
10 | "objectLiteralShorthandMethods": true,
11 | "objectLiteralShorthandProperties": true,
12 | "octalLiterals": false,
13 | "regexUFlag": false,
14 | "regexYFlag": false,
15 | "templateStrings": true,
16 | "unicodePointEscapes": true,
17 | "jsx": true
18 | },
19 | "env": {
20 | "browser": true,
21 | "node": true
22 | },
23 | "parser": "babel-eslint",
24 | "plugins": [
25 | "react"
26 | ],
27 | "rules": {
28 |
29 | /*Possible Errors */
30 | "comma-dangle": [1, "always-multiline"],
31 | "no-cond-assign": [1, "except-parens"],
32 | "no-console": 0,
33 | "no-constant-condition": 1,
34 | "no-control-regex": 1,
35 | "no-debugger": 1,
36 | "no-dupe-args": 1,
37 | "no-dupe-keys": 1,
38 | "no-duplicate-case": 0,
39 | "no-empty-character-class": 1,
40 | "no-empty": 1,
41 | "no-ex-assign": 1,
42 | "no-extra-boolean-cast": 1,
43 | "no-extra-parens": 0,
44 | "no-extra-semi": 1,
45 | "no-func-assign": 1,
46 | "no-inner-declarations": [1, "functions"],
47 | "no-invalid-regexp": 1,
48 | "no-irregular-whitespace": 1,
49 | "no-negated-in-lhs": 1,
50 | "no-obj-calls": 1,
51 | "no-regex-spaces": 1,
52 | "no-reserved-keys": 0,
53 | "no-sparse-arrays": 1,
54 | "no-unreachable": 1,
55 | "use-isnan": 1,
56 | "valid-jsdoc": 1,
57 | "valid-typeof": 1,
58 |
59 | /* Best Practices */
60 | "accessor-pairs": 0,
61 | "block-scoped-var": 1,
62 | "complexity": 0,
63 | "consistent-return": 1,
64 | "curly": [1, "all"],
65 | "default-case": 0,
66 | "dot-notation": [1, { "allowKeywords": true, "allowPattern": "" }],
67 | "dot-location": [1, "property"],
68 | "eqeqeq": 1,
69 | "guard-for-in": 0,
70 | "no-alert": 1,
71 | "no-caller": 1,
72 | "no-div-regex": 1,
73 | "no-else-return": 1,
74 | "no-empty-label": 1,
75 | "no-eq-null": 0,
76 | "no-eval": 1,
77 | "no-extend-native": 1,
78 | "no-extra-bind": 1,
79 | "no-fallthrough": 0,
80 | "no-floating-decimal": 1,
81 | "no-implied-eval": 1,
82 | "no-iterator": 1,
83 | "no-labels": 1,
84 | "no-lone-blocks": 1,
85 | "no-loop-func": 1,
86 | "no-multi-spaces": 1,
87 | "no-multi-str": 1,
88 | "no-native-reassign": 1,
89 | "no-new-func": 1,
90 | "no-new-wrappers": 1,
91 | "no-new": 1,
92 | "no-octal-escape": 1,
93 | "no-octal": 1,
94 | "no-param-reassign": 0,
95 | "no-process-env": 0,
96 | "no-proto": 1,
97 | "no-redeclare": 1,
98 | "no-return-assign": 1,
99 | "no-script-url": 1,
100 | "no-self-compare": 1,
101 | "no-sequences": 1,
102 | "no-throw-literal": 1,
103 | "no-unused-expressions": 0,
104 | "no-void": 0,
105 | "no-warning-comments": [1, { "terms": ["todo", "tofix"], "location": "start" }],
106 | "no-with": 1,
107 | "radix": 1,
108 | "vars-on-top": 1,
109 | "wrap-iife": [1, "inside"],
110 | "yoda": [1, "never"],
111 |
112 | /* Strict Mode */
113 | "strict": [1, "never"],
114 |
115 | /* Variables */
116 | "no-catch-shadow": 0,
117 | "no-delete-var": 1,
118 | "no-label-var": 1,
119 | "no-shadow-restricted-names": 1,
120 | "no-shadow": 1,
121 | "no-undef-init": 1,
122 | "no-undef": 1,
123 | "no-undefined": 1,
124 | "no-unused-vars": [1, { "vars": "local", "args": "after-used" }],
125 | "no-use-before-define": 1,
126 |
127 | /* Node.js */
128 | "handle-callback-err": 1,
129 | "no-mixed-requires": 1,
130 | "no-new-require": 1,
131 | "no-path-concat": 1,
132 | "no-process-exit": 1,
133 | "no-restricted-modules": [1, ""], // add any unwanted Node.js core modules
134 | "no-sync": 1,
135 |
136 | /* Stylistic Issues */
137 | "brace-style": [1, "stroustrup", { "allowSingleLine": true }],
138 | "camelcase": [1, { "properties": "always" }],
139 | "comma-spacing": [1, { "before": false, "after": true }],
140 | "comma-style": [1, "last"],
141 | "computed-property-spacing": 0,
142 | "consistent-this": 0,
143 | "eol-last": 1,
144 | "func-names": 1,
145 | "func-style": 0,
146 | "indent": [1, 2],
147 | "key-spacing": [1, { "beforeColon": false, "afterColon": true }],
148 | "linebreak-style": 0,
149 | "max-nested-callbacks": [0, 3],
150 | "new-cap": 1,
151 | "new-parens": 1,
152 | "newline-after-var": 0,
153 | "no-array-constructor": 1,
154 | "no-continue": 1,
155 | "no-inline-comments": 0,
156 | "no-lonely-if": 1,
157 | "no-mixed-spaces-and-tabs": 1,
158 | "no-multiple-empty-lines": [1, { "max": 1 }],
159 | "no-nested-ternary": 0,
160 | "no-new-object": 1,
161 | "no-spaced-func": 1,
162 | "no-ternary": 0,
163 | "no-trailing-spaces": 1,
164 | "no-underscore-dangle": 0,
165 | "no-unneeded-ternary": 1,
166 | "no-wrap-func": 1,
167 | "one-var": [1, "never"],
168 | "operator-assignment": [1, "never"],
169 | "padded-blocks": [0, "never"],
170 | "quote-props": [0, "as-needed"],
171 | "quotes": [1, "single"],
172 | "semi-spacing": [1, { "before": false, "after": true }],
173 | "semi": [1, "always"],
174 | "sort-vars": 0,
175 | "space-after-keywords": 0,
176 | "space-before-blocks": [1, "always"],
177 | "space-before-function-paren": [1, "never"],
178 | "space-in-brackets": 0,
179 | "space-in-parens": [1, "never"],
180 | "space-infix-ops": 1,
181 | "space-return-throw-case": 1,
182 | "space-unary-ops": 0,
183 | "spaced-comment": [1, "always"],
184 | "wrap-regex": 1,
185 |
186 | /* ECMAScript 6 */
187 | "generator-star-spacing": [1, "after"],
188 | "no-var": 1,
189 | "object-shorthand": [1, "always"],
190 | "prefer-const": 1,
191 |
192 | /* Legacy */
193 | "max-depth": [0, 3],
194 | "max-len": [1, 125, 4],
195 | "max-params": 0,
196 | "max-statements": 0,
197 | "no-bitwise": 1,
198 | "no-plusplus": 1,
199 |
200 | /* React */
201 | "react/display-name": 1,
202 | "react/jsx-boolean-value": 1,
203 | "react/jsx-quotes": [1, "single"],
204 | "react/jsx-no-undef": 1,
205 | "react/jsx-sort-props": 0,
206 | "react/jsx-sort-prop-types": 1,
207 | "react/jsx-uses-react": 1,
208 | "react/jsx-uses-vars": 1,
209 | "react/no-did-mount-set-state": 1,
210 | "react/no-did-update-set-state": 1,
211 | "react/no-multi-comp": 1,
212 | "react/no-unknown-property": 1,
213 | "react/prop-types": 1,
214 | "react/react-in-jsx-scope": 1,
215 | "react/self-closing-comp": 1,
216 | "react/sort-comp": 1,
217 | "react/wrap-multilines": 0
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | tmp
3 | *.pid
4 | *.lock
5 | npm-debug.log
6 |
--------------------------------------------------------------------------------
/.jsbeautifyrc:
--------------------------------------------------------------------------------
1 | {
2 | "html": {
3 | "allowed_file_extensions": ["htm", "html", "xhtml", "shtml", "xml", "svg"],
4 | "brace_style": "collapse",
5 | "end_with_newline": false,
6 | "indent_char": " ",
7 | "indent_handlebars": false,
8 | "indent_inner_html": false,
9 | "indent_size": 2,
10 | "indent_scripts": "keep",
11 | "max_preserve_newlines": 4,
12 | "preserve_newlines": true,
13 | "unformatted": ["a", "span", "img", "code", "pre", "sub", "sup", "em", "strong", "b", "i", "u", "strike", "big",
14 | "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6"
15 | ],
16 | "wrap_line_length": 124
17 | },
18 | "css": {
19 | "allowed_file_extensions": ["css", "scss", "sass", "less"],
20 | "end_with_newline": false,
21 | "newline_between_rules": true,
22 | "indent_char": " ",
23 | "indent_size": 2,
24 | "selector_separator_newline": true
25 | },
26 | "js": {
27 | "allowed_file_extensions": ["eslintrc", "js", "jsx", "json", "jshintrc", "jsbeautifyrc"],
28 | "brace_style": "collapse",
29 | "break_chained_methods": false,
30 | "comma_first": false,
31 | "e4x": false,
32 | "end_with_newline": false,
33 | "eval_code": false,
34 | "indent_char": " ",
35 | "indent_level": 0,
36 | "indent_size": 2,
37 | "jslint_happy": false,
38 | "keep_array_indentation": false,
39 | "keep_function_indentation": false,
40 | "max_preserve_newlines": 4,
41 | "preserve_newlines": true,
42 | "space_after_anon_function": false,
43 | "space_before_conditional": false,
44 | "space_in_empty_paren": false,
45 | "space_in_paren": false,
46 | "unescape_strings": false,
47 | "wrap_line_length": 124
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | React Statics Styles
2 | ====================
3 |
4 | Ultra-light utility to help writing CSS inside your JS React components declarations.
5 |
6 | Statically extracts CSS styles declared at the component class level and outputs a nicely formatted CSS string. It is then easing to pipe it to your CSS postprocessor of choice (eg. `postcss`).
7 |
8 | Best friends with [`gulp-react-statics-styles`](https://github.com/elierotenberg/gulp-react-statics-styles) to make it work with your building pipeline.
9 |
10 | Usage (without gulp)
11 | ====================
12 |
13 | Declare `styles` as a `static` property of your component class (or using `statics` if you use vanilla `React.createClass`):
14 | ```js
15 | class MyComponent extends React.Component {
16 | static styles = {
17 | '.MyComponent .MyComponent-item': {
18 | // you can put build-time calculations here
19 | fontSize: 0.8 * readFontSizeFromConfig() + 'px',
20 | }
21 | };
22 |
23 | render: function() {
24 | return
25 |
This is smaller that usual.
26 |
;
27 | },
28 | };
29 |
30 | // alternate syntax using the decorator
31 | import { styles } from 'react-statics-styles';
32 |
33 | @styles({
34 | '.MyComponent .MyComponent-item': {
35 | fontSize: 0.8 * readFontSizeFromConfig() + 'px',
36 | }
37 | })
38 | class MyComponent extends React.Component { ... }
39 | ```
40 |
41 | Then pass one or more class definition(s) to `extractStyles(class)` or `extractAllStyles(array of class)`:
42 | ```js
43 | import { extractStyles, extractAllStyles } from 'react-statics-styles';
44 | extractStyles(MyComponent); // returns a CSS string
45 | extractAllStyles([MyComponent1, MyComponent2, ...]);
46 | ```
47 |
48 | Assuming that `readFontSizeFromConfig()` returns `10`, then the first line returns the string:
49 |
50 | ```css
51 | /* @react-nexus-style MyComponent */
52 | .MyComponent .MyComponent-item {
53 | font-size: 8px;
54 | }
55 | ```
56 |
57 | The decorator form supports passing additional options.
58 |
59 | The only currently supported option is `prefix`, a static string which will be preprended to all the generated selectors.
60 |
61 | ```js
62 | @styles({
63 | '.ES6ClassDecoratorWithPrefix': {
64 | minWidth: '334px',
65 | },
66 | }, { prefix: '.MyApp '})
67 | class ES6ClassDecoratorWithPrefix extends React.Component {
68 | static displayName = 'ES6ClassDecoratorWithPrefix';
69 |
70 | render() {
71 | return ;
72 | }
73 | }
74 | ```
75 |
76 | will yield
77 |
78 | ```css
79 | /* @react-statics-styles ES6ClassDecoratorWithPrefix */
80 | .MyApp .ES6ClassDecoratorWithPrefix {
81 | min-width: 334px;
82 | }
83 | ```
84 |
85 | Usage (with gulp)
86 | =================
87 |
88 | See [`gulp-react-statics-styles`](https://github.com/elierotenberg/gulp-react-statics-styles).
89 |
90 |
91 | ### Installation
92 |
93 | This module is written in ES6/7. You will need `babel` to run it.
94 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | require('babel/register')({
2 | only: /\.jsx$/,
3 | optional: [
4 | 'runtime',
5 | 'es7.classProperties',
6 | 'es7.decorators',
7 | ],
8 | });
9 |
10 | var eslint = require('gulp-eslint');
11 | var gulp = require('gulp');
12 | var plumber = require('gulp-plumber');
13 | var mocha = require('gulp-mocha');
14 |
15 | function lint() {
16 | return gulp.src('src/**/*.js')
17 | .pipe(plumber())
18 | .pipe(eslint())
19 | .pipe(eslint.format());
20 | }
21 |
22 | function test() {
23 | return gulp.src('src/__tests__/**/*.jsx')
24 | .pipe(mocha());
25 | }
26 |
27 | gulp.task('lint', lint);
28 | gulp.task('test', ['lint'], test);
29 | gulp.task('default', ['test']);
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-statics-styles",
3 | "version": "3.1.0",
4 | "description": "",
5 | "license": "MIT",
6 | "author": "Elie Rotenberg ",
7 | "main": "src/index.jsx",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/elierotenberg/react-statics-styles.git"
11 | },
12 | "bugs": {
13 | "url": "https://github.com/elierotenberg/react-statics-styles/issues"
14 | },
15 | "homepage": "https://github.com/elierotenberg/react-statics-styles",
16 | "scripts": {
17 | "test": "gulp test"
18 | },
19 | "devDependencies": {
20 | "babel": "^5.5.8",
21 | "babel-eslint": "^3.1.15",
22 | "babel-runtime": "^5.5.8",
23 | "eslint": "^0.23.0",
24 | "eslint-plugin-react": "^2.5.2",
25 | "gulp": "^3.9.0",
26 | "gulp-eslint": "^0.14.0",
27 | "gulp-mocha": "^2.1.1",
28 | "gulp-plumber": "^1.0.1",
29 | "react": "^0.13.3"
30 | },
31 | "dependencies": {
32 | "bluebird": "^2.9.30",
33 | "change-case": "^2.3.0",
34 | "lodash": "^3.9.3",
35 | "should": "^6.0.3"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/__tests__/CreateClassComponent.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const CreateClassComponent = React.createClass({
4 | displayName: 'CreateClassComponent',
5 | statics: {
6 | styles: {
7 | '.CreateClassComponent': {
8 | minWidth: '1337px',
9 | },
10 | },
11 | },
12 |
13 | render() {
14 | return ;
15 | },
16 | });
17 |
18 | export default CreateClassComponent;
19 |
--------------------------------------------------------------------------------
/src/__tests__/ES6ClassComponent.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class ES6ClassComponent extends React.Component {
4 | static displayName = 'ES6ClassComponent';
5 |
6 | static styles = {
7 | '.ES6ClassComponent': {
8 | minWidth: '42px',
9 | },
10 | };
11 |
12 | render() {
13 | return ;
14 | }
15 | }
16 |
17 | export default ES6ClassComponent;
18 |
--------------------------------------------------------------------------------
/src/__tests__/ES6ClassDecorator.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { styles } from '../';
3 |
4 | @styles({
5 | '.ES6ClassDecorator': {
6 | minWidth: '33px',
7 | },
8 | })
9 | class ES6ClassDecorator extends React.Component {
10 | static displayName = 'ES6ClassDecorator';
11 |
12 | render() {
13 | return ;
14 | }
15 | }
16 |
17 | export default ES6ClassDecorator;
18 |
--------------------------------------------------------------------------------
/src/__tests__/ES6ClassDecoratorWithPrefix.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { styles } from '../';
3 |
4 | @styles({
5 | '.ES6ClassDecoratorWithPrefix': {
6 | minWidth: '334px',
7 | },
8 | }, { prefix: '.MyApp '})
9 | class ES6ClassDecoratorWithPrefix extends React.Component {
10 | static displayName = 'ES6ClassDecoratorWithPrefix';
11 |
12 | render() {
13 | return ;
14 | }
15 | }
16 |
17 | export default ES6ClassDecoratorWithPrefix;
18 |
--------------------------------------------------------------------------------
/src/__tests__/Keyframes.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const CreateClassComponent = React.createClass({
4 | displayName: 'Keyframes',
5 | statics: {
6 | stylesOpts: '-webkit-',
7 | styles: {
8 | '@keyframes animationFromTo': {
9 | from: {
10 | transform: 'rotate(0deg)',
11 | top: '0px',
12 | },
13 | to: {
14 | transform: 'rotate(360deg)',
15 | top: '100px',
16 | },
17 | },
18 | '@keyframes animationPercent': {
19 | '0%': { opacity: 0 },
20 | '100%': { opacity: 1 },
21 | },
22 | },
23 | },
24 |
25 | render() {
26 | return ;
27 | },
28 | });
29 |
30 | export default CreateClassComponent;
31 |
--------------------------------------------------------------------------------
/src/__tests__/index.jsx:
--------------------------------------------------------------------------------
1 | const { describe, it } = global;
2 | import 'should';
3 | import { extractStyles } from '../';
4 |
5 | import CreateClassComponent from './CreateClassComponent';
6 | import ES6ClassComponent from './ES6ClassComponent';
7 | import ES6ClassDecorator from './ES6ClassDecorator';
8 | import ES6ClassDecoratorWithPrefix from './ES6ClassDecoratorWithPrefix';
9 | import Keyframes from './Keyframes';
10 |
11 | describe('CreateClassComponent', () =>
12 | it('should extract the correct CSS', () =>
13 | extractStyles(CreateClassComponent).should.be.exactly([
14 | '/* @react-statics-styles CreateClassComponent */',
15 | '.CreateClassComponent {',
16 | ' min-width: 1337px;',
17 | '}',
18 | '',
19 | ].join('\n'))
20 | )
21 | );
22 |
23 | describe('ES6ClassComponent', () =>
24 | it('should extract the correct CSS', () =>
25 | extractStyles(ES6ClassComponent).should.be.exactly([
26 | '/* @react-statics-styles ES6ClassComponent */',
27 | '.ES6ClassComponent {',
28 | ' min-width: 42px;',
29 | '}',
30 | '',
31 | ].join('\n'))
32 | )
33 | );
34 |
35 | describe('ES6ClassDecorator', () =>
36 | it('should extract the correct CSS', () =>
37 | extractStyles(ES6ClassDecorator).should.be.exactly([
38 | '/* @react-statics-styles ES6ClassDecorator */',
39 | '.ES6ClassDecorator {',
40 | ' min-width: 33px;',
41 | '}',
42 | '',
43 | ].join('\n'))
44 | )
45 | );
46 |
47 | describe('ES6ClassDecoratorWithPrefix', () =>
48 | it('should extract the correct CSS', () =>
49 | extractStyles(ES6ClassDecoratorWithPrefix).should.be.exactly([
50 | '/* @react-statics-styles ES6ClassDecoratorWithPrefix */',
51 | '.MyApp .ES6ClassDecoratorWithPrefix {',
52 | ' min-width: 334px;',
53 | '}',
54 | '',
55 | ].join('\n'))
56 | )
57 | );
58 |
59 | describe('Keyframes', () =>
60 | it('should extract the correct CSS', () =>
61 | extractStyles(Keyframes).should.be.exactly([
62 | '/* @react-statics-styles Keyframes */',
63 | '@keyframes animationFromTo {',
64 | ' from {',
65 | ' transform: rotate(0deg);',
66 | ' top: 0px;',
67 | ' }',
68 | ' to {',
69 | ' transform: rotate(360deg);',
70 | ' top: 100px;',
71 | ' }',
72 | '}',
73 | '@keyframes animationPercent {',
74 | ' 0% {',
75 | ' opacity: 0;',
76 | ' }',
77 | ' 100% {',
78 | ' opacity: 1;',
79 | ' }',
80 | '}',
81 | '',
82 | ].join('\n'))
83 | )
84 | );
85 |
--------------------------------------------------------------------------------
/src/index.jsx:
--------------------------------------------------------------------------------
1 | import recase from 'change-case';
2 | import _ from 'lodash';
3 |
4 | const stylesOpts = Symbol('stylesOpts');
5 |
6 | function extractKeyframes(keyframe, prefix) {
7 | const rulesKeyframe = Object.keys(keyframe).map((attr) => {
8 | return ` ${prefix}${attr}: ${keyframe[attr]};`;
9 | }).join('\n');
10 |
11 | return `{\n${rulesKeyframe}\n }`;
12 | }
13 |
14 | function extractStyle(selector, reactStyle, { prefix = '' } = {}) {
15 | const rules = Object.keys(reactStyle).map((attr) => {
16 | return selector.indexOf('@keyframes') > -1
17 | ? ` ${prefix}${attr} ${extractKeyframes(reactStyle[attr], prefix)}`
18 | : ` ${recase.paramCase(attr)}: ${reactStyle[attr]};`;
19 | }).join('\n');
20 | return `${prefix}${selector} {\n${rules}\n}`;
21 | }
22 |
23 | function extractStyles(Component) {
24 | if(!_.isObject(Component) ||
25 | !Component.styles ||
26 | !_.isObject(Component.styles)) {
27 | return null;
28 | }
29 | return `/* @react-statics-styles ${Component.displayName} */\n${Object.keys(Component.styles)
30 | .map((selector) => extractStyle(selector, Component.styles[selector], Component[stylesOpts]))
31 | .join('\n')}\n`;
32 | }
33 |
34 | function extractAllStyles(Components) {
35 | return _.without(_.map(Components, extractStyles), null).join('\n');
36 | }
37 |
38 | function styles(newStyles, opts) {
39 | return (Component) => Object.assign(class extends Component {
40 | static styles = Object.assign({}, Component.styles || {}, newStyles);
41 | }, { [stylesOpts]: opts });
42 | }
43 |
44 | export default { extractStyle, extractStyles, extractAllStyles, styles, stylesOpts };
45 |
--------------------------------------------------------------------------------