@lilydesignsystem/vue-search-picker

Lily Design System Vue 3 search picker: a magnifying-glass icon button opening a search field with a ⏎ submit button that navigates to /? . Headless, SSR-safe, no CSS.
644 3
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
Maintainer: joelparkerhenderson

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 from label.
  • The dropdown is a real <form role="search"> — a search landmark named by label — with a real type="search" field and type="submit" button, so Return-to-submit and mobile search keyboards just work.
  • ⏎ is the visible label only: it is aria-hidden, and the submit button's name is submitLabel.
  • Opening focuses the field; Escape closes 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

@lilydesignsystem/vue-locale-picker

Lily Design System Vue 3 locale picker: an icon button opening an APG listbox th...

1,260 3
@lilydesignsystem/vue-theme-picker

Lily Design System Vue 3 theme picker: an icon button opening an APG listbox tha...

1,137 3
@lilydesignsystem/vue-text-size-picker

Lily Design System - Vue 3 text size picker

1,113 3
@lilydesignsystem/vue-motion-picker

Lily Design System - Vue 3 motion (reduced-motion) picker

816 3
@lilydesignsystem/vue-picker-bar

Lily Design System Vue 3 picker bar: composes link-picker (optional), search-pic...

648 3

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