@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.
120 lines (119 loc) • 5.32 kB
JavaScript
import { createThemeTokenVisitors } from './theme-token-visitor-creator.js';
const rule = {
meta: {
type: 'suggestion',
docs: {
description: 'require theme tokens instead of hard-coded values for colors, spacing, font sizes, and border radius',
recommended: false,
},
fixable: 'code',
// Suggestions are reported from helper modules, so static analysis in this file can’t detect them; disable the false positive.
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions
hasSuggestions: true,
schema: [
{
type: 'object',
properties: {
themeContracts: {
type: 'array',
items: {
type: 'string',
},
description: 'Array of theme contract file paths to analyze for intelligent token suggestions',
},
checkColors: {
type: 'boolean',
description: 'Check for hard-coded color values',
default: true,
},
checkSpacing: {
type: 'boolean',
description: 'Check for hard-coded spacing values',
default: true,
},
checkFontSizes: {
type: 'boolean',
description: 'Check for hard-coded font size values',
default: true,
},
checkBorderRadius: {
type: 'boolean',
description: 'Check for hard-coded border radius values',
default: true,
},
checkBorderWidths: {
type: 'boolean',
description: 'Check for hard-coded border width values',
default: true,
},
checkShadows: {
type: 'boolean',
description: 'Check for hard-coded shadow values',
default: true,
},
checkZIndex: {
type: 'boolean',
description: 'Check for hard-coded z-index values',
default: true,
},
checkOpacity: {
type: 'boolean',
description: 'Check for hard-coded opacity values',
default: true,
},
checkFontWeights: {
type: 'boolean',
description: 'Check for hard-coded font weight values',
default: true,
},
checkTransitions: {
type: 'boolean',
description: 'Check for hard-coded transition and animation values',
default: true,
},
allowedValues: {
type: 'array',
items: {
type: 'string',
},
description: 'Array of values that are allowed (e.g., "0", "auto", "100%")',
},
allowedProperties: {
type: 'array',
items: {
type: 'string',
},
description: 'Array of CSS properties to skip checking (supports both camelCase and kebab-case)',
},
autoFix: {
type: 'boolean',
description: 'Enable auto-fix for unambiguous token replacements',
default: false,
},
remBase: {
type: 'number',
description: 'Base font size for rem() calculations (default: 16)',
default: 16,
},
checkHelperFunctions: {
type: 'boolean',
description: 'Check helper function calls like rem(48) and suggest theme tokens (default: false)',
default: false,
},
},
additionalProperties: false,
},
],
messages: {
hardCodedValueWithToken: "Hard-coded {{property}} value '{{value}}' detected. Use theme token: {{tokenPath}}",
hardCodedValueGeneric: "Hard-coded {{property}} value '{{value}}' detected. Consider using a theme token from {{categoryHint}}",
hardCodedValueNoContract: "Hard-coded {{property}} value '{{value}}' detected. Consider using theme tokens for {{category}} values",
replaceWithToken: 'Replace with {{tokenPath}}',
},
},
create(context) {
const options = context.options[0] || {};
return createThemeTokenVisitors(context, options);
},
};
export default rule;