@dnncommunity/dnn-elements 0.24.3 → 0.24.4-beta.3

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.
@@ -0,0 +1,26 @@
1
+ import { RuleTester } from "eslint";
2
+ import { noLabelSlotInCheckbox } from "../src/rules/no-label-slot-in-checkbox";
3
+ const tsParser = require.resolve("@typescript-eslint/parser");
4
+ const ruleTester = new RuleTester({
5
+ parser: tsParser,
6
+ parserOptions: {
7
+ ecmaVersion: 2022,
8
+ ecmaFeatures: {
9
+ jsx: true,
10
+ },
11
+ sourceType: "module",
12
+ },
13
+ });
14
+ ruleTester.run("no-label-slot-in-checkbox", noLabelSlotInCheckbox, {
15
+ valid: [
16
+ { code: "<dnn-checkbox></dnn-checkbox>" },
17
+ ],
18
+ invalid: [
19
+ {
20
+ code: "<dnn-checkbox onClick={e => console.log(e)}><label>Label Text</label></dnn-checkbox>",
21
+ errors: [{ messageId: "noLabelSlotInCheckbox" }],
22
+ output: "<label>\nLabel Text\n<dnn-checkbox onClick={e => console.log(e)}></dnn-checkbox>\n</label>",
23
+ },
24
+ ],
25
+ });
26
+ //# sourceMappingURL=no-label-slot-in-checkbox.tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-label-slot-in-checkbox.tests.js","sourceRoot":"","sources":["../../../src/eslint-plugin/__tests__/no-label-slot-in-checkbox.tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;AAE9D,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC;IAC9B,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE;QACX,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE;YACV,GAAG,EAAE,IAAI;SACZ;QACD,UAAU,EAAE,QAAQ;KACvB;CACJ,CAAC,CAAC;AAEH,UAAU,CAAC,GAAG,CAAC,2BAA2B,EAAE,qBAAqB,EAAE;IAC/D,KAAK,EAAE;QACH,EAAE,IAAI,EAAE,+BAA+B,EAAE;KAC5C;IACD,OAAO,EAAE;QACL;YACI,IAAI,EAAE,sFAAsF;YAC5F,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC;YAChD,MAAM,EAAE,4FAA4F;SACvG;KACJ;CACJ,CAAC,CAAC","sourcesContent":["import { RuleTester } from \"eslint\";\r\nimport { noLabelSlotInCheckbox } from \"../src/rules/no-label-slot-in-checkbox\";\r\nconst tsParser = require.resolve(\"@typescript-eslint/parser\");\r\n\r\nconst ruleTester = new RuleTester({\r\n parser: tsParser,\r\n parserOptions: {\r\n ecmaVersion: 2022,\r\n ecmaFeatures: {\r\n jsx: true,\r\n },\r\n sourceType: \"module\",\r\n },\r\n});\r\n\r\nruleTester.run(\"no-label-slot-in-checkbox\", noLabelSlotInCheckbox, {\r\n valid: [\r\n { code: \"<dnn-checkbox></dnn-checkbox>\" },\r\n ],\r\n invalid: [\r\n {\r\n code: \"<dnn-checkbox onClick={e => console.log(e)}><label>Label Text</label></dnn-checkbox>\",\r\n errors: [{ messageId: \"noLabelSlotInCheckbox\" }],\r\n output: \"<label>\\nLabel Text\\n<dnn-checkbox onClick={e => console.log(e)}></dnn-checkbox>\\n</label>\",\r\n },\r\n ],\r\n});"]}
@@ -0,0 +1,5 @@
1
+ import { noLabelSlotInCheckbox } from "./src/rules/no-label-slot-in-checkbox";
2
+ export const rules = {
3
+ "no-label-slot-in-checkbox": noLabelSlotInCheckbox
4
+ };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eslint-plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,CAAC,MAAM,KAAK,GAAG;IACjB,2BAA2B,EAAE,qBAAqB;CACrD,CAAC","sourcesContent":["import { noLabelSlotInCheckbox } from \"./src/rules/no-label-slot-in-checkbox\";\r\n\r\nexport const rules = {\r\n \"no-label-slot-in-checkbox\": noLabelSlotInCheckbox\r\n};"]}
@@ -0,0 +1,58 @@
1
+ export const noLabelSlotInCheckbox = {
2
+ meta: {
3
+ type: "problem",
4
+ docs: {
5
+ description: "Disallow label slot in checkbox",
6
+ recommended: true,
7
+ url: "https://github.com/DNNCommunity/dnn-elements/releases/tag/v0.24.0",
8
+ },
9
+ messages: {
10
+ noLabelSlotInCheckbox: "Label slot is not allowed in dnn-checkbox, wrap dnn-checkbox with a label instead."
11
+ },
12
+ fixable: "code",
13
+ },
14
+ create(context) {
15
+ return {
16
+ JSXOpeningElement(node) {
17
+ if (node.type === "JSXOpeningElement") {
18
+ const jsxNode = node;
19
+ if (jsxNode.name.type === "JSXIdentifier" && jsxNode.name.name === "dnn-checkbox") {
20
+ const parent = context.getAncestors().find(ancestor => ancestor.type === "JSXElement");
21
+ if (parent) {
22
+ const hasLabel = parent.children.some(child => {
23
+ return child.type === "JSXElement" &&
24
+ child.openingElement.name.type === "JSXIdentifier" &&
25
+ child.openingElement.name.name === "label";
26
+ });
27
+ if (hasLabel) {
28
+ context.report({
29
+ node: node,
30
+ messageId: "noLabelSlotInCheckbox",
31
+ fix: (fixer) => {
32
+ if (parent && parent.type === "JSXElement" && Array.isArray(parent.children)) {
33
+ const label = parent.children.find(child => child &&
34
+ child.type === "JSXElement" &&
35
+ child.openingElement &&
36
+ child.openingElement.name &&
37
+ child.openingElement.name.type === "JSXIdentifier" &&
38
+ child.openingElement.name.name === "label");
39
+ if (label && label.type === "JSXElement") {
40
+ const labelText = context.sourceCode.getText(label).replace(/<label>|<\/label>/g, '').trim();
41
+ const checkboxText = context.sourceCode.getText(node);
42
+ // Combine the label text and checkbox into a label wrapper with multiline formatting
43
+ const fixedText = `<label>\n${labelText}\n${checkboxText}</dnn-checkbox>\n</label>`;
44
+ return fixer.replaceText(parent, fixedText);
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ });
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ };
56
+ }
57
+ };
58
+ //# sourceMappingURL=no-label-slot-in-checkbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-label-slot-in-checkbox.js","sourceRoot":"","sources":["../../../../src/eslint-plugin/src/rules/no-label-slot-in-checkbox.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,qBAAqB,GAAoB;IAClD,IAAI,EAAE;QACF,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACF,WAAW,EAAE,iCAAiC;YAC9C,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,mEAAmE;SAC3E;QACD,QAAQ,EAAE;YACN,qBAAqB,EAAE,oFAAoF;SAC9G;QACD,OAAO,EAAE,MAAM;KAClB;IACD,MAAM,CAAC,OAAyB;QAC5B,OAAO;YACH,iBAAiB,CAAC,IAAe;gBAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;oBACpC,MAAM,OAAO,GAAG,IAAyB,CAAC;oBAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;wBAChF,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBACvF,IAAI,MAAM,EAAE,CAAC;4BACT,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gCAC1C,OAAO,KAAK,CAAC,IAAI,KAAK,YAAY;oCAC9B,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe;oCAClD,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;4BACnD,CAAC,CAAC,CAAC;4BACH,IAAI,QAAQ,EAAE,CAAC;gCACX,OAAO,CAAC,MAAM,CAAC;oCACX,IAAI,EAAE,IAAI;oCACV,SAAS,EAAE,uBAAuB;oCAClC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;wCACX,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;4CAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACvC,KAAK;gDACL,KAAK,CAAC,IAAI,KAAK,YAAY;gDAC3B,KAAK,CAAC,cAAc;gDACpB,KAAK,CAAC,cAAc,CAAC,IAAI;gDACzB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe;gDAClD,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;4CAEhD,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gDACvC,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gDAC7F,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gDAEtD,qFAAqF;gDACrF,MAAM,SAAS,GAAG,YAAY,SAAS,KAAK,YAAY,2BAA2B,CAAC;gDAEpF,OAAO,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;4CAChD,CAAC;wCACL,CAAC;wCAED,OAAO,IAAI,CAAC;oCAChB,CAAC;iCACJ,CAAC,CAAC;4BACP,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;SACJ,CAAC;IACN,CAAC;CACJ,CAAC","sourcesContent":["import type { Rule } from 'eslint';\r\nimport type { JSXOpeningElement } from \"estree-jsx\";\r\n\r\nexport const noLabelSlotInCheckbox: Rule.RuleModule = {\r\n meta: {\r\n type: \"problem\",\r\n docs: {\r\n description: \"Disallow label slot in checkbox\",\r\n recommended: true,\r\n url: \"https://github.com/DNNCommunity/dnn-elements/releases/tag/v0.24.0\",\r\n },\r\n messages: {\r\n noLabelSlotInCheckbox: \"Label slot is not allowed in dnn-checkbox, wrap dnn-checkbox with a label instead.\"\r\n },\r\n fixable: \"code\",\r\n },\r\n create(context: Rule.RuleContext): Rule.RuleListener {\r\n return {\r\n JSXOpeningElement(node: Rule.Node) {\r\n if (node.type === \"JSXOpeningElement\") {\r\n const jsxNode = node as JSXOpeningElement;\r\n if (jsxNode.name.type === \"JSXIdentifier\" && jsxNode.name.name === \"dnn-checkbox\") {\r\n const parent = context.getAncestors().find(ancestor => ancestor.type === \"JSXElement\");\r\n if (parent) {\r\n const hasLabel = parent.children.some(child => {\r\n return child.type === \"JSXElement\" &&\r\n child.openingElement.name.type === \"JSXIdentifier\" &&\r\n child.openingElement.name.name === \"label\";\r\n });\r\n if (hasLabel) {\r\n context.report({\r\n node: node,\r\n messageId: \"noLabelSlotInCheckbox\",\r\n fix: (fixer) => {\r\n if (parent && parent.type === \"JSXElement\" && Array.isArray(parent.children)) {\r\n const label = parent.children.find(child => \r\n child &&\r\n child.type === \"JSXElement\" &&\r\n child.openingElement &&\r\n child.openingElement.name &&\r\n child.openingElement.name.type === \"JSXIdentifier\" &&\r\n child.openingElement.name.name === \"label\");\r\n\r\n if (label && label.type === \"JSXElement\") {\r\n const labelText = context.sourceCode.getText(label).replace(/<label>|<\\/label>/g, '').trim();\r\n const checkboxText = context.sourceCode.getText(node);\r\n\r\n // Combine the label text and checkbox into a label wrapper with multiline formatting\r\n const fixedText = `<label>\\n${labelText}\\n${checkboxText}</dnn-checkbox>\\n</label>`;\r\n\r\n return fixer.replaceText(parent, fixedText);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n };\r\n }\r\n};\r\n"]}
@@ -0,0 +1,2 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const noLabelSlotInCheckbox: Rule.RuleModule;
@@ -0,0 +1,3 @@
1
+ export declare const rules: {
2
+ "no-label-slot-in-checkbox": import("eslint").Rule.RuleModule;
3
+ };
@@ -0,0 +1,2 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const noLabelSlotInCheckbox: Rule.RuleModule;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dnncommunity/dnn-elements",
3
- "version": "0.24.3",
3
+ "version": "0.24.4-beta.3",
4
4
  "description": "Dnn themed custom elements.",
5
5
  "repository": "https://github.com/dnncommunity/dnn-elements",
6
6
  "homepage": "https://dnncommunity.github.io/dnn-elements",
@@ -15,10 +15,11 @@
15
15
  "unpkg": "dist/dnn/dnn.js",
16
16
  "files": [
17
17
  "dist/",
18
- "loader/"
18
+ "loader/",
19
+ "src/eslint-plugin/"
19
20
  ],
20
21
  "scripts": {
21
- "build": "npm run eslint && stencil build --docs",
22
+ "build": "npm run build:eslint-plugin && npm run eslint && stencil build --docs",
22
23
  "postbuild": "license-checker-rseidelsohn --out licenses.json --json --direct --relativeLicensePath --relativeModulePath",
23
24
  "watch": "stencil build --dev --watch",
24
25
  "start": "stencil build --dev --watch --serve",
@@ -26,11 +27,13 @@
26
27
  "poststart": "license-checker-rseidelsohn --out licenses.json --json --direct --relativeLicensePath --relativeModulePath",
27
28
  "test": "stencil test --spec --e2e",
28
29
  "test.watch": "stencil test --spec --e2e --watchAll",
30
+ "test.eslint": "jest --config jest.eslint.config.js",
29
31
  "generate": "stencil generate",
30
32
  "eslint": "eslint",
31
33
  "storybook": "storybook dev -p 6006",
32
- "build-storybook": "storybook build",
33
- "deploy-storybook": "gh-pages -d storybook-static --branch site"
34
+ "build-storybook": "echo 'Storybook build is disabled for this release.'",
35
+ "deploy-storybook": "gh-pages -d storybook-static --branch site",
36
+ "build:eslint-plugin": "tsc -p src/eslint-plugin/tsconfig.json"
34
37
  },
35
38
  "devDependencies": {
36
39
  "@chromatic-com/storybook": "^3.1.0",
@@ -48,6 +51,7 @@
48
51
  "@storybook/web-components": "^8.3.2",
49
52
  "@storybook/web-components-webpack5": "^8.3.2",
50
53
  "@timkendrick/monaco-editor": "^0.0.9",
54
+ "@types/estree-jsx": "^1.0.5",
51
55
  "@types/jest": "^29.5.10",
52
56
  "@typescript-eslint/eslint-plugin": "^8.0.1",
53
57
  "@typescript-eslint/parser": "^8.0.1",
@@ -67,8 +71,8 @@
67
71
  "react-dom": "^18.2.0",
68
72
  "rollup-plugin-node-polyfills": "^0.2.1",
69
73
  "storybook": "^8.3.2",
70
- "typescript": "5.6.3",
71
- "typescript-debounce-decorator": "^0.0.18"
74
+ "ts-jest": "^29.3.2",
75
+ "typescript": "5.6.3"
72
76
  },
73
77
  "dependencies": {
74
78
  "jodit": "^4.2.27"
@@ -0,0 +1,27 @@
1
+ import { RuleTester } from "eslint";
2
+ import { noLabelSlotInCheckbox } from "../src/rules/no-label-slot-in-checkbox";
3
+ const tsParser = require.resolve("@typescript-eslint/parser");
4
+
5
+ const ruleTester = new RuleTester({
6
+ parser: tsParser,
7
+ parserOptions: {
8
+ ecmaVersion: 2022,
9
+ ecmaFeatures: {
10
+ jsx: true,
11
+ },
12
+ sourceType: "module",
13
+ },
14
+ });
15
+
16
+ ruleTester.run("no-label-slot-in-checkbox", noLabelSlotInCheckbox, {
17
+ valid: [
18
+ { code: "<dnn-checkbox></dnn-checkbox>" },
19
+ ],
20
+ invalid: [
21
+ {
22
+ code: "<dnn-checkbox onClick={e => console.log(e)}><label>Label Text</label></dnn-checkbox>",
23
+ errors: [{ messageId: "noLabelSlotInCheckbox" }],
24
+ output: "<label>\nLabel Text\n<dnn-checkbox onClick={e => console.log(e)}></dnn-checkbox>\n</label>",
25
+ },
26
+ ],
27
+ });
@@ -0,0 +1,2 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const noLabelSlotInCheckbox: Rule.RuleModule;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noLabelSlotInCheckbox = void 0;
4
+ exports.noLabelSlotInCheckbox = {
5
+ meta: {
6
+ type: "problem",
7
+ docs: {
8
+ description: "Disallow label slot in checkbox",
9
+ recommended: true,
10
+ url: "https://github.com/DNNCommunity/dnn-elements/releases/tag/v0.24.0",
11
+ },
12
+ messages: {
13
+ noLabelSlotInCheckbox: "Label slot is not allowed in dnn-checkbox, wrap dnn-checkbox with a label instead."
14
+ },
15
+ fixable: "code",
16
+ },
17
+ create(context) {
18
+ return {
19
+ JSXOpeningElement(node) {
20
+ if (node.type === "JSXOpeningElement") {
21
+ const jsxNode = node;
22
+ if (jsxNode.name.type === "JSXIdentifier" && jsxNode.name.name === "dnn-checkbox") {
23
+ const parent = context.getAncestors().find(ancestor => ancestor.type === "JSXElement");
24
+ if (parent) {
25
+ const hasLabel = parent.children.some(child => {
26
+ return child.type === "JSXElement" &&
27
+ child.openingElement.name.type === "JSXIdentifier" &&
28
+ child.openingElement.name.name === "label";
29
+ });
30
+ if (hasLabel) {
31
+ context.report({
32
+ node: node,
33
+ messageId: "noLabelSlotInCheckbox",
34
+ fix: (fixer) => {
35
+ if (parent && parent.type === "JSXElement" && Array.isArray(parent.children)) {
36
+ const label = parent.children.find(child => child &&
37
+ child.type === "JSXElement" &&
38
+ child.openingElement &&
39
+ child.openingElement.name &&
40
+ child.openingElement.name.type === "JSXIdentifier" &&
41
+ child.openingElement.name.name === "label");
42
+ if (label && label.type === "JSXElement") {
43
+ const labelText = context.sourceCode.getText(label).replace(/<label>|<\/label>/g, '').trim();
44
+ const checkboxText = context.sourceCode.getText(node);
45
+ // Combine the label text and checkbox into a label wrapper with multiline formatting
46
+ const fixedText = `<label>\n${labelText}\n${checkboxText}</dnn-checkbox>\n</label>`;
47
+ return fixer.replaceText(parent, fixedText);
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ });
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ };
59
+ }
60
+ };
61
+ //# sourceMappingURL=no-label-slot-in-checkbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-label-slot-in-checkbox.js","sourceRoot":"","sources":["../src/rules/no-label-slot-in-checkbox.ts"],"names":[],"mappings":";;;AAGa,QAAA,qBAAqB,GAAoB;IAClD,IAAI,EAAE;QACF,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACF,WAAW,EAAE,iCAAiC;YAC9C,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,mEAAmE;SAC3E;QACD,QAAQ,EAAE;YACN,qBAAqB,EAAE,oFAAoF;SAC9G;QACD,OAAO,EAAE,MAAM;KAClB;IACD,MAAM,CAAC,OAAyB;QAC5B,OAAO;YACH,iBAAiB,CAAC,IAAe;gBAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;oBACpC,MAAM,OAAO,GAAG,IAAyB,CAAC;oBAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;wBAChF,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBACvF,IAAI,MAAM,EAAE,CAAC;4BACT,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gCAC1C,OAAO,KAAK,CAAC,IAAI,KAAK,YAAY;oCAC9B,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe;oCAClD,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;4BACnD,CAAC,CAAC,CAAC;4BACH,IAAI,QAAQ,EAAE,CAAC;gCACX,OAAO,CAAC,MAAM,CAAC;oCACX,IAAI,EAAE,IAAI;oCACV,SAAS,EAAE,uBAAuB;oCAClC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;wCACX,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;4CAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACvC,KAAK;gDACL,KAAK,CAAC,IAAI,KAAK,YAAY;gDAC3B,KAAK,CAAC,cAAc;gDACpB,KAAK,CAAC,cAAc,CAAC,IAAI;gDACzB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe;gDAClD,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;4CAEhD,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gDACvC,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gDAC7F,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gDAEtD,qFAAqF;gDACrF,MAAM,SAAS,GAAG,YAAY,SAAS,KAAK,YAAY,2BAA2B,CAAC;gDAEpF,OAAO,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;4CAChD,CAAC;wCACL,CAAC;wCAED,OAAO,IAAI,CAAC;oCAChB,CAAC;iCACJ,CAAC,CAAC;4BACP,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;SACJ,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { noLabelSlotInCheckbox } from "./src/rules/no-label-slot-in-checkbox";
2
+
3
+ export const rules = {
4
+ "no-label-slot-in-checkbox": noLabelSlotInCheckbox
5
+ };
@@ -0,0 +1,65 @@
1
+ import type { Rule } from 'eslint';
2
+ import type { JSXOpeningElement } from "estree-jsx";
3
+
4
+ export const noLabelSlotInCheckbox: Rule.RuleModule = {
5
+ meta: {
6
+ type: "problem",
7
+ docs: {
8
+ description: "Disallow label slot in checkbox",
9
+ recommended: true,
10
+ url: "https://github.com/DNNCommunity/dnn-elements/releases/tag/v0.24.0",
11
+ },
12
+ messages: {
13
+ noLabelSlotInCheckbox: "Label slot is not allowed in dnn-checkbox, wrap dnn-checkbox with a label instead."
14
+ },
15
+ fixable: "code",
16
+ },
17
+ create(context: Rule.RuleContext): Rule.RuleListener {
18
+ return {
19
+ JSXOpeningElement(node: Rule.Node) {
20
+ if (node.type === "JSXOpeningElement") {
21
+ const jsxNode = node as JSXOpeningElement;
22
+ if (jsxNode.name.type === "JSXIdentifier" && jsxNode.name.name === "dnn-checkbox") {
23
+ const parent = context.getAncestors().find(ancestor => ancestor.type === "JSXElement");
24
+ if (parent) {
25
+ const hasLabel = parent.children.some(child => {
26
+ return child.type === "JSXElement" &&
27
+ child.openingElement.name.type === "JSXIdentifier" &&
28
+ child.openingElement.name.name === "label";
29
+ });
30
+ if (hasLabel) {
31
+ context.report({
32
+ node: node,
33
+ messageId: "noLabelSlotInCheckbox",
34
+ fix: (fixer) => {
35
+ if (parent && parent.type === "JSXElement" && Array.isArray(parent.children)) {
36
+ const label = parent.children.find(child =>
37
+ child &&
38
+ child.type === "JSXElement" &&
39
+ child.openingElement &&
40
+ child.openingElement.name &&
41
+ child.openingElement.name.type === "JSXIdentifier" &&
42
+ child.openingElement.name.name === "label");
43
+
44
+ if (label && label.type === "JSXElement") {
45
+ const labelText = context.sourceCode.getText(label).replace(/<label>|<\/label>/g, '').trim();
46
+ const checkboxText = context.sourceCode.getText(node);
47
+
48
+ // Combine the label text and checkbox into a label wrapper with multiline formatting
49
+ const fixedText = `<label>\n${labelText}\n${checkboxText}</dnn-checkbox>\n</label>`;
50
+
51
+ return fixer.replaceText(parent, fixedText);
52
+ }
53
+ }
54
+
55
+ return null;
56
+ }
57
+ });
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ };
64
+ }
65
+ };
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "Node",
6
+ "outDir": "./dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "declaration": true,
10
+ "skipLibCheck": true,
11
+ "types": ["jest", "node", "estree-jsx"],
12
+ "forceConsistentCasingInFileNames": true,
13
+ "sourceMap": true
14
+ },
15
+ "include": ["src", "jest.config.js"]
16
+ }