GithubHelp home page GithubHelp logo

termosa / vue-uniq-ids Goto Github PK

View Code? Open in Web Editor NEW
34.0 1.0 2.0 33 KB

Vue.js 2.x plugin that helps to use id-related attributes with no side-effect

License: MIT License

JavaScript 100.00%
vue id aria unique

vue-uniq-ids's Introduction

VueUniqIds

A Vue.js plugin that helps to use id-related attributes with no side-effect

NPM version Bower version

It is a trend to use components. Components are cool, they are small, obvious, easy to use and modular. Untill it comes to the id property.

Some HTML tag attributes requires using an id property, like label[for], input[form] and many of aria-* attributes. And the problem with the id is that it is not modular. If several id properties on the page have the same value they can affect each other.

VueUniqIds helps you to get rid of this problem. It provides the set of id-related directives which value is automatically modified by adding unique string while keeping the attrbitue easy to read.

Installation

Via NPM

Install the package

$ npm install vue-uniq-ids

Via Bower

Install the package

$ bower install vue-uniq-ids

add script on page

<script src="/bower_components/vue-uniq-ids/dist/vue-uniq-ids.js"></script>

or you can do it with RequireJS or any similar tool.

Setup

There are three ways to setup VueUniqIds:

1. As a plugin

// Import the plugin
import VueUniqIds from 'vue-uniq-ids'
// or
import { UniqIdsPlugin } from 'vue-uniq-ids'

// Install it with Vue.use()
import Vue from 'vue'
Vue.use(VueUniqIds, /* options */)

2. As a global mixin

import Vue from 'vue'

// Import the mixin generator
import { createUniqIdsMixin } from 'vue-uniq-ids'

// Create the mixin
const uniqIdsMixin = createUniqIdsMixin(/* options */)

// Install it with Vue.mixin()
Vue.mixin(uniqIdsMixin)

3. As a local mixin

import Vue from 'vue'

// Import the mixin generator
import { createUniqIdsMixin } from 'vue-uniq-ids'

// Create the mixin
const uniqIdsMixin = createUniqIdsMixin(/* options */)

// Add it to the instance
new Vue({
  mixins: [uniqIdsMixin],
  // …
})
// … or to the component
Vue.component('name', {
  mixins: [uniqIdsMixin],
  // …
})

Usage

You can use those directives at any template if you add this extension by Vue.use() or Vue.mixin(), and in the template of the component where you specify the extension by mixin: [] property.

Here is an example of using directives in *.vue file:

<template>
  <form>
    <!-- Directives are expecting the string literal or a variable -->
    <label v-uni-for="'username'">Username</label>
    <!-- As well you can pass the list of items by array or a string where ids are separated by space -->
    <input v-uni-id="'username'"
        v-uni-aria-describedby="['username-description', 'username-hint']" />
    <p v-uni-id="'username-description'">Your public name</p>
    <p v-uni-id="'username-hint'">Use only latin characters</p>
  </form>
</template>

This will generate something like an example below:

  <form>
    <label for="username-pc0k8g5b">Username</label>
    <input id="username-pc0k8g5b"
        aria-describedby="username-description-dnw4bvwy username-hint-oytscr4i" />
    <p id="username-description-dnw4bvwy">Your public name</p>
    <p id="username-hint-oytscr4i">Use only latin characters</p>
  </form>

The list of available attributes:

  • id
  • for
  • form
  • aria-activedescendant
  • aria-controls
  • aria-describedby
  • aria-flowto
  • aria-labelledby
  • aria-owns

Options and customization

There are several options to customize the behavior of directives. You can pass them in several ways:

  1. With the plugin
    import VueUniqIds from 'vue-uniq-ids'
    Vue.use(VueUniqIds, options)
  2. With the mixin
    import { createUniqIdsMixin } from 'vue-uniq-ids'
    Vue.mixin(createUniqIdsMixin(options))
    // or
    new Vue({
      mixins: [createUniqIdsMixin(options)],
      // …
    })
  3. By uniqIdsConfig property
    new Vue({
      uniqIdsConfig: options
    })

The options is an object, that can contain several properties from the example below:

