mirror of
https://github.com/antebudimir/eslint-plugin-vanilla-extract.git
synced 2025-12-31 17:03:32 +00:00
feat ✅: add comprehensive test suite for CSS ordering rules
Add tests for all three CSS property ordering rules:
alphabetical-order,
concentric-order,
custom-order,
Tests cover all implemented vanilla-extract APIs, fontFace, globalFontFace, globalKeyframes, globalStyle, keyframes, style, and styleVariants.. Each test verifies both valid and invalid cases, along with proper auto-fixing functionality.
This commit is contained in:
parent
3e9bad1b02
commit
da4d2d6373
25 changed files with 3635 additions and 24 deletions
50
CHANGELOG.md
Normal file
50
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.4.1] - 2025-03-09
|
||||||
|
|
||||||
|
- Add comprehensive test suite for CSS ordering rules ()
|
||||||
|
|
||||||
|
## [1.4.0] - 2025-03-08
|
||||||
|
|
||||||
|
- Implement special ordering for fontFace APIs (3e9bad1)
|
||||||
|
|
||||||
|
## [1.3.1] - 2025-03-07
|
||||||
|
|
||||||
|
- Update milestones (8916be7)
|
||||||
|
|
||||||
|
## [1.3.0] - 2025-03-06
|
||||||
|
|
||||||
|
- Add script for versioning updates (f2ad87c)
|
||||||
|
|
||||||
|
## [1.2.0] - 2025-03-05
|
||||||
|
|
||||||
|
- Add support for linting keyframes and globalKeyframes (dea0a32)
|
||||||
|
|
||||||
|
## [1.1.2] - 2025-03-05
|
||||||
|
|
||||||
|
- add .npmignore to exclude development files from npm package (223a81d)
|
||||||
|
|
||||||
|
## [1.1.1] - 2025-03-05
|
||||||
|
|
||||||
|
- Improve packaging and TypeScript configuration (c616fb0)
|
||||||
|
|
||||||
|
## [1.1.0] - 2025-03-04
|
||||||
|
|
||||||
|
- Lower minimum Node.js version to 18.18.0 (44aba94)
|
||||||
|
|
||||||
|
## [1.0.2] - 2025-03-04
|
||||||
|
|
||||||
|
- Add npm version badge and link to vanilla-extract (87acd61)
|
||||||
|
|
||||||
|
## [1.0.1] - 2025-03-04
|
||||||
|
|
||||||
|
- Add sample CSS file for linting demo during development (88a9d43)
|
||||||
|
|
||||||
|
## [1.0.0] - 2025-03-04
|
||||||
|
|
||||||
|
- Initialize project with complete codebase (d569dea)
|
||||||
|
|
@ -253,14 +253,14 @@ The roadmap outlines the project's current status and future plans:
|
||||||
- Initial release with support for alphabetical, concentric, and custom group CSS ordering.
|
- Initial release with support for alphabetical, concentric, and custom group CSS ordering.
|
||||||
- Auto-fix capability integrated into ESLint.
|
- Auto-fix capability integrated into ESLint.
|
||||||
- Support for multiple vanilla-extract APIs (e.g., `style`, `styleVariants`, `recipe`, `globalStyle`, `fontFace`, etc.).
|
- Support for multiple vanilla-extract APIs (e.g., `style`, `styleVariants`, `recipe`, `globalStyle`, `fontFace`, etc.).
|
||||||
|
- Rules tested.
|
||||||
|
|
||||||
### Current Work
|
### Current Work
|
||||||
|
|
||||||
- Test coverage.
|
- `no-empty-blocks` rule to disallow empty blocks.
|
||||||
|
|
||||||
### Upcoming Features
|
### Upcoming Features
|
||||||
|
|
||||||
- `no-empty-blocks` rule to disallow empty blocks.
|
|
||||||
- `no-unknown-units` rule to disallow unknown units.
|
- `no-unknown-units` rule to disallow unknown units.
|
||||||
- `no-number-trailing-zeros` rule to disallow trailing zeros in numbers.
|
- `no-number-trailing-zeros` rule to disallow trailing zeros in numbers.
|
||||||
- `no-zero-unit` rule to disallow units when the value is zero.
|
- `no-zero-unit` rule to disallow units when the value is zero.
|
||||||
|
|
|
||||||
11
package.json
11
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@antebudimir/eslint-plugin-vanilla-extract",
|
"name": "@antebudimir/eslint-plugin-vanilla-extract",
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"description": "ESLint plugin for enforcing CSS ordering in vanilla-extract styles",
|
"description": "ESLint plugin for enforcing CSS ordering in vanilla-extract styles",
|
||||||
"author": "Ante Budimir",
|
"author": "Ante Budimir",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -46,6 +46,9 @@
|
||||||
"lint": "eslint src --ext .ts --fix --max-warnings 0",
|
"lint": "eslint src --ext .ts --fix --max-warnings 0",
|
||||||
"prepublishOnly": "pnpm run lint && pnpm run build",
|
"prepublishOnly": "pnpm run lint && pnpm run build",
|
||||||
"publish": "pnpm publish --access public",
|
"publish": "pnpm publish --access public",
|
||||||
|
"test": "vitest run",
|
||||||
|
"test:watch": "vitest",
|
||||||
|
"test:coverage": "vitest run --coverage",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"version:update": "node scripts/update-version.mjs"
|
"version:update": "node scripts/update-version.mjs"
|
||||||
},
|
},
|
||||||
|
|
@ -61,16 +64,20 @@
|
||||||
"@types/node": "^20.17.19",
|
"@types/node": "^20.17.19",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.25.0",
|
"@typescript-eslint/eslint-plugin": "^8.25.0",
|
||||||
"@typescript-eslint/parser": "^8.25.0",
|
"@typescript-eslint/parser": "^8.25.0",
|
||||||
|
"@typescript-eslint/rule-tester": "^8.26.0",
|
||||||
"@typescript-eslint/utils": "^8.25.0",
|
"@typescript-eslint/utils": "^8.25.0",
|
||||||
"@vanilla-extract/css": "^1.17.1",
|
"@vanilla-extract/css": "^1.17.1",
|
||||||
"@vanilla-extract/recipes": "^0.5.5",
|
"@vanilla-extract/recipes": "^0.5.5",
|
||||||
|
"@vitest/coverage-v8": "3.0.8",
|
||||||
"eslint": "^9.21.0",
|
"eslint": "^9.21.0",
|
||||||
"eslint-config-prettier": "^10.0.2",
|
"eslint-config-prettier": "^10.0.2",
|
||||||
"eslint-import-resolver-typescript": "^3.8.3",
|
"eslint-import-resolver-typescript": "^3.8.3",
|
||||||
"eslint-plugin-eslint-plugin": "^6.4.0",
|
"eslint-plugin-eslint-plugin": "^6.4.0",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
|
"eslint-vitest-rule-tester": "^1.1.0",
|
||||||
"prettier": "^3.5.2",
|
"prettier": "^3.5.2",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"typescript-eslint": "^8.25.0"
|
"typescript-eslint": "^8.25.0",
|
||||||
|
"vitest": "^3.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1330
pnpm-lock.yaml
generated
1330
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
111
src/css-rules/alphabetical-order/__tests__/animation.test.ts
Normal file
111
src/css-rules/alphabetical-order/__tests__/animation.test.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/animation',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// keyframes with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(10px)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
|
||||||
|
// globalKeyframes with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { globalKeyframes } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalKeyframes('fadeIn', {
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(10px)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// keyframes with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
transform: 'translateY(10px)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }, { messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(10px)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalKeyframes with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalKeyframes } from '@vanilla-extract/css';
|
||||||
|
globalKeyframes('fadeIn', {
|
||||||
|
'0%': {
|
||||||
|
transform: 'translateY(10px)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }, { messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalKeyframes } from '@vanilla-extract/css';
|
||||||
|
globalKeyframes('fadeIn', {
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(10px)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
143
src/css-rules/alphabetical-order/__tests__/font-face.test.ts
Normal file
143
src/css-rules/alphabetical-order/__tests__/font-face.test.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/font-face',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// fontFace with src first and other properties alphabetically ordered
|
||||||
|
`
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
|
||||||
|
// globalFontFace with src first and other properties alphabetically ordered
|
||||||
|
`
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// fontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
fontWeight: '400',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// fontFace with src first but other properties not in alphabetical order
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
fontWeight: '400',
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalFontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
fontWeight: '400',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalFontFace with src first but other properties not in alphabetical order
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
fontWeight: '400',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
ascentOverride: '90%'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
52
src/css-rules/alphabetical-order/__tests__/global.test.ts
Normal file
52
src/css-rules/alphabetical-order/__tests__/global.test.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/global',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// globalStyle with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalStyle('body', {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
color: 'black',
|
||||||
|
margin: 0,
|
||||||
|
padding: 0
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// globalStyle with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
margin: 0
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
color: 'black',
|
||||||
|
margin: 0,
|
||||||
|
padding: 0
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
92
src/css-rules/alphabetical-order/__tests__/recipe.test.ts
Normal file
92
src/css-rules/alphabetical-order/__tests__/recipe.test.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/recipe',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Recipe with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Recipe with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'red'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [
|
||||||
|
{ messageId: 'alphabeticalOrder' },
|
||||||
|
{ messageId: 'alphabeticalOrder' },
|
||||||
|
{ messageId: 'alphabeticalOrder' },
|
||||||
|
],
|
||||||
|
output: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
111
src/css-rules/alphabetical-order/__tests__/style.test.ts
Normal file
111
src/css-rules/alphabetical-order/__tests__/style.test.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/style',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Basic style object with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myStyle = style({
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '10px',
|
||||||
|
padding: '20px',
|
||||||
|
zIndex: 1
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
|
||||||
|
// Style with nested selectors
|
||||||
|
`
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myStyle = style({
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Basic style object with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
backgroundColor: 'red',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: '20px',
|
||||||
|
color: 'blue',
|
||||||
|
margin: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
zIndex: 1
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '10px',
|
||||||
|
padding: '20px',
|
||||||
|
zIndex: 1
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style with nested selectors having incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
backgroundColor: 'red',
|
||||||
|
alignItems: 'center',
|
||||||
|
color: 'blue',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }, { messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
64
src/css-rules/alphabetical-order/__tests__/variants.test.ts
Normal file
64
src/css-rules/alphabetical-order/__tests__/variants.test.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import alphabeticalOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/alphabetical-order/variants',
|
||||||
|
rule: alphabeticalOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// styleVariants with alphabetical ordering
|
||||||
|
`
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// styleVariants with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'gray'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }, { messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
70
src/css-rules/concentric-order/__tests__/animation.test.ts
Normal file
70
src/css-rules/concentric-order/__tests__/animation.test.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/animation',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// keyframes with concentric ordering
|
||||||
|
`
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// keyframes with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
97
src/css-rules/concentric-order/__tests__/font-face.test.ts
Normal file
97
src/css-rules/concentric-order/__tests__/font-face.test.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/font-face',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// fontFace with src first and other properties alphabetically ordered
|
||||||
|
`
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
|
||||||
|
// globalFontFace with src first and other properties alphabetically ordered
|
||||||
|
`
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// fontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
fontWeight: '400',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalFontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
fontWeight: '400',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
58
src/css-rules/concentric-order/__tests__/global.test.ts
Normal file
58
src/css-rules/concentric-order/__tests__/global.test.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/global',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// globalStyle with concentric ordering
|
||||||
|
`
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalStyle('body', {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
color: 'black'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// globalStyle with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
color: 'black',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
display: 'block',
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
color: 'black'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
101
src/css-rules/concentric-order/__tests__/recipe.test.ts
Normal file
101
src/css-rules/concentric-order/__tests__/recipe.test.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/recipe',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Recipe with concentric ordering
|
||||||
|
`
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Recipe with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
129
src/css-rules/concentric-order/__tests__/style.test.ts
Normal file
129
src/css-rules/concentric-order/__tests__/style.test.ts
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/style',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Basic style object with concentric ordering
|
||||||
|
`
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myStyle = style({
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: 1,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
transform: 'none',
|
||||||
|
opacity: 1,
|
||||||
|
margin: '1rem',
|
||||||
|
border: '1px solid black',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
padding: '2rem',
|
||||||
|
width: '10rem',
|
||||||
|
height: '10rem',
|
||||||
|
color: 'blue',
|
||||||
|
fontSize: '16rem'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
|
||||||
|
// Style with nested selectors
|
||||||
|
`
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
position: 'relative',
|
||||||
|
opacity: 0.8,
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Basic style object with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
color: 'blue',
|
||||||
|
width: '10rem',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
margin: '1rem',
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
width: '10rem',
|
||||||
|
color: 'blue'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style with nested selectors having incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
color: 'blue',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
position: 'relative',
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
color: 'white',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
135
src/css-rules/concentric-order/__tests__/variants.test.ts
Normal file
135
src/css-rules/concentric-order/__tests__/variants.test.ts
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import concentricOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/concentric-order/variants',
|
||||||
|
rule: concentricOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// styleVariants with concentric ordering
|
||||||
|
`
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
padding: '0.5rem',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '0.8rem',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// styleVariants with incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
padding: '0.5rem',
|
||||||
|
margin: '1rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
margin: '0.8rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
padding: '0.5rem',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '0.8rem',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// styleVariants with some variants having incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
margin: '0.8rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
padding: '0.5rem',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '0.8rem',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
151
src/css-rules/custom-order/__tests__/animation.test.ts
Normal file
151
src/css-rules/custom-order/__tests__/animation.test.ts
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/animation',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// keyframes with custom group ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// keyframes with custom group ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// keyframes with incorrect ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// keyframes with incorrect ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
transform: 'translateY(1rem)',
|
||||||
|
position: 'relative',
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
position: 'relative',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { keyframes } from '@vanilla-extract/css';
|
||||||
|
const fadeIn = keyframes({
|
||||||
|
'0%': {
|
||||||
|
opacity: 0,
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(1rem)'
|
||||||
|
},
|
||||||
|
'100%': {
|
||||||
|
opacity: 1,
|
||||||
|
position: 'relative',
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
127
src/css-rules/custom-order/__tests__/font-face.test.ts
Normal file
127
src/css-rules/custom-order/__tests__/font-face.test.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/font-face',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
configs: {
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// fontFace
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalFontFace
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
descentOverride: '10%',
|
||||||
|
fontDisplay: 'swap',
|
||||||
|
fontFeatureSettings: '"liga" 1',
|
||||||
|
fontStretch: 'normal',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontVariant: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// fontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
fontWeight: '400',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { fontFace } from '@vanilla-extract/css';
|
||||||
|
const myFont = fontFace({
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalFontFace with src not first
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
fontWeight: '400',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'fontFaceOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalFontFace } from '@vanilla-extract/css';
|
||||||
|
globalFontFace('GlobalFont', {
|
||||||
|
src: ['url("/fonts/MyFont.woff2") format("woff2")'],
|
||||||
|
ascentOverride: '90%',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
fontWeight: '400'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
127
src/css-rules/custom-order/__tests__/global.test.ts
Normal file
127
src/css-rules/custom-order/__tests__/global.test.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/global',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// globalStyle with custom group ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalStyle('body', {
|
||||||
|
margin: 0,
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
color: 'black'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalStyle with custom group ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
globalStyle('body', {
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
color: 'black',
|
||||||
|
display: 'block',
|
||||||
|
padding: 0,
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// globalStyle with incorrect ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
color: 'black',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
display: 'block',
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
margin: 0,
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
color: 'black'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// globalStyle with incorrect ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'block',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: 0,
|
||||||
|
color: 'black'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { globalStyle } from '@vanilla-extract/css';
|
||||||
|
globalStyle('body', {
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
color: 'black',
|
||||||
|
display: 'block',
|
||||||
|
padding: 0,
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
211
src/css-rules/custom-order/__tests__/recipe.test.ts
Normal file
211
src/css-rules/custom-order/__tests__/recipe.test.ts
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/recipe',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Recipe with custom group ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
width: '100%',
|
||||||
|
margin: 0,
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Recipe with custom group ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
width: '100%',
|
||||||
|
margin: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Recipe with incorrect ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: 0
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
width: '100%',
|
||||||
|
margin: 0,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Recipe with incorrect ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%',
|
||||||
|
margin: 0
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
|
const myRecipe = recipe({
|
||||||
|
base: {
|
||||||
|
width: '100%',
|
||||||
|
margin: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
color: {
|
||||||
|
blue: {
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
252
src/css-rules/custom-order/__tests__/style.test.ts
Normal file
252
src/css-rules/custom-order/__tests__/style.test.ts
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/style',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// Style with custom group ordering (dimensions, margin, font, border, boxShadow)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
// dimensions group first
|
||||||
|
width: '10rem',
|
||||||
|
minWidth: '5rem',
|
||||||
|
height: '10rem',
|
||||||
|
maxHeight: '20rem',
|
||||||
|
|
||||||
|
// margin group second
|
||||||
|
margin: '1rem',
|
||||||
|
marginTop: '0.5rem',
|
||||||
|
|
||||||
|
// font group third
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
|
||||||
|
// border group fourth
|
||||||
|
border: '1px solid black',
|
||||||
|
borderRadius: '4px',
|
||||||
|
|
||||||
|
// boxShadow group fifth
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
|
||||||
|
// remaining properties in concentric order
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
padding: '2rem',
|
||||||
|
color: 'blue'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style with nested selectors following custom group ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
width: '10rem',
|
||||||
|
margin: '1rem',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
border: '1px solid black',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
width: '12rem',
|
||||||
|
margin: '12px',
|
||||||
|
fontSize: '1rem',
|
||||||
|
borderColor: 'blue',
|
||||||
|
boxShadow: '0 4px 8px rgba(0,0,0,0.2)',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
// dimensions group first
|
||||||
|
width: '10rem',
|
||||||
|
height: '10rem',
|
||||||
|
|
||||||
|
// margin group second
|
||||||
|
margin: '1rem',
|
||||||
|
|
||||||
|
// font group third
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
|
||||||
|
// border group fourth
|
||||||
|
border: '1px solid black',
|
||||||
|
|
||||||
|
// boxShadow group fifth
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
|
||||||
|
// remaining properties in alphabetical order
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
display: 'flex',
|
||||||
|
padding: '2rem',
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// Style with incorrect custom group ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
border: '1px solid black',
|
||||||
|
width: '10rem',
|
||||||
|
color: 'blue',
|
||||||
|
margin: '1rem',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
backgroundColor: 'red'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
width: '10rem',
|
||||||
|
margin: '1rem',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
border: '1px solid black',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Style with nested selectors having incorrect ordering
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
border: '1px solid black',
|
||||||
|
width: '10rem',
|
||||||
|
position: 'relative',
|
||||||
|
margin: '1rem',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
color: 'white',
|
||||||
|
width: '12rem',
|
||||||
|
border: '2px solid blue',
|
||||||
|
margin: '1.2rem',
|
||||||
|
backgroundColor: 'blue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
width: '10rem',
|
||||||
|
margin: '1rem',
|
||||||
|
border: '1px solid black',
|
||||||
|
position: 'relative',
|
||||||
|
selectors: {
|
||||||
|
'&:hover': {
|
||||||
|
width: '12rem',
|
||||||
|
margin: '1.2rem',
|
||||||
|
border: '2px solid blue',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
border: '1px solid black',
|
||||||
|
width: '10rem',
|
||||||
|
padding: '2rem',
|
||||||
|
color: 'blue',
|
||||||
|
margin: '1rem',
|
||||||
|
display: 'flex',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
backgroundColor: 'red'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
const myStyle = style({
|
||||||
|
width: '10rem',
|
||||||
|
margin: '1rem',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
border: '1px solid black',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
color: 'blue',
|
||||||
|
display: 'flex',
|
||||||
|
padding: '2rem',
|
||||||
|
position: 'relative'
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
187
src/css-rules/custom-order/__tests__/variants.test.ts
Normal file
187
src/css-rules/custom-order/__tests__/variants.test.ts
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import { run } from 'eslint-vitest-rule-tester';
|
||||||
|
import customGroupOrderRule from '../rule-definition.js';
|
||||||
|
|
||||||
|
run({
|
||||||
|
name: 'vanilla-extract/custom-order/variants',
|
||||||
|
rule: customGroupOrderRule,
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: [
|
||||||
|
// styleVariants with custom group ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
margin: '0.8rem',
|
||||||
|
padding: '0.4rem',
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['margin', 'padding', 'dimensions', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// styleVariants with custom group ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
margin: '0.8rem',
|
||||||
|
padding: '0.4rem',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['margin', 'padding', 'dimensions', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
// styleVariants with incorrect ordering (concentric for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
color: 'white',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
padding: '0.5rem',
|
||||||
|
margin: '1rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
margin: '0.8rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['margin', 'padding', 'dimensions', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
margin: '0.8rem',
|
||||||
|
padding: '0.4rem',
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// styleVariants with incorrect ordering (alphabetical for remaining)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
color: 'black',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
padding: '0.4rem',
|
||||||
|
margin: '0.8rem',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['margin', 'padding', 'dimensions', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { styleVariants } from '@vanilla-extract/css';
|
||||||
|
const variants = styleVariants({
|
||||||
|
primary: {
|
||||||
|
margin: '1rem',
|
||||||
|
padding: '0.5rem',
|
||||||
|
backgroundColor: 'blue',
|
||||||
|
color: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
margin: '0.8rem',
|
||||||
|
padding: '0.4rem',
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
color: 'black',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
@ -18,9 +18,10 @@ import { processStyleNode } from './style-node-processor.js';
|
||||||
* @returns An object with visitor functions for the ESLint rule.
|
* @returns An object with visitor functions for the ESLint rule.
|
||||||
*
|
*
|
||||||
* This function sets up visitors for the following cases:
|
* This function sets up visitors for the following cases:
|
||||||
* 1. Style-related functions: 'style', 'styleVariants', 'createVar', 'createTheme', 'createThemeContract'
|
* 1. The fontFace and globalFontFace functions.
|
||||||
* 2. The 'globalStyle' function
|
* 2. Style-related functions: 'keyframes', 'style', 'styleVariants'.
|
||||||
* 3. The 'recipe' function
|
* 3. The 'globalStyle' and 'globalKeyframes' function
|
||||||
|
* 4. The 'recipe' function
|
||||||
*
|
*
|
||||||
* Each visitor applies the appropriate ordering strategy to the style objects in these function calls.
|
* Each visitor applies the appropriate ordering strategy to the style objects in these function calls.
|
||||||
*/
|
*/
|
||||||
|
|
@ -80,11 +81,7 @@ export const createNodeVisitors = (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle style-related functions
|
// Handle style-related functions
|
||||||
if (
|
if (['keyframes', 'style', 'styleVariants'].includes(node.callee.name)) {
|
||||||
['createThemeContract', 'createVar', 'createTheme', 'keyframes', 'style', 'styleVariants'].includes(
|
|
||||||
node.callee.name,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (node.arguments.length > 0) {
|
if (node.arguments.length > 0) {
|
||||||
const styleArguments = node.arguments[0];
|
const styleArguments = node.arguments[0];
|
||||||
processStyleNode(ruleContext, styleArguments as TSESTree.Node, processProperty);
|
processStyleNode(ruleContext, styleArguments as TSESTree.Node, processProperty);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import customOrderRule from './css-rules/custom-order/rule-definition.js';
|
||||||
export const vanillaExtract = {
|
export const vanillaExtract = {
|
||||||
meta: {
|
meta: {
|
||||||
name: '@antebudimir/eslint-plugin-vanilla-extract',
|
name: '@antebudimir/eslint-plugin-vanilla-extract',
|
||||||
version: '1.4.0',
|
version: '1.4.1',
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'alphabetical-order': alphabeticalOrderRule,
|
'alphabetical-order': alphabeticalOrderRule,
|
||||||
|
|
|
||||||
31
vitest.config.mjs
Normal file
31
vitest.config.mjs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
reporter: ['html', 'json', 'text'],
|
||||||
|
reportsDirectory: './coverage/vitest-reports',
|
||||||
|
// include: ['src/**/rule-definition.ts'],
|
||||||
|
include: ['src/**/*.ts', '!src/**/*.test.ts', '!src/**/__tests__/**'],
|
||||||
|
// exclude: [
|
||||||
|
// 'src/**/*.css.ts',
|
||||||
|
// 'src/**/*.test.ts',
|
||||||
|
// 'src/**/*constants.ts',
|
||||||
|
// 'src/**/*index.ts',
|
||||||
|
// // Exclude all icon directories and their contents
|
||||||
|
// 'src/components/common/icons/**',
|
||||||
|
// // But include the CheckboxIcon component
|
||||||
|
// '!src/components/common/icons/checkbox-icon/CheckboxIcon.tsx',
|
||||||
|
// ],
|
||||||
|
},
|
||||||
|
reporters: [
|
||||||
|
'default',
|
||||||
|
['json', { outputFile: './coverage/vitest-results/vitest-results.json' }],
|
||||||
|
['junit', { outputFile: './coverage/vitest-results/vitest-results.xml' }],
|
||||||
|
],
|
||||||
|
environment: 'node',
|
||||||
|
include: ['src/**/*.test.ts'],
|
||||||
|
globals: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue