h1 + ExpandableContent + ...
This commit is contained in:
@@ -17,7 +17,7 @@ const DanakSuggestedService: FC = () => {
|
|||||||
{
|
{
|
||||||
data?.data?.danakSuggestServices?.map((item) => {
|
data?.data?.danakSuggestServices?.map((item) => {
|
||||||
return (
|
return (
|
||||||
<ServiceItem key={item.id} item={item} />
|
<ServiceItem isShort key={item.id} item={item} />
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { FC, Fragment } from 'react'
|
import { FC, Fragment } from 'react'
|
||||||
|
import ExpandableContent from '@/components/ExpandableContent'
|
||||||
import { useGetProductBySlug } from './hooks/useProductData'
|
import { useGetProductBySlug } from './hooks/useProductData'
|
||||||
import ServiceHeader from './components/ServiceHeader'
|
import ServiceHeader from './components/ServiceHeader'
|
||||||
import moment from 'moment-jalaali'
|
import moment from 'moment-jalaali'
|
||||||
@@ -94,8 +95,7 @@ const DetailService: FC<{ id: string }> = ({ id }) => {
|
|||||||
توضیحات کامل
|
توضیحات کامل
|
||||||
</div>
|
</div>
|
||||||
{getDetailService.data?.data?.danakService?.metaDescription && (
|
{getDetailService.data?.data?.danakService?.metaDescription && (
|
||||||
<p dangerouslySetInnerHTML={{ __html: getDetailService.data.data.danakService.metaDescription }} className='text-[13px] text-description mt-4 leading-6'>
|
<ExpandableContent html={getDetailService.data.data.danakService.metaDescription} />
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</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' />
|
<Image alt='icon' width={70} height={70} src={data?.icon} className='w-full h-full rounded-xl' />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<h1>
|
||||||
{data?.name}
|
{data?.name}
|
||||||
</div>
|
</h1>
|
||||||
|
|
||||||
<p className='text-description mt-1 text-[11px]'>
|
<p className='text-description mt-1 text-[11px]'>
|
||||||
{data?.description}
|
{data?.description}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user