Skip to content

[Feature](ComboBox): Add options to clear search and selected value after item selection #1627

@ArtieReus

Description

@ArtieReus

Description

Add optional props to ComboBox to automatically clear the internal search query and/or selected value after an item is selected. This would provide flexibility for different use cases while maintaining backward compatibility.

Problem Statement

The ComboBox component currently maintains both the search query and selected value in its internal state even after an item is selected. This behavior has different implications for different use cases:

Current behavior is beneficial when:

  • Using the search query to display badges/pills outside the component
  • Showing what the user searched for as context
  • Displaying the selected value in the input field
  • Single-select scenarios where the selection should persist

Current behavior is problematic when:

  • Users want to select multiple items sequentially (e.g., adding multiple filters)
  • The search query filters out all items when reopening the dropdown
  • The selected value blocks the input, making it hard to select another item
  • Users expect a "clean slate" after each selection

Example Issue

In Supernova's alert filtering (multi-select use case):

  1. User types "prod" to filter values
  2. User selects "production" from filtered results
  3. User reopens the dropdown to select another filter value
  4. The dropdown still shows "prod" in the search input, filtering the results
  5. The selected value "production" is displayed in the input
  6. User must manually clear both the search and selection to continue

Proposed Solution

Add two optional boolean props to ComboBox:

export interface ComboBoxProps {
  // ... existing props
  /**
   * If true, automatically clear the search input after an item is selected.
   * @default false
   */
  clearSearchOnSelect?: boolean
  
  /**
   * If true, automatically clear the selected value after an item is selected.
   * Useful for multi-select scenarios where the input should reset after each selection.
   * @default false
   */
  clearValueOnSelect?: boolean
}

Implementation (ComboBox.component.tsx, lines 305-314):

const handleChange = (value: string | null) => {
  const stringValue = value || ""
  
  // Call onChange before clearing (so parent gets the selected value)
  onChange && onChange(stringValue)
  
  // Update internal state
  setSelectedValue(clearValueOnSelect ? "" : stringValue)
  
  if (stringValue) {
    setIsOpen(false)
    if (clearSearchOnSelect) {
      setQuery("") // Clear the search query if prop is enabled
    }
  }
}

Usage:

// Default behavior (backward compatible)
<ComboBox onChange={handleChange}>
  {/* search and value persist after selection */}
</ComboBox>

// Clear only search
<ComboBox clearSearchOnSelect onChange={handleChange}>
  {/* search clears, but selected value remains */}
</ComboBox>

// Clear only value
<ComboBox clearValueOnSelect onChange={handleChange}>
  {/* value clears, but search query remains */}
</ComboBox>

// Clear both (multi-select use case)
<ComboBox clearSearchOnSelect clearValueOnSelect onChange={handleChange}>
  {/* both search and value clear after selection */}
</ComboBox>

Alternatives Considered

  1. Always clear both - Breaking change for existing use cases that rely on persistent state
  2. Expose both as controlled props - More complex API, requires parent to manage all state
  3. Force remount with key prop - Current workaround we're using, but causes unnecessary remounting and performance issues
  4. Single prop with enum values - Less flexible than two independent boolean props

Additional Context

Current Workaround:

We're force remounting the ComboBox by incrementing a key prop after selection, and managing value clearing with a setTimeout hack:

const [comboBoxKey, setComboBoxKey] = useState(0)
const [filterValue, setFilterValue] = useState("")

const handleChange = (value) => {
  // Process the selection
  addFilter(value)
  
  // setTimeout defers clearing to next tick so React renders the selected value first before clearing
  setTimeout(() => {
    setFilterValue("")
  }, 0)
  
  // Increment key to force remount and clear internal search state
  setComboBoxKey(prev => prev + 1)
}

<ComboBox 
  key={comboBoxKey} 
  value={filterValue}
  onChange={handleChange} 
  ... 
/>

This works but is not ideal as it:

  • Causes the entire component to remount (performance)
  • Loses focus management
  • Causes potential UI flicker
  • Requires brittle setTimeout hack for value clearing

Related Code:

  • packages/ui-components/src/components/ComboBox/ComboBox.component.tsx (lines 220, 285-287, 305-314, 316-319)
  • Workaround: apps/supernova/src/components/filters/FilterSelect.tsx (lines 32-38, 54-78, 147-156)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions