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.
Files changed (2) hide show
  1. package/components/Card.js +149 -68
  2. package/package.json +1 -1
@@ -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 SEULEMENT
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 SEULEMENT
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; // Espacement UNIQUEMENT entre enfants
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
- this.layout();
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.layout();
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.layout();
95
+ this.childPositions.clear();
73
96
  }
74
97
 
75
98
  /**
76
- * Organise les enfants selon le layout avec espacement constant
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.y + this.padding;
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
- // Positionner l'enfant sans tenir compte de ses marges internes
89
- child.y = currentY;
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
- child.x = this.x + (this.width - child.width) / 2;
114
+ childX = (this.width - child.width) / 2;
94
115
  } else if (this.align === 'end') {
95
- child.x = this.x + this.width - child.width - this.padding;
116
+ childX = this.width - child.width - this.padding;
96
117
  } else if (this.align === 'stretch') {
97
- child.x = this.x + this.padding;
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.x + this.padding;
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
- child.x = currentX;
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
- child.y = this.y + (this.height - child.height) / 2;
147
+ childY = (this.height - child.height) / 2;
125
148
  } else if (this.align === 'end') {
126
- child.y = this.y + this.height - child.height - this.padding;
149
+ childY = this.height - child.height - this.padding;
127
150
  } else if (this.align === 'stretch') {
128
- child.y = this.y + this.padding;
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
- const totalChildrenHeight = this.children.reduce((sum, child) => sum + child.height, 0);
366
- const totalGapHeight = this.gap * Math.max(0, this.children.length - 1);
367
- return totalChildrenHeight + totalGapHeight + (this.padding * 2);
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
- const totalChildrenWidth = this.children.reduce((sum, child) => sum + child.width, 0);
378
- const totalGapWidth = this.gap * Math.max(0, this.children.length - 1);
379
- return totalChildrenWidth + totalGapWidth + (this.padding * 2);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.5.27",
3
+ "version": "0.5.29",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/beyons/CanvasFramework.git"