@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
200 lines • 9.14 kB
JavaScript
import { createComponent, flushUpdates } from '@furystack/shades';
import { describe, expect, it, vi } from 'vitest';
import { Chip } from './chip.js';
describe('Chip', () => {
it('should be defined', () => {
expect(Chip).toBeDefined();
expect(typeof Chip).toBe('function');
});
it('should create a chip element with default props', () => {
const el = (createComponent(Chip, null));
expect(el).toBeDefined();
expect(el.tagName?.toLowerCase()).toBe('shade-chip');
});
it('should pass children as chip content', () => {
const el = (createComponent(Chip, null, "Test Label"));
expect(el).toBeDefined();
});
it('should set props correctly', () => {
const el = (createComponent(Chip, { color: "primary", variant: "outlined", size: "small", disabled: true }));
expect(el.props.color).toBe('primary');
expect(el.props.variant).toBe('outlined');
expect(el.props.size).toBe('small');
expect(el.props.disabled).toBe(true);
});
it('should render with a label span', async () => {
const el = (createComponent("div", null,
createComponent(Chip, null, "Default")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.querySelector('.chip-label')).toBeDefined();
});
it('should render with a delete button when onDelete is provided', async () => {
const onDelete = vi.fn();
const el = (createComponent("div", null,
createComponent(Chip, { onDelete: onDelete }, "Deletable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
const deleteBtn = chip.querySelector('.chip-delete');
expect(deleteBtn).toBeDefined();
expect(deleteBtn).not.toBeNull();
});
it('should not render a delete button when onDelete is not provided', async () => {
const el = (createComponent("div", null,
createComponent(Chip, null, "No Delete")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
const deleteBtn = chip.querySelector('.chip-delete');
expect(deleteBtn).toBeNull();
});
it('should set data-variant attribute when variant is provided', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { variant: "outlined" }, "Outlined")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('data-variant')).toBe('outlined');
});
it('should set data-size attribute when size is small', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { size: "small" }, "Small")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('data-size')).toBe('small');
});
it('should set data-size attribute when size is large', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { size: "large" }, "Large")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('data-size')).toBe('large');
});
it('should not set data-size when size is medium (default)', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { size: "medium" }, "Medium")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('data-size')).toBeNull();
});
it('should set data-disabled attribute when disabled', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { disabled: true }, "Disabled")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('data-disabled')).toBe(true);
});
it('should not set data-disabled attribute when not disabled', async () => {
const el = (createComponent("div", null,
createComponent(Chip, null, "Enabled")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('data-disabled')).toBe(false);
});
it('should set data-clickable when clickable prop is true', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { clickable: true }, "Clickable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('data-clickable')).toBe(true);
});
it('should set data-clickable when onclick handler is provided', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { onclick: () => { } }, "Click Handler")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('data-clickable')).toBe(true);
});
it('should be focusable when clickable', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { clickable: true }, "Clickable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('tabindex')).toBe('0');
});
it('should be focusable when onclick handler is provided', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { onclick: () => { } }, "Click Handler")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.getAttribute('tabindex')).toBe('0');
});
it('should not be focusable when clickable but disabled', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { clickable: true, disabled: true }, "Disabled Clickable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('tabindex')).toBe(false);
});
it('should not be focusable when not clickable', async () => {
const el = (createComponent("div", null,
createComponent(Chip, null, "Not Clickable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.hasAttribute('tabindex')).toBe(false);
});
it('should have a focusable delete button', async () => {
const onDelete = vi.fn();
const el = (createComponent("div", null,
createComponent(Chip, { onDelete: onDelete }, "Deletable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
const deleteBtn = chip.querySelector('.chip-delete');
expect(deleteBtn.getAttribute('tabindex')).toBe('0');
});
it('should set CSS custom properties for palette color', async () => {
const el = (createComponent("div", null,
createComponent(Chip, { color: "primary" }, "Primary")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.style.getPropertyValue('--chip-color-main')).toBe('var(--shades-theme-palette-primary-main)');
});
it('should set CSS custom properties for default color when no color prop', async () => {
const el = (createComponent("div", null,
createComponent(Chip, null, "Default")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
expect(chip.style.getPropertyValue('--chip-color-main')).toBe('var(--shades-theme-text-secondary)');
});
it('should call onDelete when delete button is clicked', async () => {
const onDelete = vi.fn();
const el = (createComponent("div", null,
createComponent(Chip, { onDelete: onDelete }, "Deletable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
const deleteBtn = chip.querySelector('.chip-delete');
deleteBtn.click();
expect(onDelete).toHaveBeenCalledOnce();
});
it('should stop propagation when delete button is clicked', async () => {
const onDelete = vi.fn();
const onChipClick = vi.fn();
const el = (createComponent("div", null,
createComponent(Chip, { onDelete: onDelete, onclick: onChipClick }, "Deletable")));
const chip = el.firstElementChild;
chip.updateComponent();
await flushUpdates();
const deleteBtn = chip.querySelector('.chip-delete');
deleteBtn.click();
expect(onDelete).toHaveBeenCalledOnce();
expect(onChipClick).not.toHaveBeenCalled();
});
});
//# sourceMappingURL=chip.spec.js.map