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

vue-search-panel

v1.0.6

Published

A vue component of searching panel

Downloads

26

Readme

vue-search-panel

English | 简体中文

vue-search-panel is a search component with suggestions

Contents

Features

  • Filter suggestions based on input word, support for custom rules
  • Customize suggestion's element by slot
  • Support for custom UI
  • Support configuration panel position (top/bottom/left/right/static)
  • Extended to multifunctional panel, like VsCode

Example

Live demo

Link: https://theoxiong.github.io/vue-search-panel/

Default UI

DefaultUI

Custom UI

CustomizeUI

Install

$   npm install vue-search-panel --save

Usage

Import module

import VueSearchPanel from 'vue-search-panel'

Registration

Global registration

Vue.use(VueSearchPanel)

Local registration

<script>
export default {
  components: { VueSearchPanel }
}
</script>

Basic usage

  • Calling the show method to open panel.
  • Click outside or Press ESC to close panel.

Sample code:

<template>
  <div class="demo-comp">
    <button @click="onOpen">Open Panel</button>
    <div>Selected: {{ selected }}</div>
    <vue-search-panel
      v-model="value"
      :fetch-suggestions="getSuggestions"
      @select="onSelect"
      ref="searchPanel"
    >
    </vue-search-panel>
  </div>
</template>

<script>
import VueSearchPanel from 'vue-search-panel'
const testData = [
  { key: 'test-data-1', value: 'test data 1' },
  { key: 'test-data-2', value: 'test data 2' },
  { key: 'test-data-3', value: 'test data 3' }
]

export default {
  name: 'DemoComp',
  data () {
    return {
      value: '',
      selected: ''
    }
  },
  methods: {
    onOpen () {
      this.$refs.searchPanel.show()
    },
    onSelect (item) {
      this.selected = item.value
    },
    getSuggestions (query, cb) {
      cb(query ? testData.filter(item => { return item.value.includes(query) }) : testData)
    }
  },
  components: { VueSearchPanel }
}
</script>

Custom suggestions

Customize suggestion's element by scoped slot, access the suggestion object via the item key.

Sample code:

<template>
  <div class="demo-comp">
    <button @click="onOpen">Open Panel</button>
    <div>Selected: {{ selected }}</div>
    <vue-search-panel
      v-model="value"
      :fetch-suggestions="getSuggestions"
      @select="onSelect"
      ref="searchPanel"
    >
      <div class="demo-search-item" slot-scope="{ item }">
        <span class="search-item-value">{{ item.value }}</span>
        <span class="search-item-time">{{ item.time }}</span>
      </div>
    </vue-search-panel>
  </div>
</template>

<script>
import VueSearchPanel from 'vue-search-panel'

export default {
  name: 'DemoComp',
  data () {
    return {
      value: '',
      selected: '',
      testData: []
    }
  },
  mounted () {
    for (let i = 0; i < 20; i++) {
      this.testData.push({
        key: `data-${i}`,
        value: `Test data ${i + 1}`,
        time: new Date(Math.random() * 1000000000000).toLocaleDateString()
      })
    }
  },
  methods: {
    onOpen () {
      this.$refs.searchPanel.show()
    },
    onSelect (item) {
      this.selected = item.value
    },
    getSuggestions (query, cb) {
      cb(query ? this.testData.filter(item => { return item.value.includes(query) }) : this.testData)
    }
  },
  components: { VueSearchPanel }
}
</script>

<style scoped>
.demo-search-item{
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 32px;
  padding: 0 20px;
}
.search-item-value{
  font-size: 14px;
  color: #555;
}
.search-item-time{
  font-size: 12px;
  color: #aaa;
  width: 80px;
}

</style>

Custom UI

Customize UI by props.
The color/borderColor/backgroundColor/width/height can be configured.
For more details, see the API.

Sample code:

<template>
  <div class="demo-comp">
    <button @click="onOpen">Open Panel</button>
    <div>Selected: {{ selected }}</div>
    <vue-search-panel
      v-model="value"
      width="640px"
      height="400px"
      scrollBarColor="#aaaaaa"
      inputColor="#cccccc"
      inputBackground="#555555"
      inputBorderColor="#666666"
      inputBorderColorHovering="#999999"
      inputBorderColorFocused="#bbbbbb"
      placeholderEffect="dark"
      panelBackground="#333333"
      panelBoxShadow="rgba(0, 0, 0, 0.6)"
      highlightedColor="#444444"
      hoveredColor="#666666"
      :fetch-suggestions="getSuggestions"
      @select="onSelect"
      ref="searchPanel"
    >
      <div class="demo-search-item" slot-scope="{ item }">
        <span class="search-item-value">{{ item.value }}</span>
        <span class="search-item-time">{{ item.time }}</span>
      </div>
    </vue-search-panel>
  </div>
</template>

<script>
import VueSearchPanel from 'vue-search-panel'

export default {
  name: 'DemoComp',
  data () {
    return {
      value: '',
      selected: '',
      testData: []
    }
  },
  mounted () {
    for (let i = 0; i < 20; i++) {
      this.testData.push({
        key: `data-${i}`,
        value: `Test data ${i + 1}`,
        time: new Date(Math.random() * 1000000000000).toLocaleDateString()
      })
    }
  },
  methods: {
    onOpen () {
      this.$refs.searchPanel.show()
    },
    onSelect (item) {
      this.selected = item.value
    },
    getSuggestions (query, cb) {
      cb(query ? this.testData.filter(item => { return item.value.includes(query) }) : this.testData)
    }
  },
  components: { VueSearchPanel }
}
</script>

<style scoped>
.demo-search-item{
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 32px;
  padding: 0 20px;
}
.search-item-value{
  font-size: 14px;
  color: #999;
}
.search-item-time{
  font-size: 12px;
  color: #777;
  width: 80px;
}

