/
Pitonx
/
MyFinance
Обзор
Документация
Войти
/
Pitonx
/
MyFinance
Код
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/components/TagCell.js
120 строк
3 KB
Сергей
2.11.0 - 5.0.9. Вошедшие изменения см. в CHANGELOG.md
02 май 2026, 12:13
02 май 2026, 12:13
dfd3df4
Код
Авторство
О чём код?
import React, { useRef, useLayoutEffect, useState, useCallback } from 'react'; export default function TagCell({ tags }) { const containerRef = useRef(null); const [visibleCount, setVisibleCount] = useState(tags.length); const measure = useCallback(() => { const container = containerRef.current; if (!container || !tags.length) { setVisibleCount(tags.length); return; } const containerWidth = container.offsetWidth; if (!containerWidth) return; const children = Array.from(container.children); const tagElements = children.filter(el => !el.dataset.counter); const counterEl = children.find(el => el.dataset.counter); let total = 0; let count = 0; const gap = 3; const counterWidth = counterEl ? counterEl.offsetWidth + gap : 0; for (let i = 0; i < tagElements.length; i++) { const w = tagElements[i].offsetWidth; const remaining = tagElements.length - i - 1; const needCounter = remaining > 0; const projected = total + w + (needCounter ? counterWidth : 0) + gap; // Первый тег всегда показываем if (i === 0) { total += w + gap; count++; continue; } if (projected <= containerWidth) { total += w + gap; count++; } else { break; } } setVisibleCount(count); }, [tags]); useLayoutEffect(() => { measure(); }, [measure]); // Отслеживаем изменение размера контейнера useLayoutEffect(() => { const container = containerRef.current; if (!container) return; const observer = new ResizeObserver(() => { measure(); }); observer.observe(container); return () => observer.disconnect(); }, [measure]); if (!Array.isArray(tags) || tags.length === 0) return null; const hidden = tags.length - visibleCount; return ( <div ref={containerRef} style={{ display: 'flex', alignItems: 'center', gap: 3, whiteSpace: 'nowrap', overflow: 'hidden', width: '100%', }} > {tags.map((tag, i) => ( <span key={tag.id || tag} style={{ padding: '1px 6px', borderRadius: 10, background: '#e0e0e0', color: '#333', fontSize: 10, whiteSpace: 'nowrap', border: '1px solid #ccc', flexShrink: 0, display: i < visibleCount ? 'inline-block' : 'none', }} > {tag.name || tag} </span> ))} {hidden > 0 && ( <span data-counter="1" title={tags.slice(visibleCount).map(t => t.name || t).join(', ')} style={{ padding: '1px 5px', borderRadius: 10, background: '#f5f5f5', color: '#888', fontSize: 10, whiteSpace: 'nowrap', border: '1px solid #e0e0e0', flexShrink: 0, cursor: 'default', }} > +{hidden} </span> )} </div> ); }