├── .babelrc
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── examples
├── app.js
├── bundle.js
├── external.css
├── index.html
└── index.js
├── index.js
├── macro
├── __tests__
│ ├── __fixtures__
│ │ ├── empty
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by array multi of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by array of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by object multi-key of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by object of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by regex global
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by regex
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports by string selector
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports from node_modules stylesheet by string selector
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports multiple by string selector
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports react by array multi of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports react by array of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports react by object multi-key of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports react by object of selectors
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ ├── imports react by string selector
│ │ │ ├── code.js
│ │ │ └── output.js
│ │ └── imports react multiple by string selector
│ │ │ ├── code.js
│ │ │ └── output.js
│ ├── index.test.js
│ └── sample.css
└── index.js
├── package-lock.json
├── package.json
├── package.npm.json
├── scripts
├── dev.sh
└── prepublish.sh
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["macros"],
3 | "presets": ["react"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .tern-port
2 | node_modules
3 | tags
4 | tags.lock
5 | tags.temp
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .babelrc
2 | .tern-port
3 | node_modules
4 | package.dev.json
5 | scripts
6 | tags
7 | tags.lock
8 | tags.temp
9 | webpack.config.js
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | ## [Unreleased]
8 |
9 | ### Added
10 |
11 | ### Changed
12 |
13 | ### Fixed
14 |
15 |
16 | ## [0.3.0] - 2018-12-21
17 |
18 | ### Added
19 |
20 | - Return declarations from selectors that match regex -- see tests for
21 | [regex](https://github.com/glortho/styled-import/tree/development/macro/__tests__/__fixtures__/imports%20by%20regex) and [global
22 | regex](https://github.com/glortho/styled-import/tree/development/macro/__tests__/__fixtures__/imports%20by%20regex%20global) matching
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 junk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Styled Import
3 | > Extreme lightweight CSS parser for stealing rules from stylesheets (without adding the stylesheet to your bundle), to compose into [Styled Components](https://www.styled-components.com/) or anywhere else you might be doing CSS in JS.
4 |
5 | [](https://badge.fury.io/js/styled-import)
6 | [](https://github.com/kentcdodds/babel-plugin-macros)
7 | [](https://github.com/glortho/styled-import/issues)
8 |
9 | ## Motivation
10 |
11 | Working with global or 3rd party CSS creates constant challenges when implementing other CSS solutions. styled-import is meant to ease some of the pain by letting you steal styles from those stylesheets without needing to link or bundle or otherwise include the stylesheets themselves.
12 |
13 | Note that this library currently operates as a Babel macro, replacing all
14 | references to styled-import calls at compile-time with the actual style declarations from the
15 | referenced stylesheets.
16 |
17 | ## Installation
18 |
19 | ```
20 | $ npm install -D styled-import
21 | ```
22 |
23 | ## Dependencies
24 |
25 | Styled Import currently runs only as a Babel macro, so be sure you have
26 | configured Babel to use [babel-plugin-macros](https://www.npmjs.com/package/babel-plugin-macros).
27 |
28 | Here is one example of how to do that:
29 |
30 | _.babelrc_
31 |
32 | ```javascript
33 | {
34 | "plugins": ["macros"]
35 | }
36 | ```
37 |
38 | NOTE: Macros are included in create-react-app 2 by default.
39 |
40 | ## Use
41 |
42 | _./stylesheets/global.css_
43 |
44 | ```css
45 | .button {
46 | color: blue;
47 | }
48 | ```
49 |
50 | _./component.js_
51 |
52 | ```javascript
53 | const styledImport = require('styled-import/macro')
54 |
55 | const btnStyle = styledImport('./stylesheets/global.css', '.button')
56 |
57 | console.log(btnStyle) // 'color: blue;'
58 | ```
59 |
60 | ### Use with Styled Components
61 |
62 | ```javascript
63 | const styled = require('styled-components')
64 | const styledImport = require('styled-import/macro')
65 |
66 | const btnStyle = styledImport('./stylesheets/global.css', '.button')
67 |
68 | const Button = styled.button`
69 | padding: 10px;
70 | ${btnStyle}
71 | `
72 | ```
73 |
74 | String composition works like inheritance/cascade:
75 |
76 | ```javascript
77 | const btnBlue = styledImport('./stylesheets/global.css', '.button-blue')
78 |
79 | const Button = styled.button`
80 | color: green;
81 | padding: 10px;
82 | ${btnBlue}
83 | `
84 |
85 | // color: green is overridden by color: blue in btnBlue
86 | ```
87 |
88 | ### Use with React or other CSS-in-JS
89 |
90 | ```javascript
91 | const btnStyle = styledImport.react('./stylesheets/global.css', '.button')
92 |
93 | // btnStyle is now an object {'color': 'blue'} with camelCased properties, instead of a CSS string
94 | ```
95 |
96 | ### Import from node_modules stylesheet
97 |
98 | ```javascript
99 | const btnStyle = styledImport('@org/stylesheets/global.css', '.button')
100 | ```
101 |
102 | ### Import multiple styles
103 |
104 |
105 | ```javascript
106 | const [btnStyle, headerStyle] = styledImport('@org/styles/global.css', ['.button', '.header'])
107 |
108 | const {button, header} = styledImport('@org/styles/global.css', {button: '.button', header: '.header'})
109 | ```
110 |
111 | ### Import nested styles
112 |
113 | ```javascript
114 | const cardBtnStyle = styledImport('./stylesheets/global.css', '.card .button')
115 | ```
116 |
117 | ### Search selectors with regular expressions
118 |
119 | ```javascript
120 | const cardBtnStyle = styledImport('./stylesheets/global.css', /\.button/gi)
121 |
122 | // returns an array of declarations from selectors that matched the regex (omit
123 | g flag to return just the first match)
124 | ```
125 |
126 | ## Test
127 |
128 | Make sure you're on the development branch and then:
129 |
130 | ```
131 | $ npm test
132 | ```
133 |
134 | NOTE: Tests will only run in a git cloned repo. They are disabled in the
135 | published npm module.
136 |
137 | ## Restrictions
138 |
139 | - This currently only works with static values. Dynamic arguments can/will
140 | break it. Some dynamic support is coming soon.
141 | - Better error handling coming soon!
142 | - Selectors passed as arguments must match stylesheet selectors exactly. Partial matches/regex matches coming soon.
143 | - There is no de-duplication or other optimizations at this time. Currently styled-import just copies out the rules from the classes. It does not import the whole stylesheet into your bundle. Optimizations coming soon.
144 | - See the warning at top -- this is experimental and untested in many
145 | environments! Production-ready version...you guessed it...is coming soon.
146 |
147 |
--------------------------------------------------------------------------------
/examples/app.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const styled = require('styled-components/macro');
3 | const styleImport = require('../macro');
4 |
5 | const sectionRules = styleImport('./external.css', (selector, declarations, idx) => {
6 | return /foo/.test(selector)
7 | });
8 | console.log(sectionRules);
9 |
10 | const Title = styled.div`
11 | color: blue;
12 | ${sectionRules.title}
13 | `;
14 |
15 | module.exports = () =>
foo
Foo
16 |
--------------------------------------------------------------------------------
/examples/external.css:
--------------------------------------------------------------------------------
1 | .foo .section {
2 | color: red;
3 | border: 1pt solid green;
4 | }
5 |
6 | .bar {
7 | color: purple;
8 | }
9 |
10 | .baz {
11 | color: black
12 | }
13 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Index
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/index.js:
--------------------------------------------------------------------------------
1 | const ReactDOM = require('react-dom')
2 | const app = require('./app');
3 |
4 | ReactDOM.render(app(), document.getElementById('root'))
5 |
6 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./macro')
2 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/empty/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/empty/output.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glortho/styled-import/cf33f478cd507e3b2124bd7b6fbbb8824717c336/macro/__tests__/__fixtures__/empty/output.js
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by array multi of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', ['.foo .section', '.baz'])
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by array multi of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = ['color: red;\nborder: 1pt solid green;', 'color: black;'];
2 |
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by array of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', ['.foo .section'])
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by array of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = ['color: red;\nborder: 1pt solid green;'];
2 |
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by object multi-key of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', {section: '.foo .section', bar: '.bar'})
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by object multi-key of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'section': 'color: red;\nborder: 1pt solid green;',
3 | 'bar': 'color: purple;'
4 | };
5 |
6 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by object of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', {section: '.foo .section'})
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by object of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'section': 'color: red;\nborder: 1pt solid green;'
3 | };
4 |
5 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by regex global/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', /fo/g)
3 |
4 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by regex global/output.js:
--------------------------------------------------------------------------------
1 | const foo = ['color: red;\nborder: 1pt solid green;', 'text-align: left;'];
2 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by regex/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', /foo/)
3 |
4 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by regex/output.js:
--------------------------------------------------------------------------------
1 | const foo = 'color: red;\nborder: 1pt solid green;';
2 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by string selector/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', '.bar')
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports by string selector/output.js:
--------------------------------------------------------------------------------
1 | const foo = 'color: purple;';
2 |
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports from node_modules stylesheet by string selector/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('_styled_tester/sample.css', '.bar')
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports from node_modules stylesheet by string selector/output.js:
--------------------------------------------------------------------------------
1 | const foo = 'color: purple;';
2 |
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports multiple by string selector/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport('../../sample.css', '.foo .section')
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports multiple by string selector/output.js:
--------------------------------------------------------------------------------
1 | const foo = 'color: red;\nborder: 1pt solid green;';
2 |
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by array multi of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', ['.foo .section', '.for-react'])
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by array multi of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = [{
2 | 'color': 'red',
3 | 'border': '1pt solid green'
4 | }, {
5 | 'textAlign': 'left'
6 | }];
7 |
8 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by array of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', ['.foo .section'])
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by array of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = [{
2 | 'color': 'red',
3 | 'border': '1pt solid green'
4 | }];
5 |
6 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by object multi-key of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', {section: '.foo .section', bar: '.bar'})
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by object multi-key of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'section': {
3 | 'color': 'red',
4 | 'border': '1pt solid green'
5 | },
6 | 'bar': {
7 | 'color': 'purple'
8 | }
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by object of selectors/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', {section: '.foo .section'})
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by object of selectors/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'section': {
3 | 'color': 'red',
4 | 'border': '1pt solid green'
5 | }
6 | };
7 |
8 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by string selector/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', '.bar')
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react by string selector/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'color': 'purple'
3 | };
4 |
5 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react multiple by string selector/code.js:
--------------------------------------------------------------------------------
1 | const styledImport = require('../../../../macro')
2 | const foo = styledImport.react('../../sample.css', '.foo .section')
3 |
--------------------------------------------------------------------------------
/macro/__tests__/__fixtures__/imports react multiple by string selector/output.js:
--------------------------------------------------------------------------------
1 | const foo = {
2 | 'color': 'red',
3 | 'border': '1pt solid green'
4 | };
5 |
6 |
--------------------------------------------------------------------------------
/macro/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const pluginTester = require('babel-plugin-tester')
3 | const plugin = require('babel-plugin-macros')
4 |
5 | pluginTester({
6 | plugin,
7 | fixtures: path.join(__dirname, '__fixtures__')
8 | })
9 |
--------------------------------------------------------------------------------
/macro/__tests__/sample.css:
--------------------------------------------------------------------------------
1 | .foo .section {
2 | color: red;
3 | border: 1pt solid green;
4 | }
5 |
6 | .bar {
7 | color: purple;
8 | }
9 |
10 | .baz {
11 | color: black;
12 | }
13 |
14 | .for-react {
15 | text-align: left;
16 | }
17 |
--------------------------------------------------------------------------------
/macro/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const css = require('css');
4 |
5 | const {createMacro} = require('babel-plugin-macros')
6 |
7 | module.exports = createMacro(styleImportMacro);
8 |
9 | function styleImportMacro({references, state, babel}) {
10 | references.default.forEach(referencePath => {
11 |
12 | const { node } = referencePath.parentPath;
13 |
14 | // if there is a property on the node it means the user is using
15 | // the styledImport.(...) option, for example:
16 | //
17 | // styledImport.react(...)
18 | //
19 | const format = node.property
20 | ? node.property.name
21 | : 'string'
22 |
23 | // TODO: what is the proper way to get arguments when using the property
24 | // format?
25 | const [ cssPathArg, selectorArg ] = node.property
26 | ? referencePath.parentPath.parent.arguments
27 | : referencePath.parentPath.get('arguments').map( arg => arg.node )
28 |
29 | const cssRules = parseAst(state.file.opts.filename, cssPathArg.value).stylesheet.rules;
30 |
31 | const declarationMethods = getDeclarationMethods(cssRules, babel, { format });
32 |
33 | const declarations = (
34 | selectorArg.value ?
35 | declarationMethods.byString(selectorArg.value) :
36 | selectorArg.elements ?
37 | declarationMethods.byArray(selectorArg.elements) :
38 | selectorArg.pattern ?
39 | declarationMethods.byRegex(selectorArg) :
40 | declarationMethods.byObject(selectorArg.properties)
41 | )
42 |
43 | const fnCallPath = node.property
44 | ? referencePath.parentPath.parentPath
45 | : referencePath.parentPath
46 | fnCallPath.replaceWith(declarations);
47 | });
48 | }
49 |
50 | const getDeclarationMethods = (cssRules, babel, options = {}) => {
51 |
52 | const stringifyDeclarations = declarations =>
53 | declarations.map(item => `${item.property}: ${item.value};`).join('\n')
54 |
55 | const objectifyDeclarations = declarations =>
56 | declarations.map(item => babel.types.objectProperty(
57 | babel.types.stringLiteral(toCamelCase(item.property)),
58 | babel.types.stringLiteral(item.value)
59 | ))
60 |
61 | const formatDeclarations = rule => options.format === 'string'
62 | ? babel.types.stringLiteral(stringifyDeclarations(rule.declarations))
63 | : babel.types.ObjectExpression(objectifyDeclarations(rule.declarations))
64 |
65 | const byArray = elements => {
66 | const declarations = elements.map( node => {
67 | const rule = cssRules.find( rule => rule.selectors.some( selector => node.value === selector) )
68 | return rule
69 | ? formatDeclarations(rule)
70 | : babel.types.nullLiteral()
71 | })
72 | return babel.types.ArrayExpression(declarations)
73 | }
74 |
75 | const byObject = properties => {
76 | const declarations = properties.map(item => {
77 | const key = item.key.name;
78 | const value = item.value.value;
79 | const rule = cssRules
80 | .find( rule => rule.selectors.some( selector => selector === value ))
81 | return babel.types.objectProperty(
82 | babel.types.stringLiteral(key), (
83 | rule
84 | ? formatDeclarations(rule)
85 | : babel.types.nullLiteral()
86 | )
87 | )
88 | });
89 | return babel.types.ObjectExpression(declarations)
90 | }
91 |
92 | const byString = value => {
93 | const rule = cssRules.find( rule => rule.selectors.some( selector => selector === value ))
94 | return rule
95 | ? formatDeclarations(rule)
96 | : babel.types.nullLiteral()
97 | }
98 |
99 | const byRegex = ({pattern, flags}) => {
100 | const regex = new RegExp(pattern, flags)
101 | if (!~flags.indexOf('g')) {
102 | const rule = cssRules.find( rule => rule.selectors.some( selector => regex.test(selector)))
103 | return rule
104 | ? formatDeclarations(rule)
105 | : babel.types.nullLiteral()
106 | } else {
107 | const declarations = cssRules
108 | .filter( rule => rule.selectors.some( selector => regex.test(selector)))
109 | .map( formatDeclarations )
110 | return babel.types.ArrayExpression(declarations)
111 | }
112 | }
113 |
114 | return { byRegex, byString, byArray, byObject }
115 | }
116 |
117 | const parseAst = (modulePath, cssPath) => {
118 |
119 | const pathHint = modulePath.charAt(0)
120 | const pathReference = pathHint === '/'
121 | ? path.dirname(modulePath)
122 | : path.join(process.cwd(), path.dirname(modulePath))
123 |
124 | const cssPathHint = cssPath.charAt(0)
125 | const cssPathReference = (
126 | cssPathHint === '/' ?
127 | cssPath :
128 | cssPathHint === '.' ?
129 | path.join(pathReference, cssPath) :
130 | require.resolve(cssPath)
131 | )
132 | const cssString = fs.readFileSync(cssPathReference, 'utf-8')
133 | return css.parse(cssString, {source: cssPathReference})
134 | }
135 |
136 | const toCamelCase = str => str.replace(/(-.)/g, chars => chars[1].toUpperCase())
137 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "styled-plus",
3 | "version": "0.2.1",
4 | "description": "Extreme lightweight CSS parser for stealing rules from stylesheets (without adding the stylesheet to your bundle), to compose into Styled Components or anywhere else you might be doing CSS in JS.",
5 | "author": "jed@dataverse.me",
6 | "repository": "https://github.com/glortho/styled-import",
7 | "license": "MIT",
8 | "main": "index.js",
9 | "scripts": {
10 | "copy-test-files": "mkdir node_modules/_styled_tester > /dev/null 2>&1; cp macro/__tests__/sample.css node_modules/_styled_tester > /dev/null 2>&1",
11 | "dev": "./scripts/dev.sh",
12 | "prep": "./scripts/prepublish.sh",
13 | "test": "npm run copy-test-files; jest"
14 | },
15 | "jest": {
16 | "testMatch": [
17 | "**/__tests__/**/*.test.js"
18 | ]
19 | },
20 | "dependencies": {},
21 | "devDependencies": {
22 | "babel-cli": "^6.26.0",
23 | "babel-core": "^6.26.3",
24 | "babel-loader": "^7.1.5",
25 | "babel-plugin-macros": "^2.4.3",
26 | "babel-plugin-tester": "^5.5.2",
27 | "babel-preset-env": "^1.7.0",
28 | "babel-preset-react": "^6.24.1",
29 | "css": "^2.2.4",
30 | "jest": "^23.6.0",
31 | "react": "^16.6.3",
32 | "react-dom": "^16.6.3",
33 | "styled-components": "^4.1.3",
34 | "webpack": "^4.27.1",
35 | "webpack-cli": "^3.1.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/package.npm.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "styled-import",
3 | "version": "0.2.5",
4 | "description": "Extreme lightweight CSS parser for stealing rules from stylesheets (without adding the stylesheet to your bundle), to compose into Styled Components or anywhere else you might be doing CSS in JS.",
5 | "keywords": [
6 | "babel-plugin-macros"
7 | ],
8 | "main": "index.js",
9 | "author": "jed@dataverse.me",
10 | "repository": "https://github.com/glortho/styled-import",
11 | "license": "MIT",
12 | "scripts": {
13 | "dev": "./scripts/dev.sh"
14 | },
15 | "devDependencies": {
16 | "babel-plugin-macros": "^2.4.3",
17 | "css": "^2.2.4"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/scripts/dev.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mv package{,.npm}.json
4 | mv package{.dev,}.json
5 | npm i
6 |
--------------------------------------------------------------------------------
/scripts/prepublish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | npm test
4 | mv package{,.dev}.json
5 | mv package{.npm,}.json
6 | npm i
7 |
8 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | mode: 'development',
5 | entry: path.join(__dirname, 'examples', 'index.js'),
6 | output: {
7 | path: path.join(__dirname, 'examples'),
8 | filename: 'bundle.js'
9 | },
10 | module: {
11 | rules: [
12 | {
13 | test: /\.m?js$/,
14 | exclude: /(node_modules|bower_components)/,
15 | use: {
16 | loader: 'babel-loader',
17 | options: {
18 | presets: ['babel-preset-env']
19 | }
20 | }
21 | }
22 | ]
23 | }
24 | };
25 |
--------------------------------------------------------------------------------