Coder Social home page Coder Social logo

vue-smooth-reflow's Introduction

Vue Smooth Reflow (VSR)

A Vue mixin that transitions reflow.

When the component's data is changed, any CSS properties that you register will transition to its new value.

Common use cases are:

  • Transitioning height: auto and width: auto.
  • Smoothly repositioning elements.

Note that this library has no overlap with Vue's built in <transition> components.

Table of Contents

Demo

https://vuesmoothreflow.guanzo.io

If you want to see how the examples were configured, the demo source is here: github

Installation

Download via npm:

$ npm install vue-smooth-reflow

Include via cdn:

<script src="https://unpkg.com/vue-smooth-reflow"></script>

Usage

Module:

<template>
    <div>
        <div v-for="n in children" />
    </div>
</template>

<script>
// The component's root el will now transition to
// accomodate new values of 'this.children'

import smoothReflow from 'vue-smooth-reflow'
export default {
    mixins: [smoothReflow],
    data() {
        return {
            children: '<Dynamic value>'
        }
    },
    mounted(){
        this.$smoothReflow()
    },
}
</script>

Browser:

The mixin is available via the global variable SmoothReflow

API

$smoothReflow(options)

Enables smooth reflow on an element. This method is available on the component instance.

options can be an object, or an array of objects.

Options reference

  • el

    Type: Element | String

    Default: The components root element.

    An element reference, or a CSS selector string. The resolved element will transition reflows on registered properties. This element is referred to as the "smooth element".

    Use a selector string if the element is not rendered initially, like if it's hidden with v-if. If the selector returns multiple elements, the first one will be used.

  • property

    Type: String | Array

    Default: height

    Valid values: height, width, transform

    The CSS property(s) that you want to transition. You can pass any combination.

    For transform, VSR will only transition the translate() function. This is to handle element repositioning due to reflow.

  • transition

    Type: String

    Default: height .5s

    A valid CSS transition value. If you register multiple properties, and want different transitions for each, you can use commas.

    this.$smoothReflow({
        property: ['height', 'width'],
        transition: 'height .25s ease-in-out, width .75s ease-out'
    })

    The default value is conditional on the property option.

    For example, if you register height and transform like so:

    this.$smoothReflow({
        property: ['height', 'transform']
    })

    The default value will become height .5s, transform .5s.

    If the smooth element has transitions on other properties like background-color, they will be preserved.

    NOTE: Any transitions defined as an inline style on the smooth element will be ignored and erased.

  • transitionEvent

    Type: Object

    Default: null

    Valid values:

    transitionEvent: {
        // Any valid CSS selector. Note that comma delimited selectors are valid.
        selector: String,
        // Any valid CSS property name.
        propertyName: String
    }

    Configures the smooth element to react to transitionend events that are emitted by other elements. You must opt-in for this behavior, there is no default.

    selector and propertyName serve as filters so that the smooth element doesn't cause reflows for every transitionend event that it catches, which impacts performance. When the smooth element receives a transitionend event, it will check if selector matches event.target, and/or if propertyName matches event.propertyName. You can specify one or the other, or both. All checks must pass in order for the smooth element to proceed with the smooth reflow.

    A common use case is to delay the smooth reflow until after a child element has been transitioned out with v-if/v-show and <transition>.

    For example, if you want to react to any child div elements that transition out with opacity, use this config:

    transitionEvent: {
        selector: 'div',
        propertyName: 'opacity'
    }

    Let's say you want to transition the smooth element's position. You want to wait for an element with class .i-cause-reflow to transition out before performing the smooth reflow. This element can be located anywhere within the component. Here's the configuration for that:

    transitionEvent: {
        selector: '.i-cause-reflow',
    }

    Check out the demo for more examples.

  • hideOverflow

    Type: Boolean

    Default: true

    Hides overflow during the transition.

    This has 2 benefits. It prevents the scrollbar from appearing, and will hide child elements that overflow.

$unsmoothReflow(options)

Disables smooth reflow on an element. This method is available on the component instance.

options can be an object, or an array of objects.

Registered elements that have the same el as the passed in options will be unregistered. This usually isn't necessary, but is useful if you want to disable the behavior while the component is still alive.

Smooth Component

