# @libs-ui/components-inputs-input

> Universal input component hỗ trợ text, number, textarea với validation và customization đầy đủ

**Version:** 0.2.355-14

## Giới thiệu

`LibsUiComponentsInputsInputComponent` là một standalone Angular component đa năng cho việc nhập liệu. Component hỗ trợ nhiều loại dữ liệu (string, int, float, bigint), nhiều tag (input, textarea, iframe-textarea), và có khả năng tùy biến cao với validation, icons, templates, và external controls.

### Tính năng

- ✅ Hỗ trợ nhiều data types: string, int, float, bigint
- ✅ Hỗ trợ nhiều tag types: input, textarea, iframe-textarea
- ✅ Auto-resize cho textarea
- ✅ Number formatting theo ngôn ngữ (VI/EN)
- ✅ Min/Max value validation cho number
- ✅ Character count display
- ✅ Icon left/right với popover
- ✅ Template slots (left/right bottom)
- ✅ Up/Down buttons cho number input
- ✅ Drag & drop file support
- ✅ External control via FunctionsControl
- ✅ OnPush Change Detection
- ✅ Angular Signals

## Khi nào sử dụng

- Cần input field cơ bản cho text hoặc number
- Cần textarea với auto-resize
- Cần format number theo locale (VI/EN)
- Cần validation min/max cho number input
- Cần hiển thị character count
- Cần custom icons với popover
- Cần control input từ component cha
- Cần drag & drop file vào input

## Important Notes

⚠️ **Data Type Handling**: Component tự động format number theo ngôn ngữ hiện tại (VI dùng dấu `.` cho thousands, EN dùng `,`).

⚠️ **Textarea Auto-resize**: Khi dùng `tagInput="textarea"`, component tự động điều chỉnh height dựa trên content.

⚠️ **Number Precision**:

- `int`: max 16-17 digits
- `float`: max 15 digits (font) + decimals
- `bigint`: configurable via `maxLengthNumberCount` và `fixedFloat`

⚠️ **Value Model**: `value` là model (two-way binding), component tự động parse và emit theo `dataType`.

## Cài đặt

```bash
npm install @libs-ui/components-inputs-input
```

## Import

```typescript
import { LibsUiComponentsInputsInputComponent } from '@libs-ui/components-inputs-input';

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

## Ví dụ

### Basic Text Input

```html
<libs_ui-components-inputs-input
  [(value)]="textValue"
  [placeholder]="'Enter text'"
  (outChange)="onTextChange($event)" />
```

### Number Input với Min/Max

```html
<libs_ui-components-inputs-input
  [dataType]="'int'"
  [(value)]="numberValue"
  [minValueNumber]="0"
  [maxValueNumber]="100"
  [placeholder]="'0-100'" />
```

### Textarea với Auto-resize

```html
<libs_ui-components-inputs-input
  [tagInput]="'textarea'"
  [(value)]="textareaValue"
  [minHeightTextArea]="100"
  [maxHeightTextArea]="300"
  [showCount]="true"
  [maxLength]="500" />
```

### Float Input với Fixed Decimal

```html
<libs_ui-components-inputs-input
  [dataType]="'float'"
  [(value)]="floatValue"
  [fixedFloat]="2"
  [acceptNegativeValue]="true" />
```

### Input với Icons

```html
<libs_ui-components-inputs-input
  [(value)]="searchValue"
  [iconLeftClass]="'libs-ui-icon-search'"
  [iconRightClass]="'libs-ui-icon-close'"
  [popoverContentIconLeft]="'Search for items'"
  (outIconLeft)="onSearchClick()"
  (outIconRight)="onClearClick()" />
```

### External Control

```html
<libs_ui-components-inputs-input
  [(value)]="controlledValue"
  (outFunctionsControl)="onFunctionsControl($event)" />

<button (click)="focusInput()">Focus</button>
<button (click)="insertText('Hello')">Insert Text</button>
```

```typescript
functionControl = signal<IInputFunctionControlEvent | null>(null);

onFunctionsControl(control: IInputFunctionControlEvent) {
  this.functionControl.set(control);
}

async focusInput() {
  await this.functionControl()?.focus();
}

