Primitives / foldkit-primitives/interaction

Typeahead

namespace · packages/primitives/src/interaction/typeahead.ts:7

export * as Typeahead from './typeahead.js'

Typeahead over a set of items: printable keys build a query that a timer clears, and the query picks the item to move to. The query lives in the Model so a replay sees the same picks; the timer runs on Effect's clock so TestClock drives it. Which item matches is a pure function.

In the guides

Members

Typeahead.Args

const · packages/primitives/src/interaction/typeahead.ts:34

const Args: Schema.Struct<{ readonly timeoutMs: Schema.Number }>

Typeahead.behavior

function · packages/primitives/src/interaction/typeahead.ts:122

function behavior<Field extends string>(
  declared: Declared<typeof bundle, Field>,
): <Slots>(
  slots: Slots,
) => <Input extends { readonly [K in Field]: Model }, ParentMessage>(
  options: BehaviorOptions<Input, Slots>,
) => Behavior.NamedBehavior<Slots, Input, ParentMessage>

Wires a placed Typeahead to the host slot: a printable key extends the query, focuses the matching item by its id (which then reports itself current, through RovingTabindex's OnFocus), and dispatches Typed. With no match the key still extends the query, so the next one can match; a space with an empty query is left to the host (it activates).

Typeahead.BehaviorOptions

interface · packages/primitives/src/interaction/typeahead.ts:104

interface BehaviorOptions<Input, Slots> {
  readonly host: keyof Slots & string
  readonly items: (input: Input) => Behaviors.Collection.Items<unknown>
  readonly text: (input: Input, index: number) => string
  readonly current: (input: Input) => string | null
}

Typeahead.bundle

const · packages/primitives/src/interaction/typeahead.ts:43

const bundle: Bundle.Bundle<
  'Typeahead',
  { readonly timeoutMs: number },
  { readonly query: string; readonly generation: number },
  | { readonly _tag: 'Cleared' }
  | { readonly _tag: 'Typed'; readonly char: string }
  | { readonly _tag: 'Expired'; readonly generation: number },
  never,
  never,
  never,
  void,
  {},
  {}
>

Typeahead.isPrintable

function · packages/primitives/src/interaction/typeahead.ts:101

function isPrintable(key: string, modifiers: KeyboardModifiers): boolean

A single character with no ctrl, alt or meta: a typeahead key.

Typeahead.match

function · packages/primitives/src/interaction/typeahead.ts:82

function match(
  texts: ReadonlyArray<string>,
  enabled: ReadonlyArray<number>,
  query: string,
  current: number,
): number | undefined

The enabled index whose text starts with query, searching forward from current and wrapping, or undefined. A query of one character, or one character repeated (aaa), starts after the current item so repeated presses cycle through the items that begin with it; a longer query starts at the current item, since the user is refining a match. Case and leading whitespace are ignored.

Typeahead.Message

const · packages/primitives/src/interaction/typeahead.ts:24

const Message: MessageUnion<{
  readonly Typed: { readonly char: Schema.String }
  readonly Expired: { readonly generation: Schema.Number }
  readonly Cleared: {}
}>

Typeahead.Model

const · packages/primitives/src/interaction/typeahead.ts:16

const Model: Schema.Struct<{
  readonly query: Schema.String
  readonly generation: Schema.Number
}>