canvasframework 0.5.27 → 0.5.29
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/components/Card.js +149 -68
- package/package.json +1 -1
package/components/Card.js
CHANGED
|
@@ -6,12 +6,13 @@ import Component from '../core/Component.js';
|
|
|
6
6
|
* @extends Component
|
|
7
7
|
* @property {Component[]} children - Enfants
|
|
8
8
|
* @property {number} padding - Padding interne
|
|
9
|
-
* @property {number} gap - Espacement constant entre enfants
|
|
9
|
+
* @property {number} gap - Espacement constant entre enfants
|
|
10
10
|
* @property {string} direction - Direction ('column' ou 'row')
|
|
11
11
|
* @property {string} align - Alignement ('start', 'center', 'end', 'stretch')
|
|
12
12
|
* @property {string} bgColor - Couleur de fond
|
|
13
13
|
* @property {number} borderRadius - Rayon des coins
|
|
14
14
|
* @property {number} elevation - Niveau d'élévation (ombres)
|
|
15
|
+
* @property {boolean} autoLayout - Active le layout automatique
|
|
15
16
|
*/
|
|
16
17
|
class Card extends Component {
|
|
17
18
|
/**
|
|
@@ -19,33 +20,54 @@ class Card extends Component {
|
|
|
19
20
|
* @param {CanvasFramework} framework - Framework parent
|
|
20
21
|
* @param {Object} [options={}] - Options de configuration
|
|
21
22
|
* @param {number} [options.padding=0] - Padding interne
|
|
22
|
-
* @param {number} [options.gap=0] - Espacement constant entre enfants
|
|
23
|
+
* @param {number} [options.gap=0] - Espacement constant entre enfants
|
|
23
24
|
* @param {string} [options.direction='column'] - Direction
|
|
24
25
|
* @param {string} [options.align='start'] - Alignement
|
|
25
26
|
* @param {string} [options.bgColor='transparent'] - Couleur de fond
|
|
26
27
|
* @param {number} [options.borderRadius=0] - Rayon des coins
|
|
27
28
|
* @param {number} [options.elevation=0] - Niveau d'élévation (0-5)
|
|
29
|
+
* @param {boolean} [options.autoLayout=true] - Active le layout automatique
|
|
28
30
|
*/
|
|
29
31
|
constructor(framework, options = {}) {
|
|
30
32
|
super(framework, options);
|
|
31
33
|
this.children = [];
|
|
32
34
|
this.padding = options.padding || 0;
|
|
33
|
-
this.gap = options.gap || 0;
|
|
35
|
+
this.gap = options.gap || 0;
|
|
34
36
|
this.direction = options.direction || 'column';
|
|
35
37
|
this.align = options.align || 'start';
|
|
36
38
|
this.bgColor = options.bgColor || 'transparent';
|
|
37
39
|
this.borderRadius = options.borderRadius || 0;
|
|
38
40
|
this.elevation = options.elevation || 0;
|
|
41
|
+
this.autoLayout = options.autoLayout !== undefined ? options.autoLayout : true;
|
|
42
|
+
|
|
43
|
+
// Stocker les positions relatives des enfants
|
|
44
|
+
this.childPositions = new Map();
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
|
-
* Ajoute un enfant
|
|
48
|
+
* Ajoute un enfant (position relative convertie en absolue)
|
|
43
49
|
* @param {Component} child - Composant enfant
|
|
44
50
|
* @returns {Component} L'enfant ajouté
|
|
45
51
|
*/
|
|
46
52
|
add(child) {
|
|
47
53
|
this.children.push(child);
|
|
48
|
-
|
|
54
|
+
|
|
55
|
+
// CONVERTIR les positions relatives en positions absolues
|
|
56
|
+
// Les x, y passés sont relatifs à la Card
|
|
57
|
+
child.x = this.x + child.x;
|
|
58
|
+
child.y = this.y + child.y;
|
|
59
|
+
|
|
60
|
+
// Stocker la position relative originale
|
|
61
|
+
this.childPositions.set(child, {
|
|
62
|
+
x: child.x - this.x,
|
|
63
|
+
y: child.y - this.y
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Si autoLayout est activé, organiser automatiquement
|
|
67
|
+
if (this.autoLayout) {
|
|
68
|
+
this.layout();
|
|
69
|
+
}
|
|
70
|
+
|
|
49
71
|
return child;
|
|
50
72
|
}
|
|
51
73
|
|
|
@@ -58,7 +80,8 @@ class Card extends Component {
|
|
|
58
80
|
const index = this.children.indexOf(child);
|
|
59
81
|
if (index > -1) {
|
|
60
82
|
this.children.splice(index, 1);
|
|
61
|
-
this.
|
|
83
|
+
this.childPositions.delete(child);
|
|
84
|
+
if (this.autoLayout) this.layout();
|
|
62
85
|
return true;
|
|
63
86
|
}
|
|
64
87
|
return false;
|
|
@@ -69,40 +92,41 @@ class Card extends Component {
|
|
|
69
92
|
*/
|
|
70
93
|
clear() {
|
|
71
94
|
this.children = [];
|
|
72
|
-
this.
|
|
95
|
+
this.childPositions.clear();
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
/**
|
|
76
|
-
* Organise les enfants selon le layout
|
|
99
|
+
* Organise les enfants selon le layout
|
|
77
100
|
* @private
|
|
78
101
|
*/
|
|
79
102
|
layout() {
|
|
80
|
-
if (this.children.length === 0) return;
|
|
103
|
+
if (this.children.length === 0 || !this.autoLayout) return;
|
|
81
104
|
|
|
82
105
|
if (this.direction === 'column') {
|
|
83
|
-
let currentY = this.
|
|
106
|
+
let currentY = this.padding;
|
|
84
107
|
|
|
85
108
|
for (let i = 0; i < this.children.length; i++) {
|
|
86
109
|
const child = this.children[i];
|
|
87
110
|
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// Gérer l'alignement horizontal
|
|
111
|
+
// Calculer la position X selon l'alignement
|
|
112
|
+
let childX = this.padding;
|
|
92
113
|
if (this.align === 'center') {
|
|
93
|
-
|
|
114
|
+
childX = (this.width - child.width) / 2;
|
|
94
115
|
} else if (this.align === 'end') {
|
|
95
|
-
|
|
116
|
+
childX = this.width - child.width - this.padding;
|
|
96
117
|
} else if (this.align === 'stretch') {
|
|
97
|
-
|
|
118
|
+
childX = this.padding;
|
|
98
119
|
child.width = this.width - (this.padding * 2);
|
|
99
|
-
} else {
|
|
100
|
-
// Alignement 'start' par défaut
|
|
101
|
-
child.x = this.x + this.padding;
|
|
102
120
|
}
|
|
103
121
|
|
|
122
|
+
// Positionner l'enfant RELATIVEMENT à la Card
|
|
123
|
+
child.x = this.x + childX;
|
|
124
|
+
child.y = this.y + currentY;
|
|
125
|
+
|
|
126
|
+
// Stocker la position relative
|
|
127
|
+
this.childPositions.set(child, { x: childX, y: currentY });
|
|
128
|
+
|
|
104
129
|
// Mettre à jour la position Y pour l'enfant suivant
|
|
105
|
-
// UNIQUEMENT avec le gap spécifié, rien d'autre
|
|
106
130
|
currentY += child.height;
|
|
107
131
|
|
|
108
132
|
// Ajouter le gap seulement si ce n'est pas le dernier enfant
|
|
@@ -112,25 +136,29 @@ class Card extends Component {
|
|
|
112
136
|
}
|
|
113
137
|
} else {
|
|
114
138
|
// Direction 'row'
|
|
115
|
-
let currentX = this.
|
|
139
|
+
let currentX = this.padding;
|
|
116
140
|
|
|
117
141
|
for (let i = 0; i < this.children.length; i++) {
|
|
118
142
|
const child = this.children[i];
|
|
119
143
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// Gérer l'alignement vertical
|
|
144
|
+
// Calculer la position Y selon l'alignement
|
|
145
|
+
let childY = this.padding;
|
|
123
146
|
if (this.align === 'center') {
|
|
124
|
-
|
|
147
|
+
childY = (this.height - child.height) / 2;
|
|
125
148
|
} else if (this.align === 'end') {
|
|
126
|
-
|
|
149
|
+
childY = this.height - child.height - this.padding;
|
|
127
150
|
} else if (this.align === 'stretch') {
|
|
128
|
-
|
|
151
|
+
childY = this.padding;
|
|
129
152
|
child.height = this.height - (this.padding * 2);
|
|
130
|
-
} else {
|
|
131
|
-
child.y = this.y + this.padding;
|
|
132
153
|
}
|
|
133
154
|
|
|
155
|
+
// Positionner l'enfant RELATIVEMENT à la Card
|
|
156
|
+
child.x = this.x + currentX;
|
|
157
|
+
child.y = this.y + childY;
|
|
158
|
+
|
|
159
|
+
// Stocker la position relative
|
|
160
|
+
this.childPositions.set(child, { x: currentX, y: childY });
|
|
161
|
+
|
|
134
162
|
// Mettre à jour la position X pour l'enfant suivant
|
|
135
163
|
currentX += child.width;
|
|
136
164
|
|
|
@@ -142,6 +170,54 @@ class Card extends Component {
|
|
|
142
170
|
}
|
|
143
171
|
}
|
|
144
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Met à jour la position de la carte et ajuste les enfants
|
|
175
|
+
* @param {number} x - Nouvelle position X
|
|
176
|
+
* @param {number} y - Nouvelle position Y
|
|
177
|
+
*/
|
|
178
|
+
setPosition(x, y) {
|
|
179
|
+
const deltaX = x - this.x;
|
|
180
|
+
const deltaY = y - this.y;
|
|
181
|
+
|
|
182
|
+
super.setPosition(x, y);
|
|
183
|
+
|
|
184
|
+
// Déplacer tous les enfants avec la carte
|
|
185
|
+
for (let child of this.children) {
|
|
186
|
+
child.x += deltaX;
|
|
187
|
+
child.y += deltaY;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Définit la position d'un enfant dans le système de coordonnées de la Card
|
|
193
|
+
* @param {Component} child - L'enfant à positionner
|
|
194
|
+
* @param {number} relativeX - Position X relative à la Card
|
|
195
|
+
* @param {number} relativeY - Position Y relative à la Card
|
|
196
|
+
*/
|
|
197
|
+
setChildPosition(child, relativeX, relativeY) {
|
|
198
|
+
if (this.children.includes(child)) {
|
|
199
|
+
child.x = this.x + relativeX;
|
|
200
|
+
child.y = this.y + relativeY;
|
|
201
|
+
this.childPositions.set(child, { x: relativeX, y: relativeY });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Active/désactive le layout automatique
|
|
207
|
+
* @param {boolean} enabled - True pour activer le layout automatique
|
|
208
|
+
*/
|
|
209
|
+
setAutoLayout(enabled) {
|
|
210
|
+
this.autoLayout = enabled;
|
|
211
|
+
if (enabled) this.layout();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Force un recalcul du layout
|
|
216
|
+
*/
|
|
217
|
+
updateLayout() {
|
|
218
|
+
this.layout();
|
|
219
|
+
}
|
|
220
|
+
|
|
145
221
|
/**
|
|
146
222
|
* Génère les paramètres d'ombre selon le niveau d'élévation
|
|
147
223
|
* @param {number} elevation - Niveau d'élévation (0-5)
|
|
@@ -287,41 +363,13 @@ class Card extends Component {
|
|
|
287
363
|
this.setElevation(this.elevation - 1);
|
|
288
364
|
}
|
|
289
365
|
|
|
290
|
-
/**
|
|
291
|
-
* Met à jour la position de la carte (surcharge pour recalculer le layout)
|
|
292
|
-
* @param {number} x - Nouvelle position X
|
|
293
|
-
* @param {number} y - Nouvelle position Y
|
|
294
|
-
*/
|
|
295
|
-
setPosition(x, y) {
|
|
296
|
-
const deltaX = x - this.x;
|
|
297
|
-
const deltaY = y - this.y;
|
|
298
|
-
|
|
299
|
-
super.setPosition(x, y);
|
|
300
|
-
|
|
301
|
-
// Déplacer tous les enfants avec la carte
|
|
302
|
-
for (let child of this.children) {
|
|
303
|
-
child.x += deltaX;
|
|
304
|
-
child.y += deltaY;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Met à jour les dimensions (surcharge pour recalculer le layout)
|
|
310
|
-
* @param {number} width - Nouvelle largeur
|
|
311
|
-
* @param {number} height - Nouvelle hauteur
|
|
312
|
-
*/
|
|
313
|
-
setSize(width, height) {
|
|
314
|
-
super.setSize(width, height);
|
|
315
|
-
this.layout();
|
|
316
|
-
}
|
|
317
|
-
|
|
318
366
|
/**
|
|
319
367
|
* Définit l'espacement entre enfants
|
|
320
368
|
* @param {number} gap - Nouvel espacement
|
|
321
369
|
*/
|
|
322
370
|
setGap(gap) {
|
|
323
371
|
this.gap = Math.max(0, gap);
|
|
324
|
-
this.layout();
|
|
372
|
+
if (this.autoLayout) this.layout();
|
|
325
373
|
}
|
|
326
374
|
|
|
327
375
|
/**
|
|
@@ -330,7 +378,7 @@ class Card extends Component {
|
|
|
330
378
|
*/
|
|
331
379
|
setPadding(padding) {
|
|
332
380
|
this.padding = Math.max(0, padding);
|
|
333
|
-
this.layout();
|
|
381
|
+
if (this.autoLayout) this.layout();
|
|
334
382
|
}
|
|
335
383
|
|
|
336
384
|
/**
|
|
@@ -340,7 +388,7 @@ class Card extends Component {
|
|
|
340
388
|
setDirection(direction) {
|
|
341
389
|
if (direction === 'column' || direction === 'row') {
|
|
342
390
|
this.direction = direction;
|
|
343
|
-
this.layout();
|
|
391
|
+
if (this.autoLayout) this.layout();
|
|
344
392
|
}
|
|
345
393
|
}
|
|
346
394
|
|
|
@@ -351,7 +399,7 @@ class Card extends Component {
|
|
|
351
399
|
setAlign(align) {
|
|
352
400
|
if (['start', 'center', 'end', 'stretch'].includes(align)) {
|
|
353
401
|
this.align = align;
|
|
354
|
-
this.layout();
|
|
402
|
+
if (this.autoLayout) this.layout();
|
|
355
403
|
}
|
|
356
404
|
}
|
|
357
405
|
|
|
@@ -362,9 +410,12 @@ class Card extends Component {
|
|
|
362
410
|
getTotalHeight() {
|
|
363
411
|
if (this.children.length === 0) return 0;
|
|
364
412
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
413
|
+
if (this.direction === 'column') {
|
|
414
|
+
const totalChildrenHeight = this.children.reduce((sum, child) => sum + child.height, 0);
|
|
415
|
+
const totalGapHeight = this.gap * Math.max(0, this.children.length - 1);
|
|
416
|
+
return totalChildrenHeight + totalGapHeight + (this.padding * 2);
|
|
417
|
+
}
|
|
418
|
+
return this.height;
|
|
368
419
|
}
|
|
369
420
|
|
|
370
421
|
/**
|
|
@@ -374,9 +425,12 @@ class Card extends Component {
|
|
|
374
425
|
getTotalWidth() {
|
|
375
426
|
if (this.children.length === 0) return 0;
|
|
376
427
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
428
|
+
if (this.direction === 'row') {
|
|
429
|
+
const totalChildrenWidth = this.children.reduce((sum, child) => sum + child.width, 0);
|
|
430
|
+
const totalGapWidth = this.gap * Math.max(0, this.children.length - 1);
|
|
431
|
+
return totalChildrenWidth + totalGapWidth + (this.padding * 2);
|
|
432
|
+
}
|
|
433
|
+
return this.width;
|
|
380
434
|
}
|
|
381
435
|
|
|
382
436
|
/**
|
|
@@ -396,6 +450,33 @@ class Card extends Component {
|
|
|
396
450
|
this.width = this.getTotalWidth();
|
|
397
451
|
}
|
|
398
452
|
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Ajuste automatiquement les dimensions de la carte pour contenir tous les enfants
|
|
456
|
+
*/
|
|
457
|
+
fitSize() {
|
|
458
|
+
this.fitWidth();
|
|
459
|
+
this.fitHeight();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Met à jour les dimensions et relayout si autoLayout est activé
|
|
464
|
+
* @param {number} width - Nouvelle largeur
|
|
465
|
+
* @param {number} height - Nouvelle hauteur
|
|
466
|
+
*/
|
|
467
|
+
setSize(width, height) {
|
|
468
|
+
super.setSize(width, height);
|
|
469
|
+
if (this.autoLayout) this.layout();
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Obtient la position relative d'un enfant
|
|
474
|
+
* @param {Component} child - L'enfant
|
|
475
|
+
* @returns {Object|null} Position relative {x, y} ou null si non trouvé
|
|
476
|
+
*/
|
|
477
|
+
getChildPosition(child) {
|
|
478
|
+
return this.childPositions.get(child) || null;
|
|
479
|
+
}
|
|
399
480
|
}
|
|
400
481
|
|
|
401
482
|
export default Card;
|