async insertText(text: string) {
  await this.functionControl()?.insertContent(text);
}
```

## API

### Inputs (Most Common)

| Property                                      | Type                             | Default                    | Description                                  |
| --------------------------------------------- | -------------------------------- | -------------------------- | -------------------------------------------- |
| Property                                      | Type                             | Default                    | Description                                  |
| --------------------------------------------  | -------------------------------- | -------------------------- | -------------------------------------------- |
| `[acceptNegativeValue]`                       | `boolean`                        | `false`                    | Cho phép giá trị âm                          |
| `[acceptOnlyClickIcon]`                       | `boolean`                        | `false`                    | Chỉ cho phép click vào icon                  |
| `[autoAddZeroLessThan10InTypeInt]`            | `boolean`                        | `false`                    | Tự động thêm số 0 nếu < 10 (int)             |
| `[autoRemoveEmoji]`                           | `boolean`                        | `false`                    | Tự động loại bỏ emoji                        |
| `[backgroundNone]`                            | `boolean`                        | `false`                    | Trong suốt background                        |
| `[blurTimeOut]`                               | `number`                         | `32`                       | Delay time cho blur event                    |
| `[borderError]`                               | `boolean`                        | `false`                    | Hiển thị border error                        |
| `[classContainerBottomInput]`                 | `string`                         | `' '`                      | Class cho container dưới input               |
| `[classContainerInput]`                       | `string`                         | `'w-full'`                 | Class cho container input                    |
| `[classInclude]`                              | `string`                         | `' w-full '`               | Class bao ngoài component                    |
| `[dataType]`                                  | `TYPE_DATA_TYPE_INPUT`           | `'string'`                 | Data type: string, int, float, bigint        |
| `[defaultHeight]`                             | `number`                         | `32`                       | Chiều cao mặc định                           |
| `[disable]`                                   | `boolean`                        | `false`                    | Disable mode                                 |
| `[emitEmptyInDataTypeNumber]`                 | `boolean`                        | `false`                    | Emit empty string khi xoá hết number         |
| `[fixedFloat]`                                | `number`                         | `undefined`                | Số chữ số thập phân                          |
| `[focusInput]`                                | `boolean`                        | `false`                    | Auto focus input                             |
| `[focusTimeOut]`                              | `number`                         | `600`                      | Delay time cho focus method                  |
| `[iconLeftClass]`                             | `string`                         | `''`                       | Class cho icon trái                          |
| `[iconRightClass]`                            | `string`                         | `undefined`                | Class cho icon phải                          |
| `[iframeTextareaCustomStyle]`                 | `IIframeTextareaCustomStyle`     | `undefined`                | Custom style cho iframe textarea             |
| `[ignoreBlockInputMaxValue]`                  | `boolean`                        | `undefined`                | Không chặn nhập quá max value                |
| `[ignoreStopPropagationEvent]`                | `boolean`                        | `undefined`                | Không chặn propagation event                 |
| `[ignoreWidthInput100]`                       | `boolean`                        | `undefined`                | Không set width 100%                         |
| `[keepPlaceholderOnly]`                       | `boolean`                        | `false`                    | Chỉ giữ placeholder (ẩn value)               |
| `[keepZeroInTypeInt]`                         | `boolean`                        | `false`                    | Giữ số 0 ở đầu (int)                         |
| `[maxHeightTextArea]`                         | `number`                         | `250`                      | Max height cho textarea                      |
| `[maxLength]`                                 | `number`                         | `undefined`                | Max character length                         |
| `[maxLengthNumberCount]`                      | `number`                         | `undefined`                | Max length cho phần số (bigint)              |
| `[minHeightTextArea]`                         | `number`                         | `undefined`                | Min height cho textarea                      |
| `[minValueNumber]`                            | `number`                         | `undefined`                | Min value cho number input                   |
| `[maxValueNumber]`                            | `number`                         | `undefined`                | Max value cho number input                   |
| `[noBorder]`                                  | `boolean`                        | `false`                    | Ẩn border                                    |
| `[onlyAcceptNegativeValue]`                   | `boolean`                        | `false`                    | Chỉ chấp nhận số âm                          |
| `[placeholder]`                               | `string`                         | `' '`                      | Placeholder text                             |
| `[popoverContentIconLeft]`                    | `string`                         | `''`                       | Popover content icon trái                    |
| `[popoverContentIconRight]`                   | `string`                         | `''`                       | Popover content icon phải                    |
| `[readonly]`                                  | `boolean`                        | `false`                    | Readonly mode                                |
| `[resetAutoCompletePassword]`                 | `boolean`                        | `false`                    | Reset autocomplete cho password              |
| `[resize]`                                    | `TYPE_INPUT_RESIZE_MODE`         | `'vertical'`               | Resize mode                                  |
| `[selectAllTimeOut]`                          | `number`                         | `600`                      | Delay time cho selectAll                     |
| `[setIconRightColorSameColorDisableReadOnly]` | `boolean`                        | `false`                    | Icon phải cùng màu disable text              |
| `[showCount]`                                 | `boolean`                        | `false`                    | Hiển thị character count                     |
| `[tabInsertContentTagInput]`                  | `boolean`                        | `false`                    | Cho phép dùng Tab để insert                  |
| `[tagInput]`                                  | `TYPE_TAG_INPUT`                 | `'input'`                  | Tag type: input, textarea, iframe-textarea   |
| `[templateLeftBottomInput]`                   | `TemplateRef<TYPE_TEMPLATE_REF>` | `undefined`                | Template custom dưới trái                    |
| `[templateRightBottomInput]`                  | `TemplateRef<TYPE_TEMPLATE_REF>` | `undefined`                | Template custom dưới phải                    |
| `[textAreaEnterNotNewLine]`                   | `boolean`                        | `false`                    | Enter không xuống dòng trong textarea        |
| `[typeInput]`                                 | `TYPE_INPUT`                     | `'text'`                   | Input type: text, number, password           |
| `[useColorModeExist]`                         | `boolean`                        | `false`                    | Sử dụng màu sắc theo mode của hệ thống       |
| `[value]`                                     | `string \| number`               | `''`                       | Input value (model binding)                  |
| `[valueUpDownNumber]`                         | `number`                         | `undefined`                | Bước nhảy cho nút tăng giảm                  |
| `[zIndexPopoverContent]`                      | `number`                         | `10`                       | Z-index cho popover content                  |

**Note**: Component có 50+ inputs. Xem demo tại `/inputs/input` để biết chi tiết.

### Outputs

| Property                         | Type                                       | Description                                   |
| -------------------------------- | ------------------------------------------ | --------------------------------------------- |
| Property                         | Type                                       | Description                                   |
| -------------------------------- | ------------------------------------------ | --------------------------------------------  |
| `(outChange)`                    | `any`                                      | Emit khi value thay đổi (two-way binding)     |
| `(outChangeValueByButtonUpDown)` | `void`                                     | Emit khi click button up/down                 |
| `(outEnterEvent)`                | `IEvent`                                   | Emit khi nhấn Enter                           |
| `(outFileDrop)`                  | `File`                                     | Emit khi drop single file                     |
| `(outFilesDrop)`                 | `Array<File>`                              | Emit khi drop multiple files                  |
| `(outFocusAndBlurEvent)`         | `IFocusAndBlurEvent`                       | Emit khi focus/blur                           |
| `(outFunctionsControl)`          | `IInputFunctionControlEvent`               | Emit function controls instance               |
| `(outHeightAreaChange)`          | `{ isChange: boolean; height: number; }`   | Emit khi height textarea thay đổi auto-resize |
| `(outIconLeft)`                  | `string`                                   | Emit khi click icon left                      |
| `(outIconRight)`                 | `string`                                   | Emit khi click icon right                     |
| `(outInputEvent)`                | `IEvent`                                   | Emit pure input event (native)                |

### FunctionsControl Methods

| Method                       | Description               |
| ---------------------------- | ------------------------- |
| `focus(emitEvent?: boolean)` | Focus vào input           |
| `blur(emitEvent?: boolean)`  | Blur khỏi input           |
| `insertContent(data)`        | Insert content vào cursor |
| `resetValue()`               | Reset value về empty      |
| `getElementValue()`          | Lấy value từ element      |
| `selectAllContent()`         | Select all content        |

## Types

```typescript
type TYPE_INPUT = 'text' | 'number' | 'password';
type TYPE_DATA_TYPE_INPUT = 'string' | 'int' | 'float' | 'bigint';
type TYPE_TAG_INPUT = 'input' | 'textarea' | 'iframe-textarea';
type TYPE_INPUT_RESIZE_MODE = 'auto' | 'vertical' | 'horizontal' | 'none';

interface IInputFunctionControlEvent {
  focus: (emitEvent?: boolean) => Promise<void>;
  blur: (emitEvent?: boolean) => Promise<void>;
  insertContent: (data: string | number) => Promise<void>;
  resetValue: () => Promise<void>;
  getElementValue: () => Promise<any> | undefined;
  selectAllContent: () => Promise<void>;
}

interface IIframeTextareaCustomStyle {
  borderRadius?: string;
  borderColor?: string;
  padding?: string;
  lineHeight?: string;
  fontSize?: string;
  height?: string;
  color?: string;
  backgroundColor?: string;
}
```

## Demo

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

Truy cập: `http://localhost:4500/inputs/input`

## License

MIT
