Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions packages/@stylexjs/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ their **suggested replacements**.
This rule helps to sort the StyleX property keys according to
[property priorities](https://github.com/facebook/stylex/blob/main/packages/shared/src/utils/property-priorities.js).

#### Config options

```json
{
"validImports": ["stylex", "@stylexjs/stylex"]
}
```

### stylex/stylex-valid-shorthands

This ESLint rule enforces the use of individual longhand CSS properties in place
Expand Down Expand Up @@ -98,7 +106,8 @@ This rule has a few custom config options that can be set.
```js
{
allowImportant: false, // Whether `!important` is allowed
preferInline: false // Whether the expansion uses logical direction properties over physical
preferInline: false, // Whether the expansion uses logical direction properties over physical
validImports: ['stylex', '@stylexjs/stylex']
}
```

Expand All @@ -125,7 +134,8 @@ using `stylex.defineVars()`.

```json
{
"themeFileExtension": ".stylex.js" // default, can be customized
"themeFileExtension": ".stylex.js", // default, can be customized
"validImports": ["stylex", "@stylexjs/stylex"]
}
```

Expand All @@ -134,11 +144,27 @@ using `stylex.defineVars()`.
This rule flags unused styles created with `stylex.create(...)`. If a style key
is defined but never used, the rule auto-strips them from the create call.

#### Config options

```json
{
"validImports": ["stylex", "@stylexjs/stylex"]
}
```

### `stylex-no-legacy-contextual-styles`

This rule flags usages of the original media query/pseudo class syntax that
wraps multiple property values within a single @-rule or pseudo class like this:

#### Config options

```json
{
"validImports": ["stylex", "@stylexjs/stylex"]
}
```

```js
const styles = stylex.create({
root: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,26 @@ const ruleTester = new RuleTester({
});

const invalidFilenameWithDefineVars =
'Files that export StyleX variables defined with `stylex.defineVars()` must end with the `.stylex.jsx` or `.stylex.tsx` extension.';
'Files that export StyleX variables defined with `defineVars()` must end with the `.stylex.jsx` or `.stylex.tsx` extension.';
const invalidFilenameWithoutDefineVars =
'Only StyleX variables defined with `stylex.defineVars()` can be exported from a file with the `.stylex.jsx` or `.stylex.tsx` extension.';
'Only StyleX variables defined with `defineVars()` can be exported from a file with the `.stylex.jsx` or `.stylex.tsx` extension.';
const invalidExportWithDefineVars =
'Files that export `stylex.defineVars()` must not export anything else.';
'Files that export `defineVars()` must not export anything else.';

ruleTester.run('stylex-enforce-extension', rule.default, {
valid: [
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.stylex.jsx',
},
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.stylex.tsx',
},
{
Expand All @@ -40,12 +46,18 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
filename: 'testComponent.tsx',
},
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.custom.jsx',
options: [{ themeFileExtension: '.custom.jsx' }],
},
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.custom.tsx',
options: [{ themeFileExtension: '.custom.jsx' }],
},
Expand All @@ -56,21 +68,42 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
},
{
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({ color: 'red' });
export default stylex.defineVars({ background: 'blue' });
`,
filename: 'myComponent.stylex.jsx',
},
{
options: [{ validImports: ['custom-stylex'] }],
code: `
import * as stylex from 'custom-stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.stylex.jsx',
},
{
options: [{ validImports: [{ from: 'a', as: 'css' }] }],
code: `
import { css } from 'a';
export const vars = css.defineVars({});
`,
filename: 'testComponent.stylex.jsx',
},
],

invalid: [
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.jsx',
errors: [{ message: invalidFilenameWithDefineVars }],
},
{
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({ color: 'red' });
export const somethingElse = someFunction();
export default stylex.defineVars({ background: 'blue' });
Expand All @@ -83,6 +116,7 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
},
{
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = someFunction();
export const somethingElse = someFunction();
export default stylex.defineVars({ background: 'blue' });
Expand All @@ -96,6 +130,7 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
},
{
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({
color: 'blue',
});
Expand All @@ -106,6 +141,7 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
},
{
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({
color: 'red',
});
Expand All @@ -115,7 +151,10 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
errors: [{ message: invalidExportWithDefineVars }],
},
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.tsx',
errors: [{ message: invalidFilenameWithDefineVars }],
},
Expand All @@ -130,13 +169,16 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
errors: [{ message: invalidFilenameWithoutDefineVars }],
},
{
code: 'export const vars = stylex.defineVars({});',
code: `
import * as stylex from '@stylexjs/stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.jsx',
options: [{ themeFileExtension: '.custom.jsx' }],
errors: [
{
message:
'Files that export StyleX variables defined with `stylex.defineVars()` must end with the `.custom.jsx` or `.custom.tsx` extension.',
'Files that export StyleX variables defined with `defineVars()` must end with the `.custom.jsx` or `.custom.tsx` extension.',
},
],
},
Expand All @@ -147,7 +189,57 @@ ruleTester.run('stylex-enforce-extension', rule.default, {
errors: [
{
message:
'Only StyleX variables defined with `stylex.defineVars()` can be exported from a file with the `.custom.jsx` or `.custom.tsx` extension.',
'Only StyleX variables defined with `defineVars()` can be exported from a file with the `.custom.jsx` or `.custom.tsx` extension.',
},
],
},
{
options: [{ validImports: ['custom-stylex'] }],
code: `
import * as stylex from 'custom-stylex';
export const vars = stylex.defineVars({});
`,
filename: 'testComponent.jsx',
errors: [
{
message:
'Files that export StyleX variables defined with `defineVars()` must end with the `.stylex.jsx` or `.stylex.tsx` extension.',
},
],
},
{
options: [{ validImports: [{ from: 'a', as: 'css' }] }],
code: `
import { css } from 'a';
export const vars = css.defineVars({});
`,
filename: 'testComponent.jsx',
errors: [
{
message:
'Files that export StyleX variables defined with `defineVars()` must end with the `.stylex.jsx` or `.stylex.tsx` extension.',
},
],
},
{
options: [{ validImports: ['custom-stylex'] }],
code: 'export const somethingElse = {};',
filename: 'testComponent.stylex.jsx',
errors: [
{
message:
'Only StyleX variables defined with `defineVars()` can be exported from a file with the `.stylex.jsx` or `.stylex.tsx` extension.',
},
],
},
{
options: [{ validImports: [{ from: 'a', as: 'css' }] }],
code: 'export const somethingElse = {};',
filename: 'testComponent.stylex.jsx',
errors: [
{
message:
'Only StyleX variables defined with `defineVars()` can be exported from a file with the `.stylex.jsx` or `.stylex.tsx` extension.',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ eslintTester.run('stylex-no-legacy-contextual-styles', rule.default, {
valid: [
{
code: `
import stylex from 'stylex';
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
main: {
'::placeholder': {
Expand All @@ -44,11 +44,44 @@ eslintTester.run('stylex-no-legacy-contextual-styles', rule.default, {
});
`,
},
{
options: [{ validImports: ['custom-stylex'] }],
code: `
import * as stylex from 'custom-stylex';
const styles = stylex.create({
main: {
'::placeholder': {
color: '#999',
},
width: {
default: '100%',
'@media (min-width: 600px)': {
default: '50%',
'@media screen': '40%'
},
}
},
});
`,
},
{
options: [{ validImports: [{ from: 'a', as: 'css' }] }],
code: `
import { css } from 'a';
const styles = css.create({
main: {
'::placeholder': {
color: '#999',
},
},
});
`,
},
],
invalid: [
{
code: `
import stylex from 'stylex';
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
main: {
width: '100%',
Expand Down Expand Up @@ -84,5 +117,45 @@ eslintTester.run('stylex-no-legacy-contextual-styles', rule.default, {
},
],
},
{
options: [{ validImports: ['custom-stylex'] }],
code: `
import * as stylex from 'custom-stylex';
const styles = stylex.create({
main: {
width: '100%',
':hover': {
width: '50%',
}
}
});
`,
errors: [
{
message:
'This pseudo class syntax is deprecated. Use the new syntax specified here: https://stylexjs.com/docs/learn/styling-ui/defining-styles/#pseudo-classes',
},
],
},
{
options: [{ validImports: [{ from: 'a', as: 'css' }] }],
code: `
import { css } from 'a';
const styles = css.create({
main: {
width: '100%',
'@media (max-width: 600px)': {
width: '50%',
}
}
});
`,
errors: [
{
message:
'This media query syntax is deprecated. Use the new syntax specified here: https://stylexjs.com/docs/learn/styling-ui/defining-styles/#media-queries-and-other--rules',
},
],
},
],
});
Loading