Kyle Corbin Hurst
Kyle Corbin Hurst

Reputation: 1121

Fade transition doesn't start until I click toggle button for modal to appear twice

I'm trying to open a modal and when I open the modal I want a transition element telling the user to scroll to fade out:

<v-bottom-sheet v-if="sheet">
    <v-card>
        <v-card-title>Hello world</v-card-title>

        <v-card-text>
            <transition name="fade">
                <div v-if="!sheet" class="scrolly">
                    <div class="scroll-container">
                        <div class="scroller"></div>
                    </div>
                </div>
            </transition>
        </v-card-text>
    </v-card>
</v-bottom-sheet>

The problem is the transition element doesn't show up and fade out until the second time I click the toggle button for sheet

Codepen example

Upvotes: 1

Views: 391

Answers (2)

RuNpiXelruN
RuNpiXelruN

Reputation: 1920

@kylecorbinhurst when animating elements based on a condition it's a good idea to switch out your v-if's for v-show's.

The official docs on this page explain it well, but basically the element does not exist in the DOM if the v-if condition evaluates to false, whereas a v-show element that evaluates to false will still exist in the DOM, but rather it's css display property will be set to none.

I believe the transition isn't working the first time as it's not actually there in the DOM to fade in, however by the second click it is. I've had a play with your code pen and switching it to a v-show makes it work the first time as expected.

<div v-show="!sheet" class="scrolly">

Upvotes: 1

Kyle Corbin Hurst
Kyle Corbin Hurst

Reputation: 1121

There's a problem with getting both the transition and modal on the same variable. So I set up a sheet and show. Then when the modal opens I use a promise to set sheet to true first then set show to false.

JS

new Vue({
  el: "#app",
  vuetify: new Vuetify(),
  data: () => ({
    sheet: false,
    show: true
  }),
  methods: {
    showModalFirst() {
      return new Promise((resolve, reject) => {
        this.sheet = true;

        const error = false;

        if (!error) {
          resolve();
        } else {
          reject();
        }
      });
    },
    showModal() {
      this.showModalFirst().then(
        function () {
          this.show = false;
        }.bind(this)
      );
    },

    closeModal() {
      this.sheet = false;
      this.show = true;
    }
  }
});

Template

<v-bottom-sheet
v-model="sheet"
inset
scrollable
persistent
>
    <v-card>
        <v-card-title>Hello World</v-card-title>
        <v-card-text class="always-scroll">
        
        <p>I'm baby succulents lomo typewriter stumptown poke yuccie humblebrag next level irony food truck kitsch. Shoreditch tote bag small batch fam vegan waistcoat narwhal air plant beard. Knausgaard man braid schlitz synth. Kogi taxidermy iPhone, chambray 3 wolf moon paleo woke thundercats gluten-free schlitz. Cray brunch tumeric ramps artisan church-key cold-pressed fingerstache freegan. Normcore pour-over disrupt, man braid 3 wolf moon activated charcoal echo park keytar affogato beard pop-up vape deep v tousled narwhal.</p>
        
        
        </v-card-text>
        <v-card-actions>
            <v-btn rounded color="purple white--text px-3" class="text-capitalize font-weight-medium">Create</v-btn>
            <v-btn v-on:click="closeModal()" text class="text-capitalize font-weight-medium" >Discard</v-btn>
            <transition name="fade">
                <div v-if="show" class="scrolly">
                <div class="scroll-container">
                    <div class="scroller"></div>
                </div>
                </div>
        </transition>
        </v-card-actions>
    </card>
</v-bottom-sheet>

Upvotes: 0

Related Questions