# Searchbar Component

A standalone search input component with debouncing, clear functionality, and keyboard navigation support.

**Selector:** `ccl-searchbar`

## Quick Start

1. **Import the component:**
```typescript
import { SearchbarComponent } from '@Crystal-Code-Labs/ccl-ui-components';
```

2. **Add to your component:**
```typescript
@Component({
  imports: [SearchbarComponent],
  // ... rest of component
})
```

3. **Use in template:**
```html
<ccl-searchbar 
  placeholder="Search products..."
  [debounce]="300"
  [clearable]="true"
  (onSearch)="onSearch($event)">
</ccl-searchbar>
```

## Inputs

- `placeholder: string` – Placeholder text (default: 'Search...')
- `value: string` – Current search value (default: '')
- `debounce: number` – Debounce delay in milliseconds (default: 300)
- `clearable: boolean` – Show clear button when value exists (default: true)
- `disabled: boolean` – Disable the input (default: false)
- `showIcon: boolean` – Show/hide the search icon (default: true)
- `searchIcon?: TemplateRef<unknown>` – Custom search icon template
- `clearIcon?: TemplateRef<unknown>` – Custom clear button icon template

### Icon Defaults and Customization

- **Default prefix icon**: When `showIcon` is true and no `searchIcon` is provided, a built-in magnifier ("🔍") appears before the input.
- **Provide your own icon**: Pass a template via `searchIcon` and/or `clearIcon`.
- **Change icon color**: Use `--color-icon` CSS variable.
- **Add icon background**: Use `--search-icon-bg`, `--search-icon-padding`, and `--search-icon-radius` CSS variables.

## Outputs

- `onSearch: EventEmitter<string>` – Emitted when search value changes (debounced)

## Basic Usage

### Simple Search
```html
<ccl-searchbar 
  placeholder="Search users..."
  (onSearch)="searchUsers($event)">
</ccl-searchbar>
```

### With Custom Debounce
```html
<ccl-searchbar 
  placeholder="Search products..."
  [debounce]="500"
  (onSearch)="searchProducts($event)">
</ccl-searchbar>
```

### Without Icon
```html
<ccl-searchbar 
  placeholder="Search..."
  [showIcon]="false"
  (onSearch)="onSearch($event)">
</ccl-searchbar>
```

### Custom Icons
```html
<ng-template #customSearchIcon>
  <span class="custom-search-icon">🔎</span>
</ng-template>

<ng-template #customClearIcon>
  <span class="custom-clear-icon">❌</span>
</ng-template>

<ccl-searchbar 
  placeholder="Search..."
  [searchIcon]="customSearchIcon"
  [clearIcon]="customClearIcon"
  (onSearch)="onSearch($event)">
</ccl-searchbar>
```

### Disabled Search
```html
<ccl-searchbar 
  placeholder="Search disabled"
  [disabled]="true"
  (onSearch)="onSearch($event)">
</ccl-searchbar>
```

## Complete Example

```typescript
import { Component } from '@angular/core';
import { SearchbarComponent } from '@Crystal-Code-Labs/ccl-ui-components';

@Component({
  selector: 'app-search-example',
  standalone: true,
  imports: [SearchbarComponent],
  template: `
    <div class="search-container">
      <h2>Product Search</h2>
      
      <ccl-searchbar 
        placeholder="Search products..."
        [debounce]="300"
        [clearable]="true"
        (onSearch)="onSearch($event)">
      </ccl-searchbar>
      
      <div class="search-results">
        @for (product of filteredProducts; track product.name) {
          <div>{{ product.name }} - {{ product.price }}</div>
        }
      </div>
    </div>
  `,
  styles: [`
    .search-container {
      padding: 1rem;
    }
    
    .search-results {
      margin-top: 1rem;
    }
  `]
})
export class SearchExampleComponent {
  products = [
    { name: 'Laptop', price: '$999' },
    { name: 'Mouse', price: '$29' },
    { name: 'Keyboard', price: '$79' },
    { name: 'Monitor', price: '$299' }
  ];
  
  filteredProducts = this.products;

  onSearch(searchTerm: string) {
    if (!searchTerm.trim()) {
      this.filteredProducts = this.products;
      return;
    }
    
    this.filteredProducts = this.products.filter(product =>
      product.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }
}
```

## Keyboard Navigation

The searchbar supports several keyboard shortcuts:

- **Enter**: Immediately triggers search (bypasses debounce)
- **Escape**: Clears the search input
- **Tab**: Navigate to/from the search input

## Features

### Debouncing
- Prevents excessive API calls during typing
- Configurable delay (0 = no debounce)
- Enter key bypasses debounce for immediate search

### Clear Functionality
- Optional clear button (×) appears when value exists
- Click to clear or press Escape key
- Automatically focuses input after clearing

