UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

217 lines 10.7 kB
import { createComponent, flushUpdates } from '@furystack/shades'; import { describe, expect, it } from 'vitest'; import { Timeline, TimelineItem } from './timeline.js'; describe('TimelineItem', () => { it('should be defined', () => { expect(TimelineItem).toBeDefined(); expect(typeof TimelineItem).toBe('function'); }); it('should create a timeline item element', () => { const el = (createComponent(TimelineItem, null)); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-timeline-item'); }); it('should pass children as content', () => { const el = (createComponent(TimelineItem, null, "Event happened")); expect(el).toBeDefined(); }); it('should set props correctly', () => { const el = (createComponent(TimelineItem, { color: "success", label: "2024-01-01" })); expect(el.props.color).toBe('success'); expect(el.props.label).toBe('2024-01-01'); }); it('should render dot and content', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, null, createComponent("span", null, "Event content")))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); expect(item.querySelector('.timeline-dot')).not.toBeNull(); expect(item.querySelector('.timeline-content')).not.toBeNull(); expect(item.querySelector('.timeline-tail')).not.toBeNull(); }); it('should render a label when provided', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, { label: "Jan 2024" }, "Event"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); const label = item.querySelector('.timeline-label'); expect(label).not.toBeNull(); expect(label.textContent).toBe('Jan 2024'); }); it('should set custom dot when dot prop is provided', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, { dot: createComponent("span", null, "\uD83C\uDF89") }, "Party!"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); const dot = item.querySelector('.timeline-dot'); expect(dot.hasAttribute('data-custom')).toBe(true); }); it('should not set data-custom when dot prop is not provided', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, null, "Event"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); const dot = item.querySelector('.timeline-dot'); expect(dot.hasAttribute('data-custom')).toBe(false); }); it('should set CSS custom property for dot color', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, { color: "success" }, "Done"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); expect(item.style.getPropertyValue('--timeline-dot-color')).toBe('var(--shades-theme-palette-success-main)'); }); it('should default to primary color', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, null, "Event"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); expect(item.style.getPropertyValue('--timeline-dot-color')).toBe('var(--shades-theme-palette-primary-main)'); }); it('should render dashed tail when data-pending attribute is set', async () => { const el = (createComponent("div", null, createComponent(TimelineItem, { "data-pending": "" }, "Event"))); const item = el.firstElementChild; item.updateComponent(); await flushUpdates(); const tail = item.querySelector('.timeline-tail'); expect(tail.hasAttribute('data-pending')).toBe(true); }); }); describe('Timeline', () => { it('should be defined', () => { expect(Timeline).toBeDefined(); expect(typeof Timeline).toBe('function'); }); it('should create a timeline element', () => { const el = (createComponent(Timeline, null)); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-timeline'); }); it('should set props correctly', () => { const el = (createComponent(Timeline, { mode: "alternate", pending: true })); expect(el.props.mode).toBe('alternate'); expect(el.props.pending).toBe(true); }); it('should render timeline items as children', async () => { const el = (createComponent("div", null, createComponent(Timeline, null, createComponent(TimelineItem, null, "First"), createComponent(TimelineItem, null, "Second")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); const items = timeline.querySelectorAll('shade-timeline-item'); expect(items.length).toBe(2); }); it('should set data-mode attribute', async () => { const el = (createComponent("div", null, createComponent(Timeline, { mode: "alternate" }, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.getAttribute('data-mode')).toBe('alternate'); }); it('should default mode to left', async () => { const el = (createComponent("div", null, createComponent(Timeline, null, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.getAttribute('data-mode')).toBe('left'); }); it('should add pending item when pending is true', async () => { const el = (createComponent("div", null, createComponent(Timeline, { pending: true }, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); const items = timeline.querySelectorAll('shade-timeline-item'); expect(items.length).toBe(2); }); describe('orientation', () => { it('should not set data-orientation when orientation is not specified (defaults to vertical)', async () => { const el = (createComponent("div", null, createComponent(Timeline, null, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.hasAttribute('data-orientation')).toBe(false); }); it('should not set data-orientation when orientation is "vertical"', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "vertical" }, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.hasAttribute('data-orientation')).toBe(false); }); it('should set data-orientation="horizontal" when orientation is "horizontal"', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "horizontal" }, createComponent(TimelineItem, null, "Event")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.getAttribute('data-orientation')).toBe('horizontal'); }); it('should render children in horizontal mode', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "horizontal" }, createComponent(TimelineItem, null, "First"), createComponent(TimelineItem, null, "Second"), createComponent(TimelineItem, null, "Third")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); const items = timeline.querySelectorAll('shade-timeline-item'); expect(items.length).toBe(3); }); it('should support horizontal with mode="alternate"', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "horizontal", mode: "alternate" }, createComponent(TimelineItem, null, "First"), createComponent(TimelineItem, null, "Second")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.getAttribute('data-orientation')).toBe('horizontal'); expect(timeline.getAttribute('data-mode')).toBe('alternate'); }); it('should support horizontal with mode="right"', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "horizontal", mode: "right" }, createComponent(TimelineItem, null, "First")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); expect(timeline.getAttribute('data-orientation')).toBe('horizontal'); expect(timeline.getAttribute('data-mode')).toBe('right'); }); it('should add pending item in horizontal mode', async () => { const el = (createComponent("div", null, createComponent(Timeline, { orientation: "horizontal", pending: "Loading..." }, createComponent(TimelineItem, null, "Step 1"), createComponent(TimelineItem, null, "Step 2")))); const timeline = el.firstElementChild; timeline.updateComponent(); await flushUpdates(); const items = timeline.querySelectorAll('shade-timeline-item'); expect(items.length).toBe(3); expect(timeline.getAttribute('data-orientation')).toBe('horizontal'); }); }); }); //# sourceMappingURL=timeline.spec.js.map