npm package: @libs-ui/components-tabs
Description: > Library Angular Component hiển thị Tabs, hỗ trợ Signals, Drag & Drop, Responsive "More" Menu và nhiều modes hiển thị.
Latest version: 0.2.356-23

# @libs-ui/components-tabs

> Library Angular Component hiển thị Tabs, hỗ trợ Signals, Drag & Drop, Responsive "More" Menu và nhiều modes hiển thị.

## Giới thiệu

`LibsUiComponentsTabsComponent` là một standalone Angular component để hiển thị danh sách các tabs. Nó được thiết kế để làm việc với Angular Signals, hỗ trợ nested reactivity cho từng tab item. Component này tự động xử lý responsive bằng cách nhóm các tabs không vừa vào menu "More", hỗ trợ kéo thả để sắp xếp, và cung cấp nhiều chế độ hiển thị khác nhau.

### Tính năng

- ✅ **Angular Signals**: Full support cho reactive updates.
- ✅ **Responsive "More" Menu**: Tự động tính toán và gom gọn các tabs không hiển thị hết (Mode 'left').
- ✅ **Drag & Drop**: Hỗ trợ kéo thả để thay đổi vị trí tab.
- ✅ **Multiple Modes**: 'left', 'center', 'space-between', 'center-has-line'.
- ✅ **Rich Content**: Hỗ trợ Icon, Badge/Count, Close button trên từng tab.
- ✅ **OnPush Change Detection**: Tối ưu hiệu năng.

## Khi nào sử dụng

- Khi cần phân chia nội dung thành các modules hoặc views khác nhau.
- Khi cần hiển thị danh sách các mục có thể đóng mở (như trình duyệt web).
- Khi không gian ngang bị giới hạn (sử dụng tính năng "More" menu tự động).
- Khi cần chức năng kéo thả sắp xếp tabs.

## Cài đặt

```bash
# npm
npm install @libs-ui/components-tabs

# yarn
yarn add @libs-ui/components-tabs
```

## Import

```typescript
import { LibsUiComponentsTabsComponent } from '@libs-ui/components-tabs';

@Component({
  standalone: true,
  imports: [LibsUiComponentsTabsComponent],
  // ...
})
export class YourComponent {}
```

## Ví dụ

### Basic

```html
<libs_ui-components-tabs
  [tabs]="tabsConfig"
  [(keySelected)]="selectedKey" />
```

```typescript
// Trong component class
import { signal, WritableSignal } from '@angular/core';
import { ITabs, ITabsItem } from '@libs-ui/components-tabs';

// 1. Tạo các items dưới dạng signal
const item1 = signal<ITabsItem>({ key: 'tab1', label: 'Tab 1' });
const item2 = signal<ITabsItem>({ key: 'tab2', label: 'Tab 2' });

// 2. Tạo config tabs
protected tabsConfig: ITabs = {
  items: signal<Array<WritableSignal<ITabsItem>>>([item1, item2])
};

protected selectedKey = signal<string>('tab1');
```

## API

### libs_ui-components-tabs

#### Inputs

| Property                      | Type                                                         | Default      | Description                                             |
| ----------------------------- | ------------------------------------------------------------ | ------------ | ------------------------------------------------------- |
| `[tabs]`                      | `ITabs`                                                      | **Required** | Cấu hình chính cho tabs, chứa danh sách items (Signal). |
| `[(keySelected)]`             | `string` (Model)                                             | **Required** | Key của tab đang được chọn (Two-way binding).           |
| `[mode]`                      | `'left' \| 'center' \| 'space-between' \| 'center-has-line'` | `'left'`     | Chế độ hiển thị của tabs.                               |
| `[fieldKey]`                  | `string`                                                     | `'key'`      | Tên trường dùng làm key định danh trong item object.    |
| `[fieldLabel]`                | `string`                                                     | `'label'`    | Tên trường hiển thị label trong item object.            |
| `[disable]`                   | `boolean`                                                    | `false`      | Vô hiệu hóa toàn bộ tabs.                               |
| `[heightTabItem]`             | `number`                                                     | `40`         | Chiều cao của tab bar (px).                             |
| `[allowDragDropPosition]`     | `boolean`                                                    | `false`      | Cho phép kéo thả vị trí các tab.                        |
| `[size]`                      | `'langer' \| 'medium'`                                       | `'medium'`   | Kích thước tab.                                         |
| `[disableLabel]`              | `boolean`                                                    | `false`      | Vô hiệu hóa label.                                      |
| `[ignoreCalculatorTab]`       | `boolean`                                                    | `false`      | Bỏ qua việc tính toán hiển thị responsive (menu More).  |
| `[zIndex]`                    | `number`                                                     | `undefined`  | Z-index cho component.                                  |
| `[configCss]`                 | `ITabCssConfig` (Model)                                      | `undefined`  | Cấu hình CSS tùy chỉnh cho các mode.                    |
| `[popoverShowMoreTabItem]`    | `IPopover`                                                   | `undefined`  | Cấu hình popover cho menu "Xem thêm".                   |
| `[checkCanChangeTabSelected]` | `() => boolean \| Promise<boolean>`                          | `undefined`  | Callback kiểm tra trước khi chuyển tab.                 |
| `[useEffectUpdateItems]`      | `boolean`                                                    | `false`      | Tự động update items hiển thị khi signal items thay đổi. |

#### Outputs

| Property                | Type                        | Description                                          |
| ----------------------- | --------------------------- | ---------------------------------------------------- |
| `(outKeySelected)`      | `string`                    | Emit key của tab vừa được chọn.                      |
| `(outDragTabChange)`    | `void`                      | Emit sau khi người dùng kéo thả thay đổi vị trí tab. |
| `(outDisplayMoreItem)`  | `boolean`                   | Emit khi trạng thái hiển thị menu "More" thay đổi.   |
| `(outFunctionsControl)` | `ITabsFunctionControlEvent` | Emit các hàm điều khiển tabs từ bên ngoài.           |
| `(outAction)`           | `ITabsItemEvent`            | Emit các action khác (ví dụ: click nút close).       |

## Types & Interfaces

```typescript
export interface ITabs {
  items: WritableSignal<Array<WritableSignal<ITabsItem>>>;
  hasImage?: boolean;
  hasCount?: boolean;
  allowRemove?: boolean;
  hasStep?: boolean;
  // ... configuration options
}

export interface ITabsItem {
  key?: string;
  label?: string;
  iconLeft?: string;
  count?: number;
  disable?: boolean;
  // ... item properties
}
```

## Styling

### CSS Classes

| Class                 | Description                          |
| --------------------- | ------------------------------------ |
| `.libs-ui-tab`        | Container chính của tabs component.  |
| `.libs-ui-tab-header` | Header chứa danh sách các tab items. |

## Công nghệ

| Technology      | Version | Purpose          |
| --------------- | ------- | ---------------- |
| Angular         | 18+     | Framework        |
| Angular Signals | -       | State management |
| TailwindCSS     | 3.x     | Styling          |
| OnPush          | -       | Change Detection |

## Demo

```bash
npx nx serve core-ui
```

Truy cập: `http://localhost:4500/tabs` để xem toàn bộ các demo từ cơ bản đến nâng cao (bao gồm tích hợp Modal V2).

## Unit Tests

```bash
npx nx test components-tabs
```

## License

MIT