canvasframework 0.3.10 → 0.3.12

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.
@@ -49,6 +49,7 @@ import SearchInput from '../components/SearchInput.js';
49
49
  import ImageCarousel from '../components/ImageCarousel.js';
50
50
  import PasswordInput from '../components/PasswordInput.js';
51
51
  import InputTags from '../components/InputTags.js';
52
+ import InputDatalist from '../components/InputDatalist.js';
52
53
 
53
54
  // Utils
54
55
  import SafeArea from '../utils/SafeArea.js';
@@ -88,6 +89,7 @@ import FeatureFlags from '../manager/FeatureFlags.js';
88
89
 
89
90
  // WebGL Adapter
90
91
  import WebGLCanvasAdapter from './WebGLCanvasAdapter.js';
92
+ import ui from './UIBuilder.js';
91
93
 
92
94
  // theme
93
95
  export const lightTheme = {
@@ -870,9 +872,9 @@ class CanvasFramework {
870
872
  if (child.pressed) {
871
873
  child.pressed = false;
872
874
 
873
- if (child instanceof Input || child instanceof PasswordInput || child instanceof InputTags) {
875
+ if (child instanceof Input || child instanceof PasswordInput || child instanceof InputTags || child instanceof InputDatalist) {
874
876
  for (let other of this.components) {
875
- if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags && other !== child && other.focused) {
877
+ if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags || other instanceof InputDatalist && other !== child && other.focused) {
876
878
  other.focused = false;
877
879
  other.cursorVisible = false;
878
880
  if (other.onBlur) other.onBlur();
@@ -916,9 +918,9 @@ class CanvasFramework {
916
918
  if (comp.pressed) {
917
919
  comp.pressed = false;
918
920
 
919
- if (comp instanceof Input || comp instanceof PasswordInput || comp instanceof InputTags) {
921
+ if (comp instanceof Input || comp instanceof PasswordInput || comp instanceof InputTags || comp instanceof InputDatalist) {
920
922
  for (let other of this.components) {
921
- if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags && other !== comp && other.focused) {
923
+ if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags || other instanceof InputDatalist && other !== comp && other.focused) {
922
924
  other.focused = false;
923
925
  other.cursorVisible = false;
924
926
  if (other.onBlur) other.onBlur();
@@ -0,0 +1,236 @@
1
+ // Import ALL components explicitly
2
+ import Button from '../components/Button.js';
3
+ import SegmentedControl from '../components/SegmentedControl.js';
4
+ import Input from '../components/Input.js';
5
+ import Slider from '../components/Slider.js';
6
+ import Text from '../components/Text.js';
7
+ import View from '../components/View.js';
8
+ import Card from '../components/Card.js';
9
+ import FAB from '../components/FAB.js';
10
+ import SpeedDialFAB from '../components/SpeedDialFAB.js';
11
+ import MorphingFAB from '../components/MorphingFAB.js';
12
+ import CircularProgress from '../components/CircularProgress.js';
13
+ import ImageComponent from '../components/ImageComponent.js';
14
+ import DatePicker from '../components/DatePicker.js';
15
+ import IOSDatePickerWheel from '../components/IOSDatePickerWheel.js';
16
+ import AndroidDatePickerDialog from '../components/AndroidDatePickerDialog.js';
17
+ import Avatar from '../components/Avatar.js';
18
+ import Snackbar from '../components/Snackbar.js';
19
+ import BottomNavigationBar from '../components/BottomNavigationBar.js';
20
+ import Video from '../components/Video.js';
21
+ import Modal from '../components/Modal.js';
22
+ import Drawer from '../components/Drawer.js';
23
+ import AppBar from '../components/AppBar.js';
24
+ import Chip from '../components/Chip.js';
25
+ import Stepper from '../components/Stepper.js';
26
+ import Accordion from '../components/Accordion.js';
27
+ import Tabs from '../components/Tabs.js';
28
+ import Switch from '../components/Switch.js';
29
+ import SwipeableListItem from '../components/SwipeableListItem.js';
30
+ import ListItem from '../components/ListItem.js';
31
+ import List from '../components/List.js';
32
+ import VirtualList from '../components/VirtualList.js';
33
+ import BottomSheet from '../components/BottomSheet.js';
34
+ import ProgressBar from '../components/ProgressBar.js';
35
+ import RadioButton from '../components/RadioButton.js';
36
+ import Dialog from '../components/Dialog.js';
37
+ import ContextMenu from '../components/ContextMenu.js';
38
+ import Checkbox from '../components/Checkbox.js';
39
+ import Toast from '../components/Toast.js';
40
+ import NumberInput from '../components/NumberInput.js';
41
+ import TextField from '../components/TextField.js';
42
+ import SelectDialog from '../components/SelectDialog.js';
43
+ import Select from '../components/Select.js';
44
+ import MultiSelectDialog from '../components/MultiSelectDialog.js';
45
+ import Divider from '../components/Divider.js';
46
+ import FileUpload from '../components/FileUpload.js';
47
+ import Table from '../components/Table.js';
48
+ import TreeView from '../components/TreeView.js';
49
+ import SearchInput from '../components/SearchInput.js';
50
+ import ImageCarousel from '../components/ImageCarousel.js';
51
+ import PasswordInput from '../components/PasswordInput.js';
52
+ import InputTags from '../components/InputTags.js';
53
+ import InputDatalist from '../components/InputDatalist.js';
54
+
55
+ // Features
56
+ import PullToRefresh from '../features/PullToRefresh.js';
57
+ import Skeleton from '../features/Skeleton.js';
58
+ import SignaturePad from '../features/SignaturePad.js';
59
+ import OpenStreetMap from '../features/OpenStreetMap.js';
60
+ import LayoutComponent from '../features/LayoutComponent.js';
61
+ import Grid from '../features/Grid.js';
62
+ import Row from '../features/Row.js';
63
+ import Column from '../features/Column.js';
64
+ import Positioned from '../features/Positioned.js';
65
+ import Stack from '../features/Stack.js';
66
+
67
+ /**
68
+ * Map of all available components
69
+ */
70
+ const Components = {
71
+ Button,
72
+ SegmentedControl,
73
+ Input,
74
+ Slider,
75
+ Text,
76
+ View,
77
+ Card,
78
+ FAB,
79
+ SpeedDialFAB,
80
+ MorphingFAB,
81
+ CircularProgress,
82
+ ImageComponent,
83
+ DatePicker,
84
+ IOSDatePickerWheel,
85
+ AndroidDatePickerDialog,
86
+ Avatar,
87
+ Snackbar,
88
+ BottomNavigationBar,
89
+ Video,
90
+ Modal,
91
+ Drawer,
92
+ AppBar,
93
+ Chip,
94
+ Stepper,
95
+ Accordion,
96
+ Tabs,
97
+ Switch,
98
+ SwipeableListItem,
99
+ ListItem,
100
+ List,
101
+ VirtualList,
102
+ BottomSheet,
103
+ ProgressBar,
104
+ RadioButton,
105
+ Dialog,
106
+ ContextMenu,
107
+ Checkbox,
108
+ Toast,
109
+ NumberInput,
110
+ TextField,
111
+ SelectDialog,
112
+ Select,
113
+ MultiSelectDialog,
114
+ Divider,
115
+ FileUpload,
116
+ Table,
117
+ TreeView,
118
+ SearchInput,
119
+ ImageCarousel,
120
+ PasswordInput,
121
+ InputTags,
122
+ InputDatalist,
123
+ PullToRefresh,
124
+ Skeleton,
125
+ SignaturePad,
126
+ OpenStreetMap,
127
+ LayoutComponent,
128
+ Grid,
129
+ Row,
130
+ Column,
131
+ Positioned,
132
+ Stack
133
+ };
134
+
135
+ /**
136
+ * DSL déclaratif pour CanvasFramework
137
+ */
138
+ class UIBuilder {
139
+ constructor() {
140
+ this._tree = null;
141
+ }
142
+
143
+ /* ============================
144
+ BASE
145
+ ============================ */
146
+
147
+ _create(type, props = {}, children = []) {
148
+ return { type, props, children };
149
+ }
150
+
151
+ mount(framework) {
152
+ if (!this._tree) return;
153
+ this._mountNode(framework, this._tree, null);
154
+ }
155
+
156
+ _mountNode(framework, node, parent = null) {
157
+ if (!node) return null;
158
+
159
+ const ComponentClass = Components[node.type];
160
+ if (!ComponentClass) {
161
+ console.warn(`UIBuilder: composant inconnu "${node.type}"`);
162
+ return null;
163
+ }
164
+
165
+ const instance = new ComponentClass(framework, node.props);
166
+
167
+ // ✅ Ajouter au framework UNIQUEMENT si ce n'est pas un enfant de Card
168
+ const isChildOfCard = parent && parent.constructor?.name === 'Card';
169
+ if (!isChildOfCard) {
170
+ framework.add(instance);
171
+ }
172
+
173
+ // ✅ Ajouter au parent si parent existe et supporte add
174
+ if (parent && typeof parent.add === 'function') {
175
+ parent.add(instance);
176
+ }
177
+
178
+ // Monter les enfants
179
+ if (node.children && node.children.length > 0) {
180
+ node.children.forEach(child =>
181
+ this._mountNode(framework, child, instance)
182
+ );
183
+ }
184
+
185
+ return instance;
186
+ }
187
+
188
+ /* ============================
189
+ ROOT
190
+ ============================ */
191
+
192
+ app(node) {
193
+ this._tree = node;
194
+ return this;
195
+ }
196
+ }
197
+
198
+ /* ============================
199
+ FACTORIES AUTOMATIQUES
200
+ ============================ */
201
+
202
+ const ui = new UIBuilder();
203
+
204
+ // Génération automatique pour TOUS les composants
205
+ Object.keys(Components).forEach((name) => {
206
+ const factoryName = name.charAt(0).toLowerCase() + name.slice(1);
207
+
208
+ const factory = (props = {}, children = []) => {
209
+ // Ensure children is always an array
210
+ const childArray = Array.isArray(children) ? children : (children ? [children] : []);
211
+ return ui._create(name, props, childArray);
212
+ };
213
+
214
+ // Add both lowercase and uppercase versions
215
+ ui[factoryName] = factory; // e.g., ui.text
216
+ ui[name] = factory; // e.g., ui.Text
217
+ });
218
+
219
+ /* ============================
220
+ ALIAS SUPPLÉMENTAIRES
221
+ ============================ */
222
+
223
+ // Ensure these exist even if they were auto-generated
224
+ ui.column = ui.column || ((props = {}, children = []) =>
225
+ ui._create('Column', props, Array.isArray(children) ? children : [children]));
226
+
227
+ ui.row = ui.row || ((props = {}, children = []) =>
228
+ ui._create('Row', props, Array.isArray(children) ? children : [children]));
229
+
230
+ ui.stack = ui.stack || ((props = {}, children = []) =>
231
+ ui._create('Stack', props, Array.isArray(children) ? children : [children]));
232
+
233
+ ui.grid = ui.grid || ((props = {}, children = []) =>
234
+ ui._create('Grid', props, Array.isArray(children) ? children : [children]));
235
+
236
+ export default ui;
package/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  // Core
4
4
  export { default as CanvasFramework } from './core/CanvasFramework.js';
5
5
  export { default as Component } from './core/Component.js';
6
+ export { default as ui } from './core/UIBuilder.js';
6
7
 
7
8
  // Components
8
9
  export { default as Button } from './components/Button.js';
@@ -56,6 +57,7 @@ export { default as SearchInput } from './components/SearchInput.js';
56
57
  export { default as ImageCarousel } from './components/ImageCarousel.js';
57
58
  export { default as PasswordInput } from './components/PasswordInput.js';
58
59
  export { default as InputTags } from './components/InputTags.js';
60
+ export { default as InputDatalist } from './components/InputDatalist.js';
59
61
 
60
62
  // Utils
61
63
  export { default as SafeArea } from './utils/SafeArea.js';
@@ -95,7 +97,7 @@ export { default as FeatureFlags } from './manager/FeatureFlags.js';
95
97
 
96
98
  // Version du framework
97
99
 
98
- export const VERSION = '0.3.9';
100
+ export const VERSION = '0.3.10';
99
101
 
100
102
 
101
103
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "description": "Canvas-based cross-platform UI framework (Material & Cupertino)",
5
5
  "type": "module",
6
6
  "main": "./index.js",