Skip to content

Commit 10fc6de

Browse files
authored
Merge pull request #312 from boaz0/fix_scroll_top_wizard
fix(pf4): scroll to top on switching to a different step
2 parents 620a52e + 3851f1c commit 10fc6de

File tree

2 files changed

+48
-26
lines changed

2 files changed

+48
-26
lines changed

config/jest.setup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ import { configure } from 'enzyme';
22
import Adapter from 'enzyme-adapter-react-16';
33

44
configure({ adapter: new Adapter() });
5+
Element.prototype.scrollTo = () => {};

packages/pf4-component-mapper/src/form-fields/wizard/wizard-step.js

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,59 @@ import { Title } from '@patternfly/react-core/dist/js/components/Title/Title';
44
import PropTypes from 'prop-types';
55
import WizardStepButtons from './step-buttons';
66

7-
export const RenderTitle = ({ title, customTitle }) => customTitle ? customTitle : <Title headingLevel="h1" size="xl">{ title }</Title>;
7+
export const RenderTitle = ({ title, customTitle }) => customTitle ? customTitle : <Title headingLevel="h1" size="xl">{title}</Title>;
88

99
RenderTitle.propTypes = {
1010
title: PropTypes.node,
1111
customTitle: PropTypes.node,
1212
};
1313

14-
const WizardStep = ({
15-
title,
16-
description,
17-
fields,
18-
formOptions,
19-
showTitles,
20-
showTitle,
21-
customTitle,
22-
...rest
23-
}) => {
24-
return (
25-
<Fragment>
26-
<WizardBody hasBodyPadding={ true }>
27-
<div className="pf-c-form">
28-
{ ((showTitles && showTitle !== false) || showTitle) && <RenderTitle title={ title } customTitle={ customTitle } /> }
29-
{ fields.map(item => formOptions.renderForm([ item ], formOptions)) }
30-
</div>
31-
</WizardBody>
32-
<WizardStepButtons
33-
formOptions={ formOptions }
34-
{ ...rest }
35-
/>
36-
</Fragment>
37-
);
38-
};
14+
class WizardStep extends React.Component {
15+
formRef = React.createRef();
16+
componentDidUpdate(prevProps) {
17+
// we want to scroll to top of the new step so
18+
// the user experience won't suck. For instance,
19+
// when the first step contains many fields that you have to scroll down
20+
// to fill all the data for the next step. If the next step contains instructions
21+
// at the top, the user will miss them because the scrollbar offset will stay at
22+
// the same place it was.
23+
if(prevProps.stepKey !== this.props.stepKey) {
24+
// HACK: I can not pass ref to WizardBody because it is not
25+
// wrapped by forwardRef. However, the step body (the one that overflows)
26+
// is the grand parent of the form element.
27+
const stepBody = this.formRef.current && this.formRef.current.parentNode.parentNode;
28+
stepBody.scrollTo({top: 0, left: 0, behavior: 'smooth'});
29+
}
30+
}
31+
32+
render() {
33+
const {
34+
title,
35+
description,
36+
fields,
37+
formOptions,
38+
showTitles,
39+
showTitle,
40+
customTitle,
41+
...rest
42+
} = this.props;
43+
44+
return (
45+
<Fragment>
46+
<WizardBody hasBodyPadding={true}>
47+
<div ref={this.formRef} className="pf-c-form">
48+
{((showTitles && showTitle !== false) || showTitle) && <RenderTitle title={title} customTitle={customTitle} />}
49+
{fields.map(item => formOptions.renderForm([item], formOptions))}
50+
</div>
51+
</WizardBody>
52+
<WizardStepButtons
53+
formOptions={formOptions}
54+
{...rest}
55+
/>
56+
</Fragment>
57+
);
58+
}
59+
}
3960

4061
WizardStep.propTypes = {
4162
title: PropTypes.node,

0 commit comments

Comments
 (0)