its_ui_vite 0.0.2 → 0.0.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.
@@ -1,20 +1,57 @@
1
1
  <template>
2
- <div class="c-tabs">
3
- <button :class="['c-tabs__item', {'c-tabs__item-active': item === activeTab}]" v-for="item in tabs" :key="item.id" @click="handleTab(item)">
4
- <div>
5
- {{ item.text }}
2
+ <div v-if="isShow" class="c-tabs" :style="`--transition: ${speed}ms`">
3
+ <div
4
+ :class="classes.itemsWrap"
5
+ :style="scrollStyle"
6
+ @wheel.prevent="handleWheel"
7
+ >
8
+ <div ref="items" :class="classes.items">
9
+ <button
10
+ :class="[classes.item, {'c-tabs__item-active': item.value === activeTab?.value}]"
11
+ v-for="item in tabs"
12
+ :key="item.value"
13
+ :data-tab-value="item.value"
14
+ @click="handleTab(item, $event)"
15
+ >
16
+ <div>
17
+ {{ item.text }}
18
+ </div>
19
+ </button>
20
+
21
+ <div class="c-tabs__line">
22
+ <div ref="thumb" :style="`left: ${styleThumb.left}px; right: ${styleThumb.right}px`" class="c-tabs__thumb"></div>
23
+ </div>
6
24
  </div>
7
- </button>
25
+ </div>
8
26
  </div>
9
27
  </template>
10
28
 
11
29
  <script>
