@eagami/ui 0.7.4 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="docs/images/eagami-header.png" alt="eagami design system — elegant web design." width="800" />
2
+ <img src="docs/images/eagami-header.png" alt="eagami design system — elegant web design" width="800" />
3
3
  </p>
4
4
 
5
5
  A lightweight, accessible Angular component library built on CSS custom properties. Ready to use out of the box — install, import, and start building.
@@ -81,113 +81,137 @@ No modules to register, no providers to configure. Every component works the sam
81
81
 
82
82
  ## Components
83
83
 
84
- ### Button
84
+ <details>
85
+ <summary><strong>Accordion</strong> — expandable content sections</summary>
85
86
 
86
- Variants: `primary` | `secondary` | `ghost` | `danger`. Sizes: `sm` | `md` | `lg`. Supports `loading`, `disabled`, and `fullWidth` states.
87
+ Supports single or `multi` expand mode. Built-in chevron animation and disabled state.
87
88
 
88
89
  ```html
89
- <ea-button variant="primary" size="md" [loading]="isSaving" (clicked)="save()">
90
- Save changes
91
- </ea-button>
90
+ <ea-accordion>
91
+ <ea-accordion-item label="Section 1">Content for section 1</ea-accordion-item>
92
+ <ea-accordion-item label="Section 2">Content for section 2</ea-accordion-item>
93
+ </ea-accordion>
92
94
  ```
93
95
 
94
- <img src="docs/images/button.png" alt="Button component" width="560" />
96
+ <img src="docs/images/accordion.png" alt="Accordion component" width="560" />
95
97
 
96
- ---
98
+ </details>
97
99
 
98
- ### Input
100
+ <details>
101
+ <summary><strong>Alert</strong> — semantic alert banners with optional dismiss</summary>
99
102
 
100
- Full `ControlValueAccessor` support. Types: `text` | `email` | `password` | `number` | `search` | `tel` | `url`. Built-in password visibility toggle.
103
+ Variants: `default` | `success` | `warning` | `error` | `info`. Two-way `visible` binding.
101
104
 
102
105
  ```html
103
- <ea-input
104
- label="Email"
105
- type="email"
106
- placeholder="you@example.com"
107
- hint="We'll never share your email"
108
- [(value)]="email" />
106
+ <ea-alert variant="success">Changes saved successfully.</ea-alert>
107
+ <ea-alert variant="error" [dismissible]="true">Something went wrong.</ea-alert>
109
108
  ```
110
109
 
111
- <img src="docs/images/input.png" alt="Input component" width="560" />
110
+ <img src="docs/images/alert.png" alt="Alert component" width="560" />
112
111
 
113
- ---
112
+ </details>
114
113
 
115
- ### Textarea
114
+ <details>
115
+ <summary><strong>Autocomplete</strong> — text input with filtered suggestion dropdown</summary>
116
116
 
117
- Mirrors the Input API with `ControlValueAccessor`. Configurable `rows`, `resize` (`none` | `vertical` | `horizontal` | `both`), and `maxlength`.
117
+ Arrow key navigation, case-insensitive substring matching, configurable `minLength` and `maxResults`. Full `ControlValueAccessor` support.
118
118
 
119
119
  ```html
120
- <ea-textarea
121
- label="Message"
122
- placeholder="Enter your message…"
123
- hint="Maximum 500 characters"
124
- [rows]="4"
125
- [(value)]="message" />
120
+ <ea-autocomplete
121
+ label="Country"
122
+ placeholder="Start typing…"
123
+ [options]="countries"
124
+ [(value)]="selectedCountry"
125
+ (optionSelected)="onSelect($event)" />
126
126
  ```
127
127
 
128
- <img src="docs/images/textarea.png" alt="Textarea component" width="560" />
128
+ <img src="docs/images/autocomplete.png" alt="Autocomplete component" width="560" />
129
129
 
130
- ---
130
+ </details>
131
131
 
132
- ### Checkbox
132
+ <details>
133
+ <summary><strong>Avatar</strong> — image with initials or icon fallback</summary>
133
134
 
134
- `ControlValueAccessor` with `indeterminate` state support. Sizes: `sm` | `md` | `lg`.
135
+ Sizes: `xs` | `sm` | `md` | `lg` | `xl`. Shapes: `circle` | `square`.
135
136
 
136
137
  ```html
137
- <ea-checkbox label="Accept terms and conditions" [(checked)]="accepted" />
138
+ <ea-avatar src="/photo.jpg" alt="User" size="lg" />
139
+ <ea-avatar initials="MW" shape="square" />
140
+ <ea-avatar /> <!-- shows fallback user icon -->
138
141
  ```
139
142
 
140
- <img src="docs/images/checkbox.png" alt="Checkbox component" width="560" />
143
+ <img src="docs/images/avatar.png" alt="Avatar component" width="560" />
141
144
 
142
- ---
145
+ </details>
143
146
 
144
- ### Switch
147
+ <details>
148
+ <summary><strong>Avatar Editor</strong> — canvas-based image editor with pan, zoom, and crop</summary>
145
149
 
146
- Toggle switch with `ControlValueAccessor`. Sizes: `sm` | `md` | `lg`.
150
+ Drag-and-drop upload, zoom via slider or scroll wheel. Outputs a `Blob` and data URL.
147
151
 
148
152
  ```html
149
- <ea-switch label="Enable notifications" [(checked)]="notificationsOn" />
153
+ <ea-avatar-editor
154
+ shape="circle"
155
+ [canvasSize]="200"
156
+ (cropped)="onCropped($event)" />
150
157
  ```
151
158
 
152
- <img src="docs/images/switch.png" alt="Switch component" width="560" />
159
+ <img src="docs/images/avatar-editor.png" alt="Avatar editor component" width="560" />
153
160
 
154
- ---
161
+ </details>
155
162
 
156
- ### Radio Group
163
+ <details>
164
+ <summary><strong>Badge</strong> — semantic status indicators</summary>
157
165
 
158
- Composite pattern with `ControlValueAccessor`. Supports `vertical` and `horizontal` orientation.
166
+ Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
159
167
 
160
168
  ```html
161
- <ea-radio-group [(value)]="plan">
162
- <ea-radio value="free" label="Free" />
163
- <ea-radio value="pro" label="Pro" />
164
- <ea-radio value="enterprise" label="Enterprise" />
165
- </ea-radio-group>
169
+ <ea-badge variant="success">Active</ea-badge>
170
+ <ea-badge variant="error">Failed</ea-badge>
166
171
  ```
167
172
 
168
- <img src="docs/images/radio.png" alt="Radio group component" width="560" />
173
+ <img src="docs/images/badge.png" alt="Badge component" width="560" />
169
174
 
170
- ---
175
+ </details>
171
176
 
172
- ### Dropdown
177
+ <details>
178
+ <summary><strong>Breadcrumbs</strong> — navigation trail with chevron or slash separators</summary>
173
179
 
174
- Select dropdown with `ControlValueAccessor` and keyboard navigation (Arrow keys, Enter/Space, Escape).
180
+ Separators: `chevron` | `slash`. Items can be links (`href`), buttons (no `href`), or disabled. The last item is automatically rendered as the current page.
175
181
 
176
182
  ```html
177
- <ea-dropdown
178
- label="Country"
179
- placeholder="Select a country…"
180
- [options]="countries"
181
- [(value)]="selectedCountry" />
183
+ <ea-breadcrumbs
184
+ [items]="[
185
+ { label: 'Home', href: '/' },
186
+ { label: 'Products', href: '/products' },
187
+ { label: 'MacBook Pro' }
188
+ ]"
189
+ (itemClicked)="navigate($event)" />
182
190
  ```
183
191
 
184
- <img src="docs/images/dropdown.png" alt="Dropdown component" width="560" />
192
+ <img src="docs/images/breadcrumbs.png" alt="Breadcrumbs component" width="560" />
185
193
 
186
- ---
194
+ </details>
187
195
 
188
- ### Card
196
+ <details>
197
+ <summary><strong>Button</strong> — primary, secondary, ghost, danger variants with loading state</summary>
189
198
 
190
- Content container with variants: `elevated` | `outlined` | `filled`. Padding: `none` | `sm` | `md` | `lg` | `xl`. Customizable shadow via `--ea-card-shadow`.
199
+ Sizes: `sm` | `md` | `lg`. Supports `loading`, `disabled`, and `fullWidth` states.
200
+
201
+ ```html
202
+ <ea-button variant="primary" size="md" [loading]="isSaving" (clicked)="save()">
203
+ Save changes
204
+ </ea-button>
205
+ ```
206
+
207
+ <img src="docs/images/button.png" alt="Button component" width="560" />
208
+
209
+ </details>
210
+
211
+ <details>
212
+ <summary><strong>Card</strong> — content container with elevated, outlined, and filled variants</summary>
213
+
214
+ Padding: `none` | `sm` | `md` | `lg` | `xl`. Customizable shadow via `--ea-card-shadow`.
191
215
 
192
216
  ```html
193
217
  <ea-card variant="elevated">
@@ -202,65 +226,79 @@ Content container with variants: `elevated` | `outlined` | `filled`. Padding: `n
202
226
 
203
227
  <img src="docs/images/card.png" alt="Card component" width="560" />
204
228
 
205
- ---
229
+ </details>
206
230
 
