Implement custom lightweight modal #230
Introduce a brand new lightweight and efficient modal component. It is designed to be visually similar to the previous one to not introduce a change in feel of the application in a patch release, but behind the scenes it features: - Enhanced application speed and reduced bundle size. - New flexbox-driven layout, eliminating JS calculations. - Composition API ready for Vue 3.0 #230. Other changes: - Adopt idiomatic Vue via `v-modal` binding. - Add unit tests for both the modal and dialog. - Remove `vue-js-modal` dependency in favor of the new implementation. - Adjust modal shadow color to better match theme. - Add `@vue/test-utils` for unit testing.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import 'mocha';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { expect } from 'chai';
|
||||
import { ref, nextTick, defineComponent } from 'vue';
|
||||
import { useLockBodyBackgroundScroll } from '@/presentation/components/Shared/Modal/Hooks/UseLockBodyBackgroundScroll';
|
||||
|
||||
describe('useLockBodyBackgroundScroll', () => {
|
||||
afterEach(() => {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.width = '';
|
||||
});
|
||||
|
||||
describe('initialization', () => {
|
||||
it('blocks scroll if initially active', async () => {
|
||||
// arrange
|
||||
createComponent(true);
|
||||
|
||||
// act
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).to.equal('hidden');
|
||||
expect(document.body.style.width).to.equal('100vw');
|
||||
});
|
||||
|
||||
it('preserves initial styles if inactive', async () => {
|
||||
// arrange
|
||||
const originalOverflow = 'scroll';
|
||||
const originalWidth = '90vw';
|
||||
document.body.style.overflow = originalOverflow;
|
||||
document.body.style.width = originalWidth;
|
||||
|
||||
// act
|
||||
createComponent(false);
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).to.equal(originalOverflow);
|
||||
expect(document.body.style.width).to.equal(originalWidth);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggling', () => {
|
||||
it('blocks scroll when activated', async () => {
|
||||
// arrange
|
||||
const { isActive } = createComponent(false);
|
||||
|
||||
// act
|
||||
isActive.value = true;
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).to.equal('hidden');
|
||||
expect(document.body.style.width).to.equal('100vw');
|
||||
});
|
||||
|
||||
it('unblocks scroll when deactivated', async () => {
|
||||
// arrange
|
||||
const { isActive } = createComponent(true);
|
||||
|
||||
// act
|
||||
isActive.value = false;
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).not.to.equal('hidden');
|
||||
expect(document.body.style.width).not.to.equal('100vw');
|
||||
});
|
||||
});
|
||||
|
||||
describe('unmounting', () => {
|
||||
it('restores original styles on unmount', async () => {
|
||||
// arrange
|
||||
const originalOverflow = 'scroll';
|
||||
const originalWidth = '90vw';
|
||||
document.body.style.overflow = originalOverflow;
|
||||
document.body.style.width = originalWidth;
|
||||
|
||||
// act
|
||||
const { component } = createComponent(true);
|
||||
component.destroy();
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).to.equal(originalOverflow);
|
||||
expect(document.body.style.width).to.equal(originalWidth);
|
||||
});
|
||||
|
||||
it('resets styles on unmount', async () => {
|
||||
// arrange
|
||||
const { component } = createComponent(true);
|
||||
|
||||
// act
|
||||
component.destroy();
|
||||
await nextTick();
|
||||
|
||||
// assert
|
||||
expect(document.body.style.overflow).to.equal('');
|
||||
expect(document.body.style.width).to.equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createComponent(initialIsActiveValue: boolean) {
|
||||
const isActive = ref(initialIsActiveValue);
|
||||
const component = shallowMount(defineComponent({
|
||||
setup() {
|
||||
useLockBodyBackgroundScroll(isActive);
|
||||
},
|
||||
template: '<div></div>',
|
||||
}));
|
||||
return { component, isActive };
|
||||
}
|
||||
Reference in New Issue
Block a user