quang 20.1.9 → 20.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/autocomplete/README.md +71 -54
- package/components/checkbox/README.md +50 -40
- package/components/date/README.md +481 -23
- package/components/input/README.md +150 -26
- package/components/input/index.d.ts +6 -1
- package/components/paginator/README.md +51 -27
- package/components/select/README.md +18 -28
- package/components/wysiwyg/README.md +11 -23
- package/fesm2022/quang-components-input.mjs +11 -4
- package/fesm2022/quang-components-input.mjs.map +1 -1
- package/fesm2022/quang-overlay-modal.mjs +125 -2
- package/fesm2022/quang-overlay-modal.mjs.map +1 -1
- package/fesm2022/quang-overlay-shared.mjs +13 -15
- package/fesm2022/quang-overlay-shared.mjs.map +1 -1
- package/overlay/modal/index.d.ts +34 -3
- package/overlay/shared/index.d.ts +6 -6
- package/package.json +37 -37
|
@@ -4,35 +4,105 @@ The `QuangInputComponent` must be configured using the `componentType` input pro
|
|
|
4
4
|
|
|
5
5
|
## Supported Types
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
7
|
+
The component supports the following input types, each with specific behaviors and configurations:
|
|
8
|
+
|
|
9
|
+
### Text Input Types
|
|
10
|
+
|
|
11
|
+
- **text** — Standard text input for general text entry
|
|
12
|
+
- **email** — Email input with built-in email validation
|
|
13
|
+
- **password** — Password input with optional show/hide toggle functionality
|
|
14
|
+
- **url** — URL input with URL format validation
|
|
15
|
+
- **search** — Search input with native search behavior
|
|
16
|
+
- **tel** — Telephone number input
|
|
17
|
+
|
|
18
|
+
### Numeric Input Types
|
|
19
|
+
|
|
20
|
+
- **number** — Numeric input with step controls and min/max validation
|
|
21
|
+
|
|
22
|
+
### Special Input Types
|
|
23
|
+
|
|
24
|
+
- **textarea** — Multi-line text input with resizable functionality
|
|
25
|
+
- **color** — Color picker input
|
|
26
|
+
|
|
27
|
+
### Type-Specific Features
|
|
28
|
+
|
|
29
|
+
#### Textarea (`componentType="textarea"`)
|
|
30
|
+
|
|
31
|
+
- **Multi-line support**: Automatically expands for content
|
|
32
|
+
- **Resizable control**: Use `resizable` input to enable/disable manual resizing
|
|
33
|
+
- **No min/max number constraints**: Number-related inputs are ignored
|
|
34
|
+
|
|
35
|
+
#### Password (`componentType="password"`)
|
|
36
|
+
|
|
37
|
+
- **Toggle visibility**: Built-in show/hide password functionality
|
|
38
|
+
- **Icon support**: Uses content projection through slots for customizing the show/hide icons
|
|
39
|
+
- `[show-password]` slot: Content to display when password is hidden (show password icon)
|
|
40
|
+
- `[hide-password]` slot: Content to display when password is visible (hide password icon)
|
|
41
|
+
- **Security**: Masks input by default, reveals on toggle
|
|
42
|
+
|
|
43
|
+
#### Number (`componentType="number"`)
|
|
44
|
+
|
|
45
|
+
- **Step controls**: Use `componentStep` to define increment/decrement values
|
|
46
|
+
- **Range validation**: Set `minNumber` and `maxNumber` for value constraints
|
|
47
|
+
- **Decimal support**: Supports decimal values when step allows
|
|
48
|
+
|
|
49
|
+
#### Email (`componentType="email"`)
|
|
50
|
+
|
|
51
|
+
- **Format validation**: Automatic email format validation
|
|
52
|
+
- **Autocomplete**: Enhanced with email-specific autocomplete
|
|
53
|
+
|
|
54
|
+
#### Search (`componentType="search"`)
|
|
55
|
+
|
|
56
|
+
- **Clear button**: Native clear functionality on supported browsers
|
|
57
|
+
- **Search behavior**: Platform-specific search enhancements
|
|
16
58
|
|
|
17
59
|
## Inputs
|
|
18
60
|
|
|
61
|
+
### Core Configuration
|
|
62
|
+
|
|
19
63
|
- `componentType`: `'text' | 'textarea' | 'password' | 'email' | 'number' | 'url' | 'search' | 'tel' | 'color'` — Specifies the type of input. **(Required)**
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
- `
|
|
24
|
-
- `
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
64
|
+
|
|
65
|
+
### Text-Specific Inputs
|
|
66
|
+
|
|
67
|
+
- `maxLengthText`: `number | null` — Maximum length for text input. Applies to: `text`, `textarea`, `email`, `password`, `url`, `search`, `tel`
|
|
68
|
+
- `minLengthText`: `number | null` — Minimum length for text input. Applies to: `text`, `textarea`, `email`, `password`, `url`, `search`, `tel`
|
|
69
|
+
|
|
70
|
+
### Number-Specific Inputs
|
|
71
|
+
|
|
72
|
+
- `minNumber`: `number | undefined` — Minimum value for number input. **Only applies to**: `number`
|
|
73
|
+
- `maxNumber`: `number | undefined` — Maximum value for number input. **Only applies to**: `number`
|
|
74
|
+
- `componentStep`: `number` — Step increment for number input. Default: `1`. **Only applies to**: `number`
|
|
75
|
+
|
|
76
|
+
### Textarea-Specific Inputs
|
|
77
|
+
|
|
78
|
+
- `resizable`: `boolean` — Controls textarea resizing behavior. Default: `true`
|
|
79
|
+
|
|
80
|
+
### Password-Specific Inputs
|
|
81
|
+
|
|
82
|
+
- `showHidePasswordButton`: `boolean` — Shows/hides the password toggle button. Default: `true`. **Only applies to**: `password`
|
|
83
|
+
- `buttonClass`: `string` — Additional CSS classes for the password toggle button. **Only applies to**: `password`
|
|
84
|
+
|
|
85
|
+
### Universal Inputs
|
|
86
|
+
|
|
87
|
+
- `isReadonly`: `boolean` — Makes the input read-only
|
|
88
|
+
- `componentLabel`: `string` — Label text (supports i18n keys)
|
|
89
|
+
- `componentPlaceholder`: `string` — Placeholder text (supports i18n keys)
|
|
90
|
+
- `componentTabIndex`: `number` — Tab index for accessibility
|
|
91
|
+
- `componentClass`: `string` — Additional CSS classes for the input element
|
|
92
|
+
- `errorMap`: `Record<string, any>` — Validation error messages
|
|
93
|
+
- `successMessage`: `string` — Success message text
|
|
94
|
+
- `helpMessage`: `string` — Help text displayed below the input
|
|
95
|
+
- `formControl`: `FormControl` — Angular reactive form control
|
|
28
96
|
|
|
29
97
|
## Outputs
|
|
30
98
|
|
|
31
|
-
-
|
|
32
|
-
|
|
99
|
+
- `showPassword`: `EventEmitter<boolean>` — Emitted when the password visibility is toggled (password inputs only)
|
|
100
|
+
- `componentBlur`: `EventEmitter<void>` — Emitted when input loses focus
|
|
33
101
|
|
|
34
102
|
## Usage
|
|
35
103
|
|
|
104
|
+
### Basic Text Input
|
|
105
|
+
|
|
36
106
|
```html
|
|
37
107
|
<quang-input
|
|
38
108
|
[errorMap]="errors()"
|
|
@@ -40,19 +110,73 @@ The `QuangInputComponent` must be configured using the `componentType` input pro
|
|
|
40
110
|
componentType="text"
|
|
41
111
|
formControlName="testInput"
|
|
42
112
|
/>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Password Input with Toggle
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<quang-input
|
|
119
|
+
[errorMap]="errors()"
|
|
120
|
+
[showHidePasswordButton]="true"
|
|
121
|
+
(showPassword)="onToggleShowPassword($event)"
|
|
122
|
+
componentLabel="form.label.password"
|
|
123
|
+
componentType="password"
|
|
124
|
+
formControlName="password"
|
|
125
|
+
>
|
|
126
|
+
<!-- Content for the show/hide password button -->
|
|
127
|
+
<svg-icon src="assets/icons/svg/visibility.svg" show-password />
|
|
128
|
+
<svg-icon src="assets/icons/svg/visibility_off.svg" hide-password />
|
|
129
|
+
</quang-input>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### TypeScript Example
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
export class MyComponent {
|
|
136
|
+
showPassword = signal<boolean>(false)
|
|
137
|
+
|
|
138
|
+
onToggleShowPassword(isVisible: boolean): void {
|
|
139
|
+
this.showPassword.set(isVisible)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
errors(): Record<string, any> {
|
|
143
|
+
return this.form.get('password')?.errors ?? {}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Number Input with Constraints
|
|
43
149
|
|
|
150
|
+
```html
|
|
44
151
|
<quang-input
|
|
152
|
+
[componentStep]="5"
|
|
45
153
|
[errorMap]="errors()"
|
|
46
|
-
[
|
|
47
|
-
[maxNumber]="10"
|
|
154
|
+
[maxNumber]="100"
|
|
48
155
|
[minNumber]="0"
|
|
49
|
-
componentLabel="form.label.
|
|
156
|
+
componentLabel="form.label.quantity"
|
|
50
157
|
componentType="number"
|
|
51
|
-
formControlName="
|
|
52
|
-
successMessage="form.label.success"
|
|
158
|
+
formControlName="quantity"
|
|
53
159
|
/>
|
|
54
160
|
```
|
|
55
161
|
|
|
56
|
-
|
|
162
|
+
### Textarea
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
<quang-input
|
|
166
|
+
[errorMap]="errors()"
|
|
167
|
+
[maxLengthText]="500"
|
|
168
|
+
componentLabel="form.label.description"
|
|
169
|
+
componentType="textarea"
|
|
170
|
+
formControlName="description"
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Type-Specific Features
|
|
175
|
+
|
|
176
|
+
The component supports various input types with specific behaviors:
|
|
57
177
|
|
|
58
|
-
|
|
178
|
+
- **text, email, url, search, tel**: Support text length constraints
|
|
179
|
+
- **password**: Built-in show/hide toggle functionality with icon support
|
|
180
|
+
- **number**: Step controls and min/max validation
|
|
181
|
+
- **textarea**: Multi-line support with resizable control
|
|
182
|
+
- **color**: Color picker input
|
|
@@ -10,9 +10,14 @@ declare class QuangInputComponent extends QuangBaseComponent<string | number> {
|
|
|
10
10
|
maxNumber: _angular_core.InputSignal<number | undefined>;
|
|
11
11
|
componentStep: _angular_core.InputSignal<number>;
|
|
12
12
|
resizable: _angular_core.InputSignal<boolean>;
|
|
13
|
+
buttonClass: _angular_core.InputSignal<string>;
|
|
14
|
+
showHidePasswordButton: _angular_core.InputSignal<boolean>;
|
|
15
|
+
showPassword: _angular_core.WritableSignal<boolean>;
|
|
16
|
+
componentInputType: _angular_core.Signal<InputType>;
|
|
13
17
|
constructor();
|
|
18
|
+
onTogglePasswordVisibility(): void;
|
|
14
19
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<QuangInputComponent, never>;
|
|
15
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<QuangInputComponent, "quang-input", never, { "componentType": { "alias": "componentType"; "required": true; "isSignal": true; }; "maxLengthText": { "alias": "maxLengthText"; "required": false; "isSignal": true; }; "minLengthText": { "alias": "minLengthText"; "required": false; "isSignal": true; }; "minNumber": { "alias": "minNumber"; "required": false; "isSignal": true; }; "maxNumber": { "alias": "maxNumber"; "required": false; "isSignal": true; }; "componentStep": { "alias": "componentStep"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; }, {}, never,
|
|
20
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<QuangInputComponent, "quang-input", never, { "componentType": { "alias": "componentType"; "required": true; "isSignal": true; }; "maxLengthText": { "alias": "maxLengthText"; "required": false; "isSignal": true; }; "minLengthText": { "alias": "minLengthText"; "required": false; "isSignal": true; }; "minNumber": { "alias": "minNumber"; "required": false; "isSignal": true; }; "maxNumber": { "alias": "maxNumber"; "required": false; "isSignal": true; }; "componentStep": { "alias": "componentStep"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; "buttonClass": { "alias": "buttonClass"; "required": false; "isSignal": true; }; "showHidePasswordButton": { "alias": "showHidePasswordButton"; "required": false; "isSignal": true; }; }, {}, never, ["[hide-password]", "[show-password]"], true, never>;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
export { QuangInputComponent };
|
|
@@ -1,43 +1,67 @@
|
|
|
1
1
|
# QuangPaginatorComponent
|
|
2
2
|
|
|
3
|
-
The `QuangPaginatorComponent`
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Pagination controls
|
|
8
|
-
- Configurable total items, items per page, and current page
|
|
9
|
-
- Emits events for page changes
|
|
3
|
+
The `QuangPaginatorComponent` is a pagination control that provides navigation through large datasets with configurable page sizes and internationalization support.
|
|
10
4
|
|
|
11
5
|
## Inputs
|
|
12
6
|
|
|
13
|
-
- `page`: `number` — Current page number. **(Required)**
|
|
14
|
-
- `pageSize`: `number` — Number of items per page. **(Required)**
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `showTotalElementsCount`: `boolean` —
|
|
18
|
-
- `totalItemsText`: `string` — Translation key for total items label. Default: `'quangPaginator.totalItems'
|
|
19
|
-
- `sizeText`: `string` — Translation key for size label. Default: `'quangPaginator.size'
|
|
20
|
-
- `pageRangeText`: `string` — Translation key for page range
|
|
21
|
-
- `componentId
|
|
7
|
+
- `page`: `number` — Current active page number (1-based indexing). **(Required)**
|
|
8
|
+
- `pageSize`: `number` — Number of items displayed per page. **(Required)**
|
|
9
|
+
- `totalItems`: `number` — Total number of items in the dataset. **(Required)**
|
|
10
|
+
- `sizeList`: `number[]` — Array of available page size options for user selection. Default: `[]`
|
|
11
|
+
- `showTotalElementsCount`: `boolean` — Controls visibility of total items count display. Default: `true`
|
|
12
|
+
- `totalItemsText`: `string` — Translation key for total items label text. Default: `'quangPaginator.totalItems'`
|
|
13
|
+
- `sizeText`: `string` — Translation key for page size selector label. Default: `'quangPaginator.size'`
|
|
14
|
+
- `pageRangeText`: `string` — Translation key for page range display. Must include `{{page}}` and `{{amountPages}}` placeholders. Default: `'quangPaginator.pageRange'`
|
|
15
|
+
- `componentId`: `string` — Unique identifier for the paginator instance
|
|
16
|
+
- `componentTabIndex`: `number` — Base tab index for paginator controls. Default: `0`
|
|
17
|
+
- `componentClass`: `string | string[]` — Additional CSS classes for styling customization
|
|
22
18
|
|
|
23
19
|
## Outputs
|
|
24
20
|
|
|
25
|
-
- `changePage`:
|
|
26
|
-
- `changeSize`:
|
|
21
|
+
- `changePage`: `EventEmitter<number>` — Emitted when user navigates to a different page
|
|
22
|
+
- `changeSize`: `EventEmitter<number>` — Emitted when user changes the page size
|
|
27
23
|
|
|
28
24
|
## Usage
|
|
29
25
|
|
|
26
|
+
### Basic Paginator
|
|
27
|
+
|
|
30
28
|
```html
|
|
31
29
|
<quang-paginator
|
|
32
|
-
[page]="
|
|
33
|
-
[pageSize]="
|
|
34
|
-
[
|
|
35
|
-
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
[page]="currentPage"
|
|
31
|
+
[pageSize]="itemsPerPage"
|
|
32
|
+
[totalItems]="totalItemCount"
|
|
33
|
+
(changePage)="onPageChange($event)"
|
|
34
|
+
(changeSize)="onPageSizeChange($event)"
|
|
35
|
+
>
|
|
36
|
+
</quang-paginator>
|
|
39
37
|
```
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
#### TypeScript Example
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
export class MyComponent {
|
|
43
|
+
currentPage = 1
|
|
44
|
+
itemsPerPage = 20
|
|
45
|
+
totalItemCount = 150
|
|
46
|
+
|
|
47
|
+
onPageChange(page: number): void {
|
|
48
|
+
this.currentPage = page
|
|
49
|
+
// Load data for new page
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
onPageSizeChange(pageSize: number): void {
|
|
53
|
+
this.itemsPerPage = pageSize
|
|
54
|
+
this.currentPage = 1 // Reset to first page
|
|
55
|
+
// Load data with new page size
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Translation Integration
|
|
61
|
+
|
|
62
|
+
The component uses QuangTranslationService for all text content:
|
|
42
63
|
|
|
43
|
-
|
|
64
|
+
- **Default Keys**: Uses `quangPaginator.*` translation keys
|
|
65
|
+
- **Custom Override**: All text keys can be overridden via inputs
|
|
66
|
+
- **Placeholder Support**: Page range text supports `{{page}}` and `{{amountPages}}` placeholders
|
|
67
|
+
- **Dynamic Translation**: Responds to language changes automatically
|
|
@@ -2,53 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
The `QuangSelectComponent` supports single or multiple selections from a dropdown list.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Input
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
- Customizable options
|
|
7
|
+
- `selectOptions`: `SelectOption[]` - Array of options to display in the dropdown (required)
|
|
8
|
+
- `selectionMode`: `'single' | 'multiple'` - Selection mode (default: 'single')
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
All standard inputs inherited from `QuangBaseComponent`: `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
- `selectionMode`: `'single' | 'multiple'` — Enables single or multiple selection mode. Default: `'single'`.
|
|
15
|
-
- All standard form/label/validation-related inputs inherited from `QuangBaseComponent`:
|
|
16
|
-
- `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
|
|
12
|
+
## Output
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- All standard outputs inherited from `QuangBaseComponent`:
|
|
21
|
-
- `componentBlur`
|
|
14
|
+
All standard outputs inherited from `QuangBaseComponent`: `componentBlur`
|
|
22
15
|
|
|
23
16
|
## Usage
|
|
24
17
|
|
|
18
|
+
### Single Selection
|
|
25
19
|
```html
|
|
26
20
|
<quang-select
|
|
27
21
|
[errorMap]="errors()"
|
|
28
|
-
[isReadonly]="isReadonly()"
|
|
29
22
|
[selectOptions]="stringList"
|
|
30
|
-
class="col-4"
|
|
31
23
|
componentLabel="form.label.select"
|
|
32
|
-
componentPlaceholder="
|
|
24
|
+
componentPlaceholder="Select an option"
|
|
33
25
|
formControlName="testInput"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
/>
|
|
26
|
+
selectionMode="single">
|
|
27
|
+
</quang-select>
|
|
28
|
+
```
|
|
38
29
|
|
|
30
|
+
### Multiple Selection
|
|
31
|
+
```html
|
|
39
32
|
<quang-select
|
|
40
33
|
[errorMap]="errors()"
|
|
41
|
-
[isReadonly]="isReadonly()"
|
|
42
34
|
[selectOptions]="numberList"
|
|
43
|
-
class="col-4"
|
|
44
35
|
componentLabel="form.label.multipleSelect"
|
|
45
|
-
componentPlaceholder="
|
|
36
|
+
componentPlaceholder="Select multiple options"
|
|
46
37
|
formControlName="testInputMultiple"
|
|
47
|
-
selectionMode="multiple"
|
|
48
|
-
|
|
49
|
-
/>
|
|
38
|
+
selectionMode="multiple">
|
|
39
|
+
</quang-select>
|
|
50
40
|
```
|
|
51
41
|
|
|
52
|
-
##
|
|
42
|
+
## QuangTranslationService Integration
|
|
53
43
|
|
|
54
|
-
|
|
44
|
+
The component supports automatic translation of all labels, help messages, and error messages through `QuangTranslationService`.
|
|
@@ -2,29 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
The `QuangWysiwygComponent` is a rich text editor based on [SunEditor](https://github.com/JiHong88/SunEditor), offering a wide range of formatting options for creating and editing HTML content.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Input
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- `wysiwygOptions`: `object` - Configuration options for the editor (required)
|
|
8
|
+
- `minHeight`: `string | undefined` - Minimum height for the editor area (default: '200px')
|
|
9
|
+
- `highlightColor`: `boolean` - Show/hide the highlight color button in toolbar (default: true)
|
|
10
|
+
- `isReadonly`: `boolean` - If true, the editor is readonly
|
|
11
|
+
- `onImageUploadError`: `(errorMessage: any, result: any, core: any) => boolean` - Callback for image upload errors
|
|
12
|
+
- `onFileDrop`: `(e: any, cleanData: any, maxCharCount: any, core: any) => boolean` - Callback for file drop events
|
|
13
|
+
- Toolbar button toggles (all `boolean`, default: `true`): `font`, `fontSize`, `formatBlock`, `paragraphStyle`, `blockquote`, `bold`, `underline`, `italic`, `strike`, `fontColor`, `textStyle`, `removeFormat`, `align`, `list`, `table`, `link`, `image`, `fullScreen`, `showBlocks`
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
All standard inputs inherited from `QuangBaseComponent`: `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
- `minHeight`: `string | undefined` — Minimum height for the editor area. Default: `'200px'`.
|
|
15
|
-
- `highlightColor`: `boolean` — Show/hide the highlight color button in the toolbar. Default: `true`.
|
|
16
|
-
- `isReadonly`: `boolean` — If true, the editor is readonly.
|
|
17
|
-
- `onImageUploadError`: `(errorMessage: any, result: any, core: any) => boolean` — Callback for image upload errors.
|
|
18
|
-
- `onFileDrop`: `(e: any, cleanData: any, maxCharCount: any, core: any) => boolean` — Callback for file drop events.
|
|
19
|
-
- Toolbar button toggles (all `boolean`, default: `true`):
|
|
20
|
-
- `font`, `fontSize`, `formatBlock`, `paragraphStyle`, `blockquote`, `bold`, `underline`, `italic`, `strike`, `fontColor`, `textStyle`, `removeFormat`, `align`, `list`, `table`, `link`, `image`, `fullScreen`, `showBlocks`
|
|
21
|
-
- All standard form/label/validation-related inputs inherited from `QuangBaseComponent`:
|
|
22
|
-
- `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
|
|
17
|
+
## Output
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- All standard outputs inherited from `QuangBaseComponent`:
|
|
27
|
-
- `componentBlur`
|
|
19
|
+
All standard outputs inherited from `QuangBaseComponent`: `componentBlur`
|
|
28
20
|
|
|
29
21
|
## Usage
|
|
30
22
|
|
|
@@ -45,11 +37,7 @@ The `QuangWysiwygComponent` is a rich text editor based on [SunEditor](https://g
|
|
|
45
37
|
### Note
|
|
46
38
|
|
|
47
39
|
Remember to import:
|
|
48
|
-
|
|
49
40
|
`node_modules/quang/components/wysiwyg/global-wysiswyg.component.scss`
|
|
50
|
-
|
|
51
41
|
or
|
|
52
|
-
|
|
53
42
|
`quang/components/wysiwyg/global-wysiswyg.component.scss`
|
|
54
|
-
|
|
55
43
|
in your global style (suggested "vendors" folder).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgClass } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { input, signal, computed, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
6
|
import { TranslocoPipe } from '@jsverse/transloco';
|
|
@@ -20,20 +20,27 @@ class QuangInputComponent extends QuangBaseComponent {
|
|
|
20
20
|
this.maxNumber = input(undefined);
|
|
21
21
|
this.componentStep = input(1);
|
|
22
22
|
this.resizable = input(true);
|
|
23
|
+
this.buttonClass = input('');
|
|
24
|
+
this.showHidePasswordButton = input(true);
|
|
25
|
+
this.showPassword = signal(false);
|
|
26
|
+
this.componentInputType = computed(() => this.componentType() === 'password' && this.showPassword() ? 'text' : this.componentType());
|
|
23
27
|
toObservable(this.componentType)
|
|
24
28
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
25
29
|
.subscribe(() => {
|
|
26
30
|
this.setupFormControl();
|
|
27
31
|
});
|
|
28
32
|
}
|
|
33
|
+
onTogglePasswordVisibility() {
|
|
34
|
+
this.showPassword.update((current) => !current);
|
|
35
|
+
}
|
|
29
36
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: QuangInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: QuangInputComponent, isStandalone: true, selector: "quang-input", inputs: { componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: true, transformFunction: null }, maxLengthText: { classPropertyName: "maxLengthText", publicName: "maxLengthText", isSignal: true, isRequired: false, transformFunction: null }, minLengthText: { classPropertyName: "minLengthText", publicName: "minLengthText", isSignal: true, isRequired: false, transformFunction: null }, minNumber: { classPropertyName: "minNumber", publicName: "minNumber", isSignal: true, isRequired: false, transformFunction: null }, maxNumber: { classPropertyName: "maxNumber", publicName: "maxNumber", isSignal: true, isRequired: false, transformFunction: null }, componentStep: { classPropertyName: "componentStep", publicName: "componentStep", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
37
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: QuangInputComponent, isStandalone: true, selector: "quang-input", inputs: { componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: true, transformFunction: null }, maxLengthText: { classPropertyName: "maxLengthText", publicName: "maxLengthText", isSignal: true, isRequired: false, transformFunction: null }, minLengthText: { classPropertyName: "minLengthText", publicName: "minLengthText", isSignal: true, isRequired: false, transformFunction: null }, minNumber: { classPropertyName: "minNumber", publicName: "minNumber", isSignal: true, isRequired: false, transformFunction: null }, maxNumber: { classPropertyName: "maxNumber", publicName: "maxNumber", isSignal: true, isRequired: false, transformFunction: null }, componentStep: { classPropertyName: "componentStep", publicName: "componentStep", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, buttonClass: { classPropertyName: "buttonClass", publicName: "buttonClass", isSignal: true, isRequired: false, transformFunction: null }, showHidePasswordButton: { classPropertyName: "showHidePasswordButton", publicName: "showHidePasswordButton", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
31
38
|
{
|
|
32
39
|
provide: NG_VALUE_ACCESSOR,
|
|
33
40
|
useExisting: forwardRef(() => QuangInputComponent),
|
|
34
41
|
multi: true,
|
|
35
42
|
},
|
|
36
|
-
], usesInheritance: true, ngImport: i0, template: "@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <input\n [attr.maxLength]=\"maxLengthText()\"\n
|
|
43
|
+
], usesInheritance: true, ngImport: i0, template: "@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <div class=\"input-container\">\n <input\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.with-button-password]=\"showHidePasswordButton()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [max]=\"maxNumber()\"\n [min]=\"minNumber()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [step]=\"componentStep()\"\n [tabIndex]=\"componentTabIndex()\"\n [type]=\"componentInputType()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n autocomplete=\"off\"\n class=\"form-control\"\n />\n @if (componentType() === 'password' && showHidePasswordButton()) {\n <button\n [class.border-danger]=\"_showErrors()\"\n [class.border-success]=\"_showSuccess()\"\n [ngClass]=\"buttonClass()\"\n (click)=\"_ngControl()?.disabled ? null : onTogglePasswordVisibility()\"\n #calendarButton\n aria-label=\"calendar-button\"\n class=\"btn btn-outline-secondary btn-outline-password\"\n type=\"button\"\n >\n @if (showPassword()) {\n <ng-content select=\"[hide-password]\"></ng-content>\n } @else {\n <ng-content select=\"[show-password]\"></ng-content>\n }\n </button>\n }\n </div>\n }\n @if (componentType() === 'textarea') {\n <textarea\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.no-resize]=\"!resizable()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n class=\"form-control\"\n ></textarea>\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n </div>\n}\n", styles: ["input::-webkit-search-cancel-button{-webkit-appearance:none;height:.75rem;width:.75rem;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 3 1024 1024' width='12' height='12' fill='currentColor'%3E%3Cpath d='M9 1018q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5l459-459 459 459q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5 9-9 9-22 0-13-9-22l-459-459 459-459q9-9 9-22 0-13-9-22-9-9-22-9-13 0-22 9l-459 459-459-459q-9-9-22-9-13 0-22 9-9 9-9 22 0 13 9 22l459 459-459 459q-9 9-9 22 0 13 9 22l0 0z'/%3E%3C/svg%3E%0A\");cursor:pointer}:host{display:block}.no-resize{resize:none}.btn-outline-password{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0;min-width:unset;display:flex;border-color:var(--bs-border-color)}.input-container{display:flex}input{flex:1}input.with-button-password{border-top-right-radius:0;border-bottom-right-radius:0}input:disabled{border-radius:var(--bs-border-radius)}.border-danger{border-color:var(--bs-form-invalid-border-color)}.border-success{border-color:var(--bs-form-valid-border-color)}\n"], dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
37
44
|
}
|
|
38
45
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: QuangInputComponent, decorators: [{
|
|
39
46
|
type: Component,
|
|
@@ -43,7 +50,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
|
|
|
43
50
|
useExisting: forwardRef(() => QuangInputComponent),
|
|
44
51
|
multi: true,
|
|
45
52
|
},
|
|
46
|
-
], imports: [TranslocoPipe, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <input\n [attr.maxLength]=\"maxLengthText()\"\n
|
|
53
|
+
], imports: [TranslocoPipe, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <div class=\"input-container\">\n <input\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.with-button-password]=\"showHidePasswordButton()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [max]=\"maxNumber()\"\n [min]=\"minNumber()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [step]=\"componentStep()\"\n [tabIndex]=\"componentTabIndex()\"\n [type]=\"componentInputType()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n autocomplete=\"off\"\n class=\"form-control\"\n />\n @if (componentType() === 'password' && showHidePasswordButton()) {\n <button\n [class.border-danger]=\"_showErrors()\"\n [class.border-success]=\"_showSuccess()\"\n [ngClass]=\"buttonClass()\"\n (click)=\"_ngControl()?.disabled ? null : onTogglePasswordVisibility()\"\n #calendarButton\n aria-label=\"calendar-button\"\n class=\"btn btn-outline-secondary btn-outline-password\"\n type=\"button\"\n >\n @if (showPassword()) {\n <ng-content select=\"[hide-password]\"></ng-content>\n } @else {\n <ng-content select=\"[show-password]\"></ng-content>\n }\n </button>\n }\n </div>\n }\n @if (componentType() === 'textarea') {\n <textarea\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.no-resize]=\"!resizable()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n class=\"form-control\"\n ></textarea>\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n </div>\n}\n", styles: ["input::-webkit-search-cancel-button{-webkit-appearance:none;height:.75rem;width:.75rem;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 3 1024 1024' width='12' height='12' fill='currentColor'%3E%3Cpath d='M9 1018q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5l459-459 459 459q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5 9-9 9-22 0-13-9-22l-459-459 459-459q9-9 9-22 0-13-9-22-9-9-22-9-13 0-22 9l-459 459-459-459q-9-9-22-9-13 0-22 9-9 9-9 22 0 13 9 22l459 459-459 459q-9 9-9 22 0 13 9 22l0 0z'/%3E%3C/svg%3E%0A\");cursor:pointer}:host{display:block}.no-resize{resize:none}.btn-outline-password{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0;min-width:unset;display:flex;border-color:var(--bs-border-color)}.input-container{display:flex}input{flex:1}input.with-button-password{border-top-right-radius:0;border-bottom-right-radius:0}input:disabled{border-radius:var(--bs-border-radius)}.border-danger{border-color:var(--bs-form-invalid-border-color)}.border-success{border-color:var(--bs-form-valid-border-color)}\n"] }]
|
|
47
54
|
}], ctorParameters: () => [] });
|
|
48
55
|
|
|
49
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quang-components-input.mjs","sources":["../../../projects/quang/components/input/input.component.ts","../../../projects/quang/components/input/input.component.html","../../../projects/quang/components/input/quang-components-input.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport { ChangeDetectionStrategy, Component, forwardRef, input } from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\n\nimport { QuangBaseComponent } from 'quang/components/shared'\n\nexport type InputType = 'text' | 'textarea' | 'password' | 'email' | 'number' | 'url' | 'search' | 'tel' | 'color'\n\n@Component({\n selector: 'quang-input',\n templateUrl: './input.component.html',\n styleUrl: './input.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangInputComponent),\n multi: true,\n },\n ],\n imports: [TranslocoPipe, NgClass],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Input component that handles all the types declared in {@link InputType}\n * @property {boolean} resizable just for textarea {@link InputType}\n */\nexport class QuangInputComponent extends QuangBaseComponent<string | number> {\n componentType = input.required<InputType>()\n\n maxLengthText = input<number | null>(null)\n\n minLengthText = input<number | null>(null)\n\n minNumber = input<number | undefined>(undefined)\n\n maxNumber = input<number | undefined>(undefined)\n\n componentStep = input<number>(1)\n\n resizable = input(true)\n\n constructor() {\n super()\n toObservable(this.componentType)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.setupFormControl()\n })\n }\n}\n","@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <input\n [attr.maxLength]=\"maxLengthText()\"\n
|
|
1
|
+
{"version":3,"file":"quang-components-input.mjs","sources":["../../../projects/quang/components/input/input.component.ts","../../../projects/quang/components/input/input.component.html","../../../projects/quang/components/input/quang-components-input.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport { ChangeDetectionStrategy, Component, computed, forwardRef, input, signal } from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\n\nimport { QuangBaseComponent } from 'quang/components/shared'\n\nexport type InputType = 'text' | 'textarea' | 'password' | 'email' | 'number' | 'url' | 'search' | 'tel' | 'color'\n\n@Component({\n selector: 'quang-input',\n templateUrl: './input.component.html',\n styleUrl: './input.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangInputComponent),\n multi: true,\n },\n ],\n imports: [TranslocoPipe, NgClass],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Input component that handles all the types declared in {@link InputType}\n * @property {boolean} resizable just for textarea {@link InputType}\n */\nexport class QuangInputComponent extends QuangBaseComponent<string | number> {\n componentType = input.required<InputType>()\n\n maxLengthText = input<number | null>(null)\n\n minLengthText = input<number | null>(null)\n\n minNumber = input<number | undefined>(undefined)\n\n maxNumber = input<number | undefined>(undefined)\n\n componentStep = input<number>(1)\n\n resizable = input(true)\n\n buttonClass = input<string>('')\n\n showHidePasswordButton = input(true)\n\n showPassword = signal<boolean>(false)\n\n componentInputType = computed<InputType>(() =>\n this.componentType() === 'password' && this.showPassword() ? 'text' : this.componentType()\n )\n\n constructor() {\n super()\n toObservable(this.componentType)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.setupFormControl()\n })\n }\n\n onTogglePasswordVisibility(): void {\n this.showPassword.update((current) => !current)\n }\n}\n","@if (componentType()) {\n <div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n @if (componentType() !== 'textarea') {\n <div class=\"input-container\">\n <input\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.with-button-password]=\"showHidePasswordButton()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [max]=\"maxNumber()\"\n [min]=\"minNumber()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [step]=\"componentStep()\"\n [tabIndex]=\"componentTabIndex()\"\n [type]=\"componentInputType()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n autocomplete=\"off\"\n class=\"form-control\"\n />\n @if (componentType() === 'password' && showHidePasswordButton()) {\n <button\n [class.border-danger]=\"_showErrors()\"\n [class.border-success]=\"_showSuccess()\"\n [ngClass]=\"buttonClass()\"\n (click)=\"_ngControl()?.disabled ? null : onTogglePasswordVisibility()\"\n #calendarButton\n aria-label=\"calendar-button\"\n class=\"btn btn-outline-secondary btn-outline-password\"\n type=\"button\"\n >\n @if (showPassword()) {\n <ng-content select=\"[hide-password]\"></ng-content>\n } @else {\n <ng-content select=\"[show-password]\"></ng-content>\n }\n </button>\n }\n </div>\n }\n @if (componentType() === 'textarea') {\n <textarea\n [attr.maxLength]=\"maxLengthText()\"\n [attr.minLength]=\"minLengthText()\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.no-resize]=\"!resizable()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_value()\"\n (blur)=\"onBlurHandler()\"\n (input)=\"onChangedEventHandler($event)\"\n class=\"form-control\"\n ></textarea>\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|