@kiva/kv-components 3.3.1 → 3.5.1
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/CHANGELOG.md +39 -0
- package/package.json +2 -2
- package/utils/expander.js +72 -0
- package/vue/KvAccordionItem.vue +130 -0
- package/vue/KvCarousel.vue +6 -8
- package/vue/KvExpandable.vue +84 -0
- package/vue/KvTab.vue +9 -2
- package/vue/KvTabs.vue +16 -4
- package/vue/stories/KvAccordionItem.stories.js +24 -0
- package/vue/stories/KvTabs.stories.js +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,45 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [3.5.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.5.0...@kiva/kv-components@3.5.1) (2022-09-13)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **KvCarousel:** incorrect slide marked as current ([f496e7c](https://github.com/kiva/kv-ui-elements/commit/f496e7c0a8fdebd1f6e003f4c79b57a5926b0c4a))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [3.5.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.4.0...@kiva/kv-components@3.5.0) (2022-09-07)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* height of indicator bar ([8908e44](https://github.com/kiva/kv-ui-elements/commit/8908e44da2d3edcfbc9bfca44144604ed255674b))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add vertical tab button for new home page exp ([329e490](https://github.com/kiva/kv-ui-elements/commit/329e490a8df555b126c23e93f4ce69cd00eb7c35))
|
|
28
|
+
* add vertical variant in tab ([a23c9d1](https://github.com/kiva/kv-ui-elements/commit/a23c9d1abd1ade6a2603d422bb0f2535e299d119))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# [3.4.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.3.1...@kiva/kv-components@3.4.0) (2022-08-29)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
* creating a global resuable component (KvAccordionItem) ([5bf7685](https://github.com/kiva/kv-ui-elements/commit/5bf76858508870f9055e680406a1167cdd68099c))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
6
45
|
## [3.3.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.3.0...@kiva/kv-components@3.3.1) (2022-08-26)
|
|
7
46
|
|
|
8
47
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"optional": true
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "2d6daa94997131992d6c86f8367504c560ea9e20"
|
|
72
72
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
|
|
3
|
+
function setInitialStyle(el, { property, delay, easing }) {
|
|
4
|
+
el.style.overflow = 'hidden';
|
|
5
|
+
el.style.transition = `${property} ${delay}ms ${easing}`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function unsetStyles(el, { property }) {
|
|
9
|
+
el.style[property] = null;
|
|
10
|
+
el.style.overflow = null;
|
|
11
|
+
el.style.transition = null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function expand(el, {
|
|
15
|
+
easing = 'ease',
|
|
16
|
+
delay = 500,
|
|
17
|
+
done = () => {},
|
|
18
|
+
from = 0,
|
|
19
|
+
property = 'height',
|
|
20
|
+
}) {
|
|
21
|
+
// set initial styles
|
|
22
|
+
setInitialStyle(el, { property, delay, easing });
|
|
23
|
+
|
|
24
|
+
// need to measure the property, so first set the value to 'auto'
|
|
25
|
+
// then unset display:none from v-show
|
|
26
|
+
el.style[property] = 'auto';
|
|
27
|
+
el.style.display = null;
|
|
28
|
+
|
|
29
|
+
// measure the property
|
|
30
|
+
const propValue = window.getComputedStyle(el).getPropertyValue(property);
|
|
31
|
+
|
|
32
|
+
// set the property to the 'from' value
|
|
33
|
+
el.style[property] = from;
|
|
34
|
+
|
|
35
|
+
el.addEventListener('transitionend', function listener() {
|
|
36
|
+
unsetStyles(el, { property });
|
|
37
|
+
// finally, call the done callback after the transition
|
|
38
|
+
done();
|
|
39
|
+
el.removeEventListener('transitionend', listener, true);
|
|
40
|
+
}, true);
|
|
41
|
+
|
|
42
|
+
// hack to cause the browser to reflow
|
|
43
|
+
void el.offsetWidth; // eslint-disable-line no-void
|
|
44
|
+
// ...and set the property to the measured value on the next tick so it animates w/ css
|
|
45
|
+
el.style[property] = propValue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function collapse(el, {
|
|
49
|
+
easing = 'ease',
|
|
50
|
+
delay = 500,
|
|
51
|
+
done = () => {},
|
|
52
|
+
to = 0,
|
|
53
|
+
property = 'height',
|
|
54
|
+
}) {
|
|
55
|
+
// set initial styles
|
|
56
|
+
setInitialStyle(el, { property, delay, easing });
|
|
57
|
+
|
|
58
|
+
// explicitly set the property value...
|
|
59
|
+
el.style[property] = window.getComputedStyle(el).getPropertyValue(property);
|
|
60
|
+
|
|
61
|
+
el.addEventListener('transitionend', function listener() {
|
|
62
|
+
unsetStyles(el, { property });
|
|
63
|
+
// finally, call the done callback after the transition
|
|
64
|
+
done();
|
|
65
|
+
el.removeEventListener('transitionend', listener, true);
|
|
66
|
+
}, true);
|
|
67
|
+
|
|
68
|
+
// hack to cause the browser to reflow
|
|
69
|
+
void el.offsetWidth; // eslint-disable-line no-void
|
|
70
|
+
// ...and set the property to the 'to' value on the next tick so it animates w/ css
|
|
71
|
+
el.style[property] = to;
|
|
72
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="tw-border-b tw-border-tertiary tw-relative last:tw-border-b-0"
|
|
4
|
+
>
|
|
5
|
+
<button
|
|
6
|
+
class="tw-w-full tw-flex tw-justify-between tw-items-center tw-py-1.5 tw-px-0
|
|
7
|
+
tw-text-left disabled:tw-cursor-not-allowed disabled:tw-opacity-low
|
|
8
|
+
hover:tw-text-action-highlight focus:tw-text-action-highlight"
|
|
9
|
+
:disabled="disabled"
|
|
10
|
+
:aria-controls="`kv-accordion-${id}`"
|
|
11
|
+
:aria-expanded="isOpen ? 'true' : 'false'"
|
|
12
|
+
@click.prevent="toggle"
|
|
13
|
+
>
|
|
14
|
+
<span class="tw-flex-1">
|
|
15
|
+
<slot name="header"></slot>
|
|
16
|
+
</span>
|
|
17
|
+
<kv-material-icon
|
|
18
|
+
class="tw-h-3 tw-w-3 tw-transition tw-transform tw-duration-500 tw-ease"
|
|
19
|
+
:class="{ 'tw-rotate-180' : isOpen }"
|
|
20
|
+
:icon="mdiChevronDown"
|
|
21
|
+
/>
|
|
22
|
+
</button>
|
|
23
|
+
<kv-expandable>
|
|
24
|
+
<div
|
|
25
|
+
v-show="isOpen"
|
|
26
|
+
:id="`kv-accordion-${id}`"
|
|
27
|
+
:aria-hidden="isOpen ? 'false' : 'true'"
|
|
28
|
+
>
|
|
29
|
+
<slot></slot>
|
|
30
|
+
</div>
|
|
31
|
+
</kv-expandable>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
// Accordion a11y resources
|
|
37
|
+
// https://www.w3.org/TR/wai-aria-practices-1.1/examples/accordion/accordion.html
|
|
38
|
+
// https://www.aditus.io/patterns/accordion/
|
|
39
|
+
// Future improvement
|
|
40
|
+
// Currently the slot content is inside the button, which means h2, h3 etc. won't be
|
|
41
|
+
// navigatable via headings. See https://daverupert.com/2019/12/why-details-is-not-an-accordion/
|
|
42
|
+
// h2 + button // ✅ H1 will show up when navigating by headings
|
|
43
|
+
// button + h2 // ❌ H1 will not show up when navigating by headings
|
|
44
|
+
// Perhaps we could do some magic DOM reordering via this.$slots.header or
|
|
45
|
+
// pass a prop like 'tag' that sets the parent node of the button. <accordion tag="h3">...
|
|
46
|
+
|
|
47
|
+
import {
|
|
48
|
+
ref,
|
|
49
|
+
toRefs,
|
|
50
|
+
} from 'vue-demi';
|
|
51
|
+
import { mdiChevronDown } from '@mdi/js';
|
|
52
|
+
import KvExpandable from './KvExpandable.vue';
|
|
53
|
+
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
54
|
+
|
|
55
|
+
export default {
|
|
56
|
+
components: {
|
|
57
|
+
KvMaterialIcon,
|
|
58
|
+
KvExpandable,
|
|
59
|
+
},
|
|
60
|
+
props: {
|
|
61
|
+
/**
|
|
62
|
+
* Unique id. used for a11y
|
|
63
|
+
* */
|
|
64
|
+
id: {
|
|
65
|
+
type: String,
|
|
66
|
+
required: true,
|
|
67
|
+
validator: (v) => v.length > 0 && !/\s/g.test(v), // must be a valid html5 id
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Whether the body is shown initially
|
|
71
|
+
* */
|
|
72
|
+
open: {
|
|
73
|
+
type: Boolean,
|
|
74
|
+
default: false,
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Whether the accordion can be toggled
|
|
78
|
+
* */
|
|
79
|
+
disabled: {
|
|
80
|
+
type: Boolean,
|
|
81
|
+
default: false,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
emits: [
|
|
85
|
+
'toggle',
|
|
86
|
+
],
|
|
87
|
+
setup(props, { emit }) {
|
|
88
|
+
const {
|
|
89
|
+
open,
|
|
90
|
+
disabled,
|
|
91
|
+
} = toRefs(props);
|
|
92
|
+
|
|
93
|
+
const isOpen = ref(open.value);
|
|
94
|
+
|
|
95
|
+
const toggle = () => {
|
|
96
|
+
if (!disabled.value) {
|
|
97
|
+
isOpen.value = !isOpen.value;
|
|
98
|
+
/**
|
|
99
|
+
* Fires when the accordion has been toggled.
|
|
100
|
+
* Contains an object with a boolean 'open' property of the current open
|
|
101
|
+
* state of the accordion
|
|
102
|
+
* @event toggle
|
|
103
|
+
* @type {Event}
|
|
104
|
+
*/
|
|
105
|
+
emit('toggle', { open: isOpen.value });
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const expand = () => {
|
|
110
|
+
if (!disabled.value) {
|
|
111
|
+
isOpen.value = true;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const collapse = () => {
|
|
116
|
+
if (!disabled.value) {
|
|
117
|
+
isOpen.value = false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
collapse,
|
|
123
|
+
expand,
|
|
124
|
+
isOpen,
|
|
125
|
+
mdiChevronDown,
|
|
126
|
+
toggle,
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
</script>
|
package/vue/KvCarousel.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section
|
|
3
3
|
ref="rootEl"
|
|
4
|
-
class="tw-overflow-hidden tw-w-full"
|
|
4
|
+
class="kv-carousel tw-overflow-hidden tw-w-full"
|
|
5
5
|
aria-label="carousel"
|
|
6
6
|
>
|
|
7
7
|
<!-- Carousel Content -->
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
class="tw-flex-none tw-relative"
|
|
16
16
|
role="group"
|
|
17
17
|
:aria-label="`slide ${index + 1} of ${componentSlotKeys.length}`"
|
|
18
|
-
:aria-current="
|
|
19
|
-
:aria-hidden="isAriaHidden(index)"
|
|
18
|
+
:aria-current="currentIndex === index ? 'true' : 'false'"
|
|
19
|
+
:aria-hidden="isAriaHidden(index)? 'true' : 'false'"
|
|
20
20
|
:tab-index="isAriaHidden(index) ? '-1' : false"
|
|
21
21
|
:class="{ 'tw-w-full': !multipleSlidesVisible || slideMaxWidth }"
|
|
22
22
|
:style="slideMaxWidth ? `max-width:${slideMaxWidth}` :''"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<!-- Carousel Controls -->
|
|
30
30
|
<div
|
|
31
31
|
v-if="slideIndicatorCount > 1"
|
|
32
|
-
class="tw-flex
|
|
32
|
+
class="kv-carousel__controls tw-flex
|
|
33
33
|
tw-justify-between md:tw-justify-center tw-items-center
|
|
34
34
|
tw-mt-4 tw-w-full"
|
|
35
35
|
>
|
|
@@ -239,14 +239,12 @@ export default {
|
|
|
239
239
|
* If the slide is not completely in view in the carousel
|
|
240
240
|
* it should be aria-hidden
|
|
241
241
|
*
|
|
242
|
-
* @param {Number} index The current index of the slide
|
|
242
|
+
* @param {Number} index The current index of the slide
|
|
243
243
|
* @returns {Boolean}
|
|
244
244
|
*/
|
|
245
245
|
const isAriaHidden = (index) => {
|
|
246
|
-
// Index starts at 1
|
|
247
|
-
// Embla starts at 0
|
|
248
246
|
if (embla.value) {
|
|
249
|
-
return !embla.value.slidesInView(true).includes(index
|
|
247
|
+
return !embla.value.slidesInView(true).includes(index);
|
|
250
248
|
}
|
|
251
249
|
return false;
|
|
252
250
|
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<transition
|
|
3
|
+
@enter="enter"
|
|
4
|
+
@leave="leave"
|
|
5
|
+
>
|
|
6
|
+
<slot></slot>
|
|
7
|
+
</transition>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import {
|
|
12
|
+
toRefs,
|
|
13
|
+
} from 'vue-demi';
|
|
14
|
+
import { expand, collapse } from '../utils/expander';
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
props: {
|
|
18
|
+
property: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: 'height',
|
|
21
|
+
},
|
|
22
|
+
delay: {
|
|
23
|
+
type: Number,
|
|
24
|
+
default: 500,
|
|
25
|
+
},
|
|
26
|
+
easing: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: 'ease',
|
|
29
|
+
},
|
|
30
|
+
skipEnter: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
default: false,
|
|
33
|
+
},
|
|
34
|
+
skipLeave: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
setup(props) {
|
|
40
|
+
const {
|
|
41
|
+
property,
|
|
42
|
+
delay,
|
|
43
|
+
easing,
|
|
44
|
+
skipEnter,
|
|
45
|
+
skipLeave,
|
|
46
|
+
} = toRefs(props);
|
|
47
|
+
|
|
48
|
+
const enter = (el, done) => {
|
|
49
|
+
if (skipEnter.value) {
|
|
50
|
+
return done();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
expand(el, {
|
|
54
|
+
property: property.value,
|
|
55
|
+
delay: delay.value,
|
|
56
|
+
easing: easing.value,
|
|
57
|
+
done,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const leave = (el, done) => {
|
|
64
|
+
if (skipLeave.value) {
|
|
65
|
+
return done();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
collapse(el, {
|
|
69
|
+
property: property.value,
|
|
70
|
+
delay: delay.value,
|
|
71
|
+
easing: easing.value,
|
|
72
|
+
done,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return true;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
enter,
|
|
80
|
+
leave,
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
</script>
|
package/vue/KvTab.vue
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
:id="`kv-tab-${forPanel}`"
|
|
4
|
-
class="tw-text-h3 tw-mb-1.5 tw-whitespace-nowrap"
|
|
5
|
-
:class="{ 'hover:tw-text-action-highlight' : !isActive
|
|
4
|
+
class="tw-text-h3 tw-mb-1.5 tw-whitespace-nowrap tw-text-left"
|
|
5
|
+
:class="{ 'hover:tw-text-action-highlight' : !isActive,
|
|
6
|
+
'md:tw-border-l-2 tw-border-transparent md:tw-pl-2' : vertical,
|
|
7
|
+
'tw-text-action-highlight' : isActive && vertical
|
|
8
|
+
}"
|
|
6
9
|
role="tab"
|
|
7
10
|
:aria-selected="isActive"
|
|
8
11
|
:aria-controls="`kv-tab-panel-${forPanel}`"
|
|
@@ -39,6 +42,10 @@ export default {
|
|
|
39
42
|
type: Boolean,
|
|
40
43
|
default: false,
|
|
41
44
|
},
|
|
45
|
+
vertical: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: false,
|
|
48
|
+
},
|
|
42
49
|
},
|
|
43
50
|
setup(props) {
|
|
44
51
|
const {
|
package/vue/KvTabs.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
2
|
+
<div :class="vertical ? 'md:tw-flex' : ''">
|
|
3
3
|
<div
|
|
4
4
|
role="tablist"
|
|
5
5
|
class="
|
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
tw-gap-x-2.5 md:tw-gap-x-5 lg:tw-gap-x-6
|
|
8
8
|
tw-mb-3 lg:tw-mb-4
|
|
9
9
|
"
|
|
10
|
+
:class="{'md:tw-flex-col md:tw-mr-3' : vertical}"
|
|
10
11
|
@keydown="handleKeyDown($event)"
|
|
11
12
|
>
|
|
12
13
|
<!-- @slot Tab Navigation -->
|
|
13
|
-
<slot
|
|
14
|
+
<slot
|
|
15
|
+
name="tabNav"
|
|
16
|
+
></slot>
|
|
14
17
|
|
|
15
18
|
<!-- indicator bar -->
|
|
16
19
|
<div
|
|
@@ -19,9 +22,12 @@
|
|
|
19
22
|
tw-bg-primary-inverse tw-rounded-full
|
|
20
23
|
tw-origin-left tw-transition-all tw-duration-300
|
|
21
24
|
"
|
|
25
|
+
:class="{ 'tw-hidden md:tw-block tw-top-0 md:tw-bg-action-highlight' : vertical}"
|
|
22
26
|
:style="`
|
|
23
|
-
width: ${selectedTabEl ? selectedTabEl.clientWidth :
|
|
24
|
-
|
|
27
|
+
width: ${selectedTabEl && !vertical ? selectedTabEl.clientWidth : 3}px;
|
|
28
|
+
height: ${selectedTabEl && vertical ? `${selectedTabEl.clientHeight}px` : '0.25rem'};
|
|
29
|
+
transform: ${selectedTabEl && !vertical ? `translateX(${selectedTabEl.offsetLeft}px)`
|
|
30
|
+
: selectedTabEl ? `translateY(${selectedTabEl.offsetTop}px)` : null};
|
|
25
31
|
`"
|
|
26
32
|
></div>
|
|
27
33
|
</div>
|
|
@@ -65,6 +71,12 @@ import {
|
|
|
65
71
|
} from 'vue-demi';
|
|
66
72
|
|
|
67
73
|
export default {
|
|
74
|
+
props: {
|
|
75
|
+
vertical: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
default: false,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
68
80
|
setup(props, { emit }) {
|
|
69
81
|
const tabContext = reactive({
|
|
70
82
|
selectedIndex: 0,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import KvAccordionItem from '../KvAccordionItem.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'KvAccordionItem',
|
|
5
|
+
component: KvAccordionItem,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const DefaultTemplate = () => ({
|
|
9
|
+
components: { KvAccordionItem },
|
|
10
|
+
template: `
|
|
11
|
+
<div style="padding: 20px;">
|
|
12
|
+
<kv-accordion-item id="accordian-test">
|
|
13
|
+
<template #header>
|
|
14
|
+
<h2>Accordion</h2>
|
|
15
|
+
</template>
|
|
16
|
+
<p>
|
|
17
|
+
"Hello, KvAccordion Contents!"
|
|
18
|
+
</p>
|
|
19
|
+
</kv-accordion-item>
|
|
20
|
+
</div>
|
|
21
|
+
`,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const Default = DefaultTemplate.bind({});
|
|
@@ -5,6 +5,9 @@ import KvTabPanel from '../KvTabPanel.vue';
|
|
|
5
5
|
export default {
|
|
6
6
|
title: 'KvTabs',
|
|
7
7
|
component: KvTabs,
|
|
8
|
+
args: {
|
|
9
|
+
vertical: true,
|
|
10
|
+
},
|
|
8
11
|
};
|
|
9
12
|
|
|
10
13
|
export const DefaultTemplate = () => ({
|
|
@@ -57,6 +60,32 @@ export const InitialTabSelection = () => ({
|
|
|
57
60
|
},
|
|
58
61
|
});
|
|
59
62
|
|
|
63
|
+
export const VerticalOrientation = (args, { argTypes }) => ({
|
|
64
|
+
props: Object.keys(argTypes),
|
|
65
|
+
components: { KvTabs, KvTab, KvTabPanel },
|
|
66
|
+
template: `
|
|
67
|
+
<kv-tabs @tab-changed="handleTabChanged" :vertical="vertical">
|
|
68
|
+
<template #tabNav>
|
|
69
|
+
<kv-tab :vertical="vertical" forPanel="demo-1-first">First</kv-tab>
|
|
70
|
+
<kv-tab :vertical="vertical" forPanel="demo-1-second">Second</kv-tab>
|
|
71
|
+
<kv-tab :vertical="vertical" forPanel="demo-1-third">Third</kv-tab>
|
|
72
|
+
<kv-tab :vertical="vertical" forPanel="demo-1-forth">Forth is longer</kv-tab>
|
|
73
|
+
</template>
|
|
74
|
+
<template #tabPanels>
|
|
75
|
+
<kv-tab-panel id="demo-1-first"><p>First Panel</p></kv-tab-panel>
|
|
76
|
+
<kv-tab-panel id="demo-1-second"><p>Second Panel has <br>longer<br>content</p></kv-tab-panel>
|
|
77
|
+
<kv-tab-panel id="demo-1-third"><p>Third Panel</p></kv-tab-panel>
|
|
78
|
+
<kv-tab-panel id="demo-1-forth"><p>Forth Panel</p></kv-tab-panel>
|
|
79
|
+
</template>
|
|
80
|
+
</kv-tabs>
|
|
81
|
+
`,
|
|
82
|
+
methods: {
|
|
83
|
+
handleTabChanged(index) {
|
|
84
|
+
console.log(index);
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
60
89
|
export const MultipleOnAPage = () => ({
|
|
61
90
|
components: { KvTabs, KvTab, KvTabPanel },
|
|
62
91
|
template: `
|