Skip to content

Instantly share code, notes, and snippets.

@Acen
Created April 6, 2022 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Acen/5f9389557cdaf38b9d2c6e03a46ee304 to your computer and use it in GitHub Desktop.
Save Acen/5f9389557cdaf38b9d2c6e03a46ee304 to your computer and use it in GitHub Desktop.
i cri err tim
import React, {useEffect, useRef, useState} from "react"
import {GatsbyImage, getImage} from "gatsby-plugin-image"
import {classNames} from "../../../../utils"
import Clamp from "react-multiline-clamp"
import parse from 'html-react-parser'
import {MinusSmIcon, PlusSmIcon} from "@heroicons/react/solid";
export const Section = ({data, darken, side}) => {
const image = getImage(data.image?.localFile) ?? null
const bgClass = darken ? `bg-white` : `bg-white`
return (
<div className={`${bgClass} overflow-hidden md:mb-0 mb-8`}>
<div
className={classNames("relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 lg:grid lg:grid-cols-2 lg:grid-rows-contentSection my-12", (image || (data?.section?.body && data?.section?.title)) && "lg:gap-8")}>
{image ? (
side === "left" ? (
<LeftSection data={data} image={image}/>
) : (
<RightSection data={data} image={image}/>
)
) : (
<CenteredSection data={data}/>
)}
</div>
</div>
)
}
const LeftSection = ({data, image}) => {
const defaultHeightLimit = 552;
const [heightLimit, setHeightLimit] = useState(defaultHeightLimit);
const [lineHeight, setLineHeight] = useState(24);
const [lines, setLines] = useState(14);
const [currentContentHeight, setCurrentContentHeight] = useState(0);
// const [cleanCount, setCleanCount] = useState(1);
const [cleanedContent, setCleanedContent] = useState([]);
const [marginHeight, setMarginHeight] = useState(0);
const [ClampedElement, setClampedElement] = useState(null);
const titleRef = useRef(null);
const contentRef = useRef(null);
useEffect(() => {
if (contentRef.current) {
setLineHeight(contentRef.current.scrollHeight);
const styles = getComputedStyle(contentRef.current);
setMarginHeight(parseFloat(styles['margin-top']) + parseFloat(styles['margin-bottom']));
}
}, [contentRef])
useEffect(() => {
setHeightLimit(defaultHeightLimit - titleRef.current.clientHeight);
console.log(`heightLimit`, heightLimit);
}, [titleRef])
useEffect(() => {
if (cleanedContent.length) {
console.log({cleanedContent});
}
}, [cleanedContent]);
useEffect(() => {
setCleanedContent(parse(data.section.body.replace(/\n|\r/g, "")));
// const availableHeight = ((heightLimit - (5 * marginHeight)));
// // console.log(availableHeight);
// // console.log(availableHeight, `(heightLimit - (5 * marginHeight)) - titleRef.current.clientHeight | (${heightLimit} - (5 * ${marginHeight})) - ${titleRef.current.clientHeight}`);
// const lineCount = availableHeight / lineHeight;
// console.log({availableHeight, lineHeight, lineCount});
// console.log(lineCount);
// setLines(Math.ceil(lineCount) + 1);
// // console.log({
// // availableHeight,
// // lineHeight,
// // lineCount,
// // lines
// // }, `availableHeight / lineHeight - ${availableHeight} / ${lineHeight}`)
}, [data/*, titleRef, lineHeight*/])
// const handleContentHeight = (ref) => {
// console.log('hch');
// if(ref && ref.current) {
// const styles = getComputedStyle(ref.current);
// const margin = parseFloat(styles['margin-top']) + parseFloat(styles['margin-bottom']);
// setCurrentContentHeight((current) => {
// console.log('cch', currentContentHeight);
//
// const totalElementHeight = ref.clientHeight + margin;
// console.log(totalElementHeight);
// if (current <= heightLimit) {
// console.log('pre', lines);
// setLines((lineCount) => {
// return lineCount + (ref.clientHeight / parseFloat(styles['line-height']));
// });
// return current - (ref.clientHeight + margin);
// // setLines()
// } else {
//
// console.log('post', lines);
// }
// })
// }
// // setLines((currentLine) =>)
// // console.log(ref.clientHeight / parseFloat(styles['line-height']))
// // console.log('p height', ref.clientHeight + margin)
// // console.log(lines);
// }
useEffect(() => {
setClampedElement(<Clamp
className="text-base max-w-prose mx-auto lg:max-w-none list-disc list-outside"
showMoreElement={({toggle}) => (
<div className="relative">
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center mt-8">
<button
onClick={toggle}
type="button"
className="inline-flex items-center shadow-sm px-4 py-1.5 border border-gray-300 text-sm leading-5 font-medium rounded-full text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
<PlusSmIcon className="-ml-1.5 mr-1 h-5 w-5 text-gray-400" aria-hidden="true" />
<span>Show more</span>
</button>
</div>
</div>
// <p onClick={toggle}
// className={`mt-4 hover:bg-slate-50 inline-block py-1 px-1 rounded-md cursor-pointer`}>
// Show more
// </p>
)}
showLessElement={({toggle}) => (
<div className="relative">
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center mt-8">
<button
onClick={toggle}
type="button"
className="inline-flex items-center shadow-sm px-4 py-1.5 border border-gray-300 text-sm leading-5 font-medium rounded-full text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
<MinusSmIcon className="-ml-1.5 mr-1 h-5 w-5 text-gray-400" aria-hidden="true" />
<span>Show less</span>
</button>
</div>
</div>
)}
lines={lines}
maxLines={100}
withTooltip={false}
withToggle
>
<div dangerouslySetInnerHTML={{__html: data.section.body}} />
</Clamp>);
}, [lines])
return (
<>
{data?.section?.title && (
<div ref={titleRef} className="mx-auto text-base max-w-prose lg:max-w-none w-full">
<h2 className="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl">
{data.section.title}
</h2>
</div>
)}
<div className="relative lg:col-start-2 lg:row-span-2 pt-8 sm:pt-0">
<div className="relative text-base mx-auto max-w-prose lg:max-w-none">
<figure>
<div
className={classNames("aspect-w-12 aspect-h-7 lg:aspect-none")}
>
{image ? (
<GatsbyImage
alt={data.section.image?.altText ?? data.section.title}
image={image}
className={`w-full`}
/>
) : null}
</div>
{data.section.imageCaption ? (
<figcaption className="mt-3 flex text-sm text-gray-500">
<span className="ml-2">{data.section.imageCaption}</span>
</figcaption>
) : null}
</figure>
</div>
</div>
<div className="mt-8 lg:mt-0">
<div
className={`opacity-0 absolute text-base max-w-prose mx-auto lg:max-w-none list-disc list-outside mt-2`}
><p className={`mt-8`} ref={contentRef}>Height Element</p></div>
{ClampedElement}
</div>
{data.section.button?.label && (
<div className={`text-center lg:col-span-2`}>
<a
href={data.section.button?.link?.url ?? '/contact-us/'}
target={data.section.button?.link?.target ?? ''}
className={`bg-blue-500 rounded-md p-2 inline-flex items-center justify-center text-white hover:text-gray-300 focus:outline-none w-full md:w-96 px-4 py-3 mt-8`}
>
{data.section.button?.label ?? 'yes'}
</a>
</div>
)}
</>
)
}
const RightSection = ({image, data}) => {
const heightLimit = 600;
const [lineHeight, setLineHeight] = useState(24);
const [lines, setLines] = useState(5);
const [marginHeight, setMarginHeight] = useState(0);
const [ClampedElement, setClampedElement] = useState(null);
const titleRef = useRef(null);
const contentRef = useRef(null);
useEffect(() => {
if (contentRef.current) {
setLineHeight(contentRef.current.scrollHeight);
const styles = getComputedStyle(contentRef.current);
setMarginHeight(parseFloat(styles['margin-top']) + parseFloat(styles['margin-bottom']));
console.log({lineHeight, marginHeight});
}
}, [contentRef])
useEffect(() => {
const availableHeight = ((heightLimit - (5 * marginHeight)) - titleRef?.current?.clientHeight);
const lineCount = availableHeight / lineHeight;
setLines(Math.ceil(lineCount) + 1);
}, [data, titleRef, lineHeight])
useEffect(() => {
setClampedElement(<Clamp
className="text-base max-w-prose mx-auto lg:max-w-none list-disc list-outside"
showMoreElement={({toggle}) => (
<p onClick={toggle}
className={`mt-4 hover:bg-slate-50 inline-block py-1 px-1 rounded-md cursor-pointer`}>
Show more
</p>
)}
showLessElement={({toggle}) => (
<p onClick={toggle}
className={`mt-4 hover:bg-slate-50 inline-block py-1 px-1 rounded-md cursor-pointer`}>
Show less
</p>
)}
lines={lines}
maxLines={100}
withTooltip={false}
withToggle
>
<div
className="text-base max-w-prose mx-auto lg:max-w-none align-content-middle"
dangerouslySetInnerHTML={{__html: data.section.body}}
/>
</Clamp>);
}, [lines])
return (
<>
{data?.section?.title && (
<div ref={titleRef} className="text-base max-w-prose lg:col-start-2 lg:max-w-none mx-auto w-full">
<h3 className="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl">
{data.section.title}
</h3>
</div>
)}
<div className="lg:row-start-1 lg:col-start-1 lg:row-span-2 pt-8 sm:pt-0">
<div className="relative">
<div className="relative text-base mx-auto max-w-prose lg:max-w-none">
<figure>
<div
className={classNames("aspect-w-12 aspect-h-7 lg:aspect-none")}
>
{image ? (
<GatsbyImage
alt={data.section.image?.altText ?? data.section.title}
image={image}
className={`w-full`}
/>
) : null}
</div>
{data.section.imageCaption ? (
<figcaption className="mt-3 flex text-sm text-gray-500">
<span className="ml-2">{data.section.imageCaption}</span>
</figcaption>
) : null}
</figure>
</div>
</div>
</div>
<div className="mt-8 lg:mt-0">
<div className={`opacity-0 absolute text-base max-w-prose mx-auto lg:max-w-none align-content-middle`}
><p className={`mt-8`} ref={contentRef}>Height Element</p></div>
{ClampedElement}
</div>
{data.section.buttontext ? (
<div className={`text-center lg:col-span-2`}>
<a
href={data.section?.buttonlink?.url ?? '/contact-us/'}
target={data.section?.buttonlink?.target ?? ''}
className={`bg-blue-500 rounded-md p-2 inline-flex items-center justify-center text-white hover:text-gray-300 focus:outline-none w-full md:w-96 px-4 py-3 mt-8`}
>
{data.section.buttontext}
</a>
</div>
) : null}
</>
)
}
const CenteredSection = ({data}) => {
return (
<>
{data?.section?.title && (
<div className="mx-auto text-base max-w-prose lg:col-span-2">
<div>
<h3 className="text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl text-center">
{data.section.title}
</h3>
</div>
</div>
)}
<div className="lg:col-span-2">
<div>
<div
className="text-base max-w-prose mx-auto lg:max-w-3xl align-content-middle text-center"
dangerouslySetInnerHTML={{__html: data.section.body}}
/>
{data.section.buttontext ? (
<div className={`text-center`}>
<a
href={data.section?.buttonlink?.url ?? '/contact-us/'}
target={data.section?.buttonlink?.target ?? ''}
className={`bg-blue-500 rounded-md p-2 inline-flex items-center justify-center text-white hover:text-gray-300 focus:outline-none w-full sm:w-96 px-4 py-3 mt-8`}
>
{data.section.buttontext}
</a>
</div>
) : null}
</div>
</div>
</>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment