Skip to content

Instantly share code, notes, and snippets.

@bryandidur
Last active May 27, 2019 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryandidur/8d522b7b8236899455a66925541b2d5c to your computer and use it in GitHub Desktop.
Save bryandidur/8d522b7b8236899455a66925541b2d5c to your computer and use it in GitHub Desktop.
Pulse Button Vue Component

Code

Vue.component('pulse-button', {
    props: {
        text: {
            type: String,
            default: '',
        },
        classes: {
            type: String,
            default: 'btn btn-primary',
        },
        ms: {
            type: String,
            default: '150',
        },
        scale: {
            type: String,
            default: 'medium',
        },
        scaleup: {
            type: String,
            default: '',
        },
        scaledown: {
            type: String,
            default: '',
        },
    },
    mounted() {
        this.$el.style.transition = `transform ${this.ms / 1000}s`;

        this.addEventListener(this.$el, 'mousedown', () => {
            this.$el.style.transform = `scale(${this.resolvedScale.down})`;
        });

        this.addEventListener(document, 'mouseup', () => {
            this.$el.style.transform = `scale(${this.resolvedScale.up})`;
        });
    },
    beforeDestroy() {
        this.listeners.map((item) => item.element.removeEventListener(item.name, item.callback));
    },
    data: () => ({
        defaultScales: [
            { name: 'easy', up: '1', down: '0.95' },
            { name: 'medium', up: '1', down: '0.9' },
            { name: 'hard', up: '1', down: '0.85' },
        ],
        listeners: [],
    }),
    computed: {
        resolvedScale() {
           const defaultScale = this.defaultScales.find((item) => item.name == this.scale) || {};

           return {
                up: this.scaleup || defaultScale.up,
                down: this.scaledown || defaultScale.down,
           };
        },
        showText() {
            return Boolean(this.text);
        },
    },
    methods: {
        addEventListener(element, name, callback) {
            element.addEventListener(name, callback);

            this.listeners.push({ element, name, callback });
        },
    },
    template: `
        <button :class="classes">
            <span v-if="showText">{{text}}</span>
            <slot v-else></slot>
        </button>
    `,
});

Usage

Setting content
<pulse-button>Hello World!</pulse-button>
<pulse-button text="Hello World!"></pulse-button>
Customizing scale levels
<pulse-button scale="easy">Hello World!</pulse-button>
<pulse-button scale="medium">Hello World!</pulse-button>
<pulse-button scale="hard">Hello World!</pulse-button>
Customizing scaleup and scaledown individually
<pulse-button scaledown="0.5">Hello World!</pulse-button>
<pulse-button scaleup="1.5">Hello World!</pulse-button>
Customizing animation milliseconds
<pulse-button ms="500">Hello World!</pulse-button>
Customizing element classes
<pulse-button classes="btn btn-success">Hello World!</pulse-button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment