@eagami/ui 0.11.1 → 1.0.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
@@ -2,32 +2,17 @@
2
2
  <img src="docs/images/eagami-header.png" alt="eagami design system — elegant web design" width="800" />
3
3
  </p>
4
4
 
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@eagami/ui"><img src="https://img.shields.io/npm/v/@eagami/ui.svg" alt="npm version" /></a>
7
+ <a href="https://github.com/mwiraszka/eagami-design-system/actions/workflows/ci.yml"><img src="https://github.com/mwiraszka/eagami-design-system/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
8
+ <a href="https://github.com/mwiraszka/eagami-design-system/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@eagami/ui.svg" alt="license" /></a>
9
+ </p>
10
+
5
11
  A lightweight, accessible Angular component library built on CSS custom properties, with portable design system integration guides for Flutter and React ([see more](#framework-integration)). Ready to use out of the box — install, import, and start building.
6
12
 
7
13
  Every component is standalone, signal-based, and fully themed via design tokens. No wrapping modules, no complex setup, no runtime style conflicts. Designed to be AI-friendly with clear APIs, consistent patterns, and comprehensive documentation that makes it easy for both developers and AI assistants to work with.
8
14
 
9
- ## Why @eagami/ui?
10
-
11
- **Approx. component sizes (gzipped)¹**
12
-
13
- | Component | **@eagami/ui** | Angular Material | PrimeNG | ng-bootstrap | ng-zorro |
14
- |---|---|---|---|---|---|
15
- | Button | ~2 KB | ~12 KB | ~8 KB | ~10 KB | ~18 KB |
16
- | Input | ~4 KB | ~25 KB | ~14 KB | ~20 KB | ~35 KB |
17
- | Checkbox | ~2 KB | ~15 KB | ~9 KB | ~12 KB | ~22 KB |
18
- | Dropdown / Select | ~4 KB | ~30 KB | ~20 KB | ~25 KB | ~40 KB |
19
- | Dialog / Modal | ~2 KB | ~20 KB | ~15 KB | ~18 KB | ~30 KB |
20
-
21
- > ¹ Approximate — depends on configuration, tree-shaking, and Angular version. @eagami/ui sizes measured from production build.
22
-
23
- | | **@eagami/ui** | Angular Material | PrimeNG | ng-bootstrap | ng-zorro |
24
- |---|---|---|---|---|---|
25
- | External CSS dependency | No | No | Optional | Bootstrap (~30 KB) | No |
26
- | CSS custom property theming | Yes | Partial (MDC) | Yes | No (Sass vars) | No |
27
- | Signals-first API | Yes | Partial | No | No | No |
28
- | `OnPush` by default | Yes | Partial | No | No | No |
29
- | Runtime dependencies | 0 | CDK + animations | PrimeIcons² | Bootstrap CSS | CDK |
30
- > ² PrimeNG components are tree-shakable but PrimeIcons font (~50 KB) is typically included globally.
15
+ **Component reference and live examples:** [eagami.com/ui](https://eagami.com/ui)
31
16
 
32
17
  ## Features
33
18
 
@@ -37,9 +22,9 @@ Every component is standalone, signal-based, and fully themed via design tokens.
37
22
  - **Full theming via CSS custom properties** — override any design token on `:root` or scope overrides to individual components
38
23
  - **Dark mode built in** — automatic via `prefers-color-scheme`, no extra setup
39
24
  - **Accessible** — ARIA attributes, keyboard navigation, focus management, and screen reader support throughout
40
- - **Form-ready** — `ControlValueAccessor` on all form components (Input, Textarea, Checkbox, Switch, Radio, Dropdown)
41
- - **Lightweight** — zero runtime dependencies beyond Angular
25
+ - **Form-ready** — `ControlValueAccessor` on every form control (input, textarea, checkbox, switch, radio, dropdown, autocomplete, date picker, slider, code input, segmented)
42
26
  - **Tree-shakeable** — only the components you import end up in your bundle
27
+ - **Tiny** — the entire library is **70 KB gzipped**, and only the components you import end up in your bundle
43
28
 
44
29
  ## Installation
45
30
 
@@ -79,602 +64,23 @@ export class MyComponent {
79
64
 
80
65
  No modules to register, no providers to configure. Every component works the same way — import it, drop it in your template.
81
66
 
82
- ## Components
83
-
84
- <details>
85
- <summary><strong>Accordion</strong> — expandable content sections</summary>
86
-
87
- Supports single or `multi` expand mode. Built-in chevron animation and disabled state.
88
-
89
- ```html
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>
94
- ```
95
-
96
- <img src="docs/images/accordion.png" alt="Accordion component" width="560" />
97
-
98
- </details>
99
-
100
- <details>
101
- <summary><strong>Alert</strong> — semantic alert banners with optional dismiss</summary>
102
-
103
- Variants: `default` | `success` | `warning` | `error` | `info`. Two-way `visible` binding.
104
-
105
- ```html
106
- <ea-alert variant="success">Changes saved successfully.</ea-alert>
107
- <ea-alert variant="error" [dismissible]="true">Something went wrong.</ea-alert>
108
- ```
109
-
110
- <img src="docs/images/alert.png" alt="Alert component" width="560" />
111
-
112
- </details>
113
-
114
- <details>
115
- <summary><strong>Autocomplete</strong> — text input with filtered suggestion dropdown</summary>
116
-
117
- Arrow key navigation, case-insensitive substring matching, configurable `minLength` and `maxResults`. Full `ControlValueAccessor` support.
118
-
119
- ```html
120
- <ea-autocomplete
121
- label="Country"
122
- placeholder="Start typing…"
123
- [options]="countries"
124
- [(value)]="selectedCountry"
125
- (optionSelected)="onSelect($event)" />
126
- ```
127
-
128
- <img src="docs/images/autocomplete.png" alt="Autocomplete component" width="560" />
129
-
130
- </details>
131
-
132
- <details>
133
- <summary><strong>Avatar</strong> — image with initials or icon fallback</summary>
134
-
135
- Sizes: `xs` | `sm` | `md` | `lg` | `xl`. Shapes: `circle` | `square`.
136
-
137
- ```html
138
- <ea-avatar src="/photo.jpg" alt="User" size="lg" />
139
- <ea-avatar initials="MW" shape="square" />
140
- <ea-avatar /> <!-- shows fallback user icon -->
141
- ```
142
-
143
- <img src="docs/images/avatar.png" alt="Avatar component" width="560" />
144
-
145
- </details>
146
-
147
- <details>
148
- <summary><strong>Avatar editor</strong> — canvas-based image editor with pan, zoom, and crop</summary>
149
-
150
- Drag-and-drop upload, zoom via slider or scroll wheel. Outputs a `Blob` and data URL.
151
-
152
- ```html
153
- <ea-avatar-editor
154
- shape="circle"
155
- [canvasSize]="200"
156
- (cropped)="onCropped($event)" />
157
- ```
158
-
159
- <img src="docs/images/avatar-editor.png" alt="Avatar editor component" width="560" />
160
-
161
- </details>
162
-
163
- <details>
164
- <summary><strong>Badge</strong> — semantic status indicators</summary>
165
-
166
- Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
167
-
168
- ```html
169
- <ea-badge variant="success">Active</ea-badge>
170
- <ea-badge variant="error">Failed</ea-badge>
171
- ```
172
-
173
- <img src="docs/images/badge.png" alt="Badge component" width="560" />
174
-
175
- </details>
176
-
177
- <details>
178
- <summary><strong>Breadcrumbs</strong> — navigation trail with chevron or slash separators</summary>
179
-
180
- Separators: `chevron` | `slash`. Items can be links (`href`), buttons (no `href`), or disabled. The last item is automatically rendered as the current page.
181
-
182
- ```html
183
- <ea-breadcrumbs
184
- [items]="[
185
- { label: 'Home', href: '/' },
186
- { label: 'Products', href: '/products' },
187
- { label: 'MacBook Pro' }
188
- ]"
189
- (itemClicked)="navigate($event)" />
190
- ```
191
-
192
- <img src="docs/images/breadcrumbs.png" alt="Breadcrumbs component" width="560" />
193
-
194
- </details>
195
-
196
- <details>
197
- <summary><strong>Button</strong> — primary, secondary, ghost, danger variants with loading state</summary>
198
-
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`.
215
-
216
- ```html
217
- <ea-card variant="elevated">
218
- <span eaCardHeader>Card Title</span>
219
- Card body content goes here.
220
- <span eaCardFooter>
221
- <ea-button variant="secondary" size="sm">Cancel</ea-button>
222
- <ea-button size="sm">Save</ea-button>
223
- </span>
224
- </ea-card>
225
- ```
226
-
227
- <img src="docs/images/card.png" alt="Card component" width="560" />
228
-
229
- </details>
230
-
231
- <details>
232
- <summary><strong>Checkbox</strong> — with indeterminate state and ControlValueAccessor</summary>
233
-
234
- Sizes: `sm` | `md` | `lg`.
235
-
236
- ```html
237
- <ea-checkbox label="Accept terms and conditions" [(checked)]="accepted" />
238
- ```
239
-
240
- <img src="docs/images/checkbox.png" alt="Checkbox component" width="560" />
241
-
242
- </details>
243
-
244
- <details>
245
- <summary><strong>Code input</strong> — verification code entry with auto-advance and paste support</summary>
246
-
247
- Configurable `length` (default 6). Full `ControlValueAccessor` support.
248
-
249
- ```html
250
- <ea-code-input [(value)]="code" [length]="6" (completed)="verify()" />
251
- ```
252
-
253
- <img src="docs/images/code-input.png" alt="Code input component" width="560" />
254
-
255
- </details>
256
-
257
- <details>
258
- <summary><strong>Data table</strong> — sortable columns, sticky headers, density modes</summary>
259
-
260
- Striped, bordered, and hoverable rows. Custom cell templates via `ng-template`. Density: `compact` | `comfortable` | `spacious`. Two-way `sort` binding.
261
-
262
- ```html
263
- <ea-data-table
264
- [columns]="columns"
265
- [data]="users"
266
- [stickyHeader]="true"
267
- [striped]="true"
268
- [(sort)]="sortState"
269
- trackBy="id" />
270
- ```
271
-
272
- <img src="docs/images/data-table.png" alt="Data table component" width="560" />
273
-
274
- </details>
275
-
276
- <details>
277
- <summary><strong>Date picker</strong> — calendar popover with keyboard navigation and min/max bounds</summary>
278
-
279
- Sizes: `sm` | `md` | `lg`. Formats: `short` | `medium` | `long` (locale-aware via `Intl.DateTimeFormat`). Configurable week start (Sunday or Monday). Full keyboard navigation (arrows, PageUp/PageDown, Home/End, Enter, Escape) and `ControlValueAccessor` integration.
280
-
281
- ```html
282
- <ea-date-picker
283
- label="Appointment"
284
- placeholder="Pick a date…"
285
- format="medium"
286
- [minDate]="today"
287
- [(value)]="appointmentDate" />
288
- ```
289
-
290
- <img src="docs/images/date-picker.png" alt="Date picker component" width="560" />
291
-
292
- </details>
293
-
294
- <details>
295
- <summary><strong>Dialog</strong> — native dialog element with focus trapping</summary>
296
-
297
- Sizes: `sm` | `md` | `lg` | `full`. Two-way `open` binding.
298
-
299
- ```html
300
- <ea-button (clicked)="dialogOpen.set(true)">Open</ea-button>
301
-
302
- <ea-dialog [(open)]="dialogOpen" size="md">
303
- <span slot="header">Confirm</span>
304
- <p>Are you sure?</p>
305
- <span slot="footer">
306
- <ea-button variant="secondary" (clicked)="dialogOpen.set(false)">Cancel</ea-button>
307
- <ea-button (clicked)="confirm()">Confirm</ea-button>
308
- </span>
309
- </ea-dialog>
310
- ```
311
-
312
- <img src="docs/images/dialog.png" alt="Dialog component" width="560" />
313
-
314
- </details>
315
-
316
- <details>
317
- <summary><strong>Divider</strong> — visual separator with optional label</summary>
318
-
319
- Orientation: `horizontal` | `vertical`.
320
-
321
- ```html
322
- <ea-divider />
323
- <ea-divider label="or" />
324
- <ea-divider orientation="vertical" />
325
- ```
326
-
327
- <img src="docs/images/divider.png" alt="Divider component" width="560" />
328
-
329
- </details>
330
-
331
- <details>
332
- <summary><strong>Drawer</strong> — side panel using native dialog with focus trapping</summary>
333
-
334
- Positions: `left` | `right` | `top` | `bottom`. Sizes: `sm` | `md` | `lg` | `full`. Two-way `open` binding.
335
-
336
- ```html
337
- <ea-button (clicked)="drawerOpen.set(true)">Open</ea-button>
338
-
339
- <ea-drawer [(open)]="drawerOpen" position="right" size="md">
340
- <span slot="header">Details</span>
341
- <p>Drawer body content…</p>
342
- <span slot="footer">
343
- <ea-button variant="secondary" (clicked)="drawerOpen.set(false)">Cancel</ea-button>
344
- <ea-button (clicked)="save()">Save</ea-button>
345
- </span>
346
- </ea-drawer>
347
- ```
348
-
349
- <img src="docs/images/drawer.png" alt="Drawer component" width="560" />
67
+ > **Upgrading from v0.x?** See [MIGRATION.md](MIGRATION.md) for the full list of breaking changes and a find/replace table that covers most upgrades in one pass.
350
68
 
351
- </details>
69
+ ## What's included
352
70
 
353
- <details>
354
- <summary><strong>Dropdown</strong>select with ControlValueAccessor and keyboard navigation</summary>
71
+ - **Form controls** — Input, Textarea, Checkbox, Switch, Radio, Dropdown, Autocomplete, Date picker, Slider, Code input, Segmented
72
+ - **Overlays** Dialog, Drawer, Tooltip, Menu, Toast
73
+ - **Navigation** — Tabs, Breadcrumbs, Paginator, Accordion
74
+ - **Display** — Card, Badge, Tag, Alert, Avatar, Skeleton, Spinner, Progress bar, Empty state, Divider, Eagami wordmark
75
+ - **Data** — Data table
76
+ - **Specialised** — Avatar editor
77
+ - **Icons** — 52 stroke-based SVG icon components (`<ea-icon-*>`)
355
78
 
356
- Arrow keys, Enter/Space to select, Escape to close. Sizes: `sm` | `md` | `lg`.
357
-
358
- ```html
359
- <ea-dropdown
360
- label="Country"
361
- placeholder="Select a country…"
362
- [options]="countries"
363
- [(value)]="selectedCountry" />
364
- ```
365
-
366
- <img src="docs/images/dropdown.png" alt="Dropdown component" width="560" />
367
-
368
- </details>
369
-
370
- <details>
371
- <summary><strong>Eagami wordmark</strong> — branded logo wordmark linking to eagami.com</summary>
372
-
373
- | Variant | Text |
374
- | --- | --- |
375
- | `1` | eagami |
376
- | `2` | handcrafted by eagami |
377
- | `3` | eagami design system |
378
- | `4` | eagami design system — elegant web design |
379
-
380
- Layout: `stacked` (default, multi-line) | `inline` (single line, uniform font size — adds em dash before tagline). Size is a number (pixels) for continuous scaling; the logo, brand text, and secondary text all scale proportionally.
381
-
382
- ```html
383
- <ea-eagami-wordmark [variant]="4" [size]="96" />
384
- ```
385
-
386
- <img src="docs/images/eagami-wordmark.png" alt="Eagami wordmark component" width="560" />
387
-
388
- </details>
389
-
390
- <details>
391
- <summary><strong>Input</strong> — text field with ControlValueAccessor and password toggle</summary>
392
-
393
- Types: `text` | `email` | `password` | `number` | `search` | `tel` | `url`. Sizes: `sm` | `md` | `lg`.
394
-
395
- ```html
396
- <ea-input
397
- label="Email"
398
- type="email"
399
- placeholder="you@example.com"
400
- hint="We'll never share your email"
401
- [(value)]="email" />
402
- ```
403
-
404
- <img src="docs/images/input.png" alt="Input component" width="560" />
405
-
406
- </details>
407
-
408
- <details>
409
- <summary><strong>Menu</strong> — popup action menu with trigger slot and menu items</summary>
410
-
411
- 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.
412
-
413
- ```html
414
- <ea-menu placement="bottom-end">
415
- <ea-button slot="trigger" variant="secondary">Actions</ea-button>
416
- <ea-menu-item (itemClicked)="edit()">
417
- <ea-icon-pencil slot="icon" />
418
- Edit
419
- </ea-menu-item>
420
- <ea-menu-item variant="danger" (itemClicked)="delete()">
421
- <ea-icon-trash slot="icon" />
422
- Delete
423
- </ea-menu-item>
424
- </ea-menu>
425
- ```
426
-
427
- <img src="docs/images/menu.png" alt="Menu component" width="560" />
428
-
429
- </details>
430
-
431
- <details>
432
- <summary><strong>Paginator</strong> — page navigation with configurable page sizes</summary>
433
-
434
- Placement: `left` | `center` | `right`. Emits `pageChange` events with current page, page size, and total.
435
-
436
- ```html
437
- <ea-paginator
438
- [total]="100"
439
- [pageSize]="10"
440
- placement="center"
441
- (pageChange)="onPageChange($event)" />
442
- ```
443
-
444
- <img src="docs/images/paginator.png" alt="Paginator component" width="560" />
445
-
446
- </details>
447
-
448
- <details>
449
- <summary><strong>Progress bar</strong> — determinate and indeterminate linear indicator</summary>
450
-
451
- Variants: `default` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`. Optional `label` and `showValue` display.
452
-
453
- ```html
454
- <ea-progress-bar [value]="72" label="Uploading" [showValue]="true" />
455
- <ea-progress-bar variant="success" [value]="100" />
456
- <ea-progress-bar [indeterminate]="true" label="Processing…" />
457
- ```
458
-
459
- <img src="docs/images/progress-bar.png" alt="Progress bar component" width="560" />
460
-
461
- </details>
462
-
463
- <details>
464
- <summary><strong>Radio Group</strong> — composite pattern with ControlValueAccessor</summary>
465
-
466
- Supports `vertical` and `horizontal` orientation. Sizes: `sm` | `md` | `lg`.
467
-
468
- ```html
469
- <ea-radio-group [(value)]="plan">
470
- <ea-radio value="free" label="Free" />
471
- <ea-radio value="pro" label="Pro" />
472
- <ea-radio value="enterprise" label="Enterprise" />
473
- </ea-radio-group>
474
- ```
475
-
476
- <img src="docs/images/radio.png" alt="Radio group component" width="560" />
477
-
478
- </details>
479
-
480
- <details>
481
- <summary><strong>Skeleton</strong> — loading placeholder with animated pulse</summary>
482
-
483
- Variants: `text` | `circle` | `rect`. Custom `width` and `height`. Respects `prefers-reduced-motion`.
484
-
485
- ```html
486
- <ea-skeleton variant="text" width="200px" />
487
- <ea-skeleton variant="circle" width="48px" height="48px" />
488
- <ea-skeleton variant="rect" width="100%" height="120px" />
489
- ```
490
-
491
- <img src="docs/images/skeleton.png" alt="Skeleton component" width="560" />
492
-
493
- </details>
494
-
495
- <details>
496
- <summary><strong>Spinner</strong> — SVG loading indicator with accessible role</summary>
497
-
498
- Sizes: `sm` | `md` | `lg`.
499
-
500
- ```html
501
- <ea-spinner size="md" label="Loading data" />
502
- ```
503
-
504
- <img src="docs/images/spinner.png" alt="Spinner component" width="560" />
505
-
506
- </details>
507
-
508
- <details>
509
- <summary><strong>Switch</strong> — toggle with ControlValueAccessor</summary>
510
-
511
- Sizes: `sm` | `md` | `lg`.
512
-
513
- ```html
514
- <ea-switch label="Enable notifications" [(checked)]="notificationsOn" />
515
- ```
516
-
517
- <img src="docs/images/switch.png" alt="Switch component" width="560" />
518
-
519
- </details>
520
-
521
- <details>
522
- <summary><strong>Tabs</strong> — tab navigation with keyboard support</summary>
523
-
524
- Variants: `underline` | `filled`. Sizes: `sm` | `md` | `lg`.
525
-
526
- ```html
527
- <ea-tabs activeTab="account" variant="underline">
528
- <ea-tab value="account" label="Account">Account content</ea-tab>
529
- <ea-tab value="security" label="Security">Security content</ea-tab>
530
- </ea-tabs>
531
- ```
532
-
533
- <img src="docs/images/tabs.png" alt="Tabs component" width="560" />
534
-
535
- </details>
536
-
537
- <details>
538
- <summary><strong>Tag</strong> — inline label with optional remove button</summary>
539
-
540
- Variants: `default` | `primary` | `success` | `warning` | `error` | `info`. Sizes: `sm` | `md` | `lg`.
541
-
542
- ```html
543
- <ea-tag variant="primary">TypeScript</ea-tag>
544
- <ea-tag variant="success" [removable]="true" (removed)="onRemove()">Active</ea-tag>
545
- ```
546
-
547
- <img src="docs/images/tag.png" alt="Tag component" width="560" />
548
-
549
- </details>
550
-
551
- <details>
552
- <summary><strong>Textarea</strong> — multiline text with ControlValueAccessor</summary>
553
-
554
- Mirrors the Input API. Configurable `rows`, `resize` (`none` | `vertical` | `horizontal` | `both`), and `maxlength`.
555
-
556
- ```html
557
- <ea-textarea
558
- label="Message"
559
- placeholder="Enter your message…"
560
- hint="Maximum 500 characters"
561
- [rows]="4"
562
- [(value)]="message" />
563
- ```
564
-
565
- <img src="docs/images/textarea.png" alt="Textarea component" width="560" />
566
-
567
- </details>
568
-
569
- <details>
570
- <summary><strong>Toast</strong> — notification system via injectable ToastService</summary>
571
-
572
- Variants: `default` | `success` | `warning` | `error` | `info`. Auto-dismiss with configurable duration. Full-width on mobile, independent widths on desktop.
573
-
574
- ```typescript
575
- import { ToastService } from '@eagami/ui';
576
-
577
- export class MyComponent {
578
- private toast = inject(ToastService);
579
-
580
- save() {
581
- this.toast.success('Changes saved');
582
- }
583
-
584
- handleError() {
585
- this.toast.error('Something went wrong');
586
- }
587
- }
588
- ```
589
-
590
- Add the toast outlet once in your root template:
591
-
592
- ```html
593
- <ea-toast />
594
- ```
595
-
596
- <img src="docs/images/toast.png" alt="Toast component" width="560" />
597
-
598
- </details>
599
-
600
- <details>
601
- <summary><strong>Tooltip</strong> — positioned tooltip on hover and focus</summary>
602
-
603
- Positions: `top` | `bottom` | `left` | `right`.
604
-
605
- ```html
606
- <ea-button eaTooltip="Save your changes" tooltipPosition="top">Save</ea-button>
607
- ```
608
-
609
- <img src="docs/images/tooltip.png" alt="Tooltip component" width="560" />
610
-
611
- </details>
612
-
613
- ## Icons
614
-
615
- <details>
616
- <summary><strong>52 built-in SVG icon components</strong> — Feather-style (24x24, stroke-based, inherits <code>currentColor</code>)</summary>
617
-
618
- | Tag | Preview |
619
- |---|---|
620
- | `<ea-icon-alert-circle />` | <img src="docs/images/icons/alert-circle.png" width="48" height="48" alt="alert-circle" /> |
621
- | `<ea-icon-alert-triangle />` | <img src="docs/images/icons/alert-triangle.png" width="48" height="48" alt="alert-triangle" /> |
622
- | `<ea-icon-apple />` | <img src="docs/images/icons/apple.png" width="48" height="48" alt="apple" /> |
623
- | `<ea-icon-arrow-down />` | <img src="docs/images/icons/arrow-down.png" width="48" height="48" alt="arrow-down" /> |
624
- | `<ea-icon-arrow-left />` | <img src="docs/images/icons/arrow-left.png" width="48" height="48" alt="arrow-left" /> |
625
- | `<ea-icon-arrow-right />` | <img src="docs/images/icons/arrow-right.png" width="48" height="48" alt="arrow-right" /> |
626
- | `<ea-icon-arrow-up />` | <img src="docs/images/icons/arrow-up.png" width="48" height="48" alt="arrow-up" /> |
627
- | `<ea-icon-bell />` | <img src="docs/images/icons/bell.png" width="48" height="48" alt="bell" /> |
628
- | `<ea-icon-calendar />` | <img src="docs/images/icons/calendar.png" width="48" height="48" alt="calendar" /> |
629
- | `<ea-icon-camera />` | <img src="docs/images/icons/camera.png" width="48" height="48" alt="camera" /> |
630
- | `<ea-icon-check />` | <img src="docs/images/icons/check.png" width="48" height="48" alt="check" /> |
631
- | `<ea-icon-check-circle />` | <img src="docs/images/icons/check-circle.png" width="48" height="48" alt="check-circle" /> |
632
- | `<ea-icon-chevron-down />` | <img src="docs/images/icons/chevron-down.png" width="48" height="48" alt="chevron-down" /> |
633
- | `<ea-icon-chevron-left />` | <img src="docs/images/icons/chevron-left.png" width="48" height="48" alt="chevron-left" /> |
634
- | `<ea-icon-chevron-right />` | <img src="docs/images/icons/chevron-right.png" width="48" height="48" alt="chevron-right" /> |
635
- | `<ea-icon-chevron-up />` | <img src="docs/images/icons/chevron-up.png" width="48" height="48" alt="chevron-up" /> |
636
- | `<ea-icon-chevrons-up-down />` | <img src="docs/images/icons/chevrons-up-down.png" width="48" height="48" alt="chevrons-up-down" /> |
637
- | `<ea-icon-clock />` | <img src="docs/images/icons/clock.png" width="48" height="48" alt="clock" /> |
638
- | `<ea-icon-copy />` | <img src="docs/images/icons/copy.png" width="48" height="48" alt="copy" /> |
639
- | `<ea-icon-download />` | <img src="docs/images/icons/download.png" width="48" height="48" alt="download" /> |
640
- | `<ea-icon-eagami />` | <img src="docs/images/icons/eagami.png" width="48" height="48" alt="eagami" /> |
641
- | `<ea-icon-external-link />` | <img src="docs/images/icons/external-link.png" width="48" height="48" alt="external-link" /> |
642
- | `<ea-icon-eye />` | <img src="docs/images/icons/eye.png" width="48" height="48" alt="eye" /> |
643
- | `<ea-icon-eye-off />` | <img src="docs/images/icons/eye-off.png" width="48" height="48" alt="eye-off" /> |
644
- | `<ea-icon-facebook />` | <img src="docs/images/icons/facebook.png" width="48" height="48" alt="facebook" /> |
645
- | `<ea-icon-file />` | <img src="docs/images/icons/file.png" width="48" height="48" alt="file" /> |
646
- | `<ea-icon-filter />` | <img src="docs/images/icons/filter.png" width="48" height="48" alt="filter" /> |
647
- | `<ea-icon-github />` | <img src="docs/images/icons/github.png" width="48" height="48" alt="github" /> |
648
- | `<ea-icon-google />` | <img src="docs/images/icons/google.png" width="48" height="48" alt="google" /> |
649
- | `<ea-icon-heart />` | <img src="docs/images/icons/heart.png" width="48" height="48" alt="heart" /> |
650
- | `<ea-icon-image />` | <img src="docs/images/icons/image.png" width="48" height="48" alt="image" /> |
651
- | `<ea-icon-info />` | <img src="docs/images/icons/info.png" width="48" height="48" alt="info" /> |
652
- | `<ea-icon-link />` | <img src="docs/images/icons/link.png" width="48" height="48" alt="link" /> |
653
- | `<ea-icon-loader />` | <img src="docs/images/icons/loader.png" width="48" height="48" alt="loader" /> |
654
- | `<ea-icon-log-out />` | <img src="docs/images/icons/log-out.png" width="48" height="48" alt="log-out" /> |
655
- | `<ea-icon-mail />` | <img src="docs/images/icons/mail.png" width="48" height="48" alt="mail" /> |
656
- | `<ea-icon-menu />` | <img src="docs/images/icons/menu.png" width="48" height="48" alt="menu" /> |
657
- | `<ea-icon-microsoft />` | <img src="docs/images/icons/microsoft.png" width="48" height="48" alt="microsoft" /> |
658
- | `<ea-icon-minus />` | <img src="docs/images/icons/minus.png" width="48" height="48" alt="minus" /> |
659
- | `<ea-icon-more-horizontal />` | <img src="docs/images/icons/more-horizontal.png" width="48" height="48" alt="more-horizontal" /> |
660
- | `<ea-icon-pencil />` | <img src="docs/images/icons/pencil.png" width="48" height="48" alt="pencil" /> |
661
- | `<ea-icon-plus />` | <img src="docs/images/icons/plus.png" width="48" height="48" alt="plus" /> |
662
- | `<ea-icon-rotate-ccw />` | <img src="docs/images/icons/rotate-ccw.png" width="48" height="48" alt="rotate-ccw" /> |
663
- | `<ea-icon-search />` | <img src="docs/images/icons/search.png" width="48" height="48" alt="search" /> |
664
- | `<ea-icon-settings />` | <img src="docs/images/icons/settings.png" width="48" height="48" alt="settings" /> |
665
- | `<ea-icon-star />` | <img src="docs/images/icons/star.png" width="48" height="48" alt="star" /> |
666
- | `<ea-icon-trash />` | <img src="docs/images/icons/trash.png" width="48" height="48" alt="trash" /> |
667
- | `<ea-icon-upload />` | <img src="docs/images/icons/upload.png" width="48" height="48" alt="upload" /> |
668
- | `<ea-icon-user />` | <img src="docs/images/icons/user.png" width="48" height="48" alt="user" /> |
669
- | `<ea-icon-x />` | <img src="docs/images/icons/x.png" width="48" height="48" alt="x" /> |
670
- | `<ea-icon-x-circle />` | <img src="docs/images/icons/x-circle.png" width="48" height="48" alt="x-circle" /> |
671
- | `<ea-icon-x-twitter />` | <img src="docs/images/icons/x-twitter.png" width="48" height="48" alt="x-twitter" /> |
672
-
673
- </details>
79
+ Full per-component documentation props, events, examples, and accessibility notes lives at **[eagami.com/ui](https://eagami.com/ui)**.
674
80
 
675
81
  ## Theming
676
82
 
677
- All visual properties are controlled through CSS custom properties defined on `:root`. Override any token to customize the entire library:
83
+ All visual properties are controlled through CSS custom properties defined on `:root`. Override any token to customise the entire library:
678
84
 
679
85
  ```css
680
86
  :root {
@@ -712,12 +118,31 @@ Both files contain the full token set, mandatory design rules, theme setup, usag
712
118
  | `@angular/core` | `^21.0.0` |
713
119
  | `@angular/forms` | `^21.0.0` |
714
120
 
121
+ ## Browser support
122
+
123
+ Components are authored for modern evergreen browsers and follow Angular's default [browserslist](https://github.com/browserslist/browserslist) configuration. Specifically:
124
+
125
+ - **Chrome / Edge** — last 2 stable versions
126
+ - **Firefox** — last 2 stable versions, plus the current ESR
127
+ - **Safari** — last 2 stable versions
128
+ - **Modern mobile browsers** (iOS Safari, Chrome Android)
129
+
130
+ The library is published as ES2022. Internet Explorer and pre-Chromium Edge are not supported.
131
+
132
+ ### Runtime requirements
133
+
134
+ | Tool | Minimum |
135
+ |------|---------|
136
+ | Node.js | 20.x (for build/dev tooling) |
137
+ | Angular | 21.0 |
138
+ | TypeScript | 5.5 |
139
+
715
140
  ## Development
716
141
 
717
142
  ```bash
718
143
  pnpm install # Install dependencies
719
- pnpm sandbox # Run sandbox dev app
720
- pnpm storybook # Run Storybook
144
+ pnpm sandbox # Run sandbox dev app on http://localhost:4200
145
+ pnpm storybook # Run Storybook on http://localhost:6006
721
146
  pnpm test # Run tests
722
147
  pnpm build # Build the library
723
148
  pnpm lint # Lint