Skip to content

Commit

Permalink
Handle style composition
Browse files Browse the repository at this point in the history
  • Loading branch information
dddlr committed Dec 2, 2024
1 parent f63b99d commit 79d6c3d
Show file tree
Hide file tree
Showing 4 changed files with 467 additions and 167 deletions.
4 changes: 3 additions & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
"src"
],
"dependencies": {
"@compiled/utils": "^0.13.0"
"@compiled/utils": "^0.13.0",
"estraverse": "^5.3.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.21.8",
"@types/estraverse": "^5.1.7",
"@types/estree": "^1.0.3",
"@types/estree-jsx": "^1.0.2",
"@typescript-eslint/parser": "^5.59.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ import { outdent } from 'outdent';
import { typeScriptTester as tester } from '../../../test-utils';
import { shorthandFirst } from '../index';

const packages_calls_and_imports = [
type Package = string;
type Call = string;
type Import = string;

type PkgCallImport = [Package, Call, Import];

const packages_calls_and_imports: PkgCallImport[] = [
['css', 'css', '@atlaskit/css'],
['css', 'css', '@compiled/react'],
['styled', 'styled.div', '@compiled/react'],
['cssMap', 'cssMap', '@atlaskit/css'],
['cssMap', 'cssMap', '@compiled/react'],

// These need to be treated separately
// TODO: write separate tests for these
// ['styled', 'styled.div', '@compiled/react'],
// ['cssMap', 'cssMap', '@atlaskit/css'],
// ['cssMap', 'cssMap', '@compiled/react'],
];

// TODO: handle cssMap, maybe cx?

// TODO: test padding and paddingTop, non-border shorthand properties

const packages_and_calls = [
['css', 'css'],
['styled', 'styled.div'],
Expand All @@ -19,7 +32,7 @@ const packages_and_calls = [

tester.run('shorthand-property-sorting', shorthandFirst, {
valid: [
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
...packages_calls_and_imports.map(([pkg, call, imp]: PkgCallImport) => ({
name: `correct property ordering, (${pkg}: '${imp}')`,
code: outdent`
import {${pkg}} from '${imp}';
Expand Down Expand Up @@ -57,17 +70,6 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
export const EmphasisText = ({ children }) => <span css={styles}>{children}</span>;
`,
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `property not in bucket (${pkg}: '${imp}'`,
code: outdent`
import {${pkg}} from '${imp}';
const styles = ${call}({
transitionDuration: '2', // unknown
transition: 'fast', // 1
});
export const EmphasisText = ({ children }) => <span css={styles}>{children}</span>;
`,
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `depth in correct order for properties in the same bucket (${pkg}: '${imp}')`,
code: outdent`
Expand All @@ -79,6 +81,38 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
export const EmphasisText = ({ children }) => <span css={styles}>{children}</span>;
`,
})),

{
name: 'shorthands in different selectors',
code: outdent`
import { styled } from '@compiled/react';
const Component = styled.div({
'&:hover': {
borderTop: '...', // pseudo-selectors are sorted after non-pseudo-selectors
},
'div ul': {
borderTop: '...',
},
border: '...',
});
`,
},
{
name: 'template strings are not supported',
code: outdent`
import { styled } from '@compiled/react';
const Component = styled.div\`
border-top: 3px;
border: solid 4px white,
\`;
`,
},
{
name: 'placeholder',
code: ``,
},
],
invalid: [
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
Expand All @@ -93,6 +127,86 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
`,
errors: [{ messageId: 'shorthand-first' }],
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `property not in bucket (${pkg}: '${imp}'`,
code: outdent`
import {${pkg}} from '${imp}';
const styles = ${call}({
transitionDuration: '2', // unknown
transition: 'fast', // 1
});
export const EmphasisText = ({ children }) => <span css={styles}>{children}</span>;
`,
errors: [{ messageId: 'shorthand-first' }],
})),
{
name: `incorrect property ordering (@compiled/react: styled.div)`,
code: outdent`
import { styled } from '@compiled/react';
const Component = styled.div({
borderTop: '1px solid #00b8d9',
border: '#00b8d9',
});
`,
errors: [{ messageId: 'shorthand-first' }],
},
{
name: `incorrect property ordering with multiple css calls`,
code: outdent`
import { css } from '@compiled/react';
const styles = css({
paddingTop: '1px',
});
const styles2 = css({
padding: '2px 3px 4px',
});
const hello = true;
const world = true;
export const EmphasisText = ({ children }) => <span css={[hello && styles, !world && styles2]}>{children}</span>;
`,
errors: [{ messageId: 'shorthand-first' }],
},
{
name: `incorrect property ordering with padding (css, @compiled/react)`,
code: outdent`
import { css } from '@compiled/react';
const styles = css({
paddingTop: '1px',
padding: '2px 3px 4px',
});
export const EmphasisText = ({ children }) => <span css={styles}>{children}</span>;
`,
errors: [{ messageId: 'shorthand-first' }],
},
{
name: 'shorthands in different selectors are not supported',
code: outdent`
import { styled } from '@compiled/react';
const BaseComponent = styled.div({
borderTopColor: 'white',
});
const Component = styled(BaseComponent)({
border: '...',
});
`,
errors: [{ messageId: 'shorthand-first' }],
},
{
name: 'css inside styled',
code: outdent`
import { css, styled } from '@compiled/react';
const Component = styled.div(
{
paddingTop: '...',
},
({ disableClick }) => disableClick && css({
padding: '...',
})
);
`,
errors: [{ messageId: 'shorthand-first' }],
},
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `incorrect property ordering -> 3 properties (${pkg}: '${imp}'`,
code: outdent`
Expand Down Expand Up @@ -127,30 +241,32 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
`,
errors: [{ messageId: 'shorthand-first' }],
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `incorrect property ordering -> nested ObjectExpression (${pkg}: '${imp}')`,
code: outdent`
import {${pkg}} from '${imp}';
const containerAppearance = {
default: ${call}({
borderBlockEnd: '1px solid #00b8d9',
borderBlock: '#00b8d9',
border: '#00b8d9',
}),
success: ${call}({
border: '#00b8d9',
borderBlock: '#00b8d9',
borderBlockEnd: '1px solid #00b8d9',
}),
inverse: ${call}({
border: '#00b8d9',
borderBlockEnd: '1px solid #00b8d9',
borderBlock: '#00b8d9',
}),
};
`,
errors: [{ messageId: 'shorthand-first' }, { messageId: 'shorthand-first' }],
})),
// TODO: check whether this is valid?
//
// ...packages_calls_and_imports.map(([pkg, call, imp]) => ({
// name: `incorrect property ordering -> nested ObjectExpression (${pkg}: '${imp}')`,
// code: outdent`
// import {${pkg}} from '${imp}';
// const containerAppearance = {
// default: ${call}({
// borderBlockEnd: '1px solid #00b8d9',
// borderBlock: '#00b8d9',
// border: '#00b8d9',
// }),
// success: ${call}({
// border: '#00b8d9',
// borderBlock: '#00b8d9',
// borderBlockEnd: '1px solid #00b8d9',
// }),
// inverse: ${call}({
// border: '#00b8d9',
// borderBlockEnd: '1px solid #00b8d9',
// borderBlock: '#00b8d9',
// }),
// };
// `,
// errors: [{ messageId: 'shorthand-first' }, { messageId: 'shorthand-first' }],
// })),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `incorrect property ordering -> 6 reordering errors (${pkg}: '${imp}')`,
code: outdent`
Expand Down Expand Up @@ -181,12 +297,14 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
border: '1px solid #00b8d9', // 1
borderColor: 'red', // 2
borderTop: '1px solid #00b8d9', // 4
})
});
const Component = <div css={styles} />;
`,
errors: [{ messageId: 'shorthand-first' }],
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `includes pseudo-selectors -> non-pseduo are out of order (${pkg}: '${imp}')`,
name: `includes pseudo-selectors -> non-pseudo are out of order (${pkg}: '${imp}')`,
code: outdent`
import {${pkg}} from '${imp}';
const styles = ${call}({
Expand All @@ -198,17 +316,14 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
borderTop: '1px solid #00b8d9', // 4
borderColor: 'red', // 2
border: '1px solid #00b8d9', // 1
})
});
const Component = <div css={styles} />;
`,
errors: [{ messageId: 'shorthand-first' }],
})),

/* fixer can't deal with nested fixing in one go. I've split this test into:
pt1 with the first round of fixes,
pt2 carrying on from the output of pt1.
*/
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `includes pseduo-selectors -> pseduo and non-pseduo are out of order pt1 (${pkg}: '${imp}')`,
name: `includes pseudo-selectors -> pseudo and non-pseudo are out of order pt1 (${pkg}: '${imp}')`,
code: outdent`
import {${pkg}} from '${imp}';
const styles = ${call}({
Expand All @@ -220,20 +335,10 @@ tester.run('shorthand-property-sorting', shorthandFirst, {
borderTop: '1px solid #00b8d9', // 4
borderColor: 'red', // 2
border: '1px solid #00b8d9', // 1
})
});
const Component = <div css={styles} />;
`,
errors: [{ messageId: 'shorthand-first' }, { messageId: 'shorthand-first' }],
})),
...packages_calls_and_imports.map(([pkg, call, imp]) => ({
name: `includes pseduo-selectors -> pseduo and non-pseduo are out of order pt2 (${pkg}: '${imp}')`,
code: outdent`
import {${pkg}} from '${imp}';
const styles = ${call}({ '&:hover': {
borderTop: '1px solid #00b8d9', // 4
borderColor: 'red', // 2
border: '1px solid #00b8d9', // 1
}, border: '1px solid #00b8d9', borderColor: 'red', borderTop: '1px solid #00b8d9' })
`,
errors: [{ messageId: 'shorthand-first' }],
})),
],
Expand Down
Loading

0 comments on commit 79d6c3d

Please sign in to comment.