@volverjs/ui-vue 0.0.6-beta.2 → 0.0.6-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/components/VvAvatarGroup/VvAvatarGroup.es.js +4 -2
- package/dist/components/VvAvatarGroup/VvAvatarGroup.umd.js +1 -1
- package/dist/components/VvNav/VvNav.es.js +450 -0
- package/dist/components/VvNav/VvNav.umd.js +1 -0
- package/dist/components/VvNav/VvNav.vue.d.ts +47 -0
- package/dist/components/VvNav/index.d.ts +32 -0
- package/dist/components/VvNavItemTitle/VvNavItemTitle.es.js +19 -0
- package/dist/components/VvNavItemTitle/VvNavItemTitle.umd.js +1 -0
- package/dist/components/VvNavItemTitle/VvNavItemTitle.vue.d.ts +6 -0
- package/dist/components/VvNavSeparator/VvNavSeparator.d.ts +2 -0
- package/dist/components/VvTab/VvTab.es.js +505 -0
- package/dist/components/VvTab/VvTab.umd.js +1 -0
- package/dist/components/VvTab/VvTab.vue.d.ts +52 -0
- package/dist/components/VvTab/index.d.ts +23 -0
- package/dist/icons.es.js +3 -3
- package/dist/icons.umd.js +1 -1
- package/dist/stories/Nav/Nav.settings.d.ts +33 -0
- package/dist/stories/Nav/Nav.test.d.ts +2 -0
- package/dist/stories/Tab/Tab.settings.d.ts +37 -0
- package/dist/stories/Tab/Tab.test.d.ts +2 -0
- package/package.json +25 -1
- package/src/assets/icons/detailed.json +1 -1
- package/src/assets/icons/normal.json +1 -1
- package/src/assets/icons/simple.json +1 -1
- package/src/components/VvAvatarGroup/VvAvatarGroup.vue +2 -2
- package/src/components/VvNav/VvNav.vue +66 -0
- package/src/components/VvNav/index.ts +21 -0
- package/src/components/VvNavItemTitle/VvNavItemTitle.vue +11 -0
- package/src/components/VvNavSeparator/VvNavSeparator.ts +8 -0
- package/src/components/VvTab/VvTab.vue +53 -0
- package/src/components/VvTab/index.ts +13 -0
- package/src/stories/Nav/Nav.settings.ts +34 -0
- package/src/stories/Nav/Nav.stories.mdx +28 -0
- package/src/stories/Nav/Nav.test.ts +32 -0
- package/src/stories/Nav/NavModifiers.stories.mdx +48 -0
- package/src/stories/Tab/Tab.settings.ts +41 -0
- package/src/stories/Tab/Tab.stories.mdx +65 -0
- package/src/stories/Tab/Tab.test.ts +37 -0
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
const avatarItems = computed(() => {
|
|
20
|
-
return items.value.slice(0, toShow.value).map((item
|
|
20
|
+
return items.value.slice(0, toShow.value).map((item) => {
|
|
21
21
|
let modifiers: string[] = []
|
|
22
22
|
let itemModifiers: string[] = []
|
|
23
23
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
return {
|
|
37
37
|
...item,
|
|
38
|
-
key: item.key ||
|
|
38
|
+
key: item.key || useUniqueId().value,
|
|
39
39
|
modifiers: [...modifiers, ...itemModifiers],
|
|
40
40
|
}
|
|
41
41
|
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { VvNavProps, VvNavEvents, type NavItem } from '@/components/VvNav'
|
|
3
|
+
import VvAction from '@/components/VvAction/VvAction.vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps(VvNavProps)
|
|
6
|
+
const emit = defineEmits(VvNavEvents)
|
|
7
|
+
const { modifiers, items } = toRefs(props)
|
|
8
|
+
const activeItem: Ref<string | null> = ref(null)
|
|
9
|
+
|
|
10
|
+
// bem css classes
|
|
11
|
+
const bemCssClasses = useModifiers('vv-nav', modifiers)
|
|
12
|
+
|
|
13
|
+
const localItems = computed(() => {
|
|
14
|
+
return items.value.map((item, index) => {
|
|
15
|
+
return {
|
|
16
|
+
...item,
|
|
17
|
+
id: item.id || `nav-item_${index}`,
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Triggers when the item is clicked.
|
|
24
|
+
* @private
|
|
25
|
+
* @event click
|
|
26
|
+
* @param [NavItem, string] item - the clicked item
|
|
27
|
+
*/
|
|
28
|
+
function onClick(item: NavItem) {
|
|
29
|
+
if (!item.disabled) {
|
|
30
|
+
emit('click', item)
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
32
|
+
activeItem.value = item.id!
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<nav :class="bemCssClasses">
|
|
39
|
+
<ul class="vv-nav__menu" role="menu" aria-busy="true">
|
|
40
|
+
<li
|
|
41
|
+
v-for="navItem in localItems"
|
|
42
|
+
:key="navItem.id"
|
|
43
|
+
class="vv-nav__item"
|
|
44
|
+
role="presentation"
|
|
45
|
+
>
|
|
46
|
+
<VvAction
|
|
47
|
+
v-bind="{
|
|
48
|
+
disabled: navItem.disabled,
|
|
49
|
+
to: navItem.to,
|
|
50
|
+
href: navItem.href,
|
|
51
|
+
tabindex: 0,
|
|
52
|
+
}"
|
|
53
|
+
:class="{
|
|
54
|
+
current: activeItem == navItem.id,
|
|
55
|
+
disabled: navItem.disabled,
|
|
56
|
+
}"
|
|
57
|
+
class="vv-nav__item-label"
|
|
58
|
+
v-on="navItem.on || {}"
|
|
59
|
+
@click="onClick(navItem)"
|
|
60
|
+
>
|
|
61
|
+
{{ navItem.title }}
|
|
62
|
+
</VvAction>
|
|
63
|
+
</li>
|
|
64
|
+
</ul>
|
|
65
|
+
</nav>
|
|
66
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ModifiersProps } from '@/props'
|
|
2
|
+
|
|
3
|
+
export type NavItem = {
|
|
4
|
+
id?: string
|
|
5
|
+
title: string
|
|
6
|
+
to?: string | { [key: string]: unknown }
|
|
7
|
+
href?: string
|
|
8
|
+
disabled?: boolean
|
|
9
|
+
on: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const VvNavProps = {
|
|
13
|
+
...ModifiersProps,
|
|
14
|
+
items: {
|
|
15
|
+
type: Array<NavItem>,
|
|
16
|
+
required: true,
|
|
17
|
+
default: () => [],
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const VvNavEvents = ['click']
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { VvTabProps, VvTabEvents } from '@/components/VvTab'
|
|
3
|
+
import type { NavItem } from '@/components/VvNav'
|
|
4
|
+
import VvNav from '@/components/VvNav/VvNav.vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps(VvTabProps)
|
|
7
|
+
const emit = defineEmits(VvTabEvents)
|
|
8
|
+
const { modifiers, items } = toRefs(props)
|
|
9
|
+
const activeTab: Ref<string | null> = ref(null)
|
|
10
|
+
|
|
11
|
+
// bem css classes
|
|
12
|
+
const bemCssClasses = useModifiers('vv-tab', modifiers)
|
|
13
|
+
|
|
14
|
+
const localItems = computed(() => {
|
|
15
|
+
return items.value.map((item, index) => {
|
|
16
|
+
return {
|
|
17
|
+
...item,
|
|
18
|
+
id: item.id || `tab-item_${index}`,
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Triggers when the item is clicked.
|
|
25
|
+
* @private
|
|
26
|
+
* @event click
|
|
27
|
+
* @param [NavItem, string] item - the clicked item
|
|
28
|
+
*/
|
|
29
|
+
function onClick(item: NavItem) {
|
|
30
|
+
if (!item.disabled) {
|
|
31
|
+
emit('click', item)
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
33
|
+
activeTab.value = item.id!
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div :class="bemCssClasses">
|
|
40
|
+
<VvNav :items="localItems" modifiers="tabs full" @click="onClick" />
|
|
41
|
+
<!-- #region tab content -->
|
|
42
|
+
<article
|
|
43
|
+
v-for="item in localItems"
|
|
44
|
+
:id="item.id"
|
|
45
|
+
:key="item.id"
|
|
46
|
+
:class="{ target: activeTab === item.id }"
|
|
47
|
+
class="vv-tab__panel"
|
|
48
|
+
>
|
|
49
|
+
<slot :name="`${item.id}`" />
|
|
50
|
+
</article>
|
|
51
|
+
<!-- #endregion tab content -->
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ModifiersProps } from '@/props'
|
|
2
|
+
import type { NavItem } from '../VvNav'
|
|
3
|
+
|
|
4
|
+
export const VvTabProps = {
|
|
5
|
+
...ModifiersProps,
|
|
6
|
+
items: {
|
|
7
|
+
type: Array<NavItem>,
|
|
8
|
+
required: true,
|
|
9
|
+
default: () => [],
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const VvTabEvents = ['click']
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { VvNavProps } from '@/components/VvNav'
|
|
2
|
+
import { ModifiersArgTypes } from '@/stories/argTypes'
|
|
3
|
+
|
|
4
|
+
export const defaultArgs = {
|
|
5
|
+
...propsToObject(VvNavProps),
|
|
6
|
+
items: [
|
|
7
|
+
{
|
|
8
|
+
title: 'Item 1',
|
|
9
|
+
href: 'javascript:void(0)',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
title: 'Item 2',
|
|
13
|
+
to: 'about',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: 'Item 3',
|
|
17
|
+
to: 'contacts',
|
|
18
|
+
on: {
|
|
19
|
+
click: () => {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.log('clicked Item 3')
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
modifiers: 'sidebar',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const argTypes = {
|
|
30
|
+
modifiers: {
|
|
31
|
+
...ModifiersArgTypes.modifiers,
|
|
32
|
+
options: ['sidebar', 'aside', 'tabs', 'full'],
|
|
33
|
+
},
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Meta, Story, Canvas } from '@storybook/addon-docs'
|
|
2
|
+
import VvNav from '@/components/VvNav/VvNav.vue'
|
|
3
|
+
import { defaultArgs, argTypes } from './Nav.settings'
|
|
4
|
+
import { defaultTest } from './Nav.test'
|
|
5
|
+
|
|
6
|
+
<Meta
|
|
7
|
+
title="Components/Nav"
|
|
8
|
+
component={VvNav}
|
|
9
|
+
args={defaultArgs}
|
|
10
|
+
argTypes={argTypes}
|
|
11
|
+
/>
|
|
12
|
+
|
|
13
|
+
export const Template = (args) => ({
|
|
14
|
+
components: { VvNav },
|
|
15
|
+
setup() {
|
|
16
|
+
return { args }
|
|
17
|
+
},
|
|
18
|
+
template: /* html */ `
|
|
19
|
+
<div class="m-md w-1/5">
|
|
20
|
+
<vv-nav v-bind="args" data-testId="element" />
|
|
21
|
+
</div>`,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
<Canvas>
|
|
25
|
+
<Story name="Default" play={defaultTest}>
|
|
26
|
+
{Template.bind()}
|
|
27
|
+
</Story>
|
|
28
|
+
</Canvas>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PlayAttributes } from '@/test/types'
|
|
2
|
+
import { expect } from '@/test/expect'
|
|
3
|
+
import { within, userEvent } from '@storybook/testing-library'
|
|
4
|
+
|
|
5
|
+
export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
6
|
+
const element = (await within(canvasElement).findByTestId(
|
|
7
|
+
'element',
|
|
8
|
+
)) as HTMLElement
|
|
9
|
+
|
|
10
|
+
if (!args.items || !args.items?.length) {
|
|
11
|
+
throw new Error('No items passed')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// check children number the same of items prop
|
|
15
|
+
expect(element.children?.[0].children.length).toEqual(args.items?.length)
|
|
16
|
+
|
|
17
|
+
// take firse and second elements
|
|
18
|
+
const firstEl = await element.getElementsByTagName('a')?.[0]
|
|
19
|
+
const secondEl = await element.getElementsByTagName('router-link')?.[1]
|
|
20
|
+
// check they have not current class
|
|
21
|
+
const secondElHasCurrentClass = secondEl.classList.contains('current')
|
|
22
|
+
const firstElHasCurrentClass = firstEl.classList.contains('current')
|
|
23
|
+
|
|
24
|
+
await expect(firstElHasCurrentClass).toBe(false)
|
|
25
|
+
await expect(secondElHasCurrentClass).toBe(false)
|
|
26
|
+
// click first item and check "current" css class
|
|
27
|
+
await userEvent.click(firstEl)
|
|
28
|
+
await expect(firstEl).toHaveClass('current')
|
|
29
|
+
|
|
30
|
+
// check accessibility
|
|
31
|
+
await expect(element).toHaveNoViolations()
|
|
32
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Meta, Story, Canvas } from '@storybook/addon-docs'
|
|
2
|
+
import VvNav from '@/components/VvNav/VvNav.vue'
|
|
3
|
+
import { defaultArgs, argTypes } from './Nav.settings'
|
|
4
|
+
import { defaultTest } from './Nav.test'
|
|
5
|
+
import { Template } from './Nav.stories.mdx'
|
|
6
|
+
|
|
7
|
+
<Meta
|
|
8
|
+
title="Components/Nav/Modifiers"
|
|
9
|
+
component={VvNav}
|
|
10
|
+
args={defaultArgs}
|
|
11
|
+
argTypes={argTypes}
|
|
12
|
+
/>
|
|
13
|
+
|
|
14
|
+
<Canvas>
|
|
15
|
+
<Story name="Sidebar" play={defaultTest} args={{ modifiers: 'sidebar' }}>
|
|
16
|
+
{Template.bind({})}
|
|
17
|
+
</Story>
|
|
18
|
+
</Canvas>
|
|
19
|
+
|
|
20
|
+
<Canvas>
|
|
21
|
+
<Story name="Aside" play={defaultTest} args={{ modifiers: 'aside' }}>
|
|
22
|
+
{Template.bind({})}
|
|
23
|
+
</Story>
|
|
24
|
+
</Canvas>
|
|
25
|
+
|
|
26
|
+
<Canvas>
|
|
27
|
+
<Story
|
|
28
|
+
name="Tabs"
|
|
29
|
+
play={defaultTest}
|
|
30
|
+
args={{
|
|
31
|
+
modifiers: 'tabs',
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
{Template.bind({})}
|
|
35
|
+
</Story>
|
|
36
|
+
</Canvas>
|
|
37
|
+
|
|
38
|
+
<Canvas>
|
|
39
|
+
<Story
|
|
40
|
+
name="TabsFull"
|
|
41
|
+
play={defaultTest}
|
|
42
|
+
args={{
|
|
43
|
+
modifiers: 'tabs full',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{Template.bind({})}
|
|
47
|
+
</Story>
|
|
48
|
+
</Canvas>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { VvTabProps } from '@/components/VvTab'
|
|
2
|
+
|
|
3
|
+
export const defaultArgs = {
|
|
4
|
+
...propsToObject(VvTabProps),
|
|
5
|
+
items: [
|
|
6
|
+
{
|
|
7
|
+
title: 'Item 1',
|
|
8
|
+
href: 'javascript:void(0)',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
title: 'Item 2',
|
|
12
|
+
to: 'about',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'tab-3',
|
|
16
|
+
title: 'Item 3',
|
|
17
|
+
to: 'contacts',
|
|
18
|
+
on: {
|
|
19
|
+
click: () => {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.log('clicked Item 3')
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const defaultArgTypes = {
|
|
29
|
+
tabId: {
|
|
30
|
+
description: 'Slot by tab-id',
|
|
31
|
+
control: {
|
|
32
|
+
type: 'text',
|
|
33
|
+
},
|
|
34
|
+
table: {
|
|
35
|
+
category: 'Slots',
|
|
36
|
+
type: {
|
|
37
|
+
summary: 'html',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Meta, Story, Canvas } from '@storybook/addon-docs'
|
|
2
|
+
import VvTab from '@/components/VvTab/VvTab.vue'
|
|
3
|
+
import { defaultArgs, defaultArgTypes } from './Tab.settings'
|
|
4
|
+
import { defaultTest } from './Tab.test'
|
|
5
|
+
|
|
6
|
+
<Meta
|
|
7
|
+
title="Components/Tab"
|
|
8
|
+
component={VvTab}
|
|
9
|
+
args={defaultArgs}
|
|
10
|
+
argTypes={defaultArgTypes}
|
|
11
|
+
/>
|
|
12
|
+
|
|
13
|
+
export const Template = (args) => ({
|
|
14
|
+
components: { VvTab },
|
|
15
|
+
setup() {
|
|
16
|
+
return { args }
|
|
17
|
+
},
|
|
18
|
+
template: /* html */ `
|
|
19
|
+
<div class="m-md w-1/2">
|
|
20
|
+
<vv-tab v-bind="args" data-testId="element">
|
|
21
|
+
<template #tab-item_0>
|
|
22
|
+
<span class="text-20 font-semibold">Tab 1</span>
|
|
23
|
+
<p>
|
|
24
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
|
|
25
|
+
vitae elit libero, a pharetra augue. Nullam id dolor id nibh
|
|
26
|
+
ultricies vehicula ut id elit. Morbi leo risus, porta ac
|
|
27
|
+
consectetur ac, vestibulum at eros. Praesent commodo cursus
|
|
28
|
+
magna, vel scelerisque nisl consectetur et. Donec sed odio dui.
|
|
29
|
+
Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae
|
|
30
|
+
elit libero, a pharetra augue.
|
|
31
|
+
</p>
|
|
32
|
+
</template>
|
|
33
|
+
<template #tab-item_1>
|
|
34
|
+
<span class="text-20 font-semibold">Tab 2</span>
|
|
35
|
+
<p>
|
|
36
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
|
|
37
|
+
vitae elit libero, a pharetra augue. Nullam id dolor id nibh
|
|
38
|
+
ultricies vehicula ut id elit. Morbi leo risus, porta ac
|
|
39
|
+
consectetur ac, vestibulum at eros. Praesent commodo cursus
|
|
40
|
+
magna, vel scelerisque nisl consectetur et. Donec sed odio dui.
|
|
41
|
+
Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae
|
|
42
|
+
elit libero, a pharetra augue.
|
|
43
|
+
</p>
|
|
44
|
+
</template>
|
|
45
|
+
<template #tab-3>
|
|
46
|
+
<span class="text-20 font-semibold">Tab 3</span>
|
|
47
|
+
<p>
|
|
48
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla
|
|
49
|
+
vitae elit libero, a pharetra augue. Nullam id dolor id nibh
|
|
50
|
+
ultricies vehicula ut id elit. Morbi leo risus, porta ac
|
|
51
|
+
consectetur ac, vestibulum at eros. Praesent commodo cursus
|
|
52
|
+
magna, vel scelerisque nisl consectetur et. Donec sed odio dui.
|
|
53
|
+
Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae
|
|
54
|
+
elit libero, a pharetra augue.
|
|
55
|
+
</p>
|
|
56
|
+
</template>
|
|
57
|
+
</vv-tab>
|
|
58
|
+
</div>`,
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
<Canvas>
|
|
62
|
+
<Story name="Default" play={defaultTest}>
|
|
63
|
+
{Template.bind()}
|
|
64
|
+
</Story>
|
|
65
|
+
</Canvas>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PlayAttributes } from '@/test/types'
|
|
2
|
+
import { expect } from '@/test/expect'
|
|
3
|
+
import { within, userEvent } from '@storybook/testing-library'
|
|
4
|
+
|
|
5
|
+
export async function defaultTest({ canvasElement, args }: PlayAttributes) {
|
|
6
|
+
const element = (await within(canvasElement).findByTestId(
|
|
7
|
+
'element',
|
|
8
|
+
)) as HTMLElement
|
|
9
|
+
|
|
10
|
+
if (!args.items || !args.items?.length) {
|
|
11
|
+
throw new Error('No items passed')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// check children number the same of items prop
|
|
15
|
+
const childrenEls = element.getElementsByClassName('vv-nav')[0]
|
|
16
|
+
expect(childrenEls?.children[0].children.length).toEqual(args.items?.length)
|
|
17
|
+
|
|
18
|
+
// take firse and second elements
|
|
19
|
+
const firstEl = await element.getElementsByTagName('a')?.[0]
|
|
20
|
+
const secondEl = await element.getElementsByTagName('router-link')?.[1]
|
|
21
|
+
// check they have not current class
|
|
22
|
+
const secondElHasCurrentClass = secondEl.classList.contains('current')
|
|
23
|
+
const firstElHasCurrentClass = firstEl.classList.contains('current')
|
|
24
|
+
|
|
25
|
+
await expect(firstElHasCurrentClass).toBe(false)
|
|
26
|
+
await expect(secondElHasCurrentClass).toBe(false)
|
|
27
|
+
// click first item and check "current" css class
|
|
28
|
+
await userEvent.click(firstEl)
|
|
29
|
+
await expect(firstEl).toHaveClass('current')
|
|
30
|
+
|
|
31
|
+
// check tab content to include "Tab 1"
|
|
32
|
+
const tabPanelEl = element.getElementsByClassName('vv-tab__panel')?.[0]
|
|
33
|
+
await expect(tabPanelEl.innerHTML.includes('Tab 1')).toBe(true)
|
|
34
|
+
|
|
35
|
+
// check accessibility
|
|
36
|
+
await expect(element).toHaveNoViolations()
|
|
37
|
+
}
|