mirror of
https://github.com/antebudimir/eslint-plugin-vanilla-extract.git
synced 2026-04-15 16:27:25 +00:00
Merge 3c223c2909 into 62b1844b44
This commit is contained in:
commit
108d1ba5c8
10 changed files with 482 additions and 7 deletions
116
README.md
116
README.md
|
|
@ -304,6 +304,36 @@ export default [
|
||||||
|
|
||||||
> **Note:** Remember to enable only one ordering rule at a time. See the "Important" section above for details on switching between ordering rules.
|
> **Note:** Remember to enable only one ordering rule at a time. See the "Important" section above for details on switching between ordering rules.
|
||||||
|
|
||||||
|
### Global Settings (Recommended for shared wrappers)
|
||||||
|
|
||||||
|
If you use imported wrapper functions across multiple ordering rules, configure them once in ESLint `settings`.
|
||||||
|
All ordering rules (`alphabetical-order`, `concentric-order`, `custom-order`) read this value.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { defineConfig } from 'eslint/config';
|
||||||
|
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
files: ['**/*.css.ts'],
|
||||||
|
plugins: {
|
||||||
|
'vanilla-extract': vanillaExtract,
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle', 'layerStyle'],
|
||||||
|
recipe: ['componentRecipe'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...vanillaExtract.configs.recommended.rules,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure wrapper names only via ESLint `settings` (`style`, `recipe`).
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
### vanilla-extract/alphabetical-order
|
### vanilla-extract/alphabetical-order
|
||||||
|
|
@ -336,6 +366,32 @@ export const myStyle = style({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Global setting: `settings['vanilla-extract'].style`
|
||||||
|
|
||||||
|
`vanilla-extract/alphabetical-order` reads wrapper names from global ESLint settings.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { defineConfig } from 'eslint/config';
|
||||||
|
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
files: ['**/*.css.ts'],
|
||||||
|
plugins: {
|
||||||
|
'vanilla-extract': vanillaExtract,
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'vanilla-extract/alphabetical-order': 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
### vanilla-extract/concentric-order
|
### vanilla-extract/concentric-order
|
||||||
|
|
||||||
This rule enforces that CSS properties in vanilla-extract style objects follow the [concentric CSS](#concentric-css-model) ordering pattern, which organizes properties from outside to inside.
|
This rule enforces that CSS properties in vanilla-extract style objects follow the [concentric CSS](#concentric-css-model) ordering pattern, which organizes properties from outside to inside.
|
||||||
|
|
@ -364,6 +420,33 @@ export const myStyle = style({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Global setting: `settings['vanilla-extract'].style`
|
||||||
|
|
||||||
|
Use this setting when style wrappers are imported from local modules (for example `componentStyle`, `layerStyle`).
|
||||||
|
If a wrapper function name is listed, the rule treats calls to that function like `style(...)` calls.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { defineConfig } from 'eslint/config';
|
||||||
|
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
files: ['**/*.css.ts'],
|
||||||
|
plugins: {
|
||||||
|
'vanilla-extract': vanillaExtract,
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle', 'layerStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'vanilla-extract/concentric-order': 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
### vanilla-extract/custom-order
|
### vanilla-extract/custom-order
|
||||||
|
|
||||||
The `vanilla-extract/custom-order` rule enables you to enforce a custom ordering of CSS properties in your
|
The `vanilla-extract/custom-order` rule enables you to enforce a custom ordering of CSS properties in your
|
||||||
|
|
@ -388,6 +471,39 @@ To configure the rule, add it to your ESLint configuration file with your desire
|
||||||
`groups` array to include any number of available CSS property groups you want to enforce, with a minimum of one group
|
`groups` array to include any number of available CSS property groups you want to enforce, with a minimum of one group
|
||||||
required.
|
required.
|
||||||
|
|
||||||
|
#### Global setting: `settings['vanilla-extract'].style`
|
||||||
|
|
||||||
|
`vanilla-extract/custom-order` also reads `style` from global settings together with
|
||||||
|
`groupOrder` and `sortRemainingProperties`.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { defineConfig } from 'eslint/config';
|
||||||
|
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
files: ['**/*.css.ts'],
|
||||||
|
plugins: {
|
||||||
|
'vanilla-extract': vanillaExtract,
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'vanilla-extract/custom-order': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
groupOrder: ['font', 'dimensions', 'margin', 'padding', 'position', 'border'],
|
||||||
|
sortRemainingProperties: 'alphabetical',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// ❌ Incorrect (Unordered)
|
// ❌ Incorrect (Unordered)
|
||||||
import { style } from '@vanilla-extract/css';
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,35 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Imported local recipe wrapper with global settings recipe
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentRecipe } from './component-recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
recipe: ['componentRecipe'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentRecipe } from './component-recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -195,5 +195,69 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Imported local wrapper with global settings style
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Both vanilla style and configured wrapper should be linted (wrapper augments, not replaces)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
display: 'flex',
|
||||||
|
color: 'white',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'alphabeticalOrder' }, { messageId: 'alphabeticalOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
color: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -97,5 +97,39 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Imported local recipe wrapper with global settings recipe
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentRecipe } from './recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
recipe: ['componentRecipe'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentRecipe } from './recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -213,5 +213,69 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Imported local wrapper with global settings style
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Both vanilla style and configured wrapper should be linted (wrapper augments, not replaces)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './layer-style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
color: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './layer-style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
display: 'flex',
|
||||||
|
color: 'white',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -207,5 +207,46 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
// Imported local recipe wrapper with global settings recipe
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentRecipe } from './component-recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
recipe: ['componentRecipe'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentRecipe } from './component-recipe.css.js';
|
||||||
|
|
||||||
|
const myRecipe = componentRecipe({
|
||||||
|
base: {
|
||||||
|
width: '100%',
|
||||||
|
margin: 0,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'white'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -375,5 +375,81 @@ run({
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Imported local wrapper with global settings style
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const myStyle = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Both vanilla style and configured wrapper should be linted (wrapper augments, not replaces)
|
||||||
|
{
|
||||||
|
code: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
color: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
padding: '18px',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
groupOrder: ['dimensions', 'margin', 'font', 'border', 'boxShadow'],
|
||||||
|
sortRemainingProperties: 'concentric',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
'vanilla-extract': {
|
||||||
|
style: ['componentStyle'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors: [{ messageId: 'incorrectOrder' }, { messageId: 'incorrectOrder' }],
|
||||||
|
output: `
|
||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
import { componentStyle } from './style.css.js';
|
||||||
|
|
||||||
|
export const a = style({
|
||||||
|
display: 'flex',
|
||||||
|
color: 'white',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const b = componentStyle({
|
||||||
|
backgroundColor: 'black',
|
||||||
|
padding: '18px',
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { enforceFontFaceOrder } from './font-face-property-order-enforcer.js';
|
||||||
import { ReferenceTracker, createReferenceTrackingVisitor } from './reference-tracker.js';
|
import { ReferenceTracker, createReferenceTrackingVisitor } from './reference-tracker.js';
|
||||||
import { processStyleNode } from './style-node-processor.js';
|
import { processStyleNode } from './style-node-processor.js';
|
||||||
import type { SortRemainingProperties } from '../concentric-order/types.js';
|
import type { SortRemainingProperties } from '../concentric-order/types.js';
|
||||||
import type { OrderingStrategy } from '../types.js';
|
import type { OrderingStrategy, VanillaExtractPluginSettings } from '../types.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ESLint rule listener with visitors for style-related function calls using reference tracking.
|
* Creates an ESLint rule listener with visitors for style-related function calls using reference tracking.
|
||||||
|
|
@ -28,7 +28,8 @@ export const createNodeVisitors = (
|
||||||
userDefinedGroupOrder?: string[],
|
userDefinedGroupOrder?: string[],
|
||||||
sortRemainingProperties?: SortRemainingProperties,
|
sortRemainingProperties?: SortRemainingProperties,
|
||||||
): Rule.RuleListener => {
|
): Rule.RuleListener => {
|
||||||
const tracker = new ReferenceTracker();
|
const wrapperSettings = resolveWrapperSettings(ruleContext);
|
||||||
|
const tracker = new ReferenceTracker(wrapperSettings);
|
||||||
const trackingVisitor = createReferenceTrackingVisitor(tracker);
|
const trackingVisitor = createReferenceTrackingVisitor(tracker);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -105,6 +106,21 @@ export const createNodeVisitors = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveWrapperSettings = (
|
||||||
|
ruleContext: Rule.RuleContext,
|
||||||
|
): {
|
||||||
|
style: string[];
|
||||||
|
recipe: string[];
|
||||||
|
} => {
|
||||||
|
const pluginSettings = (ruleContext.settings?.['vanilla-extract'] ??
|
||||||
|
{}) as VanillaExtractPluginSettings;
|
||||||
|
|
||||||
|
return {
|
||||||
|
style: pluginSettings.style ?? [],
|
||||||
|
recipe: pluginSettings.recipe ?? [],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to process style ordering for style-related functions
|
* Helper function to process style ordering for style-related functions
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,10 @@ export class ReferenceTracker {
|
||||||
private imports: Map<string, ImportReference> = new Map();
|
private imports: Map<string, ImportReference> = new Map();
|
||||||
private trackedFunctions: TrackedFunctions;
|
private trackedFunctions: TrackedFunctions;
|
||||||
private wrapperFunctions: Map<string, WrapperFunctionInfo> = new Map(); // wrapper function name -> detailed info
|
private wrapperFunctions: Map<string, WrapperFunctionInfo> = new Map(); // wrapper function name -> detailed info
|
||||||
|
private style: Set<string>;
|
||||||
|
private recipe: Set<string>;
|
||||||
|
|
||||||
constructor() {
|
constructor(options?: { style?: string[]; recipe?: string[] }) {
|
||||||
this.trackedFunctions = {
|
this.trackedFunctions = {
|
||||||
styleFunctions: new Set(),
|
styleFunctions: new Set(),
|
||||||
recipeFunctions: new Set(),
|
recipeFunctions: new Set(),
|
||||||
|
|
@ -36,6 +38,8 @@ export class ReferenceTracker {
|
||||||
globalFunctions: new Set(),
|
globalFunctions: new Set(),
|
||||||
keyframeFunctions: new Set(),
|
keyframeFunctions: new Set(),
|
||||||
};
|
};
|
||||||
|
this.style = new Set(options?.style ?? []);
|
||||||
|
this.recipe = new Set(options?.recipe ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -44,25 +48,38 @@ export class ReferenceTracker {
|
||||||
processImportDeclaration(node: TSESTree.ImportDeclaration): void {
|
processImportDeclaration(node: TSESTree.ImportDeclaration): void {
|
||||||
const source = node.source.value;
|
const source = node.source.value;
|
||||||
|
|
||||||
// Check if this is a vanilla-extract import
|
if (typeof source !== 'string') {
|
||||||
if (typeof source !== 'string' || !this.isVanillaExtractSource(source)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isVanillaExtractImport = this.isVanillaExtractSource(source);
|
||||||
|
|
||||||
node.specifiers.forEach((specifier) => {
|
node.specifiers.forEach((specifier) => {
|
||||||
if (specifier.type === 'ImportSpecifier') {
|
if (specifier.type === 'ImportSpecifier') {
|
||||||
const importedName =
|
const importedName =
|
||||||
specifier.imported.type === 'Identifier' ? specifier.imported.name : specifier.imported.value;
|
specifier.imported.type === 'Identifier' ? specifier.imported.name : specifier.imported.value;
|
||||||
const localName = specifier.local.name;
|
const localName = specifier.local.name;
|
||||||
|
const customWrapper = this.getCustomWrapper(importedName, localName);
|
||||||
|
|
||||||
|
let trackedImportName: string;
|
||||||
|
|
||||||
|
if (isVanillaExtractImport) {
|
||||||
|
trackedImportName = importedName;
|
||||||
|
} else {
|
||||||
|
if (!customWrapper) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trackedImportName = customWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
const reference: ImportReference = {
|
const reference: ImportReference = {
|
||||||
source,
|
source,
|
||||||
importedName,
|
importedName: trackedImportName,
|
||||||
localName,
|
localName,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.imports.set(localName, reference);
|
this.imports.set(localName, reference);
|
||||||
this.categorizeFunction(localName, importedName);
|
this.categorizeFunction(localName, trackedImportName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -276,6 +293,18 @@ export class ReferenceTracker {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCustomWrapper(importedName: string, localName: string): 'style' | 'recipe' | null {
|
||||||
|
if (this.style.has(importedName) || this.style.has(localName)) {
|
||||||
|
return 'style';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.recipe.has(importedName) || this.recipe.has(localName)) {
|
||||||
|
return 'recipe';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private categorizeFunction(localName: string, importedName: string): void {
|
private categorizeFunction(localName: string, importedName: string): void {
|
||||||
switch (importedName) {
|
switch (importedName) {
|
||||||
case 'style':
|
case 'style':
|
||||||
|
|
|
||||||
|
|
@ -1 +1,6 @@
|
||||||
export type OrderingStrategy = 'alphabetical' | 'concentric' | 'userDefinedGroupOrder';
|
export type OrderingStrategy = 'alphabetical' | 'concentric' | 'userDefinedGroupOrder';
|
||||||
|
|
||||||
|
export interface VanillaExtractPluginSettings {
|
||||||
|
style?: string[];
|
||||||
|
recipe?: string[];
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue