0558d8c58a
- Le nombre d'onglets affichés en mode fenêtré s'adapte automatiquement à la largeur réelle (ResizeObserver + ligne de mesure cachée). Les chevrons restent fixés aux bords ; le nombre est choisi pour que les onglets tiennent (pas de chevauchement ni de rognage). Calcul isolé en fonction pure testable (tabFit.ts, basée sur les vraies largeurs). maxVisibleTabs devient un plafond optionnel. - BREAKING : suppression de la prop maxWidth (la barre prend toute la largeur). - Survol d'un onglet inactif : même style que l'actif (texte m-primary + barre). - Playground : bac à sable interactif (nb onglets, plafond, icônes, labels longs, cadre redimensionnable) pour tester tous les cas. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.9 KiB
TypeScript
44 lines
1.9 KiB
TypeScript
import {describe, it, expect} from 'vitest'
|
||
import {computeVisibleCount} from './tabFit'
|
||
|
||
const base = {gap: 60, chevronReserve: 110}
|
||
const widths = (n: number, w = 180) => Array.from({length: n}, () => w)
|
||
|
||
describe('computeVisibleCount', () => {
|
||
it('sans layout : respecte maxVisibleTabs', () => {
|
||
expect(computeVisibleCount({...base, count: 5, containerWidth: 0, tabWidths: [], maxVisibleTabs: 3})).toBe(3)
|
||
})
|
||
|
||
it('sans layout ni maxVisibleTabs : tous les onglets', () => {
|
||
expect(computeVisibleCount({...base, count: 5, containerWidth: 0, tabWidths: []})).toBe(5)
|
||
})
|
||
|
||
it('tout tient : retourne le total (pas de chevrons)', () => {
|
||
// 4×180 + 3×60 = 900 <= 1000
|
||
expect(computeVisibleCount({...base, count: 4, containerWidth: 1000, tabWidths: widths(4)})).toBe(4)
|
||
})
|
||
|
||
it('trop large : additionne les vraies largeurs (pas la pire) — pas d\'effondrement à 1', () => {
|
||
// total 7×180+6×60=1620 > 1400 ; avail=1400-110=1290 ; 180,420,660,900,1140,(1380>1290) → 5
|
||
expect(computeVisibleCount({...base, count: 7, containerWidth: 1400, tabWidths: widths(7)})).toBe(5)
|
||
})
|
||
|
||
it('largeur étroite : montre ce qui tient (≥ 2 ici, pas 1)', () => {
|
||
// avail=570-110=460 ; 180,(420),(660>460) → 2
|
||
expect(computeVisibleCount({...base, count: 7, containerWidth: 570, tabWidths: widths(7)})).toBe(2)
|
||
})
|
||
|
||
it('maxVisibleTabs plafonne le résultat', () => {
|
||
expect(computeVisibleCount({...base, count: 7, containerWidth: 1400, tabWidths: widths(7), maxVisibleTabs: 3})).toBe(3)
|
||
})
|
||
|
||
it('au moins 1 onglet si rien ne tient', () => {
|
||
expect(computeVisibleCount({...base, count: 5, containerWidth: 150, tabWidths: widths(5, 300)})).toBe(1)
|
||
})
|
||
|
||
it('gère des largeurs hétérogènes', () => {
|
||
// total 1080 > 1000 → fenêtré ; avail=1000-110=890 ; 300,560,820,(1080>890) → 3
|
||
expect(computeVisibleCount({...base, count: 4, containerWidth: 1000, tabWidths: [300, 200, 200, 200]})).toBe(3)
|
||
})
|
||
})
|