feat: implement dynamic row-based tag clipping in TopProfessionals and fix typo in CommonHeader

This commit is contained in:
pradeepkumar
2026-04-15 11:47:40 +05:30
parent 5e787f2720
commit 56c300f368
2 changed files with 48 additions and 7 deletions

View File

@@ -1,6 +1,6 @@
'use client';
import { useState, useEffect } from 'react';
import { useState, useEffect, useLayoutEffect, useRef } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { uploadService } from '@/services/upload.service';
@@ -32,7 +32,47 @@ function ProfessionalCard({
const [imgError, setImgError] = useState(false);
const placeholder = '/assets/icons/user-placeholder-icon.svg';
const isPlaceholder = imageUrl === placeholder;
const INITIAL_TAG_COUNT = 4;
// Dynamic row-based tag clipping: show as many tags as fit in 2 rows, with "+N more" if overflow
const tagContainerRef = useRef<HTMLDivElement>(null);
const [visibleTagCount, setVisibleTagCount] = useState<number>(expertise.length);
useLayoutEffect(() => {
const container = tagContainerRef.current;
if (!container) return;
const measure = () => {
const items = Array.from(container.querySelectorAll<HTMLElement>('[data-tag]'));
if (items.length === 0) return;
const firstTop = items[0].offsetTop;
let secondTop: number | null = null;
let rowBreakIndex = items.length;
for (let i = 0; i < items.length; i++) {
const top = items[i].offsetTop;
if (top > firstTop) {
if (secondTop === null) secondTop = top;
if (top > secondTop) {
rowBreakIndex = i;
break;
}
}
}
const hasOverflow = rowBreakIndex < items.length;
// If overflow, drop one tag to reserve space for "+N more" chip
const finalCount = hasOverflow ? Math.max(1, rowBreakIndex - 1) : rowBreakIndex;
setVisibleTagCount(finalCount);
};
measure();
const ro = new ResizeObserver(measure);
ro.observe(container);
return () => ro.disconnect();
}, [expertise]);
const hiddenCount = expertise.length - visibleTagCount;
return (
<div className="bg-white rounded-[15px] overflow-hidden shadow-[0px_4px_20px_rgba(0,0,0,0.08)] h-full flex flex-col">
@@ -112,18 +152,19 @@ function ProfessionalCard({
<p className="font-fractul font-bold text-[14px] leading-normal text-[#00293d]">
Expertise:
</p>
<div className="flex flex-wrap gap-1.5 mt-2 items-center max-h-[54px] overflow-hidden">
{expertise.slice(0, INITIAL_TAG_COUNT).map((tag, index) => (
<div ref={tagContainerRef} className="flex flex-wrap gap-1.5 mt-2 items-center max-h-[54px] overflow-hidden">
{expertise.slice(0, visibleTagCount).map((tag, index) => (
<span
key={index}
data-tag
className="border-[0.7px] border-[#00293d] rounded-[15px] px-[5px] h-[24px] flex items-center justify-center font-serif font-normal text-[13px] leading-[100%] text-[#00293d] whitespace-nowrap flex-shrink-0"
>
{tag}
</span>
))}
{expertise.length > INITIAL_TAG_COUNT && (
{hiddenCount > 0 && (
<span className="bg-[#e58625]/15 text-[#e58625] rounded-[15px] px-2 h-[24px] flex items-center justify-center font-serif font-semibold text-[12px] leading-[100%] whitespace-nowrap flex-shrink-0">
+{expertise.length - INITIAL_TAG_COUNT} more
+{hiddenCount} more
</span>
)}
</div>

View File

@@ -254,7 +254,7 @@ export function CommonHeader() {
Sign in
</span>
<span className="font-fractul font-bold text-[10px] text-[#00293d] leading-tight">
Sign into connect
Sign in to Connect
</span>
</div>
</button>