1
1
<template >
2
- <div class =" past-prod-list" >
2
+ <simplebar ref = " pastProdList " class =" past-prod-list" >
3
3
<VCard
4
4
:href =" '/productions/' + prod.id"
5
5
v-for =" prod in productions"
9
9
boilerplate
10
10
>
11
11
<VImg :src =" prod.thumbnail.link" :title =" prod.thumbnail.name" height =" 200px" />
12
- <VCardTitle >{{ prod.name }}</VCardTitle >
13
- <VCardSubtitle >{{ prod.description }}</VCardSubtitle >
12
+ <div class =" prod-card-text-wrapper" >
13
+ <VCardTitle >
14
+ {{ prod.name }}
15
+ </VCardTitle >
16
+ <VCardSubtitle >
17
+ {{ prod.description }}
18
+ </VCardSubtitle >
19
+ </div >
14
20
<VRow >
15
21
<VCol >
16
22
<VCardText class =" v-card__subtitle" >
26
32
</VCol >
27
33
</VRow >
28
34
</VCard >
29
- </div >
35
+
36
+ <VBtn
37
+ v-if =" showScrollButton"
38
+ @click =" pushLeft"
39
+ fab
40
+ dark
41
+ x-large
42
+ color =" primary"
43
+ class =" scroll-btn"
44
+ title =" Click to scroll left"
45
+ aria-label =" Click to scroll left"
46
+ >
47
+ <font-awesome-icon :icon =" ['fal','chevron-right']" size =" lg" />
48
+ </VBtn >
49
+ </simplebar >
30
50
</template >
31
51
32
52
<script >
33
53
import gql from ' graphql-tag'
34
54
import moment from ' moment'
55
+ import simplebar from ' simplebar-vue'
56
+ import ' simplebar/dist/simplebar.min.css'
35
57
36
58
export default {
37
59
name: ' RecentProductionsList' ,
60
+ components: {
61
+ simplebar
62
+ },
38
63
data () {
39
64
return {
40
- productions: []
65
+ productions: [],
66
+ showScrollButton: true
41
67
}
42
68
},
69
+ mounted () {
70
+ this .$refs .pastProdList .SimpleBar .getScrollElement ().addEventListener (' scroll' , this .handleScroll )
71
+ },
72
+ destroyed () {
73
+ this .$refs .pastProdList .SimpleBar .getScrollElement ().removeEventListener (' scroll' , this .handleScroll )
74
+ },
43
75
methods: {
44
76
getFormattedDate (production ) {
45
77
return moment (production .startTime ).format (' MMM Do YYYY' )
78
+ },
79
+ handleScroll (evt ) {
80
+ this .showScrollButton = (evt .target .scrollLeft === 0 )
81
+ },
82
+ /**
83
+ * Push this list left (or right, depending on how you think about it) one full width.
84
+ * This exists for the right-chevron button, to demonstrate that this list is scrollable.
85
+ * It scrolls in an ease-out manner one full width, or until the end of the list is hit.
86
+ */
87
+ pushLeft () {
88
+ let pxToPush = this .$refs .pastProdList .SimpleBar .getScrollElement ().offsetWidth // Scroll the width of the element
89
+ // Runs every 5ms
90
+ const interval = setInterval (() => {
91
+ const pushAmount = pxToPush / 35 // Scroll by 1/35th of the remaining amount - Creates ease-out effect
92
+ this .$refs .pastProdList .SimpleBar .getScrollElement ().scrollLeft += pushAmount
93
+
94
+ pxToPush -= pushAmount
95
+
96
+ if (pxToPush <= 1 ) { // Stop when 1 px left, with 0 it breaks as you infinitely approach 0
97
+ clearInterval (interval)
98
+ }
99
+ }, 5 )
46
100
}
47
101
},
48
102
apollo: {
@@ -61,22 +115,69 @@ export default {
61
115
</script >
62
116
63
117
<style lang="scss" scoped>
64
- /* Fix word wrapping in cards - See vuetifyjs/vuetify/issues/9130 */
65
- .v-card__text , .v-card__title {
66
- word-break : normal ;
67
- }
118
+ @use " sass:map" ;
119
+ @import " ~vuetify/src/styles/styles.sass" ;
68
120
69
121
.past-prod-list {
70
- white-space : nowrap ;
71
- overflow-x : scroll ;
122
+ position : relative ;
123
+ @media (min-device-width : 500px ) {
124
+ white-space : nowrap ;
125
+ overflow-x : scroll ;
126
+
127
+ -ms-overflow-style : none ;
128
+ & ::-webkit-scrollbar {
129
+ display : none ;
130
+ }
131
+
132
+ .past-prod-card {
133
+ margin-right : 20px ;
134
+ }
135
+ }
136
+
137
+ @media (max-device-width : 500px ) {
138
+ text-align : center ;
139
+ .past-prod-card {
140
+ text-align : initial ;
141
+ margin-bottom : 20px ;
142
+ }
143
+ .scroll-btn {
144
+ display : none ;
145
+ }
146
+ }
72
147
.past-prod-card {
73
148
display : inline-block ;
74
149
width : 300px ;
75
- margin-right : 20px ;
150
+ margin-bottom : 20px ;
76
151
}
77
152
78
153
.prod-actions {
79
154
float : right ;
80
155
}
81
156
}
157
+ .prod-card-text-wrapper {
158
+ height : 150px ;
159
+ overflow : hidden ;
160
+ text-overflow : ellipsis ;
161
+
162
+ & :before {
163
+ content :' ' ;
164
+ width :100% ;
165
+ height : 12% ;
166
+ position :absolute ;
167
+ left :0 ;
168
+ bottom : 78px ;
169
+ background :linear-gradient (transparent , map .get ($grey , " darken-3" ));
170
+ }
171
+ }
172
+ .scroll-btn {
173
+ opacity : 0.7 ;
174
+ & :hover {
175
+ opacity : 1 ;
176
+ }
177
+ position : absolute ;
178
+ z-index : 100 ;
179
+ right : 20px ;
180
+ top : 50% ;
181
+ transform : translateY (-50% );
182
+ }
82
183
</style >
0 commit comments