> ## Documentation Index
> Fetch the complete documentation index at: https://docs.samplehc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payer Search Combobox

> Searchable combobox for finding healthcare payers with autocomplete and alias support

## Overview

The PayerSearchCombobox provides a powerful search interface for finding healthcare payers and insurance providers. It features real-time search, autocomplete suggestions, alias support, and integration with the SampleHC clearinghouse database.

## Basic Usage

<CodeGroup>
  ```tsx Simple Payer Search theme={null}
  import { PayerSearchCombobox } from "@samplehc/ui/components";
  import { useState } from "react";

  function PayerSelection() {
    const [selectedPayer, setSelectedPayer] = useState(null);

    return (
      <div className="space-y-4">
        <PayerSearchCombobox
          placeholder="Search for insurance provider..."
          onSelect={setSelectedPayer}
          value={selectedPayer}
        />
        
        {selectedPayer && (
          <div className="p-4 bg-muted rounded-md">
            <h3 className="font-semibold">{selectedPayer.displayName}</h3>
            <p className="text-sm text-muted-foreground">
              Payer ID: {selectedPayer.primaryPayerId}
            </p>
          </div>
        )}
      </div>
    );
  }
  ```

  ```tsx Form Integration theme={null}
  import { PayerSearchCombobox } from "@samplehc/ui/components";
  import { useTaskState } from "@samplehc/ui/data";

  function InsuranceForm() {
    const [formData, setFormData] = useTaskState("insurance", {});

    const handlePayerSelect = (payer) => {
      setFormData({
        ...formData,
        primaryInsurance: payer
      });
    };

    return (
      <div className="space-y-6">
        <div>
          <label className="block text-sm font-medium mb-2">
            Primary Insurance Provider
          </label>
          <PayerSearchCombobox
            onSelect={handlePayerSelect}
            value={formData.primaryInsurance}
            required
          />
        </div>
        
        <div>
          <label className="block text-sm font-medium mb-2">
            Secondary Insurance Provider
          </label>
          <PayerSearchCombobox
            onSelect={(payer) => setFormData({
              ...formData,
              secondaryInsurance: payer
            })}
            value={formData.secondaryInsurance}
            placeholder="Select secondary insurance (optional)"
          />
        </div>
      </div>
    );
  }
  ```
</CodeGroup>

## API Reference

### PayerSearchComboboxProps

<ParamField path="onSelect" type="function">
  Callback function called when a payer is selected or cleared.

  ```tsx theme={null}
  onSelect?: (item: PayerSearchItem | null) => void
  ```
</ParamField>

<ParamField path="value" type="PayerSearchItem | null">
  Currently selected payer item for controlled component behavior.
</ParamField>

<ParamField path="disabled" type="boolean">
  Disable the combobox interaction. Defaults to false.
</ParamField>

<ParamField path="required" type="boolean">
  Mark the field as required for form validation. Defaults to false.
</ParamField>

<ParamField path="className" type="string">
  Additional CSS classes to apply to the trigger element.
</ParamField>

<ParamField path="placeholder" type="string">
  Placeholder text shown when no payer is selected. Defaults to "Search payers...".
</ParamField>

<ParamField path="id" type="string">
  HTML id attribute for the combobox. Defaults to "payer-search-combobox".
</ParamField>

<ParamField path="ref" type="React.Ref<HTMLDivElement>">
  Ref forwarded to the combobox trigger element.
</ParamField>

### PayerSearchItem

<ResponseField name="stediId" type="string" required>
  Unique identifier for the payer in the Stedi clearinghouse system.
</ResponseField>

<ResponseField name="displayName" type="string" required>
  Primary display name for the payer (e.g., "Blue Cross Blue Shield").
</ResponseField>

<ResponseField name="primaryPayerId" type="string" required>
  Primary payer identifier used for claims submission.
</ResponseField>

<ResponseField name="aliases" type="string[]" required>
  Array of alternative names and aliases for the payer.
</ResponseField>

<ResponseField name="names" type="string[]" required>
  Array of all known names for the payer, including official names.
</ResponseField>

## Search Hook

You can also use the search functionality independently with the `usePayerSearch` hook:

<CodeGroup>
  ```tsx Custom Search Implementation theme={null}
  import { usePayerSearch } from "@samplehc/ui/components";
  import { useState } from "react";
  import { useDebounce } from "@samplehc/ui";

  function CustomPayerSearch() {
    const [query, setQuery] = useState("");
    const debouncedQuery = useDebounce(query, 250);
    
    const { data: searchResults, isLoading, error } = usePayerSearch(
      debouncedQuery,
      { enabled: debouncedQuery.length >= 2 }
    );

    return (
      <div className="space-y-4">
        <input
          type="text"
          placeholder="Search payers..."
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          className="w-full p-2 border rounded"
        />
        
        {isLoading && <p>Searching...</p>}
        
        {error && (
          <p className="text-red-500">
            Search failed: {error.message}
          </p>
        )}
        
        {searchResults && (
          <div className="space-y-2">
            {searchResults.map((payer) => (
              <div key={payer.stediId} className="p-3 border rounded">
                <h3 className="font-semibold">{payer.displayName}</h3>
                <p className="text-sm text-gray-600">
                  ID: {payer.primaryPayerId}
                </p>
                {payer.aliases.length > 0 && (
                  <p className="text-xs text-gray-500">
                    Also known as: {payer.aliases.join(", ")}
                  </p>
                )}
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }
  ```

  ```tsx usePayerSearch Hook API theme={null}
  // Hook signature
  usePayerSearch(
    query: string,
    options?: { enabled?: boolean }
  )

  // Returns React Query result
  {
    data: PayerSearchItem[],
    isLoading: boolean,
    error: Error | null,
    refetch: () => void,
    // ... other React Query properties
  }
  ```
