canvasframework 0.5.16 → 0.5.18

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 (112) hide show
  1. package/dist/canvasframework.js +2 -0
  2. package/dist/canvasframework.js.LICENSE.txt +1 -0
  3. package/package.json +18 -17
  4. package/components/Accordion.js +0 -265
  5. package/components/AndroidDatePickerDialog.js +0 -406
  6. package/components/AppBar.js +0 -398
  7. package/components/AudioPlayer.js +0 -611
  8. package/components/Avatar.js +0 -202
  9. package/components/Banner.js +0 -342
  10. package/components/BottomNavigationBar.js +0 -433
  11. package/components/BottomSheet.js +0 -234
  12. package/components/Button.js +0 -360
  13. package/components/Camera.js +0 -644
  14. package/components/Card.js +0 -193
  15. package/components/Chart.js +0 -700
  16. package/components/Checkbox.js +0 -166
  17. package/components/Chip.js +0 -212
  18. package/components/CircularProgress.js +0 -327
  19. package/components/ContextMenu.js +0 -116
  20. package/components/DatePicker.js +0 -298
  21. package/components/Dialog.js +0 -337
  22. package/components/Divider.js +0 -125
  23. package/components/Drawer.js +0 -276
  24. package/components/FAB.js +0 -270
  25. package/components/FileUpload.js +0 -315
  26. package/components/FloatedCamera.js +0 -644
  27. package/components/IOSDatePickerWheel.js +0 -430
  28. package/components/ImageCarousel.js +0 -219
  29. package/components/ImageComponent.js +0 -223
  30. package/components/Input.js +0 -831
  31. package/components/InputDatalist.js +0 -723
  32. package/components/InputTags.js +0 -624
  33. package/components/List.js +0 -95
  34. package/components/ListItem.js +0 -269
  35. package/components/Modal.js +0 -364
  36. package/components/MorphingFAB.js +0 -428
  37. package/components/MultiSelectDialog.js +0 -206
  38. package/components/NumberInput.js +0 -271
  39. package/components/PasswordInput.js +0 -462
  40. package/components/ProgressBar.js +0 -88
  41. package/components/QRCodeReader.js +0 -539
  42. package/components/RadioButton.js +0 -151
  43. package/components/SearchInput.js +0 -315
  44. package/components/SegmentedControl.js +0 -357
  45. package/components/Select.js +0 -199
  46. package/components/SelectDialog.js +0 -255
  47. package/components/Slider.js +0 -113
  48. package/components/SliverAppBar.js +0 -139
  49. package/components/Snackbar.js +0 -243
  50. package/components/SpeedDialFAB.js +0 -397
  51. package/components/Stepper.js +0 -281
  52. package/components/SwipeableListItem.js +0 -327
  53. package/components/Switch.js +0 -147
  54. package/components/Table.js +0 -492
  55. package/components/Tabs.js +0 -423
  56. package/components/Text.js +0 -141
  57. package/components/TextField.js +0 -151
  58. package/components/TimePicker.js +0 -934
  59. package/components/Toast.js +0 -236
  60. package/components/TreeView.js +0 -420
  61. package/components/Video.js +0 -397
  62. package/components/View.js +0 -140
  63. package/components/VirtualList.js +0 -120
  64. package/core/CanvasFramework.js +0 -3034
  65. package/core/Component.js +0 -243
  66. package/core/ThemeManager.js +0 -358
  67. package/core/UIBuilder.js +0 -267
  68. package/core/WebGLCanvasAdapter.js +0 -782
  69. package/features/Column.js +0 -43
  70. package/features/Grid.js +0 -47
  71. package/features/LayoutComponent.js +0 -43
  72. package/features/OpenStreetMap.js +0 -310
  73. package/features/Positioned.js +0 -33
  74. package/features/PullToRefresh.js +0 -328
  75. package/features/Row.js +0 -40
  76. package/features/SignaturePad.js +0 -257
  77. package/features/Skeleton.js +0 -193
  78. package/features/Stack.js +0 -21
  79. package/index.js +0 -119
  80. package/manager/AccessibilityManager.js +0 -107
  81. package/manager/ErrorHandler.js +0 -59
  82. package/manager/FeatureFlags.js +0 -60
  83. package/manager/MemoryManager.js +0 -107
  84. package/manager/PerformanceMonitor.js +0 -84
  85. package/manager/SecurityManager.js +0 -54
  86. package/utils/AnimationEngine.js +0 -734
  87. package/utils/CryptoManager.js +0 -303
  88. package/utils/DataStore.js +0 -403
  89. package/utils/DevTools.js +0 -1618
  90. package/utils/DevToolsConsole.js +0 -201
  91. package/utils/EventBus.js +0 -407
  92. package/utils/FetchClient.js +0 -74
  93. package/utils/FirebaseAuth.js +0 -653
  94. package/utils/FirebaseCore.js +0 -246
  95. package/utils/FirebaseFirestore.js +0 -581
  96. package/utils/FirebaseFunctions.js +0 -97
  97. package/utils/FirebaseRealtimeDB.js +0 -498
  98. package/utils/FirebaseStorage.js +0 -612
  99. package/utils/FormValidator.js +0 -355
  100. package/utils/GeoLocationService.js +0 -62
  101. package/utils/I18n.js +0 -207
  102. package/utils/IndexedDBManager.js +0 -273
  103. package/utils/InspectionOverlay.js +0 -308
  104. package/utils/NotificationManager.js +0 -60
  105. package/utils/OfflineSyncManager.js +0 -342
  106. package/utils/PayPalPayment.js +0 -678
  107. package/utils/QueryBuilder.js +0 -478
  108. package/utils/SafeArea.js +0 -64
  109. package/utils/SecureStorage.js +0 -289
  110. package/utils/StateManager.js +0 -207
  111. package/utils/StripePayment.js +0 -552
  112. package/utils/WebSocketClient.js +0 -66
