Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swipe in vuetify list items

I am trying to make a swipeable version of the vuetify list elements. I found the swiperjs.com library which does an awesome job in adding swiping capabilities for an html element. I also found this project https://github.com/davidgaroro/vuetify-swipeout which integrates the vuetify library and the swipeable library. Having read the content of the vuetify-swipeout project it looks like the trick is only in setting the right classes on the v-list-tile component, namely

 <v-list-tile class="swiper-slide">

while surrounding the element with

<div :id="id" class="swiper-container">
    <div class="swiper-wrapper">
      ...
    </div>
</div>

The demo works pretty well on the github site.

However, here comes the trick, as v-list-tile is not supported anymore by the current version of vuetify, I replaced all the v-list-tile with v-list-item - which I expected to be equivalent - but it is not and all the v-list-items are translated to the left until you can't see them on the screen without swiping.

So instead of hiding the swappable content and showing the main content, the whole content it translated to the left making the tile unvisible to the screen.

I would greatly appreciate if you could lend me a hand to understand what I am doing wrong.

Thanks and regards,

Pat

like image 330
user2097439 Avatar asked Sep 13 '25 09:09

user2097439


1 Answers

I got it to work more or less, with the following component:

<!-- components/VSwipable.vue -->

<template>
    <div ref="container" class="swiper-container">
        <div class="swiper-wrapper">
            <div v-if="swipeRight" class="swiper-slide">
                <slot name="right-content"/>
            </div>
            <div class="swiper-slide">
                <slot/>
            </div>
            <div v-if="swipeLeft" class="swiper-slide">
                <slot name="left-content"/>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
    import Swiper, { SelectableElement } from 'swiper';
    import 'swiper/css/swiper.css';
    import Vue from 'vue';

    export default Vue.extend({
        mounted() {
            const swiper = new Swiper(this.$refs.container as SelectableElement, {
                initialSlide: this.swipeRight ? 1 : 0,
                resistanceRatio: 0,
                speed: 150,
            });

            swiper.on('transitionEnd', () => {
                // slide index  swipe mode
                //   0   1       R
                //   0   1   2   R   L
                //       0   1   L
                switch (true) {
                    case this.swipeRight && swiper.activeIndex === 0:
                        this.$emit('swipedRight');
                        break;
                    case this.swipeRight && swiper.activeIndex === 2:
                        this.$emit('swipedLeft');
                        break;
                    case !this.swipeRight && swiper.activeIndex === 1:
                        this.$emit('swipedLeft');
                        break;
                    default:
                }


                switch (swiper.activeIndex) {
                    case 0:
                        this.$emit('swipedRight');
                        break;
                    case 2:
                        this.$emit('swipedLeft');
                        break;
                    default:
                }
            });
        },
        props: {
            swipeLeft: Boolean,
            swipeRight: Boolean,
        },
    });
</script>

And example usage:

<template>
    <v-container>
        <v-list>
            <template v-for="item in items">

                <!-- swipe-left enablesleft swiping (you can also use swipe-right), it supports two events: swipedLeft and swipedRight -->
                <v-swipable :key="item" swipe-left>

                    <!-- inject a red list item in the left slide -
                         you can also inject buttons and stuff,
                         use right-content for the right one -->
                    <v-list-item class="error" slot="left-content"/>

                    <v-list-item :value="item">
                        <v-list-item-content>
                            <v-list-item-title v-text="item"/>
                            <v-list-item-subtitle v-text="`Some details about ${item}`"/>
                        </v-list-item-content>
                    </v-list-item>

                </v-swipable>

            </template>
        </v-list>
    </v-container>
</template>

<script lang="ts">
    import VSwipable from '@/components/VSwipable.vue';

    export default Vue.extend({
        data: () => ({
            items: ['Item 1', 'Item 2', 'Item 3']
        }),
        components: {
            VSwipable,
        },
    });
</script>
like image 185
Christian Avatar answered Sep 14 '25 22:09

Christian