</CodeGroup>

## Advanced Examples

### Multiple Payer Selection

<RequestExample>
  ```tsx Multiple Payer Form theme={null}
  import { PayerSearchCombobox } from "@samplehc/ui/components";
  import { useState } from "react";
  import { Button } from "@/components/ui/button";
  import { X } from "lucide-react";

  function MultiplePayerSelection() {
    const [selectedPayers, setSelectedPayers] = useState([]);

    const handleAddPayer = (payer) => {
      if (payer && !selectedPayers.find(p => p.stediId === payer.stediId)) {
        setSelectedPayers([...selectedPayers, payer]);
      }
    };

    const handleRemovePayer = (payerId) => {
      setSelectedPayers(selectedPayers.filter(p => p.stediId !== payerId));
    };

    return (
      <div className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-2">
            Add Insurance Providers
          </label>
          <PayerSearchCombobox
            onSelect={handleAddPayer}
            placeholder="Search and add payers..."
          />
        </div>
        
        {selectedPayers.length > 0 && (
          <div className="space-y-2">
            <h3 className="text-sm font-medium">Selected Payers:</h3>
            {selectedPayers.map((payer) => (
              <div
                key={payer.stediId}
                className="flex items-center justify-between p-3 bg-muted rounded-md"
              >
                <div>
                  <span className="font-medium">{payer.displayName}</span>
                  <span className="text-sm text-muted-foreground ml-2">
                    ({payer.primaryPayerId})
                  </span>
                </div>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => handleRemovePayer(payer.stediId)}
                >
                  <X className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }
  ```
</RequestExample>

### Validation and Error Handling

<RequestExample>
  ```tsx Validated Payer Selection theme={null}
  import { PayerSearchCombobox } from "@samplehc/ui/components";
  import { useState } from "react";
  import { Button } from "@/components/ui/button";

  function ValidatedPayerForm() {
    const [selectedPayer, setSelectedPayer] = useState(null);
    const [error, setError] = useState("");

    const validatePayer = (payer) => {
      if (!payer) {
        setError("Please select an insurance provider");
        return false;
      }
      
      // Custom validation logic
      if (!payer.primaryPayerId) {
        setError("Selected payer has invalid configuration");
        return false;
      }
      
      setError("");
      return true;
    };

    const handleSubmit = () => {
      if (validatePayer(selectedPayer)) {
        console.log("Valid payer selected:", selectedPayer);
        // Proceed with form submission
      }
    };

    return (
      <div className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-2">
            Primary Insurance Provider *
          </label>
          <PayerSearchCombobox
            onSelect={(payer) => {
              setSelectedPayer(payer);
              if (payer) setError(""); // Clear error when selection made
            }}
            value={selectedPayer}
            required
            className={error ? "border-red-500" : ""}
          />
          {error && (
            <p className="text-sm text-red-500 mt-1">{error}</p>
          )}
        </div>
        
        <Button 
          onClick={handleSubmit}
          disabled={!selectedPayer}
        >
          Continue
        </Button>
      </div>
    );
  }
  ```
</RequestExample>

## Features

### Real-time Search

* **Debounced Input**: Search queries are debounced (250ms) to reduce API calls
* **On-demand Search**: Search begins when dropdown is opened and query is entered
* **Live Results**: Results update as you type

### Smart Matching

* **Primary Names**: Matches against official payer names
* **Aliases**: Searches through known aliases and alternative names
* **Fuzzy Matching**: Handles minor spelling variations and typos

### User Experience

* **Keyboard Navigation**: Full keyboard support with arrow keys and Enter
* **Loading States**: Visual feedback during search operations
* **Error Handling**: Graceful error handling with retry options
* **Accessibility**: ARIA labels and screen reader support

### Visual Features

* **Alias Display**: Shows number of aliases with tooltip details
* **Clear Selection**: Easy-to-use clear button for selected items
* **Responsive Design**: Works on mobile and desktop devices

## Error Handling

The component includes comprehensive error handling:

<Tabs>
  <Tab title="Network Errors">
    ```tsx theme={null}
    // Automatic retry for temporary network issues
    {
      retry: (failureCount, error) => {
        // Don't retry authentication errors
        if (error.message.includes("Authentication")) {
          return false;
        }
        return failureCount < 2;
      }
    }
    ```
  </Tab>

  <Tab title="Search Errors">
    * **Authentication failures** - Shows authentication error message
    * **Network timeouts** - Provides retry button
    * **Invalid responses** - Graceful degradation with error message
    * **Rate limiting** - Automatic backoff and retry
  </Tab>

  <Tab title="User Feedback">
    * **Error States**: Clear error messages with actionable solutions
    * **Retry Mechanisms**: Easy retry buttons for failed searches
    * **Loading Indicators**: Visual feedback during operations
    * **Empty States**: Helpful messages when no results found
  </Tab>
</Tabs>

## Integration Notes

<Note>
  **Backend Integration**: The component automatically uses the configured backend URL and authentication from the workflow context.
</Note>

<Tip>
  **Performance**: Search results are cached for 30 seconds to improve performance for repeated queries.
</Tip>

<Warning>
  **API Requirements**: Requires valid API credentials and access to the SampleHC clearinghouse endpoints.
</Warning>

## Styling

The component inherits your application's theme and can be customized:

```tsx theme={null}
<PayerSearchCombobox
  className="w-full border-2 border-primary"
  // Applies custom styling to the trigger element
/>
```

All styling is compatible with Tailwind CSS classes and follows the shadcn/ui design system.
