canvasframework 0.3.6

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 (85) hide show
  1. package/README.md +554 -0
  2. package/components/Accordion.js +252 -0
  3. package/components/AndroidDatePickerDialog.js +398 -0
  4. package/components/AppBar.js +225 -0
  5. package/components/Avatar.js +202 -0
  6. package/components/BottomNavigationBar.js +205 -0
  7. package/components/BottomSheet.js +374 -0
  8. package/components/Button.js +225 -0
  9. package/components/Card.js +193 -0
  10. package/components/Checkbox.js +180 -0
  11. package/components/Chip.js +212 -0
  12. package/components/CircularProgress.js +143 -0
  13. package/components/ContextMenu.js +116 -0
  14. package/components/DatePicker.js +257 -0
  15. package/components/Dialog.js +367 -0
  16. package/components/Divider.js +125 -0
  17. package/components/Drawer.js +261 -0
  18. package/components/FAB.js +270 -0
  19. package/components/FileUpload.js +315 -0
  20. package/components/IOSDatePickerWheel.js +268 -0
  21. package/components/ImageCarousel.js +193 -0
  22. package/components/ImageComponent.js +223 -0
  23. package/components/Input.js +309 -0
  24. package/components/List.js +94 -0
  25. package/components/ListItem.js +223 -0
  26. package/components/Modal.js +364 -0
  27. package/components/MultiSelectDialog.js +206 -0
  28. package/components/NumberInput.js +271 -0
  29. package/components/ProgressBar.js +88 -0
  30. package/components/RadioButton.js +142 -0
  31. package/components/SearchInput.js +315 -0
  32. package/components/SegmentedControl.js +202 -0
  33. package/components/Select.js +199 -0
  34. package/components/SelectDialog.js +255 -0
  35. package/components/Slider.js +113 -0
  36. package/components/Snackbar.js +243 -0
  37. package/components/Stepper.js +281 -0
  38. package/components/SwipeableListItem.js +179 -0
  39. package/components/Switch.js +147 -0
  40. package/components/Table.js +492 -0
  41. package/components/Tabs.js +125 -0
  42. package/components/Text.js +141 -0
  43. package/components/TextField.js +331 -0
  44. package/components/Toast.js +236 -0
  45. package/components/TreeView.js +420 -0
  46. package/components/Video.js +397 -0
  47. package/components/View.js +140 -0
  48. package/components/VirtualList.js +120 -0
  49. package/core/CanvasFramework.js +1271 -0
  50. package/core/CanvasWork.js +32 -0
  51. package/core/Component.js +153 -0
  52. package/core/LogicWorker.js +25 -0
  53. package/core/WebGLCanvasAdapter.js +1369 -0
  54. package/features/Column.js +43 -0
  55. package/features/Grid.js +47 -0
  56. package/features/LayoutComponent.js +43 -0
  57. package/features/OpenStreetMap.js +310 -0
  58. package/features/Positioned.js +33 -0
  59. package/features/PullToRefresh.js +328 -0
  60. package/features/Row.js +40 -0
  61. package/features/SignaturePad.js +257 -0
  62. package/features/Skeleton.js +84 -0
  63. package/features/Stack.js +21 -0
  64. package/index.js +101 -0
  65. package/manager/AccessibilityManager.js +107 -0
  66. package/manager/ErrorHandler.js +59 -0
  67. package/manager/FeatureFlags.js +60 -0
  68. package/manager/MemoryManager.js +107 -0
  69. package/manager/PerformanceMonitor.js +84 -0
  70. package/manager/SecurityManager.js +54 -0
  71. package/package.json +28 -0
  72. package/utils/AnimationEngine.js +428 -0
  73. package/utils/DataStore.js +403 -0
  74. package/utils/EventBus.js +407 -0
  75. package/utils/FetchClient.js +74 -0
  76. package/utils/FormValidator.js +355 -0
  77. package/utils/GeoLocationService.js +62 -0
  78. package/utils/I18n.js +207 -0
  79. package/utils/IndexedDBManager.js +273 -0
  80. package/utils/OfflineSyncManager.js +342 -0
  81. package/utils/QueryBuilder.js +478 -0
  82. package/utils/SafeArea.js +64 -0
  83. package/utils/SecureStorage.js +289 -0
  84. package/utils/StateManager.js +207 -0
  85. package/utils/WebSocketClient.js +66 -0
