@patternfly/react-core 6.5.0-prerelease.3 → 6.5.0-prerelease.4
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.
- package/CHANGELOG.md +6 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/AboutModal/package.json +1 -1
- package/dist/dynamic/components/Accordion/package.json +1 -1
- package/dist/dynamic/components/ActionList/package.json +1 -1
- package/dist/dynamic/components/Alert/package.json +1 -1
- package/dist/dynamic/components/Avatar/package.json +1 -1
- package/dist/dynamic/components/BackToTop/package.json +1 -1
- package/dist/dynamic/components/Backdrop/package.json +1 -1
- package/dist/dynamic/components/BackgroundImage/package.json +1 -1
- package/dist/dynamic/components/Badge/package.json +1 -1
- package/dist/dynamic/components/Banner/package.json +1 -1
- package/dist/dynamic/components/Brand/package.json +1 -1
- package/dist/dynamic/components/Breadcrumb/package.json +1 -1
- package/dist/dynamic/components/Button/package.json +1 -1
- package/dist/dynamic/components/CalendarMonth/package.json +1 -1
- package/dist/dynamic/components/Card/package.json +1 -1
- package/dist/dynamic/components/Checkbox/package.json +1 -1
- package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
- package/dist/dynamic/components/CodeBlock/package.json +1 -1
- package/dist/dynamic/components/Compass/package.json +1 -1
- package/dist/dynamic/components/Content/package.json +1 -1
- package/dist/dynamic/components/DataList/package.json +1 -1
- package/dist/dynamic/components/DatePicker/package.json +1 -1
- package/dist/dynamic/components/DescriptionList/package.json +1 -1
- package/dist/dynamic/components/Divider/package.json +1 -1
- package/dist/dynamic/components/Drawer/package.json +1 -1
- package/dist/dynamic/components/Dropdown/package.json +1 -1
- package/dist/dynamic/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/components/EmptyState/package.json +1 -1
- package/dist/dynamic/components/ExpandableSection/package.json +1 -1
- package/dist/dynamic/components/FileUpload/package.json +1 -1
- package/dist/dynamic/components/Form/package.json +1 -1
- package/dist/dynamic/components/FormSelect/package.json +1 -1
- package/dist/dynamic/components/HelperText/package.json +1 -1
- package/dist/dynamic/components/Hint/package.json +1 -1
- package/dist/dynamic/components/Icon/package.json +1 -1
- package/dist/dynamic/components/InputGroup/package.json +1 -1
- package/dist/dynamic/components/JumpLinks/package.json +1 -1
- package/dist/dynamic/components/Label/package.json +1 -1
- package/dist/dynamic/components/List/package.json +1 -1
- package/dist/dynamic/components/LoginPage/package.json +1 -1
- package/dist/dynamic/components/Masthead/package.json +1 -1
- package/dist/dynamic/components/Menu/package.json +1 -1
- package/dist/dynamic/components/MenuToggle/package.json +1 -1
- package/dist/dynamic/components/Modal/package.json +1 -1
- package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
- package/dist/dynamic/components/Nav/package.json +1 -1
- package/dist/dynamic/components/NotificationBadge/package.json +1 -1
- package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
- package/dist/dynamic/components/NumberInput/package.json +1 -1
- package/dist/dynamic/components/OverflowMenu/package.json +1 -1
- package/dist/dynamic/components/Page/package.json +1 -1
- package/dist/dynamic/components/Pagination/package.json +1 -1
- package/dist/dynamic/components/Panel/package.json +1 -1
- package/dist/dynamic/components/Popover/package.json +1 -1
- package/dist/dynamic/components/Progress/package.json +1 -1
- package/dist/dynamic/components/ProgressStepper/package.json +1 -1
- package/dist/dynamic/components/Radio/package.json +1 -1
- package/dist/dynamic/components/SearchInput/package.json +1 -1
- package/dist/dynamic/components/Select/package.json +1 -1
- package/dist/dynamic/components/Sidebar/package.json +1 -1
- package/dist/dynamic/components/SimpleList/package.json +1 -1
- package/dist/dynamic/components/Skeleton/package.json +1 -1
- package/dist/dynamic/components/SkipToContent/package.json +1 -1
- package/dist/dynamic/components/Slider/package.json +1 -1
- package/dist/dynamic/components/Spinner/package.json +1 -1
- package/dist/dynamic/components/Switch/package.json +1 -1
- package/dist/dynamic/components/Tabs/package.json +1 -1
- package/dist/dynamic/components/TextArea/package.json +1 -1
- package/dist/dynamic/components/TextInput/package.json +1 -1
- package/dist/dynamic/components/TextInputGroup/package.json +1 -1
- package/dist/dynamic/components/TimePicker/package.json +1 -1
- package/dist/dynamic/components/Timestamp/package.json +1 -1
- package/dist/dynamic/components/Title/package.json +1 -1
- package/dist/dynamic/components/ToggleGroup/package.json +1 -1
- package/dist/dynamic/components/Toolbar/package.json +1 -1
- package/dist/dynamic/components/Tooltip/package.json +1 -1
- package/dist/dynamic/components/TreeView/package.json +1 -1
- package/dist/dynamic/components/Truncate/package.json +1 -1
- package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
- package/dist/dynamic/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
- package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
- package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
- package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
- package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/dynamic/helpers/AnimationsProvider/AnimationsProvider/package.json +1 -1
- package/dist/dynamic/helpers/AnimationsProvider/package.json +1 -1
- package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
- package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
- package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
- package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
- package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
- package/dist/dynamic/helpers/constants/package.json +1 -1
- package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
- package/dist/dynamic/helpers/fileUtils/package.json +1 -1
- package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
- package/dist/dynamic/helpers/package.json +1 -1
- package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
- package/dist/dynamic/helpers/typeUtils/package.json +1 -1
- package/dist/dynamic/helpers/useInterval/package.json +1 -1
- package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
- package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
- package/dist/dynamic/helpers/util/package.json +1 -1
- package/dist/dynamic/layouts/Bullseye/package.json +1 -1
- package/dist/dynamic/layouts/Flex/package.json +1 -1
- package/dist/dynamic/layouts/Gallery/package.json +1 -1
- package/dist/dynamic/layouts/Grid/package.json +1 -1
- package/dist/dynamic/layouts/Level/package.json +1 -1
- package/dist/dynamic/layouts/Split/package.json +1 -1
- package/dist/dynamic/layouts/Stack/package.json +1 -1
- package/dist/dynamic/styles/package.json +1 -1
- package/dist/esm/components/ExpandableSection/ExpandableSection.d.ts +5 -0
- package/dist/esm/components/ExpandableSection/ExpandableSection.d.ts.map +1 -1
- package/dist/esm/components/ExpandableSection/ExpandableSection.js +3 -2
- package/dist/esm/components/ExpandableSection/ExpandableSection.js.map +1 -1
- package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.d.ts +5 -0
- package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.d.ts.map +1 -1
- package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.js +3 -2
- package/dist/esm/components/ExpandableSection/ExpandableSectionToggle.js.map +1 -1
- package/dist/js/components/ExpandableSection/ExpandableSection.d.ts +5 -0
- package/dist/js/components/ExpandableSection/ExpandableSection.d.ts.map +1 -1
- package/dist/js/components/ExpandableSection/ExpandableSection.js +3 -2
- package/dist/js/components/ExpandableSection/ExpandableSection.js.map +1 -1
- package/dist/js/components/ExpandableSection/ExpandableSectionToggle.d.ts +5 -0
- package/dist/js/components/ExpandableSection/ExpandableSectionToggle.d.ts.map +1 -1
- package/dist/js/components/ExpandableSection/ExpandableSectionToggle.js +3 -2
- package/dist/js/components/ExpandableSection/ExpandableSectionToggle.js.map +1 -1
- package/dist/umd/assets/{output-b6v4lKPy.css → output-TagVdL0S.css} +13413 -13413
- package/dist/umd/react-core.min.js +1 -1
- package/helpers/package.json +1 -1
- package/layouts/package.json +1 -1
- package/next/package.json +1 -1
- package/package.json +2 -2
- package/src/components/ExpandableSection/ExpandableSection.tsx +9 -2
- package/src/components/ExpandableSection/ExpandableSectionToggle.tsx +48 -38
- package/src/components/ExpandableSection/__tests__/ExpandableSection.test.tsx +29 -0
- package/src/components/ExpandableSection/__tests__/ExpandableSectionToggle.test.tsx +28 -0
- package/src/components/ExpandableSection/examples/ExpandableSection.md +8 -0
- package/src/components/ExpandableSection/examples/ExpandableSectionCustomToggle.tsx +31 -16
- package/src/components/ExpandableSection/examples/ExpandableSectionWithHeading.tsx +89 -0
package/helpers/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.5.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.5.0-prerelease.3","private":true}
|
package/layouts/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.5.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.5.0-prerelease.3","private":true}
|
package/next/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.5.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.5.0-prerelease.3","private":true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "6.5.0-prerelease.
|
|
3
|
+
"version": "6.5.0-prerelease.4",
|
|
4
4
|
"description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"react": "^17 || ^18 || ^19",
|
|
64
64
|
"react-dom": "^17 || ^18 || ^19"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "912729437db337b5e576adbe8d06bdf2bc04b189"
|
|
67
67
|
}
|
|
@@ -74,6 +74,11 @@ export interface ExpandableSectionProps extends Omit<React.HTMLProps<HTMLDivElem
|
|
|
74
74
|
* animation will not occur.
|
|
75
75
|
*/
|
|
76
76
|
direction?: 'up' | 'down';
|
|
77
|
+
/** The HTML element to use for the toggle wrapper. Can be 'div' (default) or any heading level.
|
|
78
|
+
* When using heading elements, the button will be rendered inside the heading for proper semantics.
|
|
79
|
+
* This is useful when the toggle text should function as a heading in the document structure.
|
|
80
|
+
*/
|
|
81
|
+
toggleWrapper?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
interface ExpandableSectionState {
|
|
@@ -218,6 +223,7 @@ class ExpandableSection extends Component<ExpandableSectionProps, ExpandableSect
|
|
|
218
223
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
219
224
|
truncateMaxLines,
|
|
220
225
|
direction,
|
|
226
|
+
toggleWrapper = 'div',
|
|
221
227
|
...props
|
|
222
228
|
} = this.props;
|
|
223
229
|
|
|
@@ -250,9 +256,10 @@ class ExpandableSection extends Component<ExpandableSectionProps, ExpandableSect
|
|
|
250
256
|
|
|
251
257
|
const computedToggleContent =
|
|
252
258
|
typeof toggleContent === 'function' ? toggleContent(propOrStateIsExpanded) : toggleContent;
|
|
259
|
+
const ToggleWrapper = toggleWrapper as any;
|
|
253
260
|
|
|
254
261
|
const expandableToggle = !isDetached && (
|
|
255
|
-
<
|
|
262
|
+
<ToggleWrapper className={`${styles.expandableSection}__toggle`}>
|
|
256
263
|
<Button
|
|
257
264
|
variant="link"
|
|
258
265
|
{...(variant === ExpandableSectionVariant.truncate && { isInline: true })}
|
|
@@ -272,7 +279,7 @@ class ExpandableSection extends Component<ExpandableSectionProps, ExpandableSect
|
|
|
272
279
|
>
|
|
273
280
|
{computedToggleContent || computedToggleText}
|
|
274
281
|
</Button>
|
|
275
|
-
</
|
|
282
|
+
</ToggleWrapper>
|
|
276
283
|
);
|
|
277
284
|
|
|
278
285
|
return (
|
|
@@ -34,6 +34,11 @@ export interface ExpandableSectionToggleProps extends Omit<React.HTMLProps<HTMLD
|
|
|
34
34
|
toggleAriaLabel?: string;
|
|
35
35
|
/** Accessible name via space delimtted list of IDs for the expandable section toggle. */
|
|
36
36
|
toggleAriaLabelledBy?: string;
|
|
37
|
+
/** The HTML element to use for the toggle wrapper. Can be 'div' (default) or any heading level.
|
|
38
|
+
* When using heading elements, the button will be rendered inside the heading for proper semantics.
|
|
39
|
+
* This is useful when the toggle text should function as a heading in the document structure.
|
|
40
|
+
*/
|
|
41
|
+
toggleWrapper?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
export const ExpandableSectionToggle: React.FunctionComponent<ExpandableSectionToggleProps> = ({
|
|
@@ -48,45 +53,50 @@ export const ExpandableSectionToggle: React.FunctionComponent<ExpandableSectionT
|
|
|
48
53
|
isDetached,
|
|
49
54
|
toggleAriaLabel,
|
|
50
55
|
toggleAriaLabelledBy,
|
|
56
|
+
toggleWrapper = 'div',
|
|
51
57
|
...props
|
|
52
|
-
}: ExpandableSectionToggleProps) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
58
|
+
}: ExpandableSectionToggleProps) => {
|
|
59
|
+
const ToggleWrapper = toggleWrapper as any;
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
className={css(
|
|
64
|
+
styles.expandableSection,
|
|
65
|
+
isExpanded && styles.modifiers.expanded,
|
|
66
|
+
hasTruncatedContent && styles.modifiers.truncate,
|
|
67
|
+
isDetached && 'pf-m-detached',
|
|
68
|
+
className
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
<ToggleWrapper className={`${styles.expandableSection}__toggle`}>
|
|
73
|
+
<Button
|
|
74
|
+
variant="link"
|
|
75
|
+
{...(hasTruncatedContent && { isInline: true })}
|
|
76
|
+
aria-expanded={isExpanded}
|
|
77
|
+
aria-controls={contentId}
|
|
78
|
+
onClick={() => onToggle(!isExpanded)}
|
|
79
|
+
id={toggleId}
|
|
80
|
+
{...(!hasTruncatedContent && {
|
|
81
|
+
icon: (
|
|
82
|
+
<span
|
|
83
|
+
className={css(
|
|
84
|
+
styles.expandableSectionToggleIcon,
|
|
85
|
+
isExpanded && direction === 'up' && styles.modifiers.expandTop // TODO: next breaking change move this class to the outer styles.expandableSection wrapper
|
|
86
|
+
)}
|
|
87
|
+
>
|
|
88
|
+
<AngleRightIcon />
|
|
89
|
+
</span>
|
|
90
|
+
)
|
|
91
|
+
})}
|
|
92
|
+
aria-label={toggleAriaLabel}
|
|
93
|
+
aria-labelledby={toggleAriaLabelledBy}
|
|
94
|
+
>
|
|
95
|
+
{children}
|
|
96
|
+
</Button>
|
|
97
|
+
</ToggleWrapper>
|
|
88
98
|
</div>
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
);
|
|
100
|
+
};
|
|
91
101
|
|
|
92
102
|
ExpandableSectionToggle.displayName = 'ExpandableSectionToggle';
|
|
@@ -208,6 +208,7 @@ test('Renders with aria-labelledby when toggleAriaLabelledBy is passed', () => {
|
|
|
208
208
|
|
|
209
209
|
expect(screen.getByRole('button')).toHaveAccessibleName('Test label');
|
|
210
210
|
});
|
|
211
|
+
|
|
211
212
|
test('Renders toggleContent as a function in uncontrolled mode (collapsed)', () => {
|
|
212
213
|
render(
|
|
213
214
|
<ExpandableSection toggleContent={(isExpanded) => (isExpanded ? 'Hide details' : 'Show details')}>
|
|
@@ -242,3 +243,31 @@ test('Renders toggleContent as a function in controlled mode', () => {
|
|
|
242
243
|
|
|
243
244
|
expect(screen.getByRole('button', { name: 'Collapse' })).toBeInTheDocument();
|
|
244
245
|
});
|
|
246
|
+
|
|
247
|
+
test('Renders with default div wrapper when toggleWrapper is not specified', () => {
|
|
248
|
+
render(<ExpandableSection data-testid="test-id">Test content</ExpandableSection>);
|
|
249
|
+
|
|
250
|
+
const toggle = screen.getByRole('button').parentElement;
|
|
251
|
+
expect(toggle?.tagName).toBe('DIV');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('Renders with h2 wrapper when toggleWrapper="h2"', () => {
|
|
255
|
+
render(
|
|
256
|
+
<ExpandableSection data-testid="test-id" toggleWrapper="h2">
|
|
257
|
+
Test content
|
|
258
|
+
</ExpandableSection>
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
expect(screen.getByRole('heading', { level: 2 })).toBeInTheDocument();
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test('Renders with div wrapper when toggleWrapper="div"', () => {
|
|
265
|
+
render(
|
|
266
|
+
<ExpandableSection data-testid="test-id" toggleWrapper="div">
|
|
267
|
+
Test content
|
|
268
|
+
</ExpandableSection>
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const toggle = screen.getByRole('button').parentElement;
|
|
272
|
+
expect(toggle?.tagName).toBe('DIV');
|
|
273
|
+
});
|
|
@@ -47,3 +47,31 @@ test('Renders with aria-labelledby when toggleAriaLabelledBy is passed', () => {
|
|
|
47
47
|
|
|
48
48
|
expect(screen.getByRole('button')).toHaveAccessibleName('Test label');
|
|
49
49
|
});
|
|
50
|
+
|
|
51
|
+
test('Renders with default div wrapper when toggleWrapper is not specified', () => {
|
|
52
|
+
render(<ExpandableSectionToggle data-testid="test-id">Toggle test</ExpandableSectionToggle>);
|
|
53
|
+
|
|
54
|
+
const toggle = screen.getByRole('button').parentElement;
|
|
55
|
+
expect(toggle?.tagName).toBe('DIV');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('Renders with h2 wrapper when toggleWrapper="h2"', () => {
|
|
59
|
+
render(
|
|
60
|
+
<ExpandableSectionToggle data-testid="test-id" toggleWrapper="h2">
|
|
61
|
+
Toggle test
|
|
62
|
+
</ExpandableSectionToggle>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(screen.getByRole('heading', { level: 2 })).toBeInTheDocument();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('Renders with div wrapper when toggleWrapper="div"', () => {
|
|
69
|
+
render(
|
|
70
|
+
<ExpandableSectionToggle data-testid="test-id" toggleWrapper="div">
|
|
71
|
+
Toggle test
|
|
72
|
+
</ExpandableSectionToggle>
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const toggle = screen.getByRole('button').parentElement;
|
|
76
|
+
expect(toggle?.tagName).toBe('DIV');
|
|
77
|
+
});
|
|
@@ -70,6 +70,14 @@ By using the `toggleContent` prop, you can pass in content other than a simple s
|
|
|
70
70
|
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
### With heading semantics
|
|
74
|
+
|
|
75
|
+
When the toggle text should function as a heading in the document structure, use the `toggleWrapper` prop to specify a heading element (h1-h6). This ensures proper semantic structure for screen readers and other assistive technologies. The component automatically uses a native button element when heading wrappers are used, allowing the heading styles to display properly.
|
|
76
|
+
|
|
77
|
+
```ts file="ExpandableSectionWithHeading.tsx"
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
|
|
73
81
|
### Truncate expansion
|
|
74
82
|
|
|
75
83
|
By passing in `variant="truncate"`, the expandable content will be visible up to a maximum number of lines before being truncated, with the toggle revealing or hiding the truncated content. By default the expandable content will truncate after 3 lines, and this can be customized by also passing in the `truncateMaxLines` prop.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { ExpandableSection, Badge } from '@patternfly/react-core';
|
|
2
|
+
import { ExpandableSection, Badge, Stack, StackItem } from '@patternfly/react-core';
|
|
3
3
|
import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon';
|
|
4
4
|
|
|
5
5
|
export const ExpandableSectionCustomToggle: React.FunctionComponent = () => {
|
|
@@ -10,20 +10,35 @@ export const ExpandableSectionCustomToggle: React.FunctionComponent = () => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
<Stack hasGutter>
|
|
14
|
+
<StackItem>
|
|
15
|
+
<h3>Custom Toggle Content</h3>
|
|
16
|
+
<p>You can use custom content such as icons and badges in the toggle:</p>
|
|
17
|
+
<ExpandableSection
|
|
18
|
+
toggleContent={
|
|
19
|
+
<div>
|
|
20
|
+
<span>You can also use icons </span>
|
|
21
|
+
<CheckCircleIcon />
|
|
22
|
+
<span> or badges </span>
|
|
23
|
+
<Badge isRead={true}>4</Badge>
|
|
24
|
+
<span> !</span>
|
|
25
|
+
</div>
|
|
26
|
+
}
|
|
27
|
+
onToggle={onToggle}
|
|
28
|
+
isExpanded={isExpanded}
|
|
29
|
+
>
|
|
30
|
+
This content is visible only when the component is expanded.
|
|
31
|
+
</ExpandableSection>
|
|
32
|
+
</StackItem>
|
|
33
|
+
|
|
34
|
+
<StackItem>
|
|
35
|
+
<h3>Accessibility Note</h3>
|
|
36
|
+
<p>
|
|
37
|
+
<strong>Important:</strong> If you need the toggle text to function as a heading in the document structure, do
|
|
38
|
+
NOT put heading elements (h1-h6) inside the <code>toggleContent</code> prop, as this creates invalid HTML
|
|
39
|
+
structure. Instead, use the <code>toggleWrapper</code> prop.
|
|
40
|
+
</p>
|
|
41
|
+
</StackItem>
|
|
42
|
+
</Stack>
|
|
28
43
|
);
|
|
29
44
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useState, MouseEvent } from 'react';
|
|
2
|
+
import { ExpandableSection, ExpandableSectionToggle, Stack, StackItem } from '@patternfly/react-core';
|
|
3
|
+
import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon';
|
|
4
|
+
|
|
5
|
+
export const ExpandableSectionWithHeading = () => {
|
|
6
|
+
const [isExpanded1, setIsExpanded1] = useState(false);
|
|
7
|
+
const [isExpanded2, setIsExpanded2] = useState(false);
|
|
8
|
+
const [isExpandedDetached, setIsExpandedDetached] = useState(false);
|
|
9
|
+
|
|
10
|
+
const onToggle1 = (_event: MouseEvent, isExpanded: boolean) => {
|
|
11
|
+
setIsExpanded1(isExpanded);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const onToggle2 = (_event: MouseEvent, isExpanded: boolean) => {
|
|
15
|
+
setIsExpanded2(isExpanded);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const onToggleDetached = (isExpanded: boolean) => {
|
|
19
|
+
setIsExpandedDetached(isExpanded);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Stack hasGutter>
|
|
24
|
+
<StackItem>
|
|
25
|
+
<h4>Document with Expandable Sections</h4>
|
|
26
|
+
<p>This demonstrates how to use expandable sections with proper heading semantics.</p>
|
|
27
|
+
|
|
28
|
+
{/* Using toggleWrapper prop for proper heading semantics */}
|
|
29
|
+
<ExpandableSection
|
|
30
|
+
toggleWrapper="h5"
|
|
31
|
+
toggleText="Toggle as a heading"
|
|
32
|
+
onToggle={onToggle1}
|
|
33
|
+
isExpanded={isExpanded1}
|
|
34
|
+
>
|
|
35
|
+
<p>
|
|
36
|
+
This content is visible only when the component is expanded. The toggle text above functions as a proper
|
|
37
|
+
heading in the document structure, which is important for screen readers and other assistive technologies.
|
|
38
|
+
</p>
|
|
39
|
+
<p>
|
|
40
|
+
When using the <code>toggleWrapper</code> prop with heading elements (h1-h6), the button is rendered inside
|
|
41
|
+
the heading element, maintaining proper semantic structure.
|
|
42
|
+
</p>
|
|
43
|
+
</ExpandableSection>
|
|
44
|
+
</StackItem>
|
|
45
|
+
|
|
46
|
+
<StackItem>
|
|
47
|
+
<h4>Detached Variant with Heading</h4>
|
|
48
|
+
<p>You can also use the detached variant with heading semantics:</p>
|
|
49
|
+
|
|
50
|
+
<ExpandableSectionToggle
|
|
51
|
+
toggleWrapper="h5"
|
|
52
|
+
toggleId="detached-heading-toggle"
|
|
53
|
+
contentId="detached-heading-content"
|
|
54
|
+
isExpanded={isExpandedDetached}
|
|
55
|
+
onToggle={onToggleDetached}
|
|
56
|
+
>
|
|
57
|
+
Detached Toggle with Heading
|
|
58
|
+
</ExpandableSectionToggle>
|
|
59
|
+
|
|
60
|
+
<ExpandableSection
|
|
61
|
+
isDetached
|
|
62
|
+
toggleId="detached-heading-toggle"
|
|
63
|
+
contentId="detached-heading-content"
|
|
64
|
+
isExpanded={isExpandedDetached}
|
|
65
|
+
>
|
|
66
|
+
<p>This is detached content that can be positioned anywhere in the DOM.</p>
|
|
67
|
+
</ExpandableSection>
|
|
68
|
+
</StackItem>
|
|
69
|
+
|
|
70
|
+
<StackItem>
|
|
71
|
+
<h4>Custom Content with Heading</h4>
|
|
72
|
+
<p>You can also use custom content within heading wrappers:</p>
|
|
73
|
+
|
|
74
|
+
<ExpandableSection
|
|
75
|
+
toggleWrapper="h5"
|
|
76
|
+
toggleContent={
|
|
77
|
+
<span>
|
|
78
|
+
<CheckCircleIcon /> Custom Heading Content with Icon
|
|
79
|
+
</span>
|
|
80
|
+
}
|
|
81
|
+
onToggle={onToggle2}
|
|
82
|
+
isExpanded={isExpanded2}
|
|
83
|
+
>
|
|
84
|
+
<p>This expandable section uses custom content with an icon inside a heading wrapper.</p>
|
|
85
|
+
</ExpandableSection>
|
|
86
|
+
</StackItem>
|
|
87
|
+
</Stack>
|
|
88
|
+
);
|
|
89
|
+
};
|