canvasframework 0.3.8 → 0.3.10
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/AppBar.js +164 -70
- package/components/BottomNavigationBar.js +206 -69
- package/components/Button.js +182 -62
- package/components/InputTags.js +586 -0
- package/components/MorphingFAB.js +428 -0
- package/components/PasswordInput.js +462 -0
- package/components/SpeedDialFAB.js +397 -0
- package/components/TimePicker.js +443 -0
- package/core/CanvasFramework.js +8 -4
- package/index.js +5 -1
- package/package.json +1 -1
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import Component from '../core/Component.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sélecteur d'heure (Material horloge & iOS wheel)
|
|
5
|
+
* @class
|
|
6
|
+
* @extends Component
|
|
7
|
+
*/
|
|
8
|
+
class TimePicker extends Component {
|
|
9
|
+
/**
|
|
10
|
+
* Crée une instance de TimePicker
|
|
11
|
+
* @param {CanvasFramework} framework - Framework parent
|
|
12
|
+
* @param {Object} [options={}] - Options
|
|
13
|
+
* @param {number} [options.hours=12] - Heures (0-23)
|
|
14
|
+
* @param {number} [options.minutes=0] - Minutes (0-59)
|
|
15
|
+
* @param {boolean} [options.is24Hour=true] - Format 24h
|
|
16
|
+
* @param {Function} [options.onChange] - Callback (hours, minutes)
|
|
17
|
+
*/
|
|
18
|
+
constructor(framework, options = {}) {
|
|
19
|
+
super(framework, options);
|
|
20
|
+
|
|
21
|
+
this.hours = options.hours || 12;
|
|
22
|
+
this.minutes = options.minutes || 0;
|
|
23
|
+
this.is24Hour = options.is24Hour !== false;
|
|
24
|
+
this.onChange = options.onChange;
|
|
25
|
+
this.platform = framework.platform;
|
|
26
|
+
|
|
27
|
+
this.mode = 'hours'; // 'hours' ou 'minutes'
|
|
28
|
+
this.isOpen = false;
|
|
29
|
+
|
|
30
|
+
// Dimensions
|
|
31
|
+
if (this.platform === 'cupertino') {
|
|
32
|
+
// iOS wheel picker
|
|
33
|
+
this.pickerHeight = 216;
|
|
34
|
+
this.wheelRadius = 40;
|
|
35
|
+
} else {
|
|
36
|
+
// Material clock
|
|
37
|
+
this.clockRadius = 100;
|
|
38
|
+
this.pickerHeight = 280;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.width = options.width || framework.width - 40;
|
|
42
|
+
this.height = 56;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Ouvre/ferme le picker
|
|
47
|
+
*/
|
|
48
|
+
togglePicker() {
|
|
49
|
+
this.isOpen = !this.isOpen;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gère le clic
|
|
54
|
+
*/
|
|
55
|
+
onClick() {
|
|
56
|
+
const framework = this.framework;
|
|
57
|
+
const clickInfo = framework.getLastClick();
|
|
58
|
+
|
|
59
|
+
if (clickInfo) {
|
|
60
|
+
const { x, y } = clickInfo;
|
|
61
|
+
|
|
62
|
+
if (!this.isOpen) {
|
|
63
|
+
this.togglePicker();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (this.platform === 'material') {
|
|
68
|
+
this.handleMaterialClick(x, y);
|
|
69
|
+
} else {
|
|
70
|
+
this.handleIOSClick(x, y);
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
this.togglePicker();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Gère le clic Material (horloge)
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
handleMaterialClick(x, y) {
|
|
82
|
+
const pickerY = this.y + this.height + 8;
|
|
83
|
+
const centerX = this.x + this.width / 2;
|
|
84
|
+
const centerY = pickerY + 140;
|
|
85
|
+
|
|
86
|
+
// Toggle mode heures/minutes
|
|
87
|
+
if (y >= pickerY + 20 && y <= pickerY + 60) {
|
|
88
|
+
if (x < this.x + this.width / 2) {
|
|
89
|
+
this.mode = 'hours';
|
|
90
|
+
} else {
|
|
91
|
+
this.mode = 'minutes';
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Clic sur l'horloge
|
|
97
|
+
const dx = x - centerX;
|
|
98
|
+
const dy = y - centerY;
|
|
99
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
100
|
+
|
|
101
|
+
if (distance <= this.clockRadius) {
|
|
102
|
+
const angle = Math.atan2(dy, dx);
|
|
103
|
+
const normalizedAngle = (angle + Math.PI / 2 + 2 * Math.PI) % (2 * Math.PI);
|
|
104
|
+
|
|
105
|
+
if (this.mode === 'hours') {
|
|
106
|
+
const hourValue = Math.round((normalizedAngle / (2 * Math.PI)) * 12);
|
|
107
|
+
this.hours = hourValue === 0 ? 12 : hourValue;
|
|
108
|
+
if (!this.is24Hour && this.hours > 12) this.hours -= 12;
|
|
109
|
+
} else {
|
|
110
|
+
this.minutes = Math.round((normalizedAngle / (2 * Math.PI)) * 60) % 60;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (this.onChange) {
|
|
114
|
+
this.onChange(this.hours, this.minutes);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Bouton OK
|
|
119
|
+
const okButtonY = pickerY + this.pickerHeight - 50;
|
|
120
|
+
if (y >= okButtonY && y <= okButtonY + 40 &&
|
|
121
|
+
x >= this.x + this.width - 100 && x <= this.x + this.width - 20) {
|
|
122
|
+
this.isOpen = false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Gère le clic iOS (wheel)
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
handleIOSClick(x, y) {
|
|
131
|
+
// Bouton Done
|
|
132
|
+
const pickerY = this.y + this.height + 8;
|
|
133
|
+
const doneY = pickerY + this.pickerHeight - 44;
|
|
134
|
+
|
|
135
|
+
if (y >= doneY && y <= doneY + 44) {
|
|
136
|
+
this.isOpen = false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Dessine le composant
|
|
142
|
+
*/
|
|
143
|
+
draw(ctx) {
|
|
144
|
+
ctx.save();
|
|
145
|
+
|
|
146
|
+
// Bouton pour ouvrir le picker
|
|
147
|
+
this.drawButton(ctx);
|
|
148
|
+
|
|
149
|
+
// Picker
|
|
150
|
+
if (this.isOpen) {
|
|
151
|
+
if (this.platform === 'material') {
|
|
152
|
+
this.drawMaterialPicker(ctx);
|
|
153
|
+
} else {
|
|
154
|
+
this.drawIOSPicker(ctx);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
ctx.restore();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Dessine le bouton
|
|
163
|
+
* @private
|
|
164
|
+
*/
|
|
165
|
+
drawButton(ctx) {
|
|
166
|
+
if (this.platform === 'material') {
|
|
167
|
+
// Material button
|
|
168
|
+
ctx.fillStyle = '#FFFFFF';
|
|
169
|
+
ctx.fillRect(this.x, this.y, this.width, this.height);
|
|
170
|
+
ctx.strokeStyle = '#E0E0E0';
|
|
171
|
+
ctx.lineWidth = 1;
|
|
172
|
+
ctx.strokeRect(this.x, this.y, this.width, this.height);
|
|
173
|
+
|
|
174
|
+
// Icône horloge
|
|
175
|
+
ctx.strokeStyle = '#666666';
|
|
176
|
+
ctx.lineWidth = 2;
|
|
177
|
+
ctx.beginPath();
|
|
178
|
+
ctx.arc(this.x + 25, this.y + 28, 10, 0, Math.PI * 2);
|
|
179
|
+
ctx.stroke();
|
|
180
|
+
ctx.beginPath();
|
|
181
|
+
ctx.moveTo(this.x + 25, this.y + 28);
|
|
182
|
+
ctx.lineTo(this.x + 25, this.y + 22);
|
|
183
|
+
ctx.lineTo(this.x + 30, this.y + 28);
|
|
184
|
+
ctx.stroke();
|
|
185
|
+
|
|
186
|
+
// Texte
|
|
187
|
+
ctx.fillStyle = '#000000';
|
|
188
|
+
ctx.font = '16px Roboto, sans-serif';
|
|
189
|
+
ctx.textAlign = 'left';
|
|
190
|
+
ctx.textBaseline = 'middle';
|
|
191
|
+
ctx.fillText(this.formatTime(), this.x + 50, this.y + 28);
|
|
192
|
+
|
|
193
|
+
} else {
|
|
194
|
+
// iOS button
|
|
195
|
+
ctx.strokeStyle = '#C7C7CC';
|
|
196
|
+
ctx.lineWidth = 1;
|
|
197
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, 10);
|
|
198
|
+
ctx.stroke();
|
|
199
|
+
|
|
200
|
+
ctx.fillStyle = '#8E8E93';
|
|
201
|
+
ctx.font = '14px -apple-system, sans-serif';
|
|
202
|
+
ctx.textAlign = 'left';
|
|
203
|
+
ctx.textBaseline = 'middle';
|
|
204
|
+
ctx.fillText('Time', this.x + 15, this.y + 18);
|
|
205
|
+
|
|
206
|
+
ctx.fillStyle = '#000000';
|
|
207
|
+
ctx.font = '16px -apple-system, sans-serif';
|
|
208
|
+
ctx.fillText(this.formatTime(), this.x + 15, this.y + 38);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Dessine le picker Material (horloge)
|
|
214
|
+
* @private
|
|
215
|
+
*/
|
|
216
|
+
drawMaterialPicker(ctx) {
|
|
217
|
+
const pickerY = this.y + this.height + 8;
|
|
218
|
+
|
|
219
|
+
// Background
|
|
220
|
+
ctx.fillStyle = '#FFFFFF';
|
|
221
|
+
ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
|
|
222
|
+
ctx.shadowBlur = 16;
|
|
223
|
+
ctx.shadowOffsetY = 4;
|
|
224
|
+
ctx.fillRect(this.x, pickerY, this.width, this.pickerHeight);
|
|
225
|
+
ctx.shadowColor = 'transparent';
|
|
226
|
+
|
|
227
|
+
// Header avec time display
|
|
228
|
+
ctx.fillStyle = '#6200EE';
|
|
229
|
+
ctx.fillRect(this.x, pickerY, this.width, 80);
|
|
230
|
+
|
|
231
|
+
// Time display
|
|
232
|
+
const timeStr = `${String(this.hours).padStart(2, '0')}:${String(this.minutes).padStart(2, '0')}`;
|
|
233
|
+
ctx.fillStyle = '#FFFFFF';
|
|
234
|
+
ctx.font = 'bold 48px Roboto, sans-serif';
|
|
235
|
+
ctx.textAlign = 'center';
|
|
236
|
+
ctx.fillText(timeStr, this.x + this.width / 2, pickerY + 50);
|
|
237
|
+
|
|
238
|
+
// Mode selector (hours/minutes)
|
|
239
|
+
ctx.font = '14px Roboto, sans-serif';
|
|
240
|
+
const modeY = pickerY + 20;
|
|
241
|
+
|
|
242
|
+
if (this.mode === 'hours') {
|
|
243
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
|
244
|
+
} else {
|
|
245
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
|
|
246
|
+
}
|
|
247
|
+
ctx.fillText('Hours', this.x + this.width / 4, modeY);
|
|
248
|
+
|
|
249
|
+
if (this.mode === 'minutes') {
|
|
250
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
|
251
|
+
} else {
|
|
252
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
|
|
253
|
+
}
|
|
254
|
+
ctx.fillText('Minutes', this.x + 3 * this.width / 4, modeY);
|
|
255
|
+
|
|
256
|
+
// Clock
|
|
257
|
+
const centerX = this.x + this.width / 2;
|
|
258
|
+
const centerY = pickerY + 140 + 40;
|
|
259
|
+
|
|
260
|
+
// Clock circle
|
|
261
|
+
ctx.strokeStyle = '#E0E0E0';
|
|
262
|
+
ctx.lineWidth = 1;
|
|
263
|
+
ctx.beginPath();
|
|
264
|
+
ctx.arc(centerX, centerY, this.clockRadius, 0, Math.PI * 2);
|
|
265
|
+
ctx.stroke();
|
|
266
|
+
|
|
267
|
+
// Numbers
|
|
268
|
+
const count = this.mode === 'hours' ? 12 : 12;
|
|
269
|
+
const step = this.mode === 'hours' ? 1 : 5;
|
|
270
|
+
|
|
271
|
+
for (let i = 0; i < count; i++) {
|
|
272
|
+
const angle = (i * 2 * Math.PI / count) - Math.PI / 2;
|
|
273
|
+
const x = centerX + Math.cos(angle) * (this.clockRadius - 20);
|
|
274
|
+
const y = centerY + Math.sin(angle) * (this.clockRadius - 20);
|
|
275
|
+
const value = this.mode === 'hours' ? (i === 0 ? 12 : i) : i * step;
|
|
276
|
+
|
|
277
|
+
const isSelected = this.mode === 'hours'
|
|
278
|
+
? value === this.hours
|
|
279
|
+
: value === Math.floor(this.minutes / 5) * 5;
|
|
280
|
+
|
|
281
|
+
if (isSelected) {
|
|
282
|
+
ctx.fillStyle = '#6200EE';
|
|
283
|
+
ctx.beginPath();
|
|
284
|
+
ctx.arc(x, y, 18, 0, Math.PI * 2);
|
|
285
|
+
ctx.fill();
|
|
286
|
+
ctx.fillStyle = '#FFFFFF';
|
|
287
|
+
} else {
|
|
288
|
+
ctx.fillStyle = '#000000';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
ctx.font = '14px Roboto, sans-serif';
|
|
292
|
+
ctx.textAlign = 'center';
|
|
293
|
+
ctx.textBaseline = 'middle';
|
|
294
|
+
ctx.fillText(String(value), x, y);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Hand (aiguille)
|
|
298
|
+
const currentValue = this.mode === 'hours' ? this.hours : this.minutes;
|
|
299
|
+
const handAngle = this.mode === 'hours'
|
|
300
|
+
? ((currentValue % 12) * 2 * Math.PI / 12) - Math.PI / 2
|
|
301
|
+
: (currentValue * 2 * Math.PI / 60) - Math.PI / 2;
|
|
302
|
+
|
|
303
|
+
const handEndX = centerX + Math.cos(handAngle) * (this.clockRadius - 20);
|
|
304
|
+
const handEndY = centerY + Math.sin(handAngle) * (this.clockRadius - 20);
|
|
305
|
+
|
|
306
|
+
ctx.strokeStyle = '#6200EE';
|
|
307
|
+
ctx.lineWidth = 2;
|
|
308
|
+
ctx.beginPath();
|
|
309
|
+
ctx.moveTo(centerX, centerY);
|
|
310
|
+
ctx.lineTo(handEndX, handEndY);
|
|
311
|
+
ctx.stroke();
|
|
312
|
+
|
|
313
|
+
// Center dot
|
|
314
|
+
ctx.fillStyle = '#6200EE';
|
|
315
|
+
ctx.beginPath();
|
|
316
|
+
ctx.arc(centerX, centerY, 4, 0, Math.PI * 2);
|
|
317
|
+
ctx.fill();
|
|
318
|
+
|
|
319
|
+
// OK button
|
|
320
|
+
const okY = pickerY + this.pickerHeight - 50;
|
|
321
|
+
ctx.fillStyle = '#6200EE';
|
|
322
|
+
ctx.font = 'bold 14px Roboto, sans-serif';
|
|
323
|
+
ctx.textAlign = 'right';
|
|
324
|
+
ctx.fillText('OK', this.x + this.width - 30, okY + 20);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Dessine le picker iOS (wheel)
|
|
329
|
+
* @private
|
|
330
|
+
*/
|
|
331
|
+
drawIOSPicker(ctx) {
|
|
332
|
+
const pickerY = this.y + this.height + 8;
|
|
333
|
+
|
|
334
|
+
// Background
|
|
335
|
+
ctx.fillStyle = '#F9F9F9';
|
|
336
|
+
this.roundRect(ctx, this.x, pickerY, this.width, this.pickerHeight, 12);
|
|
337
|
+
ctx.fill();
|
|
338
|
+
|
|
339
|
+
// Selection bar (au milieu)
|
|
340
|
+
const selectionY = pickerY + this.pickerHeight / 2 - 20;
|
|
341
|
+
ctx.fillStyle = 'rgba(0, 122, 255, 0.1)';
|
|
342
|
+
this.roundRect(ctx, this.x + 20, selectionY, this.width - 40, 40, 8);
|
|
343
|
+
ctx.fill();
|
|
344
|
+
|
|
345
|
+
// Wheels (heures et minutes)
|
|
346
|
+
const hourWheelX = this.x + this.width / 3;
|
|
347
|
+
const minuteWheelX = this.x + 2 * this.width / 3;
|
|
348
|
+
const wheelY = pickerY + this.pickerHeight / 2;
|
|
349
|
+
|
|
350
|
+
// Heures
|
|
351
|
+
this.drawWheel(ctx, hourWheelX, wheelY, this.hours, 23, false);
|
|
352
|
+
|
|
353
|
+
// Séparateur ":"
|
|
354
|
+
ctx.fillStyle = '#000000';
|
|
355
|
+
ctx.font = '24px -apple-system, sans-serif';
|
|
356
|
+
ctx.textAlign = 'center';
|
|
357
|
+
ctx.fillText(':', this.x + this.width / 2, wheelY);
|
|
358
|
+
|
|
359
|
+
// Minutes
|
|
360
|
+
this.drawWheel(ctx, minuteWheelX, wheelY, this.minutes, 59, true);
|
|
361
|
+
|
|
362
|
+
// Done button
|
|
363
|
+
const doneY = pickerY + this.pickerHeight - 44;
|
|
364
|
+
ctx.fillStyle = '#007AFF';
|
|
365
|
+
ctx.font = '17px -apple-system, sans-serif';
|
|
366
|
+
ctx.textAlign = 'center';
|
|
367
|
+
ctx.fillText('Done', this.x + this.width / 2, doneY + 22);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Dessine une roue iOS
|
|
372
|
+
* @private
|
|
373
|
+
*/
|
|
374
|
+
drawWheel(ctx, x, y, selected, max, isMinute) {
|
|
375
|
+
const itemHeight = 40;
|
|
376
|
+
const visibleItems = 5;
|
|
377
|
+
|
|
378
|
+
for (let i = -2; i <= 2; i++) {
|
|
379
|
+
let value = (selected + i + max + 1) % (max + 1);
|
|
380
|
+
if (isMinute) value = Math.floor(value / 5) * 5;
|
|
381
|
+
|
|
382
|
+
const itemY = y + i * itemHeight;
|
|
383
|
+
const opacity = 1 - Math.abs(i) * 0.4;
|
|
384
|
+
const scale = 1 - Math.abs(i) * 0.2;
|
|
385
|
+
|
|
386
|
+
ctx.save();
|
|
387
|
+
ctx.globalAlpha = opacity;
|
|
388
|
+
ctx.fillStyle = i === 0 ? '#000000' : '#8E8E93';
|
|
389
|
+
ctx.font = `${Math.floor(24 * scale)}px -apple-system, sans-serif`;
|
|
390
|
+
ctx.textAlign = 'center';
|
|
391
|
+
ctx.textBaseline = 'middle';
|
|
392
|
+
ctx.fillText(String(value).padStart(2, '0'), x, itemY);
|
|
393
|
+
ctx.restore();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Formate l'heure
|
|
399
|
+
* @private
|
|
400
|
+
*/
|
|
401
|
+
formatTime() {
|
|
402
|
+
const h = String(this.hours).padStart(2, '0');
|
|
403
|
+
const m = String(this.minutes).padStart(2, '0');
|
|
404
|
+
return `${h}:${m}`;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Rectangle arrondi
|
|
409
|
+
* @private
|
|
410
|
+
*/
|
|
411
|
+
roundRect(ctx, x, y, width, height, radius) {
|
|
412
|
+
ctx.beginPath();
|
|
413
|
+
ctx.moveTo(x + radius, y);
|
|
414
|
+
ctx.lineTo(x + width - radius, y);
|
|
415
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
|
416
|
+
ctx.lineTo(x + width, y + height - radius);
|
|
417
|
+
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
|
418
|
+
ctx.lineTo(x + radius, y + height);
|
|
419
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
|
420
|
+
ctx.lineTo(x, y + radius);
|
|
421
|
+
ctx.quadraticCurveTo(x, y, x + radius, y);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Vérifie si point dans limites
|
|
426
|
+
*/
|
|
427
|
+
isPointInside(x, y) {
|
|
428
|
+
if (x >= this.x && x <= this.x + this.width &&
|
|
429
|
+
y >= this.y && y <= this.y + this.height) {
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (this.isOpen) {
|
|
434
|
+
const pickerY = this.y + this.height + 8;
|
|
435
|
+
return x >= this.x && x <= this.x + this.width &&
|
|
436
|
+
y >= pickerY && y <= pickerY + this.pickerHeight;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export default TimePicker;
|
package/core/CanvasFramework.js
CHANGED
|
@@ -6,6 +6,8 @@ import Text from '../components/Text.js';
|
|
|
6
6
|
import View from '../components/View.js';
|
|
7
7
|
import Card from '../components/Card.js';
|
|
8
8
|
import FAB from '../components/FAB.js';
|
|
9
|
+
import SpeedDialFAB from '../components/SpeedDialFAB.js';
|
|
10
|
+
import MorphingFAB from '../components/MorphingFAB.js';
|
|
9
11
|
import CircularProgress from '../components/CircularProgress.js';
|
|
10
12
|
import ImageComponent from '../components/ImageComponent.js';
|
|
11
13
|
import DatePicker from '../components/DatePicker.js';
|
|
@@ -45,6 +47,8 @@ import Table from '../components/Table.js';
|
|
|
45
47
|
import TreeView from '../components/TreeView.js';
|
|
46
48
|
import SearchInput from '../components/SearchInput.js';
|
|
47
49
|
import ImageCarousel from '../components/ImageCarousel.js';
|
|
50
|
+
import PasswordInput from '../components/PasswordInput.js';
|
|
51
|
+
import InputTags from '../components/InputTags.js';
|
|
48
52
|
|
|
49
53
|
// Utils
|
|
50
54
|
import SafeArea from '../utils/SafeArea.js';
|
|
@@ -866,9 +870,9 @@ class CanvasFramework {
|
|
|
866
870
|
if (child.pressed) {
|
|
867
871
|
child.pressed = false;
|
|
868
872
|
|
|
869
|
-
if (child instanceof Input) {
|
|
873
|
+
if (child instanceof Input || child instanceof PasswordInput || child instanceof InputTags) {
|
|
870
874
|
for (let other of this.components) {
|
|
871
|
-
if (other instanceof Input && other !== child && other.focused) {
|
|
875
|
+
if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags && other !== child && other.focused) {
|
|
872
876
|
other.focused = false;
|
|
873
877
|
other.cursorVisible = false;
|
|
874
878
|
if (other.onBlur) other.onBlur();
|
|
@@ -912,9 +916,9 @@ class CanvasFramework {
|
|
|
912
916
|
if (comp.pressed) {
|
|
913
917
|
comp.pressed = false;
|
|
914
918
|
|
|
915
|
-
if (comp instanceof Input) {
|
|
919
|
+
if (comp instanceof Input || comp instanceof PasswordInput || comp instanceof InputTags) {
|
|
916
920
|
for (let other of this.components) {
|
|
917
|
-
if (other instanceof Input && other !== comp && other.focused) {
|
|
921
|
+
if (other instanceof Input || other instanceof PasswordInput || other instanceof InputTags && other !== comp && other.focused) {
|
|
918
922
|
other.focused = false;
|
|
919
923
|
other.cursorVisible = false;
|
|
920
924
|
if (other.onBlur) other.onBlur();
|
package/index.js
CHANGED
|
@@ -13,6 +13,8 @@ export { default as Text } from './components/Text.js';
|
|
|
13
13
|
export { default as View } from './components/View.js';
|
|
14
14
|
export { default as Card } from './components/Card.js';
|
|
15
15
|
export { default as FAB } from './components/FAB.js';
|
|
16
|
+
export { default as SpeedDialFAB } from './components/SpeedDialFAB.js';
|
|
17
|
+
export { default as MorphingFAB } from './components/MorphingFAB.js';
|
|
16
18
|
export { default as CircularProgress } from './components/CircularProgress.js';
|
|
17
19
|
export { default as ImageComponent } from './components/ImageComponent.js';
|
|
18
20
|
export { default as DatePicker } from './components/DatePicker.js';
|
|
@@ -52,6 +54,8 @@ export { default as Table } from './components/Table.js';
|
|
|
52
54
|
export { default as TreeView } from './components/TreeView.js';
|
|
53
55
|
export { default as SearchInput } from './components/SearchInput.js';
|
|
54
56
|
export { default as ImageCarousel } from './components/ImageCarousel.js';
|
|
57
|
+
export { default as PasswordInput } from './components/PasswordInput.js';
|
|
58
|
+
export { default as InputTags } from './components/InputTags.js';
|
|
55
59
|
|
|
56
60
|
// Utils
|
|
57
61
|
export { default as SafeArea } from './utils/SafeArea.js';
|
|
@@ -91,7 +95,7 @@ export { default as FeatureFlags } from './manager/FeatureFlags.js';
|
|
|
91
95
|
|
|
92
96
|
// Version du framework
|
|
93
97
|
|
|
94
|
-
export const VERSION = '0.3.
|
|
98
|
+
export const VERSION = '0.3.9';
|
|
95
99
|
|
|
96
100
|
|
|
97
101
|
|