146 lines
6.5 KiB
TypeScript
146 lines
6.5 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import * as deesCatalog from '../ts_web/index.js';
|
|
|
|
tap.test('tabs indicator positioning - detailed measurements', async () => {
|
|
// Create tabs element with different length labels
|
|
const tabsElement = new deesCatalog.DeesAppuiTabs();
|
|
tabsElement.tabs = [
|
|
{ key: 'Home', iconName: 'lucide:home', action: () => {} },
|
|
{ key: 'Analytics Dashboard', iconName: 'lucide:lineChart', action: () => {} },
|
|
{ key: 'User Settings', iconName: 'lucide:settings', action: () => {} },
|
|
];
|
|
|
|
document.body.appendChild(tabsElement);
|
|
await tabsElement.updateComplete;
|
|
|
|
// Wait for fonts and indicator initialization
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
// Get all elements
|
|
const shadowRoot = tabsElement.shadowRoot;
|
|
const wrapper = shadowRoot.querySelector('.tabs-wrapper') as HTMLElement;
|
|
const container = shadowRoot.querySelector('.tabsContainer') as HTMLElement;
|
|
const tabs = shadowRoot.querySelectorAll('.tab');
|
|
const firstTab = tabs[0] as HTMLElement;
|
|
const firstContent = firstTab.querySelector('.tab-content') as HTMLElement;
|
|
const indicator = shadowRoot.querySelector('.tabIndicator') as HTMLElement;
|
|
|
|
// Verify all elements exist
|
|
expect(wrapper).toBeInstanceOf(HTMLElement);
|
|
expect(container).toBeInstanceOf(HTMLElement);
|
|
expect(firstTab).toBeInstanceOf(HTMLElement);
|
|
expect(firstContent).toBeInstanceOf(HTMLElement);
|
|
expect(indicator).toBeInstanceOf(HTMLElement);
|
|
|
|
// Get all measurements
|
|
const wrapperRect = wrapper.getBoundingClientRect();
|
|
const containerRect = container.getBoundingClientRect();
|
|
const tabRect = firstTab.getBoundingClientRect();
|
|
const contentRect = firstContent.getBoundingClientRect();
|
|
const indicatorRect = indicator.getBoundingClientRect();
|
|
|
|
console.log('\n=== DETAILED MEASUREMENTS ===');
|
|
console.log('Document body left:', document.body.getBoundingClientRect().left);
|
|
console.log('Wrapper left:', wrapperRect.left);
|
|
console.log('Container left:', containerRect.left);
|
|
console.log('Tab left:', tabRect.left);
|
|
console.log('Content left:', contentRect.left);
|
|
console.log('Indicator left (actual):', indicatorRect.left);
|
|
|
|
console.log('\n=== RELATIVE POSITIONS ===');
|
|
console.log('Container padding (container - wrapper):', containerRect.left - wrapperRect.left);
|
|
console.log('Tab position in container:', tabRect.left - containerRect.left);
|
|
console.log('Content position in tab:', contentRect.left - tabRect.left);
|
|
console.log('Content relative to wrapper:', contentRect.left - wrapperRect.left);
|
|
console.log('Indicator relative to wrapper (actual):', indicatorRect.left - wrapperRect.left);
|
|
|
|
console.log('\n=== WIDTHS ===');
|
|
console.log('Tab width:', tabRect.width);
|
|
console.log('Content width:', contentRect.width);
|
|
console.log('Indicator width:', indicatorRect.width);
|
|
|
|
console.log('\n=== STYLES (what we set) ===');
|
|
console.log('Indicator style.left:', indicator.style.left);
|
|
console.log('Indicator style.width:', indicator.style.width);
|
|
|
|
console.log('\n=== CALCULATIONS ===');
|
|
const expectedIndicatorLeft = contentRect.left - wrapperRect.left - 4; // We subtract 4 to center
|
|
const expectedIndicatorWidth = contentRect.width + 8; // We add 8 in the code
|
|
console.log('Expected indicator left:', expectedIndicatorLeft);
|
|
console.log('Expected indicator width:', expectedIndicatorWidth);
|
|
console.log('Actual indicator left (from style):', parseFloat(indicator.style.left));
|
|
console.log('Actual indicator width (from style):', parseFloat(indicator.style.width));
|
|
|
|
console.log('\n=== VISUAL ALIGNMENT CHECK ===');
|
|
const tabCenter = tabRect.left + (tabRect.width / 2);
|
|
const contentCenter = contentRect.left + (contentRect.width / 2);
|
|
const indicatorCenter = indicatorRect.left + (indicatorRect.width / 2);
|
|
|
|
console.log('Tab center:', tabCenter);
|
|
console.log('Content center:', contentCenter);
|
|
console.log('Indicator center:', indicatorCenter);
|
|
console.log('Content offset from tab center:', contentCenter - tabCenter);
|
|
console.log('Indicator offset from content center:', indicatorCenter - contentCenter);
|
|
console.log('Indicator offset from tab center:', indicatorCenter - tabCenter);
|
|
console.log('---');
|
|
console.log('Indicator extends left of content by:', contentRect.left - indicatorRect.left);
|
|
console.log('Indicator extends right of content by:', (indicatorRect.left + indicatorRect.width) - (contentRect.left + contentRect.width));
|
|
|
|
// Check if icons are rendering
|
|
const icon = firstContent.querySelector('dees-icon');
|
|
console.log('\n=== ICON CHECK ===');
|
|
console.log('Icon element found:', icon ? 'YES' : 'NO');
|
|
if (icon) {
|
|
const iconRect = icon.getBoundingClientRect();
|
|
console.log('Icon width:', iconRect.width);
|
|
console.log('Icon height:', iconRect.height);
|
|
console.log('Icon visible:', iconRect.width > 0 && iconRect.height > 0 ? 'YES' : 'NO');
|
|
}
|
|
|
|
// Verify indicator is visible
|
|
expect(indicator.style.opacity).toEqual('1');
|
|
|
|
// Verify positioning calculations
|
|
expect(parseFloat(indicator.style.left)).toBeCloseTo(expectedIndicatorLeft, 1);
|
|
expect(parseFloat(indicator.style.width)).toBeCloseTo(expectedIndicatorWidth, 1);
|
|
|
|
// Verify visual centering on content (should be perfectly centered)
|
|
expect(Math.abs(indicatorCenter - contentCenter)).toBeLessThan(1);
|
|
|
|
document.body.removeChild(tabsElement);
|
|
});
|
|
|
|
tap.test('tabs indicator should move when tab is clicked', async () => {
|
|
// Create tabs element
|
|
const tabsElement = new deesCatalog.DeesAppuiTabs();
|
|
tabsElement.tabs = [
|
|
{ key: 'Home', iconName: 'lucide:home', action: () => {} },
|
|
{ key: 'Analytics', iconName: 'lucide:barChart', action: () => {} },
|
|
{ key: 'Settings', iconName: 'lucide:settings', action: () => {} },
|
|
];
|
|
|
|
document.body.appendChild(tabsElement);
|
|
await tabsElement.updateComplete;
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
const shadowRoot = tabsElement.shadowRoot;
|
|
const tabs = shadowRoot.querySelectorAll('.tab');
|
|
const indicator = shadowRoot.querySelector('.tabIndicator') as HTMLElement;
|
|
|
|
// Get initial position
|
|
const initialLeft = parseFloat(indicator.style.left);
|
|
|
|
// Click second tab
|
|
(tabs[1] as HTMLElement).click();
|
|
await tabsElement.updateComplete;
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
// Position should have changed
|
|
const newLeft = parseFloat(indicator.style.left);
|
|
expect(newLeft).not.toEqual(initialLeft);
|
|
expect(newLeft).toBeGreaterThan(initialLeft);
|
|
|
|
document.body.removeChild(tabsElement);
|
|
});
|
|
|
|
export default tap.start(); |