SearchArea recipe

Source: 02_SearchArea/ · three flavours of SearchArea shown side-by-side in a Pivot so you can compare them.

How it looks

A search box, a facet sidebar, and a column of result cards. The real SearchArea queries the workspace; the runnable Tesserae preview below sketches the same layout with static data.

What it teaches

  • Default — SearchArea() with nothing customised. Hits the workspace's default search endpoint and renders the standard result cards.
  • With facets — Pre-filter the query with OnSearch(sr => sr.SetBeforeTypesFacet("...")) and enable the facet sidebar with .WithFacets(). The right starting point for "search inside a single node type".
  • Custom row — Adjust the search-result row with Renderer(r => r.CustomizeResult(result => ...)). You receive the row the node type built, with the search's own marks already on it, and return the same row or another one. Use this when you need a denser list, custom row commands, or to surface fields the default row doesn't show.
  • Appending a button next to the search box with SearchBox(b => b.AppendToSearchBox(...)).

Three flavours

// 1. Default
SearchArea()

// 2. Filter to one node type + facet sidebar
SearchArea()
    .OnSearch(sr => sr.SetBeforeTypesFacet(nameof(MyNodeType)))
    .WithFacets()

// 3. Customize the result row
SearchArea()
    .Renderer(r => r.CustomizeResult(result => result
       .SetText(null)
       .InlineCommands(Button().SetIcon(UIcons.Plus).OnClick(() => Select(result.Result)))))
    .SearchBox(b => b.AppendToSearchBox(Button("Action").SetIcon(UIcons.Bolt)))

The product's main search box understands @file, @webpage, filetype:, ext: and src: (see Search Box Filters). A SearchArea's box starts without them. SearchBox(...) hands you its AdvancedOmniBox, which takes the built-in set and filters of your own:

SearchArea()
    .OnSearch(sr => sr.SetBeforeTypesFacet(nameof(Ticket)))
    .SearchBox(b => b
       .WithBasicSearchFilters()
       .RegisterSnapFilter(
           new OmniBox.SnapHandler("open", "Open tickets".t(), new[] { "open" }, Icon(UIcons.Inbox), "Only show open tickets".t()),
           sr => sr.SetValueFacet("Ticket.Status", keepOtherTypes: false, invertedBehaviour: false, applyBefore: true, values: new[] { "Open" }))
       .RegisterFilterSnap(
           new OmniBox.FilterSnapHandler("priority", "Priority".t(), new[] { "priority", "prio" }, new[] { "P1", "P2", "P3" }, Icon(UIcons.Flag), "Filter by priority".t()),
           (sr, value) => sr.SetValueFacet("Ticket.Priority", keepOtherTypes: false, invertedBehaviour: false, applyBefore: true, values: new[] { value })))
Method Adds The callback receives
WithBasicSearchFilters() The five built-in filters from OmniBoxSearchFilters n/a
RegisterSnapFilter(SnapHandler, Action<SearchRequest>) An @word chip with no value The request being built
RegisterFilterSnap(FilterSnapHandler, Action<SearchRequest, string>) A word:value chip The request and the chip's value
  • The callback runs when the search is built, once per chip in the box. Narrow the request there, usually with SetBeforeTypesFacet or SetValueFacet(..., applyBefore: true, ...).
  • A FilterSnapHandler takes its values as a fixed string[] or as a Func<string, Task<string[]>> that receives what the user has typed so far. Use the async form for values that come from the server, as the built-in src: filter does.
  • Handlers carry the icon component they render, so build a new handler for each box rather than sharing one instance.
  • The id (the first constructor argument) is how a chip is matched back to its callback. Keep it unique within one box.

UI.Neighbors(...) and SimilarSearchArea.SearchBox(...) accept the same Action<AdvancedOmniBox>. None of this changes the main search box, whose filter set is fixed in OmniBoxSearchFilters.

See also

  • Migrating to OmniResult — the recipes for what WithCardCustomizer / WithCustomizedRenderer / WithRenderer used to do.
  • Omni Result — every slot and option on the row CustomizeResult hands you.
  • The Connector Recipes cover how to ingest the data this search area queries.