diff --git a/components/text.js b/components/text.js index 10547f8a..e9e90ee1 100644 --- a/components/text.js +++ b/components/text.js @@ -6,7 +6,7 @@ import { LightAsync as SyntaxHighlighter } from 'react-syntax-highlighter' import atomDark from 'react-syntax-highlighter/dist/cjs/styles/prism/atom-dark' import mention from '../lib/remark-mention' import sub from '../lib/remark-sub' -import React, { useState, memo, useRef, useCallback, useMemo } from 'react' +import React, { useState, memo, useRef, useCallback, useMemo, useEffect } from 'react' import GithubSlugger from 'github-slugger' import LinkIcon from '../svgs/link.svg' import Thumb from '../svgs/thumb-up-fill.svg' @@ -16,6 +16,7 @@ import ZoomableImage, { decodeOriginalUrl } from './image' import { IMGPROXY_URL_REGEXP } from '../lib/url' import reactStringReplace from 'react-string-replace' import { rehypeInlineCodeProperty } from '../lib/md' +import { Button } from 'react-bootstrap' export function SearchText ({ text }) { return ( @@ -31,6 +32,17 @@ export function SearchText ({ text }) { // this is one of the slowest components to render export default memo(function Text ({ nofollow, imgproxyUrls, children, tab, ...outerProps }) { + const [overflowing, setOverflowing] = useState(false) + const [show, setShow] = useState(false) + const containerRef = useRef(null) + + useEffect(() => { + const container = containerRef.current + if (!container || overflowing) return + + setOverflowing(container.scrollHeight > window.innerHeight) + }, [containerRef.current]) + // all the reactStringReplace calls are to facilitate search highlighting const slugger = useRef(new GithubSlugger()) @@ -101,7 +113,7 @@ export default memo(function Text ({ nofollow, imgproxyUrls, children, tab, ...o }, [imgproxyUrls, outerProps, tab]) return ( -
+
{children} + {overflowing && !show && + }
) }) diff --git a/components/text.module.css b/components/text.module.css index e6437c4d..af315e77 100644 --- a/components/text.module.css +++ b/components/text.module.css @@ -3,6 +3,32 @@ font-family: inherit; word-break: break-word; line-height: 140%; + overflow-y: hidden; + position: relative; +} + +.textContained { + max-height: 200vh; +} + +.textContained::before { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 50vh; + pointer-events: none; + z-index: 1; + background: linear-gradient(rgba(255, 255, 255, 0), var(--bs-body-bg) 200%); +} + +.textShowFull { + position: absolute; + bottom: 0; + left: 0; + border-radius: 0; + z-index: 2; } @media screen and (min-width: 767px) { @@ -47,6 +73,7 @@ } .text .p { + display: block; margin-bottom: .5rem; white-space: pre-wrap; word-break: break-word;