Skip to content
This repository has been archived by the owner on Feb 9, 2023. It is now read-only.

Add support for vue-emotion and emotion-styling #42

Merged
merged 2 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ const supports = {
// import styled from "react-emotion";
'react-emotion': true,

// import styled from 'vue-emotion';
// Also see:
// - https://github.com/stylelint/stylelint/issues/4247
// - https://github.com/gucong3000/postcss-jsx/issues/63
// - https://github.com/stylelint/postcss-css-in-js/issues/22
'vue-emotion': true,

// import styled from 'preact-emotion'
'preact-emotion': true,

Expand Down Expand Up @@ -198,6 +205,16 @@ function literalParser(source, opts, styles) {

return path;
}
// If this is not an object but a function returning an object, we want to parse the
// object that is in the body of the function. We will only parse it if the body only
// consist of an object and nothing else.
else if (path.isArrowFunctionExpression()) {
const body = path.get('body');

if (body) {
addObjectExpression(body);
}
}
}

function setSpecifier(id, nameSpace) {
Expand Down
99 changes: 99 additions & 0 deletions test/emotion.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,103 @@ describe('javascript tests', () => {
});
});
});

it('works with vue-emotion', () => {
// Related issues:
// - https://github.com/stylelint/stylelint/issues/4247
// - https://github.com/gucong3000/postcss-jsx/issues/63
// - https://github.com/stylelint/postcss-css-in-js/issues/22
const parsed = syntax.parse(`
import styled from 'vue-emotion';

const Wrapper = styled('div')\`
left: 0;
top: 0;
width: 100%;
height: 100%;
\`;
`);

expect(parsed.nodes).toHaveLength(1);
});

it('works with @emotion/styled', () => {
const parsed = syntax.parse(`
import styled from '@emotion/styled';

const Wrapper = styled.div\`
left: 0;
\`;
`);

expect(parsed.nodes).toHaveLength(1);
});

it('works with css objects', () => {
// It should parse:
// - Inline objects (inside of the JSX)
// - Variables that are referenced inside of the JSX
// - Variables that are referenced as spread
const parsed = syntax.parse(`
import React from 'react';

const spreaded = {
width: 100,
padding: 40,
};

const notInline = {
...spreaded,
margin: 60,
};

const Component = () => (
<div css={{
...spreaded,
margin: 60,
}}>
some other text
<span css={notInline}>Hello</span>
</div>
);
`);

expect(parsed.nodes).toHaveLength(3);
});

it('works with css object functions', () => {
// Just like the previous test, both inline and variable styles should be parsed. It should
// also parse objects if they are defined in a arrow function, which is for example what is
// used by emotion-theming.
// See also:
// - https://github.com/gucong3000/postcss-jsx/issues/69
// - https://github.com/stylelint/postcss-css-in-js/issues/22
const parsed = syntax.parse(`
import React from 'react';

const spreaded = {
width: 100,
padding: 40,
}

const notInline = theme => ({
...spreaded,
margin: 60,
color: theme.color.primary,
});

const Component = () => (
<div css={theme => ({
...spreaded,
margin: 60,
color: theme.color.primary,
})}>
some other text
<span css={notInline}>Hello</span>
</div>
);
`);

expect(parsed.nodes).toHaveLength(3);
});
});