chrv-components 1.11.3 → 1.11.5
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 +242 -58
- package/chrv-components-1.11.5.tgz +0 -0
- package/package.json +1 -1
- package/chrv-components-1.11.3.tgz +0 -0
package/README.md
CHANGED
|
@@ -37,24 +37,23 @@
|
|
|
37
37
|
|
|
38
38
|
### 📊 Affichage de données
|
|
39
39
|
|
|
40
|
-
- **
|
|
40
|
+
- **ChrDataTable** - Table de données avec fonctionnalités avancées
|
|
41
|
+
- **ChrTableComponent** - Table avec tri et fonctionnalités
|
|
41
42
|
- **ChrPaginatorComponent** - Pagination avec gestion des cookies
|
|
42
43
|
|
|
43
44
|
### 🎯 Interface utilisateur
|
|
44
45
|
|
|
45
46
|
- **ChrButtonComponent** - Bouton avec icônes et couleurs personnalisables
|
|
46
|
-
- **ChrButtonNewComponent** - Nouvelle version du bouton
|
|
47
47
|
- **ChrSpinnerComponent** - Indicateur de chargement
|
|
48
48
|
- **ChrToastComponent** - Notifications toast
|
|
49
|
-
- **ChrSeparatorComponent** - Séparateur visuel
|
|
50
49
|
- **ChrInlineSvgComponent** - Affichage SVG inline
|
|
51
50
|
|
|
52
51
|
### 🧭 Navigation
|
|
53
52
|
|
|
54
53
|
- **ChrBreadcrumbComponent** - Fil d'Ariane de navigation
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
54
|
+
- **TabComponent** - Onglet individuel
|
|
55
|
+
- **TabGroupComponent** - Groupe d'onglets
|
|
56
|
+
- **CarouselComponent** - Carrousel d'images/contenu
|
|
58
57
|
|
|
59
58
|
### 🎛️ Directives
|
|
60
59
|
|
|
@@ -107,12 +106,12 @@ export class AppModule {}
|
|
|
107
106
|
|
|
108
107
|
```typescript
|
|
109
108
|
import { Component } from "@angular/core";
|
|
110
|
-
import { ChrButtonComponent,
|
|
109
|
+
import { ChrButtonComponent, ChrFormComponent } from "chrv-components";
|
|
111
110
|
|
|
112
111
|
@Component({
|
|
113
112
|
selector: "app-example",
|
|
114
113
|
standalone: true,
|
|
115
|
-
imports: [ChrButtonComponent,
|
|
114
|
+
imports: [ChrButtonComponent, ChrFormComponent],
|
|
116
115
|
template: `...`,
|
|
117
116
|
})
|
|
118
117
|
export class ExampleComponent {}
|
|
@@ -137,54 +136,68 @@ Bouton personnalisable avec icônes et couleurs :
|
|
|
137
136
|
|
|
138
137
|
### 📝 ChrFormComponent
|
|
139
138
|
|
|
140
|
-
Formulaire dynamique
|
|
139
|
+
Formulaire dynamique basé sur l'interface IControl :
|
|
140
|
+
|
|
141
|
+
**Option 1 : Avec sections**
|
|
141
142
|
|
|
142
143
|
```html
|
|
143
|
-
<app-chr-form [sections]="formSections"
|
|
144
|
+
<app-chr-form [sections]="formSections"></app-chr-form>
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
```typescript
|
|
147
148
|
export class FormExampleComponent {
|
|
148
|
-
formSections = [
|
|
149
|
+
formSections: IFormSection[] = [
|
|
149
150
|
{
|
|
150
151
|
title: "Informations personnelles",
|
|
151
|
-
controls: [
|
|
152
|
+
controls: [
|
|
153
|
+
{ name: "firstName", type: "text", label: "Prénom" },
|
|
154
|
+
{ name: "lastName", type: "text", label: "Nom" },
|
|
155
|
+
{ name: "email", type: "text", label: "Email" },
|
|
156
|
+
{ name: "birthDate", type: "date", label: "Date de naissance" },
|
|
157
|
+
],
|
|
152
158
|
},
|
|
153
159
|
];
|
|
154
|
-
|
|
155
|
-
formControls = {
|
|
156
|
-
name: { type: "text", label: "Nom", required: true },
|
|
157
|
-
email: { type: "email", label: "Email", required: true },
|
|
158
|
-
birthDate: { type: "date", label: "Date de naissance" },
|
|
159
|
-
};
|
|
160
160
|
}
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
Barre de recherche réactive :
|
|
163
|
+
**Option 2 : Avec contrôles directement**
|
|
166
164
|
|
|
167
165
|
```html
|
|
168
|
-
<app-chr-
|
|
166
|
+
<app-chr-form [controls]="formControls"></app-chr-form>
|
|
169
167
|
```
|
|
170
168
|
|
|
171
169
|
```typescript
|
|
172
|
-
export class
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
170
|
+
export class FormExampleComponent {
|
|
171
|
+
formControls: IControl[] = [
|
|
172
|
+
{ name: "firstName", type: "text", label: "Prénom" },
|
|
173
|
+
{ name: "lastName", type: "text", label: "Nom" },
|
|
174
|
+
{ name: "email", type: "text", label: "Email" },
|
|
175
|
+
{ name: "birthDate", type: "date", label: "Date de naissance" },
|
|
176
|
+
];
|
|
179
177
|
}
|
|
180
178
|
```
|
|
181
179
|
|
|
182
|
-
###
|
|
180
|
+
### ChrPaginatorComponent
|
|
183
181
|
|
|
184
182
|
Pagination avec gestion automatique :
|
|
185
183
|
|
|
186
184
|
```html
|
|
187
|
-
<app-chr-paginator [id]="'users-pagination'" [
|
|
185
|
+
<app-chr-paginator [id]="'users-pagination'" [page]="currentPage" [pageSize]="itemsPerPage" [allowSizeChange]="true" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)"> </app-chr-paginator>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
export class PaginationExampleComponent {
|
|
190
|
+
currentPage = 1;
|
|
191
|
+
itemsPerPage = 20;
|
|
192
|
+
|
|
193
|
+
onPageChange(page: number) {
|
|
194
|
+
this.currentPage = page;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
onPageSizeChange(size: number) {
|
|
198
|
+
this.itemsPerPage = size;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
188
201
|
```
|
|
189
202
|
|
|
190
203
|
### 🪟 ModalService
|
|
@@ -193,7 +206,7 @@ Service pour gérer les modals avec injection de données :
|
|
|
193
206
|
|
|
194
207
|
```typescript
|
|
195
208
|
import { Component, inject } from "@angular/core";
|
|
196
|
-
import { ModalService,
|
|
209
|
+
import { ModalService, CHR_MODAL_DATA, CHR_MODAL_REF } from "chrv-components";
|
|
197
210
|
|
|
198
211
|
// Composant de modal
|
|
199
212
|
@Component({
|
|
@@ -206,8 +219,8 @@ import { ModalService, MODAL_DATA, MODAL_REF } from "chrv-components";
|
|
|
206
219
|
`,
|
|
207
220
|
})
|
|
208
221
|
export class MyModalComponent {
|
|
209
|
-
data = inject(
|
|
210
|
-
modalRef = inject(
|
|
222
|
+
data = inject(CHR_MODAL_DATA);
|
|
223
|
+
modalRef = inject(CHR_MODAL_REF);
|
|
211
224
|
|
|
212
225
|
close() {
|
|
213
226
|
this.modalRef.close();
|
|
@@ -220,8 +233,10 @@ export class ParentComponent {
|
|
|
220
233
|
|
|
221
234
|
openModal() {
|
|
222
235
|
this.modalService.open(MyModalComponent, {
|
|
223
|
-
|
|
224
|
-
|
|
236
|
+
data: {
|
|
237
|
+
title: "Confirmation",
|
|
238
|
+
message: "Êtes-vous sûr de vouloir continuer ?",
|
|
239
|
+
},
|
|
225
240
|
});
|
|
226
241
|
}
|
|
227
242
|
}
|
|
@@ -232,19 +247,42 @@ export class ParentComponent {
|
|
|
232
247
|
Sélection multiple avec tags :
|
|
233
248
|
|
|
234
249
|
```html
|
|
235
|
-
<app-chr-tag-select [
|
|
250
|
+
<app-chr-tag-select [data]="availableData" [display]="displayFunction" [placeholder]="'Sélectionner des éléments...'" [acceptText]="true"> </app-chr-tag-select>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
export class TagSelectExampleComponent {
|
|
255
|
+
availableData = [
|
|
256
|
+
{ id: 1, name: "Option 1" },
|
|
257
|
+
{ id: 2, name: "Option 2" },
|
|
258
|
+
{ id: 3, name: "Option 3" },
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
displayFunction = (item: any) => item.name;
|
|
262
|
+
}
|
|
236
263
|
```
|
|
237
264
|
|
|
238
265
|
### 🔄 ChrSpinnerComponent
|
|
239
266
|
|
|
240
|
-
Indicateur de chargement :
|
|
267
|
+
Indicateur de chargement automatique :
|
|
241
268
|
|
|
242
269
|
```html
|
|
243
|
-
<!-- Spinner simple -->
|
|
270
|
+
<!-- Spinner simple (contrôlé par LoaderService) -->
|
|
244
271
|
<app-chr-spinner></app-chr-spinner>
|
|
272
|
+
```
|
|
245
273
|
|
|
246
|
-
|
|
247
|
-
|
|
274
|
+
```typescript
|
|
275
|
+
export class SpinnerExampleComponent {
|
|
276
|
+
private loaderService = inject(LoaderService);
|
|
277
|
+
|
|
278
|
+
showSpinner() {
|
|
279
|
+
this.loaderService.show();
|
|
280
|
+
// Simulation d'une tâche
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
this.loaderService.hide();
|
|
283
|
+
}, 2000);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
248
286
|
```
|
|
249
287
|
|
|
250
288
|
## 🛠️ API
|
|
@@ -284,8 +322,80 @@ Indicateur de chargement :
|
|
|
284
322
|
```typescript
|
|
285
323
|
@Component({
|
|
286
324
|
inputs: {
|
|
287
|
-
sections:
|
|
288
|
-
controls:
|
|
325
|
+
sections: IFormSection[]; // Sections avec contrôles groupés
|
|
326
|
+
controls: IControl[]; // Contrôles directs (utiliser l'un OU l'autre)
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Interface IControl :**
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
interface IControl {
|
|
335
|
+
name: string; // Nom unique du contrôle
|
|
336
|
+
type: InputType; // Type d'input
|
|
337
|
+
label?: string; // Label affiché
|
|
338
|
+
value?: any; // Valeur par défaut
|
|
339
|
+
validations?: IControlValidation[]; // Validations
|
|
340
|
+
data?: any[]; // Données pour select/options
|
|
341
|
+
// ... autres propriétés
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Interface IFormSection :**
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
interface IFormSection {
|
|
349
|
+
title?: string; // Titre de la section
|
|
350
|
+
controls: IControl[]; // Contrôles de la section
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### ChrSearchbarComponent
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
@Component({
|
|
358
|
+
inputs: {
|
|
359
|
+
model: string | null; // Valeur actuelle
|
|
360
|
+
placeholder: string | null; // Texte d'aide
|
|
361
|
+
label: string | null; // Label du champ
|
|
362
|
+
},
|
|
363
|
+
outputs: {
|
|
364
|
+
modelChange: string; // Changement de valeur
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### ChrPaginatorComponent
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
@Component({
|
|
373
|
+
inputs: {
|
|
374
|
+
page: number; // Page actuelle
|
|
375
|
+
pageSize: number; // Nombre d'éléments par page
|
|
376
|
+
id: string; // ID unique du paginateur
|
|
377
|
+
allowSizeChange: boolean | string; // Permet de changer la taille
|
|
378
|
+
},
|
|
379
|
+
outputs: {
|
|
380
|
+
pageChange: number; // Changement de page
|
|
381
|
+
pageSizeChange: number; // Changement de taille
|
|
382
|
+
}
|
|
383
|
+
})
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### ChrTagSelectComponent
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
@Component({
|
|
390
|
+
inputs: {
|
|
391
|
+
placeholder: string; // Texte d'aide dans l'input
|
|
392
|
+
data: any[] | null; // Données pour l'autocomplete
|
|
393
|
+
display: (entry: any) => string; // Fonction d'affichage
|
|
394
|
+
filters: IInputSearchFilter[] | null; // Filtres de recherche
|
|
395
|
+
editCallback: Function; // Callback de modification
|
|
396
|
+
addCallback: Function; // Callback d'ajout
|
|
397
|
+
removeCallback: Function; // Callback de suppression
|
|
398
|
+
acceptText: boolean | null; // Accepte le texte libre
|
|
289
399
|
}
|
|
290
400
|
})
|
|
291
401
|
```
|
|
@@ -294,18 +404,101 @@ Indicateur de chargement :
|
|
|
294
404
|
|
|
295
405
|
```typescript
|
|
296
406
|
class ModalService {
|
|
297
|
-
open<T>(component: ComponentType<T>,
|
|
407
|
+
open<T>(component: ComponentType<T>, options?: ModalOptions): void;
|
|
298
408
|
close(): void;
|
|
299
409
|
}
|
|
410
|
+
|
|
411
|
+
interface ModalOptions {
|
|
412
|
+
closeOnBackdropClick?: boolean;
|
|
413
|
+
closeOnEscape?: boolean;
|
|
414
|
+
width?: number;
|
|
415
|
+
height?: number;
|
|
416
|
+
data?: any; // Données injectées via CHR_MODAL_DATA
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## 🎨 Thèmes et personnalisation
|
|
421
|
+
|
|
422
|
+
### Variables CSS disponibles
|
|
423
|
+
|
|
424
|
+
Les composants utilisent un système de variables CSS pour les couleurs. Vous pouvez les personnaliser en redéfinissant ces variables :
|
|
425
|
+
|
|
426
|
+
```css
|
|
427
|
+
:root {
|
|
428
|
+
--primary-color: #your-color;
|
|
429
|
+
--primary-contrast-color: #your-contrast-color;
|
|
430
|
+
--secondary-color: #your-secondary;
|
|
431
|
+
--secondary-contrast-color: #your-secondary-contrast;
|
|
432
|
+
--tertiary-color: #your-tertiary;
|
|
433
|
+
--tertiary-contrast-color: #your-tertiary-contrast;
|
|
434
|
+
--warn-color: #your-warn;
|
|
435
|
+
--warn-contrast-color: #your-warn-contrast;
|
|
436
|
+
--error-color: #your-error;
|
|
437
|
+
--error-contrast-color: #your-error-contrast;
|
|
438
|
+
--neutral-color: #your-neutral;
|
|
439
|
+
--text-color: #your-text;
|
|
440
|
+
--text-neutral-color: #your-text-neutral;
|
|
441
|
+
}
|
|
300
442
|
```
|
|
301
443
|
|
|
302
|
-
|
|
444
|
+
### Classes CSS disponibles
|
|
445
|
+
|
|
446
|
+
La bibliothèque fournit des classes utilitaires pour les couleurs :
|
|
447
|
+
|
|
448
|
+
```css
|
|
449
|
+
/* Arrière-plans */
|
|
450
|
+
.bg-primary, .bg-secondary, .bg-tertiary, .bg-warn, .bg-error, .bg-neutral
|
|
451
|
+
.bg-primary-contrast, .bg-secondary-contrast, .bg-tertiary-contrast, .bg-warn-contrast, .bg-error-contrast
|
|
452
|
+
|
|
453
|
+
/* Texte */
|
|
454
|
+
.text-primary, .text-secondary, .text-tertiary, .text-warn, .text-error, .text-neutral
|
|
455
|
+
.text-primary-contrast, .text-secondary-contrast, .text-tertiary-contrast, .text-warn-contrast, .text-error-contrast
|
|
456
|
+
|
|
457
|
+
/* Bordures */
|
|
458
|
+
.border-primary, .border-secondary, .border-tertiary, .border-warn, .border-error
|
|
459
|
+
.border-primary-contrast, .border-secondary-contrast, .border-tertiary-contrast, .border-warn-contrast, .border-error-contrast;
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Personnalisation avancée avec ::ng-deep
|
|
463
|
+
|
|
464
|
+
Pour modifier les styles des composants compilés, utilisez `::ng-deep` :
|
|
303
465
|
|
|
304
|
-
|
|
466
|
+
```scss
|
|
467
|
+
// Dans votre composant .scss
|
|
468
|
+
::ng-deep .chr-button {
|
|
469
|
+
border-radius: 8px;
|
|
470
|
+
font-weight: 600;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
::ng-deep .chr-form .form-field {
|
|
474
|
+
margin-bottom: 16px;
|
|
475
|
+
}
|
|
305
476
|
|
|
306
|
-
-
|
|
307
|
-
-
|
|
308
|
-
|
|
477
|
+
::ng-deep .chr-modal .modal-backdrop {
|
|
478
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Exemple de thème personnalisé
|
|
483
|
+
|
|
484
|
+
```css
|
|
485
|
+
/* Thème sombre personnalisé */
|
|
486
|
+
:root {
|
|
487
|
+
--primary-color: #3b82f6;
|
|
488
|
+
--primary-contrast-color: #ffffff;
|
|
489
|
+
--secondary-color: #6b7280;
|
|
490
|
+
--secondary-contrast-color: #ffffff;
|
|
491
|
+
--tertiary-color: #f3f4f6;
|
|
492
|
+
--tertiary-contrast-color: #1f2937;
|
|
493
|
+
--warn-color: #f59e0b;
|
|
494
|
+
--warn-contrast-color: #ffffff;
|
|
495
|
+
--error-color: #ef4444;
|
|
496
|
+
--error-contrast-color: #ffffff;
|
|
497
|
+
--neutral-color: #e5e7eb;
|
|
498
|
+
--text-color: #1f2937;
|
|
499
|
+
--text-neutral-color: #6b7280;
|
|
500
|
+
}
|
|
501
|
+
```
|
|
309
502
|
|
|
310
503
|
## 📦 Intégrations
|
|
311
504
|
|
|
@@ -344,15 +537,6 @@ import {
|
|
|
344
537
|
- Intégration Tailwind CSS native
|
|
345
538
|
- Support des signaux Angular modernes
|
|
346
539
|
|
|
347
|
-
## 🤝 Contribution
|
|
348
|
-
|
|
349
|
-
Les contributions sont les bienvenues ! Merci de respecter les conventions :
|
|
350
|
-
|
|
351
|
-
1. Utiliser les signaux Angular (`input()`, `output()`)
|
|
352
|
-
2. Préfixer les composants avec `chr-`
|
|
353
|
-
3. Documenter les APIs publiques
|
|
354
|
-
4. Tester les nouvelles fonctionnalités
|
|
355
|
-
|
|
356
540
|
## 📄 Licence
|
|
357
541
|
|
|
358
542
|
MIT © CHRV Components
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|