Skip to content

Commit

Permalink
feat(JumpLinks): warned about href and markup/type updates (#575)
Browse files Browse the repository at this point in the history
* feat(JumpLinks): warned about href and markup/type updates

* Separated href rule so it will flag as an error

* Added typing to PageSection rules

* Updated typing in markup warn rule
  • Loading branch information
thatblindgeye authored Feb 26, 2024
1 parent e90502b commit 0af1541
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const warningRules = [
"emptyState-warn-change-structure",
"formControls-updated-markup",
"horizontalSubnav-warn-ariaLabel",
"jumpLinksItem-warn-markup-change",
"label-warn-truncated-default",
"nav-warn-flyouts-now-inline",
"overflowMenu-warn-updated-dropdownItem",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### jumpLinksItem-href-required [(#10027)](https://github.com/patternfly/patternfly-react/pull/10027)

The `href` prop on JumpLinksItem is now required.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const ruleTester = require("../../ruletester");
import * as rule from "./jumpLinksItem-href-required";

ruleTester.run("jumpLinksItem-href-required", rule, {
valid: [
{
code: `import { JumpLinksItem } from 'someOtherPackage'; <JumpLinksItem />`,
},
{
code: `import { JumpLinksItem } from '@patternfly/react-core'; <JumpLinksItem href="someURL" />`,
},
],
invalid: [
{
code: `import { JumpLinksItem } from '@patternfly/react-core'; <JumpLinksItem />`,
output: `import { JumpLinksItem } from '@patternfly/react-core'; <JumpLinksItem />`,
errors: [
{
message: `The \`href\` prop on JumpLinksItem is now required.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { JumpLinksItem } from '@patternfly/react-core'; <JumpLinksItem href />`,
output: `import { JumpLinksItem } from '@patternfly/react-core'; <JumpLinksItem href />`,
errors: [
{
message: `The \`href\` prop on JumpLinksItem is now required.`,
type: "JSXOpeningElement",
},
],
},
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { getFromPackage } from "../../helpers";
import { Rule } from "eslint";
import { JSXOpeningElement, JSXAttribute } from "estree-jsx";

// https://github.com/patternfly/patternfly-react/pull/10027
module.exports = {
meta: {},
create: function (context: Rule.RuleContext) {
const { imports } = getFromPackage(context, "@patternfly/react-core");

const jumpLinksItemImport = imports.find(
(specifier) => specifier.imported.name === "JumpLinksItem"
);

return !jumpLinksItemImport
? {}
: {
JSXOpeningElement(node: JSXOpeningElement) {
if (
node.name.type === "JSXIdentifier" &&
jumpLinksItemImport.local.name === node.name.name
) {
const hrefAttribute = node.attributes.find(
(attribute) =>
attribute.type === "JSXAttribute" &&
attribute.name.name === "href"
);

if (!hrefAttribute || !(hrefAttribute as JSXAttribute).value) {
context.report({
node,
message: "The `href` prop on JumpLinksItem is now required.",
});
}
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { JumpLinksItem } from "@patternfly/react-core";

export const JumpLinksItemWarnMarkupChangeInput = () => (
<>
<JumpLinksItem />
<JumpLinksItem href />
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { JumpLinksItem } from "@patternfly/react-core";

export const JumpLinksItemWarnMarkupChangeInput = () => (
<>
<JumpLinksItem />
<JumpLinksItem href />
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### jumpLinksItem-warn-markup-change [(#10027)](https://github.com/patternfly/patternfly-react/pull/10027)

The markup for JumpLinksItem has changed, as it now uses our Button component internally. Additionally, the `onClick` prop type has been updated to just `React.MouseEvent` (previously `React.MouseEvent<HTMLAnchorElement>`).
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const ruleTester = require("../../ruletester");
import * as rule from "./jumpLinksItem-warn-markup-change";

ruleTester.run("jumpLinksItem-warn-markup-change", rule, {
valid: [
{
code: `import { JumpLinksItem } from '@someOtherPackage';`,
},
],
invalid: [
{
code: `import { JumpLinksItem } from '@patternfly/react-core';`,
output: `import { JumpLinksItem } from '@patternfly/react-core';`,
errors: [
{
message: `The markup for JumpLinksItem has changed, as it now uses our Button component internally. Additionally, the \`onClick\` prop type has been updated to just \`React.MouseEvent\` (previously \`React.MouseEvent<HTMLAnchorElement>\`).`,
type: "ImportDeclaration",
},
],
},
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getFromPackage } from "../../helpers";
import { Rule } from "eslint";
import { ImportDeclaration, ImportSpecifier } from "estree-jsx";

// https://github.com/patternfly/patternfly-react/pull/10027
module.exports = {
meta: {},
create: function (context: Rule.RuleContext) {
const { imports } = getFromPackage(context, "@patternfly/react-core");

const jumpLinksItemImport = imports.find(
(specifier) => specifier.imported.name === "JumpLinksItem"
);

return !jumpLinksItemImport
? {}
: {
ImportDeclaration(node: ImportDeclaration) {
if (
node.specifiers.find(
(specifier) =>
specifier.type === "ImportSpecifier" &&
specifier.imported.name === jumpLinksItemImport.imported.name
)
) {
context.report({
node,
message:
"The markup for JumpLinksItem has changed, as it now uses our Button component internally. Additionally, the `onClick` prop type has been updated to just `React.MouseEvent` (previously `React.MouseEvent<HTMLAnchorElement>`).",
});
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { JumpLinksItem } from "@patternfly/react-core";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { JumpLinksItem } from "@patternfly/react-core";
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import { getFromPackage } from "../../helpers";
import { Rule } from "eslint";
import { JSXOpeningElement, JSXAttribute, Literal } from "estree-jsx";
import { isJsxAttribute } from "typescript";

// https://github.com/patternfly/patternfly-react/pull/9774
// https://github.com/patternfly/patternfly-react/pull/9848
module.exports = {
meta: { fixable: "code" },
create: function (context: {
report: (arg0: {
node: any;
message: string;
fix(fixer: any): any;
}) => void;
}) {
create: function (context: Rule.RuleContext) {
const { imports } = getFromPackage(context, "@patternfly/react-core");

const componentImports = imports.filter(
(specifier: { imported: { name: string } }) =>
specifier.imported.name === "PageSection"
const pageSectionImport = imports.find(
(specifier) => specifier.imported.name === "PageSection"
);

return !componentImports.length
return !pageSectionImport
? {}
: {
JSXOpeningElement(node: { name: { name: any }; attributes: any[] }) {
JSXOpeningElement(node: JSXOpeningElement) {
if (
componentImports
.map((imp: { local: { name: any } }) => imp.local.name)
.includes(node.name.name)
node.name.type === "JSXIdentifier" &&
pageSectionImport.local.name === node.name.name
) {
const attribute = node.attributes.find(
(attr: { name: { name: string } }) =>
attr.name?.name === "variant"
);
(attr) =>
attr.type === "JSXAttribute" && attr.name.name === "variant"
) as JSXAttribute | undefined;

if (!attribute || !attribute.value) {
return;
}

if (
attribute &&
attribute.value.type === "Literal" &&
typeof attribute.value.value === "string" &&
!["default", "secondary"].includes(attribute.value.value)
) {
context.report({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
import { getFromPackage } from "../../helpers";
import { Rule } from "eslint";
import { JSXOpeningElement } from "estree-jsx";

// https://github.com/patternfly/patternfly-react/pull/9848
module.exports = {
meta: {},
create: function (context: {
report: (arg0: {
node: any;
message: string;
fix?(fixer: any): any;
}) => void;
}) {
create: function (context: Rule.RuleContext) {
const { imports } = getFromPackage(context, "@patternfly/react-core");

const componentImports = imports.filter(
(specifier: { imported: { name: string } }) =>
specifier.imported.name === "PageSection"
const pageSectionImport = imports.find(
(specifier) => specifier.imported.name === "PageSection"
);

return !componentImports.length
return !pageSectionImport
? {}
: {
JSXOpeningElement(node: { name: { name: any }; attributes: any[] }) {
JSXOpeningElement(node: JSXOpeningElement) {
if (
componentImports
.map((imp: { local: { name: any } }) => imp.local.name)
.includes(node.name.name)
node.name.type === "JSXIdentifier" &&
pageSectionImport.local.name === node.name.name
) {
const attribute = node.attributes.find(
(attr: { name: { name: string } }) =>
attr.name?.name === "variant"
(attr) =>
attr.type === "JSXAttribute" && attr.name.name === "variant"
);
if (attribute) {
context.report({
Expand Down

0 comments on commit 0af1541

Please sign in to comment.