UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

195 lines 9.97 kB
import { createComponent, flushUpdates } from '@furystack/shades'; import { describe, expect, it, vi } from 'vitest'; import { Pagination } from './pagination.js'; describe('Pagination', () => { it('should be defined', () => { expect(Pagination).toBeDefined(); expect(typeof Pagination).toBe('function'); }); it('should create a pagination element with required props', () => { const onPageChange = vi.fn(); const el = (createComponent(Pagination, { count: 10, page: 1, onPageChange: onPageChange })); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-pagination'); }); it('should set props correctly', () => { const onPageChange = vi.fn(); const el = (createComponent(Pagination, { count: 10, page: 3, onPageChange: onPageChange, siblingCount: 2, boundaryCount: 1, disabled: true, size: "small", color: "primary" })); const props = el.props; expect(props.count).toBe(10); expect(props.page).toBe(3); expect(props.siblingCount).toBe(2); expect(props.boundaryCount).toBe(1); expect(props.disabled).toBe(true); expect(props.size).toBe('small'); expect(props.color).toBe('primary'); }); it('should render page buttons for small page counts', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); // Should have prev + 5 page buttons + next = 7 buttons const items = pagination.querySelectorAll('.pagination-item'); expect(items.length).toBe(7); // prev + 5 pages + next }); it('should render ellipsis for large page counts', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 20, page: 10, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const ellipses = pagination.querySelectorAll('.pagination-ellipsis'); expect(ellipses.length).toBe(2); }); it('should mark current page as selected', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const selected = pagination.querySelector('[data-selected]'); expect(selected).not.toBeNull(); expect(selected.textContent).toBe('3'); }); it('should set data-disabled on prev button when on first page', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const prevButton = pagination.querySelector('.pagination-item'); expect(prevButton.hasAttribute('data-disabled')).toBe(true); }); it('should set data-disabled on next button when on last page', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 5, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const items = pagination.querySelectorAll('.pagination-item'); const nextButton = items[items.length - 1]; expect(nextButton.hasAttribute('data-disabled')).toBe(true); }); it('should call onPageChange with the correct page when a page button is clicked', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); // Click page 3 (index: prev=0, page1=1, page2=2, page3=3) const items = pagination.querySelectorAll('.pagination-item'); items[3].click(); expect(onPageChange).toHaveBeenCalledWith(3); }); it('should call onPageChange with page-1 when prev button is clicked', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const prevButton = pagination.querySelector('.pagination-item'); prevButton.click(); expect(onPageChange).toHaveBeenCalledWith(2); }); it('should call onPageChange with page+1 when next button is clicked', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const items = pagination.querySelectorAll('.pagination-item'); const nextButton = items[items.length - 1]; nextButton.click(); expect(onPageChange).toHaveBeenCalledWith(4); }); it('should not call onPageChange when clicking the currently selected page', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const selected = pagination.querySelector('[data-selected]'); selected.click(); expect(onPageChange).not.toHaveBeenCalled(); }); it('should set data-size attribute when size is provided', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, size: "small" }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); expect(pagination.getAttribute('data-size')).toBe('small'); }); it('should set data-disabled on host when disabled', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, disabled: true }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); expect(pagination.hasAttribute('data-disabled')).toBe(true); }); it('should set CSS custom properties for palette color', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, color: "primary" }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); expect(pagination.style.getPropertyValue('--pagination-color-main')).toBe('var(--shades-theme-palette-primary-main)'); }); it('should set default CSS custom properties when no color prop', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); expect(pagination.style.getPropertyValue('--pagination-color-main')).toBe('var(--shades-theme-text-primary)'); }); it('should render only left ellipsis when near the end', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 20, page: 19, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const ellipses = pagination.querySelectorAll('.pagination-ellipsis'); expect(ellipses.length).toBe(1); }); it('should render only right ellipsis when near the start', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 20, page: 2, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const ellipses = pagination.querySelectorAll('.pagination-ellipsis'); expect(ellipses.length).toBe(1); }); it('should render all pages without ellipsis for count equal to total display slots', async () => { const onPageChange = vi.fn(); const el = (createComponent("div", null, createComponent(Pagination, { count: 7, page: 4, onPageChange: onPageChange }))); const pagination = el.firstElementChild; pagination.updateComponent(); await flushUpdates(); const ellipses = pagination.querySelectorAll('.pagination-ellipsis'); expect(ellipses.length).toBe(0); const items = pagination.querySelectorAll('.pagination-item'); expect(items.length).toBe(9); // prev + 7 pages + next }); }); //# sourceMappingURL=pagination.spec.js.map