@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
232 lines • 12 kB
JavaScript
import { createInjector } from '@furystack/inject';
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades';
import { usingAsync } from '@furystack/utils';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { PageHeader } from './page-header.js';
describe('PageHeader component', () => {
beforeEach(() => {
document.body.innerHTML = '<div id="root"></div>';
});
afterEach(() => {
document.body.innerHTML = '';
});
describe('rendering', () => {
it('should render the shade-page-header custom element', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Test Title" }),
});
await flushUpdates();
const element = document.querySelector('shade-page-header');
expect(element).not.toBeNull();
expect(element?.tagName.toLowerCase()).toBe('shade-page-header');
});
});
it('should render the title', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Users" }),
});
await flushUpdates();
const title = document.querySelector('[data-testid="page-header-title"]');
expect(title).not.toBeNull();
expect(title?.textContent).toBe('Users');
});
});
it('should render the title as Typography with h4 variant', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Dashboard" }),
});
await flushUpdates();
const title = document.querySelector('[data-testid="page-header-title"]');
expect(title?.getAttribute('is')).toBe('shade-typography-h4');
expect(title?.getAttribute('data-variant')).toBe('h4');
});
});
});
describe('icon', () => {
it('should render icon when provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { icon: "\uD83D\uDC65", title: "Users" }),
});
await flushUpdates();
const icon = document.querySelector('.page-header-icon');
expect(icon).not.toBeNull();
expect(icon?.textContent).toBe('👥');
});
});
it('should not render icon element when not provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Users" }),
});
await flushUpdates();
const icon = document.querySelector('.page-header-icon');
expect(icon).toBeNull();
});
});
it('should include icon in title text', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { icon: "\uD83D\uDCC1", title: "Projects" }),
});
await flushUpdates();
const title = document.querySelector('[data-testid="page-header-title"]');
expect(title?.textContent).toContain('📁');
expect(title?.textContent).toContain('Projects');
});
});
});
describe('description', () => {
it('should render description when provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Users", description: "Manage user accounts." }),
});
await flushUpdates();
const description = document.querySelector('[data-testid="page-header-description"]');
expect(description).not.toBeNull();
expect(description?.textContent).toBe('Manage user accounts.');
});
});
it('should not render description element when not provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Users" }),
});
await flushUpdates();
const description = document.querySelector('[data-testid="page-header-description"]');
expect(description).toBeNull();
});
});
it('should render description as Typography with body1 variant', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Dashboard", description: "Overview of your data." }),
});
await flushUpdates();
const description = document.querySelector('[data-testid="page-header-description"]');
expect(description?.getAttribute('is')).toBe('shade-typography-p');
expect(description?.getAttribute('data-variant')).toBe('body1');
});
});
});
describe('actions', () => {
it('should render actions when provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: (createComponent(PageHeader, { title: "Users", actions: createComponent("button", { type: "button", "data-testid": "action-button" }, "Add User") })),
});
await flushUpdates();
const actionsContainer = document.querySelector('[data-testid="page-header-actions"]');
expect(actionsContainer).not.toBeNull();
const actionButton = document.querySelector('[data-testid="action-button"]');
expect(actionButton).not.toBeNull();
expect(actionButton?.textContent).toBe('Add User');
});
});
it('should not render actions element when not provided', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(PageHeader, { title: "Users" }),
});
await flushUpdates();
const actionsContainer = document.querySelector('[data-testid="page-header-actions"]');
expect(actionsContainer).toBeNull();
});
});
it('should render multiple action elements', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: (createComponent(PageHeader, { title: "Users", actions: createComponent(createComponent, null,
createComponent("button", { type: "button" }, "Export"),
createComponent("button", { type: "button" }, "Add User")) })),
});
await flushUpdates();
const actionsContainer = document.querySelector('[data-testid="page-header-actions"]');
const buttons = actionsContainer?.querySelectorAll('button');
expect(buttons?.length).toBe(2);
});
});
});
describe('combined props', () => {
it('should render all props together', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: (createComponent(PageHeader, { icon: "\uD83D\uDC65", title: "Users", description: "Manage user accounts and their roles.", actions: createComponent("button", { type: "button" }, "Add User") })),
});
await flushUpdates();
const icon = document.querySelector('.page-header-icon');
expect(icon?.textContent).toBe('👥');
const title = document.querySelector('[data-testid="page-header-title"]');
expect(title?.textContent).toContain('Users');
const description = document.querySelector('[data-testid="page-header-description"]');
expect(description?.textContent).toBe('Manage user accounts and their roles.');
const actionsContainer = document.querySelector('[data-testid="page-header-actions"]');
expect(actionsContainer?.querySelector('button')).not.toBeNull();
});
});
it('should work with PageContainer integration', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
const { PageContainer } = await import('./index.js');
initializeShadeRoot({
injector,
rootElement,
jsxElement: (createComponent(PageContainer, { maxWidth: "800px", centered: true },
createComponent(PageHeader, { icon: "\uD83D\uDCCA", title: "Dashboard", description: "Your data overview." }),
createComponent("div", null, "Content area"))),
});
await flushUpdates();
const container = document.querySelector('div[is="shade-page-container"]');
expect(container).not.toBeNull();
const header = document.querySelector('shade-page-header');
expect(header).not.toBeNull();
const title = document.querySelector('[data-testid="page-header-title"]');
expect(title?.textContent).toContain('Dashboard');
});
});
});
});
//# sourceMappingURL=page-header.spec.js.map