package/README.md ADDED
@@ -0,0 +1,554 @@
1
+ <img width="1536" height="1024" alt="image" src="https://github.com/user-attachments/assets/feae14e9-8d68-41f9-9e33-e444f1a6f360" />
2
+
3
+
4
+ # Canvas UI Engine (working name)
5
+
6
+ > **Canvas-based UI Engine for Mobile & Embedded Apps**
7
+ > A high-performance UI engine rendered with Canvas/WebGL, running inside a WebView runtime (Capacitor / Cordova), without DOM, HTML or CSS.
8
+
9
+ ---
10
+
11
+ ## 🚀 Overview
12
+
13
+ **Canvas UI Engine** is a **low-level UI engine** that renders the entire user interface using **Canvas 2D or WebGL**, instead of the DOM.
14
+
15
+ Although it runs inside a WebView, it **does not rely on HTML, CSS, or the browser layout engine**.
16
+ The WebView is used **only as a JavaScript runtime**, not as a UI system.
17
+
18
+ > Think **Flutter’s rendering model**, but implemented in **JavaScript**, running inside a WebView.
19
+
20
+ ---
21
+
22
+ ## ❌ What this engine is NOT
23
+
24
+ - ❌ Not a web framework
25
+ - ❌ Not DOM-based
26
+ - ❌ Not Ionic / React / Vue
27
+ - ❌ Not HTML/CSS driven
28
+ - ❌ Not designed for SEO or websites
29
+
30
+ ---
31
+
32
+ ## ✅ What this engine IS
33
+
34
+ - ✅ A **Canvas-first UI engine**
35
+ - ✅ A **custom rendering pipeline**
36
+ - ✅ A **custom layout system**
37
+ - ✅ A **custom input & gesture system**
38
+ - ✅ A **deterministic, app-like UI**
39
+ - ✅ Designed for **mobile & embedded apps**
40
+
41
+ ---
42
+
43
+ ## 🧠 Architecture
44
+
45
+ <img width="1536" height="1024" alt="image" src="https://github.com/user-attachments/assets/da04de5b-0223-4241-86bc-ccb6b7ac0eaa" />
46
+
47
+
48
+ > **The WebView is only a runtime shell.**
49
+ > **The UI is fully controlled by the engine (no DOM, no HTML layout).**
50
+
51
+
52
+ ### Key point
53
+
54
+ > **The browser does not manage UI.
55
+ > The engine does.**
56
+
57
+ ---
58
+
59
+ ## 🎨 Rendering
60
+
61
+ - Canvas 2D (CPU)
62
+ - Optional WebGL backend (GPU accelerated)
63
+ - Device Pixel Ratio aware
64
+ - Dirty-region rendering
65
+ - Scene graph based
66
+
67
+ Rendering performance depends **entirely on the engine**, not on the browser DOM.
68
+
69
+ ---
70
+
71
+ ## 🧩 UI Model
72
+
73
+ - Every component is **drawn**, not mounted
74
+ - No HTML nodes
75
+ - No CSS
76
+ - No reflow
77
+ - No repaint cost from the browser
78
+
79
+ Example components:
80
+ - Button
81
+ - Text
82
+ - Input
83
+ - Slider
84
+ - Switch
85
+ - List / Card
86
+ - Modal / Dialog / BottomSheet
87
+ - Navigation & routing system
88
+
89
+ ---
90
+
91
+ ## 🧭 Navigation
92
+
93
+ - Internal routing system
94
+ - Stack-based navigation
95
+ - Animated transitions (slide / fade)
96
+ - Independent from browser routing logic
97
+
98
+ ---
99
+
100
+ ## 🧵 Multithreading
101
+
102
+ - **UI Worker** → layout & scroll inertia
103
+ - **Logic Worker** → business logic
104
+ - Main thread → rendering only
105
+
106
+ This allows smoother UI and better separation of concerns.
107
+
108
+ ---
109
+
110
+ ## 🔌 Native capabilities
111
+
112
+ Native features are accessed via the **host runtime** (Capacitor / Cordova):
113
+
114
+ - Camera
115
+ - Filesystem
116
+ - Secure storage
117
+ - Geolocation
118
+ - WebSocket
119
+ - Network
120
+
121
+ ⚠️ Plugins that **require DOM access are not supported**.
122
+
123
+ ---
124
+
125
+ ## 📦 Data & Networking
126
+
127
+ The engine provides its own service layer:
128
+ - Cached fetch service
129
+ - WebSocket manager
130
+ - Geolocation abstraction
131
+ - Offline-first data handling
132
+
133
+ All APIs are **engine-controlled**, not browser-controlled.
134
+
135
+ ---
136
+
137
+ ## 🆚 Comparison
138
+
139
+ ### vs React Native
140
+
141
+ | React Native | Canvas UI Engine |
142
+ |-------------|-----------------|
143
+ | Native views | Custom rendering |
144
+ | Bridge overhead | Direct rendering |
145
+ | Platform UI | Engine UI |
146
+ | DOM-like model | Scene graph |
147
+
148
+ ---
149
+
150
+ ### vs Flutter
151
+
152
+ | Flutter | Canvas UI Engine |
153
+ |--------|------------------|
154
+ | Native engine | WebView runtime |
155
+ | Skia | Canvas / WebGL |
156
+ | Dart | JavaScript |
157
+ | Compiled | Interpreted |
158
+ | UI engine | UI engine |
159
+
160
+ 👉 **Same architecture philosophy**, different runtime constraints.
161
+
162
+ ---
163
+
164
+ ## ⚠️ Known limitations
165
+
166
+ - No DOM access
167
+ - No HTML rendering
168
+ - No SEO
169
+ - No accessibility (yet)
170
+ - Text shaping is basic (LTR focused)
171
+
172
+ These are **intentional design decisions**.
173
+
174
+ ---
175
+
176
+ ## 🎯 Target use cases
177
+
178
+ - Mobile applications
179
+ - Embedded systems
180
+ - Kiosk interfaces
181
+ - Medical / industrial apps
182
+ - Offline-first apps
183
+ - UI where **control > compatibility**
184
+
185
+ ---
186
+
187
+ ## 🛣️ Roadmap (simplified)
188
+
189
+ ### Phase 1 – Core engine (current)
190
+ - Canvas/WebGL rendering
191
+ - Input & layout
192
+ - Core components
193
+
194
+ ### Phase 2 – Performance & UX
195
+ - Gesture system
196
+ - Animation engine
197
+ - Advanced scrolling
198
+ - Asset caching
199
+
200
+ ### Phase 3 – Ecosystem
201
+ - Plugin bridge
202
+ - Devtools
203
+ - Theming system
204
+
205
+ ---
206
+
207
+ ## 🧪 Philosophy
208
+
209
+ > **The WebView is just a runtime.
210
+ > The UI is owned by the engine.**
211
+
212
+ If the engine is fast → the app is fast.
213
+ If the engine is slow → nothing can save it.
214
+
215
+ ---
216
+
217
+ ## Exemples
218
+ # Exemple – Accordion
219
+
220
+ Afficher des sections d’informations extensibles (FAQ, paramètres, détails).
221
+ ```
222
+ import { Accordion } from './framework/index.js';
223
+
224
+ const accordion = new Accordion(app, {
225
+ x: 16,
226
+ y: 80,
227
+ width: app.width - 32,
228
+ title: 'Informations du compte',
229
+ icon: 'ℹ️',
230
+ content: 'Votre compte vous permet de gérer vos préférences, votre sécurité et vos informations personnelles.',
231
+ expanded: false,
232
+ onToggle: (expanded) => {
233
+ console.log('Accordion ouvert ?', expanded);
234
+ }
235
+ });
236
+
237
+ app.add(accordion);
238
+ ```
239
+
240
+ # Button (Material / Cupertino auto)
241
+
242
+ Action principale (submit, navigation, confirmation).
243
+ ```
244
+ import { Button } from './framework/index.js';
245
+
246
+ const button = new Button(app, {
247
+ x: 16,
248
+ y: 300,
249
+ width: app.width - 32,
250
+ height: 48,
251
+ text: 'Continuer',
252
+ elevation: 4
253
+ });
254
+
255
+ button.onClick = () => {
256
+ console.log('Bouton cliqué');
257
+ };
258
+
259
+ app.add(button);
260
+ ```
261
+
262
+ # Exemple – BottomNavigationBar
263
+
264
+ Navigation principale d’application mobile.
265
+ ```
266
+ import { BottomNavigationBar } from './framework/index.js';
267
+
268
+ const bottomNav = new BottomNavigationBar(app, {
269
+ items: [
270
+ { icon: 'home', label: 'Accueil' },
271
+ { icon: 'search', label: 'Recherche' },
272
+ { icon: 'favorite', label: 'Favoris' },
273
+ { icon: 'person', label: 'Profil' }
274
+ ],
275
+ onChange: (index, item) => {
276
+ console.log('Onglet sélectionné:', index, item.label);
277
+ }
278
+ });
279
+
280
+ app.add(bottomNav);
281
+ ```
282
+
283
+ # Exemple – Dialog (alert / confirmation)
284
+
285
+ Alerte, confirmation, choix utilisateur.
286
+ ```
287
+ import { Dialog, Button } from './framework/index.js';
288
+
289
+ const showDialogBtn = new Button(app, {
290
+ x: 16,
291
+ y: 380,
292
+ width: app.width - 32,
293
+ height: 48,
294
+ text: 'Supprimer le compte'
295
+ });
296
+
297
+ showDialogBtn.onClick = () => {
298
+ const dialog = new Dialog(app, {
299
+ title: 'Confirmation',
300
+ message: 'Êtes-vous sûr de vouloir supprimer votre compte ? Cette action est irréversible.',
301
+ buttons: ['Annuler', 'Supprimer'],
302
+ onButtonClick: (index, label) => {
303
+ console.log('Bouton dialog:', label);
304
+ }
305
+ });
306
+
307
+ app.add(dialog);
308
+ dialog.show();
309
+ };
310
+
311
+ app.add(showDialogBtn);
312
+ ```
313
+
314
+
315
+ # Exemple – Combinaison réelle (mini écran)
316
+
317
+ ```
318
+ app.add(new Text(app, {
319
+ x: 16,
320
+ y: 24,
321
+ text: 'Paramètres',
322
+ fontSize: 22,
323
+ bold: true
324
+ }));
325
+
326
+ // Accordéon
327
+ app.add(new Accordion(app, {
328
+ x: 16,
329
+ y: 80,
330
+ width: app.width - 32,
331
+ title: 'Sécurité',
332
+ content: 'Changez votre mot de passe, activez la double authentification.'
333
+ }));
334
+
335
+ // Bouton
336
+ app.add(new Button(app, {
337
+ x: 16,
338
+ y: 240,
339
+ width: app.width - 32,
340
+ height: 48,
341
+ text: 'Déconnexion'
342
+ }));
343
+
344
+ // Navigation
345
+ app.add(new BottomNavigationBar(app, {
346
+ items: [
347
+ { icon: 'home', label: 'Accueil' },
348
+ { icon: 'settings', label: 'Paramètres' }
349
+ ]
350
+ }));
351
+ ```
352
+
353
+ # Stack – superposition (équivalent Flutter Stack)
354
+
355
+ Exemple : carte avec image + titre + bouton flottant
356
+
357
+ ```
358
+ import Stack from './layout/Stack.js';
359
+ import Text from './components/Text.js';
360
+ import Button from './components/Button.js';
361
+ import Image from './components/Image.js';
362
+
363
+ const card = new Stack(app, {
364
+ x: 16,
365
+ y: 40,
366
+ width: app.width - 32,
367
+ height: 200
368
+ });
369
+
370
+ card.add(new Image(app, {
371
+ src: 'cover.jpg',
372
+ width: card.width,
373
+ height: 200
374
+ }));
375
+
376
+ card.add(new Text(app, {
377
+ x: 16,
378
+ y: 16,
379
+ text: 'Titre de la carte',
380
+ fontSize: 20,
381
+ color: '#FFFFFF'
382
+ }));
383
+
384
+ card.add(new Button(app, {
385
+ x: card.width - 72,
386
+ y: card.height - 56,
387
+ width: 56,
388
+ height: 56,
389
+ text: '+'
390
+ }));
391
+
392
+ app.add(card);
393
+ card.layoutRecursive();
394
+ ```
395
+
396
+ # Column – layout vertical (Flutter Column)
397
+
398
+ Exemple : écran de paramètres
399
+
400
+ ```
401
+ import Column from './layout/Column.js';
402
+ import Text from './components/Text.js';
403
+ import Button from './components/Button.js';
404
+
405
+ const column = new Column(app, {
406
+ x: 16,
407
+ y: 40,
408
+ width: app.width - 32,
409
+ spacing: 12,
410
+ align: 'stretch'
411
+ });
412
+
413
+ column.add(new Text(app, {
414
+ text: 'Paramètres',
415
+ fontSize: 22,
416
+ height: 32
417
+ }));
418
+
419
+ column.add(new Button(app, {
420
+ height: 48,
421
+ text: 'Compte'
422
+ }));
423
+
424
+ column.add(new Button(app, {
425
+ height: 48,
426
+ text: 'Sécurité'
427
+ }));
428
+
429
+ column.add(new Button(app, {
430
+ height: 48,
431
+ text: 'Notifications'
432
+ }));
433
+
434
+ app.add(column);
435
+ column.layout();
436
+ ```
437
+
438
+ # Row – layout horizontal (Flutter Row)
439
+
440
+ Exemple : barre d’actions
441
+
442
+ ```
443
+ import Row from './layout/Row.js';
444
+ import Button from './components/Button.js';
445
+
446
+ const actions = new Row(app, {
447
+ x: 16,
448
+ y: 120,
449
+ height: 48,
450
+ spacing: 12,
451
+ align: 'center'
452
+ });
453
+
454
+ actions.add(new Button(app, {
455
+ width: 100,
456
+ height: 40,
457
+ text: 'Annuler'
458
+ }));
459
+
460
+ actions.add(new Button(app, {
461
+ width: 120,
462
+ height: 40,
463
+ text: 'Valider'
464
+ }));
465
+
466
+ app.add(actions);
467
+ actions.layout();
468
+ ```
469
+
470
+ # Grid – grille adaptative (Flutter GridView.count)
471
+
472
+ Exemple : grille d’options
473
+
474
+ ```
475
+ import Grid from './layout/Grid.js';
476
+ import Card from './components/Card.js';
477
+
478
+ const grid = new Grid(app, {
479
+ x: 16,
480
+ y: 200,
481
+ width: app.width - 32,
482
+ columns: 3,
483
+ spacing: 12
484
+ });
485
+
486
+ for (let i = 0; i < 6; i++) {
487
+ grid.add(new Card(app, {
488
+ height: 100,
489
+ title: `Item ${i + 1}`
490
+ }));
491
+ }
492
+
493
+ app.add(grid);
494
+ grid.layout();
495
+ ```
496
+
497
+ # Composition réelle (comme Flutter 😏)
498
+
499
+ ```
500
+ const screen = new Column(app, {
501
+ x: 0,
502
+ y: 0,
503
+ width: app.width,
504
+ spacing: 24,
505
+ align: 'stretch'
506
+ });
507
+
508
+ // Header
509
+ screen.add(new Text(app, {
510
+ text: 'Accueil',
511
+ fontSize: 24,
512
+ height: 40
513
+ }));
514
+
515
+ // Hero
516
+ const hero = new Stack(app, {
517
+ width: app.width,
518
+ height: 180
519
+ });
520
+
521
+ hero.add(new Image(app, {
522
+ src: 'hero.jpg',
523
+ width: app.width,
524
+ height: 180
525
+ }));
526
+
527
+ hero.add(new Text(app, {
528
+ x: 16,
529
+ y: 120,
530
+ text: 'Bienvenue',
531
+ fontSize: 20,
532
+ color: '#FFF'
533
+ }));
534
+
535
+ screen.add(hero);
536
+
537
+ // Actions
538
+ const row = new Row(app, {
539
+ height: 48,
540
+ spacing: 12
541
+ });
542
+
543
+ row.add(new Button(app, { width: 120, height: 40, text: 'Explorer' }));
544
+ row.add(new Button(app, { width: 120, height: 40, text: 'Profil' }));
545
+
546
+ screen.add(row);
547
+
548
+ app.add(screen);
549
+ screen.layoutRecursive();
550
+ ```
551
+
552
+ ## 📄 License
553
+
554
+ MIT