Skip to content

Commit e61a47f

Browse files
committed
[eslint-plugin] order pseudo-classes and stylex.when selectors according to the priorities
1 parent ed606a5 commit e61a47f

File tree

12 files changed

+233
-18
lines changed

12 files changed

+233
-18
lines changed

.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ suppress_type=$FlowFixMe
2828
suppress_type=$FlowTODO
2929
module.name_mapper='^@stylexjs/babel-plugin$' -> '<PROJECT_ROOT>/packages/@stylexjs/babel-plugin/src/index.js'
3030
module.name_mapper='^@stylexjs/stylex$' -> '<PROJECT_ROOT>/packages/@stylexjs/stylex/src/stylex.js'
31+
module.name_mapper='^@stylexjs/shared$' -> '<PROJECT_ROOT>/packages/@stylexjs/shared/src/index.js'
3132
module.name_mapper='^style-value-parser$' -> '<PROJECT_ROOT>/packages/style-value-parser/src/index.js'
3233
; type-stubs
3334
module.system.node.resolve_dirname=flow_modules

packages/@stylexjs/babel-plugin/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@babel/types": "^7.26.8",
2323
"@dual-bundle/import-meta-resolve": "^4.1.0",
2424
"@stylexjs/stylex": "0.16.2",
25+
"@stylexjs/shared": "0.16.2",
2526
"postcss-value-parser": "^4.1.0"
2627
},
2728
"devDependencies": {

packages/@stylexjs/babel-plugin/src/shared/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
PSEUDO_CLASS_PRIORITIES as _PSEUDO_CLASS_PRIORITIES,
4242
AT_RULE_PRIORITIES as _AT_RULE_PRIORITIES,
4343
PSEUDO_ELEMENT_PRIORITY as _PSEUDO_ELEMENT_PRIORITY,
44-
} from './utils/property-priorities';
44+
} from '@stylexjs/shared';
4545

4646
export * as types from './types';
4747
export * as when from './when/when';

packages/@stylexjs/babel-plugin/src/shared/utils/generate-css-rule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { defaultOptions } from './default-options';
1414

1515
import generateLtr from '../physical-rtl/generate-ltr';
1616
import generateRtl from '../physical-rtl/generate-rtl';
17-
import getPriority from './property-priorities';
17+
import { getPriority } from '@stylexjs/shared';
1818