Importing VSR into every component that needs it violates DRY. Instead, you can create one component that imports VSR then use it as needed. This should satisfy 90% of use cases.

Example:

// SmoothReflow.vue
<template>
    <component :is="tag">
        <slot/>
    </component>
</template>

<script>
import smoothReflow from 'vue-smooth-reflow'
export default {
    name: 'SmoothReflow',
    mixins: [smoothReflow],
    props: {
        tag: {
            type: String,
            default: 'div'
        },
        options: Object,
    },
    mounted () {
        this.$smoothReflow(this.options)
    }
}
</script>

Globally register this component for convenience.

// main.js
import SmoothReflow from './components/SmoothReflow'

Vue.component('SmoothReflow', SmoothReflow)

Update your existing components that import VSR. This is a modification of the first usage example. Goodbye boilerplate!

<template>
    <SmoothReflow>
        <div v-for="n in children"/>
    </SmoothReflow>
</template>

<script>
-import smoothReflow from 'vue-smooth-reflow'
export default {
-   mixins: [smoothReflow],
    data() {
        return {
            children: '<Dynamic value>'
        }
    },
-    mounted(){
-        this.$smoothReflow()
-    },
}
</script>

You may run into reactivity issues when using the SmoothComponent. VSR hooks into the component's beforeUpdate and updated lifecycle methods, so if those are never called, then the transition won't occur.

Examples:

mounted(){
    // Zero config. Enables smooth reflow on this.$el
    this.$smoothReflow()
    // Register with element reference
    this.$smoothReflow({
        el: this.$refs.wrapper,
    })
    // Register with classname. The first match will be used.
    this.$smoothReflow({
        el: '.wrapper-2',
    })
    // Pass an array of options
    this.$smoothReflow([
        // Wait for .reflow-causer to emit a transitionend event,
        // then transition the smooth element's position
        {
            el: this.$refs.wrapper,
            property: 'transform',
            transitionEvent: {
                selector: '.reflow-causer'
            }
        },
        // Wait for a transitionend event for opacity that
        // comes from the smooth elements descendants,
        // then transition the smooth elements height and width.
        {
            el: '.wrapper-2',
            property: ['height', 'width'],
            transitionEvent: {
                propertyName: 'opacity'
            }
        },
    ])
    // If the element reference is a component,
    // make sure to pass in its "$el" property.
    this.$smoothReflow({
        el: this.$refs.wrapper.$el,
    })
    // Unregister a smooth element that would match
    // the selector '.wrapper-5'
    this.$unsmoothReflow({
        el: '.wrapper-5'
    })
}
</script>

Differences from vue-smooth-height

  • Enables smooth reflows on width and transform.

  • VSR will no longer check for existing transition values for registered properties. It will only use the value of the transition option.

  • The hideOverflow option now defaults to true.

  • The way child transitions are handled is completely different.

License

MIT

Copyright (c) 2013-present, Eric Guan

vue-smooth-reflow's People

Contributors

djeglin avatar guanzo avatar jefferysjones avatar rx-837 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vue-smooth-reflow's Issues

License

Hi Eric,

may I know which type of License is applied to this lib? MIT or something else?

thanks.

"watch:" animation stutter

I'm using a watcher on an input to show a validation error message and setting this to show via true/false from this watch method. VSR component being wrapped around this div.

It works just fine if there's a single key press, but multiple keys inputted halts the animation and stutters. You mention there might be reactivity issues and the lifecycle. Is there a away around this issue?

Thanks,

trigger reflow manually

sometimes i'm having nested components inside a "Smooth Component" and one of them is toggling a value in it's internal state and the component inside the <slot /> never gets updated directly (which is actually fine). Is there a function (maybe a function returned from $smoothReflow()) which i can invoke manually to check and trigger a reflow?
thx

Suggestion: Hide scrollbar with CSS instead of overflow-property

Hey,

First of all thanks for the simple and smooth (pun intended) package. ๐Ÿ‘ Was trying it out and seems to be working fine. However in my use case hiding overflow isn't an option, since the content should be visible during reflow and the content has it's own entry transition using Vue's transition component. In most browsers, it's possible to hide scrollbar with CSS, although not a bullet-proof solution.

.scrollbar-none {
   -ms-overflow-style: none;
   scrollbar-width: none;
}
.scrollbar-none::-webkit-scrollbar {
   display: none;
}

