jiro-ui
Version:
A Mithril.js UI library based from construct-ui
165 lines (127 loc) • 3.56 kB
text/typescript
import m from 'mithril';
import assert from 'assert';
import { Overlay, IOverlayAttrs, Classes, Input, Keys } from '@/';
import { hasClass, TIMEOUT, triggerEvent, timeoutRedraw } from '@test-utils';
describe('overlay', () => {
const portal = () => document.body.querySelector(`.${Classes.PORTAL}`) as HTMLElement;
const overlay = () => document.body.querySelector(`.${Classes.OVERLAY}`) as HTMLElement;
const backdrop = () => overlay().querySelector(`.${Classes.OVERLAY_BACKDROP}`) as HTMLElement;
afterEach(() => {
document.body.innerHTML = '';
m.mount(document.body, null);
});
it('Renders correctly', () => {
mount({
class: Classes.POSITIVE,
style: 'color: red'
});
assert(hasClass(overlay(), Classes.POSITIVE));
assert.equal(overlay().style.color, 'red');
});
it('Renders portal correctly', () => {
mount({});
assert(hasClass(portal(), Classes.PORTAL));
});
it('Passes through attrs to portal', () => {
mount({
portalAttrs: {
class: Classes.POSITIVE,
style: 'color: red'
}
});
assert(hasClass(portal(), Classes.POSITIVE));
assert.equal(portal().style.color, 'red');
});
it('Renders content', () => {
mount({ content: 'content' });
assert(overlay().innerHTML.includes('content'));
});
it('Renders inline', () => {
mount({ inline: true });
assert(!portal());
});
it('Has backdrop by default', () => {
mount({});
assert(backdrop());
});
it('Sets backdrop class', () => {
mount({
backdropClass: Classes.POSITIVE
});
assert(hasClass(backdrop(), Classes.POSITIVE));
});
it('hasBackdrop=false hides backdrop', () => {
mount({ hasBackdrop: false });
assert(!backdrop());
});
it('Sets autofocus', () => {
mount({
content: m(Input, { autofocus: true })
});
const input = overlay().querySelector('input') as HTMLInputElement;
assert(input.autofocus);
});
it('closeOnOutsideClick=true invokes onClose', (done) => {
let count = 0;
mount({
closeOnOutsideClick: true,
onClose: () => count++
});
triggerEvent(backdrop(), 'mousedown', () => {
assert.equal(count, 1);
done();
});
});
it('Handles closeOnEscapeKey', () => {
let count = 0;
mount({
onClose: () => count++,
closeOnEscapeKey: true
});
document.dispatchEvent(new KeyboardEvent('keydown', { which: Keys.ESCAPE } as any));
assert.equal(count, 1);
});
it('Handles lifecycle callbacks', done => {
let count = 0;
const component = mount({
onOpened: () => count++,
onClosed: () => count++
});
timeoutRedraw(
() => component.isOpen = false,
() => {
assert.equal(count, 2);
done();
}
);
});
it('onClosed called when transitionDuration finishes', done => {
let count = 0;
const transitionDuration = 50;
const component = mount({
onClosed: () => count++,
transitionDuration
});
setTimeout(() => {
component.isOpen = false;
m.redraw();
setTimeout(() => {
assert.equal(count, 1);
done();
}, transitionDuration);
}, TIMEOUT);
});
function mount(attrs: IOverlayAttrs) {
const component = {
isOpen: true,
view: (vnode: any) => m(Overlay, {
addToStack: false,
isOpen: vnode.state.isOpen,
transitionDuration: 0,
...attrs
})
};
m.mount(document.body, component);
return component;
}
});