1919
const THUMB_VARIANTS = [
2020
'::-webkit-slider-thumb',

packages/@stylexjs/eslint-plugin/__tests__/stylex-sort-keys-test.js

Lines changed: 131 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,9 +1204,71 @@ eslintTester.run('stylex-sort-keys', rule.default, {
12041204
import { create, when } from '@stylexjs/stylex';
12051205
const styles = create({
12061206
base: {
1207+
display: 'flex',
1208+
width: {
1209+
':hover': 10,
1210+
default: 20,
1211+
},
1212+
},
1213+
});
1214+
`,
1215+
output: `
1216+
import { create, when } from '@stylexjs/stylex';
1217+
const styles = create({
1218+
base: {
1219+
display: 'flex',
1220+
width: {
1221+
default: 20,
1222+
':hover': 10,
1223+
},
1224+
},
1225+
});
1226+
`,
1227+
errors: [
1228+
{
1229+
message: 'StyleX property key "default" should be above ":hover"',
1230+
},
1231+
],
1232+
},
1233+
{
1234+
code: `
1235+
import { create, when } from '@stylexjs/stylex';
1236+
const styles = create({
1237+
base: {
1238+
display: 'flex',
12071239
width: {
1208-
[when.siblingAfter(":active")]: 30,
1209-
[when.descendant(":focus")]: 20,
1240+
':focus': 10,
1241+
':hover': 20,
1242+
},
1243+
},
1244+
});
1245+
`,
1246+
output: `
1247+
import { create, when } from '@stylexjs/stylex';
1248+
const styles = create({
1249+
base: {
1250+
display: 'flex',
1251+
width: {
1252+
':hover': 20,
1253+
':focus': 10,
1254+
},
1255+
},
1256+
});
1257+
`,
1258+
errors: [
1259+
{
1260+
message: 'StyleX property key ":hover" should be above ":focus"',
1261+
},
1262+
],
1263+
},
1264+
{
1265+
code: `
1266+
import { create, when } from '@stylexjs/stylex';
1267+
const styles = create({
1268+
base: {
1269+
width: {
1270+
[when.siblingAfter(':active')]: 30,
1271+
[when.descendant(':focus')]: 20,
12101272
},
12111273
display: 'flex',
12121274
},
@@ -1218,17 +1280,82 @@ eslintTester.run('stylex-sort-keys', rule.default, {
12181280
base: {
12191281
display: 'flex',
12201282
width: {
1221-
[when.siblingAfter(":active")]: 30,
1222-
[when.descendant(":focus")]: 20,
1283+
[when.siblingAfter(':active')]: 30,
1284+
[when.descendant(':focus')]: 20,
12231285
},
12241286
},
12251287
});
12261288
`,
12271289
errors: [
1290+
{
1291+
message: 'StyleX property key ":focus" should be above ":active"',
1292+
},
12281293
{
12291294
message: 'StyleX property key "display" should be above "width"',
12301295
},
12311296
],
12321297
},
1298+
{
1299+
code: `
1300+
import { create, when } from '@stylexjs/stylex';
1301+
const styles = create({
1302+
base: {
1303+
display: 'flex',
1304+
width: {
1305+
[when.siblingAfter(':active')]: 30,
1306+
[when.descendant(':focus')]: 20,
1307+
},
1308+
},
1309+
});
1310+
`,
1311+
output: `
1312+
import { create, when } from '@stylexjs/stylex';
1313+
const styles = create({
1314+
base: {
1315+
display: 'flex',
1316+
width: {
1317+
[when.descendant(':focus')]: 20,
1318+
[when.siblingAfter(':active')]: 30,
1319+
},
1320+
},
1321+
});
1322+
`,
1323+
errors: [
1324+
{
1325+
message: 'StyleX property key ":focus" should be above ":active"',
1326+
},
1327+
],
1328+
},
1329+
{
1330+
code: `
1331+
import { create, when } from '@stylexjs/stylex';
1332+
const styles = create({
1333+
base: {
1334+
display: 'flex',
1335+
width: {
1336+
[when[api](\`:active\`)]: 30,
1337+
[when[api](\`:focus\`)]: 20,
1338+
},
1339+
},
1340+
});
1341+
`,
1342+
output: `
1343+
import { create, when } from '@stylexjs/stylex';
1344+
const styles = create({
1345+
base: {
1346+
display: 'flex',
1347+
width: {
1348+
[when[api](\`:focus\`)]: 20,
1349+
[when[api](\`:active\`)]: 30,
1350+
},
1351+
},
1352+
});
1353+
`,
1354+
errors: [
1355+
{
1356+
message: 'StyleX property key ":focus" should be above ":active"',
1357+
},
1358+
],
1359+
},
12331360
],
12341361
});

packages/@stylexjs/eslint-plugin/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"test": "jest --detectOpenHandles --coverage"
1717
},
1818
"dependencies": {
19+
"@stylexjs/shared": "0.16.2",
1920
"css-shorthand-expand": "^1.2.0",
2021
"micromatch": "^4.0.5",
2122
"postcss-value-parser": "^4.2.0"

packages/@stylexjs/eslint-plugin/src/utils/getPropertyName.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ function getStaticPropertyName(node: Node | ChainExpression): string | null {
7777
return prop.name;
7878
}
7979

80+
if (prop.type === 'CallExpression') {
81+
const arg = prop.arguments[0];
82+
if (arg) {
83+
return getStaticStringValue(arg);
84+
}
85+
}
86+
8087
return getStaticStringValue(prop);
8188
}
8289

packages/@stylexjs/eslint-plugin/src/utils/getPropertyPriorityAndType.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99

1010
'use strict';
1111

12+
import {
13+
PSEUDO_CLASS_PRIORITIES,
14+
AT_RULE_PRIORITIES,
15+
PSEUDO_ELEMENT_PRIORITY,
16+
} from '@stylexjs/shared';
17+
1218
type PriorityAndType = {
1319
priority: number,
1420
type:
@@ -1023,34 +1029,44 @@ export default function getPropertyPriorityAndType(
10231029
? ORDER_PRIORITIES[order].length - 1
10241030
: 0;
10251031

1026-
const AT_CONTAINER_PRIORITY = BASE_PRIORITY + 300;
1027-
const AT_MEDIA_PRIORITY = BASE_PRIORITY + 200;
1028-
const AT_SUPPORT_PRIORITY = BASE_PRIORITY + 30;
1029-
const PSEUDO_CLASS_PRIORITY = BASE_PRIORITY + 40;
1030-
const PSEUDO_ELEMENT_PRIORITY = BASE_PRIORITY + 5000;
1031-
10321032
if (key.startsWith('@supports')) {
1033-
return { priority: AT_SUPPORT_PRIORITY, type: 'atRule' };
1033+
return {
1034+
priority: BASE_PRIORITY + AT_RULE_PRIORITIES['@supports'],
1035+
type: 'atRule',
1036+
};
10341037
}
10351038

10361039
if (key.startsWith('::')) {
1037-
return { priority: PSEUDO_ELEMENT_PRIORITY, type: 'pseudoElement' };
1040+
return {
1041+
priority: BASE_PRIORITY + PSEUDO_ELEMENT_PRIORITY,
1042+
type: 'pseudoElement',
1043+
};
10381044
}
10391045

10401046
if (key.startsWith(':')) {
1041-
// TODO: Consider restoring pseudo-specific priorities
1047+
const prop =
1048+
key.startsWith(':') && key.includes('(')
1049+
? key.slice(0, key.indexOf('('))
1050+
: key;
1051+
10421052
return {
1043-
priority: PSEUDO_CLASS_PRIORITY,
1053+
priority: PSEUDO_CLASS_PRIORITIES[prop] ?? 40,
10441054
type: 'pseudoClass',
10451055
};
10461056
}
10471057

10481058
if (key.startsWith('@media')) {
1049-
return { priority: AT_MEDIA_PRIORITY, type: 'atRule' };
1059+
return {
1060+
priority: BASE_PRIORITY + AT_RULE_PRIORITIES['@media'],
1061+
type: 'atRule',
1062+
};
10501063
}
10511064

10521065
if (key.startsWith('@container')) {
1053-
return { priority: AT_CONTAINER_PRIORITY, type: 'atRule' };
1066+
return {
1067+
priority: BASE_PRIORITY + AT_RULE_PRIORITIES['@container'],
1068+
type: 'atRule',
1069+
};
10541070
}
10551071

10561072
if (ORDER_PRIORITIES[order]) {

packages/@stylexjs/shared/.babelrc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"assumptions": {
3+
"iterableIsArray": true
4+
},
5+
"presets": [
6+
["@babel/preset-env", {
7+
"exclude": [
8+
"@babel/plugin-transform-typeof-symbol"
9+
],
10+
"targets": "defaults"
11+
}],
12+
"@babel/preset-flow",
13+
"@babel/preset-react"
14+
],
15+
"plugins": [["babel-plugin-syntax-hermes-parser", {"flow": "detect"}]]
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@stylexjs/shared",
3+
"version": "0.16.2",
4+
"main": "lib/index.js",
5+
"repository": {
6+
"type": "git",
7+
"url": "git+https://github.com/facebook/stylex.git"
8+
},
9+
"license": "MIT",
10+
"scripts": {
11+
"prebuild": "gen-types -i src/ -o lib/",
12+
"build": "babel src/ --out-dir lib/",
13+
"test": "jest --coverage"
14+
},
15+
"devDependencies": {
16+
"@babel/cli": "^7.23.9",
17+
"@babel/core": "^7.23.9"
18+
},
19+
"files": [
20+
"lib/*"
21+
]
22+
}

0 commit comments

Comments
 (0)