diff --git a/components/src/assets/styles/variables.styl b/components/src/assets/styles/variables.styl index 9729f46e..9c689b39 100644 --- a/components/src/assets/styles/variables.styl +++ b/components/src/assets/styles/variables.styl @@ -1 +1,2 @@ -border-color = #e0e0e0; \ No newline at end of file +border-color = #e0e0e0; +base-text-color = #212121; \ No newline at end of file diff --git a/components/src/index.js b/components/src/index.js index b3f0b0e2..fa868baf 100644 --- a/components/src/index.js +++ b/components/src/index.js @@ -14,6 +14,7 @@ export { default as Textfield } from '~widgets/textfield/widget.vue'; export { default as Table } from '~widgets/table/widget.vue'; export { default as ComplexTable } from './widgets/complexTable/widget.vue'; export { default as Button } from '~widgets/button/widget.vue'; +export { default as Menu } from '~widgets/menu/widget.vue'; export { default as store } from '~core/store'; export { default as bus } from '~core/eventBus'; diff --git a/components/src/stories/Menu.stories.js b/components/src/stories/Menu.stories.js new file mode 100644 index 00000000..738baa8f --- /dev/null +++ b/components/src/stories/Menu.stories.js @@ -0,0 +1,31 @@ +import Menu from '~widgets/menu/widget.vue'; +import Button from '~widgets/button/widget.vue'; +import registerWidget from '~core/registerWidget'; + +registerWidget('ui-menu', Menu); +registerWidget('ui-button', Button); + +export const Component = { + render: (args) => ({ + setup() { + return {args}; + }, + template: ` + +
+

item

+
+
` + }), +}; + +export default { + title: 'Components/Menu', + component: Menu, + parameters: { + layout: 'centered', + }, +}; \ No newline at end of file diff --git a/components/src/widgets/menu/widget.spec.js b/components/src/widgets/menu/widget.spec.js new file mode 100644 index 00000000..90f631d2 --- /dev/null +++ b/components/src/widgets/menu/widget.spec.js @@ -0,0 +1,72 @@ +import { mount } from '@vue/test-utils' +import Menu from './widget'; + +describe('Menu component', () => { + describe('methods', () => { + describe('#toggle', () => { + it('toggles menu to true when clicking', () => { + const wrapper = mount(Menu); + wrapper.vm.showMenu = false; + wrapper.vm.toggle(wrapper.vm.showMenu); + + expect(wrapper.vm.showMenu).toBe(true); + }); + + it('toggles menu back to false when clicking', () => { + const wrapper = mount(Menu); + wrapper.vm.showMenu = true; + wrapper.vm.toggle(wrapper.vm.showMenu); + + expect(wrapper.vm.showMenu).toBe(false); + }); + }); + + describe('#handleClickOutside', () => { + + it('hides menu content when clicked outside menu', () => { + const event = { target: 'another value'}; + const wrapper = mount(Menu); + wrapper.vm.menu = { contains: jest.fn().mockReturnValue(false) }; + wrapper.vm.showMenu = true; + wrapper.vm.handleClickOutside(event); + + expect(wrapper.vm.showMenu).toBe(false); + }); + + it('does not hide menu content when clicked inside menu', () => { + const event = { target: 'some value'}; + const wrapper = mount(Menu); + wrapper.vm.menu = { contains: jest.fn().mockReturnValue(true) }; + wrapper.vm.showMenu = true; + wrapper.vm.handleClickOutside(event); + + expect(wrapper.vm.showMenu).toBe(true); + }); + }); + }); + + describe('onMounted', () => { + it('adds up event listener on component mount', () => { + const addEventListenerSpy = jest.spyOn(document, 'addEventListener'); + + mount(Menu); + + expect(addEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function)); + + addEventListenerSpy.mockRestore(); + }); + }); + + describe('onUnmounted', () => { + it('cleans up event listener on component unmount', async () => { + const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener'); + + const wrapper = mount(Menu); + await wrapper.unmount(); + + expect(removeEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function)); + + removeEventListenerSpy.mockRestore(); + }); + }) +}); diff --git a/components/src/widgets/menu/widget.vue b/components/src/widgets/menu/widget.vue new file mode 100644 index 00000000..0b17ca21 --- /dev/null +++ b/components/src/widgets/menu/widget.vue @@ -0,0 +1,61 @@ + + + + + \ No newline at end of file diff --git a/components/src/widgets/textfield/widget.vue b/components/src/widgets/textfield/widget.vue index 0414c7cd..15245af4 100644 --- a/components/src/widgets/textfield/widget.vue +++ b/components/src/widgets/textfield/widget.vue @@ -61,6 +61,8 @@ export default {