@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.
Files changed (237) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +27 -39
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +47 -47
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +47 -47
  8. package/aspect-ratio/README.md +272 -5
  9. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  10. package/autocomplete/README.md +473 -34
  11. package/autocomplete/fesm2022/autocomplete.mjs +53 -71
  12. package/avatar/README.md +357 -5
  13. package/avatar/fesm2022/avatar.mjs +32 -32
  14. package/badge/README.md +289 -34
  15. package/badge/fesm2022/badge.mjs +57 -57
  16. package/basic-alert/README.md +324 -34
  17. package/basic-alert/fesm2022/basic-alert.mjs +6 -18
  18. package/breadcrumb/README.md +406 -5
  19. package/breadcrumb/fesm2022/breadcrumb.mjs +33 -39
  20. package/button/README.md +453 -34
  21. package/button/fesm2022/button.mjs +147 -219
  22. package/button/types/button.d.ts +7 -10
  23. package/button-group/README.md +318 -5
  24. package/button-group/fesm2022/button-group.mjs +20 -20
  25. package/calendar/README.md +328 -34
  26. package/calendar/fesm2022/calendar.mjs +29 -743
  27. package/card/README.md +331 -5
  28. package/card/fesm2022/card.mjs +33 -33
  29. package/carousel/README.md +333 -5
  30. package/carousel/fesm2022/carousel.mjs +39 -78
  31. package/checkbox/README.md +291 -34
  32. package/checkbox/fesm2022/checkbox.mjs +20 -58
  33. package/checkbox/types/checkbox.d.ts +5 -4
  34. package/collapsible/README.md +332 -5
  35. package/collapsible/fesm2022/collapsible.mjs +15 -15
  36. package/combobox/README.md +507 -5
  37. package/combobox/fesm2022/combobox.mjs +91 -224
  38. package/command/README.md +435 -5
  39. package/command/fesm2022/command.mjs +49 -109
  40. package/confirmation-dialog/README.md +272 -34
  41. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +15 -40
  42. package/confirmation-dialog/types/confirmation-dialog.d.ts +8 -4
  43. package/context-menu/README.md +366 -5
  44. package/context-menu/fesm2022/context-menu.mjs +9 -9
  45. package/date-picker/README.md +436 -34
  46. package/date-picker/fesm2022/date-picker.mjs +64 -267
  47. package/date-picker/types/date-picker.d.ts +7 -3
  48. package/dialog/README.md +419 -34
  49. package/dialog/fesm2022/dialog.mjs +45 -71
  50. package/drawer/README.md +395 -5
  51. package/drawer/fesm2022/drawer.mjs +44 -54
  52. package/dropdown-menu/README.md +417 -5
  53. package/dropdown-menu/fesm2022/dropdown-menu.mjs +82 -70
  54. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  55. package/empty/README.md +329 -5
  56. package/empty/fesm2022/empty.mjs +30 -30
  57. package/field/README.md +385 -5
  58. package/field/fesm2022/field.mjs +56 -72
  59. package/form-checkbox/README.md +283 -34
  60. package/form-checkbox/fesm2022/form-checkbox.mjs +25 -85
  61. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  62. package/form-date-picker/README.md +293 -34
  63. package/form-date-picker/fesm2022/form-date-picker.mjs +31 -84
  64. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  65. package/form-field/README.md +327 -34
  66. package/form-field/fesm2022/form-field.mjs +33 -19
  67. package/form-field/types/form-field.d.ts +28 -20
  68. package/form-field-simple/README.md +311 -34
  69. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  70. package/form-searchable-multiselect/README.md +332 -34
  71. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +31 -91
  72. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +7 -1
  73. package/form-select/README.md +321 -34
  74. package/form-select/fesm2022/form-select.mjs +32 -149
  75. package/form-select/types/form-select.d.ts +7 -1
  76. package/form-text-input/README.md +342 -34
  77. package/form-text-input/fesm2022/form-text-input.mjs +35 -149
  78. package/form-text-input/types/form-text-input.d.ts +9 -12
  79. package/form-textarea/README.md +318 -34
  80. package/form-textarea/fesm2022/form-textarea.mjs +34 -109
  81. package/form-textarea/types/form-textarea.d.ts +8 -1
  82. package/hover-card/README.md +256 -5
  83. package/hover-card/fesm2022/hover-card.mjs +19 -19
  84. package/icon/README.md +210 -34
  85. package/icon/fesm2022/icon.mjs +8 -8
  86. package/input/README.md +240 -34
  87. package/input/fesm2022/input.mjs +17 -12
  88. package/input/types/input.d.ts +2 -1
  89. package/input-group/README.md +335 -5
  90. package/input-group/fesm2022/input-group.mjs +34 -34
  91. package/input-otp/README.md +375 -5
  92. package/input-otp/fesm2022/input-otp.mjs +26 -26
  93. package/item/README.md +385 -5
  94. package/item/fesm2022/item.mjs +53 -53
  95. package/kbd/README.md +291 -5
  96. package/kbd/fesm2022/kbd.mjs +12 -12
  97. package/label/README.md +243 -34
  98. package/label/fesm2022/label.mjs +10 -10
  99. package/label/types/label.d.ts +1 -1
  100. package/layout-simple/README.md +174 -44
  101. package/layout-simple/fesm2022/layout-simple.mjs +508 -603
  102. package/layout-simple/types/layout-simple.d.ts +179 -128
  103. package/menu/README.md +418 -0
  104. package/menu/fesm2022/menu.mjs +455 -0
  105. package/menu/package.json +24 -0
  106. package/menu/types/menu.d.ts +137 -0
  107. package/menubar/README.md +343 -5
  108. package/menubar/fesm2022/menubar.mjs +13 -13
  109. package/native-select/README.md +323 -5
  110. package/native-select/fesm2022/native-select.mjs +19 -19
  111. package/navigation-menu/README.md +369 -5
  112. package/navigation-menu/fesm2022/navigation-menu.mjs +35 -47
  113. package/package.json +183 -154
  114. package/pagination/README.md +388 -5
  115. package/pagination/fesm2022/pagination.mjs +45 -331
  116. package/popover/README.md +302 -34
  117. package/popover/fesm2022/popover.mjs +30 -30
  118. package/progress/README.md +311 -5
  119. package/progress/fesm2022/progress.mjs +13 -13
  120. package/radio-group/README.md +335 -34
  121. package/radio-group/fesm2022/radio-group.mjs +26 -19
  122. package/radio-group/types/radio-group.d.ts +1 -1
  123. package/resizable/README.md +269 -5
  124. package/resizable/fesm2022/resizable.mjs +18 -26
  125. package/scroll-area/README.md +233 -5
  126. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  127. package/searchable-multiselect/README.md +294 -34
  128. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +28 -117
  129. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  130. package/select/README.md +408 -34
  131. package/select/fesm2022/select.mjs +71 -111
  132. package/select/types/select.d.ts +3 -1
  133. package/separator/README.md +193 -34
  134. package/separator/fesm2022/separator.mjs +9 -9
  135. package/separator/types/separator.d.ts +1 -1
  136. package/sheet/README.md +282 -34
  137. package/sheet/fesm2022/sheet.mjs +41 -53
  138. package/sidebar/README.md +457 -5
  139. package/sidebar/fesm2022/sidebar.mjs +125 -227
  140. package/skeleton/README.md +217 -5
  141. package/skeleton/fesm2022/skeleton.mjs +9 -9
  142. package/slider/README.md +273 -5
  143. package/slider/fesm2022/slider.mjs +10 -80
  144. package/sonner/README.md +317 -34
  145. package/sonner/fesm2022/sonner.mjs +13 -13
  146. package/spinner/README.md +255 -34
  147. package/spinner/fesm2022/spinner.mjs +11 -11
  148. package/switch/README.md +281 -34
  149. package/switch/fesm2022/switch.mjs +13 -15
  150. package/table/README.md +423 -5
  151. package/table/fesm2022/table.mjs +41 -41
  152. package/tabs/README.md +382 -34
  153. package/tabs/fesm2022/tabs.mjs +35 -111
  154. package/textarea/README.md +282 -5
  155. package/textarea/fesm2022/textarea.mjs +9 -9
  156. package/toggle/README.md +270 -5
  157. package/toggle/fesm2022/toggle.mjs +13 -13
  158. package/toggle-group/README.md +340 -5
  159. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  160. package/toggle-group/types/toggle-group.d.ts +13 -7
  161. package/tooltip/README.md +240 -34
  162. package/tooltip/fesm2022/tooltip.mjs +14 -14
  163. package/typography/README.md +271 -5
  164. package/typography/fesm2022/typography.mjs +53 -53
  165. package/typography/types/typography.d.ts +19 -19
  166. package/utils/README.md +274 -34
  167. package/utils/fesm2022/utils.mjs +68 -44
  168. package/accordion/fesm2022/accordion.mjs.map +0 -1
  169. package/alert/fesm2022/alert.mjs.map +0 -1
  170. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  171. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  172. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  173. package/avatar/fesm2022/avatar.mjs.map +0 -1
  174. package/badge/fesm2022/badge.mjs.map +0 -1
  175. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  176. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  177. package/button/fesm2022/button.mjs.map +0 -1
  178. package/button-group/fesm2022/button-group.mjs.map +0 -1
  179. package/calendar/fesm2022/calendar.mjs.map +0 -1
  180. package/card/fesm2022/card.mjs.map +0 -1
  181. package/carousel/fesm2022/carousel.mjs.map +0 -1
  182. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  183. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  184. package/combobox/fesm2022/combobox.mjs.map +0 -1
  185. package/command/fesm2022/command.mjs.map +0 -1
  186. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  187. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  188. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  189. package/dialog/fesm2022/dialog.mjs.map +0 -1
  190. package/drawer/fesm2022/drawer.mjs.map +0 -1
  191. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  192. package/empty/fesm2022/empty.mjs.map +0 -1
  193. package/field/fesm2022/field.mjs.map +0 -1
  194. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  195. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  196. package/form-field/fesm2022/form-field.mjs.map +0 -1
  197. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  198. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  199. package/form-select/fesm2022/form-select.mjs.map +0 -1
  200. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  201. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  202. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  203. package/icon/fesm2022/icon.mjs.map +0 -1
  204. package/input/fesm2022/input.mjs.map +0 -1
  205. package/input-group/fesm2022/input-group.mjs.map +0 -1
  206. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  207. package/item/fesm2022/item.mjs.map +0 -1
  208. package/kbd/fesm2022/kbd.mjs.map +0 -1
  209. package/label/fesm2022/label.mjs.map +0 -1
  210. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  211. package/menubar/fesm2022/menubar.mjs.map +0 -1
  212. package/native-select/fesm2022/native-select.mjs.map +0 -1
  213. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  214. package/pagination/fesm2022/pagination.mjs.map +0 -1
  215. package/popover/fesm2022/popover.mjs.map +0 -1
  216. package/progress/fesm2022/progress.mjs.map +0 -1
  217. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  218. package/resizable/fesm2022/resizable.mjs.map +0 -1
  219. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  220. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  221. package/select/fesm2022/select.mjs.map +0 -1
  222. package/separator/fesm2022/separator.mjs.map +0 -1
  223. package/sheet/fesm2022/sheet.mjs.map +0 -1
  224. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  225. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  226. package/slider/fesm2022/slider.mjs.map +0 -1
  227. package/sonner/fesm2022/sonner.mjs.map +0 -1
  228. package/spinner/fesm2022/spinner.mjs.map +0 -1
  229. package/switch/fesm2022/switch.mjs.map +0 -1
  230. package/table/fesm2022/table.mjs.map +0 -1
  231. package/tabs/fesm2022/tabs.mjs.map +0 -1
  232. package/textarea/fesm2022/textarea.mjs.map +0 -1
  233. package/toggle/fesm2022/toggle.mjs.map +0 -1
  234. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  235. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  236. package/typography/fesm2022/typography.mjs.map +0 -1
  237. package/utils/fesm2022/utils.mjs.map +0 -1
@@ -6,19 +6,19 @@ import { hlm } from '@egose/shadcn-theme-ng/utils';
6
6
 
7
7
  class HlmLabel {
8
8
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
9
- _computedClass = computed(() => hlm('flex select-none items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 has-[[disabled]]:cursor-not-allowed has-[[disabled]]:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-data-[disabled]:cursor-not-allowed peer-data-[disabled]:opacity-50', this.userClass()), /* @ts-ignore */
9
+ _computedClass = computed(() => hlm("flex select-none items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 has-[[disabled]]:cursor-not-allowed has-[[disabled]]:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-data-[disabled]:cursor-not-allowed peer-data-[disabled]:opacity-50", this.userClass()), /* @ts-ignore */
10
10
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
11
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
12
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: HlmLabel, isStandalone: true, selector: "[hlmLabel]", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, hostDirectives: [{ directive: i1.BrnLabel, inputs: ["id", "id"] }], ngImport: i0 });
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
12
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmLabel, isStandalone: true, selector: "[hlmLabel]", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, hostDirectives: [{ directive: i1.BrnLabel, inputs: ["id", "id", "for", "for"] }], ngImport: i0 });
13
13
  }
14
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmLabel, decorators: [{
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmLabel, decorators: [{
15
15
  type: Directive,
16
16
  args: [{
17
17
  selector: '[hlmLabel]',
18
18
  hostDirectives: [
19
19
  {
20
20
  directive: BrnLabel,
21
- inputs: ['id'],
21
+ inputs: ['id', 'for'],
22
22
  },
23
23
  ],
24
24
  host: {
@@ -32,11 +32,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
32
32
  */
33
33
  const HlmLabelImports = [HlmLabel];
34
34
  class HlmLabelModule {
35
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmLabelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
36
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmLabelModule, imports: [HlmLabel], exports: [HlmLabel] });
37
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmLabelModule });
35
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmLabelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
36
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmLabelModule, imports: [HlmLabel], exports: [HlmLabel] });
37
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmLabelModule });
38
38
  }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmLabelModule, decorators: [{
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmLabelModule, decorators: [{
40
40
  type: NgModule,
41
41
  args: [{
42
42
  imports: [...HlmLabelImports],
@@ -49,4 +49,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
49
49
  */
50
50
 
51
51
  export { HlmLabel, HlmLabelImports, HlmLabelModule };
52
- //# sourceMappingURL=label.mjs.map
52
+
@@ -6,7 +6,7 @@ declare class HlmLabel {
6
6
  readonly userClass: i0.InputSignal<ClassValue>;
7
7
  protected readonly _computedClass: i0.Signal<string>;
8
8
  static ɵfac: i0.ɵɵFactoryDeclaration<HlmLabel, never>;
9
- static ɵdir: i0.ɵɵDirectiveDeclaration<HlmLabel, "[hlmLabel]", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.BrnLabel; inputs: { "id": "id"; }; outputs: {}; }]>;
9
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HlmLabel, "[hlmLabel]", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.BrnLabel; inputs: { "id": "id"; "for": "for"; }; outputs: {}; }]>;
10
10
  }
11
11
 
12
12
  declare const HlmLabelImports: readonly [typeof HlmLabel];
@@ -1,64 +1,194 @@
1
- # LayoutSimple
2
-
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
4
-
5
- ## Code scaffolding
6
-
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
8
-
9
- ```bash
10
- ng generate component component-name
1
+ # Simple application layout
2
+
3
+ A responsive Angular shell with branded header, keyboard-accessible navigation, async page search, optional sidebar, and footer. Colors use the consumer's `background`, `foreground`, `border`, and `ring` theme tokens. Navigation has visible active and focus states, and controls have 44px minimum touch targets.
4
+
5
+ Import standalone components from `@egose/shadcn-theme-ng/layout-simple`, or `@egose/shadcn-theme-ng-tw/layout-simple` for Tailwind's `tw:` prefix. See the [package README](../../README.md) for installation and styling setup. Configure Angular Router (`provideRouter`) before using the shell.
6
+
7
+ ## Basic usage
8
+
9
+ ```ts
10
+ import { Component } from '@angular/core';
11
+ import { RouterOutlet } from '@angular/router';
12
+ import { EgLayoutSimple, type MenuItem } from '@egose/shadcn-theme-ng/layout-simple';
13
+
14
+ @Component({
15
+ imports: [EgLayoutSimple, RouterOutlet],
16
+ template: `
17
+ <eg-layout-simple
18
+ brandName="Acme workspace"
19
+ [primaryNavigation]="navigation"
20
+ [footerEnabled]="true"
21
+ footerText="Acme workspace"
22
+ >
23
+ <router-outlet />
24
+ </eg-layout-simple>
25
+ `,
26
+ })
27
+ export class App {
28
+ readonly navigation: MenuItem[] = [
29
+ { label: 'Home', link: '/' },
30
+ { label: 'Projects', link: '/projects', activeMatch: 'prefix' },
31
+ { label: 'Reports', disabled: true },
32
+ ];
33
+ }
11
34
  ```
12
35
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
14
-
15
- ```bash
16
- ng generate --help
36
+ ## Navigation model
37
+
38
+ `MenuItem` is shared by every navigation surface, including `UserMenuItem`:
39
+
40
+ | Field | Meaning |
41
+ | ----------------------------------- | ----------------------------------------------------------------- |
42
+ | `label: string` | Visible link/action text |
43
+ | `description?: string` | Supporting text in desktop and mobile fly-out cards |
44
+ | `link?: string` | Internal router URL; takes precedence over `action` |
45
+ | `action?: () => void` | Button callback when there is no link |
46
+ | `icon?: string` | SVG data such as `lucideHome` from `@ng-icons/lucide` |
47
+ | `activeMatch?: 'exact' \| 'prefix'` | Exact path by default; query parameters and fragments are ignored |
48
+ | `disabled?: boolean` | Prevents navigation and activation |
49
+ | `class?: string` | Per-item classes |
50
+
51
+ An item without a link or action renders as disabled. `MenuGroup` contains an optional `label` and required readonly `items`. `UserMenuSection` has optional `label`, `items`, and `separator` (a desktop dropdown separator).
52
+
53
+ ### Shell inputs
54
+
55
+ | Input | Default / purpose |
56
+ | --------------------------------------------------- | ------------------------------------------------------------------------- |
57
+ | `primaryNavigation` | `[]`; main header destinations |
58
+ | `navigationGroups` | `[]`; header dropdown groups, operated by click or keyboard |
59
+ | `utilityNavigation` | `[]`; header utility actions |
60
+ | `sectionNavigation` | `[]`; navigation row below the header |
61
+ | `secondaryNavigationGroups` | `[]`; horizontally scrollable grouped navigation |
62
+ | `flyoutNavigationGroups` | `[]`; category navbar with wide card panels; `readonly FlyoutMenuGroup[]` |
63
+ | `flyoutNavigationLabel` / `flyoutCloseLabel` | `'Fly-out navigation'` / `'Close navigation panel'`; accessible labels |
64
+ | `userMenuSections` | `[]`; desktop account dropdown and mobile account section |
65
+ | `brandName` | `'Workspace'`; visible name and accessible home-link label |
66
+ | `logo` / `logoLink` | `''` / `'/'`; optional decorative image and brand destination |
67
+ | `fullHeight` | `true`; minimum viewport height; set `false` for embedded previews |
68
+ | `loading` / `loadingText` | `false` / `'Loading content…'`; busy state with visible status |
69
+ | `skipLinkText` | `'Skip to content'`; keyboard shortcut to the main landmark |
70
+ | `sidebarEnabled` | `false`; adds a sidebar trigger |
71
+ | `sidebarTitle` | `'Navigation'` |
72
+ | `sidebarContent` | `TemplateRef<unknown>` with a `close` context function |
73
+ | `sidebarToggleLabel` | `'Open navigation sidebar'` |
74
+ | `mobileMenuLabel` / `mobileMenuCloseLabel` | `'Open navigation menu'` / `'Close navigation menu'` |
75
+ | `userMenuTrigger` / `userMenuLabel` | Optional trigger template / `'Open account menu'` |
76
+ | `footerEnabled` / `footerText` / `footerNavigation` | `false` / `''` / `[]` |
77
+
78
+ Style hooks accept `ClassValue`: `logoClass`, `headerClass`, `contentClass`, `primaryNavigationClass`, `utilityNavigationClass`, `sectionNavigationClass`, `secondaryNavigationClass`, `flyoutNavigationClass`, `flyoutPanelClass`, `navigationItemClass`, and `footerClass`. Per-item classes also work on mobile.
79
+
80
+ Below 768px, desktop navigation is replaced by a scrollable mobile disclosure. It includes page search and all navigation destinations. Escape and item selection close it and return focus to its trigger; routing and resizing to desktop also close it. Multiple shells generate distinct content and panel IDs. `EG_LAYOUT_SIMPLE_MOBILE_BREAKPOINT` exposes the breakpoint contract; Tailwind's `md` breakpoint must match it.
81
+
82
+ The sidebar is a modal sheet with focus handling from Spartan/CDK. Its body scrolls independently of its header and close button. Use `#shell` with `shell.openSidebar()` / `shell.closeSidebar()` for programmatic control:
83
+
84
+ ```html
85
+ <eg-layout-simple [sidebarEnabled]="true" [sidebarContent]="sidebar">
86
+ <h1>Dashboard</h1>
87
+ </eg-layout-simple>
88
+ <ng-template #sidebar let-close="close">
89
+ <a routerLink="/projects" (click)="close()">Projects</a>
90
+ </ng-template>
17
91
  ```
18
92
 
19
- ## Building
20
-
21
- To build the library, run:
22
-
23
- ```bash
24
- ng build layout-simple
93
+ ## Dropdown / fly-out navbar
94
+
95
+ `flyoutNavigationGroups` adds a category navbar below the header/section navigation. Each trigger opens a shell-width panel with a responsive two- or three-column grid of cards. Cards support the same routes, actions, disabled state, and active matching as other navigation, plus optional icons and descriptions.
96
+
97
+ ```ts
98
+ import { Component } from '@angular/core';
99
+ import { RouterOutlet } from '@angular/router';
100
+ import { lucideLayers, lucideTable } from '@ng-icons/lucide';
101
+ import { EgLayoutSimple, type FlyoutMenuGroup } from '@egose/shadcn-theme-ng/layout-simple';
102
+
103
+ @Component({
104
+ imports: [EgLayoutSimple, RouterOutlet],
105
+ template: `
106
+ <eg-layout-simple brandName="Acme" [flyoutNavigationGroups]="groups">
107
+ <router-outlet />
108
+ </eg-layout-simple>
109
+ `,
110
+ })
111
+ export class App {
112
+ readonly groups: FlyoutMenuGroup[] = [
113
+ {
114
+ label: 'Explore',
115
+ description: 'Find the right tools for your next project.',
116
+ items: [
117
+ { label: 'Projects', description: 'Plan and organize your work.', icon: lucideLayers, link: '/projects' },
118
+ { label: 'Reports', description: 'Turn your data into useful insights.', icon: lucideTable, link: '/reports' },
119
+ ],
120
+ },
121
+ ];
122
+ }
25
123
  ```
26
124
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
125
+ `FlyoutMenuGroup` extends `MenuGroup` with a required `label`, optional `description`, and optional trigger `icon`. `secondaryNavigationGroups` is still the independent scrollable link strip; both inputs can be used together. `navigationGroups` remains the compact header dropdown. The example app derives its fly-out groups from the active component/example catalog section and hides the row on Home.
28
126
 
29
- ### Publishing the Library
127
+ - **Pointer:** click a category to open or toggle it; opening another category replaces the panel. Click outside or use the close button to dismiss.
128
+ - **Keyboard:** Enter/Space toggles a trigger; Left/Right/Home/End move among enabled category triggers. Down/Up opens the panel and focuses its first/last enabled card. Tab follows normal document order. Escape returns focus to the trigger. Moving focus outside closes the panel.
129
+ - **Mobile:** below 768px the categories become native expandable sections inside the mobile navigation, retaining icons and descriptions.
130
+ - **State:** selection, route changes, group replacement, and resizing to mobile dismiss the desktop panel. Current categories and destination links have active styling. Empty categories are disabled.
131
+ - **Sizing:** panels overlay page content, are bounded to the shell width, and scroll internally for large catalogs. Avoid `overflow: hidden` on containing elements if the panel should extend past an embedded preview.
30
132
 
31
- Once the project is built, you can publish your library by following these steps:
133
+ ## Async search
32
134
 
33
- 1. Navigate to the `dist` directory:
135
+ ```ts
136
+ type Page = { title: string; url: string };
34
137
 
35
- ```bash
36
- cd dist/layout-simple
37
- ```
138
+ // Members of the consuming component:
139
+ readonly pages: Page[] = [
140
+ { title: 'Dashboard', url: '/' },
141
+ { title: 'Projects', url: '/projects' },
142
+ ];
143
+ readonly loadPages = async ({ search }: { search: string }): Promise<Page[]> =>
144
+ this.pages.filter((page) => page.title.toLowerCase().includes(search.toLowerCase()));
145
+ readonly pageLabel = (page: Page) => page.title;
146
+ // Handle selection by navigating with your injected Router.
147
+ ```
38
148
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
149
+ ```html
150
+ <eg-layout-simple
151
+ [searchEnabled]="true"
152
+ [searchLoader]="loadPages"
153
+ [searchResultLabel]="pageLabel"
154
+ [searchResultTemplate]="result"
155
+ (searchResultSelected)="router.navigateByUrl($event.url)"
156
+ >
157
+ <router-outlet />
158
+ </eg-layout-simple>
159
+ <ng-template #result let-page>{{ page.title }}</ng-template>
160
+ ```
43
161
 
44
- ## Running unit tests
162
+ `LayoutSearchLoader<TItem>` receives `{ search: string }` and resolves to a readonly array. It runs on opening (empty query) and after a 180ms debounce when typing. The loader owns filtering; the component does not filter results a second time. Changing the query, closing, or destroying the search invalidates old responses. Loading, empty, and error states are distinct, with a retry button on failure. Arrow keys move between the search field and result buttons; Enter selects; Escape closes the popover.
45
163
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
164
+ Shell search inputs: `searchEnabled`, `searchLoader`, `searchResultLabel`, `searchResultTemplate`, `searchPlaceholder`, `searchEmptyText`, and `searchErrorText`. Selection emits `searchResultSelected`. The template context is `LayoutSearchResultContext<TItem>` (`$implicit: TItem`). Always supply a result label or template for object results.
47
165
 
48
- ```bash
49
- ng test
50
- ```
166
+ ### Standalone building blocks
51
167
 
52
- ## Running end-to-end tests
168
+ - `EgLayoutSearch` (`eg-layout-search`): `loader`, `resultLabel`, `resultTemplate`, `placeholder`, `emptyText`, `errorText`, `loadingText`, `retryText`; emits `resultSelected`.
169
+ - `EgLayoutSimpleUserMenu` (`eg-layout-simple-user-menu`): `sections`, `triggerTemplate`, `triggerLabel`. Custom trigger templates supply non-interactive content; the component provides the button.
170
+ - The sidebar, fly-out navbar, navigation-item renderer, and mobile group are internal components, not public imports.
53
171
 
54
- For end-to-end (e2e) testing, run:
172
+ ## Migration from the positional API
55
173
 
56
- ```bash
57
- ng e2e
58
- ```
174
+ | Previous name | New name |
175
+ | --------------------------------------------------- | ------------------------------------------------------------------------------ |
176
+ | `leftMenus` / `leftMenuGroups` | `primaryNavigation` / `navigationGroups` |
177
+ | `rightMenus` | `utilityNavigation` |
178
+ | `topMenus` / `topSecondaryMenus` | `sectionNavigation` / `secondaryNavigationGroups` |
179
+ | `userMenus` | `userMenuSections` |
180
+ | `footerMenus` / `footerContent` | `footerNavigation` / `footerText` |
181
+ | `leftClass` / `rightClass` / `topClass` | `primaryNavigationClass` / `utilityNavigationClass` / `sectionNavigationClass` |
182
+ | `leftLinkClass` / `rightLinkClass` / `topLinkClass` | `navigationItemClass` or per-item `class` |
183
+ | `searchLoaderFn` | `searchLoader` |
184
+ | `searchTransformValueToSearch` | `searchResultLabel` |
185
+ | `searchPlaceholderText` | `searchPlaceholder` |
186
+ | `searchOptionTemplate` / `searchOptionChange` | `searchResultTemplate` / `searchResultSelected` |
187
+ | `EgGenericAutocomplete` | `EgLayoutSearch` |
188
+ | User menu `menus` / `menuTrigger` | `sections` / `triggerTemplate` |
59
189
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
190
+ `contentBottomClass` and the empty content spacer were removed; use `contentClass` for content sizing. Footer-specific menu/link class inputs were replaced by per-item `class`. The unsupported generic search-parameter cast and unused `AutocompleteOption` type were removed. Search now has a single generic item type. Use public `openSidebar()` / `closeSidebar()` methods instead of reaching into the sheet query.
61
191
 
62
- ## Additional Resources
192
+ ## Verification
63
193
 
64
- For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
194
+ From `packages/angular`: `pnpm test:library layout-simple`. The example at `@examples/standard` exercises source imports and custom search templates; its `pnpm build` also checks prerendering.