Of course due to accessibility concerns in most cases the scrollbars should be enabled on transitionend, but it would be nice to have the option not re-enable them as well. Actually now to think of it, maybe just adding an option to add custom styles on transitionstart and transitionend events would be even better solution. That way the dev could choose to hide the scrollbar using the styles shown above or even add some other interesting transition effects such as transitioning the background color with the reflow etc.

Cheers!

BeforeTransition hook to control options dynamically

I'm using this mixin in a global layout animating the content between route changes and such and it works very well for this. However, sometimes the difference in height between one route and the next is a lot, causing a weird (long) animation.

It would be great if there was a beforeTransition hook where start and end properties are available (in this case height before and after) and a way to dynamically change the options in that hook for that run.

For instance, if the difference in height would be more then a certain amount, we disable the transition for that particular run. I'm sure this will also be useful for a lot of other use cases!

behaviour inside tooltip

Hey, thanks for maintaining and enhancing this module so actively! I'm using it for quite a while inside an app i'm building, mostly inside https://github.com/Akryum/v-tooltip tooltips, let me give you a quick example:

I'm having a custom component base-popover which follows the Component Syntax of v-tooltip, applies some styles and options (which i have removed here) and wraps the content inside a container i'm referencing as the element to reflow smoothly.

<template>
    <v-popover
            v-bind="$attrs"
            v-on="$listeners"
            class="popover"
    >
        <slot name="target" />

        <template slot="popover">
            <div class="content-wrapper" ref="container">
                <slot name="content" />
            </div>
        </template>
    </v-popover>
</template>

<script>
    import smoothReflow from 'vue-smooth-reflow'

    export default {
        name: 'BasePopover',
        inheritAttrs: false,
        mixins: [
            smoothReflow
        ],

        mounted () {
            this.$smoothReflow({
                el: this.$refs.container
            })
        }
    }
</script>

In my components i can then use the BasePopover.vue the following way and the popover content transitions smoothly.

<base-popover :is-open="someBoolean" :trigger="manual">
    <template slot="content">
        <div v-if="isStepOne">
            <!-- or load custom component here -->
            <div style="height: 300px"></div>
        </div>
        <div v-else>
            <div style="height: 100px"></div>
        </div>
    </template>
</base-popover>

Back to the issue: Since 1 or 2 versions tooltip content flickers and jumps from initial height to 0 before transitioning smoothly back to the initial height.

I'm receiving a lot of events from v-tooltip and think waiting and reflowing on one of the events would solve this issue. Have you thought about adding support to work with event handlers by e.g. providing a method to trigger reflow manually?

Uable to use vue-smooth-reflow due to ES7 Spread Operator.

Due to the ES7 Spread Operator on line 106 im unable to import the vue-smooth-reflow library.

ERROR in ./node_modules/vue-smooth-reflow/src/index.js
Module parse failed: Unexpected token (106:12)
You may need an appropriate loader to handle this file type.
| hideOverflow: true,
| debug: false,
| ...userOptions
| }
| let properties = this.parsePropertyOption(options.property)

Is there a way to solve this?

Cheers, Michael

Smooth transition due to contents changing

I have a component that is basically a div with a bunch of headings and texts and buttons and forms and other things inside. The content is dynamic and changes when the user taps a button. The component remains the same, but the model changes.

This causes the height of the component to change. I was hoping vue-smooth-reflow would animate this height change, but I'm guessing it only does so when you explicitly set the height property in css?

Is there anyway to auto-trigger these smooth reflows? I initially thought this was the intention, but when I tried it, it didn't work for me.

Exit animation jumps when using Vue <group-transitions>

Hello,

I've been looking for something like this plugin for a very long time. It is absolutely amazing!!! please keep supporting it.

However I encountered a couple of issues.

Using group-transitions with a simple fade effect to show the content, the outer container animates its height properly when the content is entering, but when it fades away, the outer container starts animating properly but then it suddenly stops and jumps all the way to height 0 with no transition.

I created a sandbox that replicates the bug.
https://codesandbox.io/s/ry50n8vwnn

Another note:
The plugin seems not working when used together with animate.css within Vue transitions.
But that is another bug I guess, so eventually I will open another issue.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.