mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-15 15:44:45 -04:00
refactor: extract height monitor hook
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
21b2fb042c
commit
71e5d00f55
3 changed files with 41 additions and 14 deletions
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import useResizeObserver from '@react-hook/resize-observer'
|
||||||
|
import type { RefObject } from 'react'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitors the height of the referenced {@link HTMLElement} and executes the callback on change.
|
||||||
|
*
|
||||||
|
* @param elementRef The reference that contains the element to watch
|
||||||
|
* @param onHeightChange The callback that should be executed if the height changes
|
||||||
|
*/
|
||||||
|
export const useOnHeightChange = (
|
||||||
|
elementRef: RefObject<HTMLElement>,
|
||||||
|
onHeightChange: undefined | ((value: number) => void)
|
||||||
|
): void => {
|
||||||
|
const [rendererSize, setRendererSize] = useState<number>(0)
|
||||||
|
useResizeObserver(elementRef, (entry) => {
|
||||||
|
setRendererSize(entry.contentRect.height)
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
const value = elementRef.current?.clientHeight
|
||||||
|
if (value === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setRendererSize(value)
|
||||||
|
}, [elementRef])
|
||||||
|
useEffect(() => {
|
||||||
|
onHeightChange?.(rendererSize + 1)
|
||||||
|
}, [rendererSize, onHeightChange])
|
||||||
|
}
|
|
@ -11,12 +11,13 @@ import { useCalculateLineMarkerPosition } from '../../../markdown-renderer/hooks
|
||||||
import { useMarkdownExtensions } from '../../../markdown-renderer/hooks/use-markdown-extensions'
|
import { useMarkdownExtensions } from '../../../markdown-renderer/hooks/use-markdown-extensions'
|
||||||
import { MarkdownToReact } from '../../../markdown-renderer/markdown-to-react/markdown-to-react'
|
import { MarkdownToReact } from '../../../markdown-renderer/markdown-to-react/markdown-to-react'
|
||||||
import { useDocumentSyncScrolling } from '../../hooks/sync-scroll/use-document-sync-scrolling'
|
import { useDocumentSyncScrolling } from '../../hooks/sync-scroll/use-document-sync-scrolling'
|
||||||
|
import { useOnHeightChange } from '../../hooks/use-on-height-change'
|
||||||
import { RendererType } from '../../window-post-message-communicator/rendering-message'
|
import { RendererType } from '../../window-post-message-communicator/rendering-message'
|
||||||
import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../common-markdown-renderer-props'
|
import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../common-markdown-renderer-props'
|
||||||
import { DocumentTocSidebar } from './document-toc-sidebar'
|
import { DocumentTocSidebar } from './document-toc-sidebar'
|
||||||
import styles from './markdown-document.module.scss'
|
import styles from './markdown-document.module.scss'
|
||||||
import useResizeObserver from '@react-hook/resize-observer'
|
import useResizeObserver from '@react-hook/resize-observer'
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
import React, { useMemo, useRef, useState } from 'react'
|
||||||
|
|
||||||
export type DocumentMarkdownRendererProps = CommonMarkdownRendererProps & ScrollProps & HeightChangeRendererProps
|
export type DocumentMarkdownRendererProps = CommonMarkdownRendererProps & ScrollProps & HeightChangeRendererProps
|
||||||
|
|
||||||
|
@ -41,11 +42,7 @@ export const DocumentMarkdownRenderer: React.FC<DocumentMarkdownRendererProps> =
|
||||||
newLinesAreBreaks
|
newLinesAreBreaks
|
||||||
}) => {
|
}) => {
|
||||||
const rendererRef = useRef<HTMLDivElement | null>(null)
|
const rendererRef = useRef<HTMLDivElement | null>(null)
|
||||||
const [rendererSize, setRendererSize] = useState<DOMRectReadOnly>()
|
useOnHeightChange(rendererRef, onHeightChange)
|
||||||
useResizeObserver(rendererRef.current, (entry) => {
|
|
||||||
setRendererSize(entry.contentRect)
|
|
||||||
})
|
|
||||||
useEffect(() => onHeightChange?.((rendererSize?.height ?? 0) + 1), [rendererSize, onHeightChange])
|
|
||||||
|
|
||||||
const internalDocumentRenderPaneRef = useRef<HTMLDivElement>(null)
|
const internalDocumentRenderPaneRef = useRef<HTMLDivElement>(null)
|
||||||
const [internalDocumentRenderPaneSize, setInternalDocumentRenderPaneSize] = useState<DOMRectReadOnly>()
|
const [internalDocumentRenderPaneSize, setInternalDocumentRenderPaneSize] = useState<DOMRectReadOnly>()
|
||||||
|
@ -74,7 +71,7 @@ export const DocumentMarkdownRenderer: React.FC<DocumentMarkdownRendererProps> =
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${styles['markdown-document']} vh-100 bg-light`}
|
className={`${styles['markdown-document']} vh-100`}
|
||||||
ref={internalDocumentRenderPaneRef}
|
ref={internalDocumentRenderPaneRef}
|
||||||
onScroll={onUserScroll}
|
onScroll={onUserScroll}
|
||||||
data-scroll-element={true}
|
data-scroll-element={true}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||||
import { useMarkdownExtensions } from '../../../markdown-renderer/hooks/use-markdown-extensions'
|
import { useMarkdownExtensions } from '../../../markdown-renderer/hooks/use-markdown-extensions'
|
||||||
import { MarkdownToReact } from '../../../markdown-renderer/markdown-to-react/markdown-to-react'
|
import { MarkdownToReact } from '../../../markdown-renderer/markdown-to-react/markdown-to-react'
|
||||||
|
import { useOnHeightChange } from '../../hooks/use-on-height-change'
|
||||||
import { RendererType } from '../../window-post-message-communicator/rendering-message'
|
import { RendererType } from '../../window-post-message-communicator/rendering-message'
|
||||||
import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../common-markdown-renderer-props'
|
import type { CommonMarkdownRendererProps, HeightChangeRendererProps } from '../common-markdown-renderer-props'
|
||||||
import useResizeObserver from '@react-hook/resize-observer'
|
import React, { useRef } from 'react'
|
||||||
import React, { useEffect, useRef, useState } from 'react'
|
|
||||||
|
|
||||||
export type SimpleMarkdownRendererProps = CommonMarkdownRendererProps & HeightChangeRendererProps
|
export type SimpleMarkdownRendererProps = CommonMarkdownRendererProps & HeightChangeRendererProps
|
||||||
|
|
||||||
|
@ -28,11 +28,7 @@ export const SimpleMarkdownRenderer: React.FC<SimpleMarkdownRendererProps> = ({
|
||||||
newLinesAreBreaks
|
newLinesAreBreaks
|
||||||
}) => {
|
}) => {
|
||||||
const rendererRef = useRef<HTMLDivElement | null>(null)
|
const rendererRef = useRef<HTMLDivElement | null>(null)
|
||||||
const [rendererSize, setRendererSize] = useState<DOMRectReadOnly>()
|
useOnHeightChange(rendererRef, onHeightChange)
|
||||||
useResizeObserver(rendererRef.current, (entry) => {
|
|
||||||
setRendererSize(entry.contentRect)
|
|
||||||
})
|
|
||||||
useEffect(() => onHeightChange?.((rendererSize?.height ?? 0) + 1), [rendererSize, onHeightChange])
|
|
||||||
const extensions = useMarkdownExtensions(baseUrl, RendererType.SIMPLE, [])
|
const extensions = useMarkdownExtensions(baseUrl, RendererType.SIMPLE, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue