@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/README.md
CHANGED
|
@@ -1,64 +1,412 @@
|
|
|
1
|
-
# Tabs
|
|
1
|
+
# Tabs (`@egose/shadcn-theme-ng/tabs`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Tabbed navigation, equivalent to [shadcn/ui Tabs](https://ui.shadcn.com/docs/components/tabs). This subpath ships six pieces — `HlmTabs` (root), `HlmTabsList` (tab bar, with `default`/`line` variants), `HlmTabsTrigger` (individual tab), `HlmTabsContent` (panel), `HlmTabsContentLazy` (deferred panel), and `HlmTabsPaginatedList` (scrollable tab bar with chevron paginators) — all thin shadcn-styled directives/components over spartan-ng's `@spartan-ng/brain/tabs` primitives (`BrnTabs`, `BrnTabsList`, `BrnTabsTrigger`, `BrnTabsContent`, `BrnTabsPaginatedList`).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/tabs` and `@egose/shadcn-theme-ng-tw/tabs` (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
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
`@spartan-ng/brain` arrives transitively. See the [package README](../../README.md) for the full peer-dependency table.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
All public symbols are re-exported from `projects/tabs/src/public-api.ts`:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
HlmTabs,
|
|
26
|
+
HlmTabsContent,
|
|
27
|
+
HlmTabsContentLazy,
|
|
28
|
+
HlmTabsImports,
|
|
29
|
+
HlmTabsList,
|
|
30
|
+
HlmTabsModule,
|
|
31
|
+
HlmTabsPaginatedList,
|
|
32
|
+
HlmTabsTrigger,
|
|
33
|
+
} from '@egose/shadcn-theme-ng/tabs';
|
|
34
|
+
// tw variant: swap to '@egose/shadcn-theme-ng-tw/tabs'
|
|
17
35
|
```
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
Standalone-component usage (preferred):
|
|
20
38
|
|
|
21
|
-
|
|
39
|
+
```ts
|
|
40
|
+
import { Component } from '@angular/core';
|
|
41
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
22
42
|
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
@Component({
|
|
44
|
+
selector: 'app-demo',
|
|
45
|
+
standalone: true,
|
|
46
|
+
imports: [...HlmTabsImports],
|
|
47
|
+
template: `<!-- tabs markup here -->`,
|
|
48
|
+
})
|
|
49
|
+
export class DemoComponent {}
|
|
25
50
|
```
|
|
26
51
|
|
|
27
|
-
|
|
52
|
+
NgModule usage:
|
|
28
53
|
|
|
29
|
-
|
|
54
|
+
```ts
|
|
55
|
+
import { NgModule } from '@angular/core';
|
|
56
|
+
import { HlmTabsModule } from '@egose/shadcn-theme-ng/tabs';
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
@NgModule({ imports: [HlmTabsModule] })
|
|
59
|
+
export class FeatureModule {}
|
|
60
|
+
```
|
|
32
61
|
|
|
33
|
-
|
|
62
|
+
| Symbol | Kind | Description |
|
|
63
|
+
| ---------------------- | ------------- | ------------------------------------------------------------------- |
|
|
64
|
+
| `HlmTabs` | Directive | Root: `[hlmTabs], hlm-tabs` — wires `BrnTabs`. |
|
|
65
|
+
| `HlmTabsList` | Directive | Tab bar: `[hlmTabsList], hlm-tabs-list` — `default`/`line` variant. |
|
|
66
|
+
| `HlmTabsTrigger` | Directive | Tab button: `[hlmTabsTrigger]` — value key via `hlmTabsTrigger`. |
|
|
67
|
+
| `HlmTabsContent` | Directive | Panel: `[hlmTabsContent]` — value key via `hlmTabsContent`. |
|
|
68
|
+
| `HlmTabsContentLazy` | Directive | Deferred panel: `ng-template[hlmTabsContentLazy]`. |
|
|
69
|
+
| `HlmTabsPaginatedList` | Component | Scrollable bar: `<hlm-paginated-tabs-list>` with chevron buttons. |
|
|
70
|
+
| `HlmTabsImports` | `const` array | All six, spread into `imports: [...]`. |
|
|
71
|
+
| `HlmTabsModule` | NgModule | Imports + re-exports all six. |
|
|
34
72
|
|
|
35
|
-
|
|
36
|
-
cd dist/tabs
|
|
37
|
-
```
|
|
73
|
+
## Anatomy / Structure
|
|
38
74
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
75
|
+
```html
|
|
76
|
+
<div hlmTabs tab="account">
|
|
77
|
+
<div hlmTabsList>
|
|
78
|
+
<button hlmTabsTrigger="account">Account</button>
|
|
79
|
+
<button hlmTabsTrigger="password">Password</button>
|
|
80
|
+
</div>
|
|
43
81
|
|
|
44
|
-
|
|
82
|
+
<div hlmTabsContent="account">
|
|
83
|
+
<p>Account settings…</p>
|
|
84
|
+
</div>
|
|
85
|
+
<div hlmTabsContent="password">
|
|
86
|
+
<p>Change your password…</p>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
```
|
|
45
90
|
|
|
46
|
-
|
|
91
|
+
Paginated (many tabs, horizontal scroll + chevrons):
|
|
47
92
|
|
|
48
|
-
```
|
|
49
|
-
|
|
93
|
+
```html
|
|
94
|
+
<div hlmTabs tab="tab1">
|
|
95
|
+
<hlm-paginated-tabs-list>
|
|
96
|
+
<button hlmTabsTrigger="tab1">Tab 1</button>
|
|
97
|
+
<button hlmTabsTrigger="tab2">Tab 2</button>
|
|
98
|
+
<!-- …many more… -->
|
|
99
|
+
</hlm-paginated-tabs-list>
|
|
100
|
+
|
|
101
|
+
<div hlmTabsContent="tab1">Panel 1</div>
|
|
102
|
+
<div hlmTabsContent="tab2">Panel 2</div>
|
|
103
|
+
</div>
|
|
50
104
|
```
|
|
51
105
|
|
|
52
|
-
|
|
106
|
+
Lazy panel (content instantiated only when the tab is first activated):
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<div hlmTabs tab="reports">
|
|
110
|
+
<div hlmTabsList>
|
|
111
|
+
<button hlmTabsTrigger="reports">Reports</button>
|
|
112
|
+
</div>
|
|
113
|
+
<ng-template hlmTabsContentLazy>
|
|
114
|
+
<div hlmTabsContent="reports">Heavy report grid…</div>
|
|
115
|
+
</ng-template>
|
|
116
|
+
</div>
|
|
117
|
+
```
|
|
53
118
|
|
|
54
|
-
|
|
119
|
+
> Trigger keys (`hlmTabsTrigger="…"`) must match panel keys (`hlmTabsContent="…"`), and one of them must equal the root `tab` input for an initially active tab.
|
|
55
120
|
|
|
56
|
-
|
|
57
|
-
|
|
121
|
+
## API reference
|
|
122
|
+
|
|
123
|
+
### `HlmTabs` — selector `[hlmTabs], hlm-tabs` (directive, hosts `BrnTabs`)
|
|
124
|
+
|
|
125
|
+
| Input | Type | Default | Description |
|
|
126
|
+
| ---------------- | --------------------------------------- | ------- | ------------------------------------------------------------------ |
|
|
127
|
+
| `tab` | `string` (required) | — | Key of the initially active tab. Must match a trigger/content key. |
|
|
128
|
+
| `orientation` | forwarded to `BrnTabs` | — | `'horizontal' \| 'vertical'`. |
|
|
129
|
+
| `activationMode` | forwarded to `BrnTabs` | — | `'automatic' \| 'manual'`. |
|
|
130
|
+
| `brnTabs` | forwarded to `BrnTabs` (`brnTabs: tab`) | — | Low-level Brn binding for the active tab. Prefer `tab`. |
|
|
131
|
+
|
|
132
|
+
| Output | Description |
|
|
133
|
+
| -------------- | ------------------------------------------------------------ |
|
|
134
|
+
| `tabActivated` | Forwarded from `BrnTabs`. Emits when the active tab changes. |
|
|
135
|
+
|
|
136
|
+
Host: `data-slot="tabs"`, layout `flex gap-2` (column in horizontal orientation).
|
|
137
|
+
|
|
138
|
+
### `HlmTabsList` — selector `[hlmTabsList], hlm-tabs-list` (directive, hosts `BrnTabsList`)
|
|
139
|
+
|
|
140
|
+
| Input | Type | Default | Description |
|
|
141
|
+
| --------- | --------------------- | ----------- | ----------------------------------------------------------------------------- |
|
|
142
|
+
| `variant` | `'default' \| 'line'` | `'default'` | `default`: muted pill bar. `line`: transparent bar with underline indicators. |
|
|
143
|
+
|
|
144
|
+
Also exports `listVariants` (cva) for reuse. Host sets `data-slot="tabs-list"` + `data-variant`.
|
|
145
|
+
|
|
146
|
+
### `HlmTabsTrigger` — selector `[hlmTabsTrigger]` (directive, hosts `BrnTabsTrigger`)
|
|
147
|
+
|
|
148
|
+
| Input | Type | Default | Description |
|
|
149
|
+
| ---------------- | -------------------------------------------- | ------- | ------------------------------------------- |
|
|
150
|
+
| `hlmTabsTrigger` | `string` (required, aliased as `triggerFor`) | — | Tab key. Must match a `hlmTabsContent` key. |
|
|
151
|
+
| `disabled` | forwarded to `BrnTabsTrigger` | — | Disables this tab. |
|
|
152
|
+
|
|
153
|
+
Host: `data-slot="tabs-trigger"`. Only use on `<button>` elements.
|
|
154
|
+
|
|
155
|
+
### `HlmTabsContent` — selector `[hlmTabsContent]` (directive, hosts `BrnTabsContent`)
|
|
156
|
+
|
|
157
|
+
| Input | Type | Default | Description |
|
|
158
|
+
| ---------------- | -------------------------------------------- | ------- | ------------------------------------ |
|
|
159
|
+
| `hlmTabsContent` | `string` (required, aliased as `contentFor`) | — | Panel key. Must match a trigger key. |
|
|
160
|
+
|
|
161
|
+
Host: `data-slot="tabs-content"`, `flex-1 text-sm`.
|
|
162
|
+
|
|
163
|
+
### `HlmTabsContentLazy` — selector `ng-template[hlmTabsContentLazy]` (directive, hosts `BrnTabsContentLazy`)
|
|
164
|
+
|
|
165
|
+
No inputs/outputs. Wrap a `hlmTabsContent` panel in `<ng-template hlmTabsContentLazy>` to defer instantiation until first activation.
|
|
166
|
+
|
|
167
|
+
### `HlmTabsPaginatedList` — selector `hlm-paginated-tabs-list` (component, extends `BrnTabsPaginatedList`)
|
|
168
|
+
|
|
169
|
+
Scrollable tab bar with previous/next chevron paginators (uses `buttonVariants({ variant: 'ghost', size: 'icon-sm' })` internally).
|
|
170
|
+
|
|
171
|
+
| Input | Type | Default | Description |
|
|
172
|
+
| ----------------------- | ------------ | ------- | ----------------------------------------------------------------------------- |
|
|
173
|
+
| `tabListClass` | `ClassValue` | `''` | Extra classes merged onto the inner tab-list element (over `listVariants()`). |
|
|
174
|
+
| `paginationButtonClass` | `ClassValue` | `''` | Extra classes merged onto the chevron paginator buttons. |
|
|
175
|
+
|
|
176
|
+
Content children: `BrnTabsTrigger` items are queried (`contentChildren`) to drive pagination. All other `BrnTabsPaginatedList` behavior (scroll, keyboard) is inherited.
|
|
177
|
+
|
|
178
|
+
## Examples
|
|
179
|
+
|
|
180
|
+
### 1. Basic tabs
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// demo-basic.component.ts
|
|
184
|
+
import { Component } from '@angular/core';
|
|
185
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
186
|
+
|
|
187
|
+
@Component({
|
|
188
|
+
selector: 'demo-basic',
|
|
189
|
+
standalone: true,
|
|
190
|
+
imports: [...HlmTabsImports],
|
|
191
|
+
template: `
|
|
192
|
+
<div hlmTabs tab="account">
|
|
193
|
+
<div hlmTabsList>
|
|
194
|
+
<button hlmTabsTrigger="account">Account</button>
|
|
195
|
+
<button hlmTabsTrigger="password">Password</button>
|
|
196
|
+
</div>
|
|
197
|
+
<div hlmTabsContent="account">
|
|
198
|
+
<p class="text-sm">Make changes to your account here.</p>
|
|
199
|
+
</div>
|
|
200
|
+
<div hlmTabsContent="password">
|
|
201
|
+
<p class="text-sm">Change your password here.</p>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
`,
|
|
205
|
+
})
|
|
206
|
+
export class DemoBasic {}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 2. `line` variant + vertical orientation
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
// demo-variants.component.ts
|
|
213
|
+
import { Component } from '@angular/core';
|
|
214
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
215
|
+
|
|
216
|
+
@Component({
|
|
217
|
+
selector: 'demo-variants',
|
|
218
|
+
standalone: true,
|
|
219
|
+
imports: [...HlmTabsImports],
|
|
220
|
+
template: `
|
|
221
|
+
<div hlmTabs tab="overview" orientation="vertical" class="min-h-48">
|
|
222
|
+
<div hlmTabsList variant="line">
|
|
223
|
+
<button hlmTabsTrigger="overview">Overview</button>
|
|
224
|
+
<button hlmTabsTrigger="analytics">Analytics</button>
|
|
225
|
+
<button hlmTabsTrigger="reports" disabled>Reports (soon)</button>
|
|
226
|
+
</div>
|
|
227
|
+
<div hlmTabsContent="overview">Overview panel.</div>
|
|
228
|
+
<div hlmTabsContent="analytics">Analytics panel.</div>
|
|
229
|
+
<div hlmTabsContent="reports">Reports panel.</div>
|
|
230
|
+
</div>
|
|
231
|
+
`,
|
|
232
|
+
})
|
|
233
|
+
export class DemoVariants {}
|
|
58
234
|
```
|
|
59
235
|
|
|
60
|
-
|
|
236
|
+
### 3. Programmatic control + `tabActivated`
|
|
237
|
+
|
|
238
|
+
Drive the active tab from a signal and react to user changes:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
// demo-controlled.component.ts
|
|
242
|
+
import { Component, signal } from '@angular/core';
|
|
243
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
244
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
245
|
+
|
|
246
|
+
@Component({
|
|
247
|
+
selector: 'demo-controlled',
|
|
248
|
+
standalone: true,
|
|
249
|
+
imports: [...HlmTabsImports, ...HlmButtonImports],
|
|
250
|
+
template: `
|
|
251
|
+
<div hlmTabs [tab]="active()" (tabActivated)="active.set($event)">
|
|
252
|
+
<div hlmTabsList>
|
|
253
|
+
<button hlmTabsTrigger="one">One</button>
|
|
254
|
+
<button hlmTabsTrigger="two">Two</button>
|
|
255
|
+
<button hlmTabsTrigger="three">Three</button>
|
|
256
|
+
</div>
|
|
257
|
+
<div hlmTabsContent="one">Panel one.</div>
|
|
258
|
+
<div hlmTabsContent="two">Panel two.</div>
|
|
259
|
+
<div hlmTabsContent="three">Panel three.</div>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="mt-2 flex gap-2">
|
|
262
|
+
<button hlmBtn size="sm" (click)="active.set('two')">Go to Two</button>
|
|
263
|
+
<button hlmBtn size="sm" variant="outline" (click)="active.set('three')">Go to Three</button>
|
|
264
|
+
</div>
|
|
265
|
+
`,
|
|
266
|
+
})
|
|
267
|
+
export class DemoControlled {
|
|
268
|
+
readonly active = signal('one');
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 4. Forms inside tab panels
|
|
273
|
+
|
|
274
|
+
Each panel is a plain container — put full forms inside:
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
// demo-forms.component.ts
|
|
278
|
+
import { Component } from '@angular/core';
|
|
279
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
280
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
281
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
282
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
283
|
+
|
|
284
|
+
@Component({
|
|
285
|
+
selector: 'demo-forms',
|
|
286
|
+
standalone: true,
|
|
287
|
+
imports: [...HlmTabsImports, ReactiveFormsModule, HlmInput, HlmLabel],
|
|
288
|
+
template: `
|
|
289
|
+
<div hlmTabs tab="profile">
|
|
290
|
+
<div hlmTabsList>
|
|
291
|
+
<button hlmTabsTrigger="profile">Profile</button>
|
|
292
|
+
<button hlmTabsTrigger="security">Security</button>
|
|
293
|
+
</div>
|
|
294
|
+
<form [formGroup]="form">
|
|
295
|
+
<div hlmTabsContent="profile" class="space-y-2">
|
|
296
|
+
<label hlmLabel for="name">Name</label>
|
|
297
|
+
<input hlmInput id="name" formControlName="name" />
|
|
298
|
+
</div>
|
|
299
|
+
<div hlmTabsContent="security" class="space-y-2">
|
|
300
|
+
<label hlmLabel for="pw">New password</label>
|
|
301
|
+
<input hlmInput id="pw" type="password" formControlName="password" />
|
|
302
|
+
</div>
|
|
303
|
+
</form>
|
|
304
|
+
</div>
|
|
305
|
+
`,
|
|
306
|
+
})
|
|
307
|
+
export class DemoForms {
|
|
308
|
+
readonly form = new FormGroup({ name: new FormControl('Ada'), password: new FormControl('') });
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 5. Paginated tab bar (many tabs)
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
// demo-paginated.component.ts
|
|
316
|
+
import { Component } from '@angular/core';
|
|
317
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
318
|
+
|
|
319
|
+
@Component({
|
|
320
|
+
selector: 'demo-paginated',
|
|
321
|
+
standalone: true,
|
|
322
|
+
imports: [...HlmTabsImports],
|
|
323
|
+
template: `
|
|
324
|
+
<div hlmTabs tab="tab1">
|
|
325
|
+
<hlm-paginated-tabs-list tabListClass="max-w-xl">
|
|
326
|
+
@for (t of tabs; track t) {
|
|
327
|
+
<button [hlmTabsTrigger]="t">{{ t }}</button>
|
|
328
|
+
}
|
|
329
|
+
</hlm-paginated-tabs-list>
|
|
330
|
+
@for (t of tabs; track t) {
|
|
331
|
+
<div [hlmTabsContent]="t">Content for {{ t }}</div>
|
|
332
|
+
}
|
|
333
|
+
</div>
|
|
334
|
+
`,
|
|
335
|
+
})
|
|
336
|
+
export class DemoPaginated {
|
|
337
|
+
readonly tabs = Array.from({ length: 20 }, (_, i) => `tab${i + 1}`);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Paginator buttons hide automatically when everything fits (`showPaginationControls()`), and accept `paginationButtonClass` overrides.
|
|
342
|
+
|
|
343
|
+
### 6. Lazy + async panel content
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
// demo-lazy.component.ts
|
|
347
|
+
import { Component, inject, signal } from '@angular/core';
|
|
348
|
+
import { HttpClient } from '@angular/common/http';
|
|
349
|
+
import { HlmTabsImports } from '@egose/shadcn-theme-ng/tabs';
|
|
350
|
+
import { HlmSpinnerImports } from '@egose/shadcn-theme-ng/spinner';
|
|
351
|
+
|
|
352
|
+
@Component({
|
|
353
|
+
selector: 'demo-lazy',
|
|
354
|
+
standalone: true,
|
|
355
|
+
imports: [...HlmTabsImports, ...HlmSpinnerImports],
|
|
356
|
+
template: `
|
|
357
|
+
<div hlmTabs tab="summary">
|
|
358
|
+
<div hlmTabsList>
|
|
359
|
+
<button hlmTabsTrigger="summary">Summary</button>
|
|
360
|
+
<button hlmTabsTrigger="reports">Reports</button>
|
|
361
|
+
</div>
|
|
362
|
+
<div hlmTabsContent="summary">Instant summary.</div>
|
|
363
|
+
<ng-template hlmTabsContentLazy>
|
|
364
|
+
<div hlmTabsContent="reports">
|
|
365
|
+
@if (loading()) {
|
|
366
|
+
<hlm-spinner size="1.25rem" />
|
|
367
|
+
} @else {
|
|
368
|
+
<p class="text-sm">{{ report() }}</p>
|
|
369
|
+
}
|
|
370
|
+
</div>
|
|
371
|
+
</ng-template>
|
|
372
|
+
</div>
|
|
373
|
+
`,
|
|
374
|
+
})
|
|
375
|
+
export class DemoLazy {
|
|
376
|
+
private readonly http = inject(HttpClient);
|
|
377
|
+
readonly loading = signal(true);
|
|
378
|
+
readonly report = signal<string | null>(null);
|
|
379
|
+
|
|
380
|
+
constructor() {
|
|
381
|
+
this.http.get('/api/report', { responseType: 'text' }).subscribe({
|
|
382
|
+
next: (v) => {
|
|
383
|
+
this.report.set(v);
|
|
384
|
+
this.loading.set(false);
|
|
385
|
+
},
|
|
386
|
+
error: () => {
|
|
387
|
+
this.report.set('Failed to load.');
|
|
388
|
+
this.loading.set(false);
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Accessibility notes
|
|
396
|
+
|
|
397
|
+
- Triggers are real `<button>` elements wired to `role="tab"` semantics by `BrnTabsTrigger`; panels get `role="tabpanel"`. Keep that mapping 1:1 (matching keys).
|
|
398
|
+
- Keyboard: Arrow keys move between tabs (orientation-aware), Home/End jump to first/last. With `activationMode="manual"`, arrows move focus but Enter/Space activates — use it when panels are expensive.
|
|
399
|
+
- Disabled triggers (`disabled`) are skipped in keyboard navigation — use sparingly and explain why a tab is unavailable.
|
|
400
|
+
- Do not remove panels from the DOM conditionally with `@if` in ways that orphan the active tab; prefer the lazy directive or keep all panels mounted.
|
|
401
|
+
- Label the list when its purpose is ambiguous (`aria-label` on the `hlmTabsList` element).
|
|
402
|
+
|
|
403
|
+
## Theming / CSS variables
|
|
404
|
+
|
|
405
|
+
The list bar follows `listVariants({ variant })` (`bg-muted` pill vs. transparent `line`), while triggers/panels use foreground/muted tokens with `data-active` selectors. Follows your shadcn theme automatically. Extend via `class` (merged through `classes()`) or `tabListClass`/`paginationButtonClass` on the paginated list.
|
|
61
406
|
|
|
62
|
-
##
|
|
407
|
+
## Related subpaths
|
|
63
408
|
|
|
64
|
-
|
|
409
|
+
- `@egose/shadcn-theme-ng/button` — `buttonVariants` powers the paginator chevrons.
|
|
410
|
+
- `@egose/shadcn-theme-ng/card` — panels containing card-styled settings forms.
|
|
411
|
+
- `@egose/shadcn-theme-ng/input` / `@egose/shadcn-theme-ng/label` — form controls inside panels.
|
|
412
|
+
- `@egose/shadcn-theme-ng/spinner` — loading state for lazy/async panels.
|