feat(search): allow free-text values when editing a filter pill#2471
feat(search): allow free-text values when editing a filter pill#2471zoov-xavier wants to merge 2 commits into
Conversation
|
@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 detectedLatest commit: 436a7fd The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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).
3afe05b to
828dc53
Compare
Greptile SummaryThis PR replaces the closed
Confidence Score: 4/5Safe 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
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]
%%{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]
Reviews (2): Last reviewed commit: "refactor(search): address review on free..." | Re-trigger Greptile |
- 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.
Summary
The active filter pill's value picker (added in #2455) is a closed
Selectlimited 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 MantineAutocompleteso you can type any value while still seeing the existing suggestions.[data-combobox-selected]), Enter submits that option natively viaonOptionSubmit; free text is only committed when no option is highlighted.onOptionSubmit, thenonBluras the menu closes).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 Entertsc --noEmiton@hyperdx/app— cleanyarn linton@hyperdx/app— 0 errorsA changeset (
@hyperdx/app: patch) is included.