@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/collapsible/README.md
CHANGED
|
@@ -1,11 +1,338 @@
|
|
|
1
|
-
# Collapsible
|
|
1
|
+
# Collapsible (`@egose/shadcn-theme-ng/collapsible`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A show/hide disclosure container — the Angular port of shadcn/ui `Collapsible`. Three thin directives compose it: `HlmCollapsible` (state owner, wraps `BrnCollapsible`), `HlmCollapsibleTrigger` (toggle button, wraps `BrnCollapsibleTrigger`), and `HlmCollapsibleContent` (collapsing panel, wraps `BrnCollapsibleContent`). All behavior — expanded state, disabled locking, `expandedChange` events, trigger/content wiring — comes from `@spartan-ng/brain/collapsible`; this package only adds `data-slot` attributes and (for content) the `data-[state=closed]:hidden` rule.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ships as `@egose/shadcn-theme-ng/collapsible` and `@egose/shadcn-theme-ng-tw/collapsible` (the `tw:`-prefixed variant). See the [package README](../../README.md) for install, peer dependencies, and Tailwind setup. Do not publish this project directory independently — it is consumed via the published subpath only.
|
|
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
|
+
Peers are listed in the [package README](../../README.md). This subpath declares `@angular/common`, `@angular/core`, and `@spartan-ng/brain` as peers (see `projects/collapsible/package.json`).
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {
|
|
23
|
+
HlmCollapsible,
|
|
24
|
+
HlmCollapsibleTrigger,
|
|
25
|
+
HlmCollapsibleContent,
|
|
26
|
+
HlmCollapsibleImports,
|
|
27
|
+
HlmCollapsibleModule,
|
|
28
|
+
} from '@egose/shadcn-theme-ng/collapsible';
|
|
29
|
+
// tw variant:
|
|
30
|
+
// import { ... } from '@egose/shadcn-theme-ng-tw/collapsible';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Standalone:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { Component } from '@angular/core';
|
|
37
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
38
|
+
|
|
39
|
+
@Component({
|
|
40
|
+
selector: 'app-demo',
|
|
41
|
+
standalone: true,
|
|
42
|
+
imports: [...HlmCollapsibleImports],
|
|
43
|
+
template: `...`,
|
|
44
|
+
})
|
|
45
|
+
export class DemoComponent {}
|
|
11
46
|
```
|
|
47
|
+
|
|
48
|
+
NgModule:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { NgModule } from '@angular/core';
|
|
52
|
+
import { HlmCollapsibleModule } from '@egose/shadcn-theme-ng/collapsible';
|
|
53
|
+
|
|
54
|
+
@NgModule({ imports: [HlmCollapsibleModule] })
|
|
55
|
+
export class DemoModule {}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Anatomy / Structure
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<hlm-collapsible [expanded]="open" (expandedChange)="open = $event">
|
|
62
|
+
<button hlmCollapsibleTrigger>Toggle details</button>
|
|
63
|
+
<hlm-collapsible-content>
|
|
64
|
+
<p>Hidden until expanded.</p>
|
|
65
|
+
</hlm-collapsible-content>
|
|
66
|
+
</hlm-collapsible>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Real selectors (from source — note the trigger is button-only):
|
|
70
|
+
|
|
71
|
+
| Class | Selector | `data-slot` |
|
|
72
|
+
| ----------------------- | ---------------------------------------------------- | --------------------- |
|
|
73
|
+
| `HlmCollapsible` | `[hlmCollapsible]`, `hlm-collapsible` | `collapsible` |
|
|
74
|
+
| `HlmCollapsibleTrigger` | `button[hlmCollapsibleTrigger]` | `collapsible-trigger` |
|
|
75
|
+
| `HlmCollapsibleContent` | `[hlmCollapsibleContent]`, `hlm-collapsible-content` | `collapsible-content` |
|
|
76
|
+
|
|
77
|
+
The trigger **must** be a `<button>` element (`button[hlmCollapsibleTrigger]` — an `<a>` or `<div>` with the attribute will not match). Trigger and content must be descendants of the same `HlmCollapsible` host.
|
|
78
|
+
|
|
79
|
+
## API reference
|
|
80
|
+
|
|
81
|
+
### `HlmCollapsible` (`[hlmCollapsible]`, `hlm-collapsible`)
|
|
82
|
+
|
|
83
|
+
Thin wrapper around `BrnCollapsible`:
|
|
84
|
+
|
|
85
|
+
| Brain input | Type | Description |
|
|
86
|
+
| ----------- | --------- | ---------------------------------------------------------------------------------- |
|
|
87
|
+
| `expanded` | `boolean` | Controlled expanded state. Bind + listen to `expandedChange` for two-way behavior. |
|
|
88
|
+
| `disabled` | `boolean` | Locks the trigger; content stays as-is. |
|
|
89
|
+
|
|
90
|
+
| Brain output | Payload | Description |
|
|
91
|
+
| ---------------- | --------- | ------------------------------------------------------------------------ |
|
|
92
|
+
| `expandedChange` | `boolean` | Emitted whenever the trigger toggles (or state is set programmatically). |
|
|
93
|
+
|
|
94
|
+
No own inputs/outputs/methods.
|
|
95
|
+
|
|
96
|
+
### `HlmCollapsibleTrigger` (`button[hlmCollapsibleTrigger]`)
|
|
97
|
+
|
|
98
|
+
Thin wrapper around `BrnCollapsibleTrigger`:
|
|
99
|
+
|
|
100
|
+
| Brain input | Type | Description |
|
|
101
|
+
| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
102
|
+
| `type` | `string` | Forwarded button `type` (`'button'`, `'submit'`, …). Default to `type="button"` inside forms to avoid accidental submits. |
|
|
103
|
+
|
|
104
|
+
No outputs of its own — activation flows through the parent's `expandedChange`.
|
|
105
|
+
|
|
106
|
+
### `HlmCollapsibleContent` (`[hlmCollapsibleContent]`, `hlm-collapsible-content`)
|
|
107
|
+
|
|
108
|
+
Thin wrapper around `BrnCollapsibleContent`:
|
|
109
|
+
|
|
110
|
+
| Brain input | Type | Description |
|
|
111
|
+
| ----------- | -------- | ---------------------------------------- |
|
|
112
|
+
| `id` | `string` | Content panel id (aria-controls wiring). |
|
|
113
|
+
|
|
114
|
+
Adds `data-[state=closed]:hidden` — the open/close animation (if any) is yours to add via `data-[state]` selectors.
|
|
115
|
+
|
|
116
|
+
## Examples
|
|
117
|
+
|
|
118
|
+
### 1. Basic collapsible (two-way binding pattern)
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { Component } from '@angular/core';
|
|
122
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
123
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
124
|
+
|
|
125
|
+
@Component({
|
|
126
|
+
selector: 'app-basic-collapsible',
|
|
127
|
+
standalone: true,
|
|
128
|
+
imports: [...HlmCollapsibleImports, ...HlmButtonImports],
|
|
129
|
+
template: `
|
|
130
|
+
<hlm-collapsible [expanded]="open" (expandedChange)="open = $event" class="w-96 rounded-lg border p-4">
|
|
131
|
+
<div class="flex items-center justify-between">
|
|
132
|
+
<h4 class="text-sm font-medium">Repository settings</h4>
|
|
133
|
+
<button hlmBtn variant="ghost" size="sm" hlmCollapsibleTrigger>
|
|
134
|
+
{{ open ? 'Hide' : 'Show' }}
|
|
135
|
+
</button>
|
|
136
|
+
</div>
|
|
137
|
+
<hlm-collapsible-content>
|
|
138
|
+
<p class="pt-3 text-sm">Visibility, branch protection, and secrets live here.</p>
|
|
139
|
+
</hlm-collapsible-content>
|
|
140
|
+
</hlm-collapsible>
|
|
141
|
+
`,
|
|
142
|
+
})
|
|
143
|
+
export class BasicCollapsibleComponent {
|
|
144
|
+
open = false;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 2. Default-open + disabled lock
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { Component } from '@angular/core';
|
|
152
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
153
|
+
|
|
154
|
+
@Component({
|
|
155
|
+
selector: 'app-disabled-collapsible',
|
|
156
|
+
standalone: true,
|
|
157
|
+
imports: [...HlmCollapsibleImports],
|
|
158
|
+
template: `
|
|
159
|
+
<div class="space-y-4">
|
|
160
|
+
<hlm-collapsible [expanded]="true" class="rounded-lg border p-4">
|
|
161
|
+
<button hlmCollapsibleTrigger type="button" class="text-sm font-medium">Starts open (expanded=true)</button>
|
|
162
|
+
<hlm-collapsible-content>
|
|
163
|
+
<p class="pt-2 text-sm">This panel renders visible on first paint.</p>
|
|
164
|
+
</hlm-collapsible-content>
|
|
165
|
+
</hlm-collapsible>
|
|
166
|
+
|
|
167
|
+
<hlm-collapsible [disabled]="true" class="rounded-lg border p-4 opacity-80">
|
|
168
|
+
<button hlmCollapsibleTrigger type="button" class="text-sm font-medium">
|
|
169
|
+
Locked (disabled=true) — trigger does nothing
|
|
170
|
+
</button>
|
|
171
|
+
<hlm-collapsible-content>
|
|
172
|
+
<p class="pt-2 text-sm">You cannot reach this content while disabled.</p>
|
|
173
|
+
</hlm-collapsible-content>
|
|
174
|
+
</hlm-collapsible>
|
|
175
|
+
</div>
|
|
176
|
+
`,
|
|
177
|
+
})
|
|
178
|
+
export class DisabledCollapsibleComponent {}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 3. Chevron rotation driven by state
|
|
182
|
+
|
|
183
|
+
Bind the icon rotation to your `open` flag — the classic shadcn pattern.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { Component } from '@angular/core';
|
|
187
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
188
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
189
|
+
import { lucideChevronsUpDown } from '@ng-icons/lucide';
|
|
190
|
+
|
|
191
|
+
@Component({
|
|
192
|
+
selector: 'app-chevron-collapsible',
|
|
193
|
+
standalone: true,
|
|
194
|
+
imports: [...HlmCollapsibleImports, NgIcon],
|
|
195
|
+
providers: [provideIcons({ lucideChevronsUpDown })],
|
|
196
|
+
template: `
|
|
197
|
+
<hlm-collapsible [expanded]="open" (expandedChange)="open = $event" class="w-96 rounded-lg border p-4">
|
|
198
|
+
<button hlmCollapsibleTrigger type="button" class="flex w-full items-center justify-between text-sm font-medium">
|
|
199
|
+
Can I use this in my project?
|
|
200
|
+
<ng-icon name="lucideChevronsUpDown" class="transition-transform duration-200" [class.rotate-180]="open" />
|
|
201
|
+
</button>
|
|
202
|
+
<hlm-collapsible-content>
|
|
203
|
+
<p class="pt-3 text-sm">Yes — free for personal and commercial use.</p>
|
|
204
|
+
</hlm-collapsible-content>
|
|
205
|
+
</hlm-collapsible>
|
|
206
|
+
`,
|
|
207
|
+
})
|
|
208
|
+
export class ChevronCollapsibleComponent {
|
|
209
|
+
open = false;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 4. FAQ list (repeated collapsibles)
|
|
214
|
+
|
|
215
|
+
Each item owns its state — use an array of booleans or a Set of open ids.
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
import { Component } from '@angular/core';
|
|
219
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
220
|
+
|
|
221
|
+
@Component({
|
|
222
|
+
selector: 'app-faq-collapsible',
|
|
223
|
+
standalone: true,
|
|
224
|
+
imports: [...HlmCollapsibleImports],
|
|
225
|
+
template: `
|
|
226
|
+
<div class="w-full max-w-xl space-y-2">
|
|
227
|
+
@for (item of faqs; track item.q; let i = $index) {
|
|
228
|
+
<hlm-collapsible [expanded]="open[i]" (expandedChange)="open[i] = $event" class="rounded-lg border px-4 py-3">
|
|
229
|
+
<button hlmCollapsibleTrigger type="button" class="w-full text-left text-sm font-medium">
|
|
230
|
+
{{ item.q }}
|
|
231
|
+
</button>
|
|
232
|
+
<hlm-collapsible-content>
|
|
233
|
+
<p class="pt-2 text-sm">{{ item.a }}</p>
|
|
234
|
+
</hlm-collapsible-content>
|
|
235
|
+
</hlm-collapsible>
|
|
236
|
+
}
|
|
237
|
+
</div>
|
|
238
|
+
`,
|
|
239
|
+
})
|
|
240
|
+
export class FaqCollapsibleComponent {
|
|
241
|
+
readonly faqs = [
|
|
242
|
+
{ q: 'Is it accessible?', a: 'Yes — triggers are real buttons with aria-expanded wiring from BrnCollapsible.' },
|
|
243
|
+
{ q: 'Is it animated?', a: 'Not by default; add data-[state] transitions (see example 6).' },
|
|
244
|
+
{ q: 'Can I nest them?', a: 'Yes — nest a full hlm-collapsible inside any content panel.' },
|
|
245
|
+
];
|
|
246
|
+
open: boolean[] = [true, false, false];
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 5. Programmatic control (open all / close all)
|
|
251
|
+
|
|
252
|
+
Because `expanded` is a plain input, external buttons can drive it.
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
import { Component } from '@angular/core';
|
|
256
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
257
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
258
|
+
|
|
259
|
+
@Component({
|
|
260
|
+
selector: 'app-controlled-collapsible',
|
|
261
|
+
standalone: true,
|
|
262
|
+
imports: [...HlmCollapsibleImports, ...HlmButtonImports],
|
|
263
|
+
template: `
|
|
264
|
+
<div class="mb-3 flex gap-2">
|
|
265
|
+
<button hlmBtn variant="outline" size="sm" (click)="setAll(true)">Expand all</button>
|
|
266
|
+
<button hlmBtn variant="outline" size="sm" (click)="setAll(false)">Collapse all</button>
|
|
267
|
+
</div>
|
|
268
|
+
@for (s of sections; track s.title; let i = $index) {
|
|
269
|
+
<hlm-collapsible [expanded]="open[i]" (expandedChange)="open[i] = $event" class="mb-2 rounded-lg border p-4">
|
|
270
|
+
<button hlmCollapsibleTrigger type="button" class="text-sm font-medium">{{ s.title }}</button>
|
|
271
|
+
<hlm-collapsible-content>
|
|
272
|
+
<p class="pt-2 text-sm">{{ s.body }}</p>
|
|
273
|
+
</hlm-collapsible-content>
|
|
274
|
+
</hlm-collapsible>
|
|
275
|
+
}
|
|
276
|
+
`,
|
|
277
|
+
})
|
|
278
|
+
export class ControlledCollapsibleComponent {
|
|
279
|
+
readonly sections = [
|
|
280
|
+
{ title: 'Billing', body: 'Invoices, seats, and receipts.' },
|
|
281
|
+
{ title: 'Security', body: 'SSO, 2FA, and audit log.' },
|
|
282
|
+
];
|
|
283
|
+
open = [false, false];
|
|
284
|
+
setAll(v: boolean) {
|
|
285
|
+
this.open = this.open.map(() => v);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### 6. Animated height (advanced, `data-[state]` + grid trick)
|
|
291
|
+
|
|
292
|
+
The content host exposes `data-state="open" | "closed"` from the brain directive — animate with a grid-rows transition instead of `hidden`.
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
import { Component } from '@angular/core';
|
|
296
|
+
import { HlmCollapsibleImports } from '@egose/shadcn-theme-ng/collapsible';
|
|
297
|
+
|
|
298
|
+
@Component({
|
|
299
|
+
selector: 'app-animated-collapsible',
|
|
300
|
+
standalone: true,
|
|
301
|
+
imports: [...HlmCollapsibleImports],
|
|
302
|
+
template: `
|
|
303
|
+
<hlm-collapsible [expanded]="open" (expandedChange)="open = $event" class="w-96 rounded-lg border p-4">
|
|
304
|
+
<button hlmCollapsibleTrigger type="button" class="text-sm font-medium">
|
|
305
|
+
{{ open ? 'Collapse' : 'Expand' }} with animation
|
|
306
|
+
</button>
|
|
307
|
+
<hlm-collapsible-content
|
|
308
|
+
class="grid transition-all duration-200 data-[state=closed]:hidden data-[state=open]:grid-rows-[1fr] data-[state=closed]:grid-rows-[0fr]"
|
|
309
|
+
>
|
|
310
|
+
<div class="overflow-hidden">
|
|
311
|
+
<p class="pt-3 text-sm">Smooth grid-rows open/close. Keep the inner overflow-hidden wrapper.</p>
|
|
312
|
+
</div>
|
|
313
|
+
</hlm-collapsible-content>
|
|
314
|
+
</hlm-collapsible>
|
|
315
|
+
`,
|
|
316
|
+
})
|
|
317
|
+
export class AnimatedCollapsibleComponent {
|
|
318
|
+
open = false;
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Accessibility notes
|
|
323
|
+
|
|
324
|
+
- Trigger is a native `<button>` with `aria-expanded` / `aria-controls` wired by `BrnCollapsibleTrigger` — never replace it with a `<div (click)>`; keyboard (Enter/Space) support depends on the button.
|
|
325
|
+
- Always use `type="button"` on triggers inside `<form>`s to avoid accidental submits (the `type` input is forwarded).
|
|
326
|
+
- `disabled` on the parent locks the trigger (`aria-disabled` semantics from brain) — announce why it is locked with adjacent hint text.
|
|
327
|
+
- Content is hidden with `data-[state=closed]:hidden` (display:none), so screen readers skip closed panels — correct disclosure behavior.
|
|
328
|
+
|
|
329
|
+
## Theming / CSS variables
|
|
330
|
+
|
|
331
|
+
No component-specific CSS variables and no default open/close animation. Style hooks: `data-slot` (`collapsible`, `collapsible-trigger`, `collapsible-content`) and `data-state="open|closed"` / `data-disabled`. Add your own `data-[state=open]:…` transitions as in example 6.
|
|
332
|
+
|
|
333
|
+
## Related subpaths
|
|
334
|
+
|
|
335
|
+
- `@egose/shadcn-theme-ng/accordion` — mutually-exclusive multi-item disclosures (use instead of hand-rolled FAQ state).
|
|
336
|
+
- `@egose/shadcn-theme-ng/button` — ghost/small trigger styling (`hlmBtn`).
|
|
337
|
+
- `@egose/shadcn-theme-ng/icon` — chevron affordances rotated from your `open` flag.
|
|
338
|
+
- `@egose/shadcn-theme-ng/card` — bordered shells that host collapsible rows.
|
|
@@ -5,10 +5,10 @@ import { BrnCollapsible, BrnCollapsibleContent, BrnCollapsibleTrigger } from '@s
|
|
|
5
5
|
import { classes } from '@egose/shadcn-theme-ng/utils';
|
|
6
6
|
|
|
7
7
|
class HlmCollapsible {
|
|
8
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
9
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
8
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsible, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
9
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmCollapsible, isStandalone: true, selector: "[hlmCollapsible],hlm-collapsible", host: { attributes: { "data-slot": "collapsible" } }, hostDirectives: [{ directive: i1.BrnCollapsible, inputs: ["expanded", "expanded", "disabled", "disabled"], outputs: ["expandedChange", "expandedChange"] }], ngImport: i0 });
|
|
10
10
|
}
|
|
11
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
11
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsible, decorators: [{
|
|
12
12
|
type: Directive,
|
|
13
13
|
args: [{
|
|
14
14
|
selector: '[hlmCollapsible],hlm-collapsible',
|
|
@@ -25,12 +25,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
25
25
|
|
|
26
26
|
class HlmCollapsibleContent {
|
|
27
27
|
constructor() {
|
|
28
|
-
classes(() =>
|
|
28
|
+
classes(() => "data-[state=closed]:hidden");
|
|
29
29
|
}
|
|
30
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
31
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
31
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmCollapsibleContent, isStandalone: true, selector: "[hlmCollapsibleContent],hlm-collapsible-content", host: { attributes: { "data-slot": "collapsible-content" } }, hostDirectives: [{ directive: i1.BrnCollapsibleContent, inputs: ["id", "id"] }], ngImport: i0 });
|
|
32
32
|
}
|
|
33
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleContent, decorators: [{
|
|
34
34
|
type: Directive,
|
|
35
35
|
args: [{
|
|
36
36
|
selector: '[hlmCollapsibleContent],hlm-collapsible-content',
|
|
@@ -40,10 +40,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
40
40
|
}], ctorParameters: () => [] });
|
|
41
41
|
|
|
42
42
|
class HlmCollapsibleTrigger {
|
|
43
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
44
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
43
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
44
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmCollapsibleTrigger, isStandalone: true, selector: "button[hlmCollapsibleTrigger]", host: { attributes: { "data-slot": "collapsible-trigger" } }, hostDirectives: [{ directive: i1.BrnCollapsibleTrigger, inputs: ["type", "type"] }], ngImport: i0 });
|
|
45
45
|
}
|
|
46
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
46
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleTrigger, decorators: [{
|
|
47
47
|
type: Directive,
|
|
48
48
|
args: [{
|
|
49
49
|
selector: 'button[hlmCollapsibleTrigger]',
|
|
@@ -57,11 +57,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
57
57
|
*/
|
|
58
58
|
const HlmCollapsibleImports = [HlmCollapsible, HlmCollapsibleContent, HlmCollapsibleTrigger];
|
|
59
59
|
class HlmCollapsibleModule {
|
|
60
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
61
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.
|
|
62
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.
|
|
60
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
61
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleModule, imports: [HlmCollapsible, HlmCollapsibleContent, HlmCollapsibleTrigger], exports: [HlmCollapsible, HlmCollapsibleContent, HlmCollapsibleTrigger] });
|
|
62
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleModule });
|
|
63
63
|
}
|
|
64
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
64
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCollapsibleModule, decorators: [{
|
|
65
65
|
type: NgModule,
|
|
66
66
|
args: [{
|
|
67
67
|
imports: [...HlmCollapsibleImports],
|
|
@@ -74,4 +74,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
76
|
export { HlmCollapsible, HlmCollapsibleContent, HlmCollapsibleImports, HlmCollapsibleModule, HlmCollapsibleTrigger };
|
|
77
|
-
|
|
77
|
+
|