@egose/shadcn-theme-ng-tw 0.0.28 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -13
- package/accordion/README.md +376 -34
- package/accordion/fesm2022/accordion.mjs +20 -20
- package/alert/README.md +343 -34
- package/alert/fesm2022/alert.mjs +18 -18
- package/alert-dialog/README.md +471 -5
- package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
- package/alert-dialog/types/alert-dialog.d.ts +1 -1
- package/aspect-ratio/README.md +272 -5
- package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
- package/autocomplete/README.md +473 -34
- package/autocomplete/fesm2022/autocomplete.mjs +54 -54
- package/autocomplete/types/autocomplete.d.ts +1 -1
- package/avatar/README.md +357 -5
- package/avatar/fesm2022/avatar.mjs +32 -32
- package/badge/README.md +289 -34
- package/badge/fesm2022/badge.mjs +4 -4
- package/basic-alert/README.md +324 -34
- package/basic-alert/fesm2022/basic-alert.mjs +4 -4
- package/basic-alert/types/basic-alert.d.ts +1 -1
- package/breadcrumb/README.md +406 -5
- package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
- package/button/README.md +453 -34
- package/button/fesm2022/button.mjs +96 -118
- package/button/types/button.d.ts +7 -10
- package/button-group/README.md +318 -5
- package/button-group/fesm2022/button-group.mjs +20 -20
- package/calendar/README.md +328 -34
- package/calendar/fesm2022/calendar.mjs +154 -154
- package/card/README.md +331 -5
- package/card/fesm2022/card.mjs +33 -33
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +47 -44
- package/carousel/types/carousel.d.ts +1 -1
- package/checkbox/README.md +291 -34
- package/checkbox/fesm2022/checkbox.mjs +22 -20
- package/checkbox/types/checkbox.d.ts +5 -4
- package/collapsible/README.md +332 -5
- package/collapsible/fesm2022/collapsible.mjs +15 -15
- package/combobox/README.md +507 -5
- package/combobox/fesm2022/combobox.mjs +95 -92
- package/combobox/types/combobox.d.ts +1 -1
- package/command/README.md +435 -5
- package/command/fesm2022/command.mjs +56 -56
- package/confirmation-dialog/README.md +272 -34
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
- package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
- package/context-menu/README.md +366 -5
- package/context-menu/fesm2022/context-menu.mjs +9 -9
- package/date-picker/README.md +436 -34
- package/date-picker/fesm2022/date-picker.mjs +79 -68
- package/date-picker/types/date-picker.d.ts +8 -4
- package/dialog/README.md +419 -34
- package/dialog/fesm2022/dialog.mjs +48 -48
- package/drawer/README.md +395 -5
- package/drawer/fesm2022/drawer.mjs +45 -45
- package/dropdown-menu/README.md +417 -5
- package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
- package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
- package/empty/README.md +329 -5
- package/empty/fesm2022/empty.mjs +31 -31
- package/field/README.md +385 -5
- package/field/fesm2022/field.mjs +59 -59
- package/field/types/field.d.ts +1 -1
- package/form-checkbox/README.md +283 -34
- package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
- package/form-checkbox/types/form-checkbox.d.ts +7 -1
- package/form-date-picker/README.md +293 -34
- package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
- package/form-date-picker/types/form-date-picker.d.ts +7 -1
- package/form-field/README.md +327 -34
- package/form-field/fesm2022/form-field.mjs +30 -16
- package/form-field/types/form-field.d.ts +28 -20
- package/form-field-simple/README.md +311 -34
- package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
- package/form-searchable-multiselect/README.md +332 -34
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
- package/form-select/README.md +321 -34
- package/form-select/fesm2022/form-select.mjs +62 -29
- package/form-select/types/form-select.d.ts +7 -1
- package/form-text-input/README.md +342 -34
- package/form-text-input/fesm2022/form-text-input.mjs +43 -55
- package/form-text-input/types/form-text-input.d.ts +9 -12
- package/form-textarea/README.md +318 -34
- package/form-textarea/fesm2022/form-textarea.mjs +42 -23
- package/form-textarea/types/form-textarea.d.ts +8 -1
- package/hover-card/README.md +256 -5
- package/hover-card/fesm2022/hover-card.mjs +19 -19
- package/icon/README.md +210 -34
- package/icon/fesm2022/icon.mjs +8 -8
- package/input/README.md +240 -34
- package/input/fesm2022/input.mjs +17 -12
- package/input/types/input.d.ts +2 -1
- package/input-group/README.md +335 -5
- package/input-group/fesm2022/input-group.mjs +37 -37
- package/input-group/types/input-group.d.ts +3 -3
- package/input-otp/README.md +375 -5
- package/input-otp/fesm2022/input-otp.mjs +27 -27
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +54 -54
- package/kbd/README.md +291 -5
- package/kbd/fesm2022/kbd.mjs +13 -13
- package/label/README.md +243 -34
- package/label/fesm2022/label.mjs +9 -9
- package/label/types/label.d.ts +1 -1
- package/layout-simple/README.md +174 -44
- package/layout-simple/fesm2022/layout-simple.mjs +917 -398
- package/layout-simple/types/layout-simple.d.ts +180 -129
- package/menu/README.md +418 -0
- package/menu/fesm2022/menu.mjs +461 -0
- package/menu/package.json +24 -0
- package/menu/types/menu.d.ts +137 -0
- package/menubar/README.md +343 -5
- package/menubar/fesm2022/menubar.mjs +13 -13
- package/native-select/README.md +323 -5
- package/native-select/fesm2022/native-select.mjs +19 -19
- package/navigation-menu/README.md +369 -5
- package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
- package/package.json +183 -154
- package/pagination/README.md +388 -5
- package/pagination/fesm2022/pagination.mjs +63 -63
- package/popover/README.md +302 -34
- package/popover/fesm2022/popover.mjs +30 -30
- package/progress/README.md +311 -5
- package/progress/fesm2022/progress.mjs +13 -13
- package/radio-group/README.md +335 -34
- package/radio-group/fesm2022/radio-group.mjs +26 -19
- package/resizable/README.md +269 -5
- package/resizable/fesm2022/resizable.mjs +19 -19
- package/scroll-area/README.md +233 -5
- package/scroll-area/fesm2022/scroll-area.mjs +9 -9
- package/searchable-multiselect/README.md +294 -34
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
- package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
- package/select/README.md +408 -34
- package/select/fesm2022/select.mjs +80 -72
- package/select/types/select.d.ts +3 -1
- package/separator/README.md +193 -34
- package/separator/fesm2022/separator.mjs +9 -9
- package/separator/types/separator.d.ts +1 -1
- package/sheet/README.md +282 -34
- package/sheet/fesm2022/sheet.mjs +30 -30
- package/sidebar/README.md +457 -5
- package/sidebar/fesm2022/sidebar.mjs +136 -134
- package/sidebar/types/sidebar.d.ts +3 -3
- package/skeleton/README.md +217 -5
- package/skeleton/fesm2022/skeleton.mjs +9 -9
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +29 -25
- package/sonner/README.md +317 -34
- package/sonner/fesm2022/sonner.mjs +9 -9
- package/spinner/README.md +255 -34
- package/spinner/fesm2022/spinner.mjs +8 -8
- package/switch/README.md +281 -34
- package/switch/fesm2022/switch.mjs +12 -14
- package/table/README.md +423 -5
- package/table/fesm2022/table.mjs +41 -41
- package/tabs/README.md +382 -34
- package/tabs/fesm2022/tabs.mjs +48 -38
- package/textarea/README.md +282 -5
- package/textarea/fesm2022/textarea.mjs +9 -9
- package/toggle/README.md +270 -5
- package/toggle/fesm2022/toggle.mjs +14 -14
- package/toggle-group/README.md +340 -5
- package/toggle-group/fesm2022/toggle-group.mjs +13 -13
- package/toggle-group/types/toggle-group.d.ts +13 -7
- package/tooltip/README.md +240 -34
- package/tooltip/fesm2022/tooltip.mjs +14 -14
- package/typography/README.md +271 -5
- package/typography/fesm2022/typography.mjs +53 -53
- package/typography/types/typography.d.ts +12 -12
- package/utils/README.md +274 -34
- package/utils/fesm2022/utils.mjs +68 -44
- package/accordion/fesm2022/accordion.mjs.map +0 -1
- package/alert/fesm2022/alert.mjs.map +0 -1
- package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
- package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
- package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
- package/avatar/fesm2022/avatar.mjs.map +0 -1
- package/badge/fesm2022/badge.mjs.map +0 -1
- package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
- package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
- package/button/fesm2022/button.mjs.map +0 -1
- package/button-group/fesm2022/button-group.mjs.map +0 -1
- package/calendar/fesm2022/calendar.mjs.map +0 -1
- package/card/fesm2022/card.mjs.map +0 -1
- package/carousel/fesm2022/carousel.mjs.map +0 -1
- package/checkbox/fesm2022/checkbox.mjs.map +0 -1
- package/collapsible/fesm2022/collapsible.mjs.map +0 -1
- package/combobox/fesm2022/combobox.mjs.map +0 -1
- package/command/fesm2022/command.mjs.map +0 -1
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
- package/context-menu/fesm2022/context-menu.mjs.map +0 -1
- package/date-picker/fesm2022/date-picker.mjs.map +0 -1
- package/dialog/fesm2022/dialog.mjs.map +0 -1
- package/drawer/fesm2022/drawer.mjs.map +0 -1
- package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
- package/empty/fesm2022/empty.mjs.map +0 -1
- package/field/fesm2022/field.mjs.map +0 -1
- package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
- package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
- package/form-field/fesm2022/form-field.mjs.map +0 -1
- package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
- package/form-select/fesm2022/form-select.mjs.map +0 -1
- package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
- package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
- package/hover-card/fesm2022/hover-card.mjs.map +0 -1
- package/icon/fesm2022/icon.mjs.map +0 -1
- package/input/fesm2022/input.mjs.map +0 -1
- package/input-group/fesm2022/input-group.mjs.map +0 -1
- package/input-otp/fesm2022/input-otp.mjs.map +0 -1
- package/item/fesm2022/item.mjs.map +0 -1
- package/kbd/fesm2022/kbd.mjs.map +0 -1
- package/label/fesm2022/label.mjs.map +0 -1
- package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
- package/menubar/fesm2022/menubar.mjs.map +0 -1
- package/native-select/fesm2022/native-select.mjs.map +0 -1
- package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
- package/pagination/fesm2022/pagination.mjs.map +0 -1
- package/popover/fesm2022/popover.mjs.map +0 -1
- package/progress/fesm2022/progress.mjs.map +0 -1
- package/radio-group/fesm2022/radio-group.mjs.map +0 -1
- package/resizable/fesm2022/resizable.mjs.map +0 -1
- package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
- package/select/fesm2022/select.mjs.map +0 -1
- package/separator/fesm2022/separator.mjs.map +0 -1
- package/sheet/fesm2022/sheet.mjs.map +0 -1
- package/sidebar/fesm2022/sidebar.mjs.map +0 -1
- package/skeleton/fesm2022/skeleton.mjs.map +0 -1
- package/slider/fesm2022/slider.mjs.map +0 -1
- package/sonner/fesm2022/sonner.mjs.map +0 -1
- package/spinner/fesm2022/spinner.mjs.map +0 -1
- package/switch/fesm2022/switch.mjs.map +0 -1
- package/table/fesm2022/table.mjs.map +0 -1
- package/tabs/fesm2022/tabs.mjs.map +0 -1
- package/textarea/fesm2022/textarea.mjs.map +0 -1
- package/toggle/fesm2022/toggle.mjs.map +0 -1
- package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
- package/tooltip/fesm2022/tooltip.mjs.map +0 -1
- package/typography/fesm2022/typography.mjs.map +0 -1
- package/utils/fesm2022/utils.mjs.map +0 -1
package/hover-card/README.md
CHANGED
|
@@ -1,11 +1,262 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Hover Card (`@egose/shadcn-theme-ng/hover-card`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The hover card shows a rich preview panel when the user hovers (or focuses) a trigger — the shadcn/ui _HoverCard_ equivalent (docs link with an author preview, usercard on an `@mention`, product peek on hover). Behavior comes from spartan-ng's `BrnHoverCard` family (CDK overlay under the hood); this subpath adds the shadcn styling and `data-slot` hooks.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/hover-card` (plain Tailwind) and `@egose/shadcn-theme-ng-tw/hover-card` (`tw:`-prefixed variant). See the [package README](../../README.md) for installation, peer dependencies, and the Tailwind-variant contract. Do not publish this project directory independently.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
# Plain Tailwind (no prefix)
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies (Angular, CDK, `@spartan-ng/brain`, `rxjs`) are documented in the [package README](../../README.md#peer-dependencies).
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
21
|
+
// tw variant:
|
|
22
|
+
// import { HlmHoverCardImports } from '@egose/shadcn-theme-ng-tw/hover-card';
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Imports
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// Standalone component — spread the imports array:
|
|
29
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
30
|
+
|
|
31
|
+
@Component({
|
|
32
|
+
standalone: true,
|
|
33
|
+
imports: [HlmHoverCardImports],
|
|
34
|
+
template: `…`,
|
|
35
|
+
})
|
|
36
|
+
export class MyComp {}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// NgModule-based — import the module:
|
|
41
|
+
import { HlmHoverCardModule } from '@egose/shadcn-theme-ng/hover-card';
|
|
42
|
+
|
|
43
|
+
@NgModule({ imports: [HlmHoverCardModule] })
|
|
44
|
+
export class MyModule {}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Individual symbols (all exported from `src/public-api.ts`): `HlmHoverCard`, `HlmHoverCardTrigger`, `HlmHoverCardContent`, `HlmHoverCardPortal`, plus `HlmHoverCardImports` and `HlmHoverCardModule`.
|
|
48
|
+
|
|
49
|
+
## Anatomy / Structure
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<div hlmHoverCard>
|
|
53
|
+
<a href="https://example.com" hlmHoverCardTrigger>Hover me</a>
|
|
54
|
+
|
|
55
|
+
<!-- structural portal directive + styling directive on the same element -->
|
|
56
|
+
<hlm-hover-card-content *hlmHoverCardPortal>
|
|
57
|
+
<p class="tw:font-semibold">@example</p>
|
|
58
|
+
<p class="tw:text-sm tw:text-gray-500">Preview content goes here.</p>
|
|
59
|
+
</hlm-hover-card-content>
|
|
60
|
+
</div>
|
|
11
61
|
```
|
|
62
|
+
|
|
63
|
+
Real selectors: `[hlmHoverCard]` / `hlm-hover-card` (root, `hostDirectives: [BrnHoverCard]`), `[hlmHoverCardTrigger]` (trigger, `hostDirectives: [BrnHoverCardTrigger]`), `[hlmHoverCardPortal]` / `hlm-hover-card-portal` (structural overlay portal, `hostDirectives: [BrnHoverCardContent]` — used as `*hlmHoverCardPortal`), `[hlmHoverCardContent]` / `hlm-hover-card-content` (styling shell: popover colors, `w-64`, rounded, shadow, open/close animations; mirrors `data-state`/`data-side` attributes).
|
|
64
|
+
|
|
65
|
+
## API reference
|
|
66
|
+
|
|
67
|
+
### `hlmHoverCard` / `hlm-hover-card` — `HlmHoverCard`
|
|
68
|
+
|
|
69
|
+
Thin directive wrapper: `hostDirectives: [BrnHoverCard]`, `data-slot="hover-card"`. No inputs/outputs of its own — it owns the open state shared by trigger and portal.
|
|
70
|
+
|
|
71
|
+
### `[hlmHoverCardTrigger]` — `HlmHoverCardTrigger`
|
|
72
|
+
|
|
73
|
+
Thin directive wrapper forwarding these inputs to `BrnHoverCardTrigger` (plus `data-slot="hover-card-trigger"`):
|
|
74
|
+
|
|
75
|
+
| Input | Type | Description |
|
|
76
|
+
| ------------------------ | ------- | ----------------------------------------------------------------------------------- |
|
|
77
|
+
| `showDelay` | (brain) | Delay before the card opens on hover. |
|
|
78
|
+
| `hideDelay` | (brain) | Delay before the card closes after pointer leave. |
|
|
79
|
+
| `animationDelay` | (brain) | Delay applied to the open/close animation. |
|
|
80
|
+
| `sideOffset` | (brain) | Pixel offset between trigger and card. |
|
|
81
|
+
| `align` | (brain) | Overlay alignment (`start` / `center` / `end`). |
|
|
82
|
+
| `hlmHoverCardTriggerFor` | (brain) | Explicit content reference (`brnHoverCardTriggerFor` alias) for non-default wiring. |
|
|
83
|
+
|
|
84
|
+
### `[hlmHoverCardPortal]` / `hlm-hover-card-portal` — `HlmHoverCardPortal`
|
|
85
|
+
|
|
86
|
+
Structural directive (`hostDirectives: [BrnHoverCardContent]`). Apply as `*hlmHoverCardPortal` on the content element so the card renders in the CDK overlay. No inputs of its own.
|
|
87
|
+
|
|
88
|
+
### `[hlmHoverCardContent]` / `hlm-hover-card-content` — `HlmHoverCardContent`
|
|
89
|
+
|
|
90
|
+
Styling directive for the panel. No inputs/outputs; it reads the overlay `state` (`open`/`closed`) and `side` (`top`/`bottom`/`left`/`right`) signals from the brain providers and reflects them as `data-state` / `data-side` attributes for the animation classes. Default width is `tw:w-64` — override with `class`.
|
|
91
|
+
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
94
|
+
### 1. Basic link preview
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { Component } from '@angular/core';
|
|
98
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
99
|
+
|
|
100
|
+
@Component({
|
|
101
|
+
standalone: true,
|
|
102
|
+
imports: [HlmHoverCardImports],
|
|
103
|
+
template: `
|
|
104
|
+
<div hlmHoverCard>
|
|
105
|
+
<a href="https://angular.dev" hlmHoverCardTrigger class="tw:cursor-pointer tw:underline tw:text-blue-600">
|
|
106
|
+
Angular
|
|
107
|
+
</a>
|
|
108
|
+
<hlm-hover-card-content *hlmHoverCardPortal>
|
|
109
|
+
<p class="tw:font-semibold">Angular</p>
|
|
110
|
+
<p class="tw:text-sm tw:text-gray-500">The web development framework for the modern web.</p>
|
|
111
|
+
</hlm-hover-card-content>
|
|
112
|
+
</div>
|
|
113
|
+
`,
|
|
114
|
+
})
|
|
115
|
+
export class BasicExample {}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 2. Open/close delays
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { Component } from '@angular/core';
|
|
122
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
123
|
+
|
|
124
|
+
@Component({
|
|
125
|
+
standalone: true,
|
|
126
|
+
imports: [HlmHoverCardImports],
|
|
127
|
+
template: `
|
|
128
|
+
<div hlmHoverCard>
|
|
129
|
+
<button hlmHoverCardTrigger type="button" [showDelay]="400" [hideDelay]="200">Hover (opens after 400ms)</button>
|
|
130
|
+
<hlm-hover-card-content *hlmHoverCardPortal>
|
|
131
|
+
<p class="tw:text-sm">Delays keep accidental hovers from flashing the card.</p>
|
|
132
|
+
</hlm-hover-card-content>
|
|
133
|
+
</div>
|
|
134
|
+
`,
|
|
135
|
+
})
|
|
136
|
+
export class DelaysExample {}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3. Placement: side, align, offset
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { Component } from '@angular/core';
|
|
143
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
144
|
+
|
|
145
|
+
@Component({
|
|
146
|
+
standalone: true,
|
|
147
|
+
imports: [HlmHoverCardImports],
|
|
148
|
+
template: `
|
|
149
|
+
<div hlmHoverCard>
|
|
150
|
+
<span hlmHoverCardTrigger [sideOffset]="12" align="start"> Hover for right-side card </span>
|
|
151
|
+
<hlm-hover-card-content *hlmHoverCardPortal class="tw:w-72">
|
|
152
|
+
<p class="tw:text-sm">Offset by 12px, aligned to the trigger start edge.</p>
|
|
153
|
+
</hlm-hover-card-content>
|
|
154
|
+
</div>
|
|
155
|
+
`,
|
|
156
|
+
})
|
|
157
|
+
export class PlacementExample {}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> `side` itself is owned by the brain content directive — set alignment/offset on the trigger; the `data-side` attribute on the content element reflects the resolved side for animations.
|
|
161
|
+
|
|
162
|
+
### 4. User card with avatar + stats
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { Component } from '@angular/core';
|
|
166
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
167
|
+
import { HlmAvatarImports } from '@egose/shadcn-theme-ng/avatar';
|
|
168
|
+
|
|
169
|
+
@Component({
|
|
170
|
+
standalone: true,
|
|
171
|
+
imports: [HlmHoverCardImports, HlmAvatarImports],
|
|
172
|
+
template: `
|
|
173
|
+
<div hlmHoverCard>
|
|
174
|
+
<span hlmHoverCardTrigger class="tw:cursor-pointer tw:font-medium tw:underline">@jane</span>
|
|
175
|
+
<hlm-hover-card-content *hlmHoverCardPortal class="tw:w-80">
|
|
176
|
+
<div class="tw:flex tw:gap-4">
|
|
177
|
+
<hlm-avatar size="sm">
|
|
178
|
+
<img hlmAvatarImage src="https://github.com/jane.png" alt="Jane's avatar" />
|
|
179
|
+
<span hlmAvatarFallback>JA</span>
|
|
180
|
+
</hlm-avatar>
|
|
181
|
+
<div>
|
|
182
|
+
<p class="tw:font-semibold">@jane</p>
|
|
183
|
+
<p class="tw:text-sm tw:text-gray-500">Design engineer. Ships accessible UI.</p>
|
|
184
|
+
<p class="tw:mt-2 tw:text-xs tw:text-gray-500">1.2k followers · 84 following</p>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</hlm-hover-card-content>
|
|
188
|
+
</div>
|
|
189
|
+
`,
|
|
190
|
+
})
|
|
191
|
+
export class UserCardExample {}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 5. Wide content (override the default `w-64`)
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import { Component } from '@angular/core';
|
|
198
|
+
import { HlmHoverCardImports } from '@egose/shadcn-theme-ng/hover-card';
|
|
199
|
+
|
|
200
|
+
@Component({
|
|
201
|
+
standalone: true,
|
|
202
|
+
imports: [HlmHoverCardImports],
|
|
203
|
+
template: `
|
|
204
|
+
<div hlmHoverCard>
|
|
205
|
+
<button hlmHoverCardTrigger type="button">Product peek</button>
|
|
206
|
+
<hlm-hover-card-content *hlmHoverCardPortal class="tw:w-96">
|
|
207
|
+
<div class="tw:grid tw:grid-cols-[64px_1fr] tw:gap-3">
|
|
208
|
+
<div class="tw:h-16 tw:w-16 tw:rounded-md tw:bg-slate-200"></div>
|
|
209
|
+
<div>
|
|
210
|
+
<p class="tw:font-semibold">Ergonomic keyboard</p>
|
|
211
|
+
<p class="tw:text-sm tw:text-gray-500">Silent switches · $149 · In stock</p>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</hlm-hover-card-content>
|
|
215
|
+
</div>
|
|
216
|
+
`,
|
|
217
|
+
})
|
|
218
|
+
export class WideExample {}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 6. NgModule usage + keyboard-focusable trigger
|
|
222
|
+
|
|
223
|
+
Hover cards also open on keyboard focus, so a natively focusable trigger keeps them reachable without a mouse:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import { NgModule, Component } from '@angular/core';
|
|
227
|
+
import { HlmHoverCardModule } from '@egose/shadcn-theme-ng/hover-card';
|
|
228
|
+
|
|
229
|
+
@Component({
|
|
230
|
+
selector: 'app-hover-demo',
|
|
231
|
+
template: `
|
|
232
|
+
<div hlmHoverCard>
|
|
233
|
+
<button hlmHoverCardTrigger type="button">Focus me with Tab, then hover away</button>
|
|
234
|
+
<hlm-hover-card-content *hlmHoverCardPortal>
|
|
235
|
+
<p class="tw:text-sm">Focus opens the card too — no mouse required.</p>
|
|
236
|
+
</hlm-hover-card-content>
|
|
237
|
+
</div>
|
|
238
|
+
`,
|
|
239
|
+
})
|
|
240
|
+
export class HoverDemoComponent {}
|
|
241
|
+
|
|
242
|
+
@NgModule({ declarations: [HoverDemoComponent], imports: [HlmHoverCardModule] })
|
|
243
|
+
export class HoverDemoModule {}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Accessibility notes
|
|
247
|
+
|
|
248
|
+
- Use a natively focusable trigger (`<a href>`, `<button>`) — the card opens on focus as well as hover, which keeps keyboard users in the loop.
|
|
249
|
+
- Keep the card content supplementary: never put the _only_ copy of critical information (or interactive controls) inside a hover-only panel, since touch users and keyboard users may dismiss it easily.
|
|
250
|
+
- The brain layer handles overlay dismissal (Escape / outside pointer). Avoid `showDelay`s so long that keyboard focus has already moved on.
|
|
251
|
+
- If the trigger is an icon or avatar without text, give it an `aria-label` describing what the preview shows.
|
|
252
|
+
|
|
253
|
+
## Theming / CSS variables
|
|
254
|
+
|
|
255
|
+
No component-specific CSS variables; the panel uses the shared `--popover` / `--popover-foreground` / `--ring` tokens. Widen with `class="tw:w-…"`, or restyle padding via `class` overrides.
|
|
256
|
+
|
|
257
|
+
## Related subpaths
|
|
258
|
+
|
|
259
|
+
- `@egose/shadcn-theme-ng/popover` — click-triggered counterpart (same portal/content pattern).
|
|
260
|
+
- `@egose/shadcn-theme-ng/tooltip` — lightweight text-only hover hints.
|
|
261
|
+
- `@egose/shadcn-theme-ng/avatar` — typical media inside user preview cards.
|
|
262
|
+
- `@egose/shadcn-theme-ng/dialog` — modal alternative when the content needs interaction.
|
|
@@ -6,10 +6,10 @@ import { injectExposesStateProvider, injectExposedSideProvider } from '@spartan-
|
|
|
6
6
|
import { classes } from '@egose/shadcn-theme-ng-tw/utils';
|
|
7
7
|
|
|
8
8
|
class HlmHoverCard {
|
|
9
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
10
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
9
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCard, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
10
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmHoverCard, isStandalone: true, selector: "[hlmHoverCard],hlm-hover-card", host: { attributes: { "data-slot": "hover-card" } }, hostDirectives: [{ directive: i1.BrnHoverCard }], ngImport: i0 });
|
|
11
11
|
}
|
|
12
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
12
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCard, decorators: [{
|
|
13
13
|
type: Directive,
|
|
14
14
|
args: [{
|
|
15
15
|
selector: '[hlmHoverCard],hlm-hover-card',
|
|
@@ -31,14 +31,14 @@ class HlmHoverCardContent {
|
|
|
31
31
|
this._renderer.setAttribute(this._element.nativeElement, 'data-side', this.side());
|
|
32
32
|
});
|
|
33
33
|
classes(() => [
|
|
34
|
-
'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground w-64 rounded-lg p-4 text-sm shadow-md ring-1 duration-100 z-50 outline-none',
|
|
35
|
-
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
34
|
+
'tw:data-open:animate-in tw:data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 tw:data-closed:zoom-out-95 tw:data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 tw:ring-foreground/10 tw:bg-popover tw:text-popover-foreground tw:w-64 tw:rounded-lg tw:p-4 tw:text-sm tw:shadow-md tw:ring-1 tw:duration-100 tw:z-50 tw:outline-none',
|
|
35
|
+
'tw:data-[state=open]:animate-in tw:data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 tw:data-[state=closed]:zoom-out-95 tw:data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
36
36
|
]);
|
|
37
37
|
}
|
|
38
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
39
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
38
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
39
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmHoverCardContent, isStandalone: true, selector: "[hlmHoverCardContent],hlm-hover-card-content", host: { attributes: { "data-slot": "hover-card-content" } }, ngImport: i0 });
|
|
40
40
|
}
|
|
41
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
41
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardContent, decorators: [{
|
|
42
42
|
type: Directive,
|
|
43
43
|
args: [{
|
|
44
44
|
selector: '[hlmHoverCardContent],hlm-hover-card-content',
|
|
@@ -49,10 +49,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
49
49
|
}], ctorParameters: () => [] });
|
|
50
50
|
|
|
51
51
|
class HlmHoverCardPortal {
|
|
52
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
53
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
52
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
53
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmHoverCardPortal, isStandalone: true, selector: "[hlmHoverCardPortal],hlm-hover-card-portal", hostDirectives: [{ directive: i1.BrnHoverCardContent }], ngImport: i0 });
|
|
54
54
|
}
|
|
55
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
55
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardPortal, decorators: [{
|
|
56
56
|
type: Directive,
|
|
57
57
|
args: [{
|
|
58
58
|
selector: '[hlmHoverCardPortal],hlm-hover-card-portal',
|
|
@@ -61,10 +61,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
61
61
|
}] });
|
|
62
62
|
|
|
63
63
|
class HlmHoverCardTrigger {
|
|
64
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
65
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
64
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
65
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmHoverCardTrigger, isStandalone: true, selector: "[hlmHoverCardTrigger]", host: { attributes: { "data-slot": "hover-card-trigger" } }, hostDirectives: [{ directive: i1.BrnHoverCardTrigger, inputs: ["showDelay", "showDelay", "hideDelay", "hideDelay", "animationDelay", "animationDelay", "sideOffset", "sideOffset", "align", "align", "brnHoverCardTriggerFor", "hlmHoverCardTriggerFor"] }], ngImport: i0 });
|
|
66
66
|
}
|
|
67
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardTrigger, decorators: [{
|
|
68
68
|
type: Directive,
|
|
69
69
|
args: [{
|
|
70
70
|
selector: '[hlmHoverCardTrigger]',
|
|
@@ -97,17 +97,17 @@ const HlmHoverCardImports = [
|
|
|
97
97
|
HlmHoverCardTrigger,
|
|
98
98
|
];
|
|
99
99
|
class HlmHoverCardModule {
|
|
100
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
101
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.
|
|
100
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
101
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardModule, imports: [HlmHoverCardContent,
|
|
102
102
|
HlmHoverCardPortal,
|
|
103
103
|
HlmHoverCard,
|
|
104
104
|
HlmHoverCardTrigger], exports: [HlmHoverCardContent,
|
|
105
105
|
HlmHoverCardPortal,
|
|
106
106
|
HlmHoverCard,
|
|
107
107
|
HlmHoverCardTrigger] });
|
|
108
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.
|
|
108
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardModule });
|
|
109
109
|
}
|
|
110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHoverCardModule, decorators: [{
|
|
111
111
|
type: NgModule,
|
|
112
112
|
args: [{
|
|
113
113
|
imports: [...HlmHoverCardImports],
|
|
@@ -120,4 +120,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
120
120
|
*/
|
|
121
121
|
|
|
122
122
|
export { HlmHoverCard, HlmHoverCardContent, HlmHoverCardImports, HlmHoverCardModule, HlmHoverCardPortal, HlmHoverCardTrigger };
|
|
123
|
-
|
|
123
|
+
|
package/icon/README.md
CHANGED
|
@@ -1,64 +1,240 @@
|
|
|
1
|
-
# Icon
|
|
1
|
+
# Icon (`@egose/shadcn-theme-ng/icon`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`HlmIcon` is a thin directive that sizes `@ng-icons/core` icons consistently with the shadcn theme. It applies to `ng-icon` elements (`selector: 'ng-icon[hlm]'`) and maps t-shirt sizes (`xs`–`xl`) to pixel values via the `--ng-icon__size` CSS variable — the shadcn/ui equivalent of the `size-*` icon convention. A global default size can be set once with `provideHlmIconConfig`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/icon` (plain Tailwind) and `@egose/shadcn-theme-ng-tw/icon` (`tw:`-prefixed variant). See the [package README](../../README.md) for installation, peer dependencies, and the Tailwind-variant contract. Do not publish this project directory independently.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
# Plain Tailwind (no prefix)
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Peer dependencies (Angular, `@ng-icons/core`, …) are documented in the [package README](../../README.md#peer-dependencies). You must also register the icons you use with `provideIcons` from `@ng-icons/core` (see examples).
|
|
14
18
|
|
|
15
|
-
```
|
|
16
|
-
|
|
19
|
+
```ts
|
|
20
|
+
import { HlmIconImports } from '@egose/shadcn-theme-ng/icon';
|
|
21
|
+
// tw variant:
|
|
22
|
+
// import { HlmIconImports } from '@egose/shadcn-theme-ng-tw/icon';
|
|
17
23
|
```
|
|
18
24
|
|
|
19
|
-
##
|
|
25
|
+
## Imports
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
```ts
|
|
28
|
+
// Standalone component — spread the imports array:
|
|
29
|
+
import { HlmIconImports } from '@egose/shadcn-theme-ng/icon';
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
@Component({
|
|
32
|
+
standalone: true,
|
|
33
|
+
imports: [NgIcon, ...HlmIconImports], // or just [NgIcon, HlmIcon]
|
|
34
|
+
providers: [provideIcons({ lucidePlus })],
|
|
35
|
+
template: `<ng-icon hlm name="lucidePlus" size="sm" />`,
|
|
36
|
+
})
|
|
37
|
+
export class MyComp {}
|
|
25
38
|
```
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
```ts
|
|
41
|
+
// NgModule-based — import the module:
|
|
42
|
+
import { HlmIconModule } from '@egose/shadcn-theme-ng/icon';
|
|
28
43
|
|
|
29
|
-
|
|
44
|
+
@NgModule({ imports: [HlmIconModule] })
|
|
45
|
+
export class MyModule {}
|
|
46
|
+
```
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
Exported from `src/public-api.ts`: `HlmIcon`, `IconSize`, `HlmIconConfig`, `provideHlmIconConfig`, `injectHlmIconConfig`, plus `HlmIconImports` and `HlmIconModule`.
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
> Note: `HlmIcon` decorates `ng-icon` — you still import `NgIcon` itself from `@ng-icons/core` and register glyphs with `provideIcons`.
|
|
34
51
|
|
|
35
|
-
|
|
36
|
-
cd dist/icon
|
|
37
|
-
```
|
|
52
|
+
## Anatomy / Structure
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
```html
|
|
55
|
+
<!-- hlm attribute activates the sizing directive on any ng-icon -->
|
|
56
|
+
<ng-icon hlm name="lucidePlus" size="sm" />
|
|
57
|
+
```
|
|
43
58
|
|
|
44
|
-
|
|
59
|
+
The directive sets `[style.--ng-icon__size]` from the `size` input; named sizes resolve to pixels, anything else passes through verbatim as CSS.
|
|
45
60
|
|
|
46
|
-
|
|
61
|
+
## API reference
|
|
47
62
|
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
### `ng-icon[hlm]` — `HlmIcon`
|
|
64
|
+
|
|
65
|
+
| Input | Type | Default | Description |
|
|
66
|
+
| ------ | ---------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
67
|
+
| `size` | `IconSize` | config default (`base`) | `xs` → `12px`, `sm` → `16px`, `base` → `24px`, `lg` → `32px`, `xl` → `48px`, `none` → `none`, or any custom CSS size string (e.g. `'20px'`, `'1.5rem'`). |
|
|
68
|
+
|
|
69
|
+
No outputs. `IconSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | 'none' | (string & {})`.
|
|
70
|
+
|
|
71
|
+
### Config — `HlmIconConfig` / `provideHlmIconConfig` / `injectHlmIconConfig`
|
|
72
|
+
|
|
73
|
+
| API | Signature | Description |
|
|
74
|
+
| ------------------------------------------------------ | ----------------------- | ------------------------------------------------------------------------------------- |
|
|
75
|
+
| `HlmIconConfig` | `{ size: IconSize }` | Global icon config shape (default `{ size: 'base' }`). |
|
|
76
|
+
| `provideHlmIconConfig(config: Partial<HlmIconConfig>)` | returns `ValueProvider` | Provide once (root or feature) to change the default `size` for every `ng-icon[hlm]`. |
|
|
77
|
+
| `injectHlmIconConfig()` | returns `HlmIconConfig` | Reads the ambient config (falls back to defaults). |
|
|
78
|
+
|
|
79
|
+
## Examples
|
|
80
|
+
|
|
81
|
+
### 1. Basic icon with registered glyph
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { Component } from '@angular/core';
|
|
85
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
86
|
+
import { lucidePlus } from '@ng-icons/lucide';
|
|
87
|
+
import { HlmIcon } from '@egose/shadcn-theme-ng/icon';
|
|
88
|
+
|
|
89
|
+
@Component({
|
|
90
|
+
standalone: true,
|
|
91
|
+
imports: [NgIcon, HlmIcon],
|
|
92
|
+
providers: [provideIcons({ lucidePlus })],
|
|
93
|
+
template: `<ng-icon hlm name="lucidePlus" />`,
|
|
94
|
+
})
|
|
95
|
+
export class BasicExample {}
|
|
50
96
|
```
|
|
51
97
|
|
|
52
|
-
|
|
98
|
+
### 2. All named sizes
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { Component } from '@angular/core';
|
|
102
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
103
|
+
import { lucideSearch } from '@ng-icons/lucide';
|
|
104
|
+
import { HlmIconImports } from '@egose/shadcn-theme-ng/icon';
|
|
105
|
+
|
|
106
|
+
@Component({
|
|
107
|
+
standalone: true,
|
|
108
|
+
imports: [NgIcon, HlmIconImports],
|
|
109
|
+
providers: [provideIcons({ lucideSearch })],
|
|
110
|
+
template: `
|
|
111
|
+
<div class="tw:flex tw:items-center tw:gap-4">
|
|
112
|
+
<ng-icon hlm name="lucideSearch" size="xs" />
|
|
113
|
+
<ng-icon hlm name="lucideSearch" size="sm" />
|
|
114
|
+
<ng-icon hlm name="lucideSearch" size="base" />
|
|
115
|
+
<ng-icon hlm name="lucideSearch" size="lg" />
|
|
116
|
+
<ng-icon hlm name="lucideSearch" size="xl" />
|
|
117
|
+
</div>
|
|
118
|
+
`,
|
|
119
|
+
})
|
|
120
|
+
export class SizesExample {}
|
|
121
|
+
```
|
|
53
122
|
|
|
54
|
-
|
|
123
|
+
### 3. Custom CSS sizes (any string passes through)
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { Component } from '@angular/core';
|
|
127
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
128
|
+
import { lucideBell } from '@ng-icons/lucide';
|
|
129
|
+
import { HlmIcon } from '@egose/shadcn-theme-ng/icon';
|
|
130
|
+
|
|
131
|
+
@Component({
|
|
132
|
+
standalone: true,
|
|
133
|
+
imports: [NgIcon, HlmIcon],
|
|
134
|
+
providers: [provideIcons({ lucideBell })],
|
|
135
|
+
template: `
|
|
136
|
+
<div class="tw:flex tw:items-center tw:gap-4">
|
|
137
|
+
<ng-icon hlm name="lucideBell" size="20px" />
|
|
138
|
+
<ng-icon hlm name="lucideBell" size="1.5rem" />
|
|
139
|
+
<ng-icon hlm name="lucideBell" size="none" />
|
|
140
|
+
</div>
|
|
141
|
+
`,
|
|
142
|
+
})
|
|
143
|
+
export class CustomSizeExample {}
|
|
144
|
+
```
|
|
55
145
|
|
|
56
|
-
|
|
57
|
-
|
|
146
|
+
### 4. Global default via `provideHlmIconConfig`
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { Component } from '@angular/core';
|
|
150
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
151
|
+
import { lucideCheck, lucideX } from '@ng-icons/lucide';
|
|
152
|
+
import { HlmIcon, provideHlmIconConfig } from '@egose/shadcn-theme-ng/icon';
|
|
153
|
+
|
|
154
|
+
@Component({
|
|
155
|
+
standalone: true,
|
|
156
|
+
imports: [NgIcon, HlmIcon],
|
|
157
|
+
providers: [provideIcons({ lucideCheck, lucideX }), provideHlmIconConfig({ size: 'sm' })],
|
|
158
|
+
template: `
|
|
159
|
+
<!-- both inherit size="sm" unless overridden -->
|
|
160
|
+
<ng-icon hlm name="lucideCheck" />
|
|
161
|
+
<ng-icon hlm name="lucideX" size="lg" />
|
|
162
|
+
`,
|
|
163
|
+
})
|
|
164
|
+
export class ConfigExample {}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 5. Icons inside buttons and inputs (composition)
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { Component } from '@angular/core';
|
|
171
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
172
|
+
import { lucideSearch, lucidePlus } from '@ng-icons/lucide';
|
|
173
|
+
import { HlmIcon } from '@egose/shadcn-theme-ng/icon';
|
|
174
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
175
|
+
import { HlmInputGroupImports } from '@egose/shadcn-theme-ng/input-group';
|
|
176
|
+
|
|
177
|
+
@Component({
|
|
178
|
+
standalone: true,
|
|
179
|
+
imports: [NgIcon, HlmIcon, HlmButton, HlmInputGroupImports],
|
|
180
|
+
providers: [provideIcons({ lucideSearch, lucidePlus })],
|
|
181
|
+
template: `
|
|
182
|
+
<button hlmBtn type="button"><ng-icon hlm name="lucidePlus" size="sm" /> New item</button>
|
|
183
|
+
|
|
184
|
+
<div hlmInputGroup>
|
|
185
|
+
<span hlmInputGroupText><ng-icon hlm name="lucideSearch" size="sm" /></span>
|
|
186
|
+
<input hlmInputGroupInput placeholder="Search…" aria-label="Search" />
|
|
187
|
+
</div>
|
|
188
|
+
`,
|
|
189
|
+
})
|
|
190
|
+
export class CompositionExample {}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
> The input-group addon styles (`[&>ng-icon…]` hooks) assume icons sized through this directive — prefer `size="sm"` or smaller inside addons/buttons so text and glyph align.
|
|
194
|
+
|
|
195
|
+
### 6. Dynamic icon + size with signals
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { Component, signal } from '@angular/core';
|
|
199
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
200
|
+
import { lucideLoaderCircle, lucideCheck } from '@ng-icons/lucide';
|
|
201
|
+
import { HlmIcon, type IconSize } from '@egose/shadcn-theme-ng/icon';
|
|
202
|
+
|
|
203
|
+
@Component({
|
|
204
|
+
standalone: true,
|
|
205
|
+
imports: [NgIcon, HlmIcon],
|
|
206
|
+
providers: [provideIcons({ lucideLoaderCircle, lucideCheck })],
|
|
207
|
+
template: `
|
|
208
|
+
<p>
|
|
209
|
+
<ng-icon hlm [name]="saving() ? 'lucideLoaderCircle' : 'lucideCheck'" [size]="iconSize()" />
|
|
210
|
+
{{ saving() ? 'Saving…' : 'Saved' }}
|
|
211
|
+
</p>
|
|
212
|
+
<button type="button" (click)="toggleSize()">Toggle size</button>
|
|
213
|
+
`,
|
|
214
|
+
})
|
|
215
|
+
export class DynamicExample {
|
|
216
|
+
readonly saving = signal(true);
|
|
217
|
+
readonly iconSize = signal<IconSize>('sm');
|
|
218
|
+
|
|
219
|
+
toggleSize() {
|
|
220
|
+
this.iconSize.update((s) => (s === 'sm' ? 'lg' : 'sm'));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
58
223
|
```
|
|
59
224
|
|
|
60
|
-
|
|
225
|
+
## Accessibility notes
|
|
226
|
+
|
|
227
|
+
- `ng-icon` renders decorative SVG — screen readers ignore it by default. When an icon is the _only_ content of a button/link, put the accessible name on the control (`aria-label="Search"`), not on the icon.
|
|
228
|
+
- Never convey status by icon alone (e.g. a lone red `x` for errors); pair it with text or an `role="status"` message.
|
|
229
|
+
- Icon buttons need a visible focus indicator and at least a 24px (ideally 44px) hit area — use the button size variants rather than shrinking the control to the glyph.
|
|
230
|
+
|
|
231
|
+
## Theming / CSS variables
|
|
232
|
+
|
|
233
|
+
Sizing flows through the `--ng-icon__size` CSS variable set by the directive; color inherits `currentColor`, so icons follow surrounding text/foreground tokens automatically. No component-specific theme variables.
|
|
61
234
|
|
|
62
|
-
##
|
|
235
|
+
## Related subpaths
|
|
63
236
|
|
|
64
|
-
|
|
237
|
+
- `@egose/shadcn-theme-ng/button` — icon buttons and icon+label composition.
|
|
238
|
+
- `@egose/shadcn-theme-ng/input-group` — addon slots with `ng-icon` styling hooks.
|
|
239
|
+
- `@egose/shadcn-theme-ng/badge` — common icon+text pill composition.
|
|
240
|
+
- `@egose/shadcn-theme-ng/spinner` — animated loading indicator alternative.
|