@egose/shadcn-theme-ng 0.1.0 → 0.3.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 (162) hide show
  1. package/README.md +2 -2
  2. package/accordion/README.md +405 -2
  3. package/alert/README.md +372 -2
  4. package/alert-dialog/README.md +471 -5
  5. package/aspect-ratio/README.md +272 -5
  6. package/autocomplete/README.md +502 -2
  7. package/autocomplete/fesm2022/autocomplete.mjs +1 -1
  8. package/avatar/README.md +357 -5
  9. package/badge/README.md +318 -2
  10. package/basic-alert/README.md +353 -2
  11. package/breadcrumb/README.md +406 -5
  12. package/button/README.md +482 -2
  13. package/button/fesm2022/button.mjs +85 -107
  14. package/button/types/button.d.ts +5 -8
  15. package/button-group/README.md +318 -5
  16. package/calendar/README.md +357 -2
  17. package/card/README.md +331 -5
  18. package/carousel/README.md +333 -5
  19. package/carousel/fesm2022/carousel.mjs +4 -1
  20. package/checkbox/README.md +320 -2
  21. package/checkbox/fesm2022/checkbox.mjs +6 -7
  22. package/checkbox/types/checkbox.d.ts +1 -1
  23. package/collapsible/README.md +332 -5
  24. package/combobox/README.md +507 -5
  25. package/combobox/fesm2022/combobox.mjs +5 -2
  26. package/command/README.md +435 -5
  27. package/confirmation-dialog/README.md +301 -2
  28. package/context-menu/README.md +366 -5
  29. package/date-picker/README.md +469 -2
  30. package/date-picker/fesm2022/date-picker.mjs +150 -32
  31. package/date-picker/types/date-picker.d.ts +102 -9
  32. package/dialog/README.md +448 -2
  33. package/drawer/README.md +395 -5
  34. package/dropdown-menu/README.md +417 -5
  35. package/empty/README.md +329 -5
  36. package/field/README.md +385 -5
  37. package/form-autocomplete/README.md +177 -0
  38. package/form-autocomplete/fesm2022/form-autocomplete.mjs +125 -0
  39. package/form-autocomplete/package.json +24 -0
  40. package/form-autocomplete/types/form-autocomplete.d.ts +61 -0
  41. package/form-checkbox/README.md +322 -2
  42. package/form-checkbox/fesm2022/form-checkbox.mjs +22 -9
  43. package/form-checkbox/types/form-checkbox.d.ts +23 -4
  44. package/form-combobox/README.md +202 -0
  45. package/form-combobox/fesm2022/form-combobox.mjs +147 -0
  46. package/form-combobox/package.json +24 -0
  47. package/form-combobox/types/form-combobox.d.ts +73 -0
  48. package/form-date-picker/README.md +348 -2
  49. package/form-date-picker/fesm2022/form-date-picker.mjs +38 -12
  50. package/form-date-picker/types/form-date-picker.d.ts +17 -1
  51. package/form-date-picker-multi/README.md +191 -0
  52. package/form-date-picker-multi/fesm2022/form-date-picker-multi.mjs +129 -0
  53. package/form-date-picker-multi/package.json +24 -0
  54. package/form-date-picker-multi/types/form-date-picker-multi.d.ts +58 -0
  55. package/form-date-range-picker/README.md +253 -0
  56. package/form-date-range-picker/fesm2022/form-date-range-picker.mjs +130 -0
  57. package/form-date-range-picker/package.json +24 -0
  58. package/form-date-range-picker/types/form-date-range-picker.d.ts +55 -0
  59. package/form-field/README.md +356 -2
  60. package/form-field-simple/README.md +340 -2
  61. package/form-input-otp/README.md +194 -0
  62. package/form-input-otp/fesm2022/form-input-otp.mjs +106 -0
  63. package/form-input-otp/package.json +24 -0
  64. package/form-input-otp/types/form-input-otp.d.ts +58 -0
  65. package/form-month-year-picker/README.md +188 -0
  66. package/form-month-year-picker/fesm2022/form-month-year-picker.mjs +125 -0
  67. package/form-month-year-picker/package.json +24 -0
  68. package/form-month-year-picker/types/form-month-year-picker.d.ts +53 -0
  69. package/form-native-select/README.md +205 -0
  70. package/form-native-select/fesm2022/form-native-select.mjs +103 -0
  71. package/form-native-select/package.json +24 -0
  72. package/form-native-select/types/form-native-select.d.ts +57 -0
  73. package/form-phone-input/README.md +188 -0
  74. package/form-phone-input/fesm2022/form-phone-input.mjs +113 -0
  75. package/form-phone-input/package.json +24 -0
  76. package/form-phone-input/types/form-phone-input.d.ts +58 -0
  77. package/form-radio-group/README.md +198 -0
  78. package/form-radio-group/fesm2022/form-radio-group.mjs +111 -0
  79. package/form-radio-group/package.json +24 -0
  80. package/form-radio-group/types/form-radio-group.d.ts +63 -0
  81. package/form-searchable-multiselect/README.md +371 -2
  82. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +19 -10
  83. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +18 -1
  84. package/form-select/README.md +360 -2
  85. package/form-select/fesm2022/form-select.mjs +20 -11
  86. package/form-select/types/form-select.d.ts +18 -1
  87. package/form-slider/README.md +182 -0
  88. package/form-slider/fesm2022/form-slider.mjs +106 -0
  89. package/form-slider/package.json +24 -0
  90. package/form-slider/types/form-slider.d.ts +60 -0
  91. package/form-switch/README.md +173 -0
  92. package/form-switch/fesm2022/form-switch.mjs +100 -0
  93. package/form-switch/package.json +24 -0
  94. package/form-switch/types/form-switch.d.ts +50 -0
  95. package/form-text-input/README.md +381 -2
  96. package/form-text-input/fesm2022/form-text-input.mjs +19 -10
  97. package/form-text-input/types/form-text-input.d.ts +18 -1
  98. package/form-textarea/README.md +357 -2
  99. package/form-textarea/fesm2022/form-textarea.mjs +19 -10
  100. package/form-textarea/types/form-textarea.d.ts +18 -1
  101. package/form-toggle/README.md +186 -0
  102. package/form-toggle/fesm2022/form-toggle.mjs +159 -0
  103. package/form-toggle/package.json +24 -0
  104. package/form-toggle/types/form-toggle.d.ts +82 -0
  105. package/form-toggle-group/README.md +176 -0
  106. package/form-toggle-group/fesm2022/form-toggle-group.mjs +116 -0
  107. package/form-toggle-group/package.json +24 -0
  108. package/form-toggle-group/types/form-toggle-group.d.ts +65 -0
  109. package/hover-card/README.md +256 -5
  110. package/icon/README.md +239 -2
  111. package/input/README.md +269 -2
  112. package/input-group/README.md +335 -5
  113. package/input-group/fesm2022/input-group.mjs +22 -12
  114. package/input-group/types/input-group.d.ts +4 -1
  115. package/input-otp/README.md +375 -5
  116. package/item/README.md +385 -5
  117. package/item/fesm2022/item.mjs +3 -3
  118. package/kbd/README.md +291 -5
  119. package/label/README.md +272 -2
  120. package/layout-simple/README.md +193 -2
  121. package/layout-simple/fesm2022/layout-simple.mjs +472 -236
  122. package/layout-simple/types/layout-simple.d.ts +174 -137
  123. package/menu/README.md +417 -2
  124. package/menubar/README.md +343 -5
  125. package/native-select/README.md +323 -5
  126. package/native-select/fesm2022/native-select.mjs +18 -6
  127. package/native-select/types/native-select.d.ts +7 -2
  128. package/navigation-menu/README.md +369 -5
  129. package/package.json +57 -1
  130. package/pagination/README.md +388 -5
  131. package/phone-input/README.md +114 -0
  132. package/phone-input/fesm2022/phone-input.mjs +191 -0
  133. package/phone-input/package.json +24 -0
  134. package/phone-input/types/phone-input.d.ts +67 -0
  135. package/popover/README.md +331 -2
  136. package/progress/README.md +311 -5
  137. package/radio-group/README.md +364 -2
  138. package/radio-group/fesm2022/radio-group.mjs +5 -1
  139. package/resizable/README.md +269 -5
  140. package/scroll-area/README.md +233 -5
  141. package/searchable-multiselect/README.md +323 -2
  142. package/select/README.md +437 -2
  143. package/separator/README.md +222 -2
  144. package/sheet/README.md +311 -2
  145. package/sidebar/README.md +457 -5
  146. package/skeleton/README.md +217 -5
  147. package/slider/README.md +273 -5
  148. package/slider/fesm2022/slider.mjs +3 -3
  149. package/sonner/README.md +346 -2
  150. package/spinner/README.md +284 -2
  151. package/switch/README.md +310 -2
  152. package/switch/fesm2022/switch.mjs +7 -5
  153. package/switch/types/switch.d.ts +2 -1
  154. package/table/README.md +423 -5
  155. package/tabs/README.md +411 -2
  156. package/tabs/fesm2022/tabs.mjs +2 -2
  157. package/textarea/README.md +282 -5
  158. package/toggle/README.md +270 -5
  159. package/toggle-group/README.md +340 -5
  160. package/tooltip/README.md +269 -2
  161. package/typography/README.md +271 -5
  162. package/utils/README.md +303 -2
@@ -1,3 +1,194 @@
1
- # Layout Simple Subpath
1
+ # Simple application layout
2
2
 
3
- This project ships only as `@egose/shadcn-theme-ng/layout-simple` or `@egose/shadcn-theme-ng-tw/layout-simple`. See the [package README](../../README.md) for installation, compatibility, Tailwind variant, test, and release guidance. Do not publish this project directory independently.
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
+ }
34
+ ```
35
+
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>
91
+ ```
92
+
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
+ }
123
+ ```
124
+
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.
126
+
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.
132
+
133
+ ## Async search
134
+
135
+ ```ts
136
+ type Page = { title: string; url: string };
137
+
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
+ ```
148
+
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
+ ```
161
+
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.
163
+
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.
165
+
166
+ ### Standalone building blocks
167
+
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.
171
+
172
+ ## Migration from the positional API
173
+
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` |
189
+
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.
191
+
192
+ ## Verification
193
+
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.