Fix scroll issue in search page (#2596)

Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
This commit is contained in:
Cintia Sánchez García 2022-12-13 14:07:48 +01:00 committed by GitHub
parent b42de22e3c
commit aeafcf43e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 53 additions and 13 deletions

View File

@ -36,6 +36,7 @@
"remark-unlink": "^3.1.0",
"semver": "^7.3.8",
"tinycolor2": "^1.4.2",
"ua-parser-js": "^1.0.32",
"unified": "^9.2.1",
"yaml": "2.0.1"
},
@ -76,7 +77,7 @@
"proxy": "http://localhost:8000",
"scripts": {
"copy:static": "shx rm -rf src/static && shx mkdir src/static && shx cp -r public/static/* src/static",
"start": "yarn copy:static && react-scripts start",
"start": "yarn copy:static && DANGEROUSLY_DISABLE_HOST_CHECK=true react-scripts start",
"build": "yarn copy:static && INLINE_RUNTIME_CHUNK=false IMAGE_INLINE_SIZE_LIMIT=0 react-scripts build",
"test": "sed -i -e 's/const FORCE_EXIT_DELAY = 500;/const FORCE_EXIT_DELAY = 1000;/g' ./node_modules/jest-worker/build/base/BaseWorkerPool.js && TZ=UTC react-scripts test # See https://github.com/facebook/jest/issues/11354",
"test:coverage": "TZ=UTC react-scripts test --coverage --watchAll=false",

View File

@ -6,6 +6,7 @@ import API from '../../../../../api';
import { AppCtx, unselectOrg } from '../../../../../context/AppCtx';
import { AuthorizerAction, ErrorKind, Organization } from '../../../../../types';
import alertDispatcher from '../../../../../utils/alertDispatcher';
import scrollToTop from '../../../../../utils/scrollToTop';
import InputField from '../../../../common/InputField';
import Modal from '../../../../common/Modal';
import ActionBtn from '../../../ActionBtn';
@ -31,7 +32,7 @@ const DeleteOrganization = (props: Props) => {
setIsDeleting(true);
await API.deleteOrganization(props.organization.name);
dispatch(unselectOrg());
window.scrollTo(0, 0); // Scroll to top when org is deleted
scrollToTop(); // Scroll to top when org is deleted
setIsDeleting(false);
} catch (err: any) {
setIsDeleting(false);

View File

@ -14,6 +14,9 @@ jest.mock('react-markdown', () => (props: any) => {
return <>{props.children}</>;
});
jest.mock('remark-gfm', () => () => <div />);
jest.mock('../../utils/bannerDispatcher', () => ({
getBanner: () => null,
}));
const getMockPackage = (fixtureId: string): Package => {
return require(`./__fixtures__/index/${fixtureId}.json`) as Package;

View File

@ -34,6 +34,7 @@ import bannerDispatcher from '../../utils/bannerDispatcher';
import isFuture from '../../utils/isFuture';
import isPackageOfficial from '../../utils/isPackageOfficial';
import { prepareQueryString } from '../../utils/prepareQueryString';
import scrollToTop from '../../utils/scrollToTop';
import sortPackageVersions from '../../utils/sortPackageVersions';
import updateMetaIndex from '../../utils/updateMetaIndex';
import AnchorHeader from '../common/AnchorHeader';
@ -240,7 +241,7 @@ const PackageView = (props: Props) => {
setApiError(null);
setCurrentPkgId(detailPkg.packageId);
setRelatedPosition(undefined);
window.scrollTo(0, 0); // Scroll to top when a new version is loaded
scrollToTop(); // Scroll to top when a new version is loaded
// Stop loading when readme is not defined or is the same than the previous one
if (
isNull(detailPkg.readme) ||
@ -508,7 +509,7 @@ const PackageView = (props: Props) => {
if (props.hash !== currentHash) {
setCurrentHash(props.hash);
if (isUndefined(props.hash) || props.hash === '') {
window.scrollTo(0, 0);
scrollToTop();
} else {
scrollIntoView();
}

View File

@ -15,6 +15,7 @@ import { FacetOption, Facets, Package, RepositoryKind, SearchFiltersURL, SearchR
import { TS_QUERY } from '../../utils/data';
import getSampleQueries from '../../utils/getSampleQueries';
import { prepareQueryString } from '../../utils/prepareQueryString';
import scrollToTop from '../../utils/scrollToTop';
import Loading from '../common/Loading';
import NoData from '../common/NoData';
import Pagination from '../common/Pagination';
@ -121,10 +122,6 @@ const SearchView = (props: Props) => {
setScrollPosition(window.scrollY);
};
const updateWindowScrollPosition = (newPosition: number) => {
window.scrollTo(0, newPosition);
};
const prepareSelectedFilters = (name: string, newFilters: string[], prevFilters: FiltersProp): FiltersProp => {
let cleanFilters: FiltersProp = {};
switch (name) {
@ -260,7 +257,7 @@ const SearchView = (props: Props) => {
}),
});
setScrollPosition(0);
updateWindowScrollPosition(0);
scrollToTop(0);
};
const onPaginationLimitChange = (newLimit: number): void => {
@ -272,7 +269,7 @@ const SearchView = (props: Props) => {
}),
});
setScrollPosition(0);
updateWindowScrollPosition(0);
scrollToTop(0);
dispatch(updateLimit(newLimit));
};
@ -322,14 +319,14 @@ const SearchView = (props: Props) => {
if (history.action === 'PUSH') {
// When search page is open from detail page
if (props.fromDetail && !isUndefined(scrollPosition)) {
updateWindowScrollPosition(scrollPosition);
scrollToTop(scrollPosition);
// When search has changed
} else {
updateWindowScrollPosition(0);
scrollToTop(0);
}
// On pop action and when scroll position has been previously saved
} else if (!isUndefined(scrollPosition)) {
updateWindowScrollPosition(scrollPosition);
scrollToTop(scrollPosition);
}
}
}

View File

@ -0,0 +1,20 @@
const parser = require('ua-parser-js');
class BrowserDetect {
private ua: any = {};
public init() {
this.ua = parser(navigator.userAgent);
}
public isSafari(): boolean {
if (this.ua.browser.name.includes('Safari')) {
return true;
}
return false;
}
}
const browserDetect = new BrowserDetect();
browserDetect.init();
export default browserDetect;

View File

@ -0,0 +1,12 @@
import browserDetect from './browserDetect';
const scrollToTop = (position?: number): void => {
const isSafari = browserDetect.isSafari();
window.scrollTo({
top: position || 0,
// @ts-ignore: Unreachable code error
behavior: isSafari ? 'instant' : 'auto',
});
};
export default scrollToTop;

View File

@ -10118,6 +10118,11 @@ typescript@^4.9.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
ua-parser-js@^1.0.32:
version "1.0.32"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.32.tgz#786bf17df97de159d5b1c9d5e8e9e89806f8a030"
integrity sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"