UNPKG

@antebudimir/eslint-plugin-vanilla-extract

Version:

Comprehensive ESLint plugin for vanilla-extract with CSS property ordering, style validation, and best practices enforcement. Supports alphabetical, concentric and custom CSS ordering, auto-fixing, and zero-runtime safety.

334 lines (325 loc) 8.12 kB
import tsParser from '@typescript-eslint/parser'; import { run } from 'eslint-vitest-rule-tester'; import noZeroUnitRule from '../rule-definition.js'; run({ name: 'vanilla-extract/no-zero-unit', rule: noZeroUnitRule, languageOptions: { parser: tsParser, parserOptions: { ecmaVersion: 2022, sourceType: 'module', }, }, valid: [ { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0', padding: 0, width: '100%', }); `, }, { code: ` import { recipe } from '@vanilla-extract/css'; const myRecipe = recipe({ base: { margin: '0', padding: 0, }, variants: { size: { small: { height: '0', width: '10px', }, }, }, }); `, }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ ...spreadProps, margin: 0, '@media': { '0rem': '0' // Key shouldn't be checked } }); `, name: 'should ignore spread elements and object keys', }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: \`0\${someUnit}\`, // Template literal padding: someVariable }); `, name: 'should ignore non-literal values', }, { code: ` import { globalStyle } from '@vanilla-extract/css'; const callExpression = someObject.fontFace({ src: '...' }); // Non-Identifier callee `, name: 'should ignore member expression callees', }, { code: ` import { fontFace } from '@vanilla-extract/css'; fontFace(); // Missing arguments `, name: 'should handle missing fontFace arguments', }, { code: ` import { globalFontFace } from '@vanilla-extract/css'; globalFontFace('my-font'); // Missing style argument `, name: 'should handle missing globalFontFace style argument', }, ], invalid: [ { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0px', padding: '0rem', }); `, errors: [{ messageId: 'noZeroUnit' }, { messageId: 'noZeroUnit' }], output: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0', padding: '0', }); `, }, { code: ` import { recipe } from '@vanilla-extract/css'; const myRecipe = recipe({ base: { margin: '0px', }, variants: { size: { small: { height: '0vh', }, }, }, }); `, errors: [{ messageId: 'noZeroUnit' }, { messageId: 'noZeroUnit' }], output: ` import { recipe } from '@vanilla-extract/css'; const myRecipe = recipe({ base: { margin: '0', }, variants: { size: { small: { height: '0', }, }, }, }); `, }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0px', '@media': { '(min-width: 768px)': { padding: '0rem' } } }); `, errors: 2, output: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0', '@media': { '(min-width: 768px)': { padding: '0' } } }); `, name: 'should handle nested media queries', }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ '::before': { content: '""', margin: '0px' } }); `, errors: 1, output: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ '::before': { content: '""', margin: '0' } }); `, name: 'should handle pseudo-elements', }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0px', nested: { object: { padding: '0rem', deeper: { width: '0%' } } } }); `, errors: 3, output: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0', nested: { object: { padding: '0', deeper: { width: '0' } } } }); `, name: 'should handle multiple levels of nesting', }, { code: ` import { fontFace, globalFontFace } from '@vanilla-extract/css'; fontFace({ src: '...', lineGap: '0rem' }); globalFontFace('my-font', { src: '...', sizeAdjust: '0%' }); `, errors: 2, output: ` import { fontFace, globalFontFace } from '@vanilla-extract/css'; fontFace({ src: '...', lineGap: '0' }); globalFontFace('my-font', { src: '...', sizeAdjust: '0' }); `, name: 'should handle fontFace and globalFontFace arguments', }, // 0deg is valid (deg isn't in our unit check) { code: ` import { globalKeyframes, globalStyle } from '@vanilla-extract/css'; globalKeyframes('spin', { '0%': { transform: 'rotate(0deg)' }, '100%': { transform: 'rotate(0deg)' } }); globalStyle('html', { margin: '0px', padding: '0rem' }); `, errors: 2, output: ` import { globalKeyframes, globalStyle } from '@vanilla-extract/css'; globalKeyframes('spin', { '0%': { transform: 'rotate(0deg)' }, '100%': { transform: 'rotate(0deg)' } }); globalStyle('html', { margin: '0', padding: '0' }); `, name: 'should handle globalKeyframes and globalStyle arguments', }, { code: ` import { globalStyle } from '@vanilla-extract/css'; globalStyle('html', { '@media': { '(min-width: 768px)': { margin: '0px' } } }); `, errors: 1, output: ` import { globalStyle } from '@vanilla-extract/css'; globalStyle('html', { '@media': { '(min-width: 768px)': { margin: '0' } } }); `, name: 'should handle nested globalStyle arguments', }, { code: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '-0px', padding: '-0rem', top: '-0vh', left: '-0%', }); `, errors: [ { messageId: 'noZeroUnit' }, { messageId: 'noZeroUnit' }, { messageId: 'noZeroUnit' }, { messageId: 'noZeroUnit' }, ], output: ` import { style } from '@vanilla-extract/css'; const myStyle = style({ margin: '0', padding: '0', top: '0', left: '0', }); `, name: 'should convert negative zero with units to simple zero', }, ], });