</style>

config panel position

  • The prop of fixed is used for position of panel, the panel is positioned relative to the viewport when the value is true, and the panel is positioned according to the normal flow of the document when the value is false.
  • The prop of placement is used for specifying the placement of panel relative to the viewport, the optional vlaue is top/bottom/left/right

The placement prop is ignored when the fiexd value is false

Sample code:

<template>
  <div class="demo-comp">
    <button @click="onOpen('top')" :disabled="disabled" :class="{'is-disabled': disabled}">Open at top</button>
    <button @click="onOpen('bottom')" :disabled="disabled" :class="{'is-disabled': disabled}">Open at bottom</button>
    <button @click="onOpen('left')" :disabled="disabled" :class="{'is-disabled': disabled}">Open at left</button>
    <button @click="onOpen('right')" :disabled="disabled" :class="{'is-disabled': disabled}">Open at right</button>
    <button @click="onOpen('inner')" :disabled="disabled" :class="{'is-disabled': disabled}">Open at inner</button>
    <div>Selected: {{ selected }}</div>
    <vue-search-panel
      v-model="value"
      :placement="placement"
      :fixed="fixed"
      :fetch-suggestions="getSuggestions"
      @open="onPanelOpen"
      @closed="onPanelClosed"
      @select="onSelect"
      ref="searchPanel"
    >
    </vue-search-panel>
  </div>
</template>

<script>
import VueSearchPanel from 'vue-search-panel'
const testData = [
  { key: 'test-data-1', value: 'test data 1' },
  { key: 'test-data-2', value: 'test data 2' },
  { key: 'test-data-3', value: 'test data 3' }
]

export default {
  name: 'DemoComp',
  data () {
    return {
      value: '',
      selected: '',
      placement: 'top',
      fixed: true,
      disabled: false
    }
  },
  methods: {
    onOpen (position) {
      if (position === 'inner') {
        this.fixed = false
      } else {
        this.fixed = true
        this.placement = position
      }
      this.$refs.searchPanel.show()
    },
    onPanelOpen () {
      this.disabled = true
    },
    onPanelClosed () {
      this.disabled = false
    },
    onSelect (item) {
      this.selected = item.value
    },
    getSuggestions (query, cb) {
      cb(query ? testData.filter(item => { return item.value.includes(query) }) : testData)
    }
  },
  components: { VueSearchPanel }
}
</script>

<style scoped>
.demo-comp{
  margin: 20px;
  width: 600px;
}
.is-disabled,
.is-disabled:active,
.is-disabled:focus,
.is-disabled:hover{
  cursor:not-allowed;
  background-color:#e4e4ee;
}
</style>

Extension

It could be extended to multifunctional panel, such as search/recently/command, like VsCode
Live dome:https://theoxiong.github.io/vue-search-panel/

For dev:

npm install
npm run dev

API

Attributes

parameter | description | type | optional value | default value -|-|-|-|-| value / v-model | two-way binding value | String | — | — placeholder | the placeholder of input | String | — | — width | the width of panel | String | — | 50% height | the height of panel | String | — | 300px top | the marginTop of panel | String | — | 0px bottom | the marginBottom of panel | String | — | 0px left | the marginLeft of panel | String | — | 0px right | the marginRight of panel | String | — | 0px fixed | whether positioned relative to the viewport | Boolean | — | true placement | specifying the placement of panel relative to the viewport (ignored when the fiexd value is false) | String | top/bottom/left/right | top fetchSuggestions | a method to fetch input suggestions. when suggestions are ready, invoke callback(data:[]) to return them | Function(queryString, cb) | — | — closeOnPressEscape | whether close panel on press ESC | Boolean | — | true closeOnSelect | whether close panel on select | Boolean | — | true clearOnClose | whether clear input value when the panel closed | Boolean | — | true selectWhenUnmatched | whether to emit a select event on enter when there is no match | Boolean | — | false triggerOnFocus | whether show suggestions when input focus | Boolean | — | true highlightFirstItem | whether to highlight first item | Boolean | — | true valueColor | the color of suggestion item (when there is no scoped slot) | String | — | #606266 scrollBarColor | the color of scroll bar | String | — | #DFDFDF scrollBarOpacity | the opacity of scroll bar | Number | — | 0.8 panelBackground | the background color of panel | String | — | #FFFFFF panelBorderRadius | the border radius of panel | String | — | 0px panelBoxShadow | the boxShadow color of panel | String | — | rgba(0, 0, 0, 0.3) highlightedColor | the color of suggestion item when highlighted | String | — | #F5F7FA hoveredColor | the color of suggestion item when hovered | String | — | #C5C7CA placeholderEffect | the color of placeholder text | String | light/dark | light inputColor | the color of input text | String | — | #606266 inputBackground | the background color of input field | String | — | #FFFFFF inputBorderColor | the border color of input field | String | — | #DCDFE6 inputBorderColorHovering | the border color of input field when hovered | String | — | #B0B3BB inputBorderColorFocused | the border color of input field when focused | String | — | #575F96

Methods

method name | description | parameters -|-|-| show | open the panel | — close | close the panel | — focusInput | focus the input element | — getInputElement | get the input element | —

Events

event name | description | parameters -|-|-| open | triggers when the panel opens | — opened | triggers when the panel opening animation ends | — close | triggers when the panel closes | — closed | triggers when the panel closing animation ends | — focus | triggers when the input element focused | — blur | triggers when the input element blurred | — select | triggers when a suggestion is clicked | suggestion being clicked

Slots

Scoped slot

Custom content for input suggestions, the scope parameter is { item }

Named slot

name | description -|-| upon-item | content on the top of suggestions

Reference

  • VS Code
  • Element UI