Lovelace: Swiper card

I am having issues where swiping registers click, it swipes and pops up an entity at the same time on Mobile, which is very annoying…is there any fix for it?

Great card, should be integrated into core.

Anyone know how I can display the entities for picture-glance card?

One of the most un-documented custom cards I’ve ever seen.

2 Likes

Used since one year ! I love it <3

TEST

Hi there!

I have a swipe-card within a swipe-card. Is it possible to swipe within the child card without the parent card moving? Thanks in advance!

I have a couple problems I hope someone can help fix or tell me if it’s a bug… please!

I would like to know, how can I stop the swiper card from having a blank card at the end of the swipes? I have 3 images, and at the end, the last one turns, and it then shows a blank card. It starts the sequence over, however… that is my second problem…

When starting the sequence over, it almost skips the first card, just flashing it quickly and then the second one shows up and it proceeds with the other cards.

Are these bugs?? How can I get it to stop skipping the first card, and get rid of the blank card at the end? It should just be card after card after card.

I have played around with all the settings and still can’t get that blank one to disappear! Nor can I get the first one to show up normally after the first run.

The third issue is, why does it now rotate after a page refresh? Yet I can go into edit mode and it works there. But a lot of times, it won’t rotate after the app/page is reloaded.

Here’s my yaml and a quick gif to show you what I am talking about:

https://i.ibb.co/7xfJY7j6/output2.gif

  - type: custom:swipe-card
    description: Previous Artwork
    parameters:
      centeredSlides: false
      slidesPerView: 1
      spaceBetween: 0
      effect: cube
      rotate: true
      perSlideRotate: 5
      perSlideOffset: 12
      slideShadows: true
      speed: 12000
      autoplay:
        delay: 0
        disableOnInteraction: false
      loop: true
      loopAdditionalSlides: 10
    cards:
      - type: picture
        image: /local/hass-media-center-spotify-edition-logo-4.png
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.previous_artwork_1_4
            image: ${states['sensor.previous_artwork_1'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set prevsong_1 = states('sensor.previous_song_1') %}
                  {% set prevartist_1 = states('sensor.previous_artist_1') %}
                  {% if prevsong_1 != 'unknown' and prevartist_1 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ prevsong_1 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ prevartist_1 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 77%
          left: 42.6%
        card_mod:
          style: |
            :host {
              font-size: 18px;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.previous_artwork_2_5
            image: ${states['sensor.previous_artwork_2'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set prevsong_2 = states('sensor.previous_song_2') %}
                  {% set prevartist_2 = states('sensor.previous_artist_2') %}
                  {% if prevsong_2 != 'unknown' and prevartist_2 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ prevsong_2 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ prevartist_2 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 77%
          left: 42.6%
        card_mod:
          style: |
            :host {
              font-size: 18px;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.previous_artwork_3_6
            image: ${states['sensor.previous_artwork_3'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set prevsong_3 = states('sensor.previous_song_3') %}
                  {% set prevartist_3 = states('sensor.previous_artist_3') %}
                  {% if prevsong_3 != 'unknown' and prevartist_3 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ prevsong_3 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ prevartist_3 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 77%
          left: 42.6%
        card_mod:
          style: |
            :host {
              font-size: 18px;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.previous_artwork_4_8
            image: ${states['sensor.previous_artwork_4'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set prevsong_4 = states('sensor.previous_song_4') %}
                  {% set prevartist_4 = states('sensor.previous_artist_4') %}
                  {% if prevsong_4 != 'unknown' and prevartist_4 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ prevsong_4 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ prevartist_4 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 77%
          left: 42.6%
        card_mod:
          style: |
            :host {
              font-size: 18px;
            }
    style:
      top: 51%
      width: 10%
      left: 42.5%
  - type: custom:swipe-card
    description: Coming Up Artwork
    parameters:
      centeredSlides: false
      slidesPerView: 1
      spaceBetween: 0
      effect: cube
      rotate: true
      perSlideRotate: 5
      perSlideOffset: 12
      slideShadows: true
      speed: 12000
      autoplay:
        delay: 0
        disableOnInteraction: false
      loop: true
      loopAdditionalSlides: 10
    cards:
      - type: picture
        image: /local/hass-media-center-spotify-edition-logo-4.png
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.next_artwork_queued_0
            image: ${states['sensor.next_artwork_queued_0'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set nextsong_0 = states('sensor.next_song_title_queued_0') %}
                  {% set nextartist_0 = states('sensor.next_artist_queued_0') %}
                  {% if nextsong_0 != 'unknown' and nextartist_0 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ nextsong_0 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ nextartist_0 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 78%
          left: 88%
        card_mod:
          style: |
            ha-card {
              background: transparent !important;
              padding: 0px !important;
              box-shadow: none !important;
            }
            :host {
              background: transparent !important;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.next_artwork_queued_1
            image: ${states['sensor.next_artwork_queued_1'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set nextsong_1 = states('sensor.next_song_title_queued_1') %}
                  {% set nextartist_1 = states('sensor.next_artist_queued_1') %}
                  {% if nextsong_1 != 'unknown' and nextartist_1 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ nextsong_1 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ nextartist_1 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 78%
          left: 88%
        card_mod:
          style: |
            ha-card {
              background: transparent !important;
              padding: 0px !important;
              box-shadow: none !important;
            }
            :host {
              background: transparent !important;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.next_artwork_queued_2
            image: ${states['sensor.next_artwork_queued_2'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set nextsong_2 = states('sensor.next_song_title_queued_2') %}
                  {% set nextartist_2 = states('sensor.next_artist_queued_2') %}
                  {% if nextsong_2 != 'unknown' and nextartist_2 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ nextsong_2 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ nextartist_2 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 78%
          left: 88%
        card_mod:
          style: |
            ha-card {
              background: transparent !important;
              padding: 0px !important;
              box-shadow: none !important;
            }
            :host {
              background: transparent !important;
            }
      - type: vertical-stack
        cards:
          - type: picture-entity
            entity: camera.next_artwork_queued_3
            image: ${states['sensor.next_artwork_queued_3'].state}
            show_name: false
            show_state: false
          - type: custom:html-template-card
            view_layout:
              position: main
            picture_elements_mode: true
            ignore_line_breaks: true
            content: >
              <div class="container" style="width: 176px !important; height:
              40px !important; overflow: hidden !important; white-space: nowrap
              !important; position: relative !important;">
                <div class="text">
                  {% set nextsong3 = states('sensor.next_song_title_queued_3') %}
                  {% set nextartist3 = states('sensor.next_artist_queued_3') %}
                  {% if nextsong3 != 'unknown' and nextartist3 != 'unknown' %}
                    <span style="color: #2492ff !important; font-weight: bold !important; font-size: 16px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                    {{ nextsong3 }}<span style="color: rgba(207,22,207,1)"> By </span><span style="color: #2492ff;">{{ nextartist3 }}</span>
                  {% endif %}
                </div>
              </div>
        style:
          top: 78%
          left: 88%
        card_mod:
          style: |
            ha-card {
              background: transparent !important;
              padding: 0px !important;
              box-shadow: none !important;
            }
            :host {
              background: transparent !important;
            }
    style:
      top: 52%
      width: 10%
      left: 88%

More than 5 years later :slight_smile: I experience the same, and I’m looking for a solution. Did anyone ever get closer to resolving this? Every time I swipe it opens up the details (same as the tap function). I don’t want that.

re. Lovelace: Swiper card - #249 by jdbrookes

Same comment in reply to your inquiry. I experience the same, and I’m looking for a solution. Did anyone ever get closer to resolving this?

Has anyone been able to figure this out?
When I try to swipe using a mobile (with touch) the butons get pressed…

hi guys, does anyone know how to give a dynamic value to the parameter slidesPerView according to mediaquery width?

nevermind. solved with breakpoints:

      - type: custom:swipe-card
        view_layout:
          grid-area: main
          show:
            mediaquery: "(max-width:754px)"
        parameters:
          #default
          slidesPerView: 1
          breakpoints: {
            #when >= 250px wide
            250: {
              slidesPerView: 2
            },
            #when >= 300px wide
            300: {
              slidesPerView: 3
            }
          }

hello everyone, I have a problem.
Everything works but I have this behavior

Card1—>Card2<—back to Card1

I want a continuous flow

card1—>card2—>card1—>card2…

without rewinds
each card must scroll automatically from right to left.

Can you help me?

type: custom:swipe-card
card_width: calc(100% - 48px)
parameters:
  slidesPerView: auto
  spaceBetween: 16
  loop: false            # loop OFF
  freeMode: true
  freeModeMomentum: false
  autoplay:
    delay: 0
    disableOnInteraction: false
  speed: 10000
cards:
  - type: custom:button-card
    entity: person.gianni
    show_icon: false
    show_name: true
    name: |
      [[[
        return entity.state === 'home' ? 'Gianni è a casa' : 'Gianni è fuori casa';
      ]]]
    styles:
      card:
        - min-width: 180px
        - height: 50px
        - display: flex
        - justify-content: center
        - align-items: center
        - font-size: 18px
        - font-weight: bold
        - border-radius: 12px
        - background-color: rgba(0, 0, 0, 0.4)
        - box-shadow: 0 0 10px rgba(0,0,0,0.5)
      name:
        - color: |
            [[[ return entity.state === 'home' ? '#7fc07a' : '#f95f62'; ]]]
        - text-shadow: 1px 1px 3px rgba(0,0,0,0.8)
  - type: custom:button-card
    entity: sensor.amazon_quality_air_indoor_air_quality
    show_icon: false
    show_name: true
    name: |
      [[[
        const val = entity.state ? parseInt(entity.state) : 0;
        let desc = '';
        if (val <= 35) desc = 'Scarsa';
        else if (val <= 65) desc = 'Discreta';
        else desc = 'Buona';
        return `Qualità aria: ${val} (${desc})`;
      ]]]
    styles:
      card:
        - min-width: 220px
        - height: 50px
        - display: flex
        - justify-content: center
        - align-items: center
        - font-size: 18px
        - font-weight: bold
        - border-radius: 12px
        - background-color: rgba(0, 0, 0, 0.4)
        - box-shadow: 0 0 10px rgba(0,0,0,0.5)
      name:
        - color: |
            [[[
              const val = entity.state ? parseInt(entity.state) : 0;
              if (val <= 35) return '#f79c56';       // arancione
              else if (val <= 65) return '#ffd646';  // giallo
              else return '#abd25f';                  // verde
            ]]]
        - text-shadow: 1px 1px 3px rgba(0,0,0,0.8)

Thank you :slight_smile:

did you found a solution ?

loop: true

That’s not what I want. The cards should not go back when you get to the end. If there are 3 cards, I want it to always scroll from right to left after the third card and show the fourth card as the first. I hope I explained.

1 Like

i just quit the swiper card . No one is following up or updating the card and it has some imperfections to me.

I use conditional cards instead

Looking for infinite loop?

and this rewind function is not what you want?

Yes, I want infinite loop automatically
after the last card I don’t want a rewind but I want to display the first card always with an effect from right to left (see infinite loop)

have you tried rewind: false ? I am just grasping at straws while reading through the react element examples. I am pretty sure this card uses react.

i I see a blank card at the end and then the first one appears. Can I fix it?

the first card not rendering, try this code:

type: custom:swipe-card
card_width: calc(100% - 48px)
parameters:
  centeredSlides: true
  slidesPerView: auto
  spaceBetween: 16
  initialSlide: 0
  show_empty: false
  rewind: false
  loop: true
  autoplay:
    delay: 4000
    disableOnInteraction: false