npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@invisiburu/vue-picker

v2.1.0

Published

A native-like select field, but better.

Downloads

842

Readme

vue-picker

A native-like select field, but better.

version min size minzip size deps count tree shaking

Mostly behaves like native <select> but accepts custom markup for the options and the opener button.

The options are navigatable from the keyboard. The opener text is easily customizable.

The package versions of 2 and higher work with Vue3. For Vue2, use prior versions of the package.

Demo

See the demo: https://invisiburu.github.io/vue-picker/

See the demo sources in demo/

The Problem

When you think about a custom selector, you usually come to provide the options as an array. For sure, it resolves some reactivity issues by default but also has some pitfalls.

One such pitfall that in most cases, you need to map your data list to an array of something like { label, value } thus spending extra resources. Additionally, you write dummy code to display an options selector.

The second pitfall is that default <select> provides a more natural way to render lists - just by giving the elements by themselves, not the arrays.

The third pitfall is the poor customization capabilities of the options. Which mostly looks similar to the problem of default <select> but a bit milder.

VuePicker resolves all of these issues.

TypeScript

Currently, VuePicker comes with no TS declarations because of the poor TS support within Vue infrastructure. Please contact me or craft an issue if you think the times have changed or you have any other arguments of introducing TypeScript to the package. Also, you're welcome to contribute.

Installation

Using unpkg:

<head>
  <script src="https://unpkg.com/vue@3"></script>
  <script src="https://unpkg.com/@invisiburu/vue-picker"></script>
  <!-- optional css -->
  <link rel="stylesheet" href="https://unpkg.com/@invisiburu/vue-picker/dist/vue-picker.min.css">
</head>

<body>
  <div id="app"></div>
  <script>
    const App = {
      template:
        '<div>' +
          '<h3>Hello world</h3>' +
          '<VuePicker v-model="mv">' +
            '<VuePickerOption value="opt0">Option 0</VuePickerOption>' +
            '<VuePickerOption value="opt1">Option 1</VuePickerOption>' +
          '</VuePicker>' +
        '</div>',
      data: function () { return { mv: 'opt1' } },
    }
    const app = Vue.createApp(App)
    app.use(window.VuePicker)
    app.mount('#app')
  </script>
</body>

Using npm:

npm i --save @invisiburu/vue-picker

Import in your project:

import { VuePicker, VuePickerOption } from '@invisiburu/vue-picker'
// optional css
import '@invisiburu/vue-picker/dist/vue-picker.min.css'

const app = createApp(/* ... */)
app.component('VuePicker', VuePicker)
app.component('VuePickerOption', VuePickerOption)

Usage

Basic:

<VuePicker v-model="color" :isAutofocus="true">
  <VuePickerOption value="">Empty</VuePickerOption>
  <VuePickerOption value="red">Red</VuePickerOption>
  <VuePickerOption value="green">Green</VuePickerOption>
  <VuePickerOption value="blue">Blue</VuePickerOption>
  <VuePickerOption value="yellow" :isDisabled="true">Yellow</VuePickerOption>
  <VuePickerOption value="teal" text="Teal">
    How about teal (Teal will be shown instead)
  </VuePickerOption>
</VuePicker>

Custom options:

<template>
  <VuePicker v-model="variant">
    <VuePickerOption value="italic-bold">
      Some <i>italics</i> or <b>bold</b>?
    </VuePickerOption>

    <VuePickerOption value="special" text="Special! Yes!">
      <div class="grid">
        <span class="title">Or something more special?</span>
        <span class="subtitle">I am a subheading!</span>
      </div>
    </VuePickerOption>
  </VuePicker>
</template>

<style scoped>
.grid {
  display: grid;
  grid: auto-flow auto / auto;
  gap: 4px;
}

.title {
  font-size: 1.05em;
  font-weight: bold;
}

.subtitle {
  font-size: 0.9em;
  color: lightgray;
}
</style>

Custom opener:

<template>
  <VuePicker v-model="custom">
    <template #opener="{ opener }">
      <span>
        <i>{{ opener.value }}</i>
        <b>{{ opener.text }}</b>
      </span>
    </template>

    <VuePickerOption value="value-1">Value 1</VuePickerOption>
    <VuePickerOption value="value-2">Value 2</VuePickerOption>
  </VuePicker>
</template>

Api

VuePicker

Props:

  • modelValue - the value, should be a string. The behaviour is not defined for values that do not exist within provided options.
  • placeholder - a text to show when value is null, undefined or an empty string.
  • isAutofocus - focus the opener on mount.
  • isDisabled - disable the component.
  • onKeyDown - accepts a function to run before the default key-down listener. Please see the onKeyDown() section for more details

Emitted events:

  • input - an option selected. Carries the new value to assign.
  • open - dropdown open.
  • close - dropdown closed. Carries true if closed by the outer click.

Slots:

  • default - a picker option. Should be a <VuePickerOption>.
  • opener - override the displayed opener text. Provides the opener scope var with { value, text, opt }, where:
    • value - the selected value.
    • text - the text that was intended to display by the opener (HTML stripped). Content of the placeholder attribute prevails over empty option values.
    • opt - context of the current option.
  • openerIco - override the default expand arrow
  • dropdownInner - use if you want a custom dropdown inner container

VuePickerOption

Props:

  • isDisabled - disable the option. Disabled options cannot be picked or navigated.
  • value - value to set on when the option selected.
  • text - text to be displayed instead of the content of the default slot. Also overrides the optHtml and optTxt computed properties of the component.

Slots:

  • default - content to be displayed in the options list and in the opener when the option is selected. Can contain any markup, the opener will display it as is. Please consider using the text prop if you plan complex things in here.

Computed

You can use these computed properties within the opt param of the opener slot.

  • optHtml - returns the HTML from the default slot of the component.
  • optTxt - returns the HTML from the default slot of the component. Mostly the same as text param of the opener slot but does not respect placeholder attr of the picker.

onKeyDown prop

Accepts a function like the following:

function onKeyDown (event: KeyboardEvent, dropdown: any, options: any) => boolean

The listener if fired in two cases:

  1. When the dropdown in open
  2. When the dropdown is closed but the opener is focused

Return false from your onKeyDown() function to prevent the default key-down handler.

Issues

In case of a bug or a suggestion, please report on the Issues page or contact me by email.

Changelog

Check the changes in CHANGELOG.md

TODO

  • TS definitions
  • Better onKeyDown description
  • Unit tests
  • Search
  • Handle keys: Page down, Page up
  • Animation support
  • Dropdown position switch if does not fit the screen
  • Outer label[for=""] support
  • Readonly attr - ?
  • iOS, Android full screen style - ?

License

MIT