Skip to content

GemStone Search: UI polish pass — control alignment, search/no-results feedback, fuzzy Literal scope, and non-toggle control styling #471

Description

@MatiasFernandez

Summary

A batch of usability and visual-consistency improvements to the GemStone Search panel
(client/src/omniSearch/): fixing vertical alignment of the scope pills and the clear button,
giving the user clearer feedback while a search runs and when nothing was found, making the
Literal scope honor the selected matching algorithm, and reworking the styling of the multi-value
controls so they stop looking like on/off toggles.

Acceptance criteria

Alignment

  • The scope pills (.tab) render with their label vertically centered within the pill.
  • The clear ("×") button is vertically centered within the search input field.

In-flight search feedback

  • While a search is running, the panel shows explicit feedback that it is working — a spinner, a
    "Searching…" line under the input field, or whatever is most idiomatic for VS Code. Today the
    only cue is a subtle background shimmer on the input (body.busy #query), which is easy to miss.

No-results feedback

  • When a search completes with zero results, the footer count shows an explicit message
    ("No results found" / "0 found" / similar) instead of going blank. Currently updateFooter
    renders an empty string for n === 0 outside pivot mode, so a finished empty search looks
    identical to a search that never ran.

Literal scope matching

  • The Literal scope honors the currently selected matching algorithm, so Fuzzy mode fuzzy-matches
    instead of requiring an exact whole-term match.
  • Typing a bare name (no surrounding '…' and no leading #) still finds the corresponding string
    and symbol literals, so the user isn't forced to type the Smalltalk literal syntax to search.

Control styling

  • The multi-value controls (Scopes, matching mode) are visually distinguishable from the true
    on/off toggles (case sensitivity, preview pane), rather than sharing the toggle chip's
    "untoggled"/dimmed look — which reads as "off" for a control that is never off.
  • The matching mode control is discoverable as a multi-value setting rather than a click-to-cycle
    chip; a dropdown/context menu in the same style as the Scopes menu is one candidate.

Implementation notes

Possible starting points, not a prescribed design:

  • The pill and clear-button rules live in the inlined stylesheet in
    client/src/omniSearch/omniSearchShared.ts (.tab around the #tabs block, #clear just below
    the #query rule). Neither sets a line-height or uses flex centering, which is the likely cause.
  • The busy state already round-trips from the host (busy message → setBusy in
    client/src/omniSearch/omniSearchView.js, toggling body.busy), so an explicit indicator could
    potentially hang off that same class rather than needing new plumbing.
  • The zero-results text would go in updateFooter in omniSearchView.js, though it may need to
    distinguish "search finished with nothing" from "no search has run yet" (and from an empty query)
    so an idle panel doesn't advertise zero results.
  • The Literal scope is client/src/omniSearch/providers/literalsProvider.ts. Worth noting a real
    constraint there: the #symbol branch evaluates an expression on the stone, and
    isSymbolLiteral/SYMBOL_LITERAL_RE is deliberately a strict shape gate so partial or injecting
    input never reaches the server. Any relaxation toward fuzzy/unquoted terms would need to keep that
    guarantee — e.g. by treating the typed text as data to match against rather than as an expression
    to compile, or by synthesizing a well-formed literal from it.
  • The control chips share one CSS rule (#previewToggle, #scopeFilter, #matchMode) with an
    .active variant, which is exactly why the multi-value controls inherit the toggle look. Splitting
    the multi-value controls into their own rule — and reusing the existing #scopeFilterMenu pattern
    for a matching-mode menu — is one direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestideIDE component

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions