@itfin/components 1.2.45 → 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "1.2.45",
3
+ "version": "1.2.47",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -81,7 +81,10 @@
81
81
  flex-grow: 1;
82
82
  z-index: 1;
83
83
  margin-right: -1px;
84
- max-width: calc(100% - var(--itf-tabs-panel-width));
84
+
85
+ @include media-breakpoint-up(lg) {
86
+ max-width: calc(100% - var(--itf-tabs-panel-width));
87
+ }
85
88
  }
86
89
  }
87
90
 
@@ -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;
@@ -58,10 +58,6 @@ class itfDatePickerInline extends Vue {
58
58
  this.createCalendar();
59
59
  }
60
60
 
61
- updated() {
62
- this.createCalendar();
63
- }
64
-
65
61
  async createCalendar() {
66
62
  if (this.calendar) {
67
63
  this.destroyCalendar();
@@ -56,10 +56,6 @@ class itfDatePickerInline extends Vue {
56
56
  this.createCalendar();
57
57
  }
58
58
 
59
- updated() {
60
- this.createCalendar();
61
- }
62
-
63
59
  async createCalendar() {
64
60
  if (this.calendar) {
65
61
  this.destroyCalendar();
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <a :href="href" class="itf-tab" :data-test="`itf-tab-${id || _uid}`" @click="setActive" :class="{ 'active': isActive }">
3
- <span><slot /></span>
4
- </a>
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 href() {
21
- if (this.to) {
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' }, this.vertical ? tabNodes : tabNodes.reverse()),
32
- createElement('div', { staticClass: 'itf-tabs-content' }, contents)
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