@egose/shadcn-theme-ng-tw 0.0.28 → 0.2.0
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/README.md +130 -13
- package/accordion/README.md +376 -34
- package/accordion/fesm2022/accordion.mjs +20 -20
- package/alert/README.md +343 -34
- package/alert/fesm2022/alert.mjs +18 -18
- package/alert-dialog/README.md +471 -5
- package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
- package/alert-dialog/types/alert-dialog.d.ts +1 -1
- package/aspect-ratio/README.md +272 -5
- package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
- package/autocomplete/README.md +473 -34
- package/autocomplete/fesm2022/autocomplete.mjs +54 -54
- package/autocomplete/types/autocomplete.d.ts +1 -1
- package/avatar/README.md +357 -5
- package/avatar/fesm2022/avatar.mjs +32 -32
- package/badge/README.md +289 -34
- package/badge/fesm2022/badge.mjs +4 -4
- package/basic-alert/README.md +324 -34
- package/basic-alert/fesm2022/basic-alert.mjs +4 -4
- package/basic-alert/types/basic-alert.d.ts +1 -1
- package/breadcrumb/README.md +406 -5
- package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
- package/button/README.md +453 -34
- package/button/fesm2022/button.mjs +96 -118
- package/button/types/button.d.ts +7 -10
- package/button-group/README.md +318 -5
- package/button-group/fesm2022/button-group.mjs +20 -20
- package/calendar/README.md +328 -34
- package/calendar/fesm2022/calendar.mjs +154 -154
- package/card/README.md +331 -5
- package/card/fesm2022/card.mjs +33 -33
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +47 -44
- package/carousel/types/carousel.d.ts +1 -1
- package/checkbox/README.md +291 -34
- package/checkbox/fesm2022/checkbox.mjs +22 -20
- package/checkbox/types/checkbox.d.ts +5 -4
- package/collapsible/README.md +332 -5
- package/collapsible/fesm2022/collapsible.mjs +15 -15
- package/combobox/README.md +507 -5
- package/combobox/fesm2022/combobox.mjs +95 -92
- package/combobox/types/combobox.d.ts +1 -1
- package/command/README.md +435 -5
- package/command/fesm2022/command.mjs +56 -56
- package/confirmation-dialog/README.md +272 -34
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
- package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
- package/context-menu/README.md +366 -5
- package/context-menu/fesm2022/context-menu.mjs +9 -9
- package/date-picker/README.md +436 -34
- package/date-picker/fesm2022/date-picker.mjs +79 -68
- package/date-picker/types/date-picker.d.ts +8 -4
- package/dialog/README.md +419 -34
- package/dialog/fesm2022/dialog.mjs +48 -48
- package/drawer/README.md +395 -5
- package/drawer/fesm2022/drawer.mjs +45 -45
- package/dropdown-menu/README.md +417 -5
- package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
- package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
- package/empty/README.md +329 -5
- package/empty/fesm2022/empty.mjs +31 -31
- package/field/README.md +385 -5
- package/field/fesm2022/field.mjs +59 -59
- package/field/types/field.d.ts +1 -1
- package/form-checkbox/README.md +283 -34
- package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
- package/form-checkbox/types/form-checkbox.d.ts +7 -1
- package/form-date-picker/README.md +293 -34
- package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
- package/form-date-picker/types/form-date-picker.d.ts +7 -1
- package/form-field/README.md +327 -34
- package/form-field/fesm2022/form-field.mjs +30 -16
- package/form-field/types/form-field.d.ts +28 -20
- package/form-field-simple/README.md +311 -34
- package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
- package/form-searchable-multiselect/README.md +332 -34
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
- package/form-select/README.md +321 -34
- package/form-select/fesm2022/form-select.mjs +62 -29
- package/form-select/types/form-select.d.ts +7 -1
- package/form-text-input/README.md +342 -34
- package/form-text-input/fesm2022/form-text-input.mjs +43 -55
- package/form-text-input/types/form-text-input.d.ts +9 -12
- package/form-textarea/README.md +318 -34
- package/form-textarea/fesm2022/form-textarea.mjs +42 -23
- package/form-textarea/types/form-textarea.d.ts +8 -1
- package/hover-card/README.md +256 -5
- package/hover-card/fesm2022/hover-card.mjs +19 -19
- package/icon/README.md +210 -34
- package/icon/fesm2022/icon.mjs +8 -8
- package/input/README.md +240 -34
- package/input/fesm2022/input.mjs +17 -12
- package/input/types/input.d.ts +2 -1
- package/input-group/README.md +335 -5
- package/input-group/fesm2022/input-group.mjs +37 -37
- package/input-group/types/input-group.d.ts +3 -3
- package/input-otp/README.md +375 -5
- package/input-otp/fesm2022/input-otp.mjs +27 -27
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +54 -54
- package/kbd/README.md +291 -5
- package/kbd/fesm2022/kbd.mjs +13 -13
- package/label/README.md +243 -34
- package/label/fesm2022/label.mjs +9 -9
- package/label/types/label.d.ts +1 -1
- package/layout-simple/README.md +174 -44
- package/layout-simple/fesm2022/layout-simple.mjs +917 -398
- package/layout-simple/types/layout-simple.d.ts +180 -129
- package/menu/README.md +418 -0
- package/menu/fesm2022/menu.mjs +461 -0
- package/menu/package.json +24 -0
- package/menu/types/menu.d.ts +137 -0
- package/menubar/README.md +343 -5
- package/menubar/fesm2022/menubar.mjs +13 -13
- package/native-select/README.md +323 -5
- package/native-select/fesm2022/native-select.mjs +19 -19
- package/navigation-menu/README.md +369 -5
- package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
- package/package.json +183 -154
- package/pagination/README.md +388 -5
- package/pagination/fesm2022/pagination.mjs +63 -63
- package/popover/README.md +302 -34
- package/popover/fesm2022/popover.mjs +30 -30
- package/progress/README.md +311 -5
- package/progress/fesm2022/progress.mjs +13 -13
- package/radio-group/README.md +335 -34
- package/radio-group/fesm2022/radio-group.mjs +26 -19
- package/resizable/README.md +269 -5
- package/resizable/fesm2022/resizable.mjs +19 -19
- package/scroll-area/README.md +233 -5
- package/scroll-area/fesm2022/scroll-area.mjs +9 -9
- package/searchable-multiselect/README.md +294 -34
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
- package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
- package/select/README.md +408 -34
- package/select/fesm2022/select.mjs +80 -72
- package/select/types/select.d.ts +3 -1
- package/separator/README.md +193 -34
- package/separator/fesm2022/separator.mjs +9 -9
- package/separator/types/separator.d.ts +1 -1
- package/sheet/README.md +282 -34
- package/sheet/fesm2022/sheet.mjs +30 -30
- package/sidebar/README.md +457 -5
- package/sidebar/fesm2022/sidebar.mjs +136 -134
- package/sidebar/types/sidebar.d.ts +3 -3
- package/skeleton/README.md +217 -5
- package/skeleton/fesm2022/skeleton.mjs +9 -9
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +29 -25
- package/sonner/README.md +317 -34
- package/sonner/fesm2022/sonner.mjs +9 -9
- package/spinner/README.md +255 -34
- package/spinner/fesm2022/spinner.mjs +8 -8
- package/switch/README.md +281 -34
- package/switch/fesm2022/switch.mjs +12 -14
- package/table/README.md +423 -5
- package/table/fesm2022/table.mjs +41 -41
- package/tabs/README.md +382 -34
- package/tabs/fesm2022/tabs.mjs +48 -38
- package/textarea/README.md +282 -5
- package/textarea/fesm2022/textarea.mjs +9 -9
- package/toggle/README.md +270 -5
- package/toggle/fesm2022/toggle.mjs +14 -14
- package/toggle-group/README.md +340 -5
- package/toggle-group/fesm2022/toggle-group.mjs +13 -13
- package/toggle-group/types/toggle-group.d.ts +13 -7
- package/tooltip/README.md +240 -34
- package/tooltip/fesm2022/tooltip.mjs +14 -14
- package/typography/README.md +271 -5
- package/typography/fesm2022/typography.mjs +53 -53
- package/typography/types/typography.d.ts +12 -12
- package/utils/README.md +274 -34
- package/utils/fesm2022/utils.mjs +68 -44
- package/accordion/fesm2022/accordion.mjs.map +0 -1
- package/alert/fesm2022/alert.mjs.map +0 -1
- package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
- package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
- package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
- package/avatar/fesm2022/avatar.mjs.map +0 -1
- package/badge/fesm2022/badge.mjs.map +0 -1
- package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
- package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
- package/button/fesm2022/button.mjs.map +0 -1
- package/button-group/fesm2022/button-group.mjs.map +0 -1
- package/calendar/fesm2022/calendar.mjs.map +0 -1
- package/card/fesm2022/card.mjs.map +0 -1
- package/carousel/fesm2022/carousel.mjs.map +0 -1
- package/checkbox/fesm2022/checkbox.mjs.map +0 -1
- package/collapsible/fesm2022/collapsible.mjs.map +0 -1
- package/combobox/fesm2022/combobox.mjs.map +0 -1
- package/command/fesm2022/command.mjs.map +0 -1
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
- package/context-menu/fesm2022/context-menu.mjs.map +0 -1
- package/date-picker/fesm2022/date-picker.mjs.map +0 -1
- package/dialog/fesm2022/dialog.mjs.map +0 -1
- package/drawer/fesm2022/drawer.mjs.map +0 -1
- package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
- package/empty/fesm2022/empty.mjs.map +0 -1
- package/field/fesm2022/field.mjs.map +0 -1
- package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
- package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
- package/form-field/fesm2022/form-field.mjs.map +0 -1
- package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
- package/form-select/fesm2022/form-select.mjs.map +0 -1
- package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
- package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
- package/hover-card/fesm2022/hover-card.mjs.map +0 -1
- package/icon/fesm2022/icon.mjs.map +0 -1
- package/input/fesm2022/input.mjs.map +0 -1
- package/input-group/fesm2022/input-group.mjs.map +0 -1
- package/input-otp/fesm2022/input-otp.mjs.map +0 -1
- package/item/fesm2022/item.mjs.map +0 -1
- package/kbd/fesm2022/kbd.mjs.map +0 -1
- package/label/fesm2022/label.mjs.map +0 -1
- package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
- package/menubar/fesm2022/menubar.mjs.map +0 -1
- package/native-select/fesm2022/native-select.mjs.map +0 -1
- package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
- package/pagination/fesm2022/pagination.mjs.map +0 -1
- package/popover/fesm2022/popover.mjs.map +0 -1
- package/progress/fesm2022/progress.mjs.map +0 -1
- package/radio-group/fesm2022/radio-group.mjs.map +0 -1
- package/resizable/fesm2022/resizable.mjs.map +0 -1
- package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
- package/select/fesm2022/select.mjs.map +0 -1
- package/separator/fesm2022/separator.mjs.map +0 -1
- package/sheet/fesm2022/sheet.mjs.map +0 -1
- package/sidebar/fesm2022/sidebar.mjs.map +0 -1
- package/skeleton/fesm2022/skeleton.mjs.map +0 -1
- package/slider/fesm2022/slider.mjs.map +0 -1
- package/sonner/fesm2022/sonner.mjs.map +0 -1
- package/spinner/fesm2022/spinner.mjs.map +0 -1
- package/switch/fesm2022/switch.mjs.map +0 -1
- package/table/fesm2022/table.mjs.map +0 -1
- package/tabs/fesm2022/tabs.mjs.map +0 -1
- package/textarea/fesm2022/textarea.mjs.map +0 -1
- package/toggle/fesm2022/toggle.mjs.map +0 -1
- package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
- package/tooltip/fesm2022/tooltip.mjs.map +0 -1
- package/typography/fesm2022/typography.mjs.map +0 -1
- package/utils/fesm2022/utils.mjs.map +0 -1
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnChanges, ElementRef, Renderer2 } from '@angular/core';
|
|
3
2
|
import { ClassValue } from 'clsx';
|
|
4
3
|
|
|
5
|
-
declare class SpreadAttrsDirective implements OnChanges {
|
|
6
|
-
private el;
|
|
7
|
-
private renderer;
|
|
8
|
-
attrs: _angular_core.InputSignal<Record<string, any>>;
|
|
9
|
-
constructor(el: ElementRef, renderer: Renderer2);
|
|
10
|
-
ngOnChanges(): void;
|
|
11
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpreadAttrsDirective, never>;
|
|
12
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SpreadAttrsDirective, "[spreadAttrs]", never, { "attrs": { "alias": "attrs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
13
|
-
}
|
|
14
4
|
declare class EgFormTextInput {
|
|
5
|
+
private readonly formGroupDirective;
|
|
6
|
+
private readonly generatedId;
|
|
15
7
|
label: _angular_core.InputSignal<string | undefined>;
|
|
16
8
|
controlId: _angular_core.InputSignal<string | undefined>;
|
|
17
9
|
controlName: _angular_core.InputSignal<string>;
|
|
18
10
|
error: _angular_core.InputSignal<string | undefined>;
|
|
19
11
|
hint: _angular_core.InputSignal<string | undefined>;
|
|
20
|
-
id: _angular_core.InputSignal<string>;
|
|
12
|
+
id: _angular_core.InputSignal<string | undefined>;
|
|
21
13
|
name: _angular_core.InputSignal<string | undefined>;
|
|
22
14
|
type: _angular_core.InputSignal<string>;
|
|
23
15
|
placeholder: _angular_core.InputSignal<string>;
|
|
@@ -31,6 +23,11 @@ declare class EgFormTextInput {
|
|
|
31
23
|
autocomplete: _angular_core.InputSignal<string | undefined>;
|
|
32
24
|
autofocus: _angular_core.InputSignal<boolean>;
|
|
33
25
|
required: _angular_core.InputSignal<boolean>;
|
|
26
|
+
readonly effectiveId: _angular_core.Signal<string>;
|
|
27
|
+
readonly errorId: _angular_core.Signal<string>;
|
|
28
|
+
readonly hintId: _angular_core.Signal<string>;
|
|
29
|
+
describedBy(): string | null;
|
|
30
|
+
effectiveDisabled(): boolean;
|
|
34
31
|
userClass: _angular_core.InputSignal<ClassValue>;
|
|
35
32
|
labelClass: _angular_core.InputSignal<string>;
|
|
36
33
|
inputClass: _angular_core.InputSignal<string>;
|
|
@@ -45,4 +42,4 @@ declare class EgFormTextInput {
|
|
|
45
42
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormTextInput, "eg-form-text-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "maxlength": { "alias": "maxlength"; "required": false; "isSignal": true; }; "minlength": { "alias": "minlength"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "pattern": { "alias": "pattern"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "inputClass": { "alias": "inputClass"; "required": false; "isSignal": true; }; "errorClass": { "alias": "errorClass"; "required": false; "isSignal": true; }; "hintClass": { "alias": "hintClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
export { EgFormTextInput
|
|
45
|
+
export { EgFormTextInput };
|
package/form-textarea/README.md
CHANGED
|
@@ -1,64 +1,348 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Form Textarea (`@egose/shadcn-theme-ng/form-textarea`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`EgFormTextarea` is a reactive-forms wrapper that bundles a `<label>`, a styled `<textarea hlmInput>`, and error/hint text into one form-ready row. It is the Angular equivalent of shadcn/ui's `<FormField> + <Textarea>` pattern for multiline input (comments, descriptions, bios), with generated ids, `aria-describedby` wiring, and `disabled` resolution handled for you.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/form-textarea` (plain Tailwind) and `@egose/shadcn-theme-ng-tw/form-textarea` (`tw:`-prefixed variant). See the [package README](../../README.md) for installation, peer dependencies, and the Tailwind-variant contract. Do not publish this project directory independently.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
# Plain Tailwind (no prefix)
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Peer dependencies (Angular, `@angular/forms`, CDK, `@spartan-ng/brain`, `rxjs`) are documented in the [package README](../../README.md#peer-dependencies).
|
|
14
18
|
|
|
15
|
-
```
|
|
16
|
-
|
|
19
|
+
```ts
|
|
20
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
21
|
+
// tw variant:
|
|
22
|
+
// import { EgFormTextarea } from '@egose/shadcn-theme-ng-tw/form-textarea';
|
|
17
23
|
```
|
|
18
24
|
|
|
19
|
-
##
|
|
25
|
+
## Imports
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
The public API (`src/public-api.ts`) exports exactly one symbol — the standalone component `EgFormTextarea`. There is no `*Imports` array and no `*Module` for this subpath; import the component class directly.
|
|
22
28
|
|
|
23
|
-
```
|
|
24
|
-
|
|
29
|
+
```ts
|
|
30
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
31
|
+
|
|
32
|
+
@Component({
|
|
33
|
+
standalone: true,
|
|
34
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
35
|
+
template: `
|
|
36
|
+
<form [formGroup]="form">
|
|
37
|
+
<eg-form-textarea controlName="bio" label="Bio" placeholder="Tell us about yourself" />
|
|
38
|
+
</form>
|
|
39
|
+
`,
|
|
40
|
+
})
|
|
41
|
+
export class MyForm {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Requirements:
|
|
45
|
+
|
|
46
|
+
- Must sit inside a `<form [formGroup]>` (it injects `FormGroupDirective` and provides `ControlContainer`).
|
|
47
|
+
- `controlName` is required — forwarded as `[formControlName]` to the inner `<textarea>`.
|
|
48
|
+
- The bound `FormControl` holds a `string`.
|
|
49
|
+
|
|
50
|
+
## Anatomy / Structure
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<eg-form-textarea controlName="bio" label="Bio">
|
|
54
|
+
<!-- rendered internally -->
|
|
55
|
+
<hlm-form-field>
|
|
56
|
+
<label hlmLabel for="<effectiveId>">Bio <span>*</span></label>
|
|
57
|
+
<textarea
|
|
58
|
+
hlmInput
|
|
59
|
+
id="<effectiveId>"
|
|
60
|
+
name="bio"
|
|
61
|
+
formControlName="bio"
|
|
62
|
+
rows="3"
|
|
63
|
+
placeholder="…"
|
|
64
|
+
aria-describedby="<effectiveId>-error | <effectiveId>-hint"
|
|
65
|
+
></textarea>
|
|
66
|
+
<hlm-error id="<effectiveId>-error">…</hlm-error>
|
|
67
|
+
<hlm-hint id="<effectiveId>-hint">…</hlm-hint>
|
|
68
|
+
</hlm-form-field>
|
|
69
|
+
</eg-form-textarea>
|
|
25
70
|
```
|
|
26
71
|
|
|
27
|
-
|
|
72
|
+
Real selectors: `eg-form-textarea`, `hlm-form-field`, `label[hlmLabel]`, `textarea[hlmInput]`, `hlm-error`, `hlm-hint`. Note the inner textarea reuses the `hlmInput` styling directive (same class hook as single-line inputs).
|
|
28
73
|
|
|
29
|
-
|
|
74
|
+
## API reference
|
|
30
75
|
|
|
31
|
-
|
|
76
|
+
### `eg-form-textarea` — `EgFormTextarea`
|
|
32
77
|
|
|
33
|
-
|
|
78
|
+
| Input | Type | Default | Description |
|
|
79
|
+
| --------------------- | ------------------------------- | ----------- | ------------------------------------------------------------------------------------------------ |
|
|
80
|
+
| `label` | `string \| undefined` | `undefined` | Field label rendered as `<label hlmLabel>` bound to the textarea id. |
|
|
81
|
+
| `controlName` | `string` | `''` | **Required.** Control name in the parent `FormGroup`; forwarded as `formControlName` and `name`. |
|
|
82
|
+
| `controlId` | `string \| undefined` | `undefined` | Explicit id; falls back to `id`, then generated `eg-form-textarea-…`. |
|
|
83
|
+
| `id` | `string \| undefined` | `undefined` | Alias for an explicit id (same fallback chain). |
|
|
84
|
+
| `error` | `string \| undefined` | `undefined` | Error text rendered in `<hlm-error>`. |
|
|
85
|
+
| `hint` | `string \| undefined` | `undefined` | Hint text rendered in `<hlm-hint>`. |
|
|
86
|
+
| `name` | `string \| undefined` | `undefined` | `name` attribute fallback when `controlName` is empty. |
|
|
87
|
+
| `placeholder` | `string` | `''` | Placeholder text. |
|
|
88
|
+
| `readonly` | `boolean` | `false` | Native `readonly` attribute. |
|
|
89
|
+
| `disabled` | `boolean` | `false` | Wrapper-level disable (OR-ed with the reactive disabled state — see `effectiveDisabled()`). |
|
|
90
|
+
| `maxlength` | `string \| number \| null` | `null` | Native `maxlength`. |
|
|
91
|
+
| `minlength` | `string \| number \| null` | `null` | Native `minlength`. |
|
|
92
|
+
| `required` | `boolean` | `false` | Native `required` + red `*` on the label. |
|
|
93
|
+
| `rows` | `string \| number \| undefined` | `3` | Native `rows` (visible height). |
|
|
94
|
+
| `cols` | `string \| number \| undefined` | `undefined` | Native `cols` (visible width). |
|
|
95
|
+
| `class` (`userClass`) | `ClassValue` | `''` | Extra host classes (merged over `tw:flex tw:flex-col`). |
|
|
96
|
+
| `labelClass` | `string` | `''` | Extra label classes (merged over `tw:mb-1 tw:gap-0`). |
|
|
97
|
+
| `textareaClass` | `string` | `''` | Extra textarea classes (merged over `tw:mb-1`). |
|
|
98
|
+
| `errorClass` | `string` | `''` | Extra error classes (merged over `tw:mt-0`). |
|
|
99
|
+
| `hintClass` | `string` | `''` | Extra hint classes (merged over `tw:mt-0`). |
|
|
34
100
|
|
|
35
|
-
|
|
36
|
-
cd dist/form-textarea
|
|
37
|
-
```
|
|
101
|
+
No outputs. Methods: `describedBy(): string | null` (error id when invalid + dirty/touched, else hint id, else `null`); `effectiveDisabled(): boolean` (`disabled()` OR the control's reactive disabled state). Readonly computeds: `effectiveId()`, `errorId()`, `hintId()`.
|
|
38
102
|
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm publish
|
|
42
|
-
```
|
|
103
|
+
## Examples
|
|
43
104
|
|
|
44
|
-
|
|
105
|
+
### 1. Basic comment box
|
|
45
106
|
|
|
46
|
-
|
|
107
|
+
```ts
|
|
108
|
+
import { Component } from '@angular/core';
|
|
109
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
110
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
47
111
|
|
|
48
|
-
|
|
49
|
-
|
|
112
|
+
@Component({
|
|
113
|
+
standalone: true,
|
|
114
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
115
|
+
template: `
|
|
116
|
+
<form [formGroup]="form" (ngSubmit)="post()">
|
|
117
|
+
<eg-form-textarea controlName="comment" label="Comment" placeholder="Write a comment…" [rows]="4" />
|
|
118
|
+
<button type="submit">Post</button>
|
|
119
|
+
</form>
|
|
120
|
+
`,
|
|
121
|
+
})
|
|
122
|
+
export class BasicExample {
|
|
123
|
+
readonly form = new FormGroup({
|
|
124
|
+
comment: new FormControl<string>('', { nonNullable: true }),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
post() {
|
|
128
|
+
console.log(this.form.value.comment);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
50
131
|
```
|
|
51
132
|
|
|
52
|
-
|
|
133
|
+
### 2. Sizes via `rows` / `cols` / `textareaClass`
|
|
53
134
|
|
|
54
|
-
|
|
135
|
+
```ts
|
|
136
|
+
import { Component } from '@angular/core';
|
|
137
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
138
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
55
139
|
|
|
56
|
-
|
|
57
|
-
|
|
140
|
+
@Component({
|
|
141
|
+
standalone: true,
|
|
142
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
143
|
+
template: `
|
|
144
|
+
<form [formGroup]="form" class="tw:grid tw:gap-4">
|
|
145
|
+
<eg-form-textarea controlName="short" label="Compact (2 rows)" [rows]="2" />
|
|
146
|
+
<eg-form-textarea controlName="default" label="Default (3 rows)" />
|
|
147
|
+
<eg-form-textarea controlName="tall" label="Tall composer" [rows]="8" textareaClass="tw:resize-y tw:min-h-40" />
|
|
148
|
+
</form>
|
|
149
|
+
`,
|
|
150
|
+
})
|
|
151
|
+
export class SizesExample {
|
|
152
|
+
readonly form = new FormGroup({
|
|
153
|
+
short: new FormControl<string>('', { nonNullable: true }),
|
|
154
|
+
default: new FormControl<string>('', { nonNullable: true }),
|
|
155
|
+
tall: new FormControl<string>('', { nonNullable: true }),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
58
158
|
```
|
|
59
159
|
|
|
60
|
-
|
|
160
|
+
### 3. Validation with a live character counter
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { Component } from '@angular/core';
|
|
164
|
+
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
165
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
166
|
+
|
|
167
|
+
@Component({
|
|
168
|
+
standalone: true,
|
|
169
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
170
|
+
template: `
|
|
171
|
+
<form [formGroup]="form" (ngSubmit)="submit()">
|
|
172
|
+
<eg-form-textarea
|
|
173
|
+
controlName="bio"
|
|
174
|
+
label="Bio"
|
|
175
|
+
placeholder="A few sentences about you"
|
|
176
|
+
[rows]="5"
|
|
177
|
+
[maxlength]="280"
|
|
178
|
+
[hint]="counter()"
|
|
179
|
+
error="Bio must be 20–280 characters"
|
|
180
|
+
required
|
|
181
|
+
/>
|
|
182
|
+
<button type="submit" [disabled]="form.invalid">Save</button>
|
|
183
|
+
</form>
|
|
184
|
+
`,
|
|
185
|
+
})
|
|
186
|
+
export class CounterExample {
|
|
187
|
+
readonly form = new FormGroup({
|
|
188
|
+
bio: new FormControl<string>('', {
|
|
189
|
+
nonNullable: true,
|
|
190
|
+
validators: [Validators.required, Validators.minLength(20), Validators.maxLength(280)],
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
counter(): string {
|
|
195
|
+
return `${this.form.controls.bio.value.length}/280`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
submit() {
|
|
199
|
+
if (this.form.invalid) {
|
|
200
|
+
this.form.markAllAsTouched();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 4. Disabled and readonly states
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { Component, signal } from '@angular/core';
|
|
211
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
212
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
213
|
+
|
|
214
|
+
@Component({
|
|
215
|
+
standalone: true,
|
|
216
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
217
|
+
template: `
|
|
218
|
+
<form [formGroup]="form">
|
|
219
|
+
<eg-form-textarea
|
|
220
|
+
controlName="notes"
|
|
221
|
+
label="Internal notes"
|
|
222
|
+
[rows]="4"
|
|
223
|
+
[disabled]="locked()"
|
|
224
|
+
hint="Toggle the lock to edit"
|
|
225
|
+
/>
|
|
226
|
+
<eg-form-textarea controlName="audit" label="Audit trail" [rows]="3" [readonly]="true" />
|
|
227
|
+
<button type="button" (click)="locked.update((v) => !v)">Toggle lock</button>
|
|
228
|
+
</form>
|
|
229
|
+
`,
|
|
230
|
+
})
|
|
231
|
+
export class StatesExample {
|
|
232
|
+
readonly form = new FormGroup({
|
|
233
|
+
notes: new FormControl<string>('Called back twice.', { nonNullable: true }),
|
|
234
|
+
audit: new FormControl<string>('Created 2026-09-01 · Updated 2026-09-20', { nonNullable: true }),
|
|
235
|
+
});
|
|
236
|
+
readonly locked = signal(true);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 5. Feedback form composition (input + textarea + select-side hint)
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import { Component } from '@angular/core';
|
|
244
|
+
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
245
|
+
import { EgFormTextInput } from '@egose/shadcn-theme-ng/form-text-input';
|
|
246
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
247
|
+
|
|
248
|
+
@Component({
|
|
249
|
+
standalone: true,
|
|
250
|
+
imports: [ReactiveFormsModule, EgFormTextInput, EgFormTextarea],
|
|
251
|
+
template: `
|
|
252
|
+
<form [formGroup]="form" (ngSubmit)="send()" class="tw:grid tw:gap-4">
|
|
253
|
+
<eg-form-text-input controlName="subject" label="Subject" required />
|
|
254
|
+
<eg-form-textarea
|
|
255
|
+
controlName="message"
|
|
256
|
+
label="Message"
|
|
257
|
+
placeholder="Describe the issue in detail…"
|
|
258
|
+
[rows]="6"
|
|
259
|
+
[maxlength]="2000"
|
|
260
|
+
[hint]="messageHint()"
|
|
261
|
+
error="Message is required (min 20 characters)"
|
|
262
|
+
required
|
|
263
|
+
/>
|
|
264
|
+
<button type="submit">Send feedback</button>
|
|
265
|
+
</form>
|
|
266
|
+
`,
|
|
267
|
+
})
|
|
268
|
+
export class FeedbackExample {
|
|
269
|
+
readonly form = new FormGroup({
|
|
270
|
+
subject: new FormControl<string>('', { nonNullable: true, validators: Validators.required }),
|
|
271
|
+
message: new FormControl<string>('', {
|
|
272
|
+
nonNullable: true,
|
|
273
|
+
validators: [Validators.required, Validators.minLength(20), Validators.maxLength(2000)],
|
|
274
|
+
}),
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
messageHint(): string {
|
|
278
|
+
return `${this.form.controls.message.value.length}/2000 · Markdown supported`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
send() {
|
|
282
|
+
if (this.form.invalid) {
|
|
283
|
+
this.form.markAllAsTouched();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
console.log(this.form.getRawValue());
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### 6. Programmatic control (templates, reset, autosize note)
|
|
292
|
+
|
|
293
|
+
There is no auto-grow behavior — height is fixed by `rows` (plus `textareaClass` resize utilities). Insert canned text and reset programmatically:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import { Component } from '@angular/core';
|
|
297
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
298
|
+
import { EgFormTextarea } from '@egose/shadcn-theme-ng/form-textarea';
|
|
299
|
+
|
|
300
|
+
@Component({
|
|
301
|
+
standalone: true,
|
|
302
|
+
imports: [ReactiveFormsModule, EgFormTextarea],
|
|
303
|
+
template: `
|
|
304
|
+
<form [formGroup]="form">
|
|
305
|
+
<eg-form-textarea
|
|
306
|
+
#descField
|
|
307
|
+
controlName="description"
|
|
308
|
+
label="Description"
|
|
309
|
+
[rows]="6"
|
|
310
|
+
textareaClass="tw:resize-y"
|
|
311
|
+
hint="Tip: allow vertical resize for long drafts"
|
|
312
|
+
/>
|
|
313
|
+
<div class="tw:flex tw:gap-2">
|
|
314
|
+
<button type="button" (click)="insertTemplate()">Insert template</button>
|
|
315
|
+
<button type="button" (click)="form.controls.description.reset()">Clear</button>
|
|
316
|
+
</div>
|
|
317
|
+
<p>Field id: {{ descField.effectiveId() }}</p>
|
|
318
|
+
</form>
|
|
319
|
+
`,
|
|
320
|
+
})
|
|
321
|
+
export class ProgrammaticExample {
|
|
322
|
+
readonly form = new FormGroup({
|
|
323
|
+
description: new FormControl<string>('', { nonNullable: true }),
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
insertTemplate() {
|
|
327
|
+
this.form.controls.description.setValue('## Summary\n\n## Steps to reproduce\n\n1. \n2. \n');
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Accessibility notes
|
|
333
|
+
|
|
334
|
+
- `<label [for]>` targets the textarea id (explicit `controlId`/`id` or generated), so label clicks focus the field.
|
|
335
|
+
- `aria-describedby` points at the error element only when invalid and dirty/touched, otherwise at the hint — pair long hints (formatting tips, counters) with concise `error` strings so screen-reader users hear the failure, not the help text, on error.
|
|
336
|
+
- The textarea reuses `HlmInput` styling (spartan invalid-state hooks included). Use `maxlength` + a counter hint for constrained fields so users get feedback before hitting the native limit.
|
|
337
|
+
- Avoid `autofocus`-style behavior here (the component exposes none) — move focus deliberately in wizards instead.
|
|
338
|
+
|
|
339
|
+
## Theming / CSS variables
|
|
340
|
+
|
|
341
|
+
No component-specific CSS variables; visuals come from the shared theme tokens via the `hlmInput` class hook. Control height with `rows` and `textareaClass` (`tw:min-h-*`, `tw:resize-y` / `tw:resize-none`).
|
|
61
342
|
|
|
62
|
-
##
|
|
343
|
+
## Related subpaths
|
|
63
344
|
|
|
64
|
-
|
|
345
|
+
- `@egose/shadcn-theme-ng/form-text-input` — the single-line sibling.
|
|
346
|
+
- `@egose/shadcn-theme-ng/textarea` — the raw `HlmTextarea` directive for non-form usage.
|
|
347
|
+
- `@egose/shadcn-theme-ng/input` — `HlmInput`, the class hook shared by both.
|
|
348
|
+
- `@egose/shadcn-theme-ng/form-field` — `HlmFormField`, `HlmError`, `HlmHint`, `HlmFormIdGenerator`.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, computed, Component } from '@angular/core';
|
|
2
|
+
import { inject, input, computed, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
|
-
import {
|
|
5
|
-
import { HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
|
|
4
|
+
import { FormGroupDirective, ReactiveFormsModule, ControlContainer } from '@angular/forms';
|
|
5
|
+
import { HlmFormIdGenerator, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
|
|
6
6
|
import { HlmLabel } from '@egose/shadcn-theme-ng-tw/label';
|
|
7
7
|
import { HlmInput } from '@egose/shadcn-theme-ng-tw/input';
|
|
8
8
|
import { hlm } from '@egose/shadcn-theme-ng-tw/utils';
|
|
9
9
|
|
|
10
|
-
let nextId = 0;
|
|
11
10
|
class EgFormTextarea {
|
|
11
|
+
formGroupDirective = inject(FormGroupDirective);
|
|
12
|
+
generatedId = inject(HlmFormIdGenerator).generate('eg-form-textarea');
|
|
12
13
|
// General props
|
|
13
14
|
label = input(undefined, /* @ts-ignore */
|
|
14
15
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
@@ -21,9 +22,8 @@ class EgFormTextarea {
|
|
|
21
22
|
hint = input(undefined, /* @ts-ignore */
|
|
22
23
|
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
23
24
|
// HTML/textarea attributes
|
|
24
|
-
id = input(
|
|
25
|
+
id = input(undefined, /* @ts-ignore */
|
|
25
26
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
26
|
-
// id = input<string>(`eg-form-text-input-${nextId++}`);
|
|
27
27
|
name = input(undefined, /* @ts-ignore */
|
|
28
28
|
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
29
29
|
placeholder = input('', /* @ts-ignore */
|
|
@@ -42,6 +42,23 @@ class EgFormTextarea {
|
|
|
42
42
|
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
43
43
|
cols = input(undefined, /* @ts-ignore */
|
|
44
44
|
...(ngDevMode ? [{ debugName: "cols" }] : /* istanbul ignore next */ []));
|
|
45
|
+
effectiveId = computed(() => this.controlId() || this.id() || this.generatedId, /* @ts-ignore */
|
|
46
|
+
...(ngDevMode ? [{ debugName: "effectiveId" }] : /* istanbul ignore next */ []));
|
|
47
|
+
errorId = computed(() => `${this.effectiveId()}-error`, /* @ts-ignore */
|
|
48
|
+
...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
|
|
49
|
+
hintId = computed(() => `${this.effectiveId()}-hint`, /* @ts-ignore */
|
|
50
|
+
...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
|
|
51
|
+
describedBy() {
|
|
52
|
+
const control = this.formGroupDirective.form.get(this.controlName());
|
|
53
|
+
return this.error() && control?.invalid && (control.dirty || control.touched)
|
|
54
|
+
? this.errorId()
|
|
55
|
+
: this.hint()
|
|
56
|
+
? this.hintId()
|
|
57
|
+
: null;
|
|
58
|
+
}
|
|
59
|
+
effectiveDisabled() {
|
|
60
|
+
return this.disabled() || !!this.formGroupDirective.form.get(this.controlName())?.disabled;
|
|
61
|
+
}
|
|
45
62
|
// Styling classes
|
|
46
63
|
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
47
64
|
labelClass = input('', /* @ts-ignore */
|
|
@@ -63,10 +80,9 @@ class EgFormTextarea {
|
|
|
63
80
|
...(ngDevMode ? [{ debugName: "$errorClass" }] : /* istanbul ignore next */ []));
|
|
64
81
|
$hintClass = computed(() => hlm('tw:mt-0', this.hintClass()), /* @ts-ignore */
|
|
65
82
|
...(ngDevMode ? [{ debugName: "$hintClass" }] : /* istanbul ignore next */ []));
|
|
66
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
67
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
83
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormTextarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
84
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormTextarea, isStandalone: true, selector: "eg-form-textarea", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, minlength: { classPropertyName: "minlength", publicName: "minlength", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, labelClass: { classPropertyName: "labelClass", publicName: "labelClass", isSignal: true, isRequired: false, transformFunction: null }, textareaClass: { classPropertyName: "textareaClass", publicName: "textareaClass", isSignal: true, isRequired: false, transformFunction: null }, errorClass: { classPropertyName: "errorClass", publicName: "errorClass", isSignal: true, isRequired: false, transformFunction: null }, hintClass: { classPropertyName: "hintClass", publicName: "hintClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tw:w-full" }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], ngImport: i0, template: `
|
|
68
85
|
@let lbl = label();
|
|
69
|
-
@let cid = controlId();
|
|
70
86
|
@let cnm = controlName();
|
|
71
87
|
@let err = error();
|
|
72
88
|
@let hnt = hint();
|
|
@@ -74,23 +90,25 @@ class EgFormTextarea {
|
|
|
74
90
|
|
|
75
91
|
<hlm-form-field>
|
|
76
92
|
@if (lbl) {
|
|
77
|
-
<
|
|
93
|
+
<label hlmLabel [for]="effectiveId()" [class]="$labelClass()"
|
|
78
94
|
>{{ lbl }}
|
|
79
95
|
@if (rqrd) {
|
|
80
96
|
<span class="tw:text-red-500">*</span>
|
|
81
97
|
}
|
|
82
|
-
</
|
|
98
|
+
</label>
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
<textarea
|
|
86
102
|
hlmInput
|
|
87
103
|
[attr.aria-label]="lbl"
|
|
88
|
-
[id]="
|
|
104
|
+
[id]="effectiveId()"
|
|
89
105
|
[name]="cnm || name()"
|
|
90
106
|
[formControlName]="cnm"
|
|
91
107
|
[class]="$textareaClass()"
|
|
92
108
|
[placeholder]="placeholder()"
|
|
93
109
|
[readonly]="readonly()"
|
|
110
|
+
[attr.disabled]="effectiveDisabled() ? '' : null"
|
|
111
|
+
[ariaDescribedby]="describedBy()"
|
|
94
112
|
[maxlength]="maxlength()"
|
|
95
113
|
[minlength]="minlength()"
|
|
96
114
|
[required]="rqrd"
|
|
@@ -99,20 +117,20 @@ class EgFormTextarea {
|
|
|
99
117
|
></textarea>
|
|
100
118
|
|
|
101
119
|
@if (err) {
|
|
102
|
-
<hlm-error [class]="$errorClass()">
|
|
120
|
+
<hlm-error [id]="errorId()" [class]="$errorClass()">
|
|
103
121
|
{{ err }}
|
|
104
122
|
</hlm-error>
|
|
105
123
|
}
|
|
106
124
|
|
|
107
125
|
@if (hnt) {
|
|
108
|
-
<hlm-hint [class]="$hintClass()">
|
|
126
|
+
<hlm-hint [id]="hintId()" [class]="$hintClass()">
|
|
109
127
|
{{ hnt }}
|
|
110
128
|
</hlm-hint>
|
|
111
129
|
}
|
|
112
130
|
</hlm-form-field>
|
|
113
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HlmFormField, selector: "hlm-form-field", inputs: ["class"] }, { kind: "directive", type: HlmError, selector: "hlm-error", inputs: ["class"] }, { kind: "directive", type: HlmHint, selector: "hlm-hint", inputs: ["class"] }, { kind: "directive", type: HlmLabel, selector: "[hlmLabel]", inputs: ["class"] }, { kind: "directive", type: HlmInput, selector: "[hlmInput]" }] });
|
|
131
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HlmFormField, selector: "hlm-form-field", inputs: ["class"] }, { kind: "directive", type: HlmError, selector: "hlm-error", inputs: ["class"] }, { kind: "directive", type: HlmHint, selector: "hlm-hint", inputs: ["class"] }, { kind: "directive", type: HlmLabel, selector: "[hlmLabel]", inputs: ["class"] }, { kind: "directive", type: HlmInput, selector: "[hlmInput]", inputs: ["ariaDescribedby"] }] });
|
|
114
132
|
}
|
|
115
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormTextarea, decorators: [{
|
|
116
134
|
type: Component,
|
|
117
135
|
args: [{
|
|
118
136
|
selector: 'eg-form-textarea',
|
|
@@ -124,7 +142,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
124
142
|
providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
|
|
125
143
|
template: `
|
|
126
144
|
@let lbl = label();
|
|
127
|
-
@let cid = controlId();
|
|
128
145
|
@let cnm = controlName();
|
|
129
146
|
@let err = error();
|
|
130
147
|
@let hnt = hint();
|
|
@@ -132,23 +149,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
132
149
|
|
|
133
150
|
<hlm-form-field>
|
|
134
151
|
@if (lbl) {
|
|
135
|
-
<
|
|
152
|
+
<label hlmLabel [for]="effectiveId()" [class]="$labelClass()"
|
|
136
153
|
>{{ lbl }}
|
|
137
154
|
@if (rqrd) {
|
|
138
155
|
<span class="tw:text-red-500">*</span>
|
|
139
156
|
}
|
|
140
|
-
</
|
|
157
|
+
</label>
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
<textarea
|
|
144
161
|
hlmInput
|
|
145
162
|
[attr.aria-label]="lbl"
|
|
146
|
-
[id]="
|
|
163
|
+
[id]="effectiveId()"
|
|
147
164
|
[name]="cnm || name()"
|
|
148
165
|
[formControlName]="cnm"
|
|
149
166
|
[class]="$textareaClass()"
|
|
150
167
|
[placeholder]="placeholder()"
|
|
151
168
|
[readonly]="readonly()"
|
|
169
|
+
[attr.disabled]="effectiveDisabled() ? '' : null"
|
|
170
|
+
[ariaDescribedby]="describedBy()"
|
|
152
171
|
[maxlength]="maxlength()"
|
|
153
172
|
[minlength]="minlength()"
|
|
154
173
|
[required]="rqrd"
|
|
@@ -157,13 +176,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
157
176
|
></textarea>
|
|
158
177
|
|
|
159
178
|
@if (err) {
|
|
160
|
-
<hlm-error [class]="$errorClass()">
|
|
179
|
+
<hlm-error [id]="errorId()" [class]="$errorClass()">
|
|
161
180
|
{{ err }}
|
|
162
181
|
</hlm-error>
|
|
163
182
|
}
|
|
164
183
|
|
|
165
184
|
@if (hnt) {
|
|
166
|
-
<hlm-hint [class]="$hintClass()">
|
|
185
|
+
<hlm-hint [id]="hintId()" [class]="$hintClass()">
|
|
167
186
|
{{ hnt }}
|
|
168
187
|
</hlm-hint>
|
|
169
188
|
}
|
|
@@ -181,4 +200,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
181
200
|
*/
|
|
182
201
|
|
|
183
202
|
export { EgFormTextarea };
|
|
184
|
-
|
|
203
|
+
|
|
@@ -2,12 +2,14 @@ import * as _angular_core from '@angular/core';
|
|
|
2
2
|
import { ClassValue } from 'clsx';
|
|
3
3
|
|
|
4
4
|
declare class EgFormTextarea {
|
|
5
|
+
private readonly formGroupDirective;
|
|
6
|
+
private readonly generatedId;
|
|
5
7
|
label: _angular_core.InputSignal<string | undefined>;
|
|
6
8
|
controlId: _angular_core.InputSignal<string | undefined>;
|
|
7
9
|
controlName: _angular_core.InputSignal<string>;
|
|
8
10
|
error: _angular_core.InputSignal<string | undefined>;
|
|
9
11
|
hint: _angular_core.InputSignal<string | undefined>;
|
|
10
|
-
id: _angular_core.InputSignal<string>;
|
|
12
|
+
id: _angular_core.InputSignal<string | undefined>;
|
|
11
13
|
name: _angular_core.InputSignal<string | undefined>;
|
|
12
14
|
placeholder: _angular_core.InputSignal<string>;
|
|
13
15
|
readonly: _angular_core.InputSignal<boolean>;
|
|
@@ -17,6 +19,11 @@ declare class EgFormTextarea {
|
|
|
17
19
|
required: _angular_core.InputSignal<boolean>;
|
|
18
20
|
rows: _angular_core.InputSignal<string | number | undefined>;
|
|
19
21
|
cols: _angular_core.InputSignal<string | number | undefined>;
|
|
22
|
+
readonly effectiveId: _angular_core.Signal<string>;
|
|
23
|
+
readonly errorId: _angular_core.Signal<string>;
|
|
24
|
+
readonly hintId: _angular_core.Signal<string>;
|
|
25
|
+
describedBy(): string | null;
|
|
26
|
+
effectiveDisabled(): boolean;
|
|
20
27
|
userClass: _angular_core.InputSignal<ClassValue>;
|
|
21
28
|
labelClass: _angular_core.InputSignal<string>;
|
|
22
29
|
textareaClass: _angular_core.InputSignal<string>;
|