|
1 | 1 | <template> |
2 | 2 | <div :id="position + '-wrapper'" class="fab-wrapper" v-on-clickaway="away" |
3 | | - :style="[ pos, {zIndex: zIndex}, {position: positionType} ]"> |
| 3 | + :style="[ pos, {zIndex: zIndex}, {position: positionType} ]" |
| 4 | + :ref="fabWrapper"> |
4 | 5 | <div :id="position + '-action'" class="actions-container" :style="listPos"> |
5 | 6 | <transition name="fab-actions-appear" |
6 | 7 | :enter-active-class="transitionEnter" |
|
84 | 85 | toggle: this.startOpened, |
85 | 86 | pos: {}, |
86 | 87 | tooltipPosition: 'left', |
| 88 | + hasReachedEnd: false, |
| 89 | + fabWrapper: 'fabWrapper' |
87 | 90 | } |
88 | 91 | }, |
89 | 92 | props: { |
|
135 | 138 | toggleWhenAway: { |
136 | 139 | default: true |
137 | 140 | }, |
| 141 | + autoReverse: { |
| 142 | + default: false, |
| 143 | + } |
138 | 144 | }, |
139 | 145 | computed: { |
140 | 146 | actionIconSize() { |
|
200 | 206 | return '64px'; |
201 | 207 | } |
202 | 208 | }, |
203 | | - listPadding() { |
| 209 | + topListPadding() { |
| 210 | + switch (this.iconSize) { |
| 211 | + case 'small': |
| 212 | + return '58px'; |
| 213 | + break; |
| 214 | + case 'medium': |
| 215 | + return '74px'; |
| 216 | + break; |
| 217 | + case 'large': |
| 218 | + return '92px'; |
| 219 | + break; |
| 220 | + default: |
| 221 | + return '74px'; |
| 222 | + } |
| 223 | + }, |
| 224 | + bottomListPadding() { |
| 225 | + // mainIconSize + (paddingAmount) / 2 + 20 |
204 | 226 | switch (this.iconSize) { |
205 | 227 | case 'small': |
206 | | - return '72px'; |
| 228 | + return '48px'; |
207 | 229 | break; |
208 | 230 | case 'medium': |
209 | | - return '88px'; |
| 231 | + return '52px'; |
210 | 232 | break; |
211 | 233 | case 'large': |
212 | | - return '106px'; |
| 234 | + return '58px'; |
213 | 235 | break; |
214 | 236 | default: |
215 | | - return '88px'; |
| 237 | + return '52px'; |
216 | 238 | } |
217 | 239 | }, |
218 | 240 | listPos() { |
219 | 241 | if (this.position === 'top-right' || this.position === 'top-left') { |
220 | 242 | return { |
221 | | - top: this.revertDirection ? 'unset' : '-20px', |
222 | | - bottom: this.revertDirection ? this.listPadding : 'unset', |
223 | | - paddingTop: '20px', |
224 | | - position: this.revertDirection ? 'absolute' : 'relative', |
| 243 | + top: this.allowRevertDirection ? 'unset' : this.topListPadding, |
| 244 | + bottom: this.allowRevertDirection ? this.topListPadding : 'unset', |
| 245 | + position: this.allowRevertDirection ? 'absolute' : 'absolute', |
225 | 246 | width: this.listSize, |
226 | 247 | } |
227 | 248 | } |
228 | 249 | return { |
229 | | - bottom: this.revertDirection ? 'unset' : '-20px', |
230 | | - top: this.revertDirection ? '40px' : 'unset', |
231 | | - paddingBottom: '20px', |
232 | | - position: this.revertDirection ? 'absolute' : 'relative', |
| 250 | + bottom: this.allowRevertDirection ? 'unset' : this.topListPadding, |
| 251 | + top: this.allowRevertDirection ? this.topListPadding : 'unset', |
| 252 | + position: this.allowRevertDirection ? 'absolute' : 'absolute', |
233 | 253 | width: this.listSize |
234 | 254 | } |
235 | 255 | }, |
|
244 | 264 | animation() { |
245 | 265 | if (this.position === 'top-right' || this.position === 'top-left') { |
246 | 266 | return { |
247 | | - enter: this.revertDirection ? 'animated quick fadeInUp' : 'animated quick fadeInDown', |
248 | | - leave: this.revertDirection ? 'animated quick fadeOutDown' : 'animated quick fadeOutUp' |
| 267 | + enter: this.allowRevertDirection ? 'animated quick fadeInUp' : 'animated quick fadeInDown', |
| 268 | + leave: this.allowRevertDirection ? 'animated quick fadeOutDown' : 'animated quick fadeOutUp' |
249 | 269 | }; |
250 | 270 | } else if (this.position === 'bottom-right' || this.position === 'bottom-left') { |
251 | 271 | return { |
252 | | - enter: this.revertDirection ? 'animated quick fadeInDown' : 'animated quick fadeInUp', |
253 | | - leave: this.revertDirection ? 'animated quick fadeOutUp' : 'animated quick fadeOutDown' |
| 272 | + enter: this.allowRevertDirection ? 'animated quick fadeInDown' : 'animated quick fadeInUp', |
| 273 | + leave: this.allowRevertDirection ? 'animated quick fadeOutUp' : 'animated quick fadeOutDown' |
254 | 274 | }; |
255 | 275 | } else { |
256 | 276 | return { |
257 | | - enter: this.revertDirection ? 'animated fadeInDown' : 'animated fadeInUp', |
258 | | - leave: this.revertDirection ? 'animated fadeOutUp' : 'animated fadeOutDown' |
| 277 | + enter: this.allowRevertDirection ? 'animated fadeInDown' : 'animated fadeInUp', |
| 278 | + leave: this.allowRevertDirection ? 'animated fadeOutUp' : 'animated fadeOutDown' |
259 | 279 | }; |
260 | 280 | } |
261 | 281 | }, |
|
266 | 286 | } |
267 | 287 |
|
268 | 288 | return 'hover'; |
| 289 | + }, |
| 290 | + allowRevertDirection() { |
| 291 | + return this.revertDirection || |
| 292 | + (this.positionType === 'absolute' && this.autoReverse && this.hasReachedEnd); |
269 | 293 | } |
270 | 294 | }, |
271 | 295 | methods: { |
|
332 | 356 | }, |
333 | 357 | afterActionsTransitionEnter() { |
334 | 358 | this.showTooltip(); |
| 359 | + }, |
| 360 | + setHasReachedEnd(hasReachedEnd) { |
| 361 | + if (this.hasReachedEnd !== hasReachedEnd) { |
| 362 | + this.hasReachedEnd = hasReachedEnd; |
| 363 | + } |
| 364 | + }, |
| 365 | + handleScroll(event) { |
| 366 | + const bounding = this.$refs.fabWrapper.getBoundingClientRect(); |
| 367 | + if (this.position === 'top-right' || this.position === 'top-left') { |
| 368 | + const limit = (window.innerHeight || document.documentElement.clientHeight) - 180; |
| 369 | + this.setHasReachedEnd(bounding.top >= limit); |
| 370 | + } else { |
| 371 | + this.setHasReachedEnd(bounding.bottom <= 200); |
| 372 | + } |
335 | 373 | } |
336 | 374 | }, |
337 | 375 | watch: { |
|
342 | 380 | this.moveTransition(); |
343 | 381 | this.tooltipPos(); |
344 | 382 | }); |
| 383 | + }, |
| 384 | + autoReverse(val, oldVal){ |
| 385 | + if (val !== oldVal && !val) { |
| 386 | + if (val) window.addEventListener('scroll', this.handleScroll); |
| 387 | + else window.removeEventListener('scroll', this.handleScroll); |
| 388 | + } |
345 | 389 | } |
346 | 390 | }, |
347 | 391 | mounted() { |
348 | 392 | this.moveTransition(); |
349 | 393 | }, |
350 | 394 | created() { |
351 | 395 | this.setPosition(); |
| 396 | + if (this.autoReverse) window.addEventListener('scroll', this.handleScroll); |
352 | 397 |
|
353 | 398 | if (this.startOpened) { |
354 | 399 | this.showTooltip(this.tooltipTimeOutWhenStartOpened); |
355 | 400 | } |
| 401 | + }, |
| 402 | + destroyed() { |
| 403 | + if (this.autoReverse) window.removeEventListener('scroll', this.handleScroll); |
356 | 404 | } |
357 | 405 | } |
358 | 406 | </script> |
|
461 | 509 | /*width: 50px;*/ |
462 | 510 | /*height: 50px;*/ |
463 | 511 | padding: 10px; |
464 | | - margin-top: 2vh; |
| 512 | + margin-top: 1vh; |
| 513 | + margin-bottom: 1vh; |
465 | 514 | display: flex; |
466 | 515 | align-items: center; |
467 | 516 | border-radius: 100px; |
468 | 517 | box-shadow: 0 10px 10px rgba(0, 0, 0, 0.20), 0 4px 4px rgba(0, 0, 0, 0.15); |
| 518 | + z-index: 15; |
469 | 519 | } |
470 | 520 |
|
471 | 521 | .fab-list li .material-icons { |
|
480 | 530 | ul { |
481 | 531 | list-style-type: none; |
482 | 532 | padding: 0 !important; |
| 533 | + z-index: 10; |
483 | 534 | } |
484 | 535 |
|
485 | 536 | .fab-wrapper .actions-container { |
486 | | - overflow: hidden; |
487 | 537 | z-index: 0; |
488 | 538 | position: relative; |
489 | 539 | display: flex; |
|
0 commit comments