From 19b1995ea8514477847f208220a267cedd34457e Mon Sep 17 00:00:00 2001 From: Ola Date: Fri, 21 May 2021 21:23:51 +0200 Subject: [PATCH] update tabs component --- mocks/tabs.json | 33 ++++++++++++ src/atoms/tab/Tab.spec.js | 42 +++++++-------- src/molecules/tabs/Tabs.html | 61 +++++++++++----------- src/molecules/tabs/Tabs.js | 70 ++++++++++++------------- src/molecules/tabs/Tabs.stories.js | 84 ++++++++++++++---------------- src/molecules/tabs/Tabs.vue | 9 ++-- 6 files changed, 162 insertions(+), 137 deletions(-) create mode 100644 mocks/tabs.json diff --git a/mocks/tabs.json b/mocks/tabs.json new file mode 100644 index 000000000..1f96d6ab5 --- /dev/null +++ b/mocks/tabs.json @@ -0,0 +1,33 @@ +[ + { + "name": "Tab 1", + "selected": true, + "paragraph": "Toe in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "button": "Alpaca button" + }, + { + + "name": "Tab 2", + "selected": false, + "paragraph": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "button": "" + }, + { + "name": "Tab 3", + "selected": false, + "paragraph": "Sed do eiusmod tempor incididunt ut labo. Ut enim ad minim veniam, re et dolore magna aliqua. quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "button": "" + }, + { + "name": "Tab 4", + "selected": false, + "paragraph": "Toe in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "button": "" + }, + { + "name": "Tab 5", + "selected": false, + "paragraph": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "button": "" + } +] diff --git a/src/atoms/tab/Tab.spec.js b/src/atoms/tab/Tab.spec.js index 10099065a..82c5bc3e3 100644 --- a/src/atoms/tab/Tab.spec.js +++ b/src/atoms/tab/Tab.spec.js @@ -1,43 +1,41 @@ -import { mount } from '@vue/test-utils' +import { shallowMount } from '@vue/test-utils' import ATab from './Tab.vue' +const factory = () => { + const defaultData = { + slots: { + default: 'Tab default text' + }, + propsData: { + name: 'Tab' + } + } + + return shallowMount(ATab, defaultData) +} + describe('Tab', () => { it('has default structure', () => { - const wrapper = mount(ATab, { - propsData: { - name: 'Tab' - } - }) + const wrapper = factory() expect(wrapper).toBe('DIV') expect(wrapper.attributes().role).toBeDefined() - expect(wrapper.attributes().role).toEqual('tabpanel') + expect(wrapper.attributes().role).toEqual('tab') expect(wrapper.attributes('data-tab')).toBeDefined() }) it('renders slot text when passed', () => { - const wrapper = mount(ATab, { - slots: { - default: 'Tab default text' - }, - propsData: { - name: 'Tab' - } - }) + const wrapper = factory() expect(wrapper.find('div > span').exists()).toBe(true) expect(wrapper.find('div > span').text()).toEqual('Tab default text') }) it('has correct id attribute', () => { - const wrapper = mount(ATab, { - propsData: { - name: 'Sample' - } - }) + const wrapper = factory() - expect(wrapper.props().name).toBe('Sample') + expect(wrapper.props().name).toBe('Tab') expect(wrapper.attributes().id).toBeDefined() - expect(wrapper.attributes().id).toEqual('sample-tab') + expect(wrapper.attributes().id).toEqual('tab-tab') }) }) diff --git a/src/molecules/tabs/Tabs.html b/src/molecules/tabs/Tabs.html index e7ae6f205..2e98a85ae 100644 --- a/src/molecules/tabs/Tabs.html +++ b/src/molecules/tabs/Tabs.html @@ -1,40 +1,37 @@ -
- + + + {{ tab.name }} + + +
- +
diff --git a/src/molecules/tabs/Tabs.js b/src/molecules/tabs/Tabs.js index 26774f7d6..d821ed9e9 100644 --- a/src/molecules/tabs/Tabs.js +++ b/src/molecules/tabs/Tabs.js @@ -1,4 +1,3 @@ -import KeyCodes from '../../utils/key-codes' import getClass from '../../../utils/helpers/get-class.js' export default { @@ -9,17 +8,28 @@ export default { activeFocusedTab: 0, config: { base: { - tabs: [ - 'lg:flex', 'lg:flex-wrap', 'justify-center' + tabs: [], + tabs__tablist: [ + 'flex', 'w-full', 'no-wrap', + 'overflow-x-scroll', + 'border-b-2', 'border-gray-200' ], 'tabs__nav-button': [ - 'text-gray-600', 'py-4', 'px-6', 'block', 'hover:text-blue-500' + 'flex', 'items-center', + 'py-4', 'px-6', + 'text-gray-400', 'hover:text-blue-500', + 'uppercase', 'whitespace-nowrap' ], 'tabs__nav-button--active': [ - 'text-gray-600', 'py-4', 'px-6', 'block', 'hover:text-blue-500', 'text-blue-500', 'border-b-2', 'font-medium', 'border-blue-500' + 'flex', 'items-center', + 'border-b-2', 'border-primary', + 'py-4', 'px-6', + 'font-medium', 'text-primary', 'hover:text-blue-500', 'text-blue-500', + 'uppercase', 'whitespace-nowrap' ], tabs__content: [ - 'py-4' + 'w-full', + 'py-10' ] } } @@ -50,38 +60,28 @@ export default { this.$refs[el][0].focus() }, onKeydown (e) { - const key = e.keyCode + const key = e.key + const tabsCount = this.tabs.length - if (key === KeyCodes.TAB) { + if (key === 'ArrowRight' || key === 'ArrowDown') { e.preventDefault() - e.stopPropagation() - this.$refs.content.focus() - } else if ( - (key === KeyCodes.LEFT || - key === KeyCodes.UP || - key === KeyCodes.HOME) && - this.activeFocusedTab > 0 - ) { - if (key === KeyCodes.HOME) { - this.focus('button_0') - } else { - this.activeFocusedTab = this.activeFocusedTab - 1 - this.focus(`button_${this.activeFocusedTab}`) - } - } else if ( - (key === KeyCodes.RIGHT || - key === KeyCodes.DOWN || - key === KeyCodes.END) && - this.activeFocusedTab < this.tabs.length - 1 - ) { - if (key === KeyCodes.END) { - this.focus(`button_${this.tabs.length - 1}`) - } else { - this.activeFocusedTab = this.activeFocusedTab + 1 - this.focus(`button_${this.activeFocusedTab}`) - } + this.activeFocusedTab = (this.activeFocusedTab + 1) % tabsCount + this.selectTab(this.activeFocusedTab) + this.focus(`button_${this.activeFocusedTab}`) + } else if (key === 'ArrowLeft' || key === 'ArrowUp') { + e.preventDefault() + this.activeFocusedTab = (this.activeFocusedTab - 1 + tabsCount) % tabsCount + this.selectTab(this.activeFocusedTab) + this.focus(`button_${this.activeFocusedTab}`) + } else if (key === 'Home') { + e.preventDefault() + this.activeFocusedTab = 0 + } else if (key === 'End') { + e.preventDefault() + this.activeFocusedTab = tabsCount - 1 + this.selectTab(this.activeFocusedTab) + this.focus(`button_${this.activeFocusedTab}`) } - this.selectTab(this.activeFocusedTab) } } } diff --git a/src/molecules/tabs/Tabs.stories.js b/src/molecules/tabs/Tabs.stories.js index 54733461d..8d4567bdb 100644 --- a/src/molecules/tabs/Tabs.stories.js +++ b/src/molecules/tabs/Tabs.stories.js @@ -5,6 +5,8 @@ import AParagraph from '@atoms/paragraph/Paragraph.vue' import AIcon from '@atoms/icon/Icon.vue' import AIconStarBorder from '@atoms/icon/templates/IconStarBorder.vue' +import tabs from '@mocks/tabs.json' + export default { title: 'Molecules/Tabs', component: ATabs, @@ -20,31 +22,26 @@ const Template = (args, { argTypes }) => ({ ATabs, ATab, AButton, - AParagraph, - AIcon, - AIconStarBorder + AParagraph }, props: Object.keys(argTypes), + data () { + return { + tabs + } + }, template: ` - - - Toe in voluptate velit esse cillum dolore eu fugiat nulla pariatur. - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. - - - - - Sed do eiusmod tempor incididunt ut labo. Ut enim ad minim veniam, re et dolore magna aliqua. quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. - - + ` }) @@ -61,38 +58,35 @@ export const WithSlots = (args, { argTypes }) => ({ AIconStarBorder }, props: Object.keys(argTypes), + data () { + return { + tabs + } + }, template: `