@ecored-sena/base-kit 0.0.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.
Files changed (67) hide show
  1. package/README.md +1 -0
  2. package/package.json +49 -0
  3. package/plugin/components/AccordionRED.vue +78 -0
  4. package/plugin/components/AcordionA.vue +78 -0
  5. package/plugin/components/Audio.vue +20 -0
  6. package/plugin/components/BannerHero.vue +104 -0
  7. package/plugin/components/CarouselCard.vue +70 -0
  8. package/plugin/components/CarouselRED.vue +65 -0
  9. package/plugin/components/Complementario.vue +81 -0
  10. package/plugin/components/Creditos.vue +101 -0
  11. package/plugin/components/Dialogo.vue +30 -0
  12. package/plugin/components/DialogoActividad.vue +274 -0
  13. package/plugin/components/DialogoBurbuja.vue +46 -0
  14. package/plugin/components/DialogoChat.vue +88 -0
  15. package/plugin/components/Footer.vue +42 -0
  16. package/plugin/components/GlobalComponents.js +39 -0
  17. package/plugin/components/Glosario.vue +100 -0
  18. package/plugin/components/ImagenInfografica.vue +100 -0
  19. package/plugin/components/ImagenInfograficaB.vue +68 -0
  20. package/plugin/components/Inicio.vue +128 -0
  21. package/plugin/components/LineaTiempoA.vue +30 -0
  22. package/plugin/components/LineaTiempoB.vue +36 -0
  23. package/plugin/components/LineaTiempoC.vue +95 -0
  24. package/plugin/components/LineaTiempoD.vue +51 -0
  25. package/plugin/components/LineaTiempoE.vue +25 -0
  26. package/plugin/components/ModalA.vue +22 -0
  27. package/plugin/components/PasosA.vue +59 -0
  28. package/plugin/components/PasosB.vue +90 -0
  29. package/plugin/components/Referencias.vue +45 -0
  30. package/plugin/components/ScrollHorizontal.vue +105 -0
  31. package/plugin/components/Separador.vue +12 -0
  32. package/plugin/components/SlyderA.vue +65 -0
  33. package/plugin/components/SlyderB.vue +48 -0
  34. package/plugin/components/SlyderC.vue +53 -0
  35. package/plugin/components/SlyderD.vue +50 -0
  36. package/plugin/components/SlyderE.vue +58 -0
  37. package/plugin/components/SlyderF.vue +141 -0
  38. package/plugin/components/TabsA.vue +44 -0
  39. package/plugin/components/TabsB.vue +40 -0
  40. package/plugin/components/TabsC.vue +39 -0
  41. package/plugin/components/TarjetaAudio.vue +65 -0
  42. package/plugin/components/TimeLineRED.vue +51 -0
  43. package/plugin/components/actividad/ActividadController.vue +34 -0
  44. package/plugin/components/actividad/actividadCompletar/ActividadCompletar.vue +283 -0
  45. package/plugin/components/actividad/actividadCompletar/ActividadCompletarFooter.vue +63 -0
  46. package/plugin/components/actividad/actividadCompletar/ActividadParrafo.vue +218 -0
  47. package/plugin/components/actividad/actividadCompletar/ActividadResultados.vue +215 -0
  48. package/plugin/components/actividad/actividadCuestionario/Actividad.vue +222 -0
  49. package/plugin/components/actividad/actividadCuestionario/ActividadBarraAvance.vue +116 -0
  50. package/plugin/components/actividad/actividadCuestionario/ActividadPregunta.vue +146 -0
  51. package/plugin/components/actividad/actividadCuestionario/ActividadResultados.vue +215 -0
  52. package/plugin/components/audioMixins.js +73 -0
  53. package/plugin/components/componentSlotMixins.js +87 -0
  54. package/plugin/components/dialogoMixins.js +28 -0
  55. package/plugin/components/globalMixins.js +11 -0
  56. package/plugin/components/plantilla/Accesibilidad.vue +101 -0
  57. package/plugin/components/plantilla/AsideMenu.vue +242 -0
  58. package/plugin/components/plantilla/BannerInterno.vue +66 -0
  59. package/plugin/components/plantilla/BannerPrincipal.vue +104 -0
  60. package/plugin/components/plantilla/BarraAvance.vue +379 -0
  61. package/plugin/components/plantilla/Curso.vue +12 -0
  62. package/plugin/components/plantilla/Footer.vue +42 -0
  63. package/plugin/components/plantilla/Header.vue +152 -0
  64. package/plugin/components/plantilla/ScrollHorizontal.vue +105 -0
  65. package/plugin/components/plantillaMixins.js +34 -0
  66. package/plugin/components/slyderMixins.js +18 -0
  67. package/plugin/plugin.js +49 -0