### Accessibility
- Proper ARIA labels and roles
- Screen reader friendly
- Keyboard navigation support
- Focus management

## Styling

The searchbar component uses design tokens for consistent styling:

```css
.ccl-searchbar {
  display: flex;
  align-items: center;
  background: var(--color-background, #fff);
  border: 1px solid var(--color-border, #ccc);
  border-radius: var(--radius-md, 6px);
  padding: var(--spacing-sm, 0.5rem);
  box-shadow: var(--shadow-sm, none);
}

.ccl-searchbar__input {
  flex: 1;
  border: none;
  outline: none;
  font-size: var(--font-size-md, 1rem);
  background: transparent;
  color: var(--color-text, #000);
}

/* Icon container (prefix) */
.ccl-searchbar__icon {
  margin-right: var(--spacing-sm, 0.5rem);
  color: var(--color-icon, #666);
  background: var(--search-icon-bg, transparent);
  padding: var(--search-icon-padding, 0);
  border-radius: var(--search-icon-radius, 0);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
```

## Theming

Customize the searchbar appearance with CSS variables:

```css
:root, :host {
  --color-background: #f8f9fa;
  --color-border: #e9ecef;
  --color-text: #495057;
  --color-icon: #6c757d;
  --radius-md: 8px;
  --spacing-sm: 0.75rem;
  /* Search icon container variables */
  --search-icon-bg: transparent;      /* e.g. #eef5ff */
  --search-icon-padding: 0;           /* e.g. 0.25rem */
  --search-icon-radius: 0;            /* e.g. 4px */
}
```

### Examples

1) Default icon and color

```html
<ccl-searchbar placeholder="Search..." (onSearch)="onSearch($event)"></ccl-searchbar>
```

2) Custom prefix icon template

```html
<ng-template #mySearchIcon>
  <span>🔎</span>
  <!-- or an SVG -->
  <!-- <svg ...>...</svg> -->
</ng-template>

<ccl-searchbar
  placeholder="Search..."
  [searchIcon]="mySearchIcon"
  (onSearch)="onSearch($event)">
</ccl-searchbar>
```

3) Colored icon background via CSS variables

```html
<div class="search-with-colored-icon">
  <ccl-searchbar placeholder="Search products" (onSearch)="onSearch($event)"></ccl-searchbar>
</div>
```

```css
.search-with-colored-icon {
  --search-icon-bg: #eef5ff;
  --search-icon-padding: 0.25rem;
  --search-icon-radius: 6px;
  --color-icon: #1e66f5; /* also change icon color if desired */
}
```

## Testing

The searchbar component includes comprehensive test coverage:

```typescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { SearchbarComponent } from '@Crystal-Code-Labs/ccl-ui-components';

describe('SearchbarComponent', () => {
  let fixture: ComponentFixture<SearchbarComponent>;
  let component: SearchbarComponent;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [SearchbarComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(SearchbarComponent);
    component = fixture.componentInstance;
  });

  it('should emit search on input change with debounce', (done) => {
    component.debounce = 100;
    spyOn(component.onSearch, 'emit');
    
    const input = fixture.debugElement.query(By.css('.ccl-searchbar__input'));
    input.nativeElement.value = 'test';
    input.nativeElement.dispatchEvent(new Event('input'));
    
    setTimeout(() => {
      expect(component.onSearch.emit).toHaveBeenCalledWith('test');
      done();
    }, 150);
  });

  it('should emit search immediately on Enter key', () => {
    spyOn(component.onSearch, 'emit');
    
    const input = fixture.debugElement.query(By.css('.ccl-searchbar__input'));
    input.nativeElement.value = 'test';
    input.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
    
    expect(component.onSearch.emit).toHaveBeenCalledWith('test');
  });

  it('should clear input on Escape key', () => {
    component.value = 'test';
    fixture.detectChanges();
    
    const input = fixture.debugElement.query(By.css('.ccl-searchbar__input'));
    input.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
    
    expect(component.value).toBe('');
  });
});
```

## Integration with Other Components

### With DataTable
```html
<div class="data-section">
  <ccl-searchbar 
    placeholder="Filter data..."
    (onSearch)="filterData($event)">
  </ccl-searchbar>
  
  <ccl-datatable
    [columns]="columns"
    [rows]="filteredRows">
  </ccl-datatable>
</div>
```

### With Pagination
```html
<div class="search-and-pagination">
  <ccl-searchbar 
    placeholder="Search..."
    (onSearch)="onSearch($event)">
  </ccl-searchbar>
  
  <ccl-pagination 
    [currentPage]="currentPage"
    [totalPages]="totalPages"
    (pageChange)="onPageChange($event)">
  </ccl-pagination>
</div>
```
