<div className="layout-page-main">
<div className="layout-page-main-inner">
- <div className="big-padded">
+ {/* Adding a key to force re-rendering of the category content, so that it resets the scroll position */}
+ <div className="big-padded" key={selectedCategory}>
{foundAdditionalCategory && shouldRenderAdditionalCategory ? (
foundAdditionalCategory.renderComponent({
categories,
import * as React from 'react';
import { Location, withRouter } from '../../../components/hoc/withRouter';
import { sanitizeStringRestricted } from '../../../helpers/sanitize';
-import { scrollToElement } from '../../../helpers/scrolling';
import { SettingDefinitionAndValue } from '../../../types/settings';
import { Component } from '../../../types/types';
import { getSubCategoryDescription, getSubCategoryName } from '../utils';
subCategory?: string;
}
-const SCROLL_OFFSET_TOP = 200;
-const SCROLL_OFFSET_BOTTOM = 500;
-
export class SubCategoryDefinitionsList extends React.PureComponent<
SubCategoryDefinitionsListProps
> {
componentDidUpdate(prevProps: SubCategoryDefinitionsListProps) {
const { hash } = this.props.location;
if (hash && prevProps.location.hash !== hash) {
- const query = `[data-key=${hash.substr(1).replace(/[.#/]/g, '\\$&')}]`;
+ const query = `[data-key=${hash.substring(1).replace(/[.#/]/g, '\\$&')}]`;
const element = document.querySelector<HTMLHeadingElement | HTMLLIElement>(query);
this.scrollToSubCategoryOrDefinition(element);
}
scrollToSubCategoryOrDefinition = (element: HTMLHeadingElement | HTMLLIElement | null) => {
if (element) {
const { hash } = this.props.location;
- if (hash && hash.substr(1) === element.getAttribute('data-key')) {
- scrollToElement(element, {
- topOffset: SCROLL_OFFSET_TOP,
- bottomOffset: SCROLL_OFFSET_BOTTOM,
- smooth: true
- });
+ if (hash && hash.substring(1) === element.getAttribute('data-key')) {
+ element.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
}
}
};
import { mount, shallow } from 'enzyme';
import * as React from 'react';
import { mockSettingWithCategory } from '../../../../helpers/mocks/settings';
-import { scrollToElement } from '../../../../helpers/scrolling';
import { mockLocation } from '../../../../helpers/testMocks';
import { waitAndUpdate } from '../../../../helpers/testUtils';
import {
expect(shallowRender({ subCategory: 'qg' })).toMatchSnapshot('subcategory');
});
-it('should scroll if hash is defined', async () => {
+it('should scroll if hash is defined and updated', async () => {
+ window.HTMLElement.prototype.scrollIntoView = jest.fn();
const wrapper = shallowRender({ location: mockLocation({ hash: '#qg' }) });
await waitAndUpdate(wrapper);
wrapper.find('h2').forEach(node => mount(node.getElement()));
- expect(scrollToElement).toBeCalled();
-});
-
-it('should scroll when hash is updated', async () => {
- const wrapper = shallowRender({ location: mockLocation({ hash: '#qg' }) });
+ expect(window.HTMLElement.prototype.scrollIntoView).toBeCalled();
wrapper.setProps({ location: mockLocation({ hash: '#email' }) });
- await waitAndUpdate(wrapper);
-
- expect(scrollToElement).toBeCalled();
+ expect(window.HTMLElement.prototype.scrollIntoView).toBeCalled();
});
function shallowRender(props: Partial<SubCategoryDefinitionsListProps> = {}) {
>
<div
className="big-padded"
+ key="almintegration"
>
<withRouter(withAppStateContext(AlmIntegration))
categories={
>
<div
className="big-padded"
+ key="general"
>
<CategoryDefinitionsList
category="general"
>
<div
className="big-padded"
+ key="exclusions"
>
<AnalysisScope
categories={
>
<div
className="big-padded"
+ key="languages"
>
<withRouter(Languages)
categories={
>
<div
className="big-padded"
+ key="new_code_period"
>
<NewCodePeriod />
</div>
>
<div
className="big-padded"
+ key="pull_request_decoration_binding"
>
<CategoryDefinitionsList
category="pull_request_decoration_binding"
selected={currentTab}
tabs={tabs}
/>
-
+ {/* Adding a key to force re-rendering of the tab container, so that it resets the scroll position */}
<ScreenPositionHelper>
{({ top }) => (
<div
style={{
maxHeight: `calc(100vh - ${top + HEIGHT_ADJUSTMENT}px)`
}}
- className="bordered overflow-y-auto tabbed-definitions">
+ className="bordered overflow-y-auto tabbed-definitions"
+ key={currentTab}>
<div className="big-padded">
<Alert variant="info">
<FormattedMessage