207
- ### Avatar
231
+ <details>
232
+ <summary><strong>Checkbox</strong> — with indeterminate state and ControlValueAccessor</summary>
208
233
 
209
- Image with initials or icon fallback. Sizes: `xs` | `sm` | `md` | `lg` | `xl`. Shapes: `circle` | `square`.
234
+ Sizes: `sm` | `md` | `lg`.
210
235
 
211
236
  ```html
212
- <ea-avatar src="/photo.jpg" alt="User" size="lg" />
213
- <ea-avatar initials="MW" shape="square" />
214
- <ea-avatar /> <!-- shows fallback user icon -->
237
+ <ea-checkbox label="Accept terms and conditions" [(checked)]="accepted" />
215
238
  ```
216
239
 
217
- <img src="docs/images/avatar.png" alt="Avatar component" width="560" />
240
+ <img src="docs/images/checkbox.png" alt="Checkbox component" width="560" />
218
241
 
219
- ---
242
+ </details>
220
243
 
221
- ### Avatar Editor
244
+ <details>
245
+ <summary><strong>Code Input</strong> — verification code entry with auto-advance and paste support</summary>
222
246
 
223
- Canvas-based image editor with drag-and-drop upload, pan, zoom (slider + scroll wheel), and crop export. Outputs a `Blob` and data URL for use with the Avatar component.
247
+ Configurable `length` (default 6). Full `ControlValueAccessor` support.
224
248
 
225
249
  ```html
226
- <ea-avatar-editor
227
- shape="circle"
228
- [canvasSize]="200"
229
- (cropped)="onCropped($event)" />
250
+ <ea-code-input [(value)]="code" [length]="6" (completed)="verify()" />
230
251
  ```
231
252
 
232
- <img src="docs/images/avatar-editor.png" alt="Avatar editor component" width="560" />
253
+ <img src="docs/images/code-input.png" alt="Code input component" width="560" />
233
254
 
234
- ---
255
+ </details>
235
256
 
236
- ### Badge
257
+ <details>
258
+ <summary><strong>Data Table</strong> — sortable columns, sticky headers, density modes</summary>
237
259
 
238
- Semantic status indicators. Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
260
+ Striped, bordered, and hoverable rows. Custom cell templates via `ng-template`. Density: `compact` | `comfortable` | `spacious`. Two-way `sort` binding.
239
261
 
240
262
  ```html
241
- <ea-badge variant="success">Active</ea-badge>
242
- <ea-badge variant="error">Failed</ea-badge>
263
+ <ea-data-table
264
+ [columns]="columns"
265
+ [data]="users"
266
+ [stickyHeader]="true"
267
+ [striped]="true"
268
+ [(sort)]="sortState"
269
+ trackBy="id" />
243
270
  ```
244
271
 
245
- <img src="docs/images/badge.png" alt="Badge component" width="560" />
272
+ <img src="docs/images/data-table.png" alt="Data table component" width="560" />
246
273
 
247
- ---
274
+ </details>
248
275
 
249
- ### Spinner
276
+ <details>
277
+ <summary><strong>Dialog</strong> — native dialog element with focus trapping</summary>
250
278
 
251
- SVG loading indicator with `role="status"` for accessibility. Sizes: `sm` | `md` | `lg`.
279
+ Sizes: `sm` | `md` | `lg` | `full`. Two-way `open` binding.
252
280
 
253
281
  ```html
254
- <ea-spinner size="md" label="Loading data" />
282
+ <ea-button (clicked)="dialogOpen.set(true)">Open</ea-button>
283
+
284
+ <ea-dialog [(open)]="dialogOpen" size="md">
285
+ <span slot="header">Confirm</span>
286
+ <p>Are you sure?</p>
287
+ <span slot="footer">
288
+ <ea-button variant="secondary" (clicked)="dialogOpen.set(false)">Cancel</ea-button>
289
+ <ea-button (clicked)="confirm()">Confirm</ea-button>
290
+ </span>
291
+ </ea-dialog>
255
292
  ```
256
293
 
257
- <img src="docs/images/spinner.png" alt="Spinner component" width="560" />
294
+ <img src="docs/images/dialog.png" alt="Dialog component" width="560" />
258
295
 
259
- ---
296
+ </details>
260
297
 
261
- ### Divider
298
+ <details>
299
+ <summary><strong>Divider</strong> — visual separator with optional label</summary>
262
300
 
263
- Visual separator with optional label. Orientation: `horizontal` | `vertical`.
301
+ Orientation: `horizontal` | `vertical`.
264
302
 
