chrv-components 1.12.21 → 1.12.22

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,544 +1,544 @@
1
- # 🎨 CHRV Components
2
-
3
- <div align="center">
4
-
5
- ![npm version](https://img.shields.io/npm/v/chrv-components?style=for-the-badge)
6
- ![Angular](https://img.shields.io/badge/Angular-16+-red?style=for-the-badge&logo=angular)
7
- ![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue?style=for-the-badge&logo=typescript)
8
- ![Tailwind](https://img.shields.io/badge/Tailwind-3.0+-38bdf8?style=for-the-badge&logo=tailwindcss)
9
-
10
- **Bibliothèque complète de composants Angular avec Tailwind CSS**
11
-
12
- [📚 Documentation](#-documentation) • [🚀 Installation](#-installation) • [💡 Exemples](#-exemples) • [🛠️ API](#️-api)
13
-
14
- </div>
15
-
16
- ## ✨ Composants disponibles
17
-
18
- ### 🪟 Système de Modal
19
-
20
- - **ChrModalComponent** - Modal de base avec backdrop et animations
21
- - **ModalService** - Service pour gérer les modals avec injection de tokens
22
-
23
- ### 📝 Formulaires et saisie
24
-
25
- - **ChrFormComponent** - Formulaire dynamique avec sections et contrôles
26
- - **ChrBaseInputComponent** - Input de base avec validation
27
- - **ChrColorInputComponent** - Sélecteur de couleur
28
- - **ChrDateInputComponent** - Input de date
29
- - **ChrDatetimeInputComponent** - Input de date et heure
30
- - **ChrFileInputComponent** - Upload de fichiers
31
- - **ChrNiceFileInputComponent** - Upload de fichiers avec interface améliorée
32
- - **ChrTextareaInputComponent** - Zone de texte multiligne
33
- - **ChrToggleInputComponent** - Bouton toggle on/off
34
- - **ChrSearchSelectComponent** - Sélection avec recherche
35
- - **ChrTagSelectComponent** - Sélection multiple avec tags
36
- - **ChrCheckboxComponent** - Case à cocher stylisée
37
-
38
- ### 📊 Affichage de données
39
-
40
- - **ChrDataTable** - Table de données avec fonctionnalités avancées
41
- - **ChrTableComponent** - Table avec tri et fonctionnalités
42
- - **ChrPaginatorComponent** - Pagination avec gestion des cookies
43
-
44
- ### 🎯 Interface utilisateur
45
-
46
- - **ChrButtonComponent** - Bouton avec icônes et couleurs personnalisables
47
- - **ChrDropdownComponent** - Menu déroulant avec animation et état vide/ouvert
48
- - **ChrContextMenuComponent** - Menu contextuel
49
- - **ChrSpinnerComponent** - Indicateur de chargement
50
- - **ChrToastComponent** - Notifications toast
51
- - **ChrInlineSvgComponent** - Affichage SVG inline
52
-
53
- ### 🧭 Navigation
54
-
55
- - **ChrBreadcrumbComponent** - Fil d'Ariane de navigation
56
- - **TabComponent** - Onglet individuel
57
- - **TabGroupComponent** - Groupe d'onglets
58
- - **CarouselComponent** - Carrousel d'images/contenu
59
-
60
- ### 🎛️ Directives
61
-
62
- - **TabInputOnlyHandlerDirective** - Gestion navigation par Tab
63
- - **TabToEnterHandlerDirective** - Conversion Tab vers Enter
64
- - **AutofocusDirective** - Focus automatique
65
- - **ChrContextMenuDirective** - Directive pour menus contextuels
66
-
67
- ### 🛠️ Services
68
-
69
- - **ModalService** - Gestion des modals avec tokens
70
- - **DialogService** - Service de dialogue
71
- - **DataService** - Service de données
72
- - **LiveUpdateService** - Mises à jour en temps réel
73
- - **LoaderService** - Gestion des états de chargement
74
- - **ToastService** - Service de notifications
75
- - **CookieService** - Gestion des cookies
76
- - **FilesService** - Gestion des fichiers
77
-
78
- ## 🚀 Installation
79
-
80
- ```bash
81
- # Installation avec toutes les dépendances
82
- npm install chrv-components
83
-
84
- # Les dépendances suivantes sont automatiquement incluses :
85
- # - @angular/material
86
- # - ngx-pagination
87
- # - chrv-pipes
88
- # - @microsoft/signalr
89
- ```
90
-
91
- ## ⚙️ Configuration
92
-
93
- ### Import dans votre module Angular
94
-
95
- ```typescript
96
- import { NgModule } from "@angular/core";
97
- import { ChrButtonComponent, ChrFormComponent, ChrTableComponent, ModalService } from "chrv-components";
98
-
99
- @NgModule({
100
- imports: [ChrButtonComponent, ChrFormComponent, ChrTableComponent],
101
- providers: [ModalService],
102
- // ...
103
- })
104
- export class AppModule {}
105
- ```
106
-
107
- ### Import dans un composant standalone
108
-
109
- ```typescript
110
- import { Component } from "@angular/core";
111
- import { ChrButtonComponent, ChrFormComponent } from "chrv-components";
112
-
113
- @Component({
114
- selector: "app-example",
115
- standalone: true,
116
- imports: [ChrButtonComponent, ChrFormComponent],
117
- template: `...`,
118
- })
119
- export class ExampleComponent {}
120
- ```
121
-
122
- ## 💡 Exemples d'utilisation
123
-
124
- ### 🎯 ChrButtonComponent
125
-
126
- Bouton personnalisable avec icônes et couleurs :
127
-
128
- ```html
129
- <!-- Bouton simple -->
130
- <app-chr-button [display]="'Enregistrer'" [color]="'primary'" [click]="saveData"> </app-chr-button>
131
-
132
- <!-- Bouton avec icône -->
133
- <app-chr-button [display]="'Supprimer'" [icon]="'delete'" [color]="'warn'" [click]="deleteItem"> </app-chr-button>
134
-
135
- <!-- Bouton plat -->
136
- <app-chr-button [display]="'Annuler'" [flat]="true" [click]="cancel"> </app-chr-button>
137
- ```
138
-
139
- ### 📝 ChrFormComponent
140
-
141
- Formulaire dynamique basé sur l'interface IControl :
142
-
143
- **Option 1 : Avec sections**
144
-
145
- ```html
146
- <app-chr-form [sections]="formSections"></app-chr-form>
147
- ```
148
-
149
- ```typescript
150
- export class FormExampleComponent {
151
- formSections: IFormSection[] = [
152
- {
153
- title: "Informations personnelles",
154
- controls: [
155
- { name: "firstName", type: "text", label: "Prénom" },
156
- { name: "lastName", type: "text", label: "Nom" },
157
- { name: "email", type: "text", label: "Email" },
158
- { name: "birthDate", type: "date", label: "Date de naissance" },
159
- ],
160
- },
161
- ];
162
- }
163
- ```
164
-
165
- **Option 2 : Avec contrôles directement**
166
-
167
- ```html
168
- <app-chr-form [controls]="formControls"></app-chr-form>
169
- ```
170
-
171
- ```typescript
172
- export class FormExampleComponent {
173
- formControls: IControl[] = [
174
- { name: "firstName", type: "text", label: "Prénom" },
175
- { name: "lastName", type: "text", label: "Nom" },
176
- { name: "email", type: "text", label: "Email" },
177
- { name: "birthDate", type: "date", label: "Date de naissance" },
178
- ];
179
- }
180
- ```
181
-
182
- ### ChrPaginatorComponent
183
-
184
- Pagination avec gestion automatique :
185
-
186
- ```html
187
- <app-chr-paginator [id]="'users-pagination'" [page]="currentPage" [pageSize]="itemsPerPage" [allowSizeChange]="true" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)"> </app-chr-paginator>
188
- ```
189
-
190
- ```typescript
191
- export class PaginationExampleComponent {
192
- currentPage = 1;
193
- itemsPerPage = 20;
194
-
195
- onPageChange(page: number) {
196
- this.currentPage = page;
197
- }
198
-
199
- onPageSizeChange(size: number) {
200
- this.itemsPerPage = size;
201
- }
202
- }
203
- ```
204
-
205
- ### 🪟 ModalService
206
-
207
- Service pour gérer les modals avec injection de données :
208
-
209
- ```typescript
210
- import { Component, inject } from "@angular/core";
211
- import { ModalService, CHR_MODAL_DATA, CHR_MODAL_REF } from "chrv-components";
212
-
213
- // Composant de modal
214
- @Component({
215
- template: `
216
- <div class="modal-content">
217
- <h2>{{ data.title }}</h2>
218
- <p>{{ data.message }}</p>
219
- <button (click)="close()">Fermer</button>
220
- </div>
221
- `,
222
- })
223
- export class MyModalComponent {
224
- data = inject(CHR_MODAL_DATA);
225
- modalRef = inject(CHR_MODAL_REF);
226
-
227
- close() {
228
- this.modalRef.close();
229
- }
230
- }
231
-
232
- // Utilisation du service
233
- export class ParentComponent {
234
- private modalService = inject(ModalService);
235
-
236
- openModal() {
237
- this.modalService.open(MyModalComponent, {
238
- data: {
239
- title: "Confirmation",
240
- message: "Êtes-vous sûr de vouloir continuer ?",
241
- },
242
- });
243
- }
244
- }
245
- ```
246
-
247
- ### 🏷️ ChrTagSelectComponent
248
-
249
- Sélection multiple avec tags :
250
-
251
- ```html
252
- <chr-tag-select [data]="availableData" [display]="displayFunction" [placeholder]="'Sélectionner des éléments...'" [acceptText]="true"> </chr-tag-select>
253
- ```
254
-
255
- ```typescript
256
- export class TagSelectExampleComponent {
257
- availableData = [
258
- { id: 1, name: "Option 1" },
259
- { id: 2, name: "Option 2" },
260
- { id: 3, name: "Option 3" },
261
- ];
262
-
263
- displayFunction = (item: any) => item.name;
264
- }
265
- ```
266
-
267
- ### 🔄 ChrSpinnerComponent
268
-
269
- Indicateur de chargement automatique :
270
-
271
- ```html
272
- <!-- Spinner simple (contrôlé par LoaderService) -->
273
- <app-chr-spinner></app-chr-spinner>
274
- ```
275
-
276
- ```typescript
277
- export class SpinnerExampleComponent {
278
- private loaderService = inject(LoaderService);
279
-
280
- showSpinner() {
281
- this.loaderService.show();
282
- // Simulation d'une tâche
283
- setTimeout(() => {
284
- this.loaderService.hide();
285
- }, 2000);
286
- }
287
- }
288
- ```
289
-
290
- ## 🛠️ API
291
-
292
- ### ChrButtonComponent
293
-
294
- ```typescript
295
- @Component({
296
- inputs: {
297
- display: string; // Texte du bouton
298
- icon: string; // Icône Material
299
- click: Function; // Fonction onClick
300
- color: Color; // Couleur du bouton
301
- textColor: Color; // Couleur du texte
302
- flat: boolean; // Style plat
303
- }
304
- })
305
- ```
306
-
307
- ### ChrSearchbarComponent
308
-
309
- ```typescript
310
- @Component({
311
- inputs: {
312
- model: string | null; // Valeur actuelle
313
- placeholder: string | null; // Texte d'aide
314
- label: string | null; // Label du champ
315
- },
316
- outputs: {
317
- modelChange: string; // Changement de valeur
318
- }
319
- })
320
- ```
321
-
322
- ### ChrFormComponent
323
-
324
- ```typescript
325
- @Component({
326
- inputs: {
327
- sections: IFormSection[]; // Sections avec contrôles groupés
328
- controls: IControl[]; // Contrôles directs (utiliser l'un OU l'autre)
329
- }
330
- })
331
- ```
332
-
333
- **Interface IControl :**
334
-
335
- ```typescript
336
- interface IControl {
337
- name: string; // Nom unique du contrôle
338
- type: InputType; // Type d'input
339
- label?: string; // Label affiché
340
- value?: any; // Valeur par défaut
341
- validations?: IControlValidation[]; // Validations
342
- data?: any[]; // Données pour select/options
343
- // ... autres propriétés
344
- }
345
- ```
346
-
347
- **Interface IFormSection :**
348
-
349
- ```typescript
350
- interface IFormSection {
351
- title?: string; // Titre de la section
352
- controls: IControl[]; // Contrôles de la section
353
- }
354
- ```
355
-
356
- ### ChrSearchbarComponent
357
-
358
- ```typescript
359
- @Component({
360
- inputs: {
361
- model: string | null; // Valeur actuelle
362
- placeholder: string | null; // Texte d'aide
363
- label: string | null; // Label du champ
364
- },
365
- outputs: {
366
- modelChange: string; // Changement de valeur
367
- }
368
- })
369
- ```
370
-
371
- ### ChrPaginatorComponent
372
-
373
- ```typescript
374
- @Component({
375
- inputs: {
376
- page: number; // Page actuelle
377
- pageSize: number; // Nombre d'éléments par page
378
- id: string; // ID unique du paginateur
379
- allowSizeChange: boolean | string; // Permet de changer la taille
380
- },
381
- outputs: {
382
- pageChange: number; // Changement de page
383
- pageSizeChange: number; // Changement de taille
384
- }
385
- })
386
- ```
387
-
388
- ### ChrTagSelectComponent
389
-
390
- ```typescript
391
- @Component({
392
- inputs: {
393
- placeholder: string; // Texte d'aide dans l'input
394
- data: any[] | null; // Données pour l'autocomplete
395
- display: (entry: any) => string; // Fonction d'affichage
396
- filters: IInputSearchFilter[] | null; // Filtres de recherche
397
- editCallback: Function; // Callback de modification
398
- addCallback: Function; // Callback d'ajout
399
- removeCallback: Function; // Callback de suppression
400
- acceptText: boolean | null; // Accepte le texte libre
401
- }
402
- })
403
- ```
404
-
405
- ### ModalService
406
-
407
- ```typescript
408
- class ModalService {
409
- open<T>(component: ComponentType<T>, options?: ModalOptions): void;
410
- close(): void;
411
- }
412
-
413
- interface ModalOptions {
414
- closeOnBackdropClick?: boolean;
415
- closeOnEscape?: boolean;
416
- width?: number;
417
- height?: number;
418
- data?: any; // Données injectées via CHR_MODAL_DATA
419
- }
420
- ```
421
-
422
- ## 🎨 Thèmes et personnalisation
423
-
424
- ### Variables CSS disponibles
425
-
426
- Les composants utilisent un système de variables CSS pour les couleurs. Vous pouvez les personnaliser en redéfinissant ces variables :
427
-
428
- ```css
429
- :root {
430
- --primary-color: #your-color;
431
- --primary-contrast-color: #your-contrast-color;
432
- --secondary-color: #your-secondary;
433
- --secondary-contrast-color: #your-secondary-contrast;
434
- --tertiary-color: #your-tertiary;
435
- --tertiary-contrast-color: #your-tertiary-contrast;
436
- --warn-color: #your-warn;
437
- --warn-contrast-color: #your-warn-contrast;
438
- --error-color: #your-error;
439
- --error-contrast-color: #your-error-contrast;
440
- --neutral-color: #your-neutral;
441
- --text-color: #your-text;
442
- --text-neutral-color: #your-text-neutral;
443
- }
444
- ```
445
-
446
- ### Classes CSS disponibles
447
-
448
- La bibliothèque fournit des classes utilitaires pour les couleurs :
449
-
450
- ```css
451
- /* Arrière-plans */
452
- .bg-primary, .bg-secondary, .bg-tertiary, .bg-warn, .bg-error, .bg-neutral
453
- .bg-primary-contrast, .bg-secondary-contrast, .bg-tertiary-contrast, .bg-warn-contrast, .bg-error-contrast
454
-
455
- /* Texte */
456
- .text-primary, .text-secondary, .text-tertiary, .text-warn, .text-error, .text-neutral
457
- .text-primary-contrast, .text-secondary-contrast, .text-tertiary-contrast, .text-warn-contrast, .text-error-contrast
458
-
459
- /* Bordures */
460
- .border-primary, .border-secondary, .border-tertiary, .border-warn, .border-error
461
- .border-primary-contrast, .border-secondary-contrast, .border-tertiary-contrast, .border-warn-contrast, .border-error-contrast;
462
- ```
463
-
464
- ### Personnalisation avancée avec ::ng-deep
465
-
466
- Pour modifier les styles des composants compilés, utilisez `::ng-deep` :
467
-
468
- ```scss
469
- // Dans votre composant .scss
470
- ::ng-deep .chr-button {
471
- border-radius: 8px;
472
- font-weight: 600;
473
- }
474
-
475
- ::ng-deep .chr-form .form-field {
476
- margin-bottom: 16px;
477
- }
478
-
479
- ::ng-deep .chr-modal .modal-backdrop {
480
- background-color: rgba(0, 0, 0, 0.8);
481
- }
482
- ```
483
-
484
- ### Exemple de thème personnalisé
485
-
486
- ```css
487
- /* Thème sombre personnalisé */
488
- :root {
489
- --primary-color: #3b82f6;
490
- --primary-contrast-color: #ffffff;
491
- --secondary-color: #6b7280;
492
- --secondary-contrast-color: #ffffff;
493
- --tertiary-color: #f3f4f6;
494
- --tertiary-contrast-color: #1f2937;
495
- --warn-color: #f59e0b;
496
- --warn-contrast-color: #ffffff;
497
- --error-color: #ef4444;
498
- --error-contrast-color: #ffffff;
499
- --neutral-color: #e5e7eb;
500
- --text-color: #1f2937;
501
- --text-neutral-color: #6b7280;
502
- }
503
- ```
504
-
505
- ## 📦 Intégrations
506
-
507
- ### Dépendances automatiques
508
-
509
- - **Angular Material** - Composants Material Design
510
- - **ngx-pagination** - Pagination avancée
511
- - **chrv-pipes** - Pipes utilitaires
512
- - **@microsoft/signalr** - Communication temps réel
513
- - **ngx-mask** - Masques de saisie
514
-
515
- ### Interceptors et providers
516
-
517
- ```typescript
518
- // Configuration automatique des interceptors
519
- import {
520
- SpinnerInterceptor,
521
- XsrfInterceptor,
522
- xsrfProvider
523
- } from 'chrv-components';
524
-
525
- @NgModule({
526
- providers: [
527
- xsrfProvider,
528
- { provide: HTTP_INTERCEPTORS, useClass: SpinnerInterceptor, multi: true },
529
- { provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor, multi: true }
530
- ]
531
- })
532
- ```
533
-
534
- ## 📝 Notes
535
-
536
- - Compatible Angular 16+
537
- - Composants standalone prêts pour le tree-shaking
538
- - Types TypeScript complets
539
- - Intégration Tailwind CSS native
540
- - Support des signaux Angular modernes
541
-
542
- ## 📄 Licence
543
-
544
- MIT © CHRV Components
1
+ # 🎨 CHRV Components
2
+
3
+ <div align="center">
4
+
5
+ ![npm version](https://img.shields.io/npm/v/chrv-components?style=for-the-badge)
6
+ ![Angular](https://img.shields.io/badge/Angular-16+-red?style=for-the-badge&logo=angular)
7
+ ![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue?style=for-the-badge&logo=typescript)
8
+ ![Tailwind](https://img.shields.io/badge/Tailwind-3.0+-38bdf8?style=for-the-badge&logo=tailwindcss)
9
+
10
+ **Bibliothèque complète de composants Angular avec Tailwind CSS**
11
+
12
+ [📚 Documentation](#-documentation) • [🚀 Installation](#-installation) • [💡 Exemples](#-exemples) • [🛠️ API](#️-api)
13
+
14
+ </div>
15
+
16
+ ## ✨ Composants disponibles
17
+
18
+ ### 🪟 Système de Modal
19
+
20
+ - **ChrModalComponent** - Modal de base avec backdrop et animations
21
+ - **ModalService** - Service pour gérer les modals avec injection de tokens
22
+
23
+ ### 📝 Formulaires et saisie
24
+
25
+ - **ChrFormComponent** - Formulaire dynamique avec sections et contrôles
26
+ - **ChrBaseInputComponent** - Input de base avec validation
27
+ - **ChrColorInputComponent** - Sélecteur de couleur
28
+ - **ChrDateInputComponent** - Input de date
29
+ - **ChrDatetimeInputComponent** - Input de date et heure
30
+ - **ChrFileInputComponent** - Upload de fichiers
31
+ - **ChrNiceFileInputComponent** - Upload de fichiers avec interface améliorée
32
+ - **ChrTextareaInputComponent** - Zone de texte multiligne
33
+ - **ChrToggleInputComponent** - Bouton toggle on/off
34
+ - **ChrSearchSelectComponent** - Sélection avec recherche
35
+ - **ChrTagSelectComponent** - Sélection multiple avec tags
36
+ - **ChrCheckboxComponent** - Case à cocher stylisée
37
+
38
+ ### 📊 Affichage de données
39
+
40
+ - **ChrDataTable** - Table de données avec fonctionnalités avancées
41
+ - **ChrTableComponent** - Table avec tri et fonctionnalités
42
+ - **ChrPaginatorComponent** - Pagination avec gestion des cookies
43
+
44
+ ### 🎯 Interface utilisateur
45
+
46
+ - **ChrButtonComponent** - Bouton avec icônes et couleurs personnalisables
47
+ - **ChrDropdownComponent** - Menu déroulant avec animation et état vide/ouvert
48
+ - **ChrContextMenuComponent** - Menu contextuel
49
+ - **ChrSpinnerComponent** - Indicateur de chargement
50
+ - **ChrToastComponent** - Notifications toast
51
+ - **ChrInlineSvgComponent** - Affichage SVG inline
52
+
53
+ ### 🧭 Navigation
54
+
55
+ - **ChrBreadcrumbComponent** - Fil d'Ariane de navigation
56
+ - **TabComponent** - Onglet individuel
57
+ - **TabGroupComponent** - Groupe d'onglets
58
+ - **CarouselComponent** - Carrousel d'images/contenu
59
+
60
+ ### 🎛️ Directives
61
+
62
+ - **TabInputOnlyHandlerDirective** - Gestion navigation par Tab
63
+ - **TabToEnterHandlerDirective** - Conversion Tab vers Enter
64
+ - **AutofocusDirective** - Focus automatique
65
+ - **ChrContextMenuDirective** - Directive pour menus contextuels
66
+
67
+ ### 🛠️ Services
68
+
69
+ - **ModalService** - Gestion des modals avec tokens
70
+ - **DialogService** - Service de dialogue
71
+ - **DataService** - Service de données
72
+ - **LiveUpdateService** - Mises à jour en temps réel
73
+ - **LoaderService** - Gestion des états de chargement
74
+ - **ToastService** - Service de notifications
75
+ - **CookieService** - Gestion des cookies
76
+ - **FilesService** - Gestion des fichiers
77
+
78
+ ## 🚀 Installation
79
+
80
+ ```bash
81
+ # Installation avec toutes les dépendances
82
+ npm install chrv-components
83
+
84
+ # Les dépendances suivantes sont automatiquement incluses :
85
+ # - @angular/material
86
+ # - ngx-pagination
87
+ # - chrv-pipes
88
+ # - @microsoft/signalr
89
+ ```
90
+
91
+ ## ⚙️ Configuration
92
+
93
+ ### Import dans votre module Angular
94
+
95
+ ```typescript
96
+ import { NgModule } from "@angular/core";
97
+ import { ChrButtonComponent, ChrFormComponent, ChrTableComponent, ModalService } from "chrv-components";
98
+
99
+ @NgModule({
100
+ imports: [ChrButtonComponent, ChrFormComponent, ChrTableComponent],
101
+ providers: [ModalService],
102
+ // ...
103
+ })
104
+ export class AppModule {}
105
+ ```
106
+
107
+ ### Import dans un composant standalone
108
+
109
+ ```typescript
110
+ import { Component } from "@angular/core";
111
+ import { ChrButtonComponent, ChrFormComponent } from "chrv-components";
112
+
113
+ @Component({
114
+ selector: "app-example",
115
+ standalone: true,
116
+ imports: [ChrButtonComponent, ChrFormComponent],
117
+ template: `...`,
118
+ })
119
+ export class ExampleComponent {}
120
+ ```
121
+
122
+ ## 💡 Exemples d'utilisation
123
+
124
+ ### 🎯 ChrButtonComponent
125
+
126
+ Bouton personnalisable avec icônes et couleurs :
127
+
128
+ ```html
129
+ <!-- Bouton simple -->
130
+ <app-chr-button [display]="'Enregistrer'" [color]="'primary'" [click]="saveData"> </app-chr-button>
131
+
132
+ <!-- Bouton avec icône -->
133
+ <app-chr-button [display]="'Supprimer'" [icon]="'delete'" [color]="'warn'" [click]="deleteItem"> </app-chr-button>
134
+
135
+ <!-- Bouton plat -->
136
+ <app-chr-button [display]="'Annuler'" [flat]="true" [click]="cancel"> </app-chr-button>
137
+ ```
138
+
139
+ ### 📝 ChrFormComponent
140
+
141
+ Formulaire dynamique basé sur l'interface IControl :
142
+
143
+ **Option 1 : Avec sections**
144
+
145
+ ```html
146
+ <app-chr-form [sections]="formSections"></app-chr-form>
147
+ ```
148
+
149
+ ```typescript
150
+ export class FormExampleComponent {
151
+ formSections: IFormSection[] = [
152
+ {
153
+ title: "Informations personnelles",
154
+ controls: [
155
+ { name: "firstName", type: "text", label: "Prénom" },
156
+ { name: "lastName", type: "text", label: "Nom" },
157
+ { name: "email", type: "text", label: "Email" },
158
+ { name: "birthDate", type: "date", label: "Date de naissance" },
159
+ ],
160
+ },
161
+ ];
162
+ }
163
+ ```
164
+
165
+ **Option 2 : Avec contrôles directement**
166
+
167
+ ```html
168
+ <app-chr-form [controls]="formControls"></app-chr-form>
169
+ ```
170
+
171
+ ```typescript
172
+ export class FormExampleComponent {
173
+ formControls: IControl[] = [
174
+ { name: "firstName", type: "text", label: "Prénom" },
175
+ { name: "lastName", type: "text", label: "Nom" },
176
+ { name: "email", type: "text", label: "Email" },
177
+ { name: "birthDate", type: "date", label: "Date de naissance" },
178
+ ];
179
+ }
180
+ ```
181
+
182
+ ### ChrPaginatorComponent
183
+
184
+ Pagination avec gestion automatique :
185
+
186
+ ```html
187
+ <app-chr-paginator [id]="'users-pagination'" [page]="currentPage" [pageSize]="itemsPerPage" [allowSizeChange]="true" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)"> </app-chr-paginator>
188
+ ```
189
+
190
+ ```typescript
191
+ export class PaginationExampleComponent {
192
+ currentPage = 1;
193
+ itemsPerPage = 20;
194
+
195
+ onPageChange(page: number) {
196
+ this.currentPage = page;
197
+ }
198
+
199
+ onPageSizeChange(size: number) {
200
+ this.itemsPerPage = size;
201
+ }
202
+ }
203
+ ```
204
+
205
+ ### 🪟 ModalService
206
+
207
+ Service pour gérer les modals avec injection de données :
208
+
209
+ ```typescript
210
+ import { Component, inject } from "@angular/core";
211
+ import { ModalService, CHR_MODAL_DATA, CHR_MODAL_REF } from "chrv-components";
212
+
213
+ // Composant de modal
214
+ @Component({
215
+ template: `
216
+ <div class="modal-content">
217
+ <h2>{{ data.title }}</h2>
218
+ <p>{{ data.message }}</p>
219
+ <button (click)="close()">Fermer</button>
220
+ </div>
221
+ `,
222
+ })
223
+ export class MyModalComponent {
224
+ data = inject(CHR_MODAL_DATA);
225
+ modalRef = inject(CHR_MODAL_REF);
226
+
227
+ close() {
228
+ this.modalRef.close();
229
+ }
230
+ }
231
+
232
+ // Utilisation du service
233
+ export class ParentComponent {
234
+ private modalService = inject(ModalService);
235
+
236
+ openModal() {
237
+ this.modalService.open(MyModalComponent, {
238
+ data: {
239
+ title: "Confirmation",
240
+ message: "Êtes-vous sûr de vouloir continuer ?",
241
+ },
242
+ });
243
+ }
244
+ }
245
+ ```
246
+
247
+ ### 🏷️ ChrTagSelectComponent
248
+
249
+ Sélection multiple avec tags :
250
+
251
+ ```html
252
+ <chr-tag-select [data]="availableData" [display]="displayFunction" [placeholder]="'Sélectionner des éléments...'" [acceptText]="true"> </chr-tag-select>
253
+ ```
254
+
255
+ ```typescript
256
+ export class TagSelectExampleComponent {
257
+ availableData = [
258
+ { id: 1, name: "Option 1" },
259
+ { id: 2, name: "Option 2" },
260
+ { id: 3, name: "Option 3" },
261
+ ];
262
+
263
+ displayFunction = (item: any) => item.name;
264
+ }
265
+ ```
266
+
267
+ ### 🔄 ChrSpinnerComponent
268
+
269
+ Indicateur de chargement automatique :
270
+
271
+ ```html
272
+ <!-- Spinner simple (contrôlé par LoaderService) -->
273
+ <app-chr-spinner></app-chr-spinner>
274
+ ```
275
+
276
+ ```typescript
277
+ export class SpinnerExampleComponent {
278
+ private loaderService = inject(LoaderService);
279
+
280
+ showSpinner() {
281
+ this.loaderService.show();
282
+ // Simulation d'une tâche
283
+ setTimeout(() => {
284
+ this.loaderService.hide();
285
+ }, 2000);
286
+ }
287
+ }
288
+ ```
289
+
290
+ ## 🛠️ API
291
+
292
+ ### ChrButtonComponent
293
+
294
+ ```typescript
295
+ @Component({
296
+ inputs: {
297
+ display: string; // Texte du bouton
298
+ icon: string; // Icône Material
299
+ click: Function; // Fonction onClick
300
+ color: Color; // Couleur du bouton
301
+ textColor: Color; // Couleur du texte
302
+ flat: boolean; // Style plat
303
+ }
304
+ })
305
+ ```
306
+
307
+ ### ChrSearchbarComponent
308
+
309
+ ```typescript
310
+ @Component({
311
+ inputs: {
312
+ model: string | null; // Valeur actuelle
313
+ placeholder: string | null; // Texte d'aide
314
+ label: string | null; // Label du champ
315
+ },
316
+ outputs: {
317
+ modelChange: string; // Changement de valeur
318
+ }
319
+ })
320
+ ```
321
+
322
+ ### ChrFormComponent
323
+
324
+ ```typescript
325
+ @Component({
326
+ inputs: {
327
+ sections: IFormSection[]; // Sections avec contrôles groupés
328
+ controls: IControl[]; // Contrôles directs (utiliser l'un OU l'autre)
329
+ }
330
+ })
331
+ ```
332
+
333
+ **Interface IControl :**
334
+
335
+ ```typescript
336
+ interface IControl {
337
+ name: string; // Nom unique du contrôle
338
+ type: InputType; // Type d'input
339
+ label?: string; // Label affiché
340
+ value?: any; // Valeur par défaut
341
+ validations?: IControlValidation[]; // Validations
342
+ data?: any[]; // Données pour select/options
343
+ // ... autres propriétés
344
+ }
345
+ ```
346
+
347
+ **Interface IFormSection :**
348
+
349
+ ```typescript
350
+ interface IFormSection {
351
+ title?: string; // Titre de la section
352
+ controls: IControl[]; // Contrôles de la section
353
+ }
354
+ ```
355
+
356
+ ### ChrSearchbarComponent
357
+
358
+ ```typescript
359
+ @Component({
360
+ inputs: {
361
+ model: string | null; // Valeur actuelle
362
+ placeholder: string | null; // Texte d'aide
363
+ label: string | null; // Label du champ
364
+ },
365
+ outputs: {
366
+ modelChange: string; // Changement de valeur
367
+ }
368
+ })
369
+ ```
370
+
371
+ ### ChrPaginatorComponent
372
+
373
+ ```typescript
374
+ @Component({
375
+ inputs: {
376
+ page: number; // Page actuelle
377
+ pageSize: number; // Nombre d'éléments par page
378
+ id: string; // ID unique du paginateur
379
+ allowSizeChange: boolean | string; // Permet de changer la taille
380
+ },
381
+ outputs: {
382
+ pageChange: number; // Changement de page
383
+ pageSizeChange: number; // Changement de taille
384
+ }
385
+ })
386
+ ```
387
+
388
+ ### ChrTagSelectComponent
389
+
390
+ ```typescript
391
+ @Component({
392
+ inputs: {
393
+ placeholder: string; // Texte d'aide dans l'input
394
+ data: any[] | null; // Données pour l'autocomplete
395
+ display: (entry: any) => string; // Fonction d'affichage
396
+ filters: IInputSearchFilter[] | null; // Filtres de recherche
397
+ editCallback: Function; // Callback de modification
398
+ addCallback: Function; // Callback d'ajout
399
+ removeCallback: Function; // Callback de suppression
400
+ acceptText: boolean | null; // Accepte le texte libre
401
+ }
402
+ })
403
+ ```
404
+
405
+ ### ModalService
406
+
407
+ ```typescript
408
+ class ModalService {
409
+ open<T>(component: ComponentType<T>, options?: ModalOptions): void;
410
+ close(): void;
411
+ }
412
+
413
+ interface ModalOptions {
414
+ closeOnBackdropClick?: boolean;
415
+ closeOnEscape?: boolean;
416
+ width?: number;
417
+ height?: number;
418
+ data?: any; // Données injectées via CHR_MODAL_DATA
419
+ }
420
+ ```
421
+
422
+ ## 🎨 Thèmes et personnalisation
423
+
424
+ ### Variables CSS disponibles
425
+
426
+ Les composants utilisent un système de variables CSS pour les couleurs. Vous pouvez les personnaliser en redéfinissant ces variables :
427
+
428
+ ```css
429
+ :root {
430
+ --primary-color: #your-color;
431
+ --primary-contrast-color: #your-contrast-color;
432
+ --secondary-color: #your-secondary;
433
+ --secondary-contrast-color: #your-secondary-contrast;
434
+ --tertiary-color: #your-tertiary;
435
+ --tertiary-contrast-color: #your-tertiary-contrast;
436
+ --warn-color: #your-warn;
437
+ --warn-contrast-color: #your-warn-contrast;
438
+ --error-color: #your-error;
439
+ --error-contrast-color: #your-error-contrast;
440
+ --neutral-color: #your-neutral;
441
+ --text-color: #your-text;
442
+ --text-neutral-color: #your-text-neutral;
443
+ }
444
+ ```
445
+
446
+ ### Classes CSS disponibles
447
+
448
+ La bibliothèque fournit des classes utilitaires pour les couleurs :
449
+
450
+ ```css
451
+ /* Arrière-plans */
452
+ .bg-primary, .bg-secondary, .bg-tertiary, .bg-warn, .bg-error, .bg-neutral
453
+ .bg-primary-contrast, .bg-secondary-contrast, .bg-tertiary-contrast, .bg-warn-contrast, .bg-error-contrast
454
+
455
+ /* Texte */
456
+ .text-primary, .text-secondary, .text-tertiary, .text-warn, .text-error, .text-neutral
457
+ .text-primary-contrast, .text-secondary-contrast, .text-tertiary-contrast, .text-warn-contrast, .text-error-contrast
458
+
459
+ /* Bordures */
460
+ .border-primary, .border-secondary, .border-tertiary, .border-warn, .border-error
461
+ .border-primary-contrast, .border-secondary-contrast, .border-tertiary-contrast, .border-warn-contrast, .border-error-contrast;
462
+ ```
463
+
464
+ ### Personnalisation avancée avec ::ng-deep
465
+
466
+ Pour modifier les styles des composants compilés, utilisez `::ng-deep` :
467
+
468
+ ```scss
469
+ // Dans votre composant .scss
470
+ ::ng-deep .chr-button {
471
+ border-radius: 8px;
472
+ font-weight: 600;
473
+ }
474
+
475
+ ::ng-deep .chr-form .form-field {
476
+ margin-bottom: 16px;
477
+ }
478
+
479
+ ::ng-deep .chr-modal .modal-backdrop {
480
+ background-color: rgba(0, 0, 0, 0.8);
481
+ }
482
+ ```
483
+
484
+ ### Exemple de thème personnalisé
485
+
486
+ ```css
487
+ /* Thème sombre personnalisé */
488
+ :root {
489
+ --primary-color: #3b82f6;
490
+ --primary-contrast-color: #ffffff;
491
+ --secondary-color: #6b7280;
492
+ --secondary-contrast-color: #ffffff;
493
+ --tertiary-color: #f3f4f6;
494
+ --tertiary-contrast-color: #1f2937;
495
+ --warn-color: #f59e0b;
496
+ --warn-contrast-color: #ffffff;
497
+ --error-color: #ef4444;
498
+ --error-contrast-color: #ffffff;
499
+ --neutral-color: #e5e7eb;
500
+ --text-color: #1f2937;
501
+ --text-neutral-color: #6b7280;
502
+ }
503
+ ```
504
+
505
+ ## 📦 Intégrations
506
+
507
+ ### Dépendances automatiques
508
+
509
+ - **Angular Material** - Composants Material Design
510
+ - **ngx-pagination** - Pagination avancée
511
+ - **chrv-pipes** - Pipes utilitaires
512
+ - **@microsoft/signalr** - Communication temps réel
513
+ - **ngx-mask** - Masques de saisie
514
+
515
+ ### Interceptors et providers
516
+
517
+ ```typescript
518
+ // Configuration automatique des interceptors
519
+ import {
520
+ SpinnerInterceptor,
521
+ XsrfInterceptor,
522
+ xsrfProvider
523
+ } from 'chrv-components';
524
+
525
+ @NgModule({
526
+ providers: [
527
+ xsrfProvider,
528
+ { provide: HTTP_INTERCEPTORS, useClass: SpinnerInterceptor, multi: true },
529
+ { provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor, multi: true }
530
+ ]
531
+ })
532
+ ```
533
+
534
+ ## 📝 Notes
535
+
536
+ - Compatible Angular 16+
537
+ - Composants standalone prêts pour le tree-shaking
538
+ - Types TypeScript complets
539
+ - Intégration Tailwind CSS native
540
+ - Support des signaux Angular modernes
541
+
542
+ ## 📄 Licence
543
+
544
+ MIT © CHRV Components