ps-helix 5.1.3 → 6.0.1

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,1188 +1,1188 @@
1
- # Helix Design System
2
-
3
- A comprehensive Angular component library built with Angular 21+ featuring modern design patterns, accessibility-first development, and optimal developer experience.
4
-
5
- [![npm version](https://img.shields.io/badge/npm-5.1.3-blue.svg)](https://www.npmjs.com/package/ps-helix)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![Angular](https://img.shields.io/badge/Angular-21.0.3-red.svg)](https://angular.dev/)
8
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9.0-blue.svg)](https://www.typescriptlang.org/)
9
-
10
- ## Table of Contents
11
-
12
- - [Overview](#overview)
13
- - [Prerequisites](#prerequisites)
14
- - [Installation](#installation)
15
- - [Quick Start](#quick-start)
16
- - [Configuration](#configuration)
17
- - [Global Styles](#global-styles)
18
- - [Phosphor Icons Setup](#phosphor-icons-setup)
19
- - [Theme Service](#theme-service)
20
- - [Translation Service](#translation-service)
21
- - [Scroll Service](#scroll-service)
22
- - [Core Concepts](#core-concepts)
23
- - [Standalone Components](#standalone-components)
24
- - [Signal-Based Reactivity](#signal-based-reactivity)
25
- - [Type Safety](#type-safety)
26
- - [Dependency Injection](#dependency-injection)
27
- - [Available Components](#available-components)
28
- - [Service APIs](#service-apis)
29
- - [ThemeService](#themeservice)
30
- - [ToastService](#toastservice)
31
- - [ScrollService](#scrollservice)
32
- - [TranslationService](#translationservice)
33
- - [Exported Types](#exported-types)
34
- - [Theming](#theming)
35
- - [Best Practices](#best-practices)
36
- - [Troubleshooting](#troubleshooting)
37
- - [Browser Support](#browser-support)
38
- - [Development Scripts](#development-scripts)
39
- - [Contributing](#contributing)
40
- - [License](#license)
41
- - [Resources](#resources)
42
-
43
- ## Overview
44
-
45
- Helix is a production-ready design system that provides:
46
-
47
- - **28 Standalone Components** - All components are standalone, no NgModules required
48
- - **Signal-Based Reactivity** - Built with Angular 21 signals for optimal performance
49
- - **Accessibility First** - WCAG 2.1 AA compliant out of the box
50
- - **TypeScript Strict Mode** - Full type safety and IntelliSense support
51
- - **Complete Type Exports** - All component types and enums exported for type-safe development
52
- - **Customizable Theming** - Light/dark modes with brand color customization
53
- - **Phosphor Icons** - 6000+ icons with multiple weight variants
54
- - **i18n Support** - Built-in internationalization with ngx-translate
55
- - **Responsive Design** - Mobile-first approach with comprehensive breakpoint system
56
- - **Modern Architecture** - Built with Angular 21 standalone components and signals
57
-
58
- ## Prerequisites
59
-
60
- Before installing Helix, ensure your development environment meets these requirements:
61
-
62
- - **Node.js**: 18.x or higher
63
- - **npm**: 9.x or higher
64
- - **Angular**: 21.0.3 or higher
65
- - **Angular CLI**: 21.0.3 or higher
66
- - **TypeScript**: 5.9.0 or higher
67
-
68
- ### Required Peer Dependencies
69
-
70
- ```json
71
- {
72
- "@angular/common": "^21.0.3",
73
- "@angular/core": "^21.0.3",
74
- "@angular/forms": "^21.0.3",
75
- "@ngx-translate/core": "^15.0.0",
76
- "rxjs": "^7.8.0"
77
- }
78
- ```
79
-
80
- ### Included Dependencies
81
-
82
- The following dependencies are bundled with ps-helix:
83
-
84
- - **@phosphor-icons/web**: 2.0.3 - Icon library
85
- - **date-fns**: ^3.3.1 - Date utility functions
86
- - **tslib**: ^2.6.0 - TypeScript runtime library
87
-
88
- ## Installation
89
-
90
- Install the package:
91
-
92
- ```bash
93
- npm install ps-helix
94
- ```
95
-
96
- All peer dependencies should be automatically installed. If not, install them manually:
97
-
98
- ```bash
99
- npm install @angular/common@^21.0.3 @angular/core@^21.0.3 @angular/forms@^21.0.3 @ngx-translate/core@^15.0.0 rxjs@^7.8.0
100
- ```
101
-
102
- ### Verify Installation
103
-
104
- After installation, verify that ps-helix is in your `package.json`:
105
-
106
- ```json
107
- {
108
- "dependencies": {
109
- "ps-helix": "^5.1.3"
110
- }
111
- }
112
- ```
113
-
114
- ## Quick Start
115
-
116
- ### Step 1: Import Global Styles
117
-
118
- In your main `styles.css` file, import the Helix stylesheet:
119
-
120
- ```css
121
- @import 'ps-helix/styles.css';
122
- ```
123
-
124
- This single import includes:
125
- - CSS Reset (normalize styles across browsers)
126
- - Design Tokens (spacing, typography, colors, etc.)
127
- - Light and Dark theme variables
128
- - Utility classes (spacing, typography, layout, etc.)
129
- - Responsive breakpoints and grid system
130
- - Animation utilities
131
- - Focus management styles
132
-
133
- ### Step 2: Configure Phosphor Icons
134
-
135
- Add Phosphor Icons CDN links to your `src/index.html` in the `<head>` section:
136
-
137
- ```html
138
- <!DOCTYPE html>
139
- <html lang="en">
140
- <head>
141
- <meta charset="UTF-8" />
142
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
143
- <title>Your App</title>
144
-
145
- <!-- Phosphor Icons CDN -->
146
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css">
147
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/fill/style.css">
148
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/bold/style.css">
149
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/light/style.css">
150
- </head>
151
- <body>
152
- <app-root></app-root>
153
- </body>
154
- </html>
155
- ```
156
-
157
- ### Step 3: Import and Use Components
158
-
159
- All components are standalone. Import them directly where needed:
160
-
161
- ```typescript
162
- import { Component } from '@angular/core';
163
- import { PshButtonComponent } from 'ps-helix';
164
-
165
- @Component({
166
- selector: 'app-root',
167
- imports: [PshButtonComponent],
168
- template: `
169
- <psh-button
170
- variant="primary"
171
- size="medium"
172
- (clicked)="handleClick()">
173
- Click Me
174
- </psh-button>
175
- `
176
- })
177
- export class AppComponent {
178
- handleClick() {
179
- console.log('Button clicked!');
180
- }
181
- }
182
- ```
183
-
184
- ### Step 4: Initialize Theme Service (Optional)
185
-
186
- If you want to use theme switching, inject the ThemeService:
187
-
188
- ```typescript
189
- import { Component, inject, OnInit } from '@angular/core';
190
- import { ThemeService } from 'ps-helix';
191
-
192
- @Component({
193
- selector: 'app-root',
194
- template: `
195
- <button (click)="themeService.toggleTheme()">
196
- Toggle Theme ({{ themeService.themeName() }})
197
- </button>
198
- `
199
- })
200
- export class AppComponent implements OnInit {
201
- themeService = inject(ThemeService);
202
-
203
- ngOnInit() {
204
- // Theme is initialized automatically
205
- console.log('Current theme:', this.themeService.themeName());
206
- }
207
- }
208
- ```
209
-
210
- ### Step 5: Verify Everything Works
211
-
212
- Create a simple test component to ensure the library is working:
213
-
214
- ```typescript
215
- import { Component } from '@angular/core';
216
- import { PshButtonComponent, PshCardComponent, PshAlertComponent } from 'ps-helix';
217
-
218
- @Component({
219
- selector: 'app-test',
220
- imports: [PshButtonComponent, PshCardComponent, PshAlertComponent],
221
- template: `
222
- <psh-card>
223
- <h2>Helix Design System</h2>
224
- <psh-alert type="success" message="Installation successful!" />
225
- <psh-button variant="primary">Test Button</psh-button>
226
- </psh-card>
227
- `
228
- })
229
- export class TestComponent {}
230
- ```
231
-
232
- ## Configuration
233
-
234
- ### Global Styles
235
-
236
- The design system provides a comprehensive set of CSS custom properties (CSS variables) that you can use in your own styles:
237
-
238
- ```css
239
- /* Using design tokens in your custom styles */
240
- .my-custom-component {
241
- padding: var(--spacing-md);
242
- margin-bottom: var(--spacing-lg);
243
- background: var(--surface-card);
244
- color: var(--text-color);
245
- border-radius: var(--border-radius);
246
- box-shadow: var(--shadow-md);
247
- }
248
- ```
249
-
250
- ### Phosphor Icons Setup
251
-
252
- After adding the CDN links, use icons in your templates:
253
-
254
- ```html
255
- <!-- Regular weight (default) -->
256
- <i class="ph ph-heart"></i>
257
-
258
- <!-- Fill weight -->
259
- <i class="ph-fill ph-heart"></i>
260
-
261
- <!-- Bold weight -->
262
- <i class="ph-bold ph-heart"></i>
263
-
264
- <!-- Light weight -->
265
- <i class="ph-light ph-heart"></i>
266
-
267
- <!-- With accessibility label for icon-only buttons -->
268
- <button aria-label="Like this item">
269
- <i class="ph ph-heart" aria-hidden="true"></i>
270
- </button>
271
- ```
272
-
273
- Browse all 6000+ icons at: [https://phosphoricons.com/](https://phosphoricons.com/)
274
-
275
- ### Theme Service
276
-
277
- The `ThemeService` manages light/dark theme switching and custom brand colors.
278
-
279
- #### Basic Theme Switching
280
-
281
- ```typescript
282
- import { Component, inject } from '@angular/core';
283
- import { ThemeService } from 'ps-helix';
284
-
285
- @Component({
286
- selector: 'app-root',
287
- template: `
288
- <button (click)="toggleTheme()">
289
- Current theme: {{ themeService.themeName() }}
290
- </button>
291
- `
292
- })
293
- export class AppComponent {
294
- themeService = inject(ThemeService);
295
-
296
- toggleTheme() {
297
- this.themeService.toggleTheme();
298
- }
299
- }
300
- ```
301
-
302
- For complete theming documentation including custom brand colors, see [THEME.md](./THEME.md).
303
-
304
- ### Translation Service
305
-
306
- Configure internationalization with ngx-translate:
307
-
308
- ```typescript
309
- // src/main.ts
310
- import { bootstrapApplication } from '@angular/platform-browser';
311
- import { provideHttpClient } from '@angular/common/http';
312
- import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
313
- import { TranslateHttpLoader } from '@ngx-translate/http-loader';
314
- import { HttpClient } from '@angular/common/http';
315
- import { AppComponent } from './app/app.component';
316
-
317
- export function HttpLoaderFactory(http: HttpClient) {
318
- return new TranslateHttpLoader(http, './assets/i18n/', '.json');
319
- }
320
-
321
- bootstrapApplication(AppComponent, {
322
- providers: [
323
- provideHttpClient(),
324
- ...TranslateModule.forRoot({
325
- defaultLanguage: 'en',
326
- loader: {
327
- provide: TranslateLoader,
328
- useFactory: HttpLoaderFactory,
329
- deps: [HttpClient]
330
- }
331
- }).providers || []
332
- ]
333
- }).then(ref => {
334
- const translateService = ref.injector.get(TranslateService);
335
- translateService.use('en');
336
- });
337
- ```
338
-
339
- #### Using TranslationService in Components
340
-
341
- ```typescript
342
- import { Component, inject } from '@angular/core';
343
- import { TranslationService } from 'ps-helix';
344
-
345
- @Component({
346
- selector: 'app-example',
347
- template: `
348
- <select (change)="changeLanguage($event)">
349
- <option value="en">English</option>
350
- <option value="fr">Français</option>
351
- <option value="es">Español</option>
352
- </select>
353
- `
354
- })
355
- export class ExampleComponent {
356
- private translationService = inject(TranslationService);
357
-
358
- changeLanguage(event: Event) {
359
- const lang = (event.target as HTMLSelectElement).value;
360
- this.translationService.setLanguage(lang);
361
- }
362
- }
363
- ```
364
-
365
- ### Scroll Service
366
-
367
- The `ScrollService` provides utilities for scroll management:
368
-
369
- ```typescript
370
- import { Component, inject } from '@angular/core';
371
- import { ScrollService } from 'ps-helix';
372
-
373
- @Component({
374
- selector: 'app-example',
375
- template: `
376
- <button (click)="scrollToTop()">Back to Top</button>
377
- <button (click)="scrollToElement('#section-2')">Go to Section 2</button>
378
- `
379
- })
380
- export class ExampleComponent {
381
- private scrollService = inject(ScrollService);
382
-
383
- scrollToTop() {
384
- this.scrollService.scrollToTop();
385
- }
386
-
387
- scrollToElement(selector: string) {
388
- this.scrollService.scrollToElement(selector);
389
- }
390
- }
391
- ```
392
-
393
- ## Core Concepts
394
-
395
- ### Standalone Components
396
-
397
- All Helix components are standalone (no NgModules required):
398
-
399
- ```typescript
400
- import { Component } from '@angular/core';
401
- import {
402
- PshButtonComponent,
403
- PshInputComponent,
404
- PshCardComponent
405
- } from 'ps-helix';
406
-
407
- @Component({
408
- selector: 'app-form',
409
- imports: [
410
- PshButtonComponent,
411
- PshInputComponent,
412
- PshCardComponent
413
- ],
414
- template: `
415
- <psh-card>
416
- <psh-input label="Email" />
417
- <psh-button variant="primary">Submit</psh-button>
418
- </psh-card>
419
- `
420
- })
421
- export class FormComponent {}
422
- ```
423
-
424
- ### Signal-Based Reactivity
425
-
426
- Components use Angular signals for optimal change detection:
427
-
428
- ```typescript
429
- import { Component, signal } from '@angular/core';
430
- import { PshModalComponent } from 'ps-helix';
431
-
432
- @Component({
433
- selector: 'app-example',
434
- imports: [PshModalComponent],
435
- template: `
436
- <button (click)="isOpen.set(true)">Open Modal</button>
437
-
438
- <psh-modal [(open)]="isOpen" title="Confirmation">
439
- <p>Are you sure?</p>
440
- </psh-modal>
441
- `
442
- })
443
- export class ExampleComponent {
444
- isOpen = signal(false);
445
- }
446
- ```
447
-
448
- ### Signal Forms Support
449
-
450
- Form components natively implement Angular 21 Signal Forms interfaces (`FormValueControl`, `FormCheckboxControl`) while maintaining backward compatibility with Reactive Forms via `ControlValueAccessor`:
451
-
452
- | Component | Signal Forms Interface | Reactive Forms |
453
- |-----------|----------------------|----------------|
454
- | `psh-input` | `FormValueControl<string>` | `ControlValueAccessor` |
455
- | `psh-select` | `FormValueControl<T \| T[] \| null>` | `ControlValueAccessor` |
456
- | `psh-checkbox` | `FormCheckboxControl` | `ControlValueAccessor` |
457
- | `psh-switch` | `FormCheckboxControl` | `ControlValueAccessor` |
458
- | `psh-radio` | - | Property binding only |
459
-
460
- ### Type Safety
461
-
462
- All components export TypeScript types for type-safe development:
463
-
464
- ```typescript
465
- import { Component } from '@angular/core';
466
- import { PshButtonComponent, ButtonVariant, ButtonSize } from 'ps-helix';
467
-
468
- @Component({
469
- selector: 'app-example',
470
- imports: [PshButtonComponent],
471
- template: `
472
- <psh-button [variant]="variant" [size]="size">
473
- {{ buttonText }}
474
- </psh-button>
475
- `
476
- })
477
- export class ExampleComponent {
478
- variant: ButtonVariant = 'primary'; // Type-safe
479
- size: ButtonSize = 'medium'; // Type-safe
480
- buttonText = 'Click Me';
481
- }
482
- ```
483
-
484
- ### Dependency Injection
485
-
486
- Use modern `inject()` function instead of constructor injection:
487
-
488
- ```typescript
489
- import { Component, inject } from '@angular/core';
490
- import { ThemeService, ToastService } from 'ps-helix';
491
-
492
- @Component({
493
- selector: 'app-example',
494
- template: `<button (click)="showToast()">Show Toast</button>`
495
- })
496
- export class ExampleComponent {
497
- // Modern injection syntax
498
- private themeService = inject(ThemeService);
499
- private toastService = inject(ToastService);
500
-
501
- showToast() {
502
- this.toastService.success('Hello from Helix!');
503
- }
504
- }
505
- ```
506
-
507
- ## Available Components
508
-
509
- Helix provides **28 production-ready components** organized by category:
510
-
511
- ### Form Components (6)
512
-
513
- - **PshButtonComponent** - Versatile button with multiple variants, sizes, and states
514
- - **PshInputComponent** - Text input with validation, error messages, and form control integration
515
- - **PshCheckboxComponent** - Checkbox with customizable states and labels
516
- - **PshRadioComponent** - Radio button for single selection from a group
517
- - **PshSelectComponent** - Dropdown select with search, filtering, and custom rendering
518
- - **PshSwitchComponent** - Toggle switch with on/off states
519
-
520
- ### Layout Components (6)
521
-
522
- - **PshCardComponent** - Flexible content container with header, body, and footer sections
523
- - **PshModalComponent** - Modal dialog overlay with backdrop and keyboard navigation
524
- - **PshSidebarComponent** - Collapsible sidebar navigation with responsive behavior
525
- - **PshCollapseComponent** - Expandable/collapsible content section with animation
526
- - **PshTabsComponent** + **PshTabComponent** - Tabbed content organization with keyboard navigation
527
- - **PshTabBarComponent** - Bottom tab bar navigation for mobile-first applications
528
-
529
- ### Feedback Components (5)
530
-
531
- - **PshAlertComponent** - Alert messages with severity levels (success, info, warning, error)
532
- - **PshToastComponent** + **ToastService** - Toast notification system with queue management
533
- - **PshSpinloaderComponent** - Loading spinner with various sizes
534
- - **PshProgressbarComponent** - Progress indicator with percentage display
535
- - **PshTooltipComponent** - Contextual tooltips with multiple positions
536
-
537
- ### Data Display Components (7)
538
-
539
- - **PshTableComponent** - Data table with sorting, pagination, and custom rendering
540
- - **PshBadgeComponent** - Status badges and indicators with various colors
541
- - **PshTagComponent** - Removable tags for labels and filters
542
- - **PshAvatarComponent** - User avatar with image, initials, or icon fallback
543
- - **PshStatCardComponent** - Statistical card for dashboards
544
- - **PshInfoCardComponent** - Information card with icon and content
545
- - **PshHorizontalCardComponent** - Horizontal layout card component
546
-
547
- ### Navigation Components (4)
548
-
549
- - **PshMenuComponent** - Dropdown menu with nested items, vertical/horizontal modes and collapsible mode; when collapsed, automatic tooltips appear on icons for both root items and sub-items (right position, 300ms delay) with `aria-describedby` linkage
550
- - **PshPaginationComponent** - Pagination controls with page numbers
551
- - **PshStepperComponent** + **PshStepComponent** - Step-by-step wizard navigation with validation
552
- - **PshDropdownComponent** - Dropdown trigger and content container
553
-
554
- ## Service APIs
555
-
556
- ### ThemeService
557
-
558
- Manage application themes and custom brand colors.
559
-
560
- **Methods:**
561
- - `setDarkTheme(isDark: boolean)` - Set theme mode
562
- - `toggleTheme()` - Toggle between light and dark
563
- - `updateTheme(name: 'light' | 'dark')` - Update theme by name
564
- - `applyInsurerTheme()` - Apply custom brand colors
565
-
566
- **Computed Signals:**
567
- - `themeName()` - Returns current theme name
568
- - `isDarkTheme()` - Returns boolean for dark mode
569
- - `themeInfo()` - Returns complete theme information
570
-
571
- **Example:**
572
-
573
- ```typescript
574
- import { inject } from '@angular/core';
575
- import { ThemeService } from 'ps-helix';
576
-
577
- export class MyComponent {
578
- themeService = inject(ThemeService);
579
-
580
- get currentTheme() {
581
- return this.themeService.themeName(); // 'light' or 'dark'
582
- }
583
-
584
- get isDark() {
585
- return this.themeService.isDarkTheme(); // boolean
586
- }
587
-
588
- switchTheme() {
589
- this.themeService.toggleTheme();
590
- }
591
- }
592
- ```
593
-
594
- ### ToastService
595
-
596
- Display temporary notification messages.
597
-
598
- **Methods:**
599
- - `success(message: string, options?)` - Show success toast
600
- - `error(message: string, options?)` - Show error toast
601
- - `warning(message: string, options?)` - Show warning toast
602
- - `info(message: string, options?)` - Show info toast
603
-
604
- **Options:**
605
- - `duration?: number` - Display duration in milliseconds (default: 3000)
606
- - `position?: ToastPosition` - 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
607
-
608
- **Example:**
609
-
610
- ```typescript
611
- import { inject } from '@angular/core';
612
- import { ToastService } from 'ps-helix';
613
-
614
- export class MyComponent {
615
- private toastService = inject(ToastService);
616
-
617
- saveData() {
618
- try {
619
- // Save logic
620
- this.toastService.success('Data saved successfully!');
621
- } catch (error) {
622
- this.toastService.error('Failed to save data');
623
- }
624
- }
625
-
626
- showCustom() {
627
- this.toastService.info('Processing...', {
628
- duration: 5000,
629
- position: 'bottom-right'
630
- });
631
- }
632
- }
633
- ```
634
-
635
- ### ScrollService
636
-
637
- Utility service for scroll management and smooth scrolling.
638
-
639
- **Methods:**
640
- - `scrollToTop()` - Scroll to page top smoothly
641
- - `scrollToElement(selector: string)` - Scroll to specific element
642
- - `disableScroll()` - Disable page scrolling (useful for modals)
643
- - `enableScroll()` - Re-enable page scrolling
644
-
645
- **Example:**
646
-
647
- ```typescript
648
- import { inject } from '@angular/core';
649
- import { ScrollService } from 'ps-helix';
650
-
651
- export class MyComponent {
652
- private scrollService = inject(ScrollService);
653
-
654
- backToTop() {
655
- this.scrollService.scrollToTop();
656
- }
657
-
658
- goToSection(sectionId: string) {
659
- this.scrollService.scrollToElement(`#${sectionId}`);
660
- }
661
-
662
- openModal() {
663
- this.scrollService.disableScroll();
664
- // Show modal
665
- }
666
-
667
- closeModal() {
668
- this.scrollService.enableScroll();
669
- // Hide modal
670
- }
671
- }
672
- ```
673
-
674
- ### TranslationService
675
-
676
- Wrapper service for ngx-translate functionality.
677
-
678
- **Methods:**
679
- - `setLanguage(lang: string)` - Change application language
680
- - `getTranslation(key: string)` - Get translation for a key
681
- - `instant(key: string)` - Get instant translation (synchronous)
682
-
683
- **Example:**
684
-
685
- ```typescript
686
- import { Component, inject } from '@angular/core';
687
- import { TranslationService } from 'ps-helix';
688
-
689
- @Component({
690
- selector: 'app-language-selector',
691
- template: `
692
- <select (change)="changeLanguage($event)">
693
- <option value="en">English</option>
694
- <option value="fr">Français</option>
695
- <option value="es">Español</option>
696
- <option value="de">Deutsch</option>
697
- </select>
698
- `
699
- })
700
- export class LanguageSelectorComponent {
701
- private translationService = inject(TranslationService);
702
-
703
- changeLanguage(event: Event) {
704
- const selectedLang = (event.target as HTMLSelectElement).value;
705
- this.translationService.setLanguage(selectedLang);
706
- }
707
- }
708
- ```
709
-
710
- ## Exported Types
711
-
712
- All component types and enums are exported for type-safe development:
713
-
714
- ### Alert Types
715
-
716
- ```typescript
717
- import { AlertType, AlertVariant } from 'ps-helix';
718
-
719
- const type: AlertType = 'success' | 'error' | 'warning' | 'info';
720
- const variant: AlertVariant = 'solid' | 'outlined' | 'soft';
721
- ```
722
-
723
- ### Avatar Types
724
-
725
- ```typescript
726
- import { AvatarSize, AvatarShape } from 'ps-helix';
727
-
728
- const size: AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
729
- const shape: AvatarShape = 'circle' | 'square';
730
- ```
731
-
732
- ### Badge Types
733
-
734
- ```typescript
735
- import { BadgeSize, BadgeVariant } from 'ps-helix';
736
-
737
- const size: BadgeSize = 'sm' | 'md' | 'lg';
738
- const variant: BadgeVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
739
- ```
740
-
741
- ### Button Types
742
-
743
- ```typescript
744
- import { ButtonAppearance, ButtonSize, ButtonVariant } from 'ps-helix';
745
-
746
- const appearance: ButtonAppearance = 'filled' | 'outlined' | 'text' | 'ghost';
747
- const size: ButtonSize = 'small' | 'medium' | 'large';
748
- const variant: ButtonVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
749
- ```
750
-
751
- ### Input Types
752
-
753
- ```typescript
754
- import { InputSize, InputType } from 'ps-helix';
755
-
756
- const size: InputSize = 'small' | 'medium' | 'large';
757
- const type: InputType = 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search';
758
- ```
759
-
760
- ### Modal Types
761
-
762
- ```typescript
763
- import { ModalSize } from 'ps-helix';
764
-
765
- const size: ModalSize = 'small' | 'medium' | 'large' | 'fullscreen';
766
- ```
767
-
768
- ### Select Types
769
-
770
- ```typescript
771
- import { SelectOption, SelectOptionGroup, SelectSize, SearchConfig } from 'ps-helix';
772
-
773
- interface SelectOption<T> {
774
- label: string;
775
- value: T;
776
- icon?: string;
777
- disabled?: boolean;
778
- description?: string;
779
- }
780
-
781
- interface SelectOptionGroup<T> {
782
- label: string;
783
- options: SelectOption<T>[];
784
- disabled?: boolean;
785
- }
786
-
787
- interface SearchConfig {
788
- debounceTime: number;
789
- placeholder: string;
790
- minLength: number;
791
- }
792
-
793
- type SelectSize = 'small' | 'medium' | 'large';
794
- ```
795
-
796
- ### Stepper Types
797
-
798
- ```typescript
799
- import { StepperVariant } from 'ps-helix';
800
-
801
- const variant: StepperVariant = 'default' | 'numbered' | 'progress';
802
- ```
803
-
804
- ### Table Types
805
-
806
- ```typescript
807
- import { TableColumn, TableSortDirection } from 'ps-helix';
808
-
809
- const sortDirection: TableSortDirection = 'asc' | 'desc' | null;
810
-
811
- interface TableColumn<T> {
812
- key: string;
813
- label: string;
814
- sortable?: boolean;
815
- width?: string;
816
- align?: 'left' | 'center' | 'right';
817
- render?: (item: T) => string;
818
- }
819
- ```
820
-
821
- ### Toast Types
822
-
823
- ```typescript
824
- import { ToastPosition, ToastVariant } from 'ps-helix';
825
-
826
- const position: ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
827
- const variant: ToastVariant = 'success' | 'error' | 'warning' | 'info';
828
- ```
829
-
830
- ### Tooltip Types
831
-
832
- ```typescript
833
- import { TooltipPlacement, TooltipTrigger } from 'ps-helix';
834
-
835
- const placement: TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
836
- const trigger: TooltipTrigger = 'hover' | 'click' | 'focus';
837
- ```
838
-
839
- For a complete list of all exported types, see the [type definitions](./src/public-api.ts).
840
-
841
- ## Theming
842
-
843
- ### Default Colors
844
-
845
- Helix provides default theme colors:
846
- - **Primary**: `#0F02C4` (Deep Blue)
847
- - **Secondary**: `#7B3AEC` (Purple)
848
-
849
- ### Custom Brand Colors
850
-
851
- Customize to match your brand identity using the injection token pattern. See the complete guide in [THEME.md](./THEME.md).
852
-
853
- ### Available CSS Variables
854
-
855
- Once configured, numerous CSS variables are available:
856
-
857
- **Primary Color:**
858
- - `--primary-color`
859
- - `--primary-color-light`
860
- - `--primary-color-lighter`
861
- - `--primary-color-dark`
862
- - `--primary-color-darker`
863
- - `--primary-color-text`
864
- - `--primary-color-rgb`
865
-
866
- **Secondary Color:**
867
- - `--secondary-color`
868
- - `--secondary-color-light`
869
- - `--secondary-color-lighter`
870
- - `--secondary-color-dark`
871
- - `--secondary-color-darker`
872
- - `--secondary-color-text`
873
- - `--secondary-color-rgb`
874
-
875
- ### Using Custom Variables
876
-
877
- ```css
878
- .my-button {
879
- background: var(--primary-color);
880
- color: var(--primary-color-text);
881
- }
882
-
883
- .my-button:hover {
884
- background: var(--primary-color-light);
885
- }
886
- ```
887
-
888
- For complete theming guide including custom colors, dynamic changes, and advanced configurations, see [THEME.md](./THEME.md).
889
-
890
- ## Best Practices
891
-
892
- ### Component Organization
893
-
894
- ```typescript
895
- // ✅ Good: Import only what you need
896
- import { PshButtonComponent, PshInputComponent } from 'ps-helix';
897
-
898
- // ❌ Avoid: Don't import entire module
899
- import * as Helix from 'ps-helix';
900
- ```
901
-
902
- ### Type Safety
903
-
904
- ```typescript
905
- // ✅ Good: Use exported types
906
- import { ButtonVariant, ButtonSize } from 'ps-helix';
907
-
908
- const variant: ButtonVariant = 'primary';
909
- const size: ButtonSize = 'medium';
910
-
911
- // ❌ Avoid: Magic strings without types
912
- const variant = 'primary'; // No type checking
913
- ```
914
-
915
- ### Signal Usage
916
-
917
- ```typescript
918
- // ✅ Good: Use signals for reactive state
919
- import { signal } from '@angular/core';
920
-
921
- export class MyComponent {
922
- isVisible = signal(false);
923
-
924
- toggle() {
925
- this.isVisible.update(v => !v);
926
- }
927
- }
928
-
929
- // ❌ Avoid: Traditional properties for reactive UI
930
- export class MyComponent {
931
- isVisible = false; // Won't trigger change detection optimally
932
- }
933
- ```
934
-
935
- ### Accessibility
936
-
937
- ```html
938
- <!-- ✅ Good: Proper ARIA labels for icon-only buttons -->
939
- <button aria-label="Delete item" (click)="delete()">
940
- <i class="ph ph-trash" aria-hidden="true"></i>
941
- </button>
942
-
943
- <!-- ❌ Avoid: Icon buttons without labels -->
944
- <button (click)="delete()">
945
- <i class="ph ph-trash"></i>
946
- </button>
947
- ```
948
-
949
- ### Form Integration
950
-
951
- Form components (`psh-input`, `psh-checkbox`, `psh-select`, `psh-switch`) support three integration modes:
952
-
953
- ```typescript
954
- // ✅ Recommended: Signal Forms (Angular 21+)
955
- import { signal } from '@angular/core';
956
- import { form, FormField, required, email } from '@angular/forms/signals';
957
-
958
- export class MyComponent {
959
- model = signal({ email: '', password: '' });
960
- loginForm = form(this.model, (p) => {
961
- required(p.email, { message: 'Email required' });
962
- email(p.email, { message: 'Invalid email format' });
963
- });
964
- }
965
- ```
966
-
967
- ```html
968
- <psh-input [formField]="loginForm.email" type="email" label="Email" />
969
- ```
970
-
971
- ```typescript
972
- // ✅ Also supported: Reactive Forms (backward compatible)
973
- import { FormControl, Validators } from '@angular/forms';
974
-
975
- export class MyComponent {
976
- emailControl = new FormControl('', [
977
- Validators.required,
978
- Validators.email
979
- ]);
980
- }
981
- ```
982
-
983
- ```html
984
- <psh-input label="Email" [formControl]="emailControl" [required]="true" />
985
- ```
986
-
987
- ```html
988
- <!-- ✅ Also supported: Two-way binding -->
989
- <psh-input [(value)]="myValue" label="Email" />
990
- ```
991
-
992
- ### Performance Optimization
993
-
994
- ```typescript
995
- // ✅ Good: Use OnPush change detection
996
- import { ChangeDetectionStrategy } from '@angular/core';
997
-
998
- @Component({
999
- selector: 'app-example',
1000
- changeDetection: ChangeDetectionStrategy.OnPush,
1001
- template: `...`
1002
- })
1003
- export class ExampleComponent {}
1004
-
1005
- // ✅ Good: Use trackBy for lists
1006
- @Component({
1007
- template: `
1008
- @for (item of items(); track item.id) {
1009
- <psh-card>{{ item.name }}</psh-card>
1010
- }
1011
- `
1012
- })
1013
- export class ListComponent {
1014
- items = signal<Item[]>([]);
1015
- }
1016
- ```
1017
-
1018
- ### Testing
1019
-
1020
- ```typescript
1021
- // ✅ Good: Test components with TestBed
1022
- import { ComponentFixture, TestBed } from '@angular/core/testing';
1023
- import { PshButtonComponent } from 'ps-helix';
1024
-
1025
- describe('MyComponent', () => {
1026
- let component: MyComponent;
1027
- let fixture: ComponentFixture<MyComponent>;
1028
-
1029
- beforeEach(async () => {
1030
- await TestBed.configureTestingModule({
1031
- imports: [MyComponent, PshButtonComponent]
1032
- }).compileComponents();
1033
-
1034
- fixture = TestBed.createComponent(MyComponent);
1035
- component = fixture.componentInstance;
1036
- fixture.detectChanges();
1037
- });
1038
-
1039
- it('should create', () => {
1040
- expect(component).toBeTruthy();
1041
- });
1042
- });
1043
- ```
1044
-
1045
- ## Troubleshooting
1046
-
1047
- ### Styles Not Applied
1048
-
1049
- **Problem**: Components appear unstyled or broken.
1050
-
1051
- **Solution**: Ensure you've imported the global stylesheet:
1052
-
1053
- ```css
1054
- /* In src/styles.css */
1055
- @import 'ps-helix/styles.css';
1056
- ```
1057
-
1058
- ### Icons Not Displaying
1059
-
1060
- **Problem**: Icons show as empty squares or missing glyphs.
1061
-
1062
- **Solution**: Verify Phosphor Icons CDN links are in `index.html`:
1063
-
1064
- ```html
1065
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css">
1066
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/fill/style.css">
1067
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/bold/style.css">
1068
- <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/light/style.css">
1069
- ```
1070
-
1071
- ### Custom Colors Not Applying
1072
-
1073
- **Problem**: Brand colors aren't being used.
1074
-
1075
- **Solution**:
1076
- 1. Verify your theme context service implements `InsurerContextService`
1077
- 2. Check the provider configuration in `main.ts` or `app.config.ts`
1078
- 3. Ensure you're using valid hex color codes (e.g., `#FF0000`)
1079
- 4. Call `themeService.applyInsurerTheme()` after color changes
1080
-
1081
- See [THEME.md](./THEME.md) for complete theming documentation.
1082
-
1083
- ### TypeScript Errors
1084
-
1085
- **Problem**: TypeScript compilation errors with component imports.
1086
-
1087
- **Solution**:
1088
- 1. Verify Angular version is 21.0.3 or higher
1089
- 2. Check `tsconfig.json` has `"strict": true`
1090
- 3. Ensure all peer dependencies are installed
1091
- 4. Clear node_modules and reinstall: `rm -rf node_modules && npm install`
1092
-
1093
- ### Performance Issues
1094
-
1095
- **Problem**: Application feels slow or unresponsive.
1096
-
1097
- **Solution**:
1098
- 1. Use `OnPush` change detection strategy
1099
- 2. Implement proper signal usage
1100
- 3. Avoid unnecessary component re-renders
1101
- 4. Use `trackBy` functions in `@for` loops
1102
- 5. Lazy load routes and components where possible
1103
-
1104
- ### Build Errors
1105
-
1106
- **Problem**: Build fails with module resolution errors.
1107
-
1108
- **Solution**:
1109
- 1. Verify package.json includes ps-helix in dependencies
1110
- 2. Clear Angular cache: `ng cache clean`
1111
- 3. Delete .angular folder and rebuild
1112
- 4. Check that all peer dependencies match required versions
1113
-
1114
- ### Runtime Errors
1115
-
1116
- **Problem**: Errors in browser console at runtime.
1117
-
1118
- **Solution**:
1119
- 1. Check browser console for specific error messages
1120
- 2. Verify all required services are provided
1121
- 3. Ensure ThemeService is initialized if using custom themes
1122
- 4. Check that ngx-translate is properly configured if using i18n
1123
-
1124
- ## Browser Support
1125
-
1126
- Helix Design System supports:
1127
-
1128
- - **Chrome**: Latest 2 versions
1129
- - **Firefox**: Latest 2 versions
1130
- - **Safari**: Latest 2 versions
1131
- - **Edge**: Latest 2 versions
1132
- - **Mobile browsers**: iOS Safari 14+, Chrome Android latest
1133
-
1134
- **Note**: Internet Explorer is not supported.
1135
-
1136
- ## Development Scripts
1137
-
1138
- The following scripts are available for library development:
1139
-
1140
- ```bash
1141
- npm run build:lib # Build the library
1142
- npm run watch:lib # Watch for changes and rebuild
1143
- npm run publish:lib # Publish to npm registry
1144
- npm run build # Build demo application
1145
- npm run dev # Run demo application in dev mode
1146
- ```
1147
-
1148
- ## Contributing
1149
-
1150
- We welcome contributions! To contribute to Helix Design System:
1151
-
1152
- 1. Fork the repository
1153
- 2. Create a feature branch: `git checkout -b feature/my-feature`
1154
- 3. Make your changes and commit: `git commit -am 'Add new feature'`
1155
- 4. Push to the branch: `git push origin feature/my-feature`
1156
- 5. Submit a pull request
1157
-
1158
- ### Development Guidelines
1159
-
1160
- - Follow Angular style guide
1161
- - Use TypeScript strict mode
1162
- - Write tests for new components
1163
- - Document all public APIs
1164
- - Ensure accessibility compliance (WCAG 2.1 AA)
1165
- - Keep components small and focused
1166
- - Use signals for reactive state
1167
-
1168
- ## License
1169
-
1170
- MIT License - see LICENSE file for details.
1171
-
1172
- Copyright (c) 2025 PACK Solutions
1173
-
1174
- ## Resources
1175
-
1176
- - **Theme Customization Guide**: [THEME.md](./THEME.md)
1177
- - **Component Documentation**: Individual component README files in `/lib/components/`
1178
- - **Phosphor Icons**: [https://phosphoricons.com/](https://phosphoricons.com/)
1179
- - **Angular Documentation**: [https://angular.dev/](https://angular.dev/)
1180
- - **TypeScript Documentation**: [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
1181
- - **ngx-translate**: [https://github.com/ngx-translate/core](https://github.com/ngx-translate/core)
1182
-
1183
- ---
1184
-
1185
- **Version**: 5.1.3
1186
- **Built with**: Angular 21.0.3, TypeScript 5.9.0, Phosphor Icons 2.0.3
1187
- **Author**: Fabrice PEREZ | Product Designer at PACK Solutions
1188
- **Last Updated**: January 2026
1
+ # Helix Design System
2
+
3
+ A comprehensive Angular component library built with Angular 22+ featuring modern design patterns, accessibility-first development, and optimal developer experience.
4
+
5
+ [![npm version](https://img.shields.io/badge/npm-6.0.1-blue.svg)](https://www.npmjs.com/package/ps-helix)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Angular](https://img.shields.io/badge/Angular-22.0.0-red.svg)](https://angular.dev/)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-6.0.0-blue.svg)](https://www.typescriptlang.org/)
9
+
10
+ ## Table of Contents
11
+
12
+ - [Overview](#overview)
13
+ - [Prerequisites](#prerequisites)
14
+ - [Installation](#installation)
15
+ - [Quick Start](#quick-start)
16
+ - [Configuration](#configuration)
17
+ - [Global Styles](#global-styles)
18
+ - [Phosphor Icons Setup](#phosphor-icons-setup)
19
+ - [Theme Service](#theme-service)
20
+ - [Translation Service](#translation-service)
21
+ - [Scroll Service](#scroll-service)
22
+ - [Core Concepts](#core-concepts)
23
+ - [Standalone Components](#standalone-components)
24
+ - [Signal-Based Reactivity](#signal-based-reactivity)
25
+ - [Type Safety](#type-safety)
26
+ - [Dependency Injection](#dependency-injection)
27
+ - [Available Components](#available-components)
28
+ - [Service APIs](#service-apis)
29
+ - [ThemeService](#themeservice)
30
+ - [ToastService](#toastservice)
31
+ - [ScrollService](#scrollservice)
32
+ - [TranslationService](#translationservice)
33
+ - [Exported Types](#exported-types)
34
+ - [Theming](#theming)
35
+ - [Best Practices](#best-practices)
36
+ - [Troubleshooting](#troubleshooting)
37
+ - [Browser Support](#browser-support)
38
+ - [Development Scripts](#development-scripts)
39
+ - [Contributing](#contributing)
40
+ - [License](#license)
41
+ - [Resources](#resources)
42
+
43
+ ## Overview
44
+
45
+ Helix is a production-ready design system that provides:
46
+
47
+ - **28 Standalone Components** - All components are standalone, no NgModules required
48
+ - **Signal-Based Reactivity** - Built with Angular 22 signals for optimal performance
49
+ - **Accessibility First** - WCAG 2.1 AA compliant out of the box
50
+ - **TypeScript Strict Mode** - Full type safety and IntelliSense support
51
+ - **Complete Type Exports** - All component types and enums exported for type-safe development
52
+ - **Customizable Theming** - Light/dark modes with brand color customization
53
+ - **Phosphor Icons** - 6000+ icons with multiple weight variants
54
+ - **i18n Support** - Built-in internationalization with ngx-translate
55
+ - **Responsive Design** - Mobile-first approach with comprehensive breakpoint system
56
+ - **Modern Architecture** - Built with Angular 22 standalone components and signals
57
+
58
+ ## Prerequisites
59
+
60
+ Before installing Helix, ensure your development environment meets these requirements:
61
+
62
+ - **Node.js**: 22.22.3 or higher (or 24.15+)
63
+ - **npm**: 10.x or higher
64
+ - **Angular**: 22.0.0 or higher
65
+ - **Angular CLI**: 22.0.0 or higher
66
+ - **TypeScript**: 6.0.0 or higher
67
+
68
+ ### Required Peer Dependencies
69
+
70
+ ```json
71
+ {
72
+ "@angular/common": "^22.0.0",
73
+ "@angular/core": "^22.0.0",
74
+ "@angular/forms": "^22.0.0",
75
+ "@ngx-translate/core": "^15.0.0",
76
+ "rxjs": "^7.8.0"
77
+ }
78
+ ```
79
+
80
+ ### Included Dependencies
81
+
82
+ The following dependencies are bundled with ps-helix:
83
+
84
+ - **@phosphor-icons/web**: 2.0.3 - Icon library
85
+ - **date-fns**: ^3.3.1 - Date utility functions
86
+ - **tslib**: ^2.6.0 - TypeScript runtime library
87
+
88
+ ## Installation
89
+
90
+ Install the package:
91
+
92
+ ```bash
93
+ npm install ps-helix
94
+ ```
95
+
96
+ All peer dependencies should be automatically installed. If not, install them manually:
97
+
98
+ ```bash
99
+ npm install @angular/common@^22.0.0 @angular/core@^22.0.0 @angular/forms@^22.0.0 @ngx-translate/core@^15.0.0 rxjs@^7.8.0
100
+ ```
101
+
102
+ ### Verify Installation
103
+
104
+ After installation, verify that ps-helix is in your `package.json`:
105
+
106
+ ```json
107
+ {
108
+ "dependencies": {
109
+ "ps-helix": "^6.0.1"
110
+ }
111
+ }
112
+ ```
113
+
114
+ ## Quick Start
115
+
116
+ ### Step 1: Import Global Styles
117
+
118
+ In your main `styles.css` file, import the Helix stylesheet:
119
+
120
+ ```css
121
+ @import 'ps-helix/styles.css';
122
+ ```
123
+
124
+ This single import includes:
125
+ - CSS Reset (normalize styles across browsers)
126
+ - Design Tokens (spacing, typography, colors, etc.)
127
+ - Light and Dark theme variables
128
+ - Utility classes (spacing, typography, layout, etc.)
129
+ - Responsive breakpoints and grid system
130
+ - Animation utilities
131
+ - Focus management styles
132
+
133
+ ### Step 2: Configure Phosphor Icons
134
+
135
+ Add Phosphor Icons CDN links to your `src/index.html` in the `<head>` section:
136
+
137
+ ```html
138
+ <!DOCTYPE html>
139
+ <html lang="en">
140
+ <head>
141
+ <meta charset="UTF-8" />
142
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
143
+ <title>Your App</title>
144
+
145
+ <!-- Phosphor Icons CDN -->
146
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css">
147
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/fill/style.css">
148
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/bold/style.css">
149
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/light/style.css">
150
+ </head>
151
+ <body>
152
+ <app-root></app-root>
153
+ </body>
154
+ </html>
155
+ ```
156
+
157
+ ### Step 3: Import and Use Components
158
+
159
+ All components are standalone. Import them directly where needed:
160
+
161
+ ```typescript
162
+ import { Component } from '@angular/core';
163
+ import { PshButtonComponent } from 'ps-helix';
164
+
165
+ @Component({
166
+ selector: 'app-root',
167
+ imports: [PshButtonComponent],
168
+ template: `
169
+ <psh-button
170
+ variant="primary"
171
+ size="medium"
172
+ (clicked)="handleClick()">
173
+ Click Me
174
+ </psh-button>
175
+ `
176
+ })
177
+ export class AppComponent {
178
+ handleClick() {
179
+ console.log('Button clicked!');
180
+ }
181
+ }
182
+ ```
183
+
184
+ ### Step 4: Initialize Theme Service (Optional)
185
+
186
+ If you want to use theme switching, inject the ThemeService:
187
+
188
+ ```typescript
189
+ import { Component, inject, OnInit } from '@angular/core';
190
+ import { ThemeService } from 'ps-helix';
191
+
192
+ @Component({
193
+ selector: 'app-root',
194
+ template: `
195
+ <button (click)="themeService.toggleTheme()">
196
+ Toggle Theme ({{ themeService.themeName() }})
197
+ </button>
198
+ `
199
+ })
200
+ export class AppComponent implements OnInit {
201
+ themeService = inject(ThemeService);
202
+
203
+ ngOnInit() {
204
+ // Theme is initialized automatically
205
+ console.log('Current theme:', this.themeService.themeName());
206
+ }
207
+ }
208
+ ```
209
+
210
+ ### Step 5: Verify Everything Works
211
+
212
+ Create a simple test component to ensure the library is working:
213
+
214
+ ```typescript
215
+ import { Component } from '@angular/core';
216
+ import { PshButtonComponent, PshCardComponent, PshAlertComponent } from 'ps-helix';
217
+
218
+ @Component({
219
+ selector: 'app-test',
220
+ imports: [PshButtonComponent, PshCardComponent, PshAlertComponent],
221
+ template: `
222
+ <psh-card>
223
+ <h2>Helix Design System</h2>
224
+ <psh-alert type="success" message="Installation successful!" />
225
+ <psh-button variant="primary">Test Button</psh-button>
226
+ </psh-card>
227
+ `
228
+ })
229
+ export class TestComponent {}
230
+ ```
231
+
232
+ ## Configuration
233
+
234
+ ### Global Styles
235
+
236
+ The design system provides a comprehensive set of CSS custom properties (CSS variables) that you can use in your own styles:
237
+
238
+ ```css
239
+ /* Using design tokens in your custom styles */
240
+ .my-custom-component {
241
+ padding: var(--spacing-md);
242
+ margin-bottom: var(--spacing-lg);
243
+ background: var(--surface-card);
244
+ color: var(--text-color);
245
+ border-radius: var(--border-radius);
246
+ box-shadow: var(--shadow-md);
247
+ }
248
+ ```
249
+
250
+ ### Phosphor Icons Setup
251
+
252
+ After adding the CDN links, use icons in your templates:
253
+
254
+ ```html
255
+ <!-- Regular weight (default) -->
256
+ <i class="ph ph-heart"></i>
257
+
258
+ <!-- Fill weight -->
259
+ <i class="ph-fill ph-heart"></i>
260
+
261
+ <!-- Bold weight -->
262
+ <i class="ph-bold ph-heart"></i>
263
+
264
+ <!-- Light weight -->
265
+ <i class="ph-light ph-heart"></i>
266
+
267
+ <!-- With accessibility label for icon-only buttons -->
268
+ <button aria-label="Like this item">
269
+ <i class="ph ph-heart" aria-hidden="true"></i>
270
+ </button>
271
+ ```
272
+
273
+ Browse all 6000+ icons at: [https://phosphoricons.com/](https://phosphoricons.com/)
274
+
275
+ ### Theme Service
276
+
277
+ The `ThemeService` manages light/dark theme switching and custom brand colors.
278
+
279
+ #### Basic Theme Switching
280
+
281
+ ```typescript
282
+ import { Component, inject } from '@angular/core';
283
+ import { ThemeService } from 'ps-helix';
284
+
285
+ @Component({
286
+ selector: 'app-root',
287
+ template: `
288
+ <button (click)="toggleTheme()">
289
+ Current theme: {{ themeService.themeName() }}
290
+ </button>
291
+ `
292
+ })
293
+ export class AppComponent {
294
+ themeService = inject(ThemeService);
295
+
296
+ toggleTheme() {
297
+ this.themeService.toggleTheme();
298
+ }
299
+ }
300
+ ```
301
+
302
+ For complete theming documentation including custom brand colors, see [THEME.md](./THEME.md).
303
+
304
+ ### Translation Service
305
+
306
+ Configure internationalization with ngx-translate:
307
+
308
+ ```typescript
309
+ // src/main.ts
310
+ import { bootstrapApplication } from '@angular/platform-browser';
311
+ import { provideHttpClient } from '@angular/common/http';
312
+ import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
313
+ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
314
+ import { HttpClient } from '@angular/common/http';
315
+ import { AppComponent } from './app/app.component';
316
+
317
+ export function HttpLoaderFactory(http: HttpClient) {
318
+ return new TranslateHttpLoader(http, './assets/i18n/', '.json');
319
+ }
320
+
321
+ bootstrapApplication(AppComponent, {
322
+ providers: [
323
+ provideHttpClient(),
324
+ ...TranslateModule.forRoot({
325
+ defaultLanguage: 'en',
326
+ loader: {
327
+ provide: TranslateLoader,
328
+ useFactory: HttpLoaderFactory,
329
+ deps: [HttpClient]
330
+ }
331
+ }).providers || []
332
+ ]
333
+ }).then(ref => {
334
+ const translateService = ref.injector.get(TranslateService);
335
+ translateService.use('en');
336
+ });
337
+ ```
338
+
339
+ #### Using TranslationService in Components
340
+
341
+ ```typescript
342
+ import { Component, inject } from '@angular/core';
343
+ import { TranslationService } from 'ps-helix';
344
+
345
+ @Component({
346
+ selector: 'app-example',
347
+ template: `
348
+ <select (change)="changeLanguage($event)">
349
+ <option value="en">English</option>
350
+ <option value="fr">Français</option>
351
+ <option value="es">Español</option>
352
+ </select>
353
+ `
354
+ })
355
+ export class ExampleComponent {
356
+ private translationService = inject(TranslationService);
357
+
358
+ changeLanguage(event: Event) {
359
+ const lang = (event.target as HTMLSelectElement).value;
360
+ this.translationService.setLanguage(lang);
361
+ }
362
+ }
363
+ ```
364
+
365
+ ### Scroll Service
366
+
367
+ The `ScrollService` provides utilities for scroll management:
368
+
369
+ ```typescript
370
+ import { Component, inject } from '@angular/core';
371
+ import { ScrollService } from 'ps-helix';
372
+
373
+ @Component({
374
+ selector: 'app-example',
375
+ template: `
376
+ <button (click)="scrollToTop()">Back to Top</button>
377
+ <button (click)="scrollToElement('#section-2')">Go to Section 2</button>
378
+ `
379
+ })
380
+ export class ExampleComponent {
381
+ private scrollService = inject(ScrollService);
382
+
383
+ scrollToTop() {
384
+ this.scrollService.scrollToTop();
385
+ }
386
+
387
+ scrollToElement(selector: string) {
388
+ this.scrollService.scrollToElement(selector);
389
+ }
390
+ }
391
+ ```
392
+
393
+ ## Core Concepts
394
+
395
+ ### Standalone Components
396
+
397
+ All Helix components are standalone (no NgModules required):
398
+
399
+ ```typescript
400
+ import { Component } from '@angular/core';
401
+ import {
402
+ PshButtonComponent,
403
+ PshInputComponent,
404
+ PshCardComponent
405
+ } from 'ps-helix';
406
+
407
+ @Component({
408
+ selector: 'app-form',
409
+ imports: [
410
+ PshButtonComponent,
411
+ PshInputComponent,
412
+ PshCardComponent
413
+ ],
414
+ template: `
415
+ <psh-card>
416
+ <psh-input label="Email" />
417
+ <psh-button variant="primary">Submit</psh-button>
418
+ </psh-card>
419
+ `
420
+ })
421
+ export class FormComponent {}
422
+ ```
423
+
424
+ ### Signal-Based Reactivity
425
+
426
+ Components use Angular signals for optimal change detection:
427
+
428
+ ```typescript
429
+ import { Component, signal } from '@angular/core';
430
+ import { PshModalComponent } from 'ps-helix';
431
+
432
+ @Component({
433
+ selector: 'app-example',
434
+ imports: [PshModalComponent],
435
+ template: `
436
+ <button (click)="isOpen.set(true)">Open Modal</button>
437
+
438
+ <psh-modal [(open)]="isOpen" title="Confirmation">
439
+ <p>Are you sure?</p>
440
+ </psh-modal>
441
+ `
442
+ })
443
+ export class ExampleComponent {
444
+ isOpen = signal(false);
445
+ }
446
+ ```
447
+
448
+ ### Signal Forms Support
449
+
450
+ Form components natively implement Angular 22 Signal Forms interfaces (`FormValueControl`, `FormCheckboxControl`) while maintaining backward compatibility with Reactive Forms via `ControlValueAccessor`:
451
+
452
+ | Component | Signal Forms Interface | Reactive Forms |
453
+ |-----------|----------------------|----------------|
454
+ | `psh-input` | `FormValueControl<string>` | `ControlValueAccessor` |
455
+ | `psh-select` | `FormValueControl<T \| T[] \| null>` | `ControlValueAccessor` |
456
+ | `psh-checkbox` | `FormCheckboxControl` | `ControlValueAccessor` |
457
+ | `psh-switch` | `FormCheckboxControl` | `ControlValueAccessor` |
458
+ | `psh-radio` | - | Property binding only |
459
+
460
+ ### Type Safety
461
+
462
+ All components export TypeScript types for type-safe development:
463
+
464
+ ```typescript
465
+ import { Component } from '@angular/core';
466
+ import { PshButtonComponent, ButtonVariant, ButtonSize } from 'ps-helix';
467
+
468
+ @Component({
469
+ selector: 'app-example',
470
+ imports: [PshButtonComponent],
471
+ template: `
472
+ <psh-button [variant]="variant" [size]="size">
473
+ {{ buttonText }}
474
+ </psh-button>
475
+ `
476
+ })
477
+ export class ExampleComponent {
478
+ variant: ButtonVariant = 'primary'; // Type-safe
479
+ size: ButtonSize = 'medium'; // Type-safe
480
+ buttonText = 'Click Me';
481
+ }
482
+ ```
483
+
484
+ ### Dependency Injection
485
+
486
+ Use modern `inject()` function instead of constructor injection:
487
+
488
+ ```typescript
489
+ import { Component, inject } from '@angular/core';
490
+ import { ThemeService, ToastService } from 'ps-helix';
491
+
492
+ @Component({
493
+ selector: 'app-example',
494
+ template: `<button (click)="showToast()">Show Toast</button>`
495
+ })
496
+ export class ExampleComponent {
497
+ // Modern injection syntax
498
+ private themeService = inject(ThemeService);
499
+ private toastService = inject(ToastService);
500
+
501
+ showToast() {
502
+ this.toastService.success('Hello from Helix!');
503
+ }
504
+ }
505
+ ```
506
+
507
+ ## Available Components
508
+
509
+ Helix provides **28 production-ready components** organized by category:
510
+
511
+ ### Form Components (6)
512
+
513
+ - **PshButtonComponent** - Versatile button with multiple variants, sizes, and states
514
+ - **PshInputComponent** - Text input with validation, error messages, and form control integration
515
+ - **PshCheckboxComponent** - Checkbox with customizable states and labels
516
+ - **PshRadioComponent** - Radio button for single selection from a group
517
+ - **PshSelectComponent** - Dropdown select with search, filtering, and custom rendering
518
+ - **PshSwitchComponent** - Toggle switch with on/off states
519
+
520
+ ### Layout Components (6)
521
+
522
+ - **PshCardComponent** - Flexible content container with header, body, and footer sections
523
+ - **PshModalComponent** - Modal dialog overlay with backdrop and keyboard navigation
524
+ - **PshSidebarComponent** - Collapsible sidebar navigation with responsive behavior
525
+ - **PshCollapseComponent** - Expandable/collapsible content section with animation
526
+ - **PshTabsComponent** + **PshTabComponent** - Tabbed content organization with keyboard navigation
527
+ - **PshTabBarComponent** - Bottom tab bar navigation for mobile-first applications
528
+
529
+ ### Feedback Components (5)
530
+
531
+ - **PshAlertComponent** - Alert messages with severity levels (success, info, warning, error)
532
+ - **PshToastComponent** + **ToastService** - Toast notification system with queue management
533
+ - **PshSpinloaderComponent** - Loading spinner with various sizes
534
+ - **PshProgressbarComponent** - Progress indicator with percentage display
535
+ - **PshTooltipComponent** - Contextual tooltips with multiple positions
536
+
537
+ ### Data Display Components (7)
538
+
539
+ - **PshTableComponent** - Data table with sorting, pagination, and custom rendering
540
+ - **PshBadgeComponent** - Status badges and indicators with various colors
541
+ - **PshTagComponent** - Removable tags for labels and filters
542
+ - **PshAvatarComponent** - User avatar with image, initials, or icon fallback
543
+ - **PshStatCardComponent** - Statistical card for dashboards
544
+ - **PshInfoCardComponent** - Information card with icon and content
545
+ - **PshHorizontalCardComponent** - Horizontal layout card component
546
+
547
+ ### Navigation Components (4)
548
+
549
+ - **PshMenuComponent** - Dropdown menu with nested items, vertical/horizontal modes and collapsible mode; when collapsed, automatic tooltips appear on icons for both root items and sub-items (right position, 300ms delay) with `aria-describedby` linkage
550
+ - **PshPaginationComponent** - Pagination controls with page numbers
551
+ - **PshStepperComponent** + **PshStepComponent** - Step-by-step wizard navigation with validation
552
+ - **PshDropdownComponent** - Dropdown trigger and content container
553
+
554
+ ## Service APIs
555
+
556
+ ### ThemeService
557
+
558
+ Manage application themes and custom brand colors.
559
+
560
+ **Methods:**
561
+ - `setDarkTheme(isDark: boolean)` - Set theme mode
562
+ - `toggleTheme()` - Toggle between light and dark
563
+ - `updateTheme(name: 'light' | 'dark')` - Update theme by name
564
+ - `applyInsurerTheme()` - Apply custom brand colors
565
+
566
+ **Computed Signals:**
567
+ - `themeName()` - Returns current theme name
568
+ - `isDarkTheme()` - Returns boolean for dark mode
569
+ - `themeInfo()` - Returns complete theme information
570
+
571
+ **Example:**
572
+
573
+ ```typescript
574
+ import { inject } from '@angular/core';
575
+ import { ThemeService } from 'ps-helix';
576
+
577
+ export class MyComponent {
578
+ themeService = inject(ThemeService);
579
+
580
+ get currentTheme() {
581
+ return this.themeService.themeName(); // 'light' or 'dark'
582
+ }
583
+
584
+ get isDark() {
585
+ return this.themeService.isDarkTheme(); // boolean
586
+ }
587
+
588
+ switchTheme() {
589
+ this.themeService.toggleTheme();
590
+ }
591
+ }
592
+ ```
593
+
594
+ ### ToastService
595
+
596
+ Display temporary notification messages.
597
+
598
+ **Methods:**
599
+ - `success(message: string, options?)` - Show success toast
600
+ - `error(message: string, options?)` - Show error toast
601
+ - `warning(message: string, options?)` - Show warning toast
602
+ - `info(message: string, options?)` - Show info toast
603
+
604
+ **Options:**
605
+ - `duration?: number` - Display duration in milliseconds (default: 3000)
606
+ - `position?: ToastPosition` - 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
607
+
608
+ **Example:**
609
+
610
+ ```typescript
611
+ import { inject } from '@angular/core';
612
+ import { ToastService } from 'ps-helix';
613
+
614
+ export class MyComponent {
615
+ private toastService = inject(ToastService);
616
+
617
+ saveData() {
618
+ try {
619
+ // Save logic
620
+ this.toastService.success('Data saved successfully!');
621
+ } catch (error) {
622
+ this.toastService.error('Failed to save data');
623
+ }
624
+ }
625
+
626
+ showCustom() {
627
+ this.toastService.info('Processing...', {
628
+ duration: 5000,
629
+ position: 'bottom-right'
630
+ });
631
+ }
632
+ }
633
+ ```
634
+
635
+ ### ScrollService
636
+
637
+ Utility service for scroll management and smooth scrolling.
638
+
639
+ **Methods:**
640
+ - `scrollToTop()` - Scroll to page top smoothly
641
+ - `scrollToElement(selector: string)` - Scroll to specific element
642
+ - `disableScroll()` - Disable page scrolling (useful for modals)
643
+ - `enableScroll()` - Re-enable page scrolling
644
+
645
+ **Example:**
646
+
647
+ ```typescript
648
+ import { inject } from '@angular/core';
649
+ import { ScrollService } from 'ps-helix';
650
+
651
+ export class MyComponent {
652
+ private scrollService = inject(ScrollService);
653
+
654
+ backToTop() {
655
+ this.scrollService.scrollToTop();
656
+ }
657
+
658
+ goToSection(sectionId: string) {
659
+ this.scrollService.scrollToElement(`#${sectionId}`);
660
+ }
661
+
662
+ openModal() {
663
+ this.scrollService.disableScroll();
664
+ // Show modal
665
+ }
666
+
667
+ closeModal() {
668
+ this.scrollService.enableScroll();
669
+ // Hide modal
670
+ }
671
+ }
672
+ ```
673
+
674
+ ### TranslationService
675
+
676
+ Wrapper service for ngx-translate functionality.
677
+
678
+ **Methods:**
679
+ - `setLanguage(lang: string)` - Change application language
680
+ - `getTranslation(key: string)` - Get translation for a key
681
+ - `instant(key: string)` - Get instant translation (synchronous)
682
+
683
+ **Example:**
684
+
685
+ ```typescript
686
+ import { Component, inject } from '@angular/core';
687
+ import { TranslationService } from 'ps-helix';
688
+
689
+ @Component({
690
+ selector: 'app-language-selector',
691
+ template: `
692
+ <select (change)="changeLanguage($event)">
693
+ <option value="en">English</option>
694
+ <option value="fr">Français</option>
695
+ <option value="es">Español</option>
696
+ <option value="de">Deutsch</option>
697
+ </select>
698
+ `
699
+ })
700
+ export class LanguageSelectorComponent {
701
+ private translationService = inject(TranslationService);
702
+
703
+ changeLanguage(event: Event) {
704
+ const selectedLang = (event.target as HTMLSelectElement).value;
705
+ this.translationService.setLanguage(selectedLang);
706
+ }
707
+ }
708
+ ```
709
+
710
+ ## Exported Types
711
+
712
+ All component types and enums are exported for type-safe development:
713
+
714
+ ### Alert Types
715
+
716
+ ```typescript
717
+ import { AlertType, AlertVariant } from 'ps-helix';
718
+
719
+ const type: AlertType = 'success' | 'error' | 'warning' | 'info';
720
+ const variant: AlertVariant = 'solid' | 'outlined' | 'soft';
721
+ ```
722
+
723
+ ### Avatar Types
724
+
725
+ ```typescript
726
+ import { AvatarSize, AvatarShape } from 'ps-helix';
727
+
728
+ const size: AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
729
+ const shape: AvatarShape = 'circle' | 'square';
730
+ ```
731
+
732
+ ### Badge Types
733
+
734
+ ```typescript
735
+ import { BadgeSize, BadgeVariant } from 'ps-helix';
736
+
737
+ const size: BadgeSize = 'sm' | 'md' | 'lg';
738
+ const variant: BadgeVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
739
+ ```
740
+
741
+ ### Button Types
742
+
743
+ ```typescript
744
+ import { ButtonAppearance, ButtonSize, ButtonVariant } from 'ps-helix';
745
+
746
+ const appearance: ButtonAppearance = 'filled' | 'outlined' | 'text' | 'ghost';
747
+ const size: ButtonSize = 'small' | 'medium' | 'large';
748
+ const variant: ButtonVariant = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
749
+ ```
750
+
751
+ ### Input Types
752
+
753
+ ```typescript
754
+ import { InputSize, InputType } from 'ps-helix';
755
+
756
+ const size: InputSize = 'small' | 'medium' | 'large';
757
+ const type: InputType = 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search';
758
+ ```
759
+
760
+ ### Modal Types
761
+
762
+ ```typescript
763
+ import { ModalSize } from 'ps-helix';
764
+
765
+ const size: ModalSize = 'small' | 'medium' | 'large' | 'fullscreen';
766
+ ```
767
+
768
+ ### Select Types
769
+
770
+ ```typescript
771
+ import { SelectOption, SelectOptionGroup, SelectSize, SearchConfig } from 'ps-helix';
772
+
773
+ interface SelectOption<T> {
774
+ label: string;
775
+ value: T;
776
+ icon?: string;
777
+ disabled?: boolean;
778
+ description?: string;
779
+ }
780
+
781
+ interface SelectOptionGroup<T> {
782
+ label: string;
783
+ options: SelectOption<T>[];
784
+ disabled?: boolean;
785
+ }
786
+
787
+ interface SearchConfig {
788
+ debounceTime: number;
789
+ placeholder: string;
790
+ minLength: number;
791
+ }
792
+
793
+ type SelectSize = 'small' | 'medium' | 'large';
794
+ ```
795
+
796
+ ### Stepper Types
797
+
798
+ ```typescript
799
+ import { StepperVariant } from 'ps-helix';
800
+
801
+ const variant: StepperVariant = 'default' | 'numbered' | 'progress';
802
+ ```
803
+
804
+ ### Table Types
805
+
806
+ ```typescript
807
+ import { TableColumn, TableSortDirection } from 'ps-helix';
808
+
809
+ const sortDirection: TableSortDirection = 'asc' | 'desc' | null;
810
+
811
+ interface TableColumn<T> {
812
+ key: string;
813
+ label: string;
814
+ sortable?: boolean;
815
+ width?: string;
816
+ align?: 'left' | 'center' | 'right';
817
+ render?: (item: T) => string;
818
+ }
819
+ ```
820
+
821
+ ### Toast Types
822
+
823
+ ```typescript
824
+ import { ToastPosition, ToastVariant } from 'ps-helix';
825
+
826
+ const position: ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
827
+ const variant: ToastVariant = 'success' | 'error' | 'warning' | 'info';
828
+ ```
829
+
830
+ ### Tooltip Types
831
+
832
+ ```typescript
833
+ import { TooltipPlacement, TooltipTrigger } from 'ps-helix';
834
+
835
+ const placement: TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
836
+ const trigger: TooltipTrigger = 'hover' | 'click' | 'focus';
837
+ ```
838
+
839
+ For a complete list of all exported types, see the [type definitions](./src/public-api.ts).
840
+
841
+ ## Theming
842
+
843
+ ### Default Colors
844
+
845
+ Helix provides default theme colors:
846
+ - **Primary**: `#0F02C4` (Deep Blue)
847
+ - **Secondary**: `#7B3AEC` (Purple)
848
+
849
+ ### Custom Brand Colors
850
+
851
+ Customize to match your brand identity using the injection token pattern. See the complete guide in [THEME.md](./THEME.md).
852
+
853
+ ### Available CSS Variables
854
+
855
+ Once configured, numerous CSS variables are available:
856
+
857
+ **Primary Color:**
858
+ - `--primary-color`
859
+ - `--primary-color-light`
860
+ - `--primary-color-lighter`
861
+ - `--primary-color-dark`
862
+ - `--primary-color-darker`
863
+ - `--primary-color-text`
864
+ - `--primary-color-rgb`
865
+
866
+ **Secondary Color:**
867
+ - `--secondary-color`
868
+ - `--secondary-color-light`
869
+ - `--secondary-color-lighter`
870
+ - `--secondary-color-dark`
871
+ - `--secondary-color-darker`
872
+ - `--secondary-color-text`
873
+ - `--secondary-color-rgb`
874
+
875
+ ### Using Custom Variables
876
+
877
+ ```css
878
+ .my-button {
879
+ background: var(--primary-color);
880
+ color: var(--primary-color-text);
881
+ }
882
+
883
+ .my-button:hover {
884
+ background: var(--primary-color-light);
885
+ }
886
+ ```
887
+
888
+ For complete theming guide including custom colors, dynamic changes, and advanced configurations, see [THEME.md](./THEME.md).
889
+
890
+ ## Best Practices
891
+
892
+ ### Component Organization
893
+
894
+ ```typescript
895
+ // ✅ Good: Import only what you need
896
+ import { PshButtonComponent, PshInputComponent } from 'ps-helix';
897
+
898
+ // ❌ Avoid: Don't import entire module
899
+ import * as Helix from 'ps-helix';
900
+ ```
901
+
902
+ ### Type Safety
903
+
904
+ ```typescript
905
+ // ✅ Good: Use exported types
906
+ import { ButtonVariant, ButtonSize } from 'ps-helix';
907
+
908
+ const variant: ButtonVariant = 'primary';
909
+ const size: ButtonSize = 'medium';
910
+
911
+ // ❌ Avoid: Magic strings without types
912
+ const variant = 'primary'; // No type checking
913
+ ```
914
+
915
+ ### Signal Usage
916
+
917
+ ```typescript
918
+ // ✅ Good: Use signals for reactive state
919
+ import { signal } from '@angular/core';
920
+
921
+ export class MyComponent {
922
+ isVisible = signal(false);
923
+
924
+ toggle() {
925
+ this.isVisible.update(v => !v);
926
+ }
927
+ }
928
+
929
+ // ❌ Avoid: Traditional properties for reactive UI
930
+ export class MyComponent {
931
+ isVisible = false; // Won't trigger change detection optimally
932
+ }
933
+ ```
934
+
935
+ ### Accessibility
936
+
937
+ ```html
938
+ <!-- ✅ Good: Proper ARIA labels for icon-only buttons -->
939
+ <button aria-label="Delete item" (click)="delete()">
940
+ <i class="ph ph-trash" aria-hidden="true"></i>
941
+ </button>
942
+
943
+ <!-- ❌ Avoid: Icon buttons without labels -->
944
+ <button (click)="delete()">
945
+ <i class="ph ph-trash"></i>
946
+ </button>
947
+ ```
948
+
949
+ ### Form Integration
950
+
951
+ Form components (`psh-input`, `psh-checkbox`, `psh-select`, `psh-switch`) support three integration modes:
952
+
953
+ ```typescript
954
+ // ✅ Recommended: Signal Forms (Angular 22+)
955
+ import { signal } from '@angular/core';
956
+ import { form, FormField, required, email } from '@angular/forms/signals';
957
+
958
+ export class MyComponent {
959
+ model = signal({ email: '', password: '' });
960
+ loginForm = form(this.model, (p) => {
961
+ required(p.email, { message: 'Email required' });
962
+ email(p.email, { message: 'Invalid email format' });
963
+ });
964
+ }
965
+ ```
966
+
967
+ ```html
968
+ <psh-input [formField]="loginForm.email" type="email" label="Email" />
969
+ ```
970
+
971
+ ```typescript
972
+ // ✅ Also supported: Reactive Forms (backward compatible)
973
+ import { FormControl, Validators } from '@angular/forms';
974
+
975
+ export class MyComponent {
976
+ emailControl = new FormControl('', [
977
+ Validators.required,
978
+ Validators.email
979
+ ]);
980
+ }
981
+ ```
982
+
983
+ ```html
984
+ <psh-input label="Email" [formControl]="emailControl" [required]="true" />
985
+ ```
986
+
987
+ ```html
988
+ <!-- ✅ Also supported: Two-way binding -->
989
+ <psh-input [(value)]="myValue" label="Email" />
990
+ ```
991
+
992
+ ### Performance Optimization
993
+
994
+ ```typescript
995
+ // ✅ Good: Use OnPush change detection
996
+ import { ChangeDetectionStrategy } from '@angular/core';
997
+
998
+ @Component({
999
+ selector: 'app-example',
1000
+ changeDetection: ChangeDetectionStrategy.OnPush,
1001
+ template: `...`
1002
+ })
1003
+ export class ExampleComponent {}
1004
+
1005
+ // ✅ Good: Use trackBy for lists
1006
+ @Component({
1007
+ template: `
1008
+ @for (item of items(); track item.id) {
1009
+ <psh-card>{{ item.name }}</psh-card>
1010
+ }
1011
+ `
1012
+ })
1013
+ export class ListComponent {
1014
+ items = signal<Item[]>([]);
1015
+ }
1016
+ ```
1017
+
1018
+ ### Testing
1019
+
1020
+ ```typescript
1021
+ // ✅ Good: Test components with TestBed
1022
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
1023
+ import { PshButtonComponent } from 'ps-helix';
1024
+
1025
+ describe('MyComponent', () => {
1026
+ let component: MyComponent;
1027
+ let fixture: ComponentFixture<MyComponent>;
1028
+
1029
+ beforeEach(async () => {
1030
+ await TestBed.configureTestingModule({
1031
+ imports: [MyComponent, PshButtonComponent]
1032
+ }).compileComponents();
1033
+
1034
+ fixture = TestBed.createComponent(MyComponent);
1035
+ component = fixture.componentInstance;
1036
+ fixture.detectChanges();
1037
+ });
1038
+
1039
+ it('should create', () => {
1040
+ expect(component).toBeTruthy();
1041
+ });
1042
+ });
1043
+ ```
1044
+
1045
+ ## Troubleshooting
1046
+
1047
+ ### Styles Not Applied
1048
+
1049
+ **Problem**: Components appear unstyled or broken.
1050
+
1051
+ **Solution**: Ensure you've imported the global stylesheet:
1052
+
1053
+ ```css
1054
+ /* In src/styles.css */
1055
+ @import 'ps-helix/styles.css';
1056
+ ```
1057
+
1058
+ ### Icons Not Displaying
1059
+
1060
+ **Problem**: Icons show as empty squares or missing glyphs.
1061
+
1062
+ **Solution**: Verify Phosphor Icons CDN links are in `index.html`:
1063
+
1064
+ ```html
1065
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css">
1066
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/fill/style.css">
1067
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/bold/style.css">
1068
+ <link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/light/style.css">
1069
+ ```
1070
+
1071
+ ### Custom Colors Not Applying
1072
+
1073
+ **Problem**: Brand colors aren't being used.
1074
+
1075
+ **Solution**:
1076
+ 1. Verify your theme context service implements `InsurerContextService`
1077
+ 2. Check the provider configuration in `main.ts` or `app.config.ts`
1078
+ 3. Ensure you're using valid hex color codes (e.g., `#FF0000`)
1079
+ 4. Call `themeService.applyInsurerTheme()` after color changes
1080
+
1081
+ See [THEME.md](./THEME.md) for complete theming documentation.
1082
+
1083
+ ### TypeScript Errors
1084
+
1085
+ **Problem**: TypeScript compilation errors with component imports.
1086
+
1087
+ **Solution**:
1088
+ 1. Verify Angular version is 22.0.0 or higher
1089
+ 2. Check `tsconfig.json` has `"strict": true`
1090
+ 3. Ensure all peer dependencies are installed
1091
+ 4. Clear node_modules and reinstall: `rm -rf node_modules && npm install`
1092
+
1093
+ ### Performance Issues
1094
+
1095
+ **Problem**: Application feels slow or unresponsive.
1096
+
1097
+ **Solution**:
1098
+ 1. Use `OnPush` change detection strategy
1099
+ 2. Implement proper signal usage
1100
+ 3. Avoid unnecessary component re-renders
1101
+ 4. Use `trackBy` functions in `@for` loops
1102
+ 5. Lazy load routes and components where possible
1103
+
1104
+ ### Build Errors
1105
+
1106
+ **Problem**: Build fails with module resolution errors.
1107
+
1108
+ **Solution**:
1109
+ 1. Verify package.json includes ps-helix in dependencies
1110
+ 2. Clear Angular cache: `ng cache clean`
1111
+ 3. Delete .angular folder and rebuild
1112
+ 4. Check that all peer dependencies match required versions
1113
+
1114
+ ### Runtime Errors
1115
+
1116
+ **Problem**: Errors in browser console at runtime.
1117
+
1118
+ **Solution**:
1119
+ 1. Check browser console for specific error messages
1120
+ 2. Verify all required services are provided
1121
+ 3. Ensure ThemeService is initialized if using custom themes
1122
+ 4. Check that ngx-translate is properly configured if using i18n
1123
+
1124
+ ## Browser Support
1125
+
1126
+ Helix Design System supports:
1127
+
1128
+ - **Chrome**: Latest 2 versions
1129
+ - **Firefox**: Latest 2 versions
1130
+ - **Safari**: Latest 2 versions
1131
+ - **Edge**: Latest 2 versions
1132
+ - **Mobile browsers**: iOS Safari 14+, Chrome Android latest
1133
+
1134
+ **Note**: Internet Explorer is not supported.
1135
+
1136
+ ## Development Scripts
1137
+
1138
+ The following scripts are available for library development:
1139
+
1140
+ ```bash
1141
+ npm run build:lib # Build the library
1142
+ npm run watch:lib # Watch for changes and rebuild
1143
+ npm run publish:lib # Publish to npm registry
1144
+ npm run build # Build demo application
1145
+ npm run dev # Run demo application in dev mode
1146
+ ```
1147
+
1148
+ ## Contributing
1149
+
1150
+ We welcome contributions! To contribute to Helix Design System:
1151
+
1152
+ 1. Fork the repository
1153
+ 2. Create a feature branch: `git checkout -b feature/my-feature`
1154
+ 3. Make your changes and commit: `git commit -am 'Add new feature'`
1155
+ 4. Push to the branch: `git push origin feature/my-feature`
1156
+ 5. Submit a pull request
1157
+
1158
+ ### Development Guidelines
1159
+
1160
+ - Follow Angular style guide
1161
+ - Use TypeScript strict mode
1162
+ - Write tests for new components
1163
+ - Document all public APIs
1164
+ - Ensure accessibility compliance (WCAG 2.1 AA)
1165
+ - Keep components small and focused
1166
+ - Use signals for reactive state
1167
+
1168
+ ## License
1169
+
1170
+ MIT License - see LICENSE file for details.
1171
+
1172
+ Copyright (c) 2025 PACK Solutions
1173
+
1174
+ ## Resources
1175
+
1176
+ - **Theme Customization Guide**: [THEME.md](./THEME.md)
1177
+ - **Component Documentation**: Individual component README files in `/lib/components/`
1178
+ - **Phosphor Icons**: [https://phosphoricons.com/](https://phosphoricons.com/)
1179
+ - **Angular Documentation**: [https://angular.dev/](https://angular.dev/)
1180
+ - **TypeScript Documentation**: [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
1181
+ - **ngx-translate**: [https://github.com/ngx-translate/core](https://github.com/ngx-translate/core)
1182
+
1183
+ ---
1184
+
1185
+ **Version**: 6.0.1
1186
+ **Built with**: Angular 22.0.0, TypeScript 6.0.0, Phosphor Icons 2.0.3
1187
+ **Author**: Fabrice PEREZ | Product Designer at PACK Solutions
1188
+ **Last Updated**: January 2026