npm package: @libs-ui/components-scroll-measure-items-direction-horizontal
Description: > Directive hỗ trợ ảo hóa danh sách (virtual scrolling) theo chiều ngang với kích thước item động (dynamic width).
Latest version: 0.2.356-23

# @libs-ui/components-scroll-measure-items-direction-horizontal

> Directive hỗ trợ ảo hóa danh sách (virtual scrolling) theo chiều ngang với kích thước item động (dynamic width).

## Giới thiệu

`LibsUiScrollMeasureItemDirectionHorizontalDirective` là một directive giúp tối ưu hóa hiệu năng khi render danh sách lớn các item theo chiều ngang. Nó chỉ render các item đang nằm trong vùng nhìn thấy (viewport) và sử dụng các element ảo để duy trì kích thước scroll, đồng thời hỗ trợ các hàm điều khiển scroll mạnh mẽ.

### Tính năng

- ✅ **Virtual Scrolling**: Chỉ render các item trong viewport, giúp giảm số lượng DOM node.
- ✅ **Dynamic Width**: Hỗ trợ item có kích thước thay đổi (không cố định) thông qua hàm đo kích thước bất đồng bộ.
- ✅ **Scroll Control API**: Cung cấp các phương thức `scrollToIndex`, `scrollToPosition`, `scrollInto` item cụ thể.
- ✅ **Performance**: Tối ưu hóa cho danh sách lớn (hàng nghìn item).

## Khi nào sử dụng

- Hiển thị danh sách ảnh, thẻ, hoặc item theo chiều ngang với số lượng lớn.
- Kích thước các item không đều nhau (ví dụ: text dài ngắn khác nhau).
- Cần tính năng scroll đến item cụ thể hoặc index cụ thể.

## Cài đặt

```bash
# npm
npm install @libs-ui/components-scroll-measure-items-direction-horizontal

# yarn
yarn add @libs-ui/components-scroll-measure-items-direction-horizontal
```

## Import

```typescript
import { LibsUiScrollMeasureItemDirectionHorizontalDirective } from '@libs-ui/components-scroll-measure-items-direction-horizontal';

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

## Ví dụ

### Basic Usage

```html
<div
  #scrollContainer
  class="scroll-container flex overflow-x-auto"
  LibsUiScrollMeasureItemDirectionHorizontalDirective
  [elementScroll]="scrollContainer"
  [items]="items"
  [functionGetWidthItem]="measureWidth"
  (outViewPortItem)="viewPortItems = $event">
  @for (item of viewPortItems; track item.id) {
  <div
    class="item"
    [style.width.px]="item.width">
    {{ item.text }}
  </div>
  }
</div>
```

```typescript
items = [...]; // Data source
viewPortItems = []; // Items processed for display

// Function to measure item width (async)
measureWidth = async (item: any): Promise<number> => {
  // Logic to calculate width, e.g., based on content length or fixed rules
  return item.text.length * 10 + 20;
};
```

## API

### LibsUiScrollMeasureItemDirectionHorizontalDirective

#### Inputs

| Property                 | Type                             | Default    | Description                                     |
| ------------------------ | -------------------------------- | ---------- | ----------------------------------------------- |
| `[items]`                | `Array<any>`                     | `required` | Danh sách dữ liệu gốc cần hiển thị.             |
| `[elementScroll]`        | `HTMLElement`                    | `required` | Element chứa thanh cuộn (container chính).      |
| `[functionGetWidthItem]` | `(item: any) => Promise<number>` | `required` | Hàm async trả về chiều rộng (px) của từng item. |

#### Outputs

| Property               | Type                                                    | Description                                                                       |
| ---------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `(outViewPortItem)`    | `Array<Record<string, any>>`                            | Emit danh sách item cần render trong viewport. Item gốc nằm trong property `ref`. |
| `(outFunctionControl)` | `IScrollMeasureItemDirectionHorizontalFunctionsControl` | Emit controller chứa các hàm điều khiển scroll.                                   |
| `(outDivVirtual)`      | `HTMLDivElement`                                        | Emit element ảo được tạo ra để giữ chiều rộng scroll của container.               |

#### Interfaces

**IScrollMeasureItemDirectionHorizontalFunctionsControl**

| Method                                              | Description                                                                |
| --------------------------------------------------- | -------------------------------------------------------------------------- |
| `scrollInto(item: any): Promise<void>`              | Scroll đến item cụ thể.                                                    |
| `scrollToPosition(position: number): Promise<void>` | Scroll đến vị trí pixel cụ thể.                                            |
| `scrollToIndex(index: number): Promise<void>`       | Scroll đến item tại index cụ thể.                                          |
| `reCalculatorViewPort(): Promise<void>`             | Tính toán lại viewport (dùng khi kích thước container hoặc item thay đổi). |

## Demo

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

Truy cập path: `/components/scroll-measure-items/direction-horizontal`