@zukhruf/eslint 0.3.22 → 0.3.24
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 +1 -1
- package/dist/react/config.d.ts +1 -1
- package/dist/react/config.d.ts.map +1 -1
- package/dist/react/config.js +3 -3
- package/dist/react/config.js.map +1 -1
- package/dist/react/no-as-child.d.ts +3 -0
- package/dist/react/no-as-child.d.ts.map +1 -0
- package/dist/react/no-as-child.js +7 -0
- package/dist/react/no-as-child.js.map +1 -0
- package/package.json +1 -1
- package/dist/react/require-combobox-popover-modal.d.ts +0 -10
- package/dist/react/require-combobox-popover-modal.d.ts.map +0 -1
- package/dist/react/require-combobox-popover-modal.js +0 -101
- package/dist/react/require-combobox-popover-modal.js.map +0 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Put framework presets (for example Nx's `flat/react`) **before** the zukhruf con
|
|
|
47
47
|
| `diagnostics` | source, not tests | `no-fabricated-fallback`, `no-hardcoded-id-shape`, `consistent-event-name` |
|
|
48
48
|
| `env` | TypeScript, not tests | `no-undeclared-process-env`, `no-single-env-read-wrapper`, `no-default-for-path-env` |
|
|
49
49
|
| `packaged-app` | TypeScript, not tests | `no-bare-spawn` |
|
|
50
|
-
| `react` | `.tsx`, `.jsx` | `
|
|
50
|
+
| `react` | `.tsx`, `.jsx` | `no-as-child` |
|
|
51
51
|
| `react-router` | source | `require-loader-data-type-argument`; outside tests: `no-raw-route-path`, `no-internal-anchor` |
|
|
52
52
|
| `hono` | TypeScript, not tests | `no-untyped-empty-json` |
|
|
53
53
|
| `tailwind` | source | `no-h-screen`, `no-arbitrary-z-index`, `no-will-change` |
|
package/dist/react/config.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/react/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAMrD,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/react/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAMrD,oEAAoE;AACpE,eAAO,MAAM,KAAK,EAAE,OAMnB,CAAC"}
|
package/dist/react/config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { enable } from "../concept.js";
|
|
2
2
|
import { JSX } from "../files.js";
|
|
3
|
-
import
|
|
4
|
-
const rules = { '
|
|
5
|
-
/** React components built from shadcn/ui and
|
|
3
|
+
import noAsChild from "./no-as-child.js";
|
|
4
|
+
const rules = { 'no-as-child': noAsChild };
|
|
5
|
+
/** React components built from shadcn/ui and Base UI primitives. */
|
|
6
6
|
export const react = {
|
|
7
7
|
name: 'react',
|
|
8
8
|
rules,
|
package/dist/react/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/react/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/react/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AAEzC,MAAM,KAAK,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAE3C,oEAAoE;AACpE,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,OAAO;IACb,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;KACrE;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-as-child.d.ts","sourceRoot":"","sources":["../../src/react/no-as-child.ts"],"names":[],"mappings":";AAEA,wBAMG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { selectorRule } from "../authoring/selector-rule.js";
|
|
2
|
+
export default selectorRule({
|
|
3
|
+
description: 'Disallow the Radix `asChild` prop; Base UI sets the rendered element with `render`',
|
|
4
|
+
selectors: ["JSXAttribute[name.name='asChild']"],
|
|
5
|
+
message: 'Do not use `asChild`. It is a Radix UI prop, and Base UI does not have it. Use the `render` prop: `<DialogTrigger render={<Button />}>`. When the element is not a button, also set `nativeButton={false}`. For a link that looks like a button, do not use `render`. Use a plain link with `className={cn(buttonVariants(...))}`.',
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=no-as-child.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-as-child.js","sourceRoot":"","sources":["../../src/react/no-as-child.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,oFAAoF;IACtF,SAAS,EAAE,CAAC,mCAAmC,CAAC;IAChD,OAAO,EACL,oUAAoU;CACvU,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zukhruf/eslint",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.24",
|
|
4
4
|
"description": "ESLint rules and configs shared across workspaces. Every check is its own named rule, so a repo's own config cannot silently erase it.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Rule } from 'eslint';
|
|
2
|
-
/**
|
|
3
|
-
* A modal <Dialog> locks scrolling with react-remove-scroll, which lets wheel
|
|
4
|
-
* events through only inside the dialog's subtree. A combobox <Popover> portals
|
|
5
|
-
* to document.body, outside that subtree, so its list silently stops scrolling
|
|
6
|
-
* with the wheel unless the popover holds its own lock (`modal`).
|
|
7
|
-
*/
|
|
8
|
-
declare const rule: Rule.RuleModule;
|
|
9
|
-
export default rule;
|
|
10
|
-
//# sourceMappingURL=require-combobox-popover-modal.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-combobox-popover-modal.d.ts","sourceRoot":"","sources":["../../src/react/require-combobox-popover-modal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AA4DnC;;;;;GAKG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAkDhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { isAstNode, isType } from "../authoring/ast.js";
|
|
2
|
-
// The opening tag of a JSX element, but only for the plain-identifier form
|
|
3
|
-
// (`<Popover>`). The member/namespaced forms (`<Popover.Root>`) are not this
|
|
4
|
-
// rule's concern — the shadcn wrapper this rule guards is always used as a bare
|
|
5
|
-
// identifier.
|
|
6
|
-
function plainTag(node) {
|
|
7
|
-
if (!isType(node, 'JSXElement'))
|
|
8
|
-
return undefined;
|
|
9
|
-
const opening = node['openingElement'];
|
|
10
|
-
if (!isAstNode(opening))
|
|
11
|
-
return undefined;
|
|
12
|
-
const name = opening['name'];
|
|
13
|
-
if (!isType(name, 'JSXIdentifier') || typeof name['name'] !== 'string') {
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
return { opening, name, text: name['name'] };
|
|
17
|
-
}
|
|
18
|
-
function readModal(opening) {
|
|
19
|
-
const attributes = opening['attributes'];
|
|
20
|
-
const list = Array.isArray(attributes) ? attributes : [];
|
|
21
|
-
let hasSpread = false;
|
|
22
|
-
for (const attribute of list) {
|
|
23
|
-
if (isType(attribute, 'JSXSpreadAttribute')) {
|
|
24
|
-
hasSpread = true;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (!isType(attribute, 'JSXAttribute'))
|
|
28
|
-
continue;
|
|
29
|
-
const name = attribute['name'];
|
|
30
|
-
if (!isType(name, 'JSXIdentifier') || name['name'] !== 'modal')
|
|
31
|
-
continue;
|
|
32
|
-
const value = attribute['value'];
|
|
33
|
-
if (value === null)
|
|
34
|
-
return { kind: 'ok' }; // `<Popover modal>`
|
|
35
|
-
if (isType(value, 'JSXExpressionContainer')) {
|
|
36
|
-
const expression = value['expression'];
|
|
37
|
-
if (isType(expression, 'Literal') && expression['value'] === false) {
|
|
38
|
-
return { kind: 'false', attribute };
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// `modal={true}`, `modal={someVar}`, `modal="..."` — leave the author's
|
|
42
|
-
// explicit/dynamic choice alone.
|
|
43
|
-
return { kind: 'ok' };
|
|
44
|
-
}
|
|
45
|
-
// A spread could supply `modal` at runtime; too imprecise to flag.
|
|
46
|
-
return hasSpread ? { kind: 'ok' } : { kind: 'absent' };
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* A modal <Dialog> locks scrolling with react-remove-scroll, which lets wheel
|
|
50
|
-
* events through only inside the dialog's subtree. A combobox <Popover> portals
|
|
51
|
-
* to document.body, outside that subtree, so its list silently stops scrolling
|
|
52
|
-
* with the wheel unless the popover holds its own lock (`modal`).
|
|
53
|
-
*/
|
|
54
|
-
const rule = {
|
|
55
|
-
meta: {
|
|
56
|
-
type: 'problem',
|
|
57
|
-
fixable: 'code',
|
|
58
|
-
docs: {
|
|
59
|
-
description: 'Require `modal` on a <Popover> that wraps a <Command> combobox so wheel scrolling survives inside a modal <Dialog>',
|
|
60
|
-
},
|
|
61
|
-
messages: {
|
|
62
|
-
requireModal: 'A <Popover> wrapping a <Command> combobox must set `modal`. Rendered inside a modal <Dialog>, react-remove-scroll allows wheel events only within the dialog subtree; this popover portals to document.body, so without its own lock the wheel is silently canceled (arrow keys still work via cmdk scrollIntoView). Add `modal`, or disable this line if this popover is never mounted inside a modal Dialog.',
|
|
63
|
-
noExplicitFalse: '`modal={false}` on a <Popover> wrapping a <Command> combobox reintroduces the wheel-scroll bug inside a modal <Dialog>. Remove it (default to `modal`), or disable this line if this popover is never mounted inside a modal Dialog.',
|
|
64
|
-
},
|
|
65
|
-
schema: [],
|
|
66
|
-
},
|
|
67
|
-
create(context) {
|
|
68
|
-
const reported = new Set();
|
|
69
|
-
return {
|
|
70
|
-
JSXElement(node) {
|
|
71
|
-
if (plainTag(node)?.text !== 'Command')
|
|
72
|
-
return;
|
|
73
|
-
// The nearest syntactic ancestor, so an enclosing <Popover> is matched
|
|
74
|
-
// only when the <Command> is genuinely nested inside it in the same
|
|
75
|
-
// file — the co-located shadcn combobox shape — never a sibling
|
|
76
|
-
// <Popover> elsewhere in the module.
|
|
77
|
-
const popover = context.sourceCode
|
|
78
|
-
.getAncestors(node)
|
|
79
|
-
.map(plainTag)
|
|
80
|
-
.findLast((tag) => tag?.text === 'Popover');
|
|
81
|
-
if (!popover || reported.has(popover.opening))
|
|
82
|
-
return;
|
|
83
|
-
const modal = readModal(popover.opening);
|
|
84
|
-
if (modal.kind === 'ok')
|
|
85
|
-
return;
|
|
86
|
-
reported.add(popover.opening);
|
|
87
|
-
if (modal.kind === 'absent') {
|
|
88
|
-
context.report({
|
|
89
|
-
node: popover.opening,
|
|
90
|
-
messageId: 'requireModal',
|
|
91
|
-
fix: (fixer) => fixer.insertTextAfter(popover.name, ' modal'),
|
|
92
|
-
});
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
context.report({ node: modal.attribute, messageId: 'noExplicitFalse' });
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
export default rule;
|
|
101
|
-
//# sourceMappingURL=require-combobox-popover-modal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-combobox-popover-modal.js","sourceRoot":"","sources":["../../src/react/require-combobox-popover-modal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAQtE,2EAA2E;AAC3E,6EAA6E;AAC7E,gFAAgF;AAChF,cAAc;AACd,SAAS,QAAQ,CAAC,IAAa;IAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC;QAAE,OAAO,SAAS,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACvC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/C,CAAC;AAOD,SAAS,SAAS,CAAC,OAAgB;IACjC,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,IAAI,GAAuB,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,CAAC;YAC5C,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC;YAAE,SAAS;QACjD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,OAAO;YAAE,SAAS;QAEzE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,oBAAoB;QAC/D,IAAI,MAAM,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC;gBACnE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QACD,wEAAwE;QACxE,iCAAiC;QACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAED,mEAAmE;IACnE,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,WAAW,EACT,oHAAoH;SACvH;QACD,QAAQ,EAAE;YACR,YAAY,EACV,gZAAgZ;YAClZ,eAAe,EACb,sOAAsO;SACzO;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;QAEpC,OAAO;YACL,UAAU,CAAC,IAAe;gBACxB,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,SAAS;oBAAE,OAAO;gBAE/C,uEAAuE;gBACvE,oEAAoE;gBACpE,gEAAgE;gBAChE,qCAAqC;gBACrC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU;qBAC/B,YAAY,CAAC,IAAI,CAAC;qBAClB,GAAG,CAAC,QAAQ,CAAC;qBACb,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC;gBAC9C,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;oBAAE,OAAO;gBAEtD,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;oBAAE,OAAO;gBAChC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAE9B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5B,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,OAAO,CAAC,OAAO;wBACrB,SAAS,EAAE,cAAc;wBACzB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;qBAC9D,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC1E,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|