Skip to main content
View as Markdown

Search Components

Where tables declare what is searchable and engines declare how a query runs (see search-overview), components are where search appears on the page. Sovrium provides four complementary pieces: a searchInput that drives a query, a list that renders results, a pageSearch that indexes static page content, and toolbar search built into data components.

Component Purpose
searchInput Standalone search box that drives another component via dataSource.bindTo.
list Search-first result display with item templates, highlighting, and pagination.
pageSearch Site-wide static search over public page content (build/start-time index).
toolbar search In-component search bar on data-table, kanban, calendar, etc.

searchInput

A standalone search box. On its own it renders an accessible input; bound to a data source it becomes the query driver for a sibling component. Pair it with a list (or data-table) whose data source sets bindTo to the input's props.id.

Property Description
props.id Identifier other components reference via dataSource.bindTo.
visibility Standard visibility controls (shared across components).
i18n Standard internationalization fields (translatable label/placeholder).
app.yaml
components:
  # 1. The input drives the query
  - type: searchInput
    props: { id: product-query }

  # 2. The list consumes it via bindTo
  - type: list
    dataSource:
      table: products
      mode: search
      searchFields: [name, description]
      searchEngine: hybrid
      debounceMs: 300
      bindTo: product-query
    listDisplay:
      itemTemplate:
        title: '$record.name'
        subtitle: '$record.description'
      highlight: true

list — result display

The list component is designed as a search-first display: the natural companion for searchInput. It renders each record through an item template with optional highlighting, dividers, and load-more pagination.

Property Description
itemTemplate.title Primary text via a $record.* reference (e.g. $record.name).
itemTemplate.subtitle Secondary text (e.g. $record.description).
itemTemplate.image Image URL (e.g. $record.thumbnail).
itemTemplate.badge Badge text (e.g. $record.category).
itemTemplate.metadata Array of { field, format } shown in the item footer (currency, relative-date, badge, text, short-date).
emptyMessage Message shown when no results match.
loadMore button (Load More button) or infinite (load on scroll).
highlight Boolean. Highlight matched search terms in item text (default false).
divider Boolean. Show visual dividers between items (default false).
maxItems Maximum number of items to display (integer ≥ 1).
app.yaml
- type: list
  dataSource:
    table: products
    mode: search
    searchFields: [name, description]
    bindTo: product-query
  listDisplay:
    itemTemplate:
      title: '$record.name'
      subtitle: '$record.description'
      image: '$record.thumbnail'
      badge: '$record.category'
      metadata:
        - field: price
          format: currency
    emptyMessage: No products found
    loadMore: infinite
    highlight: true
    divider: true
    maxItems: 50

pageSearch — static page index

A site-wide search component that indexes public pages (access missing or access: 'all') at sovrium build time and sovrium start boot. The index is a JSON file plus a tiny client runtime under <outputDir>/sovrium-search/, served by the public-dir route. This is a different layer from record search — it searches page content, not table rows.

Property Description
placeholder Placeholder text shown in the search input.
maxResults Maximum number of results to display (positive integer).
visibility Standard visibility controls.
i18n Standard internationalization fields.
app.yaml
pages:
  - id: home
    name: home
    path: /
    components:
      - type: pageSearch
        placeholder: Search the site...
        maxResults: 10

The platform palette (app.palette)

Sovrium appends its own command palette to every page and binds ⌘K / Ctrl+K to it. You get it for free — no configuration.

That becomes a problem exactly once: when your app ships its own ⌘K overlay. Both open on the same keystroke. Opt out at the app level:

app.yaml
palette:
  enabled: false
Property Description
enabled Append the platform palette and register its keybinding. Defaults to true.

With enabled: false the component is not rendered and no global keybinding is registered, leaving ⌘K free for your own overlay. Leave the block out entirely unless you are opting out.

Data components expose an in-component search bar through their toolbar. On a data-table, set toolbar.search: true to render a global search input over the bound rows — a quick filter without a separate searchInput.

Toolbar flag Description
search Show the global search input.
filters Show the filter builder.
sort Show the sort builder.
app.yaml
- type: data-table
  dataSource:
    table: orders
    mode: search
    searchFields: [customer, reference]
  toolbar:
    search: true
    filters: true
    sort: true

Kanban and calendar components share a search configuration for their own in-component search bar via the same pattern.

Highlighting and debounce

  • Highlighting — set highlight: true on list (listDisplay.highlight) to wrap matched terms in result text. Off by default.
  • Debounce — set debounceMs on the data source (e.g. 300) so the query fires only after the user pauses typing, preventing a request per keystroke.

These work together: a searchInput emits keystrokes, the bound data source debounces and queries, and the list highlights matches in the rendered results.

Last updated August 11, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium