Skip to content

useTypeahead

Buffer typed text for keyboard navigation.

useTypeahead collects text and clears it after a pause. Use it for custom menus or lists. It does not attach keyboard listeners, choose matches, or move focus.

Usage

Normalize text before calling push. Ignore modifier keys and editing targets in your own keyboard handler.

vue
<script setup lang="ts">
import { useTypeahead } from "akaza-ui";

const { query, push, reset } = useTypeahead({ timeout: 500 });

function onKeydown(event: KeyboardEvent) {
  if (event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return;
  push(event.key.toLocaleLowerCase());
}
</script>

<template>
  <button
    type="button"
    @keydown="onKeydown"
    @blur="reset"
  >
    Type to build a query
  </button>
  <output>{{ query }}</output>
</template>

Match the returned query against your items, then apply your control's focus or selection rules. Existing Akaza components already handle their own typeahead; consumers do not need to wire this helper into them.

Repeated Characters

Set resetOnRepeatedCharacter: true to keep repeated letters as a single-character query. For example, consecutive a presses return a, not aa. Your matching code must search after the current item to cycle through matches. The default keeps repeated characters.

API Reference

ts
<Dialog
  :ui="{
    overlay: 'fixed inset-0 bg-black/50 backdrop-blur-sm',
    content: 'bg-white rounded-xl shadow-xl w-full max-w-md',
    header: 'flex items-center justify-between p-6 border-b',
    body: 'p-6',
    footer: 'flex justify-end gap-2 p-6 border-t',
  }"
>
OptionTypeDefaultDescription
timeoutMaybeRefOrGetter<number>500Milliseconds before clearing. Read on each nonempty push; changes do not reschedule a pending timer.
resetOnRepeatedCharacterbooleanfalseRestart a query containing only repetitions of the new character. Set when creating the composable.
ReturnTypeDescription
queryReadonly<Ref<string>>Current buffered text.
push(text: string) => stringAppend normalized text, restart the timer, and return the query. Empty text leaves the query and timer unchanged.
reset() => voidClear text and cancel the timer.

SSR and Scope

Call in component setup or an active Vue effect scope. Timers are canceled when that scope stops. Creating the composable does not access the DOM or schedule a timer, so it is safe during SSR. Call push from client interaction handlers.

Edit this page on GitHub ↗