@lilydesignsystem/vue-search-picker
| Install | |
|---|---|
npm install @lilydesignsystem/vue-search-picker |
|
| Latest Version: | 0.2.0 |
| Vue: | 3 |
| License: | MIT OR Apache-2.0 OR GPL-2.0-only OR GPL-3.0-only OR BSD-3-Clause |
| Last Updated: | Oct 23, 2026 |
| Links: | GitHub · npm |
SearchPicker (Vue helper)
A headless Vue 3 site-search control: a single-icon button (a bundled
magnifying-glass SVG) that opens a dropdown holding a search field and,
at its right, a submit button labelled ⏎. Pressing Return in the field,
or the ⏎ button, navigates to /?<query> — a search for foo goes to
/?foo.
A port of the canonical
@lilydesignsystem/svelte-search-picker.
The single source of truth is spec/index.md. This file
is the human-readable guide.
Install
import { SearchPicker, searchHref } from "@lilydesignsystem/vue-search-picker";
Quick start
<script setup lang="ts">
import SearchPicker from "@lilydesignsystem/vue-search-picker";
</script>
<template>
<SearchPicker
label="Search this site"
input-label="Search terms"
submit-label="Search"
/>
</template>
That is the whole wiring: a search for foo performs a GET to /?foo.
Where the search goes
The destination is searchHref(query, action):
| You type | action |
Destination |
|---|---|---|
foo |
"/" |
/?foo |
foo bar |
"/" |
/?foo%20bar |
a&b |
"/" |
/?a%26b |
foo |
"/search" |
/search?foo |
The query is trimmed and URI-encoded, so spaces and & cannot split or
corrupt it. An empty query goes nowhere.
The bare query (/?foo, not /?q=foo) is why the component navigates
in script: a native GET form always sends name=value pairs, so it
cancels the native submission and navigates to the exact URL itself.
Client-side routing
By default the component calls location.assign(href) — a real GET
request. In a single-page app, pass your router's navigate function so
the search stays in-app:
<script setup lang="ts">
import { useRouter } from "vue-router";
import SearchPicker from "@lilydesignsystem/vue-search-picker";
const router = useRouter();
</script>
<template>
<SearchPicker
label="Search this site"
input-label="Search terms"
submit-label="Search"
:navigate="(href) => router.push(href)"
/>
</template>
The search event (@search="(query, href) => …") fires before
navigating, for analytics or to record the query.
Props, events, slot
Full table in spec/index.md §4.1. Required:
label, inputLabel, submitLabel — no English defaults, because every
user-facing string is yours to localise. Optional: placeholder,
value (v-model:value), action, navigate, class.
Events: search(query, href) and update:value(value). The default
scoped slot replaces the icon and receives { open, query }.
Accessibility
- The icon is
aria-hidden; the button's name comes fromlabel. - The dropdown is a real
<form role="search">— a search landmark named bylabel— with a realtype="search"field andtype="submit"button, so Return-to-submit and mobile search keyboards just work. ⏎is the visible label only: it isaria-hidden, and the submit button's name issubmitLabel.- Opening focuses the field;
Escapecloses and returns focus to the button; clicking outside or tabbing away closes. - See docs/accessibility.md for the tradeoffs.
Styling
Class hooks: .search-picker (root), .search-picker-button,
.search-picker-icon, .search-picker-panel, .search-picker-form,
.search-picker-input, .search-picker-submit,
.search-picker-submit-symbol.
The package ships no CSS beyond the icon markup.
Tests
npx vitest run lily-design-system-vue-search-picker from the catalog
root — 24 cases, one per §7 clause.
Lily™ and Lily Design System™ are trademarks.
Related Packages
Lily Design System Vue 3 locale picker: an icon button opening an APG listbox th...
Lily Design System Vue 3 theme picker: an icon button opening an APG listbox tha...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.2.0 | ^3.0.0 | MIT OR Apache-2.0 OR GPL-2.0-only OR GPL-3.0-only OR BSD-3-Clause | |
| 0.1.0 | ^3.0.0 | MIT OR Apache-2.0 OR GPL-2.0-only OR GPL-3.0-only OR BSD-3-Clause |
Pre-releases (1)
| Version | Released | License |
|---|---|---|
| 0.0.0-stage |