The Wayback Machine - https://web.archive.org/web/20221204153847/https://github.com/vuejs/vue/issues/9986
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ability to keep enter-to class after show transition completes #9986

Open
tmorehouse opened this issue May 7, 2019 · 4 comments
Open

ability to keep enter-to class after show transition completes #9986

tmorehouse opened this issue May 7, 2019 · 4 comments

Comments

@tmorehouse
Copy link

tmorehouse commented May 7, 2019

What problem does this feature solve?

In some CSS libraries, i.e. Bootstrap, many components have opacity set to 0 by default, and only have opacity set to 1 when a class is applied. i.e. Bootstrap's fade + show classes:

.fade:not(.show) { opacity: 0; }

The current <transition> behaviour does not support retaining the enter-to-class (as it is immediately removed once the transition completes).

Currently one has to use javascript hooks and VM data to add/remove the show class, which makes it impossible to make re-usable transition components, as simply adding a class via javascript to the el reference (via el.classList.add/remove('show')) doesn't guarantee persistence if the content in the default slot manipulates it's own classes, meaning the transition component must be integrated into the custom component, not as a re-usable utility wrapper component).

What does the proposed API look like?

It would be nice to either be able to retain the enter-to-class class after the transition completes, or create a new prop that provides this behaviour for a particular class name i.e. enter-to-retain-class. The class would be removed on leave.

The other option would be to create a new prop active-class="classname" which is added one frame after insertion, and removed when the leave transition is to start (basically rolling the enter-to-class and leave-class into one prop, but retain the class until leave is initiated)

@posva posva changed the title [feature] ability to keep enter-to-class after show transition completes ability to keep enter-to-class after show transition completes May 7, 2019
@tmorehouse
Copy link
Author

tmorehouse commented May 8, 2019

In our (BootstrapVue's) use case, we have to hard-code the transition component and code into each component that uses the fade+show Bootstrap V4 transition classes (modals, toasts, alerts, tabs, etc), causing unnecessary code duplication, and making it difficult for us to allow users to provide their own custom transitions (which has been a common ask for the past while), due to the need for us to mix CSS+Javascript to make Vue's transition system work with Bootstrap.

@JoshMoreno
Copy link

JoshMoreno commented Apr 22, 2020

Ran into this issue today. +1 for adding it to core. Here's the workaround I came up with today:

Transparent wrapper around the default transition component with js hooks to add classes after the enter transitioning is done, and remove those classes before our leave transition starts.
after-enter-class is the prop I added which in my case just mirrors enter-to-class.

https://codesandbox.io/s/serene-darwin-r7h4o?file=/src/components/BetterTransition.vue

<template>
  <transition
    v-bind="$attrs"
    v-on="$listeners"
    v-on:after-enter="afterEnter"
    v-on:before-leave="beforeLeave"
  >
    <slot></slot>
  </transition>
</template>

<script>
export default {
  props: {
    afterEnterClass: {
      type: String,
      default: ""
    }
  },
  computed: {
    classes() {
      return this.afterEnterClass.split(" ").filter(i => i);
    }
  },
  methods: {
    afterEnter(el) {
      this.classes.forEach(cssClass => el.classList.add(cssClass));
    },
    beforeLeave(el) {
      this.classes.forEach(cssClass => el.classList.remove(cssClass));
    }
  }
};
</script>

Usage

<better-transition
  enter-active-class="transition duration-1000"
  enter-class="opacity-0"
  enter-to-class="opacity-50"

  after-enter-class="opacity-50"
        
  leave-active-class="transition duration-1000"
  leave-class="opacity-50"
  leave-to-class="opacity-0"
>
  <div v-if="open" class="mt-5">Our transition</div>
</better-transition>

@tmorehouse
Copy link
Author

tmorehouse commented Apr 22, 2020

We tried something similar, but ran into issue if the root element of the default slot updates (i.e. classes dynamically added or attributes changed), that the class added by the afterEnter hook can get trashed/removed

@JoshMoreno
Copy link

JoshMoreno commented Apr 22, 2020

Ahhh. Yup I'm getting the same thing. Easiest workaround is to wrap the content for the slot in a tag using and ensure it doesn't ever update. Not ideal; works for me since I'm in complete control of everything, but I can see this not being something you'd want to support in a public package.

<better-transition
  enter-active-class="transition duration-1000"
  enter-class="opacity-0"
  enter-to-class="opacity-50"

  after-enter-class="opacity-50"
        
  leave-active-class="transition duration-1000"
  leave-class="opacity-50"
  leave-to-class="opacity-0"
>
  <div v-if="open">
    <div class="mt-5" :class="{'text-white': isActive}">Our transition</div>
  </div>
</better-transition>

@tmorehouse On a side note, thanks for all your work on bootstrap-vue. We've used it in a few projects and it's been great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.