@monospaced/set-config 0.20.2 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -7
- package/baseline/index.d.ts +3 -0
- package/baseline/index.mjs +13 -0
- package/browserslist/esbuild.mjs +3 -1
- package/browserslist/index.mjs +3 -1
- package/browserslist/lightningcss.d.ts +5 -0
- package/browserslist/lightningcss.mjs +8 -0
- package/eslint/index.mjs +48 -6
- package/eslint/react.d.ts +5 -0
- package/eslint/react.mjs +18 -0
- package/eslint/rules.d.ts +5 -0
- package/eslint/rules.mjs +23 -0
- package/package.json +50 -3
- package/stylelint/index.mjs +19 -0
package/README.md
CHANGED
|
@@ -2,26 +2,72 @@
|
|
|
2
2
|
|
|
3
3
|
Shared developer-tooling config for Set. ESLint, Stylelint, Prettier, browserslist presets plus the `--set-*` token catalog for editor autocomplete and tooling — install once, plug in via subpath imports.
|
|
4
4
|
|
|
5
|
+
## Baseline
|
|
6
|
+
|
|
7
|
+
Set targets [Baseline](https://web.dev/baseline) Widely available: features supported in every core browser for at least 30 months. One constant encodes that target and every preset derives from it, so the browserslist query, the esbuild target, and the ESLint and Stylelint Baseline rules can never disagree.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import baseline from "@monospaced/set-config/baseline"; // "widely"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- **ESLint** reports JS builtins and Web APIs outside the target as errors, via [`eslint-plugin-baseline-js`](https://github.com/3ru/eslint-plugin-baseline-js). Unsupported JS throws at runtime, so this is a hard floor.
|
|
14
|
+
- **Stylelint** reports CSS properties, values, functions, at-rules and selectors outside the target as errors, via [`stylelint-plugin-use-baseline`](https://github.com/ryo-manba/stylelint-plugin-use-baseline). Unsupported CSS degrades silently where unsupported JS throws, so the preset ignores a short list of progressive enhancements that degrade gracefully. Anything else needs an `@supports` guard or an inline justification:
|
|
15
|
+
|
|
16
|
+
```css
|
|
17
|
+
/* stylelint-disable-next-line plugin/use-baseline -- Baseline newly available 2025; physical fallback above */
|
|
18
|
+
overflow-block: auto;
|
|
19
|
+
```
|
|
20
|
+
|
|
5
21
|
## ESLint
|
|
6
22
|
|
|
7
|
-
|
|
23
|
+
Two complete flat configs and one layer. `eslint` and `typescript` are peer dependencies: install them alongside.
|
|
24
|
+
|
|
25
|
+
### Default
|
|
26
|
+
|
|
27
|
+
A complete config for a web project: `@eslint/js` recommended, `typescript-eslint` recommended, `@eslint/json` recommended (`tsconfig*.json` and `.vscode/*.json` are parsed as JSONC, since TypeScript and VS Code accept comments and trailing commas there), browser globals for source files, Node globals for root-level `*.config.*` files and `scripts/`, Set's import sort, and the Baseline rule (off for the Node-run files, where the `engines` range is the support contract). `dist`, `build` and `coverage` are ignored.
|
|
8
28
|
|
|
9
29
|
```js
|
|
10
30
|
// eslint.config.mjs
|
|
11
31
|
import setEslint from "@monospaced/set-config/eslint";
|
|
12
32
|
|
|
13
33
|
export default [
|
|
14
|
-
// your TypeScript / JSON / JS configs here
|
|
15
34
|
...setEslint,
|
|
16
35
|
// your local rules / overrides
|
|
17
36
|
];
|
|
18
37
|
```
|
|
19
38
|
|
|
20
|
-
|
|
39
|
+
### React
|
|
40
|
+
|
|
41
|
+
The default config plus `eslint-plugin-react-hooks` recommended and the `eslint-plugin-react-refresh` Vite config, both at their own defaults.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
// eslint.config.mjs
|
|
45
|
+
import setEslint from "@monospaced/set-config/eslint/react";
|
|
46
|
+
|
|
47
|
+
export default [...setEslint];
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Rules
|
|
51
|
+
|
|
52
|
+
Only Set's own conventions — import/export sort (`simple-import-sort`) and the Baseline rule (`baseline-js/use-baseline`, see above) — for layering onto a config you already have. Turn the Baseline rule off for code that runs under Node.
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// eslint.config.mjs
|
|
56
|
+
import setRules from "@monospaced/set-config/eslint/rules";
|
|
57
|
+
|
|
58
|
+
export default [
|
|
59
|
+
// your TypeScript / JSON / JS configs here
|
|
60
|
+
...setRules,
|
|
61
|
+
{
|
|
62
|
+
files: ["**/scripts/**", "**/*.config.{js,mjs,ts}"],
|
|
63
|
+
rules: { "baseline-js/use-baseline": "off" },
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
```
|
|
21
67
|
|
|
22
68
|
## Stylelint
|
|
23
69
|
|
|
24
|
-
Drop-in shareable config — extends `stylelint-config-standard` and layers on Set's CSS authoring discipline: alphabetical property ordering (`stylelint-order`), token-discipline rules (no raw colors, no absolute lengths, no raw time, no `!important`),
|
|
70
|
+
Drop-in shareable config — extends `stylelint-config-standard` and layers on Set's CSS authoring discipline: alphabetical property ordering (`stylelint-order`), token-discipline rules (no raw colors, no absolute lengths, no raw time, no `!important`), logical-CSS enforcement (`stylelint-plugin-logical-css`) so component CSS stays portable across writing modes, and the Baseline rule (`plugin/use-baseline`, see above).
|
|
25
71
|
|
|
26
72
|
```js
|
|
27
73
|
// .stylelintrc.mjs
|
|
@@ -78,9 +124,9 @@ Catalog enforcement for `--set-*` references is preserved; non-`--set-` customs
|
|
|
78
124
|
import browserslist from "@monospaced/set-config/browserslist";
|
|
79
125
|
```
|
|
80
126
|
|
|
81
|
-
Use the query directly in tools that accept query arrays (for example Autoprefixer `overrideBrowserslist`).
|
|
127
|
+
Use the query directly in tools that accept query arrays (for example Autoprefixer `overrideBrowserslist`, or Lightning CSS via `browserslistToTargets`).
|
|
82
128
|
|
|
83
|
-
For plain `package.json` `browserslist` fields, use the equivalent query:
|
|
129
|
+
For plain `package.json` `browserslist` fields, use the equivalent query. Autoprefixer, Lightning CSS and anything else built on the `browserslist` package read this field automatically, so it is the single source of truth for a project:
|
|
84
130
|
|
|
85
131
|
```json
|
|
86
132
|
{
|
|
@@ -88,8 +134,18 @@ For plain `package.json` `browserslist` fields, use the equivalent query:
|
|
|
88
134
|
}
|
|
89
135
|
```
|
|
90
136
|
|
|
91
|
-
## Vite
|
|
137
|
+
## Vite targets
|
|
138
|
+
|
|
139
|
+
The esbuild target string and the Lightning CSS targets object, both derived from the Baseline query. `browserslist` and `lightningcss` are optional peer dependencies, needed only for the Lightning CSS export.
|
|
92
140
|
|
|
93
141
|
```ts
|
|
142
|
+
// vite.config.ts
|
|
94
143
|
import target from "@monospaced/set-config/browserslist/esbuild";
|
|
144
|
+
import targets from "@monospaced/set-config/browserslist/lightningcss";
|
|
145
|
+
import { defineConfig } from "vite";
|
|
146
|
+
|
|
147
|
+
export default defineConfig({
|
|
148
|
+
build: { cssMinify: "lightningcss", target },
|
|
149
|
+
css: { lightningcss: { targets }, transformer: "lightningcss" },
|
|
150
|
+
});
|
|
95
151
|
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set's Baseline availability target. One constant drives every preset that
|
|
3
|
+
* encodes browser support: the browserslist query, the esbuild target, and
|
|
4
|
+
* the ESLint and Stylelint Baseline rules, so they can never drift apart.
|
|
5
|
+
*
|
|
6
|
+
* "widely" means Baseline Widely available: supported in all core browsers
|
|
7
|
+
* for at least 30 months. Switch to "newly" to adopt features sooner.
|
|
8
|
+
*
|
|
9
|
+
* @type {"widely" | "newly"}
|
|
10
|
+
*/
|
|
11
|
+
const baseline = "widely";
|
|
12
|
+
|
|
13
|
+
export default baseline;
|
package/browserslist/esbuild.mjs
CHANGED
package/browserslist/index.mjs
CHANGED
package/eslint/index.mjs
CHANGED
|
@@ -1,13 +1,55 @@
|
|
|
1
|
-
import
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import json from "@eslint/json";
|
|
3
|
+
import globals from "globals";
|
|
4
|
+
import tseslint from "typescript-eslint";
|
|
5
|
+
|
|
6
|
+
import setRules from "./rules.mjs";
|
|
7
|
+
|
|
8
|
+
// Files that run under Node rather than in the browser: root-level tool
|
|
9
|
+
// configs and the scripts directory. Anchored to the root so that shipped
|
|
10
|
+
// code such as src/scripts/ or src/theme.config.ts stays browser code.
|
|
11
|
+
const NODE_FILES = ["*.config.{js,cjs,mjs,ts,cts,mts}", "scripts/**"];
|
|
12
|
+
|
|
13
|
+
const off = (names) => Object.fromEntries(names.map((name) => [name, "off"]));
|
|
2
14
|
|
|
3
15
|
const eslintConfig = [
|
|
4
16
|
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
17
|
+
ignores: ["**/build/**", "**/coverage/**", "**/dist/**"],
|
|
18
|
+
},
|
|
19
|
+
...setRules,
|
|
20
|
+
{
|
|
21
|
+
files: ["**/*.json"],
|
|
22
|
+
...json.configs.recommended,
|
|
23
|
+
language: "json/json",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
// Editor and TypeScript config files allow comments and trailing commas.
|
|
27
|
+
files: ["**/.vscode/*.json", "**/tsconfig*.json"],
|
|
28
|
+
...json.configs.recommended,
|
|
29
|
+
language: "json/jsonc",
|
|
30
|
+
languageOptions: { allowTrailingCommas: true },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
files: ["**/*.{js,cjs,mjs,jsx}"],
|
|
34
|
+
...js.configs.recommended,
|
|
35
|
+
languageOptions: { globals: { ...globals.browser } },
|
|
36
|
+
},
|
|
37
|
+
...tseslint.configs.recommended.map((config) => ({
|
|
38
|
+
...config,
|
|
39
|
+
files: ["**/*.{ts,cts,mts,tsx}"],
|
|
40
|
+
languageOptions: {
|
|
41
|
+
...(config.languageOptions ?? {}),
|
|
42
|
+
globals: { ...globals.browser },
|
|
43
|
+
},
|
|
44
|
+
})),
|
|
45
|
+
{
|
|
46
|
+
files: NODE_FILES,
|
|
47
|
+
languageOptions: {
|
|
48
|
+
globals: { ...off(Object.keys(globals.browser)), ...globals.node },
|
|
10
49
|
},
|
|
50
|
+
// Enabled for every JS and TS file by rules.mjs; Baseline is a browser
|
|
51
|
+
// support contract, and these files run under Node.
|
|
52
|
+
rules: { "baseline-js/use-baseline": "off" },
|
|
11
53
|
},
|
|
12
54
|
];
|
|
13
55
|
|
package/eslint/react.mjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
2
|
+
import reactRefresh from "eslint-plugin-react-refresh";
|
|
3
|
+
|
|
4
|
+
import eslintConfig from "./index.mjs";
|
|
5
|
+
|
|
6
|
+
const hooks = reactHooks.configs.flat.recommended;
|
|
7
|
+
const refresh = reactRefresh.configs.vite;
|
|
8
|
+
|
|
9
|
+
const reactConfig = [
|
|
10
|
+
...eslintConfig,
|
|
11
|
+
{
|
|
12
|
+
files: ["**/*.{js,jsx,ts,tsx}"],
|
|
13
|
+
plugins: { ...hooks.plugins, ...refresh.plugins },
|
|
14
|
+
rules: { ...hooks.rules, ...refresh.rules },
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export default reactConfig;
|
package/eslint/rules.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import baselineJs from "eslint-plugin-baseline-js";
|
|
2
|
+
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
3
|
+
|
|
4
|
+
import baseline from "../baseline/index.mjs";
|
|
5
|
+
|
|
6
|
+
const rulesConfig = [
|
|
7
|
+
{
|
|
8
|
+
files: ["**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}"],
|
|
9
|
+
plugins: {
|
|
10
|
+
"baseline-js": baselineJs,
|
|
11
|
+
"simple-import-sort": simpleImportSort,
|
|
12
|
+
},
|
|
13
|
+
rules: {
|
|
14
|
+
"simple-import-sort/imports": "error",
|
|
15
|
+
"simple-import-sort/exports": "error",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
// Baseline: JS builtins and Web APIs available at Set's Baseline level.
|
|
19
|
+
baselineJs.configs.recommended({ available: baseline }),
|
|
20
|
+
baselineJs.configs["recommended-ts"]({ available: baseline }),
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export default rulesConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monospaced/set-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Shared developer-tooling config for Set. ESLint, Stylelint, Prettier, browserslist presets plus the --set-* token catalog for editor autocomplete and tooling.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"type": "module",
|
|
11
11
|
"files": [
|
|
12
|
+
"baseline",
|
|
12
13
|
"browserslist",
|
|
13
14
|
"eslint",
|
|
14
15
|
"stylelint",
|
|
@@ -17,6 +18,10 @@
|
|
|
17
18
|
],
|
|
18
19
|
"types": "./browserslist/index.d.ts",
|
|
19
20
|
"exports": {
|
|
21
|
+
"./baseline": {
|
|
22
|
+
"types": "./baseline/index.d.ts",
|
|
23
|
+
"default": "./baseline/index.mjs"
|
|
24
|
+
},
|
|
20
25
|
"./browserslist": {
|
|
21
26
|
"types": "./browserslist/index.d.ts",
|
|
22
27
|
"default": "./browserslist/index.mjs"
|
|
@@ -25,10 +30,22 @@
|
|
|
25
30
|
"types": "./browserslist/esbuild.d.ts",
|
|
26
31
|
"default": "./browserslist/esbuild.mjs"
|
|
27
32
|
},
|
|
33
|
+
"./browserslist/lightningcss": {
|
|
34
|
+
"types": "./browserslist/lightningcss.d.ts",
|
|
35
|
+
"default": "./browserslist/lightningcss.mjs"
|
|
36
|
+
},
|
|
28
37
|
"./eslint": {
|
|
29
38
|
"types": "./eslint/index.d.ts",
|
|
30
39
|
"default": "./eslint/index.mjs"
|
|
31
40
|
},
|
|
41
|
+
"./eslint/react": {
|
|
42
|
+
"types": "./eslint/react.d.ts",
|
|
43
|
+
"default": "./eslint/react.mjs"
|
|
44
|
+
},
|
|
45
|
+
"./eslint/rules": {
|
|
46
|
+
"types": "./eslint/rules.d.ts",
|
|
47
|
+
"default": "./eslint/rules.mjs"
|
|
48
|
+
},
|
|
32
49
|
"./stylelint": {
|
|
33
50
|
"types": "./stylelint/index.d.ts",
|
|
34
51
|
"default": "./stylelint/index.mjs"
|
|
@@ -38,17 +55,47 @@
|
|
|
38
55
|
"baseline widely available"
|
|
39
56
|
],
|
|
40
57
|
"dependencies": {
|
|
58
|
+
"@eslint/js": "^10.0.1",
|
|
59
|
+
"@eslint/json": "^2.1.1",
|
|
60
|
+
"eslint-plugin-baseline-js": "^0.7.7",
|
|
61
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
62
|
+
"eslint-plugin-react-refresh": "^0.5.7",
|
|
41
63
|
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
64
|
+
"globals": "^17.14.0",
|
|
42
65
|
"stylelint-config-standard": "^40.0.0",
|
|
43
66
|
"stylelint-declaration-strict-value": "^1.11.1",
|
|
44
67
|
"stylelint-order": "^8.1.1",
|
|
45
|
-
"stylelint-plugin-logical-css": "^2.1.0"
|
|
68
|
+
"stylelint-plugin-logical-css": "^2.1.0",
|
|
69
|
+
"stylelint-plugin-use-baseline": "^1.4.8",
|
|
70
|
+
"typescript-eslint": "^8.72.1"
|
|
46
71
|
},
|
|
47
72
|
"peerDependencies": {
|
|
73
|
+
"browserslist": "^4.26.0",
|
|
48
74
|
"eslint": "^10.0.0",
|
|
49
|
-
"
|
|
75
|
+
"lightningcss": "^1.0.0",
|
|
76
|
+
"stylelint": "^17.0.0",
|
|
77
|
+
"typescript": "^5.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"browserslist": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"lightningcss": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"stylelint": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"typescript": {
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"eslint": "^10.2.1",
|
|
95
|
+
"typescript": "^5.9.3"
|
|
50
96
|
},
|
|
51
97
|
"scripts": {
|
|
98
|
+
"test": "node --test",
|
|
52
99
|
"verify": "node scripts/verify.mjs"
|
|
53
100
|
}
|
|
54
101
|
}
|
package/stylelint/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
|
|
3
|
+
import baseline from "../baseline/index.mjs";
|
|
3
4
|
import setTokensPlugin from "./plugin-set-tokens.mjs";
|
|
4
5
|
|
|
5
6
|
// Stylelint resolves `extends`/`plugins` strings from the consumer's config
|
|
@@ -34,6 +35,7 @@ const stylelintConfig = {
|
|
|
34
35
|
plugins: [
|
|
35
36
|
require.resolve("stylelint-declaration-strict-value"),
|
|
36
37
|
require.resolve("stylelint-order"),
|
|
38
|
+
require.resolve("stylelint-plugin-use-baseline"),
|
|
37
39
|
setTokensPlugin,
|
|
38
40
|
],
|
|
39
41
|
rules: {
|
|
@@ -75,6 +77,23 @@ const stylelintConfig = {
|
|
|
75
77
|
],
|
|
76
78
|
"no-descending-specificity": null,
|
|
77
79
|
"order/properties-alphabetical-order": true,
|
|
80
|
+
// Baseline: CSS features available at Set's Baseline level. The ignores
|
|
81
|
+
// are progressive enhancements that degrade gracefully; prune each once
|
|
82
|
+
// it reaches Widely available.
|
|
83
|
+
"plugin/use-baseline": [
|
|
84
|
+
true,
|
|
85
|
+
{
|
|
86
|
+
available: baseline,
|
|
87
|
+
ignoreProperties: {
|
|
88
|
+
"accent-color": ["/^.+$/"],
|
|
89
|
+
"forced-color-adjust": ["/^.+$/"],
|
|
90
|
+
"/^overscroll-behavior/": ["/^.+$/"],
|
|
91
|
+
resize: ["/^.+$/"],
|
|
92
|
+
"text-wrap": ["balance", "pretty"],
|
|
93
|
+
},
|
|
94
|
+
ignoreSelectors: ["marker", "selection"],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
78
97
|
"scale-unlimited/declaration-strict-value": [
|
|
79
98
|
[
|
|
80
99
|
"/^border.*radius$/",
|