265
303
  ```html
266
304
  <ea-divider />
@@ -270,110 +308,154 @@ Visual separator with optional label. Orientation: `horizontal` | `vertical`.
270
308
 
271
309
  <img src="docs/images/divider.png" alt="Divider component" width="560" />
272
310
 
273
- ---
311
+ </details>
274
312
 
275
- ### Dialog
313
+ <details>
314
+ <summary><strong>Drawer</strong> — side panel using native dialog with focus trapping</summary>
276
315
 
277
- Built on the native `<dialog>` element for built-in focus trapping. Sizes: `sm` | `md` | `lg` | `full`. Two-way `open` binding.
316
+ Positions: `left` | `right` | `top` | `bottom`. Sizes: `sm` | `md` | `lg` | `full`. Two-way `open` binding.
278
317
 
279
318
  ```html
280
- <ea-button (clicked)="dialogOpen.set(true)">Open</ea-button>
319
+ <ea-button (clicked)="drawerOpen.set(true)">Open</ea-button>
281
320
 
282
- <ea-dialog [(open)]="dialogOpen" size="md">
283
- <span slot="header">Confirm</span>
284
- <p>Are you sure?</p>
321
+ <ea-drawer [(open)]="drawerOpen" position="right" size="md">
322
+ <span slot="header">Details</span>
323
+ <p>Drawer body content…</p>
285
324
  <span slot="footer">
286
- <ea-button variant="secondary" (clicked)="dialogOpen.set(false)">Cancel</ea-button>
287
- <ea-button (clicked)="confirm()">Confirm</ea-button>
325
+ <ea-button variant="secondary" (clicked)="drawerOpen.set(false)">Cancel</ea-button>
326
+ <ea-button (clicked)="save()">Save</ea-button>
288
327
  </span>
289
- </ea-dialog>
328
+ </ea-drawer>
290
329
  ```
291
330
 
292
- ---
331
+ <img src="docs/images/drawer.png" alt="Drawer component" width="560" />
293
332
 
294
- ### Tooltip
333
+ </details>
295
334
 
296
- Directive that shows a positioned tooltip on hover and focus. Positions: `top` | `bottom` | `left` | `right`.
335
+ <details>
336
+ <summary><strong>Dropdown</strong> — select with ControlValueAccessor and keyboard navigation</summary>
337
+
338
+ Arrow keys, Enter/Space to select, Escape to close. Sizes: `sm` | `md` | `lg`.
297
339
 
298
340
  ```html
299
- <ea-button eaTooltip="Save your changes" tooltipPosition="top">Save</ea-button>
341
+ <ea-dropdown
342
+ label="Country"
343
+ placeholder="Select a country…"
344
+ [options]="countries"
345
+ [(value)]="selectedCountry" />
300
346
  ```
301
347
 
302
- ---
348
+ <img src="docs/images/dropdown.png" alt="Dropdown component" width="560" />
303
349
 
304
- ### Toast
350
+ </details>
305
351
 
306
- Notification system via injectable `ToastService`. Variants: `default` | `success` | `warning` | `error` | `info`. Auto-dismiss with configurable duration. Full-width on mobile, independent widths on desktop.
352
+ <details>
353
+ <summary><strong>Eagami Wordmark</strong> — branded logo wordmark linking to eagami.com</summary>
307
354
 
308
- ```typescript
309
- import { ToastService } from '@eagami/ui';
355
+ Variants: `logo` (icon only) | `signature` (handcrafted by eagami) | `brand` (eagami with tagline). Three discrete sizes (`sm`, `md`, `lg`) scale both the logo and the text proportionally.
310
356
 
311
- export class MyComponent {
312
- private toast = inject(ToastService);
357
+ ```html
358
+ <ea-eagami-wordmark variant="brand" size="md" />
359
+ ```
313
360
 
314
- save() {
315
- this.toast.success('Changes saved');
316
- }
361
+ <img src="docs/images/eagami-wordmark.png" alt="Eagami Wordmark component" width="560" />
317
362
 
318
- handleError() {
319
- this.toast.error('Something went wrong');
320
- }
321
- }
363
+ </details>
364
+
365
+ <details>
366
+ <summary><strong>Input</strong> — text field with ControlValueAccessor and password toggle</summary>
367
+
368
+ Types: `text` | `email` | `password` | `number` | `search` | `tel` | `url`. Sizes: `sm` | `md` | `lg`.
369
+
370
+ ```html
371
+ <ea-input
372
+ label="Email"
373
+ type="email"
374
+ placeholder="you@example.com"
375
+ hint="We'll never share your email"
376
+ [(value)]="email" />
322
377
  ```
323
378
 
324
- Add the toast outlet once in your root template:
379
+ <img src="docs/images/input.png" alt="Input component" width="560" />
380
+
381
+ </details>
382
+
383
+ <details>
384
+ <summary><strong>Menu</strong> — popup action menu with trigger slot and menu items</summary>
385
+
386
+ Placements: `bottom-start` | `bottom-end` | `top-start` | `top-end`. Menu items support icons, disabled state, and a `danger` variant. Closes on outside click or Escape.
325
387
 
