@egose/shadcn-theme-ng 0.1.0 → 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 (87) hide show
  1. package/README.md +1 -1
  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/avatar/README.md +357 -5
  8. package/badge/README.md +318 -2
  9. package/basic-alert/README.md +353 -2
  10. package/breadcrumb/README.md +406 -5
  11. package/button/README.md +482 -2
  12. package/button/fesm2022/button.mjs +85 -107
  13. package/button/types/button.d.ts +5 -8
  14. package/button-group/README.md +318 -5
  15. package/calendar/README.md +357 -2
  16. package/card/README.md +331 -5
  17. package/carousel/README.md +333 -5
  18. package/carousel/fesm2022/carousel.mjs +4 -1
  19. package/checkbox/README.md +320 -2
  20. package/collapsible/README.md +332 -5
  21. package/combobox/README.md +507 -5
  22. package/combobox/fesm2022/combobox.mjs +4 -1
  23. package/command/README.md +435 -5
  24. package/confirmation-dialog/README.md +301 -2
  25. package/context-menu/README.md +366 -5
  26. package/date-picker/README.md +465 -2
  27. package/date-picker/fesm2022/date-picker.mjs +2 -2
  28. package/dialog/README.md +448 -2
  29. package/drawer/README.md +395 -5
  30. package/dropdown-menu/README.md +417 -5
  31. package/empty/README.md +329 -5
  32. package/field/README.md +385 -5
  33. package/form-checkbox/README.md +312 -2
  34. package/form-date-picker/README.md +322 -2
  35. package/form-field/README.md +356 -2
  36. package/form-field-simple/README.md +340 -2
  37. package/form-searchable-multiselect/README.md +361 -2
  38. package/form-select/README.md +350 -2
  39. package/form-text-input/README.md +371 -2
  40. package/form-textarea/README.md +347 -2
  41. package/hover-card/README.md +256 -5
  42. package/icon/README.md +239 -2
  43. package/input/README.md +269 -2
  44. package/input-group/README.md +335 -5
  45. package/input-group/fesm2022/input-group.mjs +3 -3
  46. package/input-otp/README.md +375 -5
  47. package/item/README.md +385 -5
  48. package/item/fesm2022/item.mjs +3 -3
  49. package/kbd/README.md +291 -5
  50. package/label/README.md +272 -2
  51. package/layout-simple/README.md +193 -2
  52. package/layout-simple/fesm2022/layout-simple.mjs +472 -236
  53. package/layout-simple/types/layout-simple.d.ts +174 -137
  54. package/menu/README.md +417 -2
  55. package/menubar/README.md +343 -5
  56. package/native-select/README.md +323 -5
  57. package/navigation-menu/README.md +369 -5
  58. package/package.json +1 -1
  59. package/pagination/README.md +388 -5
  60. package/popover/README.md +331 -2
  61. package/progress/README.md +311 -5
  62. package/radio-group/README.md +364 -2
  63. package/radio-group/fesm2022/radio-group.mjs +5 -1
  64. package/radio-group/types/radio-group.d.ts +1 -1
  65. package/resizable/README.md +269 -5
  66. package/scroll-area/README.md +233 -5
  67. package/searchable-multiselect/README.md +323 -2
  68. package/select/README.md +437 -2
  69. package/separator/README.md +222 -2
  70. package/sheet/README.md +311 -2
  71. package/sidebar/README.md +457 -5
  72. package/skeleton/README.md +217 -5
  73. package/slider/README.md +273 -5
  74. package/slider/fesm2022/slider.mjs +3 -3
  75. package/sonner/README.md +346 -2
  76. package/spinner/README.md +284 -2
  77. package/switch/README.md +310 -2
  78. package/table/README.md +423 -5
  79. package/tabs/README.md +411 -2
  80. package/tabs/fesm2022/tabs.mjs +2 -2
  81. package/textarea/README.md +282 -5
  82. package/toggle/README.md +270 -5
  83. package/toggle-group/README.md +340 -5
  84. package/tooltip/README.md +269 -2
  85. package/typography/README.md +271 -5
  86. package/typography/types/typography.d.ts +8 -8
  87. package/utils/README.md +303 -2
package/empty/README.md CHANGED
@@ -1,11 +1,335 @@
1
- # Empty
1
+ # Empty (`@egose/shadcn-theme-ng/empty`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli).
3
+ An empty-state placeholder in the shadcn/ui Empty style: dashed bordered panel with media (icon/illustration), title, description, and action content. Equivalent to shadcn/ui `Empty`.
4
4
 
5
- ## Building
5
+ The Angular implementation is a set of pure styling directives — there is no headless primitive or
6
+ behavioral code. Each directive applies its `data-slot` shadcn classes via `classes()` from
7
+ `@egose/shadcn-theme-ng/utils`; `HlmEmptyMedia` adds a `cva` variant (`default` | `icon`).
6
8
 
7
- To build the library, run:
9
+ > **Ships as:** `@egose/shadcn-theme-ng/empty` and `@egose/shadcn-theme-ng-tw/empty`
10
+ > (the `tw:`-prefixed Tailwind variant). Both expose the identical TypeScript surface; only the
11
+ > emitted Tailwind class strings differ. See the [package README](../../README.md) for install
12
+ > steps, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
13
+
14
+ ## Installation
8
15
 
9
16
  ```bash
10
- ng build empty
17
+ # Plain Tailwind (no prefix)
18
+ npm install @egose/shadcn-theme-ng
19
+
20
+ # tw:-prefixed Tailwind variant
21
+ npm install @egose/shadcn-theme-ng-tw
22
+ ```
23
+
24
+ Peer dependencies (Angular, `@spartan-ng/brain`, `@ng-icons/*`, `rxjs`, …) are documented in the
25
+ [package README](../../README.md#peer-dependencies). This subpath has no extra runtime component
26
+ dependencies beyond `@egose/shadcn-theme-ng/utils` and `class-variance-authority` (media variant).
27
+
28
+ ## Imports
29
+
30
+ All symbols are exported from the subpath root (`projects/empty/src/public-api.ts`):
31
+
32
+ ```ts
33
+ import {
34
+ HlmEmpty,
35
+ HlmEmptyHeader,
36
+ HlmEmptyTitle,
37
+ HlmEmptyDescription,
38
+ HlmEmptyContent,
39
+ HlmEmptyMedia,
40
+ HlmEmptyImports,
41
+ HlmEmptyModule,
42
+ } from '@egose/shadcn-theme-ng/empty';
43
+ // tw variant: replace with '@egose/shadcn-theme-ng-tw/empty'
44
+ ```
45
+
46
+ Standalone component — spread the `*Imports` array:
47
+
48
+ ```ts
49
+ import { Component } from '@angular/core';
50
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
51
+
52
+ @Component({
53
+ selector: 'app-demo',
54
+ standalone: true,
55
+ imports: [...HlmEmptyImports],
56
+ template: `...`,
57
+ })
58
+ export class DemoComponent {}
59
+ ```
60
+
61
+ NgModule-based consumer — import the module:
62
+
63
+ ```ts
64
+ import { NgModule } from '@angular/core';
65
+ import { HlmEmptyModule } from '@egose/shadcn-theme-ng/empty';
66
+
67
+ @NgModule({ imports: [HlmEmptyModule] })
68
+ export class DemoModule {}
11
69
  ```
70
+
71
+ ## Anatomy / Structure
72
+
73
+ ```html
74
+ <div hlmEmpty>
75
+ <div hlmEmptyMedia variant="icon">
76
+ <ng-icon name="lucideInbox" />
77
+ </div>
78
+ <div hlmEmptyHeader>
79
+ <h3 hlmEmptyTitle>No results found</h3>
80
+ <p hlmEmptyDescription>Try adjusting your search or filters.</p>
81
+ </div>
82
+ <div hlmEmptyContent>
83
+ <button hlmBtn variant="outline">Clear filters</button>
84
+ </div>
85
+ </div>
86
+ ```
87
+
88
+ Real selectors (from source):
89
+
90
+ | Class | Selector(s) | Kind |
91
+ | --------------------- | -------------------------------------- | -------------------------- |
92
+ | `HlmEmpty` | `[hlmEmpty], hlm-empty` | Directive |
93
+ | `HlmEmptyHeader` | `[hlmEmptyHeader], hlm-empty-header` | Directive |
94
+ | `HlmEmptyTitle` | `[hlmEmptyTitle]` | Directive (attribute only) |
95
+ | `HlmEmptyDescription` | `[hlmEmptyDescription]` | Directive (attribute only) |
96
+ | `HlmEmptyContent` | `[hlmEmptyContent], hlm-empty-content` | Directive |
97
+ | `HlmEmptyMedia` | `[hlmEmptyMedia], hlm-empty-media` | Directive |
98
+
99
+ ## API reference
100
+
101
+ All directives are style-only (no inputs except media, no outputs).
102
+
103
+ | Directive | Selector | Description |
104
+ | --------------------- | -------------------------------------- | ------------------------------------------------------------ |
105
+ | `HlmEmpty` | `[hlmEmpty], hlm-empty` | Dashed rounded panel, centered column layout. |
106
+ | `HlmEmptyHeader` | `[hlmEmptyHeader], hlm-empty-header` | Narrow centered stack for title + description. |
107
+ | `HlmEmptyTitle` | `[hlmEmptyTitle]` | Large medium title. Apply to a heading element. |
108
+ | `HlmEmptyDescription` | `[hlmEmptyDescription]` | Muted small description with link styling. Apply to a `<p>`. |
109
+ | `HlmEmptyContent` | `[hlmEmptyContent], hlm-empty-content` | Action area (buttons, inputs) below the header. |
110
+
111
+ ### `HlmEmptyMedia` — `[hlmEmptyMedia], hlm-empty-media`
112
+
113
+ | Input | Type | Default | Description |
114
+ | --------- | --------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------- |
115
+ | `variant` | `'default' \| 'icon'` | `'default'` (cva default) | `'icon'` renders a muted rounded tile sized for an `ng-icon`; `'default'` is transparent (for illustrations). |
116
+
117
+ Host sets `data-slot="empty-media"` and `data-variant`.
118
+
119
+ ## Examples
120
+
121
+ ### 1. Basic no-results state
122
+
123
+ ```ts
124
+ import { Component } from '@angular/core';
125
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
126
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
127
+
128
+ @Component({
129
+ selector: 'app-no-results',
130
+ standalone: true,
131
+ imports: [...HlmEmptyImports, HlmButton],
132
+ template: `
133
+ <div hlmEmpty>
134
+ <div hlmEmptyHeader>
135
+ <h3 hlmEmptyTitle>No results found</h3>
136
+ <p hlmEmptyDescription>Try adjusting your search or filter to find what you're looking for.</p>
137
+ </div>
138
+ <div hlmEmptyContent>
139
+ <button hlmBtn variant="outline" (click)="clear()">Clear filters</button>
140
+ </div>
141
+ </div>
142
+ `,
143
+ })
144
+ export class NoResultsComponent {
145
+ clear() {
146
+ console.log('filters cleared');
147
+ }
148
+ }
149
+ ```
150
+
151
+ ### 2. Icon media variant
152
+
153
+ ```ts
154
+ import { Component } from '@angular/core';
155
+ import { NgIcon, provideIcons } from '@ng-icons/core';
156
+ import { lucideInbox } from '@ng-icons/lucide';
157
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
158
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
159
+
160
+ @Component({
161
+ selector: 'app-inbox-empty',
162
+ standalone: true,
163
+ imports: [...HlmEmptyImports, HlmButton, NgIcon],
164
+ providers: [provideIcons({ lucideInbox })],
165
+ template: `
166
+ <div hlmEmpty>
167
+ <div hlmEmptyMedia variant="icon">
168
+ <ng-icon name="lucideInbox" />
169
+ </div>
170
+ <div hlmEmptyHeader>
171
+ <h3 hlmEmptyTitle>Inbox zero</h3>
172
+ <p hlmEmptyDescription>You're all caught up. New messages will appear here.</p>
173
+ </div>
174
+ <div hlmEmptyContent>
175
+ <button hlmBtn>Compose</button>
176
+ </div>
177
+ </div>
178
+ `,
179
+ })
180
+ export class InboxEmptyComponent {}
181
+ ```
182
+
183
+ ### 3. Illustration media (default variant)
184
+
185
+ ```ts
186
+ import { Component } from '@angular/core';
187
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
188
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
189
+
190
+ @Component({
191
+ selector: 'app-illustration',
192
+ standalone: true,
193
+ imports: [...HlmEmptyImports, HlmButton],
194
+ template: `
195
+ <div hlmEmpty>
196
+ <div hlmEmptyMedia>
197
+ <img src="/assets/empty-projects.svg" alt="" width="120" height="120" />
198
+ </div>
199
+ <div hlmEmptyHeader>
200
+ <h3 hlmEmptyTitle>No projects yet</h3>
201
+ <p hlmEmptyDescription>
202
+ Get started by creating your first project. Read the <a href="/docs">docs</a> for ideas.
203
+ </p>
204
+ </div>
205
+ <div hlmEmptyContent>
206
+ <button hlmBtn>Create project</button>
207
+ <button hlmBtn variant="ghost">Import</button>
208
+ </div>
209
+ </div>
210
+ `,
211
+ })
212
+ export class IllustrationComponent {}
213
+ ```
214
+
215
+ ### 4. Element spellings
216
+
217
+ ```ts
218
+ import { Component } from '@angular/core';
219
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
220
+
221
+ @Component({
222
+ selector: 'app-elements',
223
+ standalone: true,
224
+ imports: [...HlmEmptyImports],
225
+ template: `
226
+ <hlm-empty>
227
+ <hlm-empty-header>
228
+ <h3 hlmEmptyTitle>Nothing here</h3>
229
+ <p hlmEmptyDescription>This space is intentionally left blank.</p>
230
+ </hlm-empty-header>
231
+ <hlm-empty-content>
232
+ <p class="tw:text-sm">Custom element selectors work identically.</p>
233
+ </hlm-empty-content>
234
+ </hlm-empty>
235
+ `,
236
+ })
237
+ export class ElementsComponent {}
238
+ ```
239
+
240
+ ### 5. Search empty state with input action
241
+
242
+ ```ts
243
+ import { Component, signal } from '@angular/core';
244
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
245
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
246
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
247
+ import { NgIcon, provideIcons } from '@ng-icons/core';
248
+ import { lucideSearchX } from '@ng-icons/lucide';
249
+
250
+ @Component({
251
+ selector: 'app-search-empty',
252
+ standalone: true,
253
+ imports: [...HlmEmptyImports, HlmButton, HlmInput, NgIcon],
254
+ providers: [provideIcons({ lucideSearchX })],
255
+ template: `
256
+ <div hlmEmpty>
257
+ <div hlmEmptyMedia variant="icon">
258
+ <ng-icon name="lucideSearchX" />
259
+ </div>
260
+ <div hlmEmptyHeader>
261
+ <h3 hlmEmptyTitle>No matches for "{{ query() }}"</h3>
262
+ <p hlmEmptyDescription>Check your spelling or try a different keyword.</p>
263
+ </div>
264
+ <div hlmEmptyContent>
265
+ <input hlmInput [value]="query()" (input)="query.set($any($event.target).value)" placeholder="Search again" />
266
+ <button hlmBtn variant="outline" (click)="query.set('')">Reset search</button>
267
+ </div>
268
+ </div>
269
+ `,
270
+ })
271
+ export class SearchEmptyComponent {
272
+ readonly query = signal('qwerty');
273
+ }
274
+ ```
275
+
276
+ ### 6. Error / offline state
277
+
278
+ ```ts
279
+ import { Component, signal } from '@angular/core';
280
+ import { HlmEmptyImports } from '@egose/shadcn-theme-ng/empty';
281
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
282
+ import { HlmSpinner } from '@egose/shadcn-theme-ng/spinner';
283
+ import { NgIcon, provideIcons } from '@ng-icons/core';
284
+ import { lucideWifiOff } from '@ng-icons/lucide';
285
+
286
+ @Component({
287
+ selector: 'app-offline',
288
+ standalone: true,
289
+ imports: [...HlmEmptyImports, HlmButton, HlmSpinner, NgIcon],
290
+ providers: [provideIcons({ lucideWifiOff })],
291
+ template: `
292
+ <div hlmEmpty>
293
+ <div hlmEmptyMedia variant="icon">
294
+ @if (retrying()) {
295
+ <hlm-spinner />
296
+ } @else {
297
+ <ng-icon name="lucideWifiOff" />
298
+ }
299
+ </div>
300
+ <div hlmEmptyHeader>
301
+ <h3 hlmEmptyTitle>You're offline</h3>
302
+ <p hlmEmptyDescription>We couldn't load your data. Check your connection and retry.</p>
303
+ </div>
304
+ <div hlmEmptyContent>
305
+ <button hlmBtn variant="outline" [disabled]="retrying()" (click)="retry()">Try again</button>
306
+ </div>
307
+ </div>
308
+ `,
309
+ })
310
+ export class OfflineComponent {
311
+ readonly retrying = signal(false);
312
+ retry() {
313
+ this.retrying.set(true);
314
+ setTimeout(() => this.retrying.set(false), 1200);
315
+ }
316
+ }
317
+ ```
318
+
319
+ ## Accessibility notes
320
+
321
+ - Use a real heading level for `hlmEmptyTitle` (`h2`/`h3` matching the page outline) — the directive adds no role or level itself.
322
+ - Mark decorative media `aria-hidden="true"` (or `alt=""` on images); give meaningful illustrations an `alt` or `role="img"` + `aria-label`.
323
+ - Keep the empty panel out of the tab order except for its interactive content (buttons/inputs); do not add `tabindex` to the container.
324
+ - For async states (loading → empty → results), announce changes with an `aria-live` region around the title or content.
325
+
326
+ ## Theming / CSS variables
327
+
328
+ No component-specific CSS variables. Geometry comes from the directives; colors from global tokens (`--muted`, `--muted-foreground`, `--background`). The `icon` media variant sizes `ng-icon` via `[&_ng-icon]` selectors — pass icon size through the icon itself if you need a different size.
329
+
330
+ ## Related subpaths
331
+
332
+ - `@egose/shadcn-theme-ng/card` — bordered container alternative when the state needs richer layout.
333
+ - `@egose/shadcn-theme-ng/skeleton` — loading placeholder to show before the empty state resolves.
334
+ - `@egose/shadcn-theme-ng/button` — `hlmBtn` actions inside `hlmEmptyContent`.
335
+ - `@egose/shadcn-theme-ng/spinner` — loading indicator for retrying/error empties.