mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-07 14:05:44 +01:00
fix scrolling for markdown content, which is loaded asynchronous
The code to find and scroll to the anchor is now moved from the ScrollToTop component to the MarkdownView. The anchor with the id from location hash, is searched after the MarkdownView and all its children finished rendering.
This commit is contained in:
@@ -4,12 +4,17 @@ import SyntaxHighlighter from "./SyntaxHighlighter";
|
||||
import Markdown from "react-markdown/with-html";
|
||||
import {binder} from "@scm-manager/ui-extensions";
|
||||
import MarkdownHeadingRenderer from "./MarkdownHeadingRenderer";
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
|
||||
type Props = {
|
||||
content: string,
|
||||
renderContext?: Object,
|
||||
renderers?: Object,
|
||||
enableAnchorHeadings: boolean
|
||||
enableAnchorHeadings: boolean,
|
||||
|
||||
// context props
|
||||
location: any
|
||||
};
|
||||
|
||||
class MarkdownView extends React.Component<Props> {
|
||||
@@ -18,10 +23,27 @@ class MarkdownView extends React.Component<Props> {
|
||||
enableAnchorHeadings: false
|
||||
};
|
||||
|
||||
contentRef: ?HTMLDivElement;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// we have to use componentDidUpdate, because we have to wait until all
|
||||
// children are rendered and componentDidMount is called before the
|
||||
// markdown content was rendered.
|
||||
const hash = this.props.location.hash;
|
||||
if (this.contentRef && hash) {
|
||||
// we query only child elements, to avoid strange scrolling with multiple
|
||||
// markdown elements on one page.
|
||||
const element = this.contentRef.querySelector(hash);
|
||||
if (element && element.scrollIntoView) {
|
||||
element.scrollIntoView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {content, renderers, renderContext, enableAnchorHeadings} = this.props;
|
||||
|
||||
@@ -45,15 +67,17 @@ class MarkdownView extends React.Component<Props> {
|
||||
}
|
||||
|
||||
return (
|
||||
<Markdown
|
||||
className="content"
|
||||
skipHtml={true}
|
||||
escapeHtml={true}
|
||||
source={content}
|
||||
renderers={rendererList}
|
||||
/>
|
||||
<div ref={el => (this.contentRef = el)}>
|
||||
<Markdown
|
||||
className="content"
|
||||
skipHtml={true}
|
||||
escapeHtml={true}
|
||||
source={content}
|
||||
renderers={rendererList}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MarkdownView;
|
||||
export default withRouter(MarkdownView);
|
||||
|
||||
@@ -11,15 +11,7 @@ type Props = {
|
||||
class ScrollToTop extends React.Component<Props> {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.location.pathname !== prevProps.location.pathname) {
|
||||
const hash = this.props.location.hash;
|
||||
if (hash) {
|
||||
const element = document.getElementById(hash.substring(1));
|
||||
if (element && element.scrollIntoView) {
|
||||
element.scrollIntoView();
|
||||
}
|
||||
} else {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user