Skip to content

Commit 159385f

Browse files
committed
feat(851): PageToggleButton BarsIcon to isHamburgerButton prop
Signed-off-by: gitdallas <5322142+gitdallas@users.noreply.github.com>
1 parent 8fbc87a commit 159385f

File tree

7 files changed

+222
-1
lines changed

7 files changed

+222
-1
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### pageToggleButton-replace-barsIcon-with-isHamburgerButton [(#11861)](https://github.com/patternfly/patternfly-react/pull/11861)
2+
3+
The `BarsIcon` child component should be replaced with the `isHamburgerButton` prop on PageToggleButton. This simplifies the API and provides a more semantic way to indicate that the toggle button should render as a hamburger menu button. It also allows for the button to use animation.
4+
5+
#### Examples
6+
7+
In:
8+
9+
```jsx
10+
%inputExample%
11+
```
12+
13+
Out:
14+
15+
```jsx
16+
%outputExample%
17+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const ruleTester = require("../../ruletester");
2+
import * as rule from "./pageToggleButton-replace-barsIcon-with-isHamburgerButton";
3+
4+
ruleTester.run("pageToggleButton-replace-barsIcon-with-isHamburgerButton", rule, {
5+
valid: [
6+
{
7+
code: `<PageToggleButton isHamburgerButton />`,
8+
},
9+
{
10+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton isHamburgerButton />`,
11+
},
12+
{
13+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton><SomeOtherIcon /></PageToggleButton>`,
14+
},
15+
{
16+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton>Some text content</PageToggleButton>`,
17+
},
18+
{
19+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton />`,
20+
},
21+
],
22+
invalid: [
23+
{
24+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
25+
output: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton isHamburgerButton />`,
26+
errors: [
27+
{
28+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
29+
type: "JSXElement",
30+
},
31+
],
32+
},
33+
{
34+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/esm/components/PageToggleButton/index.js'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
35+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/esm/components/PageToggleButton/index.js'; <PageToggleButton isHamburgerButton />`,
36+
errors: [
37+
{
38+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
39+
type: "JSXElement",
40+
},
41+
],
42+
},
43+
{
44+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/js/components/PageToggleButton/index.js'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
45+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/js/components/PageToggleButton/index.js'; <PageToggleButton isHamburgerButton />`,
46+
errors: [
47+
{
48+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
49+
type: "JSXElement",
50+
},
51+
],
52+
},
53+
{
54+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/dynamic/components/PageToggleButton/index.js'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
55+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/dynamic/components/PageToggleButton/index.js'; <PageToggleButton isHamburgerButton />`,
56+
errors: [
57+
{
58+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
59+
type: "JSXElement",
60+
},
61+
],
62+
},
63+
{
64+
code: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton><BarsIcon /><SomeOtherContent /></PageToggleButton>`,
65+
output: `import { PageToggleButton } from '@patternfly/react-core'; <PageToggleButton isHamburgerButton><SomeOtherContent /></PageToggleButton>`,
66+
errors: [
67+
{
68+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
69+
type: "JSXElement",
70+
},
71+
],
72+
},
73+
],
74+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Rule } from "eslint";
2+
import { JSXElement } from "estree-jsx";
3+
import {
4+
getFromPackage,
5+
getChildJSXElementByName,
6+
isReactIcon,
7+
getAttribute,
8+
removeElement,
9+
makeJSXElementSelfClosing,
10+
} from "../../helpers";
11+
12+
// https://github.com/patternfly/patternfly-react/pull/11861
13+
module.exports = {
14+
meta: { fixable: "code" },
15+
create: function (context: Rule.RuleContext) {
16+
const source = context.getSourceCode();
17+
const { imports } = getFromPackage(context, "@patternfly/react-core");
18+
19+
const pageToggleButtonImport = imports.find(
20+
(specifier) => specifier.imported.name === "PageToggleButton"
21+
);
22+
23+
return !pageToggleButtonImport
24+
? {}
25+
: {
26+
JSXElement(node: JSXElement) {
27+
if (
28+
node.openingElement.name.type === "JSXIdentifier" &&
29+
pageToggleButtonImport.local.name === node.openingElement.name.name
30+
) {
31+
// Check if isHamburgerButton prop already exists
32+
const isHamburgerButtonProp = getAttribute(node, "isHamburgerButton");
33+
34+
if (isHamburgerButtonProp) {
35+
return; // Already has the prop, skip
36+
}
37+
38+
// Check if BarsIcon is a direct child
39+
const barsIconChild = getChildJSXElementByName(node, "BarsIcon");
40+
const isBarsIconChild = barsIconChild && (
41+
isReactIcon(context, barsIconChild) ||
42+
barsIconChild.openingElement.name.type === "JSXIdentifier" &&
43+
barsIconChild.openingElement.name.name === "BarsIcon"
44+
);
45+
46+
if (!isBarsIconChild) {
47+
return; // No BarsIcon child found
48+
}
49+
50+
context.report({
51+
node,
52+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
53+
fix(fixer) {
54+
const fixes = [];
55+
56+
// Add isHamburgerButton prop
57+
fixes.push(
58+
fixer.insertTextAfter(
59+
node.openingElement.name,
60+
" isHamburgerButton"
61+
)
62+
);
63+
64+
// Remove the BarsIcon child
65+
fixes.push(...removeElement(fixer, barsIconChild));
66+
67+
// Make the element self-closing if it has no other children
68+
const otherChildren = node.children.filter(child => child !== barsIconChild);
69+
if (otherChildren.length === 0 && node.closingElement) {
70+
// Use the helper to make the element self-closing (it will handle removing the BarsIcon child)
71+
return [
72+
fixer.insertTextAfter(
73+
node.openingElement.name,
74+
" isHamburgerButton"
75+
),
76+
...makeJSXElementSelfClosing(node, context, fixer, true)
77+
];
78+
}
79+
80+
return fixes;
81+
},
82+
});
83+
}
84+
},
85+
};
86+
},
87+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { PageToggleButton } from "@patternfly/react-core";
2+
import { BarsIcon } from "@patternfly/react-icons";
3+
4+
export const PageToggleButtonReplaceBarsIconWithIsHamburgerButtonInput = () => (
5+
<PageToggleButton>
6+
<BarsIcon />
7+
</PageToggleButton>
8+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { PageToggleButton } from "@patternfly/react-core";
2+
3+
export const PageToggleButtonReplaceBarsIconWithIsHamburgerButtonOutput = () => (
4+
<PageToggleButton isHamburgerButton />
5+
);

packages/pf-codemods/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,35 @@ export const PageSidebarRemoveThemePropInput = () => (
22062206

22072207
The markup for Page has changed. When either the `horizontalSubnav` or `breadcrumb` props are passed, a PageBody component will always wrap the contents.
22082208

2209+
### pageToggleButton-replace-barsIcon-with-isHamburgerButton [(#11861)](https://github.com/patternfly/patternfly-react/pull/11861)
2210+
2211+
The `BarsIcon` child component should be replaced with the `isHamburgerButton` prop on PageToggleButton. This simplifies the API and provides a more semantic way to indicate that the toggle button should render as a hamburger menu button. It also allows for the button to use animation.
2212+
2213+
#### Examples
2214+
2215+
In:
2216+
2217+
```jsx
2218+
import { PageToggleButton } from "@patternfly/react-core";
2219+
import { BarsIcon } from "@patternfly/react-icons";
2220+
2221+
export const PageToggleButtonReplaceBarsIconWithIsHamburgerButtonInput = () => (
2222+
<PageToggleButton>
2223+
<BarsIcon />
2224+
</PageToggleButton>
2225+
);
2226+
```
2227+
2228+
Out:
2229+
2230+
```jsx
2231+
import { PageToggleButton } from "@patternfly/react-core";
2232+
2233+
export const PageToggleButtonReplaceBarsIconWithIsHamburgerButtonOutput = () => (
2234+
<PageToggleButton isHamburgerButton />
2235+
);
2236+
```
2237+
22092238
### pagination-warn-markup-changed [(#10662)](https://github.com/patternfly/patternfly-react/pull/10662)
22102239

22112240
The markup for Pagination has changed. There is now a wrapper element rendered around the PaginationOptionsMenu toggle. This rule does not provide a fixer, but will throw a warning.

test/test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
ChartThemeVariant,
1010
} from "@patternfly/react-charts";
1111
import { CodeEditor } from "@patternfly/react-code-editor";
12-
import { FrogIcon } from "@patternfly/react-icons";
12+
import { BarsIcon, FrogIcon } from "@patternfly/react-icons";
1313

1414
import {
1515
AboutModal,
@@ -193,6 +193,7 @@ const themeClassName = 'pf-theme-dark';
193193
direction={DropdownDirection.up}
194194
/>
195195
<DropdownContext.Provider />
196+
<PageToggleButton><BarsIcon /></PageToggleButton>
196197
<DropdownItem isHovered={true} />
197198
<DropdownToggle isPrimary onToggle={} />
198199
<DropdownToggleCheckbox

0 commit comments

Comments
 (0)