@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.
Files changed (244) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +20 -20
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +18 -18
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
  8. package/alert-dialog/types/alert-dialog.d.ts +1 -1
  9. package/aspect-ratio/README.md +272 -5
  10. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  11. package/autocomplete/README.md +473 -34
  12. package/autocomplete/fesm2022/autocomplete.mjs +54 -54
  13. package/autocomplete/types/autocomplete.d.ts +1 -1
  14. package/avatar/README.md +357 -5
  15. package/avatar/fesm2022/avatar.mjs +32 -32
  16. package/badge/README.md +289 -34
  17. package/badge/fesm2022/badge.mjs +4 -4
  18. package/basic-alert/README.md +324 -34
  19. package/basic-alert/fesm2022/basic-alert.mjs +4 -4
  20. package/basic-alert/types/basic-alert.d.ts +1 -1
  21. package/breadcrumb/README.md +406 -5
  22. package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
  23. package/button/README.md +453 -34
  24. package/button/fesm2022/button.mjs +96 -118
  25. package/button/types/button.d.ts +7 -10
  26. package/button-group/README.md +318 -5
  27. package/button-group/fesm2022/button-group.mjs +20 -20
  28. package/calendar/README.md +328 -34
  29. package/calendar/fesm2022/calendar.mjs +154 -154
  30. package/card/README.md +331 -5
  31. package/card/fesm2022/card.mjs +33 -33
  32. package/carousel/README.md +333 -5
  33. package/carousel/fesm2022/carousel.mjs +47 -44
  34. package/carousel/types/carousel.d.ts +1 -1
  35. package/checkbox/README.md +291 -34
  36. package/checkbox/fesm2022/checkbox.mjs +22 -20
  37. package/checkbox/types/checkbox.d.ts +5 -4
  38. package/collapsible/README.md +332 -5
  39. package/collapsible/fesm2022/collapsible.mjs +15 -15
  40. package/combobox/README.md +507 -5
  41. package/combobox/fesm2022/combobox.mjs +95 -92
  42. package/combobox/types/combobox.d.ts +1 -1
  43. package/command/README.md +435 -5
  44. package/command/fesm2022/command.mjs +56 -56
  45. package/confirmation-dialog/README.md +272 -34
  46. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
  47. package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
  48. package/context-menu/README.md +366 -5
  49. package/context-menu/fesm2022/context-menu.mjs +9 -9
  50. package/date-picker/README.md +436 -34
  51. package/date-picker/fesm2022/date-picker.mjs +79 -68
  52. package/date-picker/types/date-picker.d.ts +8 -4
  53. package/dialog/README.md +419 -34
  54. package/dialog/fesm2022/dialog.mjs +48 -48
  55. package/drawer/README.md +395 -5
  56. package/drawer/fesm2022/drawer.mjs +45 -45
  57. package/dropdown-menu/README.md +417 -5
  58. package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
  59. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  60. package/empty/README.md +329 -5
  61. package/empty/fesm2022/empty.mjs +31 -31
  62. package/field/README.md +385 -5
  63. package/field/fesm2022/field.mjs +59 -59
  64. package/field/types/field.d.ts +1 -1
  65. package/form-checkbox/README.md +283 -34
  66. package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
  67. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  68. package/form-date-picker/README.md +293 -34
  69. package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
  70. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  71. package/form-field/README.md +327 -34
  72. package/form-field/fesm2022/form-field.mjs +30 -16
  73. package/form-field/types/form-field.d.ts +28 -20
  74. package/form-field-simple/README.md +311 -34
  75. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  76. package/form-searchable-multiselect/README.md +332 -34
  77. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
  78. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
  79. package/form-select/README.md +321 -34
  80. package/form-select/fesm2022/form-select.mjs +62 -29
  81. package/form-select/types/form-select.d.ts +7 -1
  82. package/form-text-input/README.md +342 -34
  83. package/form-text-input/fesm2022/form-text-input.mjs +43 -55
  84. package/form-text-input/types/form-text-input.d.ts +9 -12
  85. package/form-textarea/README.md +318 -34
  86. package/form-textarea/fesm2022/form-textarea.mjs +42 -23
  87. package/form-textarea/types/form-textarea.d.ts +8 -1
  88. package/hover-card/README.md +256 -5
  89. package/hover-card/fesm2022/hover-card.mjs +19 -19
  90. package/icon/README.md +210 -34
  91. package/icon/fesm2022/icon.mjs +8 -8
  92. package/input/README.md +240 -34
  93. package/input/fesm2022/input.mjs +17 -12
  94. package/input/types/input.d.ts +2 -1
  95. package/input-group/README.md +335 -5
  96. package/input-group/fesm2022/input-group.mjs +37 -37
  97. package/input-group/types/input-group.d.ts +3 -3
  98. package/input-otp/README.md +375 -5
  99. package/input-otp/fesm2022/input-otp.mjs +27 -27
  100. package/item/README.md +385 -5
  101. package/item/fesm2022/item.mjs +54 -54
  102. package/kbd/README.md +291 -5
  103. package/kbd/fesm2022/kbd.mjs +13 -13
  104. package/label/README.md +243 -34
  105. package/label/fesm2022/label.mjs +9 -9
  106. package/label/types/label.d.ts +1 -1
  107. package/layout-simple/README.md +174 -44
  108. package/layout-simple/fesm2022/layout-simple.mjs +917 -398
  109. package/layout-simple/types/layout-simple.d.ts +180 -129
  110. package/menu/README.md +418 -0
  111. package/menu/fesm2022/menu.mjs +461 -0
  112. package/menu/package.json +24 -0
  113. package/menu/types/menu.d.ts +137 -0
  114. package/menubar/README.md +343 -5
  115. package/menubar/fesm2022/menubar.mjs +13 -13
  116. package/native-select/README.md +323 -5
  117. package/native-select/fesm2022/native-select.mjs +19 -19
  118. package/navigation-menu/README.md +369 -5
  119. package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
  120. package/package.json +183 -154
  121. package/pagination/README.md +388 -5
  122. package/pagination/fesm2022/pagination.mjs +63 -63
  123. package/popover/README.md +302 -34
  124. package/popover/fesm2022/popover.mjs +30 -30
  125. package/progress/README.md +311 -5
  126. package/progress/fesm2022/progress.mjs +13 -13
  127. package/radio-group/README.md +335 -34
  128. package/radio-group/fesm2022/radio-group.mjs +26 -19
  129. package/resizable/README.md +269 -5
  130. package/resizable/fesm2022/resizable.mjs +19 -19
  131. package/scroll-area/README.md +233 -5
  132. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  133. package/searchable-multiselect/README.md +294 -34
  134. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
  135. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  136. package/select/README.md +408 -34
  137. package/select/fesm2022/select.mjs +80 -72
  138. package/select/types/select.d.ts +3 -1
  139. package/separator/README.md +193 -34
  140. package/separator/fesm2022/separator.mjs +9 -9
  141. package/separator/types/separator.d.ts +1 -1
  142. package/sheet/README.md +282 -34
  143. package/sheet/fesm2022/sheet.mjs +30 -30
  144. package/sidebar/README.md +457 -5
  145. package/sidebar/fesm2022/sidebar.mjs +136 -134
  146. package/sidebar/types/sidebar.d.ts +3 -3
  147. package/skeleton/README.md +217 -5
  148. package/skeleton/fesm2022/skeleton.mjs +9 -9
  149. package/slider/README.md +273 -5
  150. package/slider/fesm2022/slider.mjs +29 -25
  151. package/sonner/README.md +317 -34
  152. package/sonner/fesm2022/sonner.mjs +9 -9
  153. package/spinner/README.md +255 -34
  154. package/spinner/fesm2022/spinner.mjs +8 -8
  155. package/switch/README.md +281 -34
  156. package/switch/fesm2022/switch.mjs +12 -14
  157. package/table/README.md +423 -5
  158. package/table/fesm2022/table.mjs +41 -41
  159. package/tabs/README.md +382 -34
  160. package/tabs/fesm2022/tabs.mjs +48 -38
  161. package/textarea/README.md +282 -5
  162. package/textarea/fesm2022/textarea.mjs +9 -9
  163. package/toggle/README.md +270 -5
  164. package/toggle/fesm2022/toggle.mjs +14 -14
  165. package/toggle-group/README.md +340 -5
  166. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  167. package/toggle-group/types/toggle-group.d.ts +13 -7
  168. package/tooltip/README.md +240 -34
  169. package/tooltip/fesm2022/tooltip.mjs +14 -14
  170. package/typography/README.md +271 -5
  171. package/typography/fesm2022/typography.mjs +53 -53
  172. package/typography/types/typography.d.ts +12 -12
  173. package/utils/README.md +274 -34
  174. package/utils/fesm2022/utils.mjs +68 -44
  175. package/accordion/fesm2022/accordion.mjs.map +0 -1
  176. package/alert/fesm2022/alert.mjs.map +0 -1
  177. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  178. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  179. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  180. package/avatar/fesm2022/avatar.mjs.map +0 -1
  181. package/badge/fesm2022/badge.mjs.map +0 -1
  182. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  183. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  184. package/button/fesm2022/button.mjs.map +0 -1
  185. package/button-group/fesm2022/button-group.mjs.map +0 -1
  186. package/calendar/fesm2022/calendar.mjs.map +0 -1
  187. package/card/fesm2022/card.mjs.map +0 -1
  188. package/carousel/fesm2022/carousel.mjs.map +0 -1
  189. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  190. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  191. package/combobox/fesm2022/combobox.mjs.map +0 -1
  192. package/command/fesm2022/command.mjs.map +0 -1
  193. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  194. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  195. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  196. package/dialog/fesm2022/dialog.mjs.map +0 -1
  197. package/drawer/fesm2022/drawer.mjs.map +0 -1
  198. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  199. package/empty/fesm2022/empty.mjs.map +0 -1
  200. package/field/fesm2022/field.mjs.map +0 -1
  201. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  202. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  203. package/form-field/fesm2022/form-field.mjs.map +0 -1
  204. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  205. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  206. package/form-select/fesm2022/form-select.mjs.map +0 -1
  207. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  208. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  209. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  210. package/icon/fesm2022/icon.mjs.map +0 -1
  211. package/input/fesm2022/input.mjs.map +0 -1
  212. package/input-group/fesm2022/input-group.mjs.map +0 -1
  213. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  214. package/item/fesm2022/item.mjs.map +0 -1
  215. package/kbd/fesm2022/kbd.mjs.map +0 -1
  216. package/label/fesm2022/label.mjs.map +0 -1
  217. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  218. package/menubar/fesm2022/menubar.mjs.map +0 -1
  219. package/native-select/fesm2022/native-select.mjs.map +0 -1
  220. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  221. package/pagination/fesm2022/pagination.mjs.map +0 -1
  222. package/popover/fesm2022/popover.mjs.map +0 -1
  223. package/progress/fesm2022/progress.mjs.map +0 -1
  224. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  225. package/resizable/fesm2022/resizable.mjs.map +0 -1
  226. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  227. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  228. package/select/fesm2022/select.mjs.map +0 -1
  229. package/separator/fesm2022/separator.mjs.map +0 -1
  230. package/sheet/fesm2022/sheet.mjs.map +0 -1
  231. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  232. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  233. package/slider/fesm2022/slider.mjs.map +0 -1
  234. package/sonner/fesm2022/sonner.mjs.map +0 -1
  235. package/spinner/fesm2022/spinner.mjs.map +0 -1
  236. package/switch/fesm2022/switch.mjs.map +0 -1
  237. package/table/fesm2022/table.mjs.map +0 -1
  238. package/tabs/fesm2022/tabs.mjs.map +0 -1
  239. package/textarea/fesm2022/textarea.mjs.map +0 -1
  240. package/toggle/fesm2022/toggle.mjs.map +0 -1
  241. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  242. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  243. package/typography/fesm2022/typography.mjs.map +0 -1
  244. package/utils/fesm2022/utils.mjs.map +0 -1
package/menu/README.md ADDED
@@ -0,0 +1,418 @@
1
+ # Menu (`@egose/shadcn-theme-ng/menu`)
2
+
3
+ Headless menu building blocks (CDK `CdkMenu` family) with shadcn styling: container, bar, items, checkbox/radio items, indicators, labels, separators, shortcuts, and sub-menus. This is the styling/behavior layer underneath `dropdown-menu`, `context-menu`, and `menubar` — use it directly when you need a custom menu surface (e.g. an always-visible `hlm-menu-bar` toolbar or a CDK-triggered floating menu) rather than one of the opinionated wrappers.
4
+
5
+ Ships as `@egose/shadcn-theme-ng/menu` and `@egose/shadcn-theme-ng-tw/menu` (tw: variant). See the [package README](../../README.md) for installation, peer dependencies, Tailwind setup, and testing. Do not publish this project directory independently.
6
+
7
+ ## Installation
8
+
9
+ ```bash
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 are inherited from the package root (see [package README](../../README.md)). This subpath itself declares `@angular/common`, `@angular/core` as peers plus a `tslib` runtime dependency; at runtime it also uses `@angular/cdk/menu` and `@egose/shadcn-theme-ng/icon` / `.../utils`. No extra install step is needed beyond the package install above.
18
+
19
+ ## Imports
20
+
21
+ Real exported symbols (from `src/public-api.ts`):
22
+
23
+ ```ts
24
+ import {
25
+ HlmMenu,
26
+ HlmSubMenu,
27
+ HlmMenuBar,
28
+ HlmMenuBarItem,
29
+ HlmMenuGroup,
30
+ HlmMenuItem,
31
+ HlmMenuItemCheck,
32
+ HlmMenuItemCheckbox,
33
+ HlmMenuItemIcon,
34
+ HlmMenuItemRadio,
35
+ HlmMenuItemRadioIndicator,
36
+ HlmMenuItemSubIndicator,
37
+ HlmMenuLabel,
38
+ HlmMenuSeparator,
39
+ HlmMenuShortcut,
40
+ menuVariants, // cva variants for HlmMenu
41
+ HlmMenuItemImports, // items + icons + checks + shortcuts
42
+ HlmMenuStructureImports, // [HlmMenuLabel, HlmMenuSeparator]
43
+ HlmMenuImports, // item + structure + HlmMenu + HlmSubMenu
44
+ HlmMenuBarImports, // HlmMenuImports + HlmMenuBar + HlmMenuBarItem
45
+ HlmMenuItemModule,
46
+ HlmMenuModule,
47
+ HlmMenuBarModule,
48
+ } from '@egose/shadcn-theme-ng/menu';
49
+ ```
50
+
51
+ Standalone usage (full bar):
52
+
53
+ ```ts
54
+ import { Component } from '@angular/core';
55
+ import { HlmMenuBarImports } from '@egose/shadcn-theme-ng/menu';
56
+
57
+ @Component({
58
+ selector: 'app-demo',
59
+ standalone: true,
60
+ imports: [...HlmMenuBarImports],
61
+ template: `
62
+ <hlm-menu-bar>
63
+ <button hlmMenuBarItem>File</button>
64
+ </hlm-menu-bar>
65
+ `,
66
+ })
67
+ export class DemoComponent {}
68
+ ```
69
+
70
+ Standalone usage (floating menu only):
71
+
72
+ ```ts
73
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
74
+
75
+ @Component({
76
+ standalone: true,
77
+ imports: [...HlmMenuImports],
78
+ template: `
79
+ <hlm-menu>
80
+ <hlm-menu-label>Actions</hlm-menu-label>
81
+ <button hlmMenuItem>Edit</button>
82
+ </hlm-menu>
83
+ `,
84
+ })
85
+ export class MenuOnlyComponent {}
86
+ ```
87
+
88
+ NgModule usage:
89
+
90
+ ```ts
91
+ import { NgModule } from '@angular/core';
92
+ import { HlmMenuModule, HlmMenuBarModule, HlmMenuItemModule } from '@egose/shadcn-theme-ng/menu';
93
+
94
+ @NgModule({ imports: [HlmMenuModule, HlmMenuBarModule, HlmMenuItemModule] })
95
+ export class DemoModule {}
96
+ ```
97
+
98
+ For the `tw:` build, swap the specifier to `@egose/shadcn-theme-ng-tw/menu`. Symbol names are identical.
99
+
100
+ ## Anatomy / Structure
101
+
102
+ ```html
103
+ <!-- Static bar -->
104
+ <hlm-menu-bar>
105
+ <button hlmMenuBarItem [cdkMenuTriggerFor]="fileMenu">File</button>
106
+ </hlm-menu-bar>
107
+
108
+ <!-- Floating menu (anchored via CDK trigger) -->
109
+ <ng-template #fileMenu>
110
+ <hlm-menu variant="default">
111
+ <hlm-menu-label>File</hlm-menu-label>
112
+ <button hlmMenuItem>
113
+ <ng-icon hlmMenuIcon name="lucidePencil" />
114
+ Rename
115
+ <hlm-menu-shortcut>⌘R</hlm-menu-shortcut>
116
+ </button>
117
+ <button hlmMenuItem variant="destructive">Delete</button>
118
+ <hlm-menu-separator />
119
+ <hlm-menu-group>
120
+ <button hlmMenuItemCheckbox>
121
+ <hlm-menu-item-check />
122
+ Word wrap
123
+ </button>
124
+ <button hlmMenuItemRadio>
125
+ <hlm-menu-item-radio />
126
+ Option A
127
+ </button>
128
+ </hlm-menu-group>
129
+ <button hlmMenuItem>
130
+ More
131
+ <hlm-menu-item-sub-indicator />
132
+ </button>
133
+ </hlm-menu>
134
+ </ng-template>
135
+
136
+ <hlm-sub-menu><!-- nested submenu surface --></hlm-sub-menu>
137
+ ```
138
+
139
+ | Class | Selector | Element | Role |
140
+ | --------------------------- | ----------------------------- | ------------------------------ | ---------------------------------------------- |
141
+ | `HlmMenu` | `hlm-menu` | component | Floating menu surface (`CdkMenu`) |
142
+ | `HlmSubMenu` | `hlm-sub-menu` | component | Nested submenu surface (`CdkMenu`) |
143
+ | `HlmMenuBar` | `hlm-menu-bar` | component | Static bar (`CdkMenuBar`) |
144
+ | `HlmMenuBarItem` | `[hlmMenuBarItem]` | any (usually `<button>`) | Bar item (`CdkMenuItem`) |
145
+ | `HlmMenuItem` | `[hlmMenuItem]` | any (usually `<button>`/`<a>`) | Menu row (`CdkMenuItem`) |
146
+ | `HlmMenuGroup` | `hlm-menu-group` | component | Grouping (`CdkMenuGroup`) |
147
+ | `HlmMenuLabel` | `hlm-menu-label` | component | Section heading |
148
+ | `HlmMenuSeparator` | `hlm-menu-separator` | component | Divider |
149
+ | `HlmMenuShortcut` | `hlm-menu-shortcut` | component | Right-aligned hint text |
150
+ | `HlmMenuItemIcon` | `[hlmMenuIcon]` | icon host | Leading-icon sizing (`sm` icon config) |
151
+ | `HlmMenuItemCheckbox` | `[hlmMenuItemCheckbox]` | any | Checkable row (`CdkMenuItemCheckbox`) |
152
+ | `HlmMenuItemRadio` | `[hlmMenuItemRadio]` | any | Radio row (`CdkMenuItemRadio`) |
153
+ | `HlmMenuItemCheck` | `hlm-menu-item-check` | component | Check glyph (shows when parent has `.checked`) |
154
+ | `HlmMenuItemRadioIndicator` | `hlm-menu-item-radio` (!) | component | Dot glyph (shows when parent has `.checked`) |
155
+ | `HlmMenuItemSubIndicator` | `hlm-menu-item-sub-indicator` | component | Chevron-right for submenu parents |
156
+
157
+ > API surprise: the radio indicator's selector is `hlm-menu-item-radio` while its class is `HlmMenuItemRadioIndicator`. The attribute directive `[hlmMenuItemRadio]` (class `HlmMenuItemRadio`) is the _row_; the element `<hlm-menu-item-radio>` is the _dot_. Read selectors carefully when composing radio rows.
158
+
159
+ CDK passthroughs (via `hostDirectives`): `HlmMenuItem` forwards `cdkMenuItemDisabled: disabled` input and `cdkMenuItemTriggered: triggered` output; checkbox/radio variants forward `disabled`/`checked` inputs and `triggered` outputs. `menuVariants` exposes `variant: 'default' | 'menubar'` (`default` adds `my-0.5`, `menubar` adds `my-2`).
160
+
161
+ ## API reference
162
+
163
+ | Selector | Inputs | Notes |
164
+ | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
165
+ | `hlm-menu` (`HlmMenu`) | `variant: 'default' \| 'menubar'` (default `'default'`), `class` | `menuVariants({ variant })` merged with `class` |
166
+ | `hlm-sub-menu` (`HlmSubMenu`) | `class` | Static popover-look surface |
167
+ | `hlm-menu-bar` (`HlmMenuBar`) | `class` | `h-9` bar, `rounded-md border shadow-xs` |
168
+ | `[hlmMenuBarItem]` | `class` | Forwards full `CdkMenuItem` API via host directive |
169
+ | `[hlmMenuItem]` | `variant: 'default' \| 'destructive'` (default `'default'`), `inset: boolean` (default `false`), `class`; CDK `disabled` input + `triggered` output | `data-variant` / `data-inset` reflected; `inset` adds `pl-8` for icon-less alignment |
170
+ | `hlm-menu-label` | `inset: boolean` (default `false`), `class` | `data-inset` reflected; semibold section text |
171
+ | `hlm-menu-separator` | `class` | `h-px bg-border` |
172
+ | `hlm-menu-shortcut` | `class` | `ml-auto text-xs tracking-widest text-muted-foreground` |
173
+ | `[hlmMenuIcon]` | `class` | Provides `sm` icon config; adds `mr-2` |
174
+ | `[hlmMenuItemCheckbox]` / `[hlmMenuItemRadio]` | `class`; CDK `disabled`/`checked` inputs, `triggered` output | Rows reserve `pl-8` for the indicator |
175
+ | `hlm-menu-item-check` | `class` | Check icon; `opacity-0` until ancestor has `.checked` |
176
+ | `hlm-menu-item-radio` (indicator) | `class` | Dot icon; same `.checked` reveal rule |
177
+ | `hlm-menu-item-sub-indicator` | `class` | Chevron-right, `ml-auto size-4` |
178
+ | `hlm-menu-group` | — | `CdkMenuGroup` only |
179
+
180
+ Every `class` input above is `input<ClassValue>('', { alias: 'class' })` merged after the base classes via `hlm()`.
181
+
182
+ ## Examples
183
+
184
+ ### 1. Static menu bar + floating menu (CDK triggers)
185
+
186
+ ```ts
187
+ import { Component } from '@angular/core';
188
+ import { CdkMenuTrigger, CdkMenuModule } from '@angular/cdk/menu';
189
+ import { HlmMenuBarImports } from '@egose/shadcn-theme-ng/menu';
190
+
191
+ @Component({
192
+ selector: 'app-menu-bar',
193
+ standalone: true,
194
+ imports: [CdkMenuModule, CdkMenuTrigger, ...HlmMenuBarImports],
195
+ template: `
196
+ <hlm-menu-bar>
197
+ <button hlmMenuBarItem [cdkMenuTriggerFor]="fileTpl">File</button>
198
+ <button hlmMenuBarItem [cdkMenuTriggerFor]="editTpl">Edit</button>
199
+ </hlm-menu-bar>
200
+
201
+ <ng-template #fileTpl>
202
+ <hlm-menu>
203
+ <hlm-menu-label>File</hlm-menu-label>
204
+ <button hlmMenuItem (cdkMenuItemTriggered)="onNew()">New file</button>
205
+ <button hlmMenuItem>Open…</button>
206
+ <hlm-menu-separator />
207
+ <button hlmMenuItem variant="destructive" (cdkMenuItemTriggered)="onDelete()">Delete</button>
208
+ </hlm-menu>
209
+ </ng-template>
210
+
211
+ <ng-template #editTpl>
212
+ <hlm-menu>
213
+ <button hlmMenuItem>Undo</button>
214
+ <button hlmMenuItem>Redo</button>
215
+ </hlm-menu>
216
+ </ng-template>
217
+ `,
218
+ })
219
+ export class MenuBarComponent {
220
+ onNew(): void {
221
+ console.log('new file');
222
+ }
223
+ onDelete(): void {
224
+ console.log('delete');
225
+ }
226
+ }
227
+ ```
228
+
229
+ ### 2. Variants, inset, shortcuts, icons
230
+
231
+ ```ts
232
+ import { Component } from '@angular/core';
233
+ import { NgIcon, provideIcons } from '@ng-icons/core';
234
+ import { lucidePencil, lucideTrash } from '@ng-icons/lucide';
235
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
236
+
237
+ @Component({
238
+ selector: 'app-menu-variants',
239
+ standalone: true,
240
+ imports: [NgIcon, ...HlmMenuImports],
241
+ providers: [provideIcons({ lucidePencil, lucideTrash })],
242
+ template: `
243
+ <hlm-menu>
244
+ <hlm-menu-label>Actions</hlm-menu-label>
245
+ <button hlmMenuItem>
246
+ <ng-icon hlmMenuIcon name="lucidePencil" />
247
+ Rename
248
+ <hlm-menu-shortcut>⌘R</hlm-menu-shortcut>
249
+ </button>
250
+ <button hlmMenuItem inset>Aligned without icon</button>
251
+ <button hlmMenuItem variant="destructive">
252
+ <ng-icon hlmMenuIcon name="lucideTrash" />
253
+ Delete
254
+ <hlm-menu-shortcut>⌫</hlm-menu-shortcut>
255
+ </button>
256
+ </hlm-menu>
257
+ `,
258
+ })
259
+ export class MenuVariantsComponent {}
260
+ ```
261
+
262
+ ### 3. Checkbox and radio rows
263
+
264
+ ```ts
265
+ import { Component, signal } from '@angular/core';
266
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
267
+
268
+ @Component({
269
+ selector: 'app-menu-checks',
270
+ standalone: true,
271
+ imports: [...HlmMenuImports],
272
+ template: `
273
+ <hlm-menu>
274
+ <hlm-menu-label inset>View</hlm-menu-label>
275
+ <hlm-menu-group>
276
+ <button hlmMenuItemCheckbox [cdkMenuItemChecked]="wordWrap()" (cdkMenuItemTriggered)="toggleWrap()">
277
+ <hlm-menu-item-check />
278
+ Word wrap
279
+ </button>
280
+ <button hlmMenuItemCheckbox [cdkMenuItemChecked]="minimap()" (cdkMenuItemTriggered)="toggleMap()">
281
+ <hlm-menu-item-check />
282
+ Minimap
283
+ </button>
284
+ </hlm-menu-group>
285
+ <hlm-menu-separator />
286
+ <hlm-menu-label inset>Theme</hlm-menu-label>
287
+ <hlm-menu-group>
288
+ <button hlmMenuItemRadio [cdkMenuItemChecked]="theme() === 'light'" (cdkMenuItemTriggered)="theme.set('light')">
289
+ <hlm-menu-item-radio />
290
+ Light
291
+ </button>
292
+ <button hlmMenuItemRadio [cdkMenuItemChecked]="theme() === 'dark'" (cdkMenuItemTriggered)="theme.set('dark')">
293
+ <hlm-menu-item-radio />
294
+ Dark
295
+ </button>
296
+ </hlm-menu-group>
297
+ </hlm-menu>
298
+ `,
299
+ })
300
+ export class MenuChecksComponent {
301
+ readonly wordWrap = signal(true);
302
+ readonly minimap = signal(false);
303
+ readonly theme = signal<'light' | 'dark'>('light');
304
+
305
+ toggleWrap(): void {
306
+ this.wordWrap.update((v) => !v);
307
+ }
308
+ toggleMap(): void {
309
+ this.minimap.update((v) => !v);
310
+ }
311
+ }
312
+ ```
313
+
314
+ > The check/dot indicators reveal via the CDK-added `.checked` class (`group-[.checked]:opacity-100`). Bind `[cdkMenuItemChecked]` — the `checked` alias exposed through the host directive — and toggle on `(cdkMenuItemTriggered)` (exposed as `triggered`).
315
+
316
+ ### 4. Submenu with indicator
317
+
318
+ ```ts
319
+ import { Component } from '@angular/core';
320
+ import { CdkMenuModule } from '@angular/cdk/menu';
321
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
322
+
323
+ @Component({
324
+ selector: 'app-menu-sub',
325
+ standalone: true,
326
+ imports: [CdkMenuModule, ...HlmMenuImports],
327
+ template: `
328
+ <hlm-menu>
329
+ <button hlmMenuItem [cdkMenuTriggerFor]="shareTpl">
330
+ Share
331
+ <hlm-menu-item-sub-indicator />
332
+ </button>
333
+ </hlm-menu>
334
+
335
+ <ng-template #shareTpl>
336
+ <hlm-sub-menu>
337
+ <button hlmMenuItem>Email</button>
338
+ <button hlmMenuItem>Copy link</button>
339
+ </hlm-sub-menu>
340
+ </ng-template>
341
+ `,
342
+ })
343
+ export class MenuSubComponent {}
344
+ ```
345
+
346
+ ### 5. Menubar-variant floating menu + disabled rows
347
+
348
+ ```ts
349
+ import { Component } from '@angular/core';
350
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
351
+
352
+ @Component({
353
+ selector: 'app-menu-menubar-variant',
354
+ standalone: true,
355
+ imports: [...HlmMenuImports],
356
+ template: `
357
+ <hlm-menu variant="menubar">
358
+ <hlm-menu-label>Help</hlm-menu-label>
359
+ <button hlmMenuItem>Documentation</button>
360
+ <button hlmMenuItem [cdkMenuItemDisabled]="true">Release notes (soon)</button>
361
+ </hlm-menu>
362
+ `,
363
+ })
364
+ export class MenuMenubarVariantComponent {}
365
+ ```
366
+
367
+ Note: `variant="menubar"` on `hlm-menu` only adjusts vertical margin (`my-2` vs `my-0.5`); it does not wire menubar behavior — pair it with `hlm-menu-bar` / `HlmMenubar` triggers as in example 1 for the real thing.
368
+
369
+ ### 6. Async list + programmatic template menu
370
+
371
+ ```ts
372
+ import { Component, signal } from '@angular/core';
373
+ import { HlmMenuImports } from '@egose/shadcn-theme-ng/menu';
374
+
375
+ @Component({
376
+ selector: 'app-menu-async',
377
+ standalone: true,
378
+ imports: [...HlmMenuImports],
379
+ template: `
380
+ <hlm-menu>
381
+ <hlm-menu-label>Recent files</hlm-menu-label>
382
+ @for (f of files(); track f) {
383
+ <button hlmMenuItem (cdkMenuItemTriggered)="open(f)">
384
+ {{ f }}
385
+ <hlm-menu-shortcut>{{ $index + 1 }}</hlm-menu-shortcut>
386
+ </button>
387
+ } @empty {
388
+ <hlm-menu-label>No recent files</hlm-menu-label>
389
+ }
390
+ </hlm-menu>
391
+ `,
392
+ })
393
+ export class MenuAsyncComponent {
394
+ readonly files = signal<string[]>(['proposal.docx', 'budget.xlsx', 'notes.md']);
395
+
396
+ open(name: string): void {
397
+ console.log('open', name);
398
+ }
399
+ }
400
+ ```
401
+
402
+ ## Accessibility notes
403
+
404
+ - CDK `CdkMenu`/`CdkMenuBar` own roving-focus, arrow-key navigation, typeahead, and `aria` roles — keep the prescribed nesting (`menu-bar` → trigger → `menu` → items) so keyboard behavior holds.
405
+ - Use `hlm-menu-label` for headings and `hlm-menu-separator` for dividers rather than disabled items; separators are presentational, labels are announced.
406
+ - `variant="destructive"` is color-only — pair destructive actions with explicit text ("Delete") and, for irreversible actions, a confirmation step.
407
+ - Disabled rows (`[cdkMenuItemDisabled]`) are skipped by arrow navigation and announced as disabled.
408
+
409
+ ## Theming / CSS variables
410
+
411
+ No theming inputs. Surfaces use `bg-popover text-popover-foreground border shadow-md` and items use `hover:bg-secondary`; all flow from shadcn tokens. Extend per-instance via `class`.
412
+
413
+ ## Related subpaths
414
+
415
+ - `@egose/shadcn-theme-ng/dropdown-menu` — opinionated trigger + menu wrapper built on this layer.
416
+ - `@egose/shadcn-theme-ng/context-menu` — right-click variant of the same CDK foundation.
417
+ - `@egose/shadcn-theme-ng/menubar` — desktop app-style menu bar with its own trigger primitive.
418
+ - `@egose/shadcn-theme-ng/icon` — `HlmMenuItemIcon` consumes its `sm` icon config.