Skip to content

feat(search): allow free-text values when editing a filter pill#2471

Open
zoov-xavier wants to merge 2 commits into
hyperdxio:mainfrom
zoov-xavier:claude/editable-filter-pill-free-text-value
Open

feat(search): allow free-text values when editing a filter pill#2471
zoov-xavier wants to merge 2 commits into
hyperdxio:mainfrom
zoov-xavier:claude/editable-filter-pill-free-text-value

Conversation

@zoov-xavier

Copy link
Copy Markdown

Summary

The active filter pill's value picker (added in #2455) is a closed Select limited to the field's existing values. That means a filter can only ever be switched to a value already present in the sampled data. This PR replaces it with a Mantine Autocomplete so you can type any value while still seeing the existing suggestions.

  • Typed free text is committed on Enter or blur, in addition to picking from the suggestion list.
  • The picker opens with an empty input (the current value shown as a placeholder), so the full suggestion list is visible instead of being filtered down to just the current value.
  • Keyboard navigation is preserved: when an option is highlighted (Mantine marks it with [data-combobox-selected]), Enter submits that option natively via onOptionSubmit; free text is only committed when no option is highlighted.
  • A commit guard prevents applying the same value twice (picking an option fires onOptionSubmit, then onBlur as the menu closes).
  • Copy, polarity flip (include/exclude), one-click remove, and range/not-applied pill behavior are unchanged.

Why

Editing a pill only let you switch to a value that already exists in the data. When you want to filter on a value that hasn't appeared yet (a new service name, a release tag about to ship, an error code not seen in the sample window), you had no way to enter it from the pill — you had to type it as a raw query instead. Free-text entry closes that gap while keeping the suggestion-driven flow for the common case.

Test plan

  • yarn ci:unit ActiveFilterPills.test.tsx — 28 tests, incl. new coverage for free-typed values not in the list and for keyboard-navigated option selection via Enter
  • tsc --noEmit on @hyperdx/app — clean
  • yarn lint on @hyperdx/app — 0 errors
  • Manual: drove the pill menu in the dev stack — typing a value absent from the data and pressing Enter applies it; arrow-key navigation + Enter selects the highlighted option

A changeset (@hyperdx/app: patch) is included.

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

@zoov-xavier is attempting to deploy a commit to the HyperDX Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 436a7fd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

The active filter pill's value picker was a closed Select limited to the
field's existing values, so a filter could only be switched to a value
already present in the sampled data. Replace it with an Autocomplete that
accepts arbitrary typed input (committed on Enter or blur) while keeping
the existing suggestions.

Keyboard navigation of the dropdown is preserved: when an option is
highlighted, Enter submits that option natively; free text is only
committed when no option is highlighted. A commit guard avoids applying
the same value twice (onOptionSubmit followed by onBlur).
@zoov-xavier zoov-xavier force-pushed the claude/editable-filter-pill-free-text-value branch from 3afe05b to 828dc53 Compare June 16, 2026 14:15
@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the closed Select in the filter pill's value picker with a Mantine Autocomplete, enabling free-text entry committed on Enter or blur in addition to suggestion-list selection. The previous comment about a global document.querySelector has been addressed by scoping the highlighted-option lookup to the input's own listbox via aria-controls.

  • Free-text flow: a draftValue state tracks typed input; a committedRef ref guards against the double-commit that would otherwise occur when onOptionSubmit fires followed by the onBlur from the dropdown closing.
  • Keyboard navigation: onKeyDown checks aria-controls to locate this input's own listbox, letting Mantine's combobox handle Enter natively when an option is highlighted and committing free text only otherwise.
  • Tests: two new cases cover keyboard-navigated selection and free-typed values not present in the suggestion list.

Confidence Score: 4/5

Safe to merge with one known UX edge case around the Copy button when the Autocomplete input has focus.

The core free-text commit logic is well-guarded by committedRef and the aria-controls-scoped keyboard check is a solid improvement over a global DOM query. The one rough edge is that onBlur always calls commitValue + setOpened(false) without checking whether focus moved to another element inside the same Dropdown — specifically the Copy button. In that scenario the user gets the pre-draft value on the clipboard, the draft is committed silently, and the Copied checkmark is never visible because the popover closes in the same render. The fix is isolated and the core feature behaviour is correct.

packages/app/src/components/ActiveFilterPills.tsx — the onBlur handler on the Autocomplete

Important Files Changed

Filename Overview
packages/app/src/components/ActiveFilterPills.tsx Replaces the closed Select with a Mantine Autocomplete to allow free-text entry; introduces draft state, a commit guard ref, and scoped aria-controls DOM query for keyboard navigation. The onBlur handler always commits+closes, which can produce a wrong clipboard copy and invisible feedback when the input has focus and the Copy button is clicked.
packages/app/src/components/tests/ActiveFilterPills.test.tsx Adds two new tests covering keyboard-navigated option selection and free-typed value submission; existing test suite structure is preserved.
.changeset/filter-pill-free-text-value.md Changeset entry correctly marked as a patch for @hyperdx/app with an accurate description of the free-text entry feature.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User opens filter pill] --> B[Popover opens
useEffect resets draftValue and committedRef]
    B --> C[Autocomplete renders with empty value
current pill shown as placeholder]
    C --> D{User action}
    D -->|Types text| E[draftValue updates via onChange]
    D -->|Arrow keys| F[Mantine highlights option
data-combobox-selected set]
    E --> G{Enter pressed}
    F --> G
    G -->|listbox has highlighted option| H[Let Mantine handle Enter natively
onOptionSubmit fires]
    G -->|No highlighted option| I[e.preventDefault
commitValue draftValue]
    H --> J[commitValue selected option]
    D -->|Clicks option| J
    D -->|Blurs input| K[commitValue draftValue]
    J --> L{trimmed != pill.value and not already committed?}
    K --> L
    I --> L
    L -->|Yes| M[committedRef = true
onReplaceValue trimmed
setOpened false]
    L -->|No| N[setOpened false only]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[User opens filter pill] --> B[Popover opens
useEffect resets draftValue and committedRef]
    B --> C[Autocomplete renders with empty value
current pill shown as placeholder]
    C --> D{User action}
    D -->|Types text| E[draftValue updates via onChange]
    D -->|Arrow keys| F[Mantine highlights option
data-combobox-selected set]
    E --> G{Enter pressed}
    F --> G
    G -->|listbox has highlighted option| H[Let Mantine handle Enter natively
onOptionSubmit fires]
    G -->|No highlighted option| I[e.preventDefault
commitValue draftValue]
    H --> J[commitValue selected option]
    D -->|Clicks option| J
    D -->|Blurs input| K[commitValue draftValue]
    J --> L{trimmed != pill.value and not already committed?}
    K --> L
    I --> L
    L -->|Yes| M[committedRef = true
onReplaceValue trimmed
setOpened false]
    L -->|No| N[setOpened false only]
Loading

Reviews (2): Last reviewed commit: "refactor(search): address review on free..." | Re-trigger Greptile

Comment thread packages/app/src/components/ActiveFilterPills.tsx Outdated
Comment thread packages/app/src/components/ActiveFilterPills.tsx
Comment thread packages/app/src/components/__tests__/ActiveFilterPills.test.tsx Outdated
- Scope the highlighted-option lookup to this input's own listbox (via
  aria-controls) instead of the whole document, so another open combobox
  on the page can't make us swallow Enter and drop free-text entry.
- Pin the keyboard-navigation test to the expected option ('404') instead
  of accepting any value from the list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant