GithubHelp home page GithubHelp logo

privatenumber / vue-vnode-syringe Goto Github PK

View Code? Open in Web Editor NEW
22.0 3.0 1.0 881 KB

๐Ÿงฌ Add attributes and event-listeners to <slot> content ๐Ÿ’‰

License: MIT License

JavaScript 100.00%
vnode-syringe vue slot mutate overwrite merge attributes props event-listeners vnode

vue-vnode-syringe's Introduction

๐Ÿ’‰ vNode Syringe Latest version Monthly downloads Install size Bundle size

Add attributes and event-listeners to <slot> content.

Supports key, class/style, attrs, props & listeners!

<template>
    <div>
        <vnode-syringe
            class="new-class"
            @click="handleClick"
        >
            <slot />   โฌ… The class and event-listener gets added to every element passed in
        </vnode-syringe>
    </div>
</template>

๐Ÿ™‹โ€โ™‚๏ธ Why?

  • ๐Ÿ”ฅ Set or overwrite attributes & event-listeners on content received from the <slot>!
  • ๐Ÿง  Smart merging strategies Pick between merging, overwriting, or falling-back!
  • ๐Ÿฅ Tiny 1.05 KB minzipped!

๐Ÿš€ Install

npm i vue-vnode-syringe

๐Ÿ’  Merging strategies

Fallback

This is the default behavior. The class new-class and event-listener newOnClick only gets added if there isn't one added yet.

<vnode-syringe
    class="new-class"
    @click="newOnClick"
>
    <slot />
</vnode-syringe>

For example, given the following <slot> content, only the event-listener newOnClick will be added:

<div
	class="some-class"
	<!-- @click="newOnClick" gets added -->
>
    some content
</div>

Overwrite !

Add ! at the end of the attribute or event-listener to overwrite what exists.

<vnode-syringe
    class!="new-class"
    @click!="newOnClick"
>
    <slot />
</vnode-syringe>

For example, given the following <slot> content, both the class and event-listener will overwrite the existing class and event-listener.

<div
    class="some-class" <!-- becomes "new-class" -->
    @click="existing" <!-- becomes "newOnClick" -->
>
    some content
</div>

Merge &

Add & at the end of the attribute or event-listener to merge with what exists.

<vnode-syringe
    class&="new-class"
    @click&="newOnClick"
>
    <slot />
</vnode-syringe>

For example, given the following <slot> content, both the class and event-listener will merge with the existing class and event-listener. When merging event-listeners, both event-listeners will be called.

<div
    class="some-class" <!-- becomes "some-class new-class" -->
    @click="existing" <!-- becomes "existing(); newOnClick()" -->
>
    some content
</div>

๐Ÿ‘จ๐Ÿปโ€๐Ÿซ Examples

Demo 1: Passing down attributes

In this demo, the class="button-group__button" attribute is passed down to all of its <slot> content.

ButtonGroup.vue

<template>
    <div class="button-group">
        <vnode-syringe
            class="button-group__button"
        >
            <slot />
        </vnode-syringe>
    </div>
</template>

<style scoped>
.button-group { ... }
.button-group__button { ... }
</style>

Usage.vue

<button-group>
    <button>Button 1</button> <!-- Will render with the `button-group__button` class -->
    <button>Button 2</button> <!-- Will render with the `button-group__button` class -->
    <button>Button 3</button> <!-- Will render with the `button-group__button` class -->
</button-group>
Demo 2: Merging and Overwriting classes

By default, vNode Syringe only adds the attribute/event-listener if it doesn't already exist. To merge with or overwrite the existing one, use the & (merge) or ! (overwrite) suffix.

ButtonGroup.vue

<template>
    <div class="button-group">
        <vnode-syringe

            <!-- Merge with existing class -->
            class&="button-group__button"

            <!-- Force all buttons to have type="button" -->
            type!="button"

            <!-- Only gets added if child doesn't specify `disabled` -->
            :disabled="disabled"
        >
            <slot />
        </vnode-syringe>
    </div>
</template>

<script>
export default {
    props: {
        disabled: Boolean
    }
};
</script>

<style scoped>
.button-group { ... }
.button-group__button { ... }
</style>

Usage.vue

<button-group disabled>
    <button

         <!-- Gets overwritten to button button-group__button -->
        class="button"

        <!-- Gets overwritten to type="button" -->
        type="submit"

        <!-- Will be inherit parent's disabled state -->
    >
        Button 1
    </button>

    <button
         <!-- Gets overwritten to button button-group__button -->
        class="button"

        <!-- Won't inherit parent's disabled state -->
        :disabled="false"
    >
        Button 2
    </button>
</button-group>

๐Ÿ’โ€โ™€๏ธ FAQ

How can I add attributes/event-listeners to a specific element in the <slot>?

You can use Subslot to pick out specific elements in the slot.

For example, if you only want to accept <button>s in your slot:

<template>
    <div class="button-group">
        <vnode-syringe
            class&="button-group-item"
            @click="onClick"
        >
            <subslot element="button" />
        </vnode-syringe>
    </div>
</template>

<script>
import Subslot from 'vue-subslot';
import vnodeSyringe from 'vue-vnode-syringe';

export default {
    components: {
        Subslot,
        vnodeSyringe
    },

    ...,

    methods: {
        onClick() {
            ...
        }
    }
};
</script>

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง Related

  • vue-proxi - ๐Ÿ’  Tiny proxy component
  • vue-subslot - ๐Ÿ’ Pick 'n choose what you want from a slot passed into your Vue component
  • vue-pseudo-window - ๐Ÿ–ผ Declaratively interface window/document in your Vue template
  • vue-v - render vNodes via component template
  • vue-frag - ๐Ÿคฒ Directive to return multiple root elements

vue-vnode-syringe's People

Contributors

privatenumber avatar

Stargazers

 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

Forkers

sermonis

vue-vnode-syringe's Issues

.flat() is not supported by all browsers

Description

The use of the .flat() function is not supported by all browsers (see documentation) and is resulting in a multitude of Sentry errors (1, 2, 3, 4).

Solution

A custom .flat() function like those suggested in this stackoverflow question may help prevent errors caused by outdated browser versions.

That being said, the versions are pretty old, e.g. Google Chrome v68.0 (last incompatible version) was released in July 2018, so patching it up for this may be kind of overkill.

Directive Support

Do you have a plan to support for directives?

Like as:

<vnode-syringe v-show="show">
  <slot />
</vnode-syringe>

or for custom directives.

Thank you.

feat: Longhand syntax for merge and override

I wasn't able to intuit the meaning of the & and ! modifiers at first glance. What do you think about supporting a more verbose syntax for the 'modifiers' as well?

I don't know if it's feasible to add modifiers narrowly to this component's props.

class.merge="..."
class&="..."

class.override="..."
class!="..."

Similar in philosophy to:

v-bind:class="..."
:class=""

 v-on:click="..."
@click="..."

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.