@patternfly/react-core 6.5.0-prerelease.71 → 6.5.0-prerelease.73
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 +12 -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/Hero/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/SSRSafeIds/SSRSafeIds/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/useSSRSafeId/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/Hero/Hero.d.ts +2 -2
- package/dist/esm/components/Hero/Hero.d.ts.map +1 -1
- package/dist/esm/components/Hero/Hero.js +2 -2
- package/dist/esm/components/Hero/Hero.js.map +1 -1
- package/dist/esm/components/Page/PageGroup.d.ts +5 -1
- package/dist/esm/components/Page/PageGroup.d.ts.map +1 -1
- package/dist/esm/components/Page/PageGroup.js +2 -2
- package/dist/esm/components/Page/PageGroup.js.map +1 -1
- package/dist/esm/components/Page/PageSection.d.ts +4 -0
- package/dist/esm/components/Page/PageSection.d.ts.map +1 -1
- package/dist/esm/components/Page/PageSection.js +2 -2
- package/dist/esm/components/Page/PageSection.js.map +1 -1
- package/dist/js/components/Hero/Hero.d.ts +2 -2
- package/dist/js/components/Hero/Hero.d.ts.map +1 -1
- package/dist/js/components/Hero/Hero.js +2 -2
- package/dist/js/components/Hero/Hero.js.map +1 -1
- package/dist/js/components/Page/PageGroup.d.ts +5 -1
- package/dist/js/components/Page/PageGroup.d.ts.map +1 -1
- package/dist/js/components/Page/PageGroup.js +2 -2
- package/dist/js/components/Page/PageGroup.js.map +1 -1
- package/dist/js/components/Page/PageSection.d.ts +4 -0
- package/dist/js/components/Page/PageSection.d.ts.map +1 -1
- package/dist/js/components/Page/PageSection.js +2 -2
- package/dist/js/components/Page/PageSection.js.map +1 -1
- package/dist/umd/assets/{output-BA8-zZeB.css → output-B4C76oED.css} +18554 -18440
- 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 +6 -6
- package/src/components/Hero/Hero.tsx +4 -4
- package/src/components/Hero/__tests__/Hero.test.tsx +19 -1
- package/src/components/Page/PageGroup.tsx +10 -0
- package/src/components/Page/PageSection.tsx +10 -0
- package/src/components/Page/__tests__/PageGroup.test.tsx +52 -0
- package/src/components/Page/__tests__/PageSection.test.tsx +64 -0
- package/src/components/Page/examples/Page.md +11 -1
- package/src/components/Page/examples/PageDynamicStickySection.tsx +108 -0
- package/src/demos/Compass/examples/CompassDemo.tsx +3 -1
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.72","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.72","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.72","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.73",
|
|
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",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@patternfly/react-icons": "^6.5.0-prerelease.
|
|
50
|
-
"@patternfly/react-styles": "^6.5.0-prerelease.
|
|
51
|
-
"@patternfly/react-tokens": "^6.5.0-prerelease.
|
|
49
|
+
"@patternfly/react-icons": "^6.5.0-prerelease.34",
|
|
50
|
+
"@patternfly/react-styles": "^6.5.0-prerelease.24",
|
|
51
|
+
"@patternfly/react-tokens": "^6.5.0-prerelease.23",
|
|
52
52
|
"focus-trap": "7.6.6",
|
|
53
53
|
"react-dropzone": "^14.3.5",
|
|
54
54
|
"tslib": "^2.8.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@patternfly/patternfly": "6.5.0-prerelease.
|
|
57
|
+
"@patternfly/patternfly": "6.5.0-prerelease.82",
|
|
58
58
|
"case-anything": "^3.1.2",
|
|
59
59
|
"css": "^3.0.0",
|
|
60
60
|
"fs-extra": "^11.3.3"
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"react": "^17 || ^18 || ^19",
|
|
64
64
|
"react-dom": "^17 || ^18 || ^19"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "49cdd4af567d0e44031932738edb6d05ffe68c99"
|
|
67
67
|
}
|
|
@@ -34,8 +34,8 @@ export interface HeroProps extends Omit<React.HTMLProps<HTMLDivElement>, 'conten
|
|
|
34
34
|
stop2?: string;
|
|
35
35
|
stop3?: string;
|
|
36
36
|
};
|
|
37
|
-
/** Flag indicating
|
|
38
|
-
|
|
37
|
+
/** @beta Flag indicating the hero has glass styling when glass theme is applied. */
|
|
38
|
+
isGlass?: boolean;
|
|
39
39
|
/** Modifies the width of the hero body. */
|
|
40
40
|
bodyWidth?: string;
|
|
41
41
|
/** Modifies the max-width of the hero body. */
|
|
@@ -49,7 +49,7 @@ export const Hero: React.FunctionComponent<HeroProps> = ({
|
|
|
49
49
|
backgroundSrcDark,
|
|
50
50
|
gradientLight,
|
|
51
51
|
gradientDark,
|
|
52
|
-
|
|
52
|
+
isGlass = false,
|
|
53
53
|
bodyWidth,
|
|
54
54
|
bodyMaxWidth,
|
|
55
55
|
...props
|
|
@@ -90,7 +90,7 @@ export const Hero: React.FunctionComponent<HeroProps> = ({
|
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
92
|
<div
|
|
93
|
-
className={css(styles.hero,
|
|
93
|
+
className={css(styles.hero, isGlass && styles.modifiers.glass, className)}
|
|
94
94
|
style={{ ...props.style, ...customStyles }}
|
|
95
95
|
{...props}
|
|
96
96
|
>
|
|
@@ -16,12 +16,30 @@ test('Renders with children', () => {
|
|
|
16
16
|
expect(screen.getByText('Test content')).toBeVisible();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
test(`Renders with ${styles.hero} class on wrapper by
|
|
19
|
+
test(`Renders with ${styles.hero} class on wrapper by default`, () => {
|
|
20
20
|
render(<Hero>Test</Hero>);
|
|
21
21
|
|
|
22
22
|
expect(screen.getByText('Test').parentElement).toHaveClass(`${styles.hero}`, { exact: true });
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
+
test(`Renders with ${styles.modifiers.glass} class when isGlass is true`, () => {
|
|
26
|
+
render(<Hero isGlass>Test</Hero>);
|
|
27
|
+
|
|
28
|
+
expect(screen.getByText('Test').parentElement).toHaveClass(`${styles.modifiers.glass}`);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test(`Renders without ${styles.modifiers.glass} class when isGlass is false`, () => {
|
|
32
|
+
render(<Hero isGlass={false}>Test</Hero>);
|
|
33
|
+
|
|
34
|
+
expect(screen.getByText('Test').parentElement).not.toHaveClass(`${styles.modifiers.glass}`);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test(`Renders without ${styles.modifiers.glass} class by default`, () => {
|
|
38
|
+
render(<Hero>Test</Hero>);
|
|
39
|
+
|
|
40
|
+
expect(screen.getByText('Test').parentElement).not.toHaveClass(`${styles.modifiers.glass}`);
|
|
41
|
+
});
|
|
42
|
+
|
|
25
43
|
test('Renders with custom class name on wrapper when className prop is provided', () => {
|
|
26
44
|
render(<Hero className="custom-class">Test</Hero>);
|
|
27
45
|
expect(screen.getByText('Test').parentElement).toHaveClass('custom-class');
|
|
@@ -17,6 +17,10 @@ export interface PageGroupProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
17
17
|
xl?: 'top' | 'bottom';
|
|
18
18
|
'2xl'?: 'top' | 'bottom';
|
|
19
19
|
};
|
|
20
|
+
/** @beta Applies the base sticky positioning to the top or bottom of the scroll parent container. */
|
|
21
|
+
stickyBase?: 'top' | 'bottom';
|
|
22
|
+
/** @beta Flag indicating if the group has stuck styling, applied when the group is not at the edge of the scroll parent container. */
|
|
23
|
+
isStickyStuck?: boolean;
|
|
20
24
|
/** Enables the page group to fill the available vertical space if true, or disable filling if false. */
|
|
21
25
|
isFilled?: boolean;
|
|
22
26
|
/** Modifier indicating if PageGroup should have a shadow at the top */
|
|
@@ -37,6 +41,8 @@ export const PageGroup = ({
|
|
|
37
41
|
className = '',
|
|
38
42
|
children,
|
|
39
43
|
stickyOnBreakpoint,
|
|
44
|
+
stickyBase,
|
|
45
|
+
isStickyStuck = false,
|
|
40
46
|
isFilled,
|
|
41
47
|
hasShadowTop = false,
|
|
42
48
|
hasShadowBottom = false,
|
|
@@ -61,6 +67,10 @@ export const PageGroup = ({
|
|
|
61
67
|
className={css(
|
|
62
68
|
styles.pageMainGroup,
|
|
63
69
|
formatBreakpointMods(stickyOnBreakpoint, styles, 'sticky-', getVerticalBreakpoint(height), true),
|
|
70
|
+
stickyBase === 'top' && styles.modifiers.stickyTopBase,
|
|
71
|
+
stickyBase === 'bottom' && styles.modifiers.stickyBottomBase,
|
|
72
|
+
isStickyStuck && stickyBase === 'top' && styles.modifiers.stickyTopStuck,
|
|
73
|
+
isStickyStuck && stickyBase === 'bottom' && styles.modifiers.stickyBottomStuck,
|
|
64
74
|
isFilled === false && styles.modifiers.noFill,
|
|
65
75
|
isFilled === true && styles.modifiers.fill,
|
|
66
76
|
hasShadowTop && styles.modifiers.shadowTop,
|
|
@@ -51,6 +51,10 @@ export interface PageSectionProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
51
51
|
xl?: 'top' | 'bottom';
|
|
52
52
|
'2xl'?: 'top' | 'bottom';
|
|
53
53
|
};
|
|
54
|
+
/** @beta Applies the base sticky positioning to the top or bottom of the scroll parent container. */
|
|
55
|
+
stickyBase?: 'top' | 'bottom';
|
|
56
|
+
/** @beta Flag indicating if the section has stuck styling, applied when the section is not at the edge of the scroll parent container. */
|
|
57
|
+
isStickyStuck?: boolean;
|
|
54
58
|
/** Modifier indicating if PageSection should have a shadow at the top */
|
|
55
59
|
hasShadowTop?: boolean;
|
|
56
60
|
/** Modifier indicating if PageSection should have a shadow at the bottom */
|
|
@@ -96,6 +100,8 @@ export const PageSection: React.FunctionComponent<PageSectionProps> = ({
|
|
|
96
100
|
isWidthLimited = false,
|
|
97
101
|
isCenterAligned = false,
|
|
98
102
|
stickyOnBreakpoint,
|
|
103
|
+
stickyBase,
|
|
104
|
+
isStickyStuck = false,
|
|
99
105
|
hasShadowTop = false,
|
|
100
106
|
hasShadowBottom = false,
|
|
101
107
|
hasOverflowScroll = false,
|
|
@@ -124,6 +130,10 @@ export const PageSection: React.FunctionComponent<PageSectionProps> = ({
|
|
|
124
130
|
variantType[type],
|
|
125
131
|
formatBreakpointMods(padding, styles),
|
|
126
132
|
formatBreakpointMods(stickyOnBreakpoint, styles, 'sticky-', getVerticalBreakpoint(height), true),
|
|
133
|
+
stickyBase === 'top' && styles.modifiers.stickyTopBase,
|
|
134
|
+
stickyBase === 'bottom' && styles.modifiers.stickyBottomBase,
|
|
135
|
+
isStickyStuck && stickyBase === 'top' && styles.modifiers.stickyTopStuck,
|
|
136
|
+
isStickyStuck && stickyBase === 'bottom' && styles.modifiers.stickyBottomStuck,
|
|
127
137
|
type === PageSectionTypes.default && variantStyle[variant],
|
|
128
138
|
isFilled === false && styles.modifiers.noFill,
|
|
129
139
|
isFilled === true && styles.modifiers.fill,
|
|
@@ -101,3 +101,55 @@ test(`Renders with ${styles.modifiers.noPlainOnGlass} class when isNoPlainOnGlas
|
|
|
101
101
|
|
|
102
102
|
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noPlainOnGlass);
|
|
103
103
|
});
|
|
104
|
+
|
|
105
|
+
test(`Does not add sticky base or sticky stuck classes by default`, () => {
|
|
106
|
+
render(<PageGroup>test</PageGroup>);
|
|
107
|
+
const group = screen.getByText('test');
|
|
108
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyTopBase);
|
|
109
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyBottomBase);
|
|
110
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
111
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test(`Adds ${styles.modifiers.stickyTopBase} without stuck class when stickyBase="top"`, () => {
|
|
115
|
+
render(<PageGroup stickyBase="top">test</PageGroup>);
|
|
116
|
+
const group = screen.getByText('test');
|
|
117
|
+
expect(group).toHaveClass(styles.modifiers.stickyTopBase);
|
|
118
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test(`Adds ${styles.modifiers.stickyBottomBase} without stuck class when stickyBase="bottom"`, () => {
|
|
122
|
+
render(<PageGroup stickyBase="bottom">test</PageGroup>);
|
|
123
|
+
const group = screen.getByText('test');
|
|
124
|
+
expect(group).toHaveClass(styles.modifiers.stickyBottomBase);
|
|
125
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test(`Adds ${styles.modifiers.stickyTopStuck} when stickyBase="top" and isStickyStuck`, () => {
|
|
129
|
+
render(
|
|
130
|
+
<PageGroup stickyBase="top" isStickyStuck>
|
|
131
|
+
test
|
|
132
|
+
</PageGroup>
|
|
133
|
+
);
|
|
134
|
+
const group = screen.getByText('test');
|
|
135
|
+
expect(group).toHaveClass(styles.modifiers.stickyTopBase);
|
|
136
|
+
expect(group).toHaveClass(styles.modifiers.stickyTopStuck);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test(`Adds ${styles.modifiers.stickyBottomStuck} when stickyBase="bottom" and isStickyStuck`, () => {
|
|
140
|
+
render(
|
|
141
|
+
<PageGroup stickyBase="bottom" isStickyStuck>
|
|
142
|
+
test
|
|
143
|
+
</PageGroup>
|
|
144
|
+
);
|
|
145
|
+
const group = screen.getByText('test');
|
|
146
|
+
expect(group).toHaveClass(styles.modifiers.stickyBottomBase);
|
|
147
|
+
expect(group).toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test(`Does not add stuck class when isStickyStuck is true but stickyBase is not set`, () => {
|
|
151
|
+
render(<PageGroup isStickyStuck>test</PageGroup>);
|
|
152
|
+
const group = screen.getByText('test');
|
|
153
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
154
|
+
expect(group).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
155
|
+
});
|
|
@@ -199,3 +199,67 @@ test(`Renders with ${styles.modifiers.noPlainOnGlass} class when isNoPlainOnGlas
|
|
|
199
199
|
|
|
200
200
|
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noPlainOnGlass);
|
|
201
201
|
});
|
|
202
|
+
|
|
203
|
+
test(`Does not add sticky base or sticky stuck classes by default`, () => {
|
|
204
|
+
render(<PageSection component="main">test</PageSection>);
|
|
205
|
+
const section = screen.getByRole('main');
|
|
206
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyTopBase);
|
|
207
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyBottomBase);
|
|
208
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
209
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test(`Adds ${styles.modifiers.stickyTopBase} without stuck class when stickyBase="top"`, () => {
|
|
213
|
+
render(
|
|
214
|
+
<PageSection component="main" stickyBase="top">
|
|
215
|
+
test
|
|
216
|
+
</PageSection>
|
|
217
|
+
);
|
|
218
|
+
const section = screen.getByRole('main');
|
|
219
|
+
expect(section).toHaveClass(styles.modifiers.stickyTopBase);
|
|
220
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test(`Adds ${styles.modifiers.stickyBottomBase} without stuck class when stickyBase="bottom"`, () => {
|
|
224
|
+
render(
|
|
225
|
+
<PageSection component="main" stickyBase="bottom">
|
|
226
|
+
test
|
|
227
|
+
</PageSection>
|
|
228
|
+
);
|
|
229
|
+
const section = screen.getByRole('main');
|
|
230
|
+
expect(section).toHaveClass(styles.modifiers.stickyBottomBase);
|
|
231
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test(`Adds ${styles.modifiers.stickyTopStuck} when stickyBase="top" and isStickyStuck`, () => {
|
|
235
|
+
render(
|
|
236
|
+
<PageSection component="main" stickyBase="top" isStickyStuck>
|
|
237
|
+
test
|
|
238
|
+
</PageSection>
|
|
239
|
+
);
|
|
240
|
+
const section = screen.getByRole('main');
|
|
241
|
+
expect(section).toHaveClass(styles.modifiers.stickyTopBase);
|
|
242
|
+
expect(section).toHaveClass(styles.modifiers.stickyTopStuck);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test(`Adds ${styles.modifiers.stickyBottomStuck} when stickyBase="bottom" and isStickyStuck`, () => {
|
|
246
|
+
render(
|
|
247
|
+
<PageSection component="main" stickyBase="bottom" isStickyStuck>
|
|
248
|
+
test
|
|
249
|
+
</PageSection>
|
|
250
|
+
);
|
|
251
|
+
const section = screen.getByRole('main');
|
|
252
|
+
expect(section).toHaveClass(styles.modifiers.stickyBottomBase);
|
|
253
|
+
expect(section).toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test(`Does not add stuck class when isStickyStuck is true but stickyBase is not set`, () => {
|
|
257
|
+
render(
|
|
258
|
+
<PageSection component="main" isStickyStuck>
|
|
259
|
+
test
|
|
260
|
+
</PageSection>
|
|
261
|
+
);
|
|
262
|
+
const section = screen.getByRole('main');
|
|
263
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyTopStuck);
|
|
264
|
+
expect(section).not.toHaveClass(styles.modifiers.stickyBottomStuck);
|
|
265
|
+
});
|
|
@@ -6,7 +6,7 @@ propComponents:
|
|
|
6
6
|
['Page', 'PageSidebar', 'PageSidebarBody', 'PageSection', 'PageGroup', 'PageBreadcrumb', 'PageToggleButton']
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
import { useState } from 'react';
|
|
9
|
+
import { useState, useLayoutEffect, useRef } from 'react';
|
|
10
10
|
import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';
|
|
11
11
|
import pageSectionWidthLimitMaxWidth from '@patternfly/react-tokens/dist/esm/c_page_section_m_limit_width_MaxWidth';
|
|
12
12
|
|
|
@@ -131,3 +131,13 @@ To remove the default background color from a page section or group, use the `is
|
|
|
131
131
|
```ts file="./PagePlainSections.tsx"
|
|
132
132
|
|
|
133
133
|
```
|
|
134
|
+
|
|
135
|
+
### Dynamic sticky section
|
|
136
|
+
|
|
137
|
+
A page section may be made sticky with separate control of its sticky positioning and stuck styling using the `stickyBase` and `isStickyStuck` properties. The `stickyBase` property accepts a value of `"top"` or `"bottom"` and applies the base sticky positioning in the given direction. The `isStickyStuck` property applies visual "stuck" styling such as a background, box shadow, and border, and should be toggled based on the scroll position of the scroll parent container.
|
|
138
|
+
|
|
139
|
+
In this example, a scroll event listener on the scroll parent container toggles `isStickyStuck` when `scrollTop > 0`, so the stuck styling appears only when the content is scrolled.
|
|
140
|
+
|
|
141
|
+
```ts file="./PageDynamicStickySection.tsx"
|
|
142
|
+
|
|
143
|
+
```
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { useLayoutEffect, useState, useRef } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Page,
|
|
4
|
+
Masthead,
|
|
5
|
+
MastheadMain,
|
|
6
|
+
MastheadBrand,
|
|
7
|
+
MastheadLogo,
|
|
8
|
+
MastheadContent,
|
|
9
|
+
PageSection,
|
|
10
|
+
Toolbar,
|
|
11
|
+
ToolbarContent,
|
|
12
|
+
ToolbarItem,
|
|
13
|
+
Breadcrumb,
|
|
14
|
+
BreadcrumbItem,
|
|
15
|
+
Content
|
|
16
|
+
} from '@patternfly/react-core';
|
|
17
|
+
|
|
18
|
+
const useIsStuckFromScrollParent = ({
|
|
19
|
+
shouldTrack,
|
|
20
|
+
scrollParentRef
|
|
21
|
+
}: {
|
|
22
|
+
shouldTrack: boolean;
|
|
23
|
+
scrollParentRef: React.RefObject<any>;
|
|
24
|
+
}): boolean => {
|
|
25
|
+
const [isStuck, setIsStuck] = useState(false);
|
|
26
|
+
|
|
27
|
+
useLayoutEffect(() => {
|
|
28
|
+
if (!shouldTrack) {
|
|
29
|
+
setIsStuck(false);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const scrollElement = scrollParentRef.current;
|
|
34
|
+
if (!scrollElement) {
|
|
35
|
+
setIsStuck(false);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const syncFromScroll = () => {
|
|
40
|
+
setIsStuck(scrollElement.scrollTop > 0);
|
|
41
|
+
};
|
|
42
|
+
syncFromScroll();
|
|
43
|
+
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
|
|
44
|
+
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
|
|
45
|
+
}, [shouldTrack, scrollParentRef]);
|
|
46
|
+
|
|
47
|
+
return isStuck;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const PageDynamicStickySection: React.FunctionComponent = () => {
|
|
51
|
+
const scrollParentRef = useRef<HTMLDivElement>(null);
|
|
52
|
+
const isStickyStuck = useIsStuckFromScrollParent({ shouldTrack: true, scrollParentRef });
|
|
53
|
+
|
|
54
|
+
const headerToolbar = (
|
|
55
|
+
<Toolbar id="dynamic-sticky-toolbar">
|
|
56
|
+
<ToolbarContent>
|
|
57
|
+
<ToolbarItem>header-tools</ToolbarItem>
|
|
58
|
+
</ToolbarContent>
|
|
59
|
+
</Toolbar>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const masthead = (
|
|
63
|
+
<Masthead>
|
|
64
|
+
<MastheadMain>
|
|
65
|
+
<MastheadBrand>
|
|
66
|
+
<MastheadLogo href="https://patternfly.org" target="_blank">
|
|
67
|
+
Logo
|
|
68
|
+
</MastheadLogo>
|
|
69
|
+
</MastheadBrand>
|
|
70
|
+
</MastheadMain>
|
|
71
|
+
<MastheadContent>{headerToolbar}</MastheadContent>
|
|
72
|
+
</Masthead>
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Page masthead={masthead}>
|
|
77
|
+
<div ref={scrollParentRef} style={{ overflowY: 'auto', height: '100%' }}>
|
|
78
|
+
<PageSection type="breadcrumb" stickyBase="top" isStickyStuck={isStickyStuck}>
|
|
79
|
+
<Breadcrumb>
|
|
80
|
+
<BreadcrumbItem>Section home</BreadcrumbItem>
|
|
81
|
+
<BreadcrumbItem to="#">Section title</BreadcrumbItem>
|
|
82
|
+
<BreadcrumbItem to="#" isActive>
|
|
83
|
+
Section landing
|
|
84
|
+
</BreadcrumbItem>
|
|
85
|
+
</Breadcrumb>
|
|
86
|
+
</PageSection>
|
|
87
|
+
<PageSection>
|
|
88
|
+
<Content>
|
|
89
|
+
<h1>Main title</h1>
|
|
90
|
+
<p>
|
|
91
|
+
Scroll the container to see the breadcrumb section above dynamically apply its stuck styling. The section
|
|
92
|
+
uses <code>stickyBase="top"</code> to remain fixed at the top of the scroll parent, and{' '}
|
|
93
|
+
<code>isStickyStuck</code> is toggled via a scroll event listener to apply visual styling when the section
|
|
94
|
+
is no longer at the top edge.
|
|
95
|
+
</p>
|
|
96
|
+
</Content>
|
|
97
|
+
</PageSection>
|
|
98
|
+
{Array.from({ length: 30 }, (_, i) => (
|
|
99
|
+
<PageSection key={i} variant={i % 2 === 0 ? 'default' : 'secondary'}>
|
|
100
|
+
<Content>
|
|
101
|
+
<p>{`Section ${i + 1} content`}</p>
|
|
102
|
+
</Content>
|
|
103
|
+
</PageSection>
|
|
104
|
+
))}
|
|
105
|
+
</div>
|
|
106
|
+
</Page>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
@@ -149,7 +149,9 @@ export const CompassBasic: React.FunctionComponent = () => {
|
|
|
149
149
|
const mainContent = (
|
|
150
150
|
<>
|
|
151
151
|
<CompassHero>
|
|
152
|
-
<Hero gradientDark={{ stop1: '#000', stop2: '#1b0d33', stop3: '#3d2785' }}>
|
|
152
|
+
<Hero isGlass gradientDark={{ stop1: '#000', stop2: '#1b0d33', stop3: '#3d2785' }}>
|
|
153
|
+
Hero
|
|
154
|
+
</Hero>
|
|
153
155
|
</CompassHero>
|
|
154
156
|
<CompassMainHeader title={<Title headingLevel="h1">Content title</Title>} />
|
|
155
157
|
<CompassContent>
|