30
+ import { getPropValidator, isMobile } from '../assets/js/helpers'
31
+
12
32
  export default {
13
33
  data() {
14
34
  return {
15
- activeTab: this.tabs.find(({id}) => id === this.activeId)
35
+ activeTab: null,
36
+ speed: 200,
37
+ translateTabTruck: 0,
38
+ isTrail: this.animationType === 'trail',
39
+ updatedFoo: () => {},
40
+
41
+ classes: {
42
+ item: 'c-tabs__item',
43
+ items: 'c-tabs__items',
44
+ itemsWrap: 'c-tabs__items_wrap',
45
+ },
46
+
47
+ styleThumb: {
48
+ left: 0,
49
+ right: '100%'
50
+ }
16
51
  }
17
52
  },
53
+
54
+
18
55
  props: {
19
56
  tabs: {
20
57
  type: Array,
@@ -25,39 +62,189 @@ export default {
25
62
 
26
63
  activeId: {
27
64
  required: true,
28
- }
65
+ },
66
+
67
+ transformVal: {
68
+ type: Boolean,
69
+
70
+ default: true
71
+ },
72
+
73
+ scroll: {
74
+ type: Boolean,
75
+
76
+ default: false
77
+ },
78
+
79
+ animationType: {
80
+ type: String,
81
+
82
+ default: 'trail',
83
+ validator: getPropValidator('CTabs', 'animationType', ['worm', 'trail'])
84
+ },
29
85
  },
30
86
 
31
- computed: {
32
- activeTab() {
33
- return this.tabs.find(({id}) => id === (this.activeTab.id || this.activeId))
34
- }
87
+ emits: ['change'],
88
+
89
+ updated() {
90
+ this.updatedFoo()
91
+ this.updatedFoo = () => {}
92
+ },
93
+
94
+ mounted() {
95
+ this.initTabs()
35
96
  },
36
97
 
37
98
  methods: {
38
- handleTab(activeTab) {
39
- console.log('handleTab');
40
- if (this.activeTab === activeTab) return;
99
+ initTabs() {
100
+ const activeId = this.activeId || this.tabs?.[0]?.value;
101
+ const activeTab = this.tabs?.find(({value}) => value === activeId);
102
+ const $activeTab = this.$refs?.items?.querySelector(`[data-tab-value="${activeTab?.value}"]`);
103
+
104
+ if (!$activeTab && !activeTab) return;
105
+
106
+ this.setActiveTab(activeTab);
107
+ this.setThumb();
108
+ this.setTabTruck();
109
+ },
110
+
111
+ handleTab(activeTab, evt) {
112
+ this.setActiveTab(activeTab);
113
+ this.setThumb();
114
+ this.setTabTruck();
115
+ },
116
+
117
+ handleWheel(evt) {
118
+ if (!this.scroll || isMobile()) return;
119
+
120
+ const translate = evt.deltaY || evt.deltaX;
121
+
122
+ this.setStyleTabTruck(this.translateTabTruck + translate)
123
+ },
124
+
125
+ setActiveTab(activeTab) {
126
+ if (this.activeTab?.value === activeTab.value) return;
41
127
 
42
128
  this.activeTab = activeTab
43
- this.$emit('tabChange', activeTab)
129
+ this.$emit('change', this.transformVal ? activeTab.value : activeTab)
130
+ },
131
+
132
+ getPositions() {
133
+ const $activeTab = this.$refs?.items?.querySelector(`[data-tab-value="${this.activeTab?.value ?? this.activeTab}"]`);
134
+
135
+ return {
136
+ activeTab: $activeTab.getBoundingClientRect(),
137
+ tabsWrap: this.$refs.items.closest(`.${this.classes.itemsWrap}`).getBoundingClientRect(),
138
+ items: this.$refs.items.getBoundingClientRect(),
139
+ }
140
+ },
141
+
142
+ setThumb() {
143
+ const positions = this.getPositions();
144
+
145
+ const right = positions.items.right - positions.activeTab.right;
146
+ const left = positions.activeTab.left - positions.items.left;
147
+
148
+ this.setStyleThumb(right, left);
149
+ },
150
+
151
+ setStyleThumb(right, left) {
152
+ const styleRight = {
153
+ name: 'right',
154
+ value: right,
155
+ }
156
+
157
+ const styleLeft = {
158
+ name: 'left',
159
+ value: left,
160
+ }
161
+
162
+ const styleQueue = this.styleThumb.right > right ? [styleRight, styleLeft] : [styleLeft, styleRight]
163
+
164
+ this.styleThumb[styleQueue[0].name] = styleQueue[0].value;
165
+
166
+ setTimeout(() => {
167
+ this.styleThumb[styleQueue[1].name] = styleQueue[1].value;
168
+ }, this.isTrail ? 0 : this.speed);
169
+ },
170
+
171
+ setTabTruck() {
172
+ if (!this.scroll || isMobile()) return;
173
+
174
+ const position = this.getPositions();
175
+
176
+ const right = position.items.right - position.activeTab.right;
177
+ const centerTab = right + (position.activeTab.width / 2);
178
+ const centerPosition = (position.tabsWrap.width / 2) - centerTab;
179
+
180
+ this.setStyleTabTruck(centerPosition);
181
+ },
182
+
183
+ setStyleTabTruck(translate) {
184
+ const position = this.getPositions();
185
+
186
+ const maxPosition = this.$refs.items.scrollWidth - position.tabsWrap.width;
187
+
188
+ this.translateTabTruck = Math.max(0, Math.min(maxPosition, translate));
189
+ this.$refs.items.style.transform = `translateX(-${this.translateTabTruck}px)`;
44
190
  }
45
191
  },
192
+
193
+ computed: {
194
+ isShow() {
195
+ return !([null, undefined].includes(this.tabs?.[0]?.value))
196
+ },
197
+
198
+ scrollStyle() {
199
+ return `overflow: ${(isMobile() && this.scroll) ? 'auto' : 'hidden'};`
200
+ }
201
+ },
202
+
203
+ watch: {
204
+ tabs: {
205
+ handler() {
206
+ this.updatedFoo = this.initTabs
207
+ },
208
+
209
+ deep: true,
210
+ immediate: true,
211
+ },
212
+
213
+ activeId: {
214
+ handler() {
215
+ this.updatedFoo = this.initTabs
216
+ },
217
+
218
+ deep: true,
219
+ immediate: true,
220
+ },
221
+ }
46
222
  }
47
223
  </script>
48
224
 
49
225
  <style lang="scss">
50
226
  .c-tabs {
51
- display: flex;
227
+ --tab-line-height: 5px;
52
228
 
53
229
  max-width: 100%;
54
230
 
55
- gap: 40px;
231
+ display: flex;
232
+
233
+ &__items {
234
+ position: relative;
235
+
236
+ display: flex;
237
+
238
+ gap: 40px;
239
+ padding-bottom: 16px;
240
+ }
56
241
 
57
242
  &__item {
58
243
  display: flex;
59
244
  flex-direction: column;
60
245
 
246
+ padding: 0;
247
+
61
248
  font-size: 16px;
62
249
 
63
250
  border: none;
@@ -66,28 +253,34 @@ export default {
66
253
  background: transparent;
67
254
 
68
255
  cursor: pointer;
256
+ transition: var(--transition);
69
257
 
70
- &::after {
71
- content: '';
72
- display: flex;
258
+ &-active {
259
+ color: var(--green-light);
260
+ }
261
+ }
73
262
 
74
- height: 5px;
75
- width: 100%;
76
- margin-top: 12px;
263
+ &__line {
264
+ position: absolute;
265
+ left: 0;
266
+ bottom: 0;
77
267
 
78
- border-radius: 5px;
268
+ height: var(--tab-line-height);
269
+ width: 100%;
270
+ }
79
271
 
80
- background: var(--green-light);
81
- opacity: 0;
82
- }
272
+ &__thumb {
273
+ position: absolute;
274
+
275
+ height: 100%;
83
276
 
84
- &-active {
85
- color: var(--green-light);
277
+ border-radius: 5px;
86
278
 
87
- &::after {
88
- opacity: 1;
89
- }
90
- }
279
+ background: var(--green-light);
280
+
281
+ transition: var(--transition);
282
+
283
+ pointer-events: none;
91
284
  }
92
285
  }
93
286
  </style>
@@ -39,7 +39,7 @@ export default {
39
39
  type: String,
40
40
 
41
41
  default: 'top',
42
- validator: getPropValidator('CTooltip', 'position', ['top', 'bottom']),
42
+ validator: getPropValidator('CTooltip', 'position', ['top', 'top_left', 'top_right', 'bottom', 'bottom_left', 'bottom_right']),
43
43
  },
44
44
 
45
45
  interactive: {
@@ -110,41 +110,112 @@ export default {
110
110
  </script>
111
111
 
112
112
  <style lang="scss">
113
+ @mixin top {
114
+ --translate-y: -10px;
115
+
116
+ // arrow
117
+ --arrow-translate-y: -6px;
118
+
119
+ .c-tooltip__content_wrap {
120
+ bottom: 100%;
121
+ }
122
+
123
+ .c-tooltip__arrow {
124
+ --rotate: 45deg;
125
+
126
+ top: 100%;
127
+ }
128
+ }
129
+
130
+ @mixin bottom {
131
+ --translate-y: 10px;
132
+
133
+ // arrow
134
+ --arrow-translate-y: 6px;
135
+
136
+ .c-tooltip__content_wrap {
137
+ top: 100%;
138
+ }
139
+
140
+ .c-tooltip__arrow {
141
+ --rotate: -135deg;
142
+
143
+ bottom: 100%;
144
+ }
145
+ }
146
+
147
+ @mixin left {
148
+ --translate-x: 0%;
149
+ --left: 0%;
150
+ --right: auto;
151
+
152
+ // arrow
153
+ --arrow-translate-x: 5px;
154
+ --arrow-left: 0%;
155
+ --arrow-right: auto;
156
+ }
157
+
158
+ @mixin right {
159
+ --translate-x: 0%;
160
+ --left: auto;
161
+ --right: 0%;
162
+
163
+ // arrow
164
+ --arrow-translate-x: -5px;
165
+ --arrow-left: auto;
166
+ --arrow-right: 0%;
167
+ }
168
+
113
169
  .c-tooltip {
170
+ --translate-x: -50%;
171
+ --left: 50%;
172
+ --right: auto;
173
+
174
+ // arrow
175
+ --arrow-translate-x: -50%;
176
+ --arrow-left: 50%;
177
+ --arrow-right: auto;
178
+
114
179
  --arrow-size: 12px;
115
180
 
116
181
  position: relative;
117
182
 
118
183
  font-size: 12px;
119
184
 
185
+ button,
186
+ input,
187
+ div,
188
+ a {
189
+ font-family: inherit;
190
+ font-weight: inherit;
191
+ }
192
+
120
193
  // props.position
121
194
  &.top {
122
- .c-tooltip__content_wrap{
123
- --translate-y: -10px;
124
- --arrow-translate-y: -6px;
125
-
126
- bottom: 100%;
195
+ @include top();
196
+
197
+ &_left {
198
+ @include top();
199
+ @include left();
127
200
  }
128
201
 
129
- .c-tooltip__arrow {
130
- --rotate: 45deg;
131
-
132
- top: 100%;
202
+ &_right {
203
+ @include top();
204
+ @include right();
133
205
  }
134
206
  }
135
207
 
136
208
  &.bottom {
137
- .c-tooltip__content_wrap {
138
- --translate-y: 10px;
139
- --arrow-translate-y: 6px;
209
+ @include bottom();
140
210
 
141
- top: 100%;
211
+ &_left {
212
+ @include bottom();
213
+ @include left();
142
214
  }
143
215
 
144
- .c-tooltip__arrow {
145
- --rotate: -135deg;
146
-
147
- bottom: 100%;
216
+ &_right {
217
+ @include bottom();
218
+ @include right();
148
219
  }
149
220
  }
150
221
  // ./props.position
@@ -180,8 +251,12 @@ export default {
180
251
 
181
252
  &_wrap {
182
253
  position: absolute;
183
- left: 50%;
184
- transform: translate(-50%, var(--translate-y));
254
+ left: var(--left);
255
+ right: var(--right);
256
+ transform: translate(var(--translate-x), var(--translate-y));
257
+ z-index: 10;
258
+
259
+ min-width: 100%;
185
260
 
186
261
  border: 1px solid var(--green-medium);
187
262
  border-radius: 6px;
@@ -196,8 +271,10 @@ export default {
196
271
 
197
272
  &__arrow {
198
273
  position: absolute;
199
- left: 50%;
200
- transform: translate(-50%, var(--arrow-translate-y)) rotate(var(--rotate));
274
+ left: var(--arrow-left);
275
+ right: var(--arrow-right);
276
+
277
+ transform: translate(var(--arrow-translate-x), var(--arrow-translate-y)) rotate(var(--rotate));
201
278
 
202
279
  width: var(--arrow-size);
203
280
  height: var(--arrow-size);