@egose/shadcn-theme-ng 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 +27 -39
- package/alert/README.md +343 -34
- package/alert/fesm2022/alert.mjs +47 -47
- package/alert-dialog/README.md +471 -5
- package/alert-dialog/fesm2022/alert-dialog.mjs +47 -47
- 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 +53 -71
- package/avatar/README.md +357 -5
- package/avatar/fesm2022/avatar.mjs +32 -32
- package/badge/README.md +289 -34
- package/badge/fesm2022/badge.mjs +57 -57
- package/basic-alert/README.md +324 -34
- package/basic-alert/fesm2022/basic-alert.mjs +6 -18
- package/breadcrumb/README.md +406 -5
- package/breadcrumb/fesm2022/breadcrumb.mjs +33 -39
- package/button/README.md +453 -34
- package/button/fesm2022/button.mjs +147 -219
- 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 +29 -743
- package/card/README.md +331 -5
- package/card/fesm2022/card.mjs +33 -33
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +39 -78
- package/checkbox/README.md +291 -34
- package/checkbox/fesm2022/checkbox.mjs +20 -58
- 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 +91 -224
- package/command/README.md +435 -5
- package/command/fesm2022/command.mjs +49 -109
- package/confirmation-dialog/README.md +272 -34
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +15 -40
- package/confirmation-dialog/types/confirmation-dialog.d.ts +8 -4
- 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 +64 -267
- package/date-picker/types/date-picker.d.ts +7 -3
- package/dialog/README.md +419 -34
- package/dialog/fesm2022/dialog.mjs +45 -71
- package/drawer/README.md +395 -5
- package/drawer/fesm2022/drawer.mjs +44 -54
- package/dropdown-menu/README.md +417 -5
- package/dropdown-menu/fesm2022/dropdown-menu.mjs +82 -70
- package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
- package/empty/README.md +329 -5
- package/empty/fesm2022/empty.mjs +30 -30
- package/field/README.md +385 -5
- package/field/fesm2022/field.mjs +56 -72
- package/form-checkbox/README.md +283 -34
- package/form-checkbox/fesm2022/form-checkbox.mjs +25 -85
- 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 +31 -84
- 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 +33 -19
- 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 +31 -91
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +7 -1
- package/form-select/README.md +321 -34
- package/form-select/fesm2022/form-select.mjs +32 -149
- 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 +35 -149
- 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 +34 -109
- 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 +34 -34
- package/input-otp/README.md +375 -5
- package/input-otp/fesm2022/input-otp.mjs +26 -26
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +53 -53
- package/kbd/README.md +291 -5
- package/kbd/fesm2022/kbd.mjs +12 -12
- package/label/README.md +243 -34
- package/label/fesm2022/label.mjs +10 -10
- package/label/types/label.d.ts +1 -1
- package/layout-simple/README.md +174 -44
- package/layout-simple/fesm2022/layout-simple.mjs +508 -603
- package/layout-simple/types/layout-simple.d.ts +179 -128
- package/menu/README.md +418 -0
- package/menu/fesm2022/menu.mjs +455 -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 +35 -47
- package/package.json +183 -154
- package/pagination/README.md +388 -5
- package/pagination/fesm2022/pagination.mjs +45 -331
- 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/radio-group/types/radio-group.d.ts +1 -1
- package/resizable/README.md +269 -5
- package/resizable/fesm2022/resizable.mjs +18 -26
- 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 +28 -117
- package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
- package/select/README.md +408 -34
- package/select/fesm2022/select.mjs +71 -111
- 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 +41 -53
- package/sidebar/README.md +457 -5
- package/sidebar/fesm2022/sidebar.mjs +125 -227
- package/skeleton/README.md +217 -5
- package/skeleton/fesm2022/skeleton.mjs +9 -9
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +10 -80
- package/sonner/README.md +317 -34
- package/sonner/fesm2022/sonner.mjs +13 -13
- package/spinner/README.md +255 -34
- package/spinner/fesm2022/spinner.mjs +11 -11
- package/switch/README.md +281 -34
- package/switch/fesm2022/switch.mjs +13 -15
- package/table/README.md +423 -5
- package/table/fesm2022/table.mjs +41 -41
- package/tabs/README.md +382 -34
- package/tabs/fesm2022/tabs.mjs +35 -111
- package/textarea/README.md +282 -5
- package/textarea/fesm2022/textarea.mjs +9 -9
- package/toggle/README.md +270 -5
- package/toggle/fesm2022/toggle.mjs +13 -13
- 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 +19 -19
- 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
package/tabs/fesm2022/tabs.mjs
CHANGED
|
@@ -14,12 +14,12 @@ class HlmTabs {
|
|
|
14
14
|
tab = input.required(/* @ts-ignore */
|
|
15
15
|
...(ngDevMode ? [{ debugName: "tab" }] : /* istanbul ignore next */ []));
|
|
16
16
|
constructor() {
|
|
17
|
-
classes(() =>
|
|
17
|
+
classes(() => "group/tabs flex gap-2 data-[orientation=horizontal]:flex-col");
|
|
18
18
|
}
|
|
19
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
20
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
19
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabs, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
20
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTabs, isStandalone: true, selector: "[hlmTabs],hlm-tabs", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "data-slot": "tabs" } }, hostDirectives: [{ directive: i1.BrnTabs, inputs: ["orientation", "orientation", "activationMode", "activationMode", "brnTabs", "tab"], outputs: ["tabActivated", "tabActivated"] }], ngImport: i0 });
|
|
21
21
|
}
|
|
22
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
22
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabs, decorators: [{
|
|
23
23
|
type: Directive,
|
|
24
24
|
args: [{
|
|
25
25
|
selector: '[hlmTabs],hlm-tabs',
|
|
@@ -39,12 +39,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
39
39
|
class HlmTabsContent {
|
|
40
40
|
contentFor = input.required({ ...(ngDevMode ? { debugName: "contentFor" } : /* istanbul ignore next */ {}), alias: 'hlmTabsContent' });
|
|
41
41
|
constructor() {
|
|
42
|
-
classes(() =>
|
|
42
|
+
classes(() => "flex-1 text-sm outline-none");
|
|
43
43
|
}
|
|
44
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
45
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
44
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
45
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTabsContent, isStandalone: true, selector: "[hlmTabsContent]", inputs: { contentFor: { classPropertyName: "contentFor", publicName: "hlmTabsContent", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "data-slot": "tabs-content" } }, hostDirectives: [{ directive: i1.BrnTabsContent, inputs: ["brnTabsContent", "hlmTabsContent"] }], ngImport: i0 });
|
|
46
46
|
}
|
|
47
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
47
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsContent, decorators: [{
|
|
48
48
|
type: Directive,
|
|
49
49
|
args: [{
|
|
50
50
|
selector: '[hlmTabsContent]',
|
|
@@ -56,10 +56,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
56
56
|
}], ctorParameters: () => [], propDecorators: { contentFor: [{ type: i0.Input, args: [{ isSignal: true, alias: "hlmTabsContent", required: true }] }] } });
|
|
57
57
|
|
|
58
58
|
class HlmTabsContentLazy {
|
|
59
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
60
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
59
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsContentLazy, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
60
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmTabsContentLazy, isStandalone: true, selector: "ng-template[hlmTabsContentLazy]", hostDirectives: [{ directive: i1.BrnTabsContentLazy }], ngImport: i0 });
|
|
61
61
|
}
|
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
62
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsContentLazy, decorators: [{
|
|
63
63
|
type: Directive,
|
|
64
64
|
args: [{
|
|
65
65
|
selector: 'ng-template[hlmTabsContentLazy]',
|
|
@@ -67,11 +67,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
67
67
|
}]
|
|
68
68
|
}] });
|
|
69
69
|
|
|
70
|
-
const listVariants = cva(
|
|
70
|
+
const listVariants = cva("rounded-lg p-[3px] group-data-horizontal/tabs:h-9 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col", {
|
|
71
71
|
variants: {
|
|
72
72
|
variant: {
|
|
73
|
-
default:
|
|
74
|
-
line:
|
|
73
|
+
default: "bg-muted",
|
|
74
|
+
line: "gap-1 bg-transparent",
|
|
75
75
|
},
|
|
76
76
|
},
|
|
77
77
|
defaultVariants: {
|
|
@@ -84,10 +84,10 @@ class HlmTabsList {
|
|
|
84
84
|
constructor() {
|
|
85
85
|
classes(() => listVariants({ variant: this.variant() }));
|
|
86
86
|
}
|
|
87
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
88
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
87
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsList, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
88
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTabsList, isStandalone: true, selector: "[hlmTabsList],hlm-tabs-list", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "tabs-list" }, properties: { "attr.data-variant": "variant()" } }, hostDirectives: [{ directive: i1.BrnTabsList }], ngImport: i0 });
|
|
89
89
|
}
|
|
90
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
90
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsList, decorators: [{
|
|
91
91
|
type: Directive,
|
|
92
92
|
args: [{
|
|
93
93
|
selector: '[hlmTabsList],hlm-tabs-list',
|
|
@@ -102,7 +102,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
102
102
|
class HlmTabsPaginatedList extends BrnTabsPaginatedList {
|
|
103
103
|
constructor() {
|
|
104
104
|
super();
|
|
105
|
-
classes(() =>
|
|
105
|
+
classes(() => "relative flex flex-shrink-0 items-center gap-1 overflow-hidden");
|
|
106
106
|
}
|
|
107
107
|
items = contentChildren(BrnTabsTrigger, { ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), descendants: false });
|
|
108
108
|
/** Explicitly annotating type to avoid non-portable inferred type */
|
|
@@ -122,53 +122,15 @@ class HlmTabsPaginatedList extends BrnTabsPaginatedList {
|
|
|
122
122
|
...(ngDevMode ? [{ debugName: "_tabListClass" }] : /* istanbul ignore next */ []));
|
|
123
123
|
paginationButtonClass = input('', /* @ts-ignore */
|
|
124
124
|
...(ngDevMode ? [{ debugName: "paginationButtonClass" }] : /* istanbul ignore next */ []));
|
|
125
|
-
_paginationButtonClass = computed(() => hlm(
|
|
125
|
+
_paginationButtonClass = computed(() => hlm("relative z-[2] select-none disabled:cursor-default", buttonVariants({ variant: 'ghost', size: 'icon-sm' }), this.paginationButtonClass(), this.showPaginationControls() ? "inline-flex" : "hidden"), /* @ts-ignore */
|
|
126
126
|
...(ngDevMode ? [{ debugName: "_paginationButtonClass" }] : /* istanbul ignore next */ []));
|
|
127
127
|
_itemSelected(event) {
|
|
128
128
|
event.preventDefault();
|
|
129
129
|
}
|
|
130
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
131
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.
|
|
132
|
-
<button
|
|
133
|
-
#previousPaginator
|
|
134
|
-
data-pagination="previous"
|
|
135
|
-
type="button"
|
|
136
|
-
aria-hidden="true"
|
|
137
|
-
tabindex="-1"
|
|
138
|
-
[class]="_paginationButtonClass()"
|
|
139
|
-
[disabled]="disableScrollBefore || null"
|
|
140
|
-
(click)="_handlePaginatorClick('before')"
|
|
141
|
-
(mousedown)="_handlePaginatorPress('before', $event)"
|
|
142
|
-
(touchend)="_stopInterval()"
|
|
143
|
-
>
|
|
144
|
-
<ng-icon name="lucideChevronLeft" />
|
|
145
|
-
</button>
|
|
146
|
-
|
|
147
|
-
<div #tabListContainer class="z-[1] flex grow overflow-hidden" (keydown)="_handleKeydown($event)">
|
|
148
|
-
<div class="relative grow transition-transform" #tabList role="tablist" (cdkObserveContent)="_onContentChanges()">
|
|
149
|
-
<div #tabListInner [class]="_tabListClass()">
|
|
150
|
-
<ng-content />
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
|
|
155
|
-
<button
|
|
156
|
-
#nextPaginator
|
|
157
|
-
data-pagination="next"
|
|
158
|
-
type="button"
|
|
159
|
-
aria-hidden="true"
|
|
160
|
-
tabindex="-1"
|
|
161
|
-
[class]="_paginationButtonClass()"
|
|
162
|
-
[disabled]="disableScrollAfter || null"
|
|
163
|
-
(click)="_handlePaginatorClick('after')"
|
|
164
|
-
(mousedown)="_handlePaginatorPress('after', $event)"
|
|
165
|
-
(touchend)="_stopInterval()"
|
|
166
|
-
>
|
|
167
|
-
<ng-icon name="lucideChevronRight" />
|
|
168
|
-
</button>
|
|
169
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: CdkObserveContent, selector: "[cdkObserveContent]", inputs: ["cdkObserveContentDisabled", "debounce"], outputs: ["cdkObserveContent"], exportAs: ["cdkObserveContent"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsPaginatedList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.3", type: HlmTabsPaginatedList, isStandalone: true, selector: "hlm-paginated-tabs-list", inputs: { tabListClass: { classPropertyName: "tabListClass", publicName: "tabListClass", isSignal: true, isRequired: false, transformFunction: null }, paginationButtonClass: { classPropertyName: "paginationButtonClass", publicName: "paginationButtonClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "tabs-paginated-list" } }, providers: [provideIcons({ lucideChevronRight, lucideChevronLeft })], queries: [{ propertyName: "items", predicate: BrnTabsTrigger, isSignal: true }], viewQueries: [{ propertyName: "tabListContainer", first: true, predicate: ["tabListContainer"], descendants: true, isSignal: true }, { propertyName: "tabList", first: true, predicate: ["tabList"], descendants: true, isSignal: true }, { propertyName: "tabListInner", first: true, predicate: ["tabListInner"], descendants: true, isSignal: true }, { propertyName: "nextPaginator", first: true, predicate: ["nextPaginator"], descendants: true, isSignal: true }, { propertyName: "previousPaginator", first: true, predicate: ["previousPaginator"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "\n <button\n #previousPaginator\n data-pagination=\"previous\"\n type=\"button\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n [class]=\"_paginationButtonClass()\"\n [disabled]=\"disableScrollBefore || null\"\n (click)=\"_handlePaginatorClick('before')\"\n (mousedown)=\"_handlePaginatorPress('before', $event)\"\n (touchend)=\"_stopInterval()\"\n >\n <ng-icon name=\"lucideChevronLeft\" />\n </button>\n\n <div #tabListContainer class=\"z-[1] flex grow overflow-hidden\" (keydown)=\"_handleKeydown($event)\">\n <div\n class=\"relative grow transition-transform\"\n #tabList\n role=\"tablist\"\n (cdkObserveContent)=\"_onContentChanges()\"\n >\n <div #tabListInner [class]=\"_tabListClass()\">\n <ng-content />\n </div>\n </div>\n </div>\n\n <button\n #nextPaginator\n data-pagination=\"next\"\n type=\"button\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n [class]=\"_paginationButtonClass()\"\n [disabled]=\"disableScrollAfter || null\"\n (click)=\"_handlePaginatorClick('after')\"\n (mousedown)=\"_handlePaginatorPress('after', $event)\"\n (touchend)=\"_stopInterval()\"\n >\n <ng-icon name=\"lucideChevronRight\" />\n </button>\n ", isInline: true, dependencies: [{ kind: "directive", type: CdkObserveContent, selector: "[cdkObserveContent]", inputs: ["cdkObserveContentDisabled", "debounce"], outputs: ["cdkObserveContent"], exportAs: ["cdkObserveContent"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
170
132
|
}
|
|
171
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsPaginatedList, decorators: [{
|
|
172
134
|
type: Component,
|
|
173
135
|
args: [{
|
|
174
136
|
selector: 'hlm-paginated-tabs-list',
|
|
@@ -178,45 +140,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
178
140
|
host: {
|
|
179
141
|
'data-slot': 'tabs-paginated-list',
|
|
180
142
|
},
|
|
181
|
-
template:
|
|
182
|
-
<button
|
|
183
|
-
#previousPaginator
|
|
184
|
-
data-pagination="previous"
|
|
185
|
-
type="button"
|
|
186
|
-
aria-hidden="true"
|
|
187
|
-
tabindex="-1"
|
|
188
|
-
[class]="_paginationButtonClass()"
|
|
189
|
-
[disabled]="disableScrollBefore || null"
|
|
190
|
-
(click)="_handlePaginatorClick('before')"
|
|
191
|
-
(mousedown)="_handlePaginatorPress('before', $event)"
|
|
192
|
-
(touchend)="_stopInterval()"
|
|
193
|
-
>
|
|
194
|
-
<ng-icon name="lucideChevronLeft" />
|
|
195
|
-
</button>
|
|
196
|
-
|
|
197
|
-
<div #tabListContainer class="z-[1] flex grow overflow-hidden" (keydown)="_handleKeydown($event)">
|
|
198
|
-
<div class="relative grow transition-transform" #tabList role="tablist" (cdkObserveContent)="_onContentChanges()">
|
|
199
|
-
<div #tabListInner [class]="_tabListClass()">
|
|
200
|
-
<ng-content />
|
|
201
|
-
</div>
|
|
202
|
-
</div>
|
|
203
|
-
</div>
|
|
204
|
-
|
|
205
|
-
<button
|
|
206
|
-
#nextPaginator
|
|
207
|
-
data-pagination="next"
|
|
208
|
-
type="button"
|
|
209
|
-
aria-hidden="true"
|
|
210
|
-
tabindex="-1"
|
|
211
|
-
[class]="_paginationButtonClass()"
|
|
212
|
-
[disabled]="disableScrollAfter || null"
|
|
213
|
-
(click)="_handlePaginatorClick('after')"
|
|
214
|
-
(mousedown)="_handlePaginatorPress('after', $event)"
|
|
215
|
-
(touchend)="_stopInterval()"
|
|
216
|
-
>
|
|
217
|
-
<ng-icon name="lucideChevronRight" />
|
|
218
|
-
</button>
|
|
219
|
-
`,
|
|
143
|
+
template: "\n <button\n #previousPaginator\n data-pagination=\"previous\"\n type=\"button\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n [class]=\"_paginationButtonClass()\"\n [disabled]=\"disableScrollBefore || null\"\n (click)=\"_handlePaginatorClick('before')\"\n (mousedown)=\"_handlePaginatorPress('before', $event)\"\n (touchend)=\"_stopInterval()\"\n >\n <ng-icon name=\"lucideChevronLeft\" />\n </button>\n\n <div #tabListContainer class=\"z-[1] flex grow overflow-hidden\" (keydown)=\"_handleKeydown($event)\">\n <div\n class=\"relative grow transition-transform\"\n #tabList\n role=\"tablist\"\n (cdkObserveContent)=\"_onContentChanges()\"\n >\n <div #tabListInner [class]=\"_tabListClass()\">\n <ng-content />\n </div>\n </div>\n </div>\n\n <button\n #nextPaginator\n data-pagination=\"next\"\n type=\"button\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n [class]=\"_paginationButtonClass()\"\n [disabled]=\"disableScrollAfter || null\"\n (click)=\"_handlePaginatorClick('after')\"\n (mousedown)=\"_handlePaginatorPress('after', $event)\"\n (touchend)=\"_stopInterval()\"\n >\n <ng-icon name=\"lucideChevronRight\" />\n </button>\n ",
|
|
220
144
|
}]
|
|
221
145
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => BrnTabsTrigger), { ...{ descendants: false }, isSignal: true }] }], tabListContainer: [{ type: i0.ViewChild, args: ['tabListContainer', { isSignal: true }] }], tabList: [{ type: i0.ViewChild, args: ['tabList', { isSignal: true }] }], tabListInner: [{ type: i0.ViewChild, args: ['tabListInner', { isSignal: true }] }], nextPaginator: [{ type: i0.ViewChild, args: ['nextPaginator', { isSignal: true }] }], previousPaginator: [{ type: i0.ViewChild, args: ['previousPaginator', { isSignal: true }] }], tabListClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabListClass", required: false }] }], paginationButtonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationButtonClass", required: false }] }] } });
|
|
222
146
|
|
|
@@ -224,16 +148,16 @@ class HlmTabsTrigger {
|
|
|
224
148
|
triggerFor = input.required({ ...(ngDevMode ? { debugName: "triggerFor" } : /* istanbul ignore next */ {}), alias: 'hlmTabsTrigger' });
|
|
225
149
|
constructor() {
|
|
226
150
|
classes(() => [
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
151
|
+
"gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_ng-icon:not([class*='text-'])]:text-[length:--spacing(4)] focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0",
|
|
152
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
153
|
+
"data-active:bg-background dark:data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 data-active:text-foreground",
|
|
154
|
+
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
231
155
|
]);
|
|
232
156
|
}
|
|
233
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
234
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
157
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
158
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTabsTrigger, isStandalone: true, selector: "[hlmTabsTrigger]", inputs: { triggerFor: { classPropertyName: "triggerFor", publicName: "hlmTabsTrigger", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "data-slot": "tabs-trigger" } }, hostDirectives: [{ directive: i1.BrnTabsTrigger, inputs: ["brnTabsTrigger", "hlmTabsTrigger", "disabled", "disabled"] }], ngImport: i0 });
|
|
235
159
|
}
|
|
236
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsTrigger, decorators: [{
|
|
237
161
|
type: Directive,
|
|
238
162
|
args: [{
|
|
239
163
|
selector: '[hlmTabsTrigger]',
|
|
@@ -256,8 +180,8 @@ const HlmTabsImports = [
|
|
|
256
180
|
HlmTabsPaginatedList,
|
|
257
181
|
];
|
|
258
182
|
class HlmTabsModule {
|
|
259
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
260
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.
|
|
183
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
184
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsModule, imports: [HlmTabs,
|
|
261
185
|
HlmTabsList,
|
|
262
186
|
HlmTabsTrigger,
|
|
263
187
|
HlmTabsContent,
|
|
@@ -268,9 +192,9 @@ class HlmTabsModule {
|
|
|
268
192
|
HlmTabsContent,
|
|
269
193
|
HlmTabsContentLazy,
|
|
270
194
|
HlmTabsPaginatedList] });
|
|
271
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.
|
|
195
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsModule, imports: [HlmTabsPaginatedList] });
|
|
272
196
|
}
|
|
273
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
197
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTabsModule, decorators: [{
|
|
274
198
|
type: NgModule,
|
|
275
199
|
args: [{
|
|
276
200
|
imports: [...HlmTabsImports],
|
|
@@ -283,4 +207,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
283
207
|
*/
|
|
284
208
|
|
|
285
209
|
export { HlmTabs, HlmTabsContent, HlmTabsContentLazy, HlmTabsImports, HlmTabsList, HlmTabsModule, HlmTabsPaginatedList, HlmTabsTrigger, listVariants };
|
|
286
|
-
|
|
210
|
+
|
package/textarea/README.md
CHANGED
|
@@ -1,11 +1,288 @@
|
|
|
1
|
-
# Textarea
|
|
1
|
+
# Textarea (`@egose/shadcn-theme-ng/textarea`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A multi-line text input, equivalent to [shadcn/ui Textarea](https://ui.shadcn.com/docs/components/textarea). This subpath ships a single thin styling directive, `HlmTextarea` (`[hlmTextarea]`), over spartan-ng's `BrnTextarea` primitive (plus `BrnFieldControlDescribedBy` for form-field hint/error wiring). All behavior — value binding, validation, auto-sizing — comes from the Brn primitive and Angular forms; this package only applies shadcn styling (border, focus ring, invalid state, placeholder color).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/textarea` and `@egose/shadcn-theme-ng-tw/textarea` (the `tw:`-prefixed Tailwind variant). See the [package README](../../README.md) for install steps, peer dependencies, Tailwind setup, and testing/release guidance. 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
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`@spartan-ng/brain` arrives transitively; `FormsModule`/`ReactiveFormsModule` come from your app when you need form bindings. See the [package README](../../README.md) for the full peer-dependency table.
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
All public symbols are re-exported from `projects/textarea/src/public-api.ts`:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { HlmTextarea, HlmTextareaImports, HlmTextareaModule } from '@egose/shadcn-theme-ng/textarea';
|
|
25
|
+
// tw variant:
|
|
26
|
+
// import { HlmTextarea, HlmTextareaImports, HlmTextareaModule } from '@egose/shadcn-theme-ng-tw/textarea';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Standalone-component usage (preferred):
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { Component } from '@angular/core';
|
|
33
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
34
|
+
|
|
35
|
+
@Component({
|
|
36
|
+
selector: 'app-demo',
|
|
37
|
+
standalone: true,
|
|
38
|
+
imports: [...HlmTextareaImports],
|
|
39
|
+
template: `<textarea hlmTextarea placeholder="Type here…"></textarea>`,
|
|
40
|
+
})
|
|
41
|
+
export class DemoComponent {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
NgModule usage:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { NgModule } from '@angular/core';
|
|
48
|
+
import { HlmTextareaModule } from '@egose/shadcn-theme-ng/textarea';
|
|
49
|
+
|
|
50
|
+
@NgModule({ imports: [HlmTextareaModule] })
|
|
51
|
+
export class FeatureModule {}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| Symbol | Kind | Description |
|
|
55
|
+
| -------------------- | ------------- | ---------------------------------------------------- |
|
|
56
|
+
| `HlmTextarea` | Directive | `[hlmTextarea]` — shadcn styling over `BrnTextarea`. |
|
|
57
|
+
| `HlmTextareaImports` | `const` array | `[HlmTextarea]` — spread into `imports: [...]`. |
|
|
58
|
+
| `HlmTextareaModule` | NgModule | Imports + re-exports `HlmTextarea`. |
|
|
59
|
+
|
|
60
|
+
## Anatomy / Structure
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<!-- basic -->
|
|
64
|
+
<textarea hlmTextarea placeholder="Tell us about yourself…"></textarea>
|
|
65
|
+
|
|
66
|
+
<!-- with label + hint -->
|
|
67
|
+
<div class="space-y-2">
|
|
68
|
+
<label hlmLabel for="bio">Bio</label>
|
|
69
|
+
<textarea hlmTextarea id="bio" rows="4" placeholder="Short bio…"></textarea>
|
|
70
|
+
<p class="text-sm text-muted-foreground">Up to 500 characters.</p>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<!-- reactive form -->
|
|
74
|
+
<textarea hlmTextarea formControlName="notes" rows="5"></textarea>
|
|
75
|
+
|
|
76
|
+
<!-- forced invalid state -->
|
|
77
|
+
<textarea hlmTextarea [forceInvalid]="true"></textarea>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API reference
|
|
81
|
+
|
|
82
|
+
### `HlmTextarea` — selector `[hlmTextarea]` (directive, hosts `BrnTextarea` + `BrnFieldControlDescribedBy`)
|
|
83
|
+
|
|
84
|
+
The directive declares **no own inputs/outputs**. All behavior comes from host directives:
|
|
85
|
+
|
|
86
|
+
| Input | Source | Description |
|
|
87
|
+
| -------------- | ---------------------------- | ---------------------------------------------------------------------------------------- |
|
|
88
|
+
| `id` | `BrnTextarea` | Element id (pairs with `<label for>` and form-field wiring). |
|
|
89
|
+
| `forceInvalid` | `BrnTextarea` | Force the `data-[matches-spartan-invalid=true]` invalid styles even without form errors. |
|
|
90
|
+
| (described-by) | `BrnFieldControlDescribedBy` | Auto-wires `aria-describedby` to enclosing form-field hint/error. |
|
|
91
|
+
|
|
92
|
+
Standard native attributes (`rows`, `placeholder`, `disabled`, `readonly`, `maxlength`, `name`, …) and Angular form bindings (`formControl`, `formControlName`, `ngModel`) work as usual through the underlying `<textarea>`.
|
|
93
|
+
|
|
94
|
+
Host: `data-slot="textarea"`. Invalid styling keys off `data-[matches-spartan-invalid=true]` (`border-destructive`, `ring-destructive`). Disabled state renders `cursor-not-allowed` + `opacity-50`. User `class` is preserved and merged via `classes()`.
|
|
95
|
+
|
|
96
|
+
## Examples
|
|
97
|
+
|
|
98
|
+
### 1. Basic usage with label
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
// demo-basic.component.ts
|
|
102
|
+
import { Component } from '@angular/core';
|
|
103
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
104
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
105
|
+
|
|
106
|
+
@Component({
|
|
107
|
+
selector: 'demo-basic',
|
|
108
|
+
standalone: true,
|
|
109
|
+
imports: [...HlmTextareaImports, HlmLabel],
|
|
110
|
+
template: `
|
|
111
|
+
<div class="space-y-2">
|
|
112
|
+
<label hlmLabel for="bio">Bio</label>
|
|
113
|
+
<textarea hlmTextarea id="bio" rows="4" placeholder="Tell us about yourself…"></textarea>
|
|
114
|
+
</div>
|
|
115
|
+
`,
|
|
116
|
+
})
|
|
117
|
+
export class DemoBasic {}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 2. Reactive form with validation + character count
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// demo-reactive.component.ts
|
|
124
|
+
import { Component } from '@angular/core';
|
|
125
|
+
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
126
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
127
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
128
|
+
|
|
129
|
+
@Component({
|
|
130
|
+
selector: 'demo-reactive',
|
|
131
|
+
standalone: true,
|
|
132
|
+
imports: [...HlmTextareaImports, ReactiveFormsModule, HlmLabel],
|
|
133
|
+
template: `
|
|
134
|
+
<form [formGroup]="form" class="space-y-2">
|
|
135
|
+
<label hlmLabel for="feedback">Feedback</label>
|
|
136
|
+
<textarea
|
|
137
|
+
hlmTextarea
|
|
138
|
+
id="feedback"
|
|
139
|
+
rows="5"
|
|
140
|
+
maxlength="500"
|
|
141
|
+
placeholder="What did you think?"
|
|
142
|
+
formControlName="feedback"
|
|
143
|
+
></textarea>
|
|
144
|
+
<div class="flex justify-between text-sm">
|
|
145
|
+
<span class="text-destructive">
|
|
146
|
+
@if (form.controls.feedback.hasError('required') && form.controls.feedback.touched) {
|
|
147
|
+
Feedback is required.
|
|
148
|
+
} @else if (form.controls.feedback.hasError('minlength')) {
|
|
149
|
+
At least 10 characters.
|
|
150
|
+
}
|
|
151
|
+
</span>
|
|
152
|
+
<span class="text-muted-foreground">{{ form.controls.feedback.value?.length ?? 0 }}/500</span>
|
|
153
|
+
</div>
|
|
154
|
+
</form>
|
|
155
|
+
`,
|
|
156
|
+
})
|
|
157
|
+
export class DemoReactive {
|
|
158
|
+
readonly form = new FormGroup({
|
|
159
|
+
feedback: new FormControl('', [Validators.required, Validators.minLength(10)]),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3. Template-driven form (`ngModel`)
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// demo-template.component.ts
|
|
168
|
+
import { Component } from '@angular/core';
|
|
169
|
+
import { FormsModule } from '@angular/forms';
|
|
170
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
171
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
172
|
+
|
|
173
|
+
@Component({
|
|
174
|
+
selector: 'demo-template',
|
|
175
|
+
standalone: true,
|
|
176
|
+
imports: [...HlmTextareaImports, FormsModule, HlmLabel],
|
|
177
|
+
template: `
|
|
178
|
+
<div class="space-y-2">
|
|
179
|
+
<label hlmLabel for="notes">Notes</label>
|
|
180
|
+
<textarea hlmTextarea id="notes" name="notes" rows="3" [(ngModel)]="notes"></textarea>
|
|
181
|
+
<p class="text-sm text-muted-foreground">Preview: {{ notes || '—' }}</p>
|
|
182
|
+
</div>
|
|
183
|
+
`,
|
|
184
|
+
})
|
|
185
|
+
export class DemoTemplate {
|
|
186
|
+
notes = '';
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 4. Disabled / readonly / error states
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
// demo-states.component.ts
|
|
194
|
+
import { Component } from '@angular/core';
|
|
195
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
196
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
197
|
+
|
|
198
|
+
@Component({
|
|
199
|
+
selector: 'demo-states',
|
|
200
|
+
standalone: true,
|
|
201
|
+
imports: [...HlmTextareaImports, HlmLabel],
|
|
202
|
+
template: `
|
|
203
|
+
<div class="space-y-4">
|
|
204
|
+
<div class="space-y-2">
|
|
205
|
+
<label hlmLabel for="t-disabled">Disabled</label>
|
|
206
|
+
<textarea hlmTextarea id="t-disabled" disabled placeholder="Cannot edit…"></textarea>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="space-y-2">
|
|
209
|
+
<label hlmLabel for="t-readonly">Readonly</label>
|
|
210
|
+
<textarea hlmTextarea id="t-readonly" readonly rows="2">Submitted value, read only.</textarea>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="space-y-2">
|
|
213
|
+
<label hlmLabel for="t-invalid">Forced invalid</label>
|
|
214
|
+
<textarea hlmTextarea id="t-invalid" [forceInvalid]="true" rows="2">Fails custom rule.</textarea>
|
|
215
|
+
<p class="text-sm text-destructive">Custom server error goes here.</p>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
`,
|
|
219
|
+
})
|
|
220
|
+
export class DemoStates {}
|
|
11
221
|
```
|
|
222
|
+
|
|
223
|
+
### 5. Inside a form-field (hint + error wiring)
|
|
224
|
+
|
|
225
|
+
`BrnFieldControlDescribedBy` auto-links the textarea to the surrounding field's hint/error for screen readers:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
// demo-field.component.ts
|
|
229
|
+
import { Component } from '@angular/core';
|
|
230
|
+
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
231
|
+
import { HlmTextareaImports } from '@egose/shadcn-theme-ng/textarea';
|
|
232
|
+
import { HlmFormFieldImports } from '@egose/shadcn-theme-ng/form-field';
|
|
233
|
+
|
|
234
|
+
@Component({
|
|
235
|
+
selector: 'demo-field',
|
|
236
|
+
standalone: true,
|
|
237
|
+
imports: [...HlmTextareaImports, ...HlmFormFieldImports, ReactiveFormsModule],
|
|
238
|
+
template: `
|
|
239
|
+
<form [formGroup]="form">
|
|
240
|
+
<hlm-form-field>
|
|
241
|
+
<label hlmLabel for="desc">Description</label>
|
|
242
|
+
<textarea hlmTextarea id="desc" formControlName="description" rows="4"></textarea>
|
|
243
|
+
<hlm-hint>Describe the issue in a few sentences.</hlm-hint>
|
|
244
|
+
<hlm-error>Description is required.</hlm-error>
|
|
245
|
+
</hlm-form-field>
|
|
246
|
+
</form>
|
|
247
|
+
`,
|
|
248
|
+
})
|
|
249
|
+
export class DemoField {
|
|
250
|
+
readonly form = new FormGroup({ description: new FormControl('', Validators.required) });
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
(Exact `hlm-form-field`/`hlm-hint`/`hlm-error` selector names come from `@egose/shadcn-theme-ng/form-field` — check that subpath for the current API.)
|
|
255
|
+
|
|
256
|
+
### 6. Autosize / custom sizing
|
|
257
|
+
|
|
258
|
+
The base styles include `field-sizing-content` + `min-h-16`, so the textarea grows with content in supporting browsers. Combine with `rows` and width utilities:
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<!-- fixed 8 rows, full width (default w-full) -->
|
|
262
|
+
<textarea hlmTextarea rows="8" placeholder="Long-form answer…"></textarea>
|
|
263
|
+
|
|
264
|
+
<!-- constrained width + no manual resize -->
|
|
265
|
+
<textarea hlmTextarea rows="4" class="max-w-xl resize-none" placeholder="No drag handle…"></textarea>
|
|
266
|
+
|
|
267
|
+
<!-- tall monospace variant for code -->
|
|
268
|
+
<textarea hlmTextarea rows="10" class="font-mono text-sm" spellcheck="false"></textarea>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Accessibility notes
|
|
272
|
+
|
|
273
|
+
- Every textarea needs a visible `<label>` (matching `for`/`id`) — placeholders are not labels.
|
|
274
|
+
- Wire hint/error text with `aria-describedby` (automatic inside `hlm-form-field` via `BrnFieldControlDescribedBy`; manual `aria-describedby="hint-id"` otherwise).
|
|
275
|
+
- Surface validation errors both visually (`forceInvalid` / form errors → `border-destructive`) and as text adjacent to the field; do not rely on color alone.
|
|
276
|
+
- Keep `maxlength` announcements truthful — show a live character count for constrained fields.
|
|
277
|
+
- Disabled textareas are skipped by assistive tech; use `readonly` when the value must remain perceivable but not editable.
|
|
278
|
+
|
|
279
|
+
## Theming / CSS variables
|
|
280
|
+
|
|
281
|
+
Keys off theme tokens (`border-input`, `bg-input/30` in dark mode, `ring-ring/50`, `text-muted-foreground` placeholder, `border-destructive`/`ring-destructive` invalid). Follows your shadcn theme automatically; extend via `class` (merged through `classes()`).
|
|
282
|
+
|
|
283
|
+
## Related subpaths
|
|
284
|
+
|
|
285
|
+
- `@egose/shadcn-theme-ng/input` — single-line sibling control.
|
|
286
|
+
- `@egose/shadcn-theme-ng/label` — accessible labels.
|
|
287
|
+
- `@egose/shadcn-theme-ng/form-field` / `@egose/shadcn-theme-ng/form-textarea` — labeled field with hint/error wiring.
|
|
288
|
+
- `@egose/shadcn-theme-ng/button` — submit actions for textarea forms.
|
|
@@ -8,12 +8,12 @@ import { classes } from '@egose/shadcn-theme-ng/utils';
|
|
|
8
8
|
|
|
9
9
|
class HlmTextarea {
|
|
10
10
|
constructor() {
|
|
11
|
-
classes(() =>
|
|
11
|
+
classes(() => "border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 data-[matches-spartan-invalid=true]:ring-destructive/20 dark:data-[matches-spartan-invalid=true]:ring-destructive/40 data-[matches-spartan-invalid=true]:border-destructive dark:data-[matches-spartan-invalid=true]:border-destructive/50 rounded-md border bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-3 data-[matches-spartan-invalid=true]:ring-3 md:text-sm placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full outline-none disabled:cursor-not-allowed disabled:opacity-50");
|
|
12
12
|
}
|
|
13
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
14
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
13
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTextarea, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
14
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmTextarea, isStandalone: true, selector: "[hlmTextarea]", host: { attributes: { "data-slot": "textarea" } }, hostDirectives: [{ directive: i1.BrnTextarea, inputs: ["id", "id", "forceInvalid", "forceInvalid"] }, { directive: i2.BrnFieldControlDescribedBy }], ngImport: i0 });
|
|
15
15
|
}
|
|
16
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTextarea, decorators: [{
|
|
17
17
|
type: Directive,
|
|
18
18
|
args: [{
|
|
19
19
|
selector: '[hlmTextarea]',
|
|
@@ -27,11 +27,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
27
27
|
*/
|
|
28
28
|
const HlmTextareaImports = [HlmTextarea];
|
|
29
29
|
class HlmTextareaModule {
|
|
30
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
31
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.
|
|
32
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTextareaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
31
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmTextareaModule, imports: [HlmTextarea], exports: [HlmTextarea] });
|
|
32
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTextareaModule });
|
|
33
33
|
}
|
|
34
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
34
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTextareaModule, decorators: [{
|
|
35
35
|
type: NgModule,
|
|
36
36
|
args: [{
|
|
37
37
|
imports: [...HlmTextareaImports],
|
|
@@ -44,4 +44,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
46
|
export { HlmTextarea, HlmTextareaImports, HlmTextareaModule };
|
|
47
|
-
|
|
47
|
+
|