npm package: @libs-ui/pipes-format-text-highlight-by-keyword
Description: Pipe highlight (tô màu) từ khóa trong chuỗi văn bản. Hỗ trợ tìm kiếm không dấu tiếng Việt, không phân biệt hoa/thường và tùy chỉnh CSS class highlight.
Latest version: 0.2.356-23

# Highlight By Keyword Pipe

Pipe highlight (tô màu) từ khóa trong chuỗi văn bản. Hỗ trợ tìm kiếm không dấu tiếng Việt, không phân biệt hoa/thường và tùy chỉnh CSS class highlight.

## Tính năng

- ✅ Highlight tất cả các lần xuất hiện của từ khóa trong chuỗi
- ✅ Tìm kiếm không dấu — "an" match "An", "ăn", "ân", "ản"... (tiếng Việt)
- ✅ Không phân biệt hoa/thường (case-insensitive)
- ✅ Tùy chỉnh CSS class cho phần highlight
- ✅ Option `ignoreHighlight` để vô hiệu hóa linh hoạt
- ✅ Xử lý an toàn null/undefined

## Cài đặt

```bash
npm install @libs-ui/pipes-format-text-highlight-by-keyword
```

## Import

```typescript
import { LibsUiPipesFormatTextHighlightByKeywordPipe } from '@libs-ui/pipes-format-text-highlight-by-keyword';

@Component({
  standalone: true,
  imports: [LibsUiPipesFormatTextHighlightByKeywordPipe],
})
export class ExampleComponent {}
```

## Cú pháp

```html
value | LibsUiPipesFormatTextHighlightByKeywordPipe : search : ignoreHighlight? : classHightLight?
```

> ⚠️ **Quan trọng:** Pipe trả về **HTML string**. Phải dùng `[innerHTML]` để hiển thị highlight. Dùng `{{ }}` sẽ chỉ hiện HTML thô (escaped).

## Ví dụ

### Trong Template

```html
<!-- ✅ Đúng: dùng [innerHTML] -->
<p [innerHTML]="text | LibsUiPipesFormatTextHighlightByKeywordPipe : keyword"></p>

<!-- ❌ Sai: dùng {{ }} sẽ hiện text thô -->
<p>{{ text | LibsUiPipesFormatTextHighlightByKeywordPipe : keyword }}</p>

<!-- Custom CSS class -->
<p
  [innerHTML]="text | LibsUiPipesFormatTextHighlightByKeywordPipe
  : keyword
  : false
  : 'bg-yellow-300 text-gray-900 font-bold'"></p>

<!-- Tắt highlight có điều kiện -->
<p [innerHTML]="text | LibsUiPipesFormatTextHighlightByKeywordPipe : keyword : !isSearching"></p>
```

### Dùng trong TypeScript

Pipe là thin wrapper của hàm `highlightByKeyword` trong `@libs-ui/utils`. Khi cần gọi trong TypeScript, import và dùng thẳng hàm đó — **không cần inject pipe**:

```typescript
import { highlightByKeyword } from '@libs-ui/utils';

// Dùng thẳng hàm utils — không cần inject pipe
const result = highlightByKeyword('Nguyễn Văn An', 'an');
// Output: 'Nguyễn Văn <span class="bg-[#19344a] text-white">An</span>'

// Custom class:
const custom = highlightByKeyword('Hello World', 'hello', false, 'bg-yellow-300 text-gray-900');

// Trong component class:
class ExampleComponent {
  safeHtml = highlightByKeyword(this.rawText, this.searchTerm);
}
```

## API

| Tham số           | Kiểu                   | Bắt buộc | Default                     | Mô tả                                              |
| ----------------- | ---------------------- | -------- | --------------------------- | -------------------------------------------------- |
| `value`           | `string \| undefined`  | ✅       | -                           | Chuỗi văn bản gốc cần tô màu keyword               |
| `search`          | `string \| undefined`  | ✅       | -                           | Từ khóa cần highlight trong chuỗi                  |
| `ignoreHighlight` | `boolean \| undefined` | ❌       | `undefined`                 | Nếu `true`, bỏ qua highlight và trả về `value` gốc |
| `classHightLight` | `string \| undefined`  | ❌       | `'bg-[#19344a] text-white'` | CSS class áp dụng cho `<span>` bao quanh keyword   |

## Khi nào sử dụng

- **Search result:** Highlight keyword trong danh sách kết quả tìm kiếm
- **Autocomplete:** Tô màu từ khóa trong dropdown gợi ý
- **Table filter:** Highlight từ khóa trong bảng dữ liệu khi lọc
- **Tiếng Việt:** Cần tìm kiếm không dấu (gõ "an" match "Ân", "ăn"...)

## Lưu ý quan trọng

- **Luôn dùng `[innerHTML]`** — pipe trả về HTML string chứa `<span>` tags
- **XSS:** Chỉ dùng với dữ liệu đã tin cậy. Nếu `value` đến từ user input chưa kiểm tra, hãy sanitize trước khi truyền vào pipe
- **Default class** là `'bg-[#19344a] text-white'` (dark navy background). Có thể override bằng bất kỳ Tailwind hoặc CSS class nào
- **ignoreHighlight** hữu ích để toggle highlight theo state, tránh phải thêm `@if` trong template