h1 + ExpandableContent + ...

This commit is contained in:
hamid zarghami
2025-08-18 16:31:07 +03:30
parent e4b6758754
commit 922b62909c
4 changed files with 65 additions and 5 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ const DanakSuggestedService: FC = () => {
{
data?.data?.danakSuggestServices?.map((item) => {
return (
<ServiceItem key={item.id} item={item} />
<ServiceItem isShort key={item.id} item={item} />
)
})
}
+2 -2
View File
@@ -1,5 +1,6 @@
'use client'
import { FC, Fragment } from 'react'
import ExpandableContent from '@/components/ExpandableContent'
import { useGetProductBySlug } from './hooks/useProductData'
import ServiceHeader from './components/ServiceHeader'
import moment from 'moment-jalaali'
@@ -94,8 +95,7 @@ const DetailService: FC<{ id: string }> = ({ id }) => {
توضیحات کامل
</div>
{getDetailService.data?.data?.danakService?.metaDescription && (
<p dangerouslySetInnerHTML={{ __html: getDetailService.data.data.danakService.metaDescription }} className='text-[13px] text-description mt-4 leading-6'>
</p>
<ExpandableContent html={getDetailService.data.data.danakService.metaDescription} />
)}
</div>
@@ -40,9 +40,9 @@ const ServiceHeader: FC<Props> = (props: Props) => {
<Image alt='icon' width={70} height={70} src={data?.icon} className='w-full h-full rounded-xl' />
</div>
<div>
<div>
<h1>
{data?.name}
</div>
</h1>
<p className='text-description mt-1 text-[11px]'>
{data?.description}
+60
View File
@@ -0,0 +1,60 @@
'use client'
import { FC, memo, useEffect, useRef, useState } from 'react'
import Button from '@/components/Button'
import { clx } from '@/helpers/utils'
type Props = {
html: string;
collapsedHeightClass?: string; // e.g. 'max-h-36' for ~6 lines with leading-6
className?: string;
}
const ExpandableContent: FC<Props> = memo(({ html, collapsedHeightClass = 'max-h-36', className }) => {
const [expanded, setExpanded] = useState(false)
const [isOverflowing, setIsOverflowing] = useState(false)
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const el = containerRef.current
if (!el) return
if (expanded) {
setIsOverflowing(false)
return
}
setIsOverflowing(el.scrollHeight > el.clientHeight + 1)
}, [html, expanded])
return (
<div className={clx('mt-4', className)}>
<div
ref={containerRef}
className={clx(
'relative text-[13px] text-description leading-6',
!expanded && 'overflow-hidden',
!expanded && collapsedHeightClass,
)}
>
<div dangerouslySetInnerHTML={{ __html: html }} />
{!expanded && isOverflowing && (
<div className='pointer-events-none absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-white to-transparent' />
)}
</div>
{isOverflowing || expanded ? (
<div className='mt-3'>
<Button
type='button'
onClick={() => setExpanded((s) => !s)}
className='h-8 w-fit px-3 text-xs rounded-lg'
label={expanded ? 'بستن' : 'مشاهده بیشتر'}
/>
</div>
) : null}
</div>
)
})
ExpandableContent.displayName = 'ExpandableContent'
export default ExpandableContent