const options = {

  /*
   * scope {object|boolean} — is an object to store a list of generated ids
   *
   * If object is passed it will be used to store generated ids, so you can
   * share the same scope between several components
   * If the value is not object, but it is equivalent to true, the scope
   * object will be created automatically for current instance
   * Otherwise, plugin will use the global scope if the plugin was
   * initialized by Vue.use or Vue.mixin or it will create a new scope.
   * 
   * By default it is using the global scope
   */
  scope: true,

  /*
   * prefix {string} — a prefix for directive names
   * By default it is 'uni-'
   */
  prefix: 'uni-',

  /*
   * attrs: {array} — a list of attributes for which directives will be created
   * By default it is ['id', 'for', 'form', 'aria-activedescendant', 'aria-controls', 'aria-describedby', 'aria-flowto', 'aria-labelledby', 'aria-owns']
   */
  attrs: ['id', 'for'],
  
  /*
   * The rest are options for qinu — a unique string generator
   * Check the link for more details https://www.npmjs.com/package/qinu
   */

  /*
   * template {string} — the template for unique identifiers
   * 
   * The %qinu% will be replaced with generated uniq code, and %args[N]%'s are
   * replaced by args and directive value
   * 
   * By default it is '%arg[0]%-%qinu%'
   */
  template: '%arg[0]%-%arg[1]%-%qinu%',

  /*
   * args {array} — predefined args for template string
   *
   * This are values for template string, can be useful when you want to scope
   * ids with an additional name, or to avoid using value for directives in
   * the components with one id only.
   * 
   * By default it is empty
   */
  args: [],

  /*
   * chars {string|array} — a list of characters to generate the unique string
   */
  chars: '1234567890abcdef',

  /*
   * length {integer} — a length of unique string
   */
  length: 8
}

An example of usage without specifying the value in template

Vue.use(VueUniqIds)
Vue.component('input-section', {
  props: ['label'],
  template: '\n\
    <div>\n\
      <label v-uni-for>{{label}}</label>\n\
      <input v-uni-id />\n\
    </div>',
  uniqIdsConfig: {
    args: ['input-section'],
    scope: true
  }
})

This component will be rendered to code similar to the example below:

    <div>
      <label for="input-section-97muvl55">LABEL</label>
      <input id="input-section-97muvl55" />
    </div>

Accessing and generating ids via JS

Ids generated in template and those that will be generated via this.uniId() method have the same scope inside of the same component

Vue.use(VueUniqIds)
Vue.component('input-section', {
  props: ['label'],
  template: '\n\
    <div>\n\
      <label v-uni-for="textId">{{label}}</label>\n\
      <input v-uni-id="\'text\'" />\n\
    </div>',
  computed: {
    textId: function () {
      return this.uniId('text')
    }
  }
})

This component will be rendered to code similar to the example below:

    <div>
      <label for="text-97muvl55">LABEL</label>
      <input id="text-97muvl55" />
    </div>

License

MIT © Stanislav Termosa

vue-uniq-ids's People

Contributors

termosa 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

Watchers

 avatar

vue-uniq-ids's Issues

typo in npmjs page

On 2022-03-01 the page rendered at
https://www.npmjs.com/package/vue-uniq-ids
included a text as follows:

If several id properties on the page will has the same value they can affect each other.
However, it should read as follows:
If several id properties on the page have the same value they can affect each other.

How to use this plugin in a method

Hi there
I can't wrap my head around how I can use this plugin outside of the template.

I would like to use something like this: (Look at the uid bindings!)

<svg
      class="Blob__svg"
      viewBox="0 0 450 450"
      @mouseover="hover"
      @mouseout="hoverOut"
    >
      <clipPath :id="uid">
        <path
          ref="path"
          class="Blob__clippath"
          d="M 189,80.37 C 243,66.12 307.3,87.28 350.9,124.1 389.3,156.6 417,211.2 418.1,263.4 419.1,305.7 401.8,355.6 368.5,379.1 298.8,428 179.2,446.4 117.6,386.3 65.4,335.3 78.55,230.3 105.5,160.5 119.7,123.6 152.6,89.85 189,80.37 Z"
        />
      </clipPath>
      <g :clip-path="`url(#${uid})`">
        <rect width="494.5" height="494.5" :fill="fillColor" />
      </g>
    </svg>

But for that I need the uid to be setup before.
Like

mounted() {
    this.uid = createUniqIdsMixin.doSomethingToReturnAUniqueID()
}

Thanks for your help here.
Cheers

Add support of refs in values

It would be nice to add referral objects as values in templates, like:

<label v-uniq-for="input">Label</label>
<input ref="input" />

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.