Skip to content

Commit 23adc28

Browse files
authored
feat(851): PageToggleButton BarsIcon to isHamburgerButton prop (#852)
* feat(851): PageToggleButton BarsIcon to isHamburgerButton prop Signed-off-by: gitdallas <[email protected]> mend * check that BarsIcon in pageToggleButton is from pf icons Signed-off-by: gitdallas <[email protected]> --------- Signed-off-by: gitdallas <[email protected]>
1 parent 8fbc87a commit 23adc28

File tree

7 files changed

+230
-1
lines changed

7 files changed

+230
-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,86 @@
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+
// PageToggleButton not imported from PatternFly, but BarsIcon is
22+
{
23+
code: `import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
24+
},
25+
// Neither PageToggleButton nor BarsIcon imported from PatternFly
26+
{
27+
code: `import { BarsIcon } from 'some-other-package'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
28+
},
29+
// PageToggleButton imported from PatternFly, but BarsIcon not imported from PatternFly
30+
{
31+
code: `import { PageToggleButton } from '@patternfly/react-core'; import { BarsIcon } from 'some-other-package'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
32+
},
33+
],
34+
invalid: [
35+
{
36+
code: `import { PageToggleButton } from '@patternfly/react-core'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
37+
output: `import { PageToggleButton } from '@patternfly/react-core'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton isHamburgerButton />`,
38+
errors: [
39+
{
40+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
41+
type: "JSXElement",
42+
},
43+
],
44+
},
45+
{
46+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/esm/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
47+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/esm/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton isHamburgerButton />`,
48+
errors: [
49+
{
50+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
51+
type: "JSXElement",
52+
},
53+
],
54+
},
55+
{
56+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/js/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
57+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/js/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton isHamburgerButton />`,
58+
errors: [
59+
{
60+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
61+
type: "JSXElement",
62+
},
63+
],
64+
},
65+
{
66+
code: `import { PageToggleButton } from '@patternfly/react-core/dist/dynamic/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /></PageToggleButton>`,
67+
output: `import { PageToggleButton } from '@patternfly/react-core/dist/dynamic/components/PageToggleButton/index.js'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton isHamburgerButton />`,
68+
errors: [
69+
{
70+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
71+
type: "JSXElement",
72+
},
73+
],
74+
},
75+
{
76+
code: `import { PageToggleButton } from '@patternfly/react-core'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton><BarsIcon /><SomeOtherContent /></PageToggleButton>`,
77+
output: `import { PageToggleButton } from '@patternfly/react-core'; import { BarsIcon } from '@patternfly/react-icons'; <PageToggleButton isHamburgerButton><SomeOtherContent /></PageToggleButton>`,
78+
errors: [
79+
{
80+
message: `The BarsIcon child component should be replaced with the \`isHamburgerButton\` prop on PageToggleButton.`,
81+
type: "JSXElement",
82+
},
83+
],
84+
},
85+
],
86+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
41+
if (!barsIconChild) {
42+
return; // No BarsIcon child found
43+
}
44+
45+
// Check if BarsIcon is imported from PatternFly
46+
if (!isReactIcon(context, barsIconChild)) {
47+
return; // BarsIcon is not from PatternFly, skip
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+
// Check if we need to make the element self-closing
55+
const otherChildren = node.children.filter(child => child !== barsIconChild);
56+
const shouldBeSelfClosing = otherChildren.length === 0 && node.closingElement;
57+
58+
// Always add the isHamburgerButton prop
59+
const addPropFix = fixer.insertTextAfter(
60+
node.openingElement.name,
61+
" isHamburgerButton"
62+
);
63+
64+
if (shouldBeSelfClosing) {
65+
// For self-closing case: add prop and make self-closing (which removes children)
66+
return [
67+
addPropFix,
68+
...makeJSXElementSelfClosing(node, context, fixer, true)
69+
];
70+
} else {
71+
// For non-self-closing case: add prop and remove the specific child
72+
return [
73+
addPropFix,
74+
...removeElement(fixer, barsIconChild)
75+
];
76+
}
77+
},
78+
});
79+
}
80+
},
81+
};
82+
},
83+
};
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)