diff --git a/src/components/Object/Object.jsx b/src/components/Object/Object.jsx index 5e45bac..de91261 100644 --- a/src/components/Object/Object.jsx +++ b/src/components/Object/Object.jsx @@ -1,26 +1,59 @@ import "./Object.scss"; -import { useState } from "react"; +import { useState, useEffect, useRef } from "react"; function Object(props) { const [isExpanded, setIsExpanded] = useState(false); + const [needsExpansion, setNeedsExpansion] = useState(false); + const contentRef = useRef(null); - const addressLimit = 30; - const isAddressTooLong = props.address && props.address.length > addressLimit; - const needsExpansion = isAddressTooLong; + const checkIfContentOverflows = () => { + if (contentRef.current) { + // Временно убираем класс collapsed для измерения полной высоты + const element = contentRef.current; + const hadCollapsedClass = element.classList.contains( + "item__content--collapsed" + ); - const truncateAddress = (text) => { - if (!text) return ""; - if (isExpanded) return text; - if (text.length <= addressLimit) return text; + if (hadCollapsedClass) { + element.classList.remove("item__content--collapsed"); + } - const truncated = text.substring(0, addressLimit); - const lastSpaceIndex = truncated.lastIndexOf(" "); - if (lastSpaceIndex > 0) { - return truncated.substring(0, lastSpaceIndex) + "..."; + // Измеряем полную высоту + const fullHeight = element.scrollHeight; + + // Возвращаем класс обратно + if (hadCollapsedClass) { + element.classList.add("item__content--collapsed"); + } + + // Измеряем высоту в свернутом состоянии + const collapsedHeight = element.clientHeight; + + // Проверяем, есть ли разница больше чем 20px (чтобы избежать ложных срабатываний) + const heightDifference = fullHeight - collapsedHeight; + setNeedsExpansion(heightDifference > 20); } - return truncated + "..."; }; + useEffect(() => { + // Задержка для правильного расчета после рендера + const timeoutId = setTimeout(() => { + checkIfContentOverflows(); + }, 200); + + // Проверяем при изменении размера окна + const handleResize = () => { + setTimeout(checkIfContentOverflows, 100); + }; + + window.addEventListener("resize", handleResize); + + return () => { + clearTimeout(timeoutId); + window.removeEventListener("resize", handleResize); + }; + }, [props.desc, props.address]); + const toggleExpansion = () => { setIsExpanded(!isExpanded); }; @@ -29,23 +62,31 @@ function Object(props) {
квартира
-
+

{props.price}

{props.desc}

- {truncateAddress(props.address)} + {props.address}

+ {needsExpansion && ( - +
+ +
)}
diff --git a/src/components/Object/Object.scss b/src/components/Object/Object.scss index 1d64e70..195d930 100644 --- a/src/components/Object/Object.scss +++ b/src/components/Object/Object.scss @@ -191,6 +191,78 @@ flex: 1; display: flex; flex-direction: column; + margin-bottom: 10px; + transition: max-height 0.3s ease, opacity 0.2s ease; + + &--collapsed { + max-height: 180px; + overflow: hidden; + position: relative; + + &::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 20px; + background: linear-gradient(transparent, white); + pointer-events: none; + } + + @media (min-width: 1800px) { + max-height: 200px; + } + + @media (max-width: 1300px) { + max-height: 170px; + } + + @media (max-width: 1200px) { + max-height: 160px; + } + + @media (max-width: 1100px) { + max-height: 150px; + } + + @media (max-width: $laptopWidth) { + max-height: 140px; + } + + @media (max-width: $tabletWidth) { + max-height: 190px; + } + + @media (max-width: 740px) { + max-height: 180px; + } + + @media (max-width: 690px) { + max-height: 170px; + } + + @media (max-width: 635px) { + max-height: 160px; + } + + @media (max-width: 570px) { + max-height: 150px; + } + + @media (max-width: $mobileWidth) { + max-height: 160px; + } + + @media (max-width: 420px) { + max-height: 150px; + } + } +} + +.item__expand-wrapper { + margin-top: auto; + padding-top: 5px; } .item__price { @@ -239,12 +311,11 @@ .item__expand-btn { background: none; border: none; - color: #007bff; + color: #007bff !important; font-size: 11px; font-weight: 500; cursor: pointer; padding: 4px 0; - margin-top: auto; margin-bottom: 5px; text-align: left; transition: color 0.2s ease; @@ -256,12 +327,17 @@ text-overflow: ellipsis; &:hover { - color: #0056b3; + color: #0056b3 !important; text-decoration: underline; } &:focus { outline: none; + color: #007bff !important; + } + + &:visited { + color: #007bff !important; } @media (min-width: 1800px) {