@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
134 lines • 6.54 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 { AppBar } from './app-bar.js';
describe('AppBar component', () => {
beforeEach(() => {
document.body.innerHTML = '<div id="root"></div>';
});
afterEach(() => {
document.body.innerHTML = '';
});
const renderAppBar = async (children) => {
const injector = createInjector();
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: createComponent(AppBar, null, children),
});
await flushUpdates();
await new Promise((resolve) => requestAnimationFrame(resolve));
await flushUpdates();
return {
injector,
appBar: document.querySelector('shade-app-bar'),
[Symbol.asyncDispose]: () => injector[Symbol.asyncDispose](),
};
};
describe('rendering', () => {
it('should render the shade-app-bar custom element', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
expect(appBar).not.toBeNull();
expect(appBar.tagName.toLowerCase()).toBe('shade-app-bar');
});
});
it('should render children in custom element', async () => {
await usingAsync(await renderAppBar(createComponent("span", { id: "child-content" }, "Test Content")), async ({ appBar }) => {
// Children are rendered inside the custom element
expect(appBar).not.toBeNull();
});
});
it('should render multiple children', async () => {
await usingAsync(createInjector(), async (injector) => {
const rootElement = document.getElementById('root');
initializeShadeRoot({
injector,
rootElement,
jsxElement: (createComponent(AppBar, null,
createComponent("span", { id: "logo" }, "Logo"),
createComponent("nav", { id: "navigation" }, "Nav"),
createComponent("button", { id: "action" }, "Action"))),
});
await flushUpdates();
const appBar = document.querySelector('shade-app-bar');
expect(appBar).not.toBeNull();
});
});
});
describe('positioning', () => {
it('should have fixed positioning', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.position).toBe('fixed');
});
});
it('should have z-index of 1', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.zIndex).toBe('1');
});
});
it('should have full width', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.width).toBe('100%');
});
});
});
describe('fade-in animation', () => {
it('should add visible class after construction', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
expect(appBar.hasAttribute('data-visible')).toBe(true);
});
});
it('should have opacity 1 when visible class is applied', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.opacity).toBe('1');
});
});
it('should have transition styles for animation', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.transition).toContain('opacity');
});
});
});
describe('layout', () => {
it('should have flex display', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.display).toBe('flex');
});
});
it('should align items center', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.alignItems).toBe('center');
});
});
it('should justify content to flex-start', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.justifyContent).toBe('flex-start');
});
});
});
describe('styling', () => {
it('should have box shadow', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async ({ appBar }) => {
const computedStyle = window.getComputedStyle(appBar);
expect(computedStyle.boxShadow).not.toBe('none');
});
});
it('should have semi-transparent background', async () => {
await usingAsync(await renderAppBar(createComponent("span", null, "Content")), async () => {
const styleEl = document.querySelector('style[data-shades-styles]');
expect(styleEl?.textContent).toContain('color-mix');
});
});
});
});
//# sourceMappingURL=app-bar.spec.js.map