Skip to content

Commit 3fbe066

Browse files
committed
feat(ExpandableSection): Allow more control over toggle icon
Allow for custom icons and disabled icons.
1 parent 2409ed1 commit 3fbe066

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

packages/react-core/src/components/ExpandableSection/ExpandableSection.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export interface ExpandableSectionProps extends Omit<React.HTMLProps<HTMLDivElem
6060
toggleAriaLabel?: string;
6161
/** Accessible name via space delimtted list of IDs for the expandable section toggle. */
6262
toggleAriaLabelledBy?: string;
63+
/** Icon shown in toggle when variant is not truncated. */
64+
toggleIcon?: React.ReactNode;
65+
/** Whether to show a toggle icon when variant is not truncated. If omitted, it is important to ensure the current state of the ExpandableSection is conveyed, most likely by having dynamic toggle text. */
66+
hasToggleIcon?: boolean;
6367
/** Truncates the expandable content to the specified number of lines when using the
6468
* "truncate" variant.
6569
*/
@@ -204,6 +208,8 @@ class ExpandableSection extends Component<ExpandableSectionProps, ExpandableSect
204208
toggleContent,
205209
toggleAriaLabel,
206210
toggleAriaLabelledBy,
211+
toggleIcon = <AngleRightIcon />,
212+
hasToggleIcon = true,
207213
children,
208214
isExpanded,
209215
isDetached,
@@ -255,13 +261,10 @@ class ExpandableSection extends Component<ExpandableSectionProps, ExpandableSect
255261
aria-controls={uniqueContentId}
256262
id={uniqueToggleId}
257263
onClick={(event) => onToggle(event, !propOrStateIsExpanded)}
258-
{...(variant !== ExpandableSectionVariant.truncate && {
259-
icon: (
260-
<span className={css(styles.expandableSectionToggleIcon)}>
261-
<AngleRightIcon />
262-
</span>
263-
)
264-
})}
264+
{...(variant !== ExpandableSectionVariant.truncate &&
265+
hasToggleIcon && {
266+
icon: <span className={css(styles.expandableSectionToggleIcon)}>{toggleIcon}</span>
267+
})}
265268
aria-label={toggleAriaLabel}
266269
aria-labelledby={toggleAriaLabelledBy}
267270
>

packages/react-core/src/components/ExpandableSection/__tests__/ExpandableSection.test.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
33

44
import { ExpandableSection, ExpandableSectionVariant } from '../ExpandableSection';
55
import styles from '@patternfly/react-styles/css/components/ExpandableSection/expandable-section';
6+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
67

78
const props = { contentId: 'content-id', toggleId: 'toggle-id' };
89

@@ -208,3 +209,33 @@ test('Renders with aria-labelledby when toggleAriaLabelledBy is passed', () => {
208209

209210
expect(screen.getByRole('button')).toHaveAccessibleName('Test label');
210211
});
212+
213+
test('Can render custom toggle icon', () => {
214+
render(<ExpandableSection toggleIcon={<BellIcon data-testid="bell-icon" />}>Test content</ExpandableSection>);
215+
216+
expect(screen.getByTestId('bell-icon')).toBeInTheDocument();
217+
});
218+
219+
test('Does not render toggle icon when hasToggleIcon is false', () => {
220+
render(<ExpandableSection hasToggleIcon={false}>Test content</ExpandableSection>);
221+
222+
const button = screen.getByRole('button');
223+
expect(button.querySelector('.pf-v6-c-expandable-section__toggle-icon')).not.toBeInTheDocument();
224+
});
225+
226+
test('Does not render custom toggle icon when hasToggleIcon is false', () => {
227+
render(
228+
<ExpandableSection toggleIcon={<BellIcon data-testid="bell-icon" />} hasToggleIcon={false}>
229+
Test content
230+
</ExpandableSection>
231+
);
232+
233+
expect(screen.queryByTestId('bell-icon')).not.toBeInTheDocument();
234+
});
235+
236+
test('Renders toggle icon by default when hasToggleIcon is true', () => {
237+
render(<ExpandableSection>Test content</ExpandableSection>);
238+
239+
const button = screen.getByRole('button');
240+
expect(button.querySelector('.pf-v6-c-expandable-section__toggle-icon')).toBeInTheDocument();
241+
});

0 commit comments

Comments
 (0)