@itfin/components 1.2.46 → 1.2.47
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/package.json
CHANGED
|
@@ -9,6 +9,20 @@
|
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
@include media-breakpoint-down(md) {
|
|
13
|
+
.itf-select__dropdown-menu {
|
|
14
|
+
.dropdown-item.active {
|
|
15
|
+
background: transparent;
|
|
16
|
+
color: var(--bs-dropdown-link-color);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.dropdown-item.vs__dropdown-option--selected {
|
|
20
|
+
background: var(--bs-primary);
|
|
21
|
+
color: $vs-state-active-color;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
.vs__dropdown-option--highlight {
|
|
13
27
|
background: $vs-state-active-bg;
|
|
14
28
|
color: $vs-state-active-color;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
</
|
|
2
|
+
<span :data-test="`itf-tab-${tabId}`">
|
|
3
|
+
<slot />
|
|
4
|
+
</span>
|
|
5
5
|
</template>
|
|
6
6
|
<script>
|
|
7
7
|
import { Vue, Component, Prop, Inject } from 'vue-property-decorator';
|
|
@@ -17,31 +17,8 @@ class itfTab extends Vue {
|
|
|
17
17
|
@Prop() to;
|
|
18
18
|
@Prop({ type: Boolean, default: undefined }) active;
|
|
19
19
|
|
|
20
|
-
get
|
|
21
|
-
|
|
22
|
-
const route = this.$router.resolve(this.to);
|
|
23
|
-
return route && route.href;
|
|
24
|
-
}
|
|
25
|
-
return 'javascript:;';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get isActive() {
|
|
29
|
-
if (this.active === true || this.active === false) {
|
|
30
|
-
return this.active;
|
|
31
|
-
}
|
|
32
|
-
if (this.to) {
|
|
33
|
-
const route = this.$router.resolve(this.to);
|
|
34
|
-
return this.$route.fullPath === (route && route.href);
|
|
35
|
-
}
|
|
36
|
-
return this.tabsManager && this.tabsManager.getValue() === this.id;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
setActive(e) {
|
|
40
|
-
if (this.to) {
|
|
41
|
-
this.$router.push(this.to);
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
}
|
|
44
|
-
this.tabsManager.setValue(this.id || this._uid);
|
|
20
|
+
get tabId() {
|
|
21
|
+
return this.id || this._uid;
|
|
45
22
|
}
|
|
46
23
|
}
|
|
47
24
|
</script>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="d-lg-none itf-tab-dropdown my-2">
|
|
3
|
+
<itf-select
|
|
4
|
+
:options="getOptions()"
|
|
5
|
+
:reduce="(item) => item.id"
|
|
6
|
+
:get-option-key="(item) => item.id"
|
|
7
|
+
:get-option-label="(item) => item.text"
|
|
8
|
+
:value="value"
|
|
9
|
+
@input="onTabSelect"
|
|
10
|
+
>
|
|
11
|
+
<template #option="{ option }">
|
|
12
|
+
<v-nodes :nodes="[option.node]" />
|
|
13
|
+
</template>
|
|
14
|
+
<template #selected-option="{ option }">
|
|
15
|
+
<v-nodes :nodes="[option.node]" />
|
|
16
|
+
</template>
|
|
17
|
+
</itf-select>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<style lang="scss">
|
|
21
|
+
.itf-tab-dropdown {
|
|
22
|
+
.itf-tab a {
|
|
23
|
+
pointer-events: none;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
</style>
|
|
27
|
+
<script>
|
|
28
|
+
import {Vue, Component, Prop, Provide, Inject} from 'vue-property-decorator';
|
|
29
|
+
import itfSelect from '../select/Select';
|
|
30
|
+
|
|
31
|
+
export default @Component({
|
|
32
|
+
name: 'itfTabDropdown',
|
|
33
|
+
components: {
|
|
34
|
+
itfSelect,
|
|
35
|
+
VNodes: {
|
|
36
|
+
functional: true,
|
|
37
|
+
render: (h, ctx) => ctx.props.nodes
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
class itfTabDropdown extends Vue {
|
|
42
|
+
@Inject({ default: null }) tabsManager;
|
|
43
|
+
@Prop(Array) nodes;
|
|
44
|
+
|
|
45
|
+
get value() {
|
|
46
|
+
const option = this.getOptions().find(({ node }) => this.tabsManager.isActive(node));
|
|
47
|
+
return option && option.id;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getOptions() {
|
|
51
|
+
const opts = this.nodes.map(node => {
|
|
52
|
+
const id = node.componentInstance ? (node.componentInstance.id || node.componentInstance._uid) : '-';
|
|
53
|
+
const text = node.elm ? node.elm.textContent : '';
|
|
54
|
+
return { id, text: text.trim(), node }
|
|
55
|
+
});
|
|
56
|
+
return opts;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
onTabSelect(itemId) {
|
|
60
|
+
const option = this.getOptions().find(({ id }) => itemId === id);
|
|
61
|
+
if (option) {
|
|
62
|
+
if (option.node.componentInstance.to) {
|
|
63
|
+
this.$router.push(option.node.componentInstance.to);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.tabsManager.setValue(itemId);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
</script>
|
|
@@ -3,11 +3,13 @@ import {
|
|
|
3
3
|
Vue, Component, Model, Emit, Prop
|
|
4
4
|
} from 'vue-property-decorator';
|
|
5
5
|
import itfTab from './Tab';
|
|
6
|
+
import itfTabDropdown from './TabDropdown';
|
|
6
7
|
|
|
7
8
|
export default @Component({
|
|
8
9
|
name: 'itfTabs',
|
|
9
10
|
components: {
|
|
10
|
-
itfTab
|
|
11
|
+
itfTab,
|
|
12
|
+
itfTabDropdown
|
|
11
13
|
},
|
|
12
14
|
provide() {
|
|
13
15
|
return { tabsManager: this }; // do not use Provide from vue-property-decorator
|
|
@@ -27,9 +29,16 @@ class itfTabs extends Vue {
|
|
|
27
29
|
if (this.vertical) {
|
|
28
30
|
staticClass += ' itf-tabs__vertical';
|
|
29
31
|
}
|
|
32
|
+
|
|
33
|
+
const list = (this.vertical ? tabNodes : [...tabNodes].reverse());
|
|
34
|
+
const tabs = list.map((node) => createElement('a', this.createTab(node), [node]));
|
|
30
35
|
return createElement('div', { staticClass }, [
|
|
31
|
-
createElement('div', { staticClass: 'itf-tabs-panel' },
|
|
32
|
-
createElement('div', { staticClass: 'itf-tabs-content' },
|
|
36
|
+
createElement('div', { staticClass: 'itf-tabs-panel d-lg-flex d-none' }, tabs),
|
|
37
|
+
createElement('div', { staticClass: 'itf-tabs-content' }, [createElement(itfTabDropdown, {
|
|
38
|
+
props: {
|
|
39
|
+
nodes: tabNodes
|
|
40
|
+
}
|
|
41
|
+
}), ...contents])
|
|
33
42
|
]);
|
|
34
43
|
|
|
35
44
|
function parseNodes(slots) {
|
|
@@ -53,8 +62,50 @@ class itfTabs extends Vue {
|
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
|
|
65
|
+
isActive(node) {
|
|
66
|
+
const options = (node.componentOptions && node.componentOptions.propsData) || {};
|
|
67
|
+
const id = options.id || Math.random();
|
|
68
|
+
let isActive = this.getValue() === id;
|
|
69
|
+
if (options.active === true || options.active === false) {
|
|
70
|
+
isActive = options.active;
|
|
71
|
+
} else if (options.to) {
|
|
72
|
+
const route = this.$router.resolve(options.to);
|
|
73
|
+
isActive = this.$route.fullPath === (route && route.href);
|
|
74
|
+
}
|
|
75
|
+
return isActive;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
createTab(node) {
|
|
79
|
+
const options = node.componentOptions.propsData || {};
|
|
80
|
+
const id = options.id || node.componentOptions.Ctor.cid;
|
|
81
|
+
|
|
82
|
+
let href = 'javascript:;';
|
|
83
|
+
if (options.to) {
|
|
84
|
+
const route = this.$router.resolve(options.to);
|
|
85
|
+
href = route && route.href;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
staticClass: 'itf-tab',
|
|
90
|
+
class: {
|
|
91
|
+
'active': this.isActive(node)
|
|
92
|
+
},
|
|
93
|
+
attrs: { href },
|
|
94
|
+
on: {
|
|
95
|
+
click: (e) => {
|
|
96
|
+
if (options.to) {
|
|
97
|
+
this.$router.push(options.to);
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
}
|
|
100
|
+
this.setValue(id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
56
106
|
@Emit('input')
|
|
57
107
|
setValue(value) {
|
|
108
|
+
console.info(value);
|
|
58
109
|
this.tabNodes = null;
|
|
59
110
|
}
|
|
60
111
|
|