@@ -0,0 +1,379 @@
1
+ <template lang="pug">
2
+ .barra-avance(:class="[showBarra ? 'barra-avance--open' : 'barra-avance--close']")
3
+
4
+ router-link.boton.barra-avance__boton--regresar(
5
+ :class="[!controlLinks.back.name && 'barra-avance__boton--disable']"
6
+ :to="{name: controlLinks.back.name, hash: controlLinks.back.hash ? `#${controlLinks.back.hash}` : ''}"
7
+ )
8
+ i.me-2(class="fas fa-angle-left")
9
+ span Regresar
10
+
11
+ //- .barra-avance__barra
12
+ //- .barra-avance__barra--blanca
13
+ //- .barra-avance__barra--amarilla
14
+
15
+ router-link.boton(
16
+ :class="[!controlLinks.next.name && 'barra-avance__boton--disable']"
17
+ :to="{name: controlLinks.next.name, hash: controlLinks.next.hash ? `#${controlLinks.next.hash}` : ''}"
18
+ )
19
+ span.me-2 Continuar
20
+ i(class="fas fa-angle-right")
21
+
22
+ </template>
23
+
24
+ <script>
25
+ export default {
26
+ name: 'BarraAvance',
27
+ data: () => ({
28
+ cursoSelection: null,
29
+ idSelecctionArr: [],
30
+ }),
31
+ computed: {
32
+ menuData() {
33
+ return this.$config.menuPrincipal.menu
34
+ },
35
+ showBarra() {
36
+ const enIntro = this.$route.fullPath.includes('/introduccion')
37
+ const enCurso = this.$route.fullPath.includes('/curso')
38
+ const haveControls =
39
+ (this.controlLinks.next && this.controlLinks.next.name) ||
40
+ (this.controlLinks.back && this.controlLinks.back.name)
41
+ return !this.menuOpen && (enIntro || enCurso) && haveControls
42
+ },
43
+ // controlLinks() {
44
+ // const menuObject = this.menuData.find(
45
+ // item => item.nombreRuta === this.$route.name,
46
+ // )
47
+ // if (this.$route.name === 'introduccion') {
48
+ // // SI ESTOY EN INTRODUCCION
49
+ // const tema1 = this.menuData.find(item => item.nombreRuta === 'tema1')
50
+ // return {
51
+ // next: {
52
+ // name: tema1.nombreRuta,
53
+ // hash: '',
54
+ // },
55
+ // back: {
56
+ // name: '',
57
+ // hash: '',
58
+ // },
59
+ // }
60
+ // } else if (!menuObject) {
61
+ // // SI NO ESTOY EN UN TEMA O SI NO HAY SUBTEMAS --ERROR FALLBACK
62
+ // return {
63
+ // next: {
64
+ // name: '',
65
+ // hash: '',
66
+ // },
67
+ // back: {
68
+ // name: '',
69
+ // hash: '',
70
+ // },
71
+ // }
72
+ // } else {
73
+ // // SI ESTOY EN UN TEMA
74
+
75
+ // let routeObj = {}
76
+ // const idxOfMenuItem = this.menuData
77
+ // .map(item => item.nombreRuta)
78
+ // .indexOf(this.$route.name)
79
+
80
+ // if (menuObject.subMenu) {
81
+ // // MENU ITEM TIENE SUBMENU
82
+ // const idxCurrentHash = menuObject.subMenu
83
+ // .map(item => item.hash)
84
+ // .indexOf(this.$route.hash.replace('#', ''))
85
+
86
+ // // back logic
87
+ // if (idxCurrentHash <= 0) {
88
+ // // SI NO HAY SELECCIONADO UN HASH O ESTA SELECCIONADO EL PRIMERO
89
+ // const backMenuItem = this.menuData[idxOfMenuItem - 1]
90
+
91
+ // const backIsTheme =
92
+ // backMenuItem && backMenuItem.nombreRuta.includes('tema')
93
+ // const backIsIntro =
94
+ // backMenuItem && backMenuItem.nombreRuta.includes('introduccion')
95
+
96
+ // if (backIsTheme || backIsIntro) {
97
+ // // si el anterior objeto es un tema o introduccion
98
+ // routeObj.back = {
99
+ // name: backMenuItem.nombreRuta,
100
+ // hash: '',
101
+ // }
102
+ // } else {
103
+ // // si el objeto anterior no es tema o introduccion
104
+ // routeObj.back = {
105
+ // name: '',
106
+ // hash: '',
107
+ // }
108
+ // }
109
+ // } else if (idxCurrentHash === menuObject.subMenu.length - 1) {
110
+ // // SI EL ULTIMO HASH ESTA SELECCIONADO
111
+ // const backHash = menuObject.subMenu[idxCurrentHash - 1].hash
112
+
113
+ // routeObj.back = {
114
+ // name: this.$route.name,
115
+ // hash: backHash,
116
+ // }
117
+ // } else {
118
+ // // SI ESTOY ENMEDIO DE LOS HASH
119
+ // routeObj.back = {
120
+ // name: this.$route.name,
121
+ // hash: menuObject.subMenu[idxCurrentHash - 1].hash,
122
+ // }
123
+ // }
124
+
125
+ // // Next Logic
126
+ // if (idxCurrentHash === menuObject.subMenu.length - 1) {
127
+ // // es el ultimo hash seleccionado
128
+ // const nextMenuItem = this.menuData[idxOfMenuItem + 1]
129
+
130
+ // const nextIsTheme =
131
+ // nextMenuItem && nextMenuItem.nombreRuta.includes('tema')
132
+
133
+ // if (nextIsTheme) {
134
+ // // el siguiente objeto del menu es tema
135
+ // routeObj.next = {
136
+ // name: nextMenuItem.nombreRuta,
137
+ // hash: '',
138
+ // }
139
+ // } else {
140
+ // // si es el ultimo tema
141
+ // routeObj.next = {
142
+ // name: '',
143
+ // hash: '',
144
+ // }
145
+ // }
146
+ // } else {
147
+ // // no estoy en el ultimo hash
148
+ // const nextSubMenuItem = menuObject.subMenu[idxCurrentHash + 1]
149
+ // const nextHash = nextSubMenuItem.hash
150
+ // routeObj.next = {
151
+ // name: this.$route.name,
152
+ // hash: nextHash,
153
+ // }
154
+ // }
155
+ // } else {
156
+ // // MENU ITEM NO TIENE SUBMENU
157
+
158
+ // // Back logic
159
+ // const backMenuItem = this.menuData[idxOfMenuItem - 1]
160
+
161
+ // const backIsTheme =
162
+ // backMenuItem && backMenuItem.nombreRuta.includes('tema')
163
+ // const backIsIntro =
164
+ // backMenuItem && backMenuItem.nombreRuta.includes('introduccion')
165
+
166
+ // if (backIsTheme || backIsIntro) {
167
+ // // si el anterior objeto es un tema o introduccion
168
+ // routeObj.back = {
169
+ // name: backMenuItem.nombreRuta,
170
+ // hash: '',
171
+ // }
172
+ // } else {
173
+ // // si el objeto anterior no es tema o introduccion
174
+ // routeObj.back = {
175
+ // name: '',
176
+ // hash: '',
177
+ // }
178
+ // }
179
+
180
+ // // Next logic
181
+ // const nextMenuItem = this.menuData[idxOfMenuItem + 1]
182
+
183
+ // const nextIsTheme =
184
+ // nextMenuItem && nextMenuItem.nombreRuta.includes('tema')
185
+
186
+ // if (nextIsTheme) {
187
+ // // el siguiente objeto del menu es tema
188
+ // routeObj.next = {
189
+ // name: nextMenuItem.nombreRuta,
190
+ // hash: '',
191
+ // }
192
+ // } else {
193
+ // // si es el ultimo tema
194
+ // routeObj.next = {
195
+ // name: '',
196
+ // hash: '',
197
+ // }
198
+ // }
199
+ // }
200
+ // return routeObj
201
+ // }
202
+ // },
203
+ controlLinks() {
204
+ const menuObject = this.menuData.find(
205
+ item => item.nombreRuta === this.$route.name,
206
+ )
207
+ if (this.$route.name === 'introduccion') {
208
+ // SI ESTOY EN INTRODUCCION
209
+ const tema1 = this.menuData.find(item => item.nombreRuta === 'tema1')
210
+ return {
211
+ next: {
212
+ name: tema1.nombreRuta,
213
+ hash: '',
214
+ },
215
+ back: {
216
+ name: '',
217
+ hash: '',
218
+ },
219
+ }
220
+ } else if (!menuObject) {
221
+ // SI NO ESTOY EN UN TEMA O SI NO HAY SUBTEMAS --ERROR FALLBACK
222
+ return {
223
+ next: {
224
+ name: '',
225
+ hash: '',
226
+ },
227
+ back: {
228
+ name: '',
229
+ hash: '',
230
+ },
231
+ }
232
+ } else {
233
+ let routeObj = {}
234
+ const idxOfMenuItem = this.menuData
235
+ .map(item => item.nombreRuta)
236
+ .indexOf(this.$route.name)
237
+
238
+ // Back logic
239
+ const backMenuItem = this.menuData[idxOfMenuItem - 1]
240
+
241
+ const backIsTheme =
242
+ backMenuItem && backMenuItem.nombreRuta.includes('tema')
243
+ const backIsIntro =
244
+ backMenuItem && backMenuItem.nombreRuta.includes('introduccion')
245
+
246
+ if (backIsTheme || backIsIntro) {
247
+ // si el anterior objeto es un tema o introduccion
248
+ routeObj.back = {
249
+ name: backMenuItem.nombreRuta,
250
+ hash: '',
251
+ }
252
+ } else {
253
+ // si el objeto anterior no es tema o introduccion
254
+ routeObj.back = {
255
+ name: '',
256
+ hash: '',
257
+ }
258
+ }
259
+
260
+ // Next logic
261
+ const nextMenuItem = this.menuData[idxOfMenuItem + 1]
262
+
263
+ const nextIsTheme =
264
+ nextMenuItem && nextMenuItem.nombreRuta.includes('tema')
265
+
266
+ if (nextIsTheme) {
267
+ // el siguiente objeto del menu es tema
268
+ routeObj.next = {
269
+ name: nextMenuItem.nombreRuta,
270
+ hash: '',
271
+ }
272
+ } else {
273
+ // si es el ultimo tema
274
+ routeObj.next = {
275
+ name: '',
276
+ hash: '',
277
+ }
278
+ }
279
+ return routeObj
280
+ }
281
+ },
282
+ menuOpen() {
283
+ return this.$store.getters.isMenuOpen
284
+ },
285
+ },
286
+ // created() {
287
+ // document.addEventListener('scroll', this.trackIds)
288
+ // },
289
+ // mounted() {
290
+ // this.cursoSelection = document.querySelector('#curso')
291
+ // const subMenuSelected = this.menuData.find(
292
+ // item => item.nombreRuta === this.$route.name,
293
+ // ).subMenu
294
+ // this.idSelecctionArr = subMenuSelected
295
+ // ? subMenuSelected.map(item => document.querySelector(`#${item.hash}`))
296
+ // : []
297
+ // },
298
+ // methods: {
299
+ // trackIds() {
300
+ // if (!this.idSelecctionArr.length) return
301
+ // this.idSelecctionArr.forEach(item => {
302
+ // console.log(item.scrollTop)
303
+ // })
304
+ // const mao = document.querySelector('#t_1_5')
305
+ // console.log(this.cursoSelection.clientHeight)
306
+ // console.log(window.innerHeight, window.scrollY, mao.offsetTop)
307
+ // },
308
+ // },
309
+ }
310
+ </script>
311
+
312
+ <style lang="sass">
313
+ .barra-avance
314
+ display: flex
315
+ align-items: center
316
+ justify-content: space-between
317
+ position: fixed
318
+ bottom: 0
319
+ left: 0
320
+ width: 100%
321
+ padding: 10px
322
+ background-color: $color-sistema-e
323
+ transition: transform 0.5s ease-in-out
324
+ z-index: 100000
325
+
326
+ &__barra
327
+ margin: 0 20px
328
+ flex: 1
329
+ position: relative
330
+ max-width: 800px
331
+
332
+ &--blanca, &--amarilla
333
+ height: 4px
334
+
335
+ &:before, &:after
336
+ content: ''
337
+ display: block
338
+ width: 10px
339
+ height: 10px
340
+ border-radius: 50%
341
+ position: absolute
342
+ top: 50%
343
+
344
+ &:before
345
+ left: 0
346
+ transform: translate(-50%,-50%)
347
+
348
+ &:after
349
+ right: 0
350
+ transform: translate(50%,-50%)
351
+
352
+ &--blanca
353
+ background-color: $white
354
+ &:before, &:after
355
+ background-color: $white
356
+
357
+ &--amarilla
358
+ position: absolute
359
+ width: 100%
360
+ top: 0
361
+ background-color: $color-acento-botones
362
+ &:before, &:after
363
+ background-color: $color-acento-botones
364
+
365
+ &__boton
366
+ &--regresar
367
+ background-color: $color-sistema-c
368
+ span
369
+ color: $color-sistema-a !important
370
+ &--disable
371
+ opacity: 0
372
+ pointer-events: none
373
+
374
+ &--open
375
+ transform: translateY(0)
376
+
377
+ &--close
378
+ transform: translateY(100%)
379
+ </style>
@@ -0,0 +1,12 @@
1
+ <template lang="pug">
2
+ #curso.curso
3
+ router-view
4
+ </template>
5
+
6
+ <script>
7
+ export default {
8
+ name: 'Curso',
9
+ }
10
+ </script>
11
+
12
+ <style lang="sass"></style>
@@ -0,0 +1,42 @@
1
+ <template lang="pug">
2
+ footer.container.footer.tarjeta.p-3.px-sm-5.py-sm-4(:class="[allRound && 'footer__all-round']")
3
+ .row.align-items-center.justify-content-center
4
+ .col-auto.mb-2.mb-sm-0
5
+ img(src="@/assets/bullets/cc.svg")
6
+ .col-12.col-sm
7
+ p.mb-2.text-small Este material puede ser distribuido, copiado y exhibido por terceros si se muestra en los créditos. No se puede obtener ningún beneficio comercial y las obras derivadas tienen que estar bajo los mismos términos de la licencia que el trabajo original.
8
+ p.mb-0.text-small Base v{{versiones.base}} - Paquete v{{versiones.pkg}}
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ name: 'Footer',
14
+ props: {
15
+ allRound: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ },
20
+ computed: {
21
+ versiones() {
22
+ return {
23
+ base: this.$package.version,
24
+ pkg: this.$package.dependencies['ecored-base-pkg'],
25
+ }
26
+ },
27
+ },
28
+ }
29
+ </script>
30
+
31
+ <style lang="sass">
32
+ .footer
33
+ background-color: $color-sistema-d
34
+ border-bottom-right-radius: 0 !important
35
+ border-bottom-left-radius: 0 !important
36
+ &__all-round
37
+ border-bottom-right-radius: 20px !important
38
+ border-bottom-left-radius: 20px !important
39
+ p
40
+ color: $color-sistema-b
41
+ line-height: 1.2em
42
+ </style>
@@ -0,0 +1,152 @@
1
+ <template lang="pug">
2
+ header.header.container-fluid
3
+ .row.align-items-center.justify-content-between
4
+ .col.col-sm-auto.d-flex.align-items-center.justify-content-between.justify-content-sm-start
5
+
6
+ .header__menu.me-4.me-sm-5(v-if="$route.name != 'inicio'" @click="toggleMenu")
7
+ .header__menu__btn(:class="{'header__menu__btn--open': menuOpen}")
8
+ .line-2
9
+ .line-1
10
+ .line-3
11
+ span MENÚ
12
+
13
+ img.header__logo.me-4.me-sm-5(src="@/assets/logos/logo-sena.svg")
14
+
15
+ .d-none.d-md-flex.align-items-center(v-if="isInicio")
16
+ a(href="#contenidos").me-5 Contenidos
17
+
18
+ .header__componente-formativo(v-else)
19
+ span(v-html="globalData.Name")
20
+
21
+ .col-auto(v-if="isInicio")
22
+ router-link.boton(:to="{name: iniciarLnk.nombreRuta }")
23
+ span.me-1 Ver contenido
24
+ i(class="fas fa-angle-right")
25
+
26
+ </template>
27
+
28
+ <script>
29
+ import plantillaMixins from '../plantillaMixins'
30
+ export default {
31
+ name: 'Header',
32
+ mixins: [plantillaMixins],
33
+ computed: {
34
+ globalData() {
35
+ return this.$config && this.$config.global
36
+ },
37
+ isInicio() {
38
+ return this.$route.name === 'inicio'
39
+ },
40
+ menuOpen() {
41
+ return this.$store.getters.isMenuOpen
42
+ },
43
+ },
44
+ methods: {
45
+ toggleMenu() {
46
+ this.$store.dispatch('toggleMenu', !this.menuOpen)
47
+ },
48
+ },
49
+ }
50
+ </script>
51
+
52
+ <style lang="sass" scoped>
53
+ .header
54
+ position: sticky
55
+ top: 0
56
+ padding-top: 10px
57
+ padding-bottom: 10px
58
+ background-color: $white
59
+ z-index: 10010
60
+ line-height: 1.1em
61
+ &__logo
62
+ width: 50px
63
+ &__componente-formativo
64
+ @media (max-width: $bp-max-xs)
65
+ font-size: 0.8em
66
+
67
+
68
+ .header__menu
69
+ cursor: pointer
70
+ span
71
+ font-size: 0.7em
72
+ display: block
73
+ line-height: 1em
74
+ text-align: center
75
+ color: $color-sistema-a
76
+ &__btn
77
+ width: 30px
78
+ height: 30px
79
+ position: relative
80
+ margin-bottom: 4px
81
+ .line-1,.line-2,.line-3
82
+ height: 4px
83
+ width: 30px
84
+ background-color: $color-sistema-a
85
+ transform-origin: center center
86
+ position: absolute
87
+ left: 0
88
+ border-radius: 2px
89
+ .line-1
90
+ top: 4px
91
+ animation: line-1-inactive 0.5s ease-in-out forwards
92
+ .line-2
93
+ top: 13px
94
+ animation: line-2-inactive 0.5s ease-in-out forwards
95
+ .line-3
96
+ top: 22px
97
+ animation: line-3-inactive 0.5s ease-in-out forwards
98
+ &:hover
99
+ cursor: pointer
100
+
101
+ &--open
102
+ .line-1
103
+ animation: line-1-active 0.5s ease-in-out forwards
104
+ .line-2
105
+ animation: line-2-active 0.5s ease-in-out forwards
106
+ .line-3
107
+ animation: line-3-active 0.5s ease-in-out forwards
108
+
109
+ @keyframes line-1-active
110
+ 0%
111
+ transform: translate(0, 0) rotate(0)
112
+ 50%
113
+ transform: translate(0, 9px) rotate(0)
114
+ 100%
115
+ transform: translate(0, 9px) rotate(45deg)
116
+
117
+ @keyframes line-2-active
118
+ 0%
119
+ transform: scale(1)
120
+ 100%
121
+ transform: scale(0)
122
+
123
+ @keyframes line-3-active
124
+ 0%
125
+ transform: translate(0, 0) rotate(0)
126
+ 50%
127
+ transform: translate(0, -9px) rotate(0)
128
+ 100%
129
+ transform: translate(0, -9px) rotate(-45deg)
130
+
131
+ @keyframes line-1-inactive
132
+ 0%
133
+ transform: translate(0, 9px) rotate(45deg)
134
+ 50%
135
+ transform: translate(0, 9px) rotate(0)
136
+ 100%
137
+ transform: translate(0, 0) rotate(0)
138
+
139
+ @keyframes line-2-inactive
140
+ 0%
141
+ transform: scale(0)
142
+ 100%
143
+ transform: scale(1)
144
+
145
+ @keyframes line-3-inactive
146
+ 0%
147
+ transform: translate(0, -9px) rotate(-45deg)
148
+ 50%
149
+ transform: translate(0, -9px) rotate(0)
150
+ 100%
151
+ transform: translate(0, 0) rotate(0)
152
+ </style>
@@ -0,0 +1,105 @@
1
+ <template lang="pug">
2
+ .horizontal-scroll__wrapper(ref="hContainer")
3
+ .horizontal-scroll(
4
+ :class="[{'horizontal-scroll--item-fw':itemFullWidth},{'row':row}]"
5
+ :style="[{transform: `translate(${scrollVal}px,0px)`}]"
6
+ )
7
+ slot
8
+ </template>
9
+
10
+ <script>
11
+ export default {
12
+ name: 'ScrollHorizontal',
13
+ props: {
14
+ selectedId: {
15
+ type: String,
16
+ default: '',
17
+ },
18
+ itemFullWidth: {
19
+ type: Boolean,
20
+ default: false,
21
+ },
22
+ row: {
23
+ type: Boolean,
24
+ default: false,
25
+ },
26
+ },
27
+ data() {
28
+ return {
29
+ scrollVal: 0,
30
+ ids: [],
31
+ }
32
+ },
33
+ watch: {
34
+ selectedId(newVal) {
35
+ if (newVal.length) {
36
+ this.scroll()
37
+ }
38
+ },
39
+ },
40
+ mounted() {
41
+ this.getCords()
42
+ this.scroll()
43
+ window.addEventListener('resize', this.scroll)
44
+ },
45
+ updated() {
46
+ this.getCords()
47
+ },
48
+ beforeDestroy() {
49
+ window.removeEventListener('resize', this.scroll)
50
+ },
51
+ methods: {
52
+ scroll() {
53
+ const selectedElementId = this.ids.find(
54
+ item => item.id === this.selectedId,
55
+ )?.id
56
+ const selectedElement = document.getElementById(selectedElementId)
57
+ if (
58
+ !Object.keys(this.$slots.default).length ||
59
+ !this.selectedId.length ||
60
+ selectedElement === null
61
+ )
62
+ return
63
+ const container = this.$refs.hContainer
64
+ const scrollContentTotalWidth =
65
+ selectedElement.offsetWidth * this.ids.length
66
+ let newScrollVal = selectedElement.offsetLeft
67
+ const elementsFitInContainer =
68
+ container.offsetWidth / selectedElement.offsetWidth
69
+ if (
70
+ elementsFitInContainer > 1 &&
71
+ scrollContentTotalWidth - newScrollVal < container.offsetWidth
72
+ ) {
73
+ newScrollVal = scrollContentTotalWidth - container.offsetWidth
74
+ }
75
+ this.scrollVal = this.ids.length === 1 ? 0 : -newScrollVal
76
+ },
77
+ getCords() {
78
+ if (this.$slots.default) {
79
+ this.ids = this.$slots.default.map(element => ({
80
+ id: element.elm.id,
81
+ key: element.key,
82
+ }))
83
+ }
84
+ },
85
+ },
86
+ }
87
+ </script>
88
+
89
+ <style lang="sass" scoped>
90
+ .horizontal-scroll__wrapper
91
+ overflow: hidden
92
+ .horizontal-scroll
93
+ display: flex
94
+ transition: transform 0.5s ease-in-out
95
+ align-items: center
96
+ flex-wrap: nowrap
97
+ &:not(.row)
98
+ width: 100%
99
+ &--item-fw
100
+ & ::v-deep > div
101
+ flex-grow: 0
102
+ flex-shrink: 0
103
+ width: 100%
104
+ margin: 0 !important
105
+ </style>