@@ -1,147 +0,0 @@
1
- import Component from '../core/Component.js';
2
- /**
3
- * Interrupteur (toggle)
4
- * @class
5
- * @extends Component
6
- * @property {boolean} checked - État activé
7
- * @property {string} platform - Plateforme
8
- * @property {number} animProgress - Progression de l'animation
9
- * @property {boolean} isAnimating - En cours d'animation
10
- * @property {Function} onChange - Callback au changement
11
- */
12
- class Switch extends Component {
13
- /**
14
- * Crée une instance de Switch
15
- * @param {CanvasFramework} framework - Framework parent
16
- * @param {Object} [options={}] - Options de configuration
17
- * @param {boolean} [options.checked=false] - État initial
18
- * @param {Function} [options.onChange] - Callback au changement
19
- */
20
- constructor(framework, options = {}) {
21
- super(framework, options);
22
- this.checked = options.checked || false;
23
- this.platform = framework.platform;
24
- this.width = 51;
25
- this.height = 31;
26
- this.onChange = options.onChange;
27
- this.animProgress = this.checked ? 1 : 0;
28
- this.isAnimating = false;
29
-
30
- // S'assurer que le Switch est cliquable
31
- this.onClick = this.handleClick.bind(this);
32
- }
33
-
34
- /**
35
- * Gère le clic sur le switch
36
- * @private
37
- */
38
- handleClick() {
39
- console.log('Switch clicked!');
40
- this.checked = !this.checked;
41
- if (this.onChange) this.onChange(this.checked);
42
- this.animate();
43
- }
44
-
45
- /**
46
- * Anime le toggle
47
- * @private
48
- */
49
- animate() {
50
- if (this.isAnimating) return;
51
-
52
- this.isAnimating = true;
53
- const target = this.checked ? 1 : 0;
54
- const step = 0.1;
55
- const interval = setInterval(() => {
56
- if (Math.abs(this.animProgress - target) < step) {
57
- this.animProgress = target;
58
- clearInterval(interval);
59
- this.isAnimating = false;
60
- } else {
61
- this.animProgress += this.animProgress < target ? step : -step;
62
- }
63
- }, 16);
64
- }
65
-
66
- /**
67
- * Dessine le switch
68
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
69
- */
70
- draw(ctx) {
71
- ctx.save();
72
-
73
- // Déplacer le contexte avec le scroll
74
- const adjustedY = this.y;
75
-
76
- if (this.platform === 'material') {
77
- // Material Design Switch
78
- const trackColor = this.checked ? 'rgba(98, 0, 238, 0.5)' : 'rgba(0, 0, 0, 0.38)';
79
- const thumbColor = this.checked ? '#6200EE' : '#FAFAFA';
80
-
81
- // Track
82
- ctx.fillStyle = trackColor;
83
- ctx.beginPath();
84
- ctx.arc(this.x + 15.5, adjustedY + 15.5, 7, Math.PI / 2, Math.PI * 1.5);
85
- ctx.arc(this.x + 35.5, adjustedY + 15.5, 7, Math.PI * 1.5, Math.PI / 2);
86
- ctx.closePath();
87
- ctx.fill();
88
-
89
- // Thumb
90
- const thumbX = this.x + 15.5 + (this.animProgress * 20);
91
- ctx.fillStyle = thumbColor;
92
- ctx.beginPath();
93
- ctx.arc(thumbX, adjustedY + 15.5, 10, 0, Math.PI * 2);
94
- ctx.fill();
95
-
96
- // Shadow for unchecked state
97
- if (!this.checked) {
98
- ctx.strokeStyle = 'rgba(0, 0, 0, 0.12)';
99
- ctx.lineWidth = 1;
100
- ctx.stroke();
101
- }
102
- } else {
103
- // Cupertino (iOS) Switch
104
- const bgColor = this.checked ? '#34C759' : '#E9E9EA';
105
-
106
- // Track
107
- ctx.fillStyle = bgColor;
108
- ctx.beginPath();
109
- ctx.arc(this.x + 15.5, adjustedY + 15.5, 15.5, Math.PI / 2, Math.PI * 1.5);
110
- ctx.arc(this.x + 35.5, adjustedY + 15.5, 15.5, Math.PI * 1.5, Math.PI / 2);
111
- ctx.closePath();
112
- ctx.fill();
113
-
114
- // Thumb with shadow
115
- const thumbX = this.x + 15.5 + (this.animProgress * 20);
116
- ctx.fillStyle = '#FFFFFF';
117
- ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
118
- ctx.shadowBlur = 4;
119
- ctx.shadowOffsetY = 2;
120
- ctx.beginPath();
121
- ctx.arc(thumbX, adjustedY + 15.5, 13.5, 0, Math.PI * 2);
122
- ctx.fill();
123
-
124
- // Reset shadow
125
- ctx.shadowColor = 'transparent';
126
- ctx.shadowBlur = 0;
127
- ctx.shadowOffsetY = 0;
128
- }
129
-
130
- ctx.restore();
131
- }
132
-
133
- /**
134
- * Vérifie si un point est dans les limites
135
- * @param {number} x - Coordonnée X
136
- * @param {number} y - Coordonnée Y
137
- * @returns {boolean} True si le point est dans le switch
138
- */
139
- isPointInside(x, y) {
140
- return x >= this.x &&
141
- x <= this.x + this.width &&
142
- y >= this.y &&
143
- y <= this.y + this.height;
144
- }
145
- }
146
-
147
- export default Switch;
@@ -1,492 +0,0 @@
1
- import Component from '../core/Component.js';
2
-
3
- /**
4
- * Tableau avec tri, pagination et sélection
5
- * @class
6
- * @extends Component
7
- * @property {Array} columns - Définition des colonnes
8
- * @property {Array} data - Données du tableau
9
- * @property {boolean} sortable - Activation du tri
10
- * @property {boolean} paginated - Activation de la pagination
11
- * @property {number} rowsPerPage - Lignes par page
12
- * @property {number} currentPage - Page actuelle
13
- * @property {string} sortColumn - Colonne de tri
14
- * @property {string} sortDirection - Direction du tri
15
- * @property {Set} selectedRows - Lignes sélectionnées
16
- * @property {boolean} selectable - Sélection activée
17
- * @property {number} headerHeight - Hauteur de l'en-tête
18
- * @property {number} rowHeight - Hauteur des lignes
19
- * @property {string} headerBg - Couleur fond en-tête
20
- * @property {string} rowBg - Couleur fond ligne
21
- * @property {string} rowAltBg - Couleur fond ligne alternée
22
- * @property {Function} onRowClick - Callback clic ligne
23
- * @property {Function} onSelectionChange - Callback sélection
24
- */
25
- class Table extends Component {
26
- /**
27
- * Crée une instance de Table
28
- * @param {CanvasFramework} framework - Framework parent
29
- * @param {Object} [options={}] - Options de configuration
30
- * @param {Array} [options.columns=[]] - Colonnes [{key, label, width, sortable}]
31
- * @param {Array} [options.data=[]] - Données
32
- * @param {boolean} [options.sortable=true] - Tri activé
33
- * @param {boolean} [options.paginated=false] - Pagination
34
- * @param {number} [options.rowsPerPage=10] - Lignes par page
35
- * @param {boolean} [options.selectable=false] - Sélection
36
- * @param {number} [options.headerHeight=48] - Hauteur en-tête
37
- * @param {number} [options.rowHeight=48] - Hauteur ligne
38
- * @param {Function} [options.onRowClick] - Callback clic
39
- * @param {Function} [options.onSelectionChange] - Callback sélection
40
- */
41
- constructor(framework, options = {}) {
42
- super(framework, options);
43
-
44
- this.columns = options.columns || [];
45
- this.data = options.data || [];
46
- this.sortable = options.sortable !== false;
47
- this.paginated = options.paginated || false;
48
- this.rowsPerPage = options.rowsPerPage || 10;
49
- this.currentPage = 0;
50
- this.sortColumn = null;
51
- this.sortDirection = 'asc';
52
- this.selectedRows = new Set();
53
- this.selectable = options.selectable || false;
54
- this.headerHeight = options.headerHeight || 48;
55
- this.rowHeight = options.rowHeight || 48;
56
-
57
- this.onRowClick = options.onRowClick || null;
58
- this.onSelectionChange = options.onSelectionChange || null;
59
-
60
- const platform = framework.platform;
61
-
62
- // Styles selon la plateforme
63
- if (platform === 'material') {
64
- this.headerBg = '#FAFAFA';
65
- this.rowBg = '#FFFFFF';
66
- this.rowAltBg = '#F5F5F5';
67
- this.borderColor = 'rgba(0, 0, 0, 0.12)';
68
- this.textColor = '#000000';
69
- this.headerTextColor = '#616161';
70
- this.selectedBg = 'rgba(98, 0, 238, 0.08)';
71
- this.hoverBg = 'rgba(0, 0, 0, 0.04)';
72
- } else {
73
- this.headerBg = '#F2F2F7';
74
- this.rowBg = '#FFFFFF';
75
- this.rowAltBg = '#F9F9F9';
76
- this.borderColor = 'rgba(60, 60, 67, 0.29)';
77
- this.textColor = '#000000';
78
- this.headerTextColor = '#6C6C70';
79
- this.selectedBg = 'rgba(0, 122, 255, 0.1)';
80
- this.hoverBg = 'rgba(0, 0, 0, 0.03)';
81
- }
82
-
83
- // Calculer les largeurs de colonnes
84
- this.calculateColumnWidths();
85
-
86
- // Calculer la hauteur totale
87
- this.updateHeight();
88
-
89
- // Hover state
90
- this.hoveredRow = -1;
91
- }
92
-
93
- /**
94
- * Calcule les largeurs de colonnes
95
- * @private
96
- */
97
- calculateColumnWidths() {
98
- const totalWidth = this.width - (this.selectable ? 48 : 0);
99
- const definedWidth = this.columns.reduce((sum, col) => sum + (col.width || 0), 0);
100
- const undefinedCols = this.columns.filter(col => !col.width).length;
101
- const autoWidth = undefinedCols > 0 ? (totalWidth - definedWidth) / undefinedCols : 0;
102
-
103
- this.columns.forEach(col => {
104
- if (!col.width) col.width = autoWidth;
105
- });
106
- }
107
-
108
- /**
109
- * Met à jour la hauteur du tableau
110
- * @private
111
- */
112
- updateHeight() {
113
- const visibleRows = this.paginated ?
114
- Math.min(this.rowsPerPage, this.data.length) :
115
- this.data.length;
116
- this.height = this.headerHeight + (visibleRows * this.rowHeight) +
117
- (this.paginated ? 48 : 0); // Pagination bar
118
- }
119
-
120
- /**
121
- * Trie les données
122
- * @param {string} columnKey - Clé de la colonne
123
- * @private
124
- */
125
- sortData(columnKey) {
126
- if (this.sortColumn === columnKey) {
127
- this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
128
- } else {
129
- this.sortColumn = columnKey;
130
- this.sortDirection = 'asc';
131
- }
132
-
133
- this.data.sort((a, b) => {
134
- const aVal = a[columnKey];
135
- const bVal = b[columnKey];
136
-
137
- if (typeof aVal === 'number' && typeof bVal === 'number') {
138
- return this.sortDirection === 'asc' ? aVal - bVal : bVal - aVal;
139
- }
140
-
141
- const aStr = String(aVal).toLowerCase();
142
- const bStr = String(bVal).toLowerCase();
143
-
144
- if (this.sortDirection === 'asc') {
145
- return aStr.localeCompare(bStr);
146
- } else {
147
- return bStr.localeCompare(aStr);
148
- }
149
- });
150
- }
151
-
152
- /**
153
- * Change de page
154
- * @param {number} page - Numéro de page
155
- * @private
156
- */
157
- changePage(page) {
158
- const maxPage = Math.ceil(this.data.length / this.rowsPerPage) - 1;
159
- this.currentPage = Math.max(0, Math.min(page, maxPage));
160
- }
161
-
162
- /**
163
- * Obtient les lignes visibles
164
- * @returns {Array} Lignes visibles
165
- * @private
166
- */
167
- getVisibleRows() {
168
- if (!this.paginated) return this.data;
169
- const start = this.currentPage * this.rowsPerPage;
170
- return this.data.slice(start, start + this.rowsPerPage);
171
- }
172
-
173
- /**
174
- * Dessine le tableau
175
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
176
- */
177
- draw(ctx) {
178
- ctx.save();
179
-
180
- // Bordure du tableau
181
- ctx.strokeStyle = this.borderColor;
182
- ctx.lineWidth = 1;
183
- ctx.strokeRect(this.x, this.y, this.width, this.height);
184
-
185
- // En-tête
186
- this.drawHeader(ctx);
187
-
188
- // Lignes
189
- const visibleRows = this.getVisibleRows();
190
- visibleRows.forEach((row, index) => {
191
- this.drawRow(ctx, row, index);
192
- });
193
-
194
- // Pagination
195
- if (this.paginated) {
196
- this.drawPagination(ctx);
197
- }
198
-
199
- ctx.restore();
200
- }
201
-
202
- /**
203
- * Dessine l'en-tête
204
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
205
- * @private
206
- */
207
- drawHeader(ctx) {
208
- // Fond
209
- ctx.fillStyle = this.headerBg;
210
- ctx.fillRect(this.x, this.y, this.width, this.headerHeight);
211
-
212
- // Bordure inférieure
213
- ctx.strokeStyle = this.borderColor;
214
- ctx.lineWidth = 1;
215
- ctx.beginPath();
216
- ctx.moveTo(this.x, this.y + this.headerHeight);
217
- ctx.lineTo(this.x + this.width, this.y + this.headerHeight);
218
- ctx.stroke();
219
-
220
- let currentX = this.x;
221
-
222
- // Checkbox pour sélectionner tout
223
- if (this.selectable) {
224
- const checkboxSize = 20;
225
- const checkboxX = currentX + 14;
226
- const checkboxY = this.y + this.headerHeight / 2 - checkboxSize / 2;
227
-
228
- const allSelected = this.data.length > 0 &&
229
- this.selectedRows.size === this.data.length;
230
-
231
- ctx.strokeStyle = this.borderColor;
232
- ctx.lineWidth = 2;
233
- ctx.strokeRect(checkboxX, checkboxY, checkboxSize, checkboxSize);
234
-
235
- if (allSelected) {
236
- ctx.fillStyle = '#6200EE';
237
- ctx.fillRect(checkboxX, checkboxY, checkboxSize, checkboxSize);
238
-
239
- ctx.strokeStyle = '#FFFFFF';
240
- ctx.lineWidth = 2;
241
- ctx.beginPath();
242
- ctx.moveTo(checkboxX + 5, checkboxY + 10);
243
- ctx.lineTo(checkboxX + 8, checkboxY + 13);
244
- ctx.lineTo(checkboxX + 15, checkboxY + 6);
245
- ctx.stroke();
246
- }
247
-
248
- currentX += 48;
249
- }
250
-
251
- // Colonnes
252
- ctx.fillStyle = this.headerTextColor;
253
- ctx.font = 'bold 14px -apple-system, BlinkMacSystemFont, Roboto, sans-serif';
254
- ctx.textAlign = 'left';
255
- ctx.textBaseline = 'middle';
256
-
257
- this.columns.forEach((col, index) => {
258
- // Texte
259
- ctx.fillText(
260
- col.label,
261
- currentX + 16,
262
- this.y + this.headerHeight / 2
263
- );
264
-
265
- // Indicateur de tri
266
- if (this.sortable && col.sortable !== false && this.sortColumn === col.key) {
267
- const arrowX = currentX + ctx.measureText(col.label).width + 24;
268
- const arrowY = this.y + this.headerHeight / 2;
269
-
270
- ctx.beginPath();
271
- if (this.sortDirection === 'asc') {
272
- ctx.moveTo(arrowX, arrowY + 3);
273
- ctx.lineTo(arrowX + 4, arrowY - 3);
274
- ctx.lineTo(arrowX + 8, arrowY + 3);
275
- } else {
276
- ctx.moveTo(arrowX, arrowY - 3);
277
- ctx.lineTo(arrowX + 4, arrowY + 3);
278
- ctx.lineTo(arrowX + 8, arrowY - 3);
279
- }
280
- ctx.stroke();
281
- }
282
-
283
- // Bordure verticale
284
- if (index < this.columns.length - 1) {
285
- ctx.strokeStyle = this.borderColor;
286
- ctx.beginPath();
287
- ctx.moveTo(currentX + col.width, this.y);
288
- ctx.lineTo(currentX + col.width, this.y + this.headerHeight);
289
- ctx.stroke();
290
- }
291
-
292
- currentX += col.width;
293
- });
294
- }
295
-
296
- /**
297
- * Dessine une ligne
298
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
299
- * @param {Object} row - Données de la ligne
300
- * @param {number} index - Index de la ligne
301
- * @private
302
- */
303
- drawRow(ctx, row, index) {
304
- const rowY = this.y + this.headerHeight + (index * this.rowHeight);
305
- const isSelected = this.selectedRows.has(row);
306
- const isHovered = this.hoveredRow === index;
307
-
308
- // Fond
309
- let bgColor = this.rowBg;
310
- if (isSelected) {
311
- bgColor = this.selectedBg;
312
- } else if (isHovered) {
313
- bgColor = this.hoverBg;
314
- } else if (index % 2 === 1) {
315
- bgColor = this.rowAltBg;
316
- }
317
-
318
- ctx.fillStyle = bgColor;
319
- ctx.fillRect(this.x, rowY, this.width, this.rowHeight);
320
-
321
- // Bordure inférieure
322
- ctx.strokeStyle = this.borderColor;
323
- ctx.lineWidth = 1;
324
- ctx.beginPath();
325
- ctx.moveTo(this.x, rowY + this.rowHeight);
326
- ctx.lineTo(this.x + this.width, rowY + this.rowHeight);
327
- ctx.stroke();
328
-
329
- let currentX = this.x;
330
-
331
- // Checkbox
332
- if (this.selectable) {
333
- const checkboxSize = 20;
334
- const checkboxX = currentX + 14;
335
- const checkboxY = rowY + this.rowHeight / 2 - checkboxSize / 2;
336
-
337
- ctx.strokeStyle = this.borderColor;
338
- ctx.lineWidth = 2;
339
- ctx.strokeRect(checkboxX, checkboxY, checkboxSize, checkboxSize);
340
-
341
- if (isSelected) {
342
- ctx.fillStyle = '#6200EE';
343
- ctx.fillRect(checkboxX, checkboxY, checkboxSize, checkboxSize);
344
-
345
- ctx.strokeStyle = '#FFFFFF';
346
- ctx.lineWidth = 2;
347
- ctx.beginPath();
348
- ctx.moveTo(checkboxX + 5, checkboxY + 10);
349
- ctx.lineTo(checkboxX + 8, checkboxY + 13);
350
- ctx.lineTo(checkboxX + 15, checkboxY + 6);
351
- ctx.stroke();
352
- }
353
-
354
- currentX += 48;
355
- }
356
-
357
- // Cellules
358
- ctx.fillStyle = this.textColor;
359
- ctx.font = '14px -apple-system, BlinkMacSystemFont, Roboto, sans-serif';
360
- ctx.textAlign = 'left';
361
- ctx.textBaseline = 'middle';
362
-
363
- this.columns.forEach((col, colIndex) => {
364
- const cellValue = String(row[col.key] || '');
365
- const maxWidth = col.width - 32;
366
-
367
- // Tronquer le texte si nécessaire
368
- let displayText = cellValue;
369
- if (ctx.measureText(displayText).width > maxWidth) {
370
- while (ctx.measureText(displayText + '...').width > maxWidth && displayText.length > 0) {
371
- displayText = displayText.slice(0, -1);
372
- }
373
- displayText += '...';
374
- }
375
-
376
- ctx.fillText(
377
- displayText,
378
- currentX + 16,
379
- rowY + this.rowHeight / 2
380
- );
381
-
382
- // Bordure verticale
383
- if (colIndex < this.columns.length - 1) {
384
- ctx.strokeStyle = this.borderColor;
385
- ctx.beginPath();
386
- ctx.moveTo(currentX + col.width, rowY);
387
- ctx.lineTo(currentX + col.width, rowY + this.rowHeight);
388
- ctx.stroke();
389
- }
390
-
391
- currentX += col.width;
392
- });
393
- }
394
-
395
- /**
396
- * Dessine la pagination
397
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
398
- * @private
399
- */
400
- drawPagination(ctx) {
401
- const paginationY = this.y + this.height - 48;
402
- const totalPages = Math.ceil(this.data.length / this.rowsPerPage);
403
-
404
- // Fond
405
- ctx.fillStyle = this.headerBg;
406
- ctx.fillRect(this.x, paginationY, this.width, 48);
407
-
408
- // Bordure supérieure
409
- ctx.strokeStyle = this.borderColor;
410
- ctx.lineWidth = 1;
411
- ctx.beginPath();
412
- ctx.moveTo(this.x, paginationY);
413
- ctx.lineTo(this.x + this.width, paginationY);
414
- ctx.stroke();
415
-
416
- // Texte
417
- ctx.fillStyle = this.textColor;
418
- ctx.font = '14px -apple-system, BlinkMacSystemFont, Roboto, sans-serif';
419
- ctx.textAlign = 'center';
420
- ctx.textBaseline = 'middle';
421
-
422
- const start = this.currentPage * this.rowsPerPage + 1;
423
- const end = Math.min((this.currentPage + 1) * this.rowsPerPage, this.data.length);
424
- const text = `${start}-${end} of ${this.data.length}`;
425
-
426
- ctx.fillText(text, this.x + this.width / 2, paginationY + 24);
427
-
428
- // Boutons prev/next (simples flèches)
429
- const arrowSize = 20;
430
- const prevX = this.x + this.width - 100;
431
- const nextX = this.x + this.width - 50;
432
- const arrowY = paginationY + 24;
433
-
434
- // Prev
435
- ctx.strokeStyle = this.currentPage > 0 ? this.textColor : this.borderColor;
436
- ctx.lineWidth = 2;
437
- ctx.beginPath();
438
- ctx.moveTo(prevX + 8, arrowY - 6);
439
- ctx.lineTo(prevX, arrowY);
440
- ctx.lineTo(prevX + 8, arrowY + 6);
441
- ctx.stroke();
442
-
443
- // Next
444
- ctx.strokeStyle = this.currentPage < totalPages - 1 ? this.textColor : this.borderColor;
445
- ctx.beginPath();
446
- ctx.moveTo(nextX - 8, arrowY - 6);
447
- ctx.lineTo(nextX, arrowY);
448
- ctx.lineTo(nextX - 8, arrowY + 6);
449
- ctx.stroke();
450
- }
451
-
452
- /**
453
- * Vérifie si un point est dans les limites
454
- * @param {number} x - Coordonnée X
455
- * @param {number} y - Coordonnée Y
456
- * @returns {boolean} True si le point est dans le tableau
457
- */
458
- isPointInside(x, y) {
459
- return x >= this.x &&
460
- x <= this.x + this.width &&
461
- y >= this.y &&
462
- y <= this.y + this.height;
463
- }
464
-
465
- /**
466
- * Gère le clic
467
- * @param {number} x - Coordonnée X
468
- * @param {number} y - Coordonnée Y
469
- */
470
- onClick() {
471
- // Implémenté dans checkComponentsAtPosition
472
- }
473
-
474
- /**
475
- * Gère le mouvement
476
- * @param {number} x - Coordonnée X
477
- * @param {number} y - Coordonnée Y
478
- */
479
- onMove(x, y) {
480
- const relY = y - this.y - this.headerHeight;
481
- const rowIndex = Math.floor(relY / this.rowHeight);
482
-
483
- const visibleRows = this.getVisibleRows();
484
- if (rowIndex >= 0 && rowIndex < visibleRows.length) {
485
- this.hoveredRow = rowIndex;
486
- } else {
487
- this.hoveredRow = -1;
488
- }
489
- }
490
- }
491
-
492
- export default Table;