326
388
  ```html
327
- <ea-toast />
389
+ <ea-menu placement="bottom-end">
390
+ <ea-button slot="trigger" variant="secondary">Actions</ea-button>
391
+ <ea-menu-item (itemClicked)="edit()">
392
+ <ea-icon-pencil slot="icon" />
393
+ Edit
394
+ </ea-menu-item>
395
+ <ea-menu-item variant="danger" (itemClicked)="delete()">
396
+ <ea-icon-trash slot="icon" />
397
+ Delete
398
+ </ea-menu-item>
399
+ </ea-menu>
328
400
  ```
329
401
 
330
- <img src="docs/images/toast.png" alt="Toast component" width="560" />
402
+ <img src="docs/images/menu.png" alt="Menu component" width="560" />
331
403
 
332
- ---
404
+ </details>
333
405
 
334
- ### Code Input
406
+ <details>
407
+ <summary><strong>Paginator</strong> — page navigation with configurable page sizes</summary>
335
408
 
336
- Verification code input with auto-advance, paste support, and arrow key navigation. Configurable `length` (default 6). Full `ControlValueAccessor` support.
409
+ Placement: `left` | `center` | `right`. Emits `pageChange` events with current page, page size, and total.
337
410
 
338
411
  ```html
339
- <ea-code-input [(value)]="code" [length]="6" (completed)="verify()" />
412
+ <ea-paginator
413
+ [total]="100"
414
+ [pageSize]="10"
415
+ placement="center"
416
+ (pageChange)="onPageChange($event)" />
340
417
  ```
341
418
 
342
- <img src="docs/images/code-input.png" alt="Code input component" width="560" />
419
+ <img src="docs/images/paginator.png" alt="Paginator component" width="560" />
343
420
 
344
- ---
421
+ </details>
345
422
 
346
- ### Tabs
423
+ <details>
424
+ <summary><strong>Progress Bar</strong> — determinate and indeterminate linear indicator</summary>
347
425
 
348
- Tab navigation with keyboard support (Arrow keys, Home/End). Variants: `underline` | `filled`. Sizes: `sm` | `md` | `lg`.
426
+ Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`. Optional `label` and `showValue` display.
349
427
 
350
428
  ```html
351
- <ea-tabs activeTab="account" variant="underline">
352
- <ea-tab value="account" label="Account">Account content</ea-tab>
353
- <ea-tab value="security" label="Security">Security content</ea-tab>
354
- </ea-tabs>
429
+ <ea-progress-bar [value]="72" label="Uploading" [showValue]="true" />
430
+ <ea-progress-bar variant="success" [value]="100" />
431
+ <ea-progress-bar [indeterminate]="true" label="Processing…" />
355
432
  ```
356
433
 
357
- <img src="docs/images/tabs.png" alt="Tabs component" width="560" />
434
+ <img src="docs/images/progress-bar.png" alt="Progress bar component" width="560" />
358
435
 
359
- ---
436
+ </details>
360
437
 
361
- ### Alert
438
+ <details>
439
+ <summary><strong>Radio Group</strong> — composite pattern with ControlValueAccessor</summary>
362
440
 
363
- Semantic alert banners. Variants: `default` | `success` | `warning` | `error` | `info`. Optional `dismissible` close button with two-way `visible` binding.
441
+ Supports `vertical` and `horizontal` orientation. Sizes: `sm` | `md` | `lg`.
364
442
 
365
443
  ```html
366
- <ea-alert variant="success">Changes saved successfully.</ea-alert>
367
- <ea-alert variant="error" [dismissible]="true">Something went wrong.</ea-alert>
444
+ <ea-radio-group [(value)]="plan">
445
+ <ea-radio value="free" label="Free" />
446
+ <ea-radio value="pro" label="Pro" />
447
+ <ea-radio value="enterprise" label="Enterprise" />
448
+ </ea-radio-group>
368
449
  ```
369
450
 
370
- <img src="docs/images/alert.png" alt="Alert component" width="560" />
451
+ <img src="docs/images/radio.png" alt="Radio group component" width="560" />
371
452
 
372
- ---
453
+ </details>
373
454
 
374
- ### Skeleton
455
+ <details>
456
+ <summary><strong>Skeleton</strong> — loading placeholder with animated pulse</summary>
375
457
 
376
- Loading placeholder with animated pulse. Variants: `text` | `circle` | `rect`. Custom `width` and `height`. Respects `prefers-reduced-motion`.
458
+ Variants: `text` | `circle` | `rect`. Custom `width` and `height`. Respects `prefers-reduced-motion`.
377
459
 
378
460
  ```html
379
461
  <ea-skeleton variant="text" width="200px" />
@@ -383,38 +465,54 @@ Loading placeholder with animated pulse. Variants: `text` | `circle` | `rect`. C
383
465
 
384
466
  <img src="docs/images/skeleton.png" alt="Skeleton component" width="560" />
385
467
 
386
- ---
468
+ </details>
387
469
 
388
- ### Accordion
470
+ <details>
471
+ <summary><strong>Spinner</strong> — SVG loading indicator with accessible role</summary>
389
472
 
390
- Expandable content sections. Supports single or `multi` expand mode. Built-in chevron animation and disabled state.
473
+ Sizes: `sm` | `md` | `lg`.
391
474
 
392
475
  ```html
393
- <ea-accordion>
394
- <ea-accordion-item label="Section 1">Content for section 1</ea-accordion-item>
395
- <ea-accordion-item label="Section 2">Content for section 2</ea-accordion-item>
396
- </ea-accordion>
476
+ <ea-spinner size="md" label="Loading data" />
397
477
  ```
398
478
 
399
- <img src="docs/images/accordion.png" alt="Accordion component" width="560" />
479
+ <img src="docs/images/spinner.png" alt="Spinner component" width="560" />
480
+
481
+ </details>
400
482
 
401
- ### Progress Bar
483
+ <details>
484
+ <summary><strong>Switch</strong> — toggle with ControlValueAccessor</summary>
402
485
 
403
- Linear progress indicator with determinate and indeterminate modes. Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`. Optional `label` and `showValue` display.
486
+ Sizes: `sm` | `md` | `lg`.
404
487
 
405
488
  ```html
406
- <ea-progress-bar [value]="72" label="Uploading" [showValue]="true" />
407
- <ea-progress-bar variant="success" [value]="100" />
408
- <ea-progress-bar [indeterminate]="true" label="Processing…" />
489
+ <ea-switch label="Enable notifications" [(checked)]="notificationsOn" />
409
490
  ```
410
491
 
411
- <img src="docs/images/progress-bar.png" alt="Progress bar component" width="560" />
492
+ <img src="docs/images/switch.png" alt="Switch component" width="560" />
412
493
 
413
- ---
494
+ </details>
414
495
 
415
- ### Tag
496
+ <details>
497
+ <summary><strong>Tabs</strong> — tab navigation with keyboard support</summary>
416
498
 
417
- Inline label with optional remove button. Variants: `default` | `primary` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
499
+ Variants: `underline` | `filled`. Sizes: `sm` | `md` | `lg`.
500
+
501
+ ```html
502
+ <ea-tabs activeTab="account" variant="underline">
503
+ <ea-tab value="account" label="Account">Account content</ea-tab>
504
+ <ea-tab value="security" label="Security">Security content</ea-tab>
505
+ </ea-tabs>
506
+ ```
507
+
508
+ <img src="docs/images/tabs.png" alt="Tabs component" width="560" />
509
+
510
+ </details>
511
+
512
+ <details>
513
+ <summary><strong>Tag</strong> — inline label with optional remove button</summary>
514
+
515
+ Variants: `default` | `primary` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
418
516
 
419
517
  ```html
420
518
  <ea-tag variant="primary">TypeScript</ea-tag>
@@ -423,30 +521,131 @@ Inline label with optional remove button. Variants: `default` | `primary` | `suc
423
521
 
424
522
  <img src="docs/images/tag.png" alt="Tag component" width="560" />
425
523
 
426
- ---
524
+ </details>
525
+
526
+ <details>
527
+ <summary><strong>Textarea</strong> — multiline text with ControlValueAccessor</summary>
528
+
529
+ Mirrors the Input API. Configurable `rows`, `resize` (`none` | `vertical` | `horizontal` | `both`), and `maxlength`.
530
+
531
+ ```html
532
+ <ea-textarea
533
+ label="Message"
534
+ placeholder="Enter your message…"
535
+ hint="Maximum 500 characters"
536
+ [rows]="4"
537
+ [(value)]="message" />
538
+ ```
539
+
540
+ <img src="docs/images/textarea.png" alt="Textarea component" width="560" />
541
+
542
+ </details>
543
+
544
+ <details>
545
+ <summary><strong>Toast</strong> — notification system via injectable ToastService</summary>
546
+
547
+ Variants: `default` | `success` | `warning` | `error` | `info`. Auto-dismiss with configurable duration. Full-width on mobile, independent widths on desktop.
548
+
549
+ ```typescript
550
+ import { ToastService } from '@eagami/ui';
551
+
552
+ export class MyComponent {
553
+ private toast = inject(ToastService);
554
+
555
+ save() {
556
+ this.toast.success('Changes saved');
557
+ }
558
+
559
+ handleError() {
560
+ this.toast.error('Something went wrong');
561
+ }
562
+ }
563
+ ```
564
+
565
+ Add the toast outlet once in your root template:
566
+
567
+ ```html
568
+ <ea-toast />
569
+ ```
570
+
571
+ <img src="docs/images/toast.png" alt="Toast component" width="560" />
572
+
573
+ </details>
574
+
575
+ <details>
576
+ <summary><strong>Tooltip</strong> — positioned tooltip on hover and focus</summary>
577
+
578
+ Positions: `top` | `bottom` | `left` | `right`.
579
+
580
+ ```html
581
+ <ea-button eaTooltip="Save your changes" tooltipPosition="top">Save</ea-button>
582
+ ```
583
+
584
+ <img src="docs/images/tooltip.png" alt="Tooltip component" width="560" />
585
+
586
+ </details>
427
587
 
428
588
  ## Icons
429
589
 
430
- Built-in SVG icon components following the Feather icon style (24x24 viewBox, stroke-based, inherits `currentColor`):
590
+ <details>
591
+ <summary><strong>52 built-in SVG icon components</strong> — Feather-style (24x24, stroke-based, inherits <code>currentColor</code>)</summary>
431
592
 
432
593
  | Tag | Preview |
433
594
  |---|---|
434
595
  | `<ea-icon-alert-circle />` | <img src="docs/images/icons/alert-circle.png" width="48" height="48" alt="alert-circle" /> |
596
+ | `<ea-icon-alert-triangle />` | <img src="docs/images/icons/alert-triangle.png" width="48" height="48" alt="alert-triangle" /> |
597
+ | `<ea-icon-apple />` | <img src="docs/images/icons/apple.png" width="48" height="48" alt="apple" /> |
598
+ | `<ea-icon-arrow-down />` | <img src="docs/images/icons/arrow-down.png" width="48" height="48" alt="arrow-down" /> |
599
+ | `<ea-icon-arrow-left />` | <img src="docs/images/icons/arrow-left.png" width="48" height="48" alt="arrow-left" /> |
600
+ | `<ea-icon-arrow-right />` | <img src="docs/images/icons/arrow-right.png" width="48" height="48" alt="arrow-right" /> |
601
+ | `<ea-icon-arrow-up />` | <img src="docs/images/icons/arrow-up.png" width="48" height="48" alt="arrow-up" /> |
602
+ | `<ea-icon-bell />` | <img src="docs/images/icons/bell.png" width="48" height="48" alt="bell" /> |
603
+ | `<ea-icon-calendar />` | <img src="docs/images/icons/calendar.png" width="48" height="48" alt="calendar" /> |
435
604
  | `<ea-icon-camera />` | <img src="docs/images/icons/camera.png" width="48" height="48" alt="camera" /> |
436
- | `<ea-icon-chevron-down />` | <img src="docs/images/icons/chevron-down.png" width="48" height="48" alt="chevron-down" /> |
437
605
  | `<ea-icon-check />` | <img src="docs/images/icons/check.png" width="48" height="48" alt="check" /> |
606
+ | `<ea-icon-check-circle />` | <img src="docs/images/icons/check-circle.png" width="48" height="48" alt="check-circle" /> |
607
+ | `<ea-icon-chevron-down />` | <img src="docs/images/icons/chevron-down.png" width="48" height="48" alt="chevron-down" /> |
608
+ | `<ea-icon-chevron-left />` | <img src="docs/images/icons/chevron-left.png" width="48" height="48" alt="chevron-left" /> |
609
+ | `<ea-icon-chevron-right />` | <img src="docs/images/icons/chevron-right.png" width="48" height="48" alt="chevron-right" /> |
610
+ | `<ea-icon-chevron-up />` | <img src="docs/images/icons/chevron-up.png" width="48" height="48" alt="chevron-up" /> |
611
+ | `<ea-icon-chevrons-up-down />` | <img src="docs/images/icons/chevrons-up-down.png" width="48" height="48" alt="chevrons-up-down" /> |
612
+ | `<ea-icon-clock />` | <img src="docs/images/icons/clock.png" width="48" height="48" alt="clock" /> |
613
+ | `<ea-icon-copy />` | <img src="docs/images/icons/copy.png" width="48" height="48" alt="copy" /> |
614
+ | `<ea-icon-download />` | <img src="docs/images/icons/download.png" width="48" height="48" alt="download" /> |
615
+ | `<ea-icon-eagami />` | <img src="docs/images/icons/eagami.png" width="48" height="48" alt="eagami" /> |
616
+ | `<ea-icon-external-link />` | <img src="docs/images/icons/external-link.png" width="48" height="48" alt="external-link" /> |
438
617
  | `<ea-icon-eye />` | <img src="docs/images/icons/eye.png" width="48" height="48" alt="eye" /> |
439
618
  | `<ea-icon-eye-off />` | <img src="docs/images/icons/eye-off.png" width="48" height="48" alt="eye-off" /> |
619
+ | `<ea-icon-facebook />` | <img src="docs/images/icons/facebook.png" width="48" height="48" alt="facebook" /> |
620
+ | `<ea-icon-file />` | <img src="docs/images/icons/file.png" width="48" height="48" alt="file" /> |
621
+ | `<ea-icon-filter />` | <img src="docs/images/icons/filter.png" width="48" height="48" alt="filter" /> |
622
+ | `<ea-icon-github />` | <img src="docs/images/icons/github.png" width="48" height="48" alt="github" /> |
440
623
  | `<ea-icon-google />` | <img src="docs/images/icons/google.png" width="48" height="48" alt="google" /> |
624
+ | `<ea-icon-heart />` | <img src="docs/images/icons/heart.png" width="48" height="48" alt="heart" /> |
625
+ | `<ea-icon-image />` | <img src="docs/images/icons/image.png" width="48" height="48" alt="image" /> |
441
626
  | `<ea-icon-info />` | <img src="docs/images/icons/info.png" width="48" height="48" alt="info" /> |
627
+ | `<ea-icon-link />` | <img src="docs/images/icons/link.png" width="48" height="48" alt="link" /> |
442
628
  | `<ea-icon-loader />` | <img src="docs/images/icons/loader.png" width="48" height="48" alt="loader" /> |
629
+ | `<ea-icon-log-out />` | <img src="docs/images/icons/log-out.png" width="48" height="48" alt="log-out" /> |
630
+ | `<ea-icon-mail />` | <img src="docs/images/icons/mail.png" width="48" height="48" alt="mail" /> |
631
+ | `<ea-icon-menu />` | <img src="docs/images/icons/menu.png" width="48" height="48" alt="menu" /> |
632
+ | `<ea-icon-microsoft />` | <img src="docs/images/icons/microsoft.png" width="48" height="48" alt="microsoft" /> |
443
633
  | `<ea-icon-minus />` | <img src="docs/images/icons/minus.png" width="48" height="48" alt="minus" /> |
634
+ | `<ea-icon-more-horizontal />` | <img src="docs/images/icons/more-horizontal.png" width="48" height="48" alt="more-horizontal" /> |
635
+ | `<ea-icon-pencil />` | <img src="docs/images/icons/pencil.png" width="48" height="48" alt="pencil" /> |
444
636
  | `<ea-icon-plus />` | <img src="docs/images/icons/plus.png" width="48" height="48" alt="plus" /> |
445
637
  | `<ea-icon-rotate-ccw />` | <img src="docs/images/icons/rotate-ccw.png" width="48" height="48" alt="rotate-ccw" /> |
638
+ | `<ea-icon-search />` | <img src="docs/images/icons/search.png" width="48" height="48" alt="search" /> |
639
+ | `<ea-icon-settings />` | <img src="docs/images/icons/settings.png" width="48" height="48" alt="settings" /> |
640
+ | `<ea-icon-star />` | <img src="docs/images/icons/star.png" width="48" height="48" alt="star" /> |
446
641
  | `<ea-icon-trash />` | <img src="docs/images/icons/trash.png" width="48" height="48" alt="trash" /> |
447
642
  | `<ea-icon-upload />` | <img src="docs/images/icons/upload.png" width="48" height="48" alt="upload" /> |
448
643
  | `<ea-icon-user />` | <img src="docs/images/icons/user.png" width="48" height="48" alt="user" /> |
449
644
  | `<ea-icon-x />` | <img src="docs/images/icons/x.png" width="48" height="48" alt="x" /> |
645
+ | `<ea-icon-x-circle />` | <img src="docs/images/icons/x-circle.png" width="48" height="48" alt="x-circle" /> |
646
+ | `<ea-icon-x-twitter />` | <img src="docs/images/icons/x-twitter.png" width="48" height="48" alt="x-twitter" /> |
647
+
648
+ </details>
450
649
 
451
650
  ## Theming
452
651
 
@@ -483,7 +682,7 @@ See [`src/styles/tokens/`](src/styles/tokens/) for the full token reference.
483
682
 
484
683
  ```bash
485
684
  pnpm install # Install dependencies
486
- pnpm start # Run sandbox dev app
685
+ pnpm sandbox # Run sandbox dev app
487
686
  pnpm storybook # Run Storybook
488
687
  pnpm test # Run tests
489
688
  pnpm build # Build the library