canvasframework 0.5.18 → 0.5.19
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/Accordion.js +265 -0
- package/components/AndroidDatePickerDialog.js +406 -0
- package/components/AppBar.js +398 -0
- package/components/AudioPlayer.js +611 -0
- package/components/Avatar.js +202 -0
- package/components/Banner.js +342 -0
- package/components/BottomNavigationBar.js +433 -0
- package/components/BottomSheet.js +234 -0
- package/components/Button.js +358 -0
- package/components/Camera.js +644 -0
- package/components/Card.js +193 -0
- package/components/Chart.js +700 -0
- package/components/Checkbox.js +166 -0
- package/components/Chip.js +212 -0
- package/components/CircularProgress.js +327 -0
- package/components/ContextMenu.js +116 -0
- package/components/DatePicker.js +298 -0
- package/components/Dialog.js +337 -0
- package/components/Divider.js +125 -0
- package/components/Drawer.js +276 -0
- package/components/FAB.js +270 -0
- package/components/FileUpload.js +315 -0
- package/components/FloatedCamera.js +644 -0
- package/components/IOSDatePickerWheel.js +430 -0
- package/components/ImageCarousel.js +219 -0
- package/components/ImageComponent.js +223 -0
- package/components/Input.js +831 -0
- package/components/InputDatalist.js +723 -0
- package/components/InputTags.js +624 -0
- package/components/List.js +95 -0
- package/components/ListItem.js +269 -0
- package/components/Modal.js +364 -0
- package/components/MorphingFAB.js +428 -0
- package/components/MultiSelectDialog.js +206 -0
- package/components/NumberInput.js +271 -0
- package/components/PasswordInput.js +462 -0
- package/components/ProgressBar.js +88 -0
- package/components/QRCodeReader.js +539 -0
- package/components/RadioButton.js +151 -0
- package/components/SearchInput.js +315 -0
- package/components/SegmentedControl.js +357 -0
- package/components/Select.js +199 -0
- package/components/SelectDialog.js +255 -0
- package/components/Slider.js +113 -0
- package/components/SliverAppBar.js +139 -0
- package/components/Snackbar.js +243 -0
- package/components/SpeedDialFAB.js +397 -0
- package/components/Stepper.js +281 -0
- package/components/SwipeableListItem.js +327 -0
- package/components/Switch.js +147 -0
- package/components/Table.js +492 -0
- package/components/Tabs.js +423 -0
- package/components/Text.js +141 -0
- package/components/TextField.js +151 -0
- package/components/TimePicker.js +934 -0
- package/components/Toast.js +236 -0
- package/components/TreeView.js +420 -0
- package/components/Video.js +397 -0
- package/components/View.js +140 -0
- package/components/VirtualList.js +120 -0
- package/core/CanvasFramework.js +3045 -0
- package/core/Component.js +243 -0
- package/core/ThemeManager.js +358 -0
- package/core/UIBuilder.js +267 -0
- package/core/WebGLCanvasAdapter.js +782 -0
- package/features/Column.js +43 -0
- package/features/Grid.js +47 -0
- package/features/LayoutComponent.js +43 -0
- package/features/OpenStreetMap.js +310 -0
- package/features/Positioned.js +33 -0
- package/features/PullToRefresh.js +328 -0
- package/features/Row.js +40 -0
- package/features/SignaturePad.js +257 -0
- package/features/Skeleton.js +193 -0
- package/features/Stack.js +21 -0
- package/index.js +119 -0
- package/manager/AccessibilityManager.js +107 -0
- package/manager/ErrorHandler.js +59 -0
- package/manager/FeatureFlags.js +60 -0
- package/manager/MemoryManager.js +107 -0
- package/manager/PerformanceMonitor.js +84 -0
- package/manager/SecurityManager.js +54 -0
- package/package.json +22 -16
- package/utils/AnimationEngine.js +734 -0
- package/utils/CryptoManager.js +303 -0
- package/utils/DataStore.js +403 -0
- package/utils/DevTools.js +1618 -0
- package/utils/DevToolsConsole.js +201 -0
- package/utils/EventBus.js +407 -0
- package/utils/FetchClient.js +74 -0
- package/utils/FirebaseAuth.js +653 -0
- package/utils/FirebaseCore.js +246 -0
- package/utils/FirebaseFirestore.js +581 -0
- package/utils/FirebaseFunctions.js +97 -0
- package/utils/FirebaseRealtimeDB.js +498 -0
- package/utils/FirebaseStorage.js +612 -0
- package/utils/FormValidator.js +355 -0
- package/utils/GeoLocationService.js +62 -0
- package/utils/I18n.js +207 -0
- package/utils/IndexedDBManager.js +273 -0
- package/utils/InspectionOverlay.js +308 -0
- package/utils/NotificationManager.js +60 -0
- package/utils/OfflineSyncManager.js +342 -0
- package/utils/PayPalPayment.js +678 -0
- package/utils/QueryBuilder.js +478 -0
- package/utils/SafeArea.js +64 -0
- package/utils/SecureStorage.js +289 -0
- package/utils/StateManager.js +207 -0
- package/utils/StripePayment.js +552 -0
- package/utils/WebSocketClient.js +66 -0
- package/dist/canvasframework.js +0 -2
- package/dist/canvasframework.js.LICENSE.txt +0 -1
|
@@ -0,0 +1,831 @@
|
|
|
1
|
+
import Component from '../core/Component.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Champ de saisie texte avec styles Material 3 (Filled/Outlined) et Cupertino
|
|
5
|
+
* @class
|
|
6
|
+
* @extends Component
|
|
7
|
+
* @property {string} placeholder - Texte d'indication
|
|
8
|
+
* @property {string} value - Valeur
|
|
9
|
+
* @property {number} fontSize - Taille de police
|
|
10
|
+
* @property {boolean} focused - Focus actif
|
|
11
|
+
* @property {string} platform - Plateforme ('material' ou 'cupertino')
|
|
12
|
+
* @property {string} variant - Variante Material ('filled' ou 'outlined')
|
|
13
|
+
* @property {boolean} cursorVisible - Curseur visible
|
|
14
|
+
* @property {number} cursorPosition - Position du curseur
|
|
15
|
+
* @property {HTMLInputElement} hiddenInput - Input HTML caché
|
|
16
|
+
* @property {string} label - Label flottant (Material)
|
|
17
|
+
* @property {boolean} hasLabel - Si un label est défini
|
|
18
|
+
* @property {boolean} error - État d'erreur
|
|
19
|
+
* @property {string} errorText - Texte d'erreur
|
|
20
|
+
* @property {boolean} disabled - État désactivé
|
|
21
|
+
* @property {string} helperText - Texte d'aide
|
|
22
|
+
* @property {boolean} leadingIcon - Afficher une icône à gauche
|
|
23
|
+
* @property {boolean} trailingIcon - Afficher une icône à droite
|
|
24
|
+
* @property {string} backgroundColor - Couleur de fond personnalisée
|
|
25
|
+
* @property {string} borderColor - Couleur de bordure personnalisée
|
|
26
|
+
* @property {string} focusColor - Couleur au focus personnalisée
|
|
27
|
+
* @property {string} textColor - Couleur du texte personnalisée
|
|
28
|
+
* @property {string} placeholderColor - Couleur du placeholder personnalisée
|
|
29
|
+
*/
|
|
30
|
+
class Input extends Component {
|
|
31
|
+
static activeInput = null;
|
|
32
|
+
static allInputs = new Set();
|
|
33
|
+
static globalClickHandler = null;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Crée une instance de Input
|
|
37
|
+
* @param {CanvasFramework} framework - Framework parent
|
|
38
|
+
* @param {Object} [options={}] - Options de configuration
|
|
39
|
+
* @param {string} [options.placeholder=''] - Texte d'indication
|
|
40
|
+
* @param {string} [options.value=''] - Valeur initiale
|
|
41
|
+
* @param {string} [options.label=''] - Label flottant (Material)
|
|
42
|
+
* @param {number} [options.fontSize=16] - Taille de police
|
|
43
|
+
* @param {string} [options.variant='filled'] - Variante Material ('filled' ou 'outlined')
|
|
44
|
+
* @param {boolean} [options.error=false] - État d'erreur
|
|
45
|
+
* @param {string} [options.errorText=''] - Texte d'erreur
|
|
46
|
+
* @param {boolean} [options.disabled=false] - État désactivé
|
|
47
|
+
* @param {string} [options.helperText=''] - Texte d'aide
|
|
48
|
+
* @param {boolean} [options.leadingIcon=false] - Afficher une icône à gauche
|
|
49
|
+
* @param {boolean} [options.trailingIcon=false] - Afficher une icône à droite
|
|
50
|
+
* @param {string} [options.backgroundColor] - Couleur de fond personnalisée
|
|
51
|
+
* @param {string} [options.borderColor] - Couleur de bordure personnalisée
|
|
52
|
+
* @param {string} [options.focusColor] - Couleur au focus personnalisée
|
|
53
|
+
* @param {string} [options.textColor] - Couleur du texte personnalisée
|
|
54
|
+
* @param {string} [options.placeholderColor] - Couleur du placeholder personnalisée
|
|
55
|
+
* @param {string} [options.labelColor] - Couleur du label personnalisée
|
|
56
|
+
* @param {Function} [options.onFocus] - Callback au focus
|
|
57
|
+
* @param {Function} [options.onBlur] - Callback au blur
|
|
58
|
+
* @param {Function} [options.onChange] - Callback au changement
|
|
59
|
+
*/
|
|
60
|
+
constructor(framework, options = {}) {
|
|
61
|
+
super(framework, options);
|
|
62
|
+
this.placeholder = options.placeholder || '';
|
|
63
|
+
this.value = options.value || '';
|
|
64
|
+
this.label = options.label || '';
|
|
65
|
+
this.fontSize = options.fontSize || 16;
|
|
66
|
+
this.focused = false;
|
|
67
|
+
this.platform = framework.platform;
|
|
68
|
+
this.variant = options.variant || 'filled'; // 'filled' ou 'outlined'
|
|
69
|
+
this.cursorVisible = true;
|
|
70
|
+
this.cursorPosition = this.value.length;
|
|
71
|
+
this.error = options.error || false;
|
|
72
|
+
this.errorText = options.errorText || '';
|
|
73
|
+
this.disabled = options.disabled || false;
|
|
74
|
+
this.helperText = options.helperText || '';
|
|
75
|
+
this.hasLabel = !!this.label;
|
|
76
|
+
this.leadingIcon = options.leadingIcon || false;
|
|
77
|
+
this.trailingIcon = options.trailingIcon || false;
|
|
78
|
+
|
|
79
|
+
// Couleurs personnalisables
|
|
80
|
+
this.backgroundColor = options.backgroundColor || null;
|
|
81
|
+
this.borderColor = options.borderColor || null;
|
|
82
|
+
this.focusColor = options.focusColor || null;
|
|
83
|
+
this.textColor = options.textColor || null;
|
|
84
|
+
this.placeholderColor = options.placeholderColor || null;
|
|
85
|
+
this.labelColor = options.labelColor || null;
|
|
86
|
+
|
|
87
|
+
// Dimensions pour le padding
|
|
88
|
+
this.paddingLeft = this.leadingIcon ? 56 : 16;
|
|
89
|
+
this.paddingRight = this.trailingIcon ? 56 : 16;
|
|
90
|
+
|
|
91
|
+
// Couleurs Material Design 3 par défaut
|
|
92
|
+
this.m3Colors = {
|
|
93
|
+
primary: '#6750A4',
|
|
94
|
+
onSurface: '#1D1B20',
|
|
95
|
+
onSurfaceVariant: '#49454F',
|
|
96
|
+
surfaceVariant: '#E7E0EC',
|
|
97
|
+
surface: '#FEF7FF',
|
|
98
|
+
error: '#BA1A1A',
|
|
99
|
+
onError: '#FFFFFF',
|
|
100
|
+
outline: '#79747E',
|
|
101
|
+
outlineVariant: '#CAC4D0',
|
|
102
|
+
disabled: '#1D1B20' + '61', // 38% opacity
|
|
103
|
+
disabledContainer: '#E7E0EC' + '80',
|
|
104
|
+
// Valeurs par défaut si pas personnalisé
|
|
105
|
+
defaultBackground: '#F5F5F5', // Gris clair pour filled
|
|
106
|
+
defaultBorder: '#CCCCCC', // Gris pour bordure non focus
|
|
107
|
+
defaultFocus: '#1976D2' // Bleu Material par défaut
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Couleurs iOS Cupertino par défaut
|
|
111
|
+
this.cupertinoColors = {
|
|
112
|
+
blue: '#007AFF',
|
|
113
|
+
label: '#000000',
|
|
114
|
+
placeholder: '#999999',
|
|
115
|
+
background: '#FFFFFF',
|
|
116
|
+
border: '#C7C7CC',
|
|
117
|
+
error: '#FF3B30',
|
|
118
|
+
disabled: '#000000' + '4D' // 30% opacity
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Gestion du focus
|
|
122
|
+
this.onFocus = this.onFocus.bind(this);
|
|
123
|
+
this.onBlur = this.onBlur.bind(this);
|
|
124
|
+
this.onChange = options.onChange || (() => {});
|
|
125
|
+
|
|
126
|
+
// Enregistrer cet input
|
|
127
|
+
Input.allInputs.add(this);
|
|
128
|
+
|
|
129
|
+
// Animation du curseur
|
|
130
|
+
this.cursorInterval = setInterval(() => {
|
|
131
|
+
if (this.focused && !this.disabled) this.cursorVisible = !this.cursorVisible;
|
|
132
|
+
}, 500);
|
|
133
|
+
|
|
134
|
+
// Écouter les clics partout pour détecter quand on clique ailleurs
|
|
135
|
+
this.setupGlobalClickHandler();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Écoute les clics globaux pour détecter les clics hors input
|
|
140
|
+
*/
|
|
141
|
+
setupGlobalClickHandler() {
|
|
142
|
+
if (!Input.globalClickHandler) {
|
|
143
|
+
Input.globalClickHandler = (e) => {
|
|
144
|
+
let clickedOnInput = false;
|
|
145
|
+
|
|
146
|
+
for (let input of Input.allInputs) {
|
|
147
|
+
if (input.hiddenInput && e.target === input.hiddenInput) {
|
|
148
|
+
clickedOnInput = true;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!clickedOnInput) {
|
|
154
|
+
Input.removeAllHiddenInputs();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
document.addEventListener('click', Input.globalClickHandler, true);
|
|
159
|
+
document.addEventListener('touchstart', Input.globalClickHandler, true);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Configure l'input HTML caché
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
setupHiddenInput() {
|
|
168
|
+
if (this.hiddenInput) return;
|
|
169
|
+
|
|
170
|
+
this.hiddenInput = document.createElement('input');
|
|
171
|
+
this.hiddenInput.style.position = 'fixed';
|
|
172
|
+
this.hiddenInput.style.opacity = '0';
|
|
173
|
+
this.hiddenInput.style.pointerEvents = 'none';
|
|
174
|
+
this.hiddenInput.style.top = '-100px';
|
|
175
|
+
this.hiddenInput.style.zIndex = '9999';
|
|
176
|
+
document.body.appendChild(this.hiddenInput);
|
|
177
|
+
|
|
178
|
+
this.hiddenInput.addEventListener('input', (e) => {
|
|
179
|
+
if (this.focused && !this.disabled) {
|
|
180
|
+
const oldValue = this.value;
|
|
181
|
+
this.value = e.target.value;
|
|
182
|
+
this.cursorPosition = this.value.length;
|
|
183
|
+
if (oldValue !== this.value) {
|
|
184
|
+
this.onChange(this.value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
this.hiddenInput.addEventListener('blur', () => {
|
|
190
|
+
this.focused = false;
|
|
191
|
+
this.cursorVisible = false;
|
|
192
|
+
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
this.destroyHiddenInput();
|
|
195
|
+
}, 100);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Gérer les touches spéciales
|
|
199
|
+
this.hiddenInput.addEventListener('keydown', (e) => {
|
|
200
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
this.focused = false;
|
|
203
|
+
this.cursorVisible = false;
|
|
204
|
+
this.destroyHiddenInput();
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Gère le focus
|
|
211
|
+
*/
|
|
212
|
+
onFocus() {
|
|
213
|
+
if (this.disabled || Input.activeInput === this) return;
|
|
214
|
+
|
|
215
|
+
Input.removeAllHiddenInputs();
|
|
216
|
+
|
|
217
|
+
for (let input of Input.allInputs) {
|
|
218
|
+
if (input !== this) {
|
|
219
|
+
input.focused = false;
|
|
220
|
+
input.cursorVisible = false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this.focused = true;
|
|
225
|
+
this.cursorVisible = true;
|
|
226
|
+
Input.activeInput = this;
|
|
227
|
+
|
|
228
|
+
this.setupHiddenInput();
|
|
229
|
+
|
|
230
|
+
if (this.hiddenInput) {
|
|
231
|
+
this.hiddenInput.value = this.value;
|
|
232
|
+
this.hiddenInput.disabled = this.disabled;
|
|
233
|
+
const adjustedY = this.y + this.framework.scrollOffset;
|
|
234
|
+
this.hiddenInput.style.top = `${adjustedY}px`;
|
|
235
|
+
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
if (this.hiddenInput && this.focused) {
|
|
238
|
+
this.hiddenInput.focus();
|
|
239
|
+
this.hiddenInput.setSelectionRange(this.value.length, this.value.length);
|
|
240
|
+
}
|
|
241
|
+
}, 50);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Gère le blur
|
|
247
|
+
*/
|
|
248
|
+
onBlur() {
|
|
249
|
+
this.focused = false;
|
|
250
|
+
this.cursorVisible = false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Détruit l'input HTML
|
|
255
|
+
*/
|
|
256
|
+
destroyHiddenInput() {
|
|
257
|
+
if (this.hiddenInput && this.hiddenInput.parentNode) {
|
|
258
|
+
this.hiddenInput.parentNode.removeChild(this.hiddenInput);
|
|
259
|
+
this.hiddenInput = null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Gère le clic
|
|
265
|
+
*/
|
|
266
|
+
onClick() {
|
|
267
|
+
if (!this.disabled) {
|
|
268
|
+
this.onFocus();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Méthode statique pour détruire tous les inputs HTML
|
|
274
|
+
*/
|
|
275
|
+
static removeAllHiddenInputs() {
|
|
276
|
+
for (let input of Input.allInputs) {
|
|
277
|
+
input.focused = false;
|
|
278
|
+
input.cursorVisible = false;
|
|
279
|
+
|
|
280
|
+
if (input.hiddenInput && input.hiddenInput.parentNode) {
|
|
281
|
+
input.hiddenInput.parentNode.removeChild(input.hiddenInput);
|
|
282
|
+
input.hiddenInput = null;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
Input.activeInput = null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Vérifie si un point est dans les limites
|
|
291
|
+
*/
|
|
292
|
+
isPointInside(x, y) {
|
|
293
|
+
return x >= this.x &&
|
|
294
|
+
x <= this.x + this.width &&
|
|
295
|
+
y >= this.y &&
|
|
296
|
+
y <= this.y + this.height;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Obtient la couleur avec fallback
|
|
301
|
+
* @param {string} customColor - Couleur personnalisée
|
|
302
|
+
* @param {string} defaultColor - Couleur par défaut
|
|
303
|
+
* @returns {string} La couleur à utiliser
|
|
304
|
+
* @private
|
|
305
|
+
*/
|
|
306
|
+
getColor(customColor, defaultColor) {
|
|
307
|
+
return this.disabled ? this.m3Colors.disabled :
|
|
308
|
+
(customColor || defaultColor);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Obtient la couleur de focus
|
|
313
|
+
* @returns {string} La couleur au focus
|
|
314
|
+
* @private
|
|
315
|
+
*/
|
|
316
|
+
getFocusColor() {
|
|
317
|
+
if (this.disabled) return this.m3Colors.outlineVariant;
|
|
318
|
+
if (this.error && this.errorText) return this.m3Colors.error;
|
|
319
|
+
return this.focusColor || this.m3Colors.defaultFocus;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Obtient la couleur de bordure
|
|
324
|
+
* @returns {string} La couleur de bordure
|
|
325
|
+
* @private
|
|
326
|
+
*/
|
|
327
|
+
getBorderColor() {
|
|
328
|
+
if (this.disabled) return this.m3Colors.outlineVariant;
|
|
329
|
+
if (this.error && this.errorText) return this.m3Colors.error;
|
|
330
|
+
if (this.focused) return this.getFocusColor();
|
|
331
|
+
return this.borderColor || this.m3Colors.defaultBorder;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Obtient la couleur de fond
|
|
336
|
+
* @returns {string} La couleur de fond
|
|
337
|
+
* @private
|
|
338
|
+
*/
|
|
339
|
+
getBackgroundColor() {
|
|
340
|
+
if (this.disabled) return this.m3Colors.disabledContainer;
|
|
341
|
+
return this.backgroundColor || this.m3Colors.defaultBackground;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Obtient la couleur du texte
|
|
346
|
+
* @returns {string} La couleur du texte
|
|
347
|
+
* @private
|
|
348
|
+
*/
|
|
349
|
+
getTextColor() {
|
|
350
|
+
if (this.disabled) return this.m3Colors.disabled;
|
|
351
|
+
return this.textColor || this.m3Colors.onSurface;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Obtient la couleur du placeholder
|
|
356
|
+
* @returns {string} La couleur du placeholder
|
|
357
|
+
* @private
|
|
358
|
+
*/
|
|
359
|
+
getPlaceholderColor() {
|
|
360
|
+
if (this.disabled) return this.m3Colors.disabled;
|
|
361
|
+
return this.placeholderColor || this.m3Colors.onSurfaceVariant;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Obtient la couleur du label
|
|
366
|
+
* @returns {string} La couleur du label
|
|
367
|
+
* @private
|
|
368
|
+
*/
|
|
369
|
+
getLabelColor() {
|
|
370
|
+
if (this.disabled) return this.m3Colors.disabled;
|
|
371
|
+
if (this.error && this.errorText) return this.m3Colors.error;
|
|
372
|
+
if (this.focused) return this.getFocusColor();
|
|
373
|
+
return this.labelColor || this.m3Colors.onSurfaceVariant;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Dessine l'icône Material
|
|
378
|
+
* @param {CanvasRenderingContext2D} ctx - Contexte de dessin
|
|
379
|
+
* @param {string} type - Type d'icône ('leading' ou 'trailing')
|
|
380
|
+
* @private
|
|
381
|
+
*/
|
|
382
|
+
drawMaterialIcon(ctx, type) {
|
|
383
|
+
const isError = this.error && this.errorText;
|
|
384
|
+
|
|
385
|
+
ctx.save();
|
|
386
|
+
ctx.strokeStyle = this.disabled ? this.m3Colors.disabled :
|
|
387
|
+
isError ? this.m3Colors.error :
|
|
388
|
+
this.focused ? this.getFocusColor() : this.m3Colors.onSurfaceVariant;
|
|
389
|
+
ctx.lineWidth = 2;
|
|
390
|
+
ctx.lineCap = 'round';
|
|
391
|
+
|
|
392
|
+
// Position de l'icône
|
|
393
|
+
const iconSize = 24;
|
|
394
|
+
const iconX = type === 'leading' ?
|
|
395
|
+
this.x + 16 : this.x + this.width - 40;
|
|
396
|
+
const iconY = this.y + this.height / 2 - iconSize / 2;
|
|
397
|
+
|
|
398
|
+
// Dessiner une icône simple
|
|
399
|
+
ctx.beginPath();
|
|
400
|
+
if (type === 'leading') {
|
|
401
|
+
// Icône de recherche (loupe)
|
|
402
|
+
ctx.arc(iconX + 12, iconY + 12, 8, 0, Math.PI * 2);
|
|
403
|
+
ctx.moveTo(iconX + 18, iconY + 18);
|
|
404
|
+
ctx.lineTo(iconX + 22, iconY + 22);
|
|
405
|
+
} else {
|
|
406
|
+
// Icône d'erreur ou clear
|
|
407
|
+
if (this.error) {
|
|
408
|
+
// Point d'exclamation dans un cercle
|
|
409
|
+
ctx.arc(iconX + 12, iconY + 12, 10, 0, Math.PI * 2);
|
|
410
|
+
ctx.stroke();
|
|
411
|
+
ctx.fillStyle = this.m3Colors.error;
|
|
412
|
+
ctx.fill();
|
|
413
|
+
ctx.fillStyle = this.m3Colors.onError;
|
|
414
|
+
ctx.fillRect(iconX + 11, iconY + 6, 2, 8);
|
|
415
|
+
ctx.fillRect(iconX + 11, iconY + 16, 2, 2);
|
|
416
|
+
ctx.restore();
|
|
417
|
+
return;
|
|
418
|
+
} else {
|
|
419
|
+
// Croix simple (clear)
|
|
420
|
+
ctx.moveTo(iconX + 8, iconY + 8);
|
|
421
|
+
ctx.lineTo(iconX + 16, iconY + 16);
|
|
422
|
+
ctx.moveTo(iconX + 16, iconY + 8);
|
|
423
|
+
ctx.lineTo(iconX + 8, iconY + 16);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
ctx.stroke();
|
|
428
|
+
ctx.restore();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Dessine l'input Material Design 3 - Filled avec bordure en bas
|
|
433
|
+
* @param {CanvasRenderingContext2D} ctx - Contexte de dessin
|
|
434
|
+
* @private
|
|
435
|
+
*/
|
|
436
|
+
drawMaterialFilledInput(ctx) {
|
|
437
|
+
const isActive = this.focused || this.value.length > 0;
|
|
438
|
+
const showError = this.error && this.errorText;
|
|
439
|
+
|
|
440
|
+
// Container avec fond personnalisable
|
|
441
|
+
ctx.fillStyle = this.getBackgroundColor();
|
|
442
|
+
ctx.beginPath();
|
|
443
|
+
// Coins arrondis seulement en haut
|
|
444
|
+
ctx.moveTo(this.x + 12, this.y);
|
|
445
|
+
ctx.lineTo(this.x + this.width - 12, this.y);
|
|
446
|
+
ctx.quadraticCurveTo(this.x + this.width, this.y, this.x + this.width, this.y + 12);
|
|
447
|
+
ctx.lineTo(this.x + this.width, this.y + this.height);
|
|
448
|
+
ctx.lineTo(this.x, this.y + this.height);
|
|
449
|
+
ctx.lineTo(this.x, this.y + 12);
|
|
450
|
+
ctx.quadraticCurveTo(this.x, this.y, this.x + 12, this.y);
|
|
451
|
+
ctx.closePath();
|
|
452
|
+
ctx.fill();
|
|
453
|
+
|
|
454
|
+
// Bordure inférieure - toujours visible
|
|
455
|
+
const borderHeight = 1;
|
|
456
|
+
const focusBorderHeight = 2;
|
|
457
|
+
|
|
458
|
+
// Bordure normale (gris par défaut)
|
|
459
|
+
ctx.fillStyle = this.getBorderColor();
|
|
460
|
+
|
|
461
|
+
if (this.focused || showError) {
|
|
462
|
+
// Bordure épaisse au focus/erreur
|
|
463
|
+
ctx.fillRect(this.x, this.y + this.height - focusBorderHeight,
|
|
464
|
+
this.width, focusBorderHeight);
|
|
465
|
+
} else {
|
|
466
|
+
// Bordure fine normale
|
|
467
|
+
ctx.fillRect(this.x, this.y + this.height - borderHeight,
|
|
468
|
+
this.width, borderHeight);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Icône leading
|
|
472
|
+
if (this.leadingIcon) {
|
|
473
|
+
this.drawMaterialIcon(ctx, 'leading');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Icône trailing
|
|
477
|
+
if (this.trailingIcon) {
|
|
478
|
+
this.drawMaterialIcon(ctx, 'trailing');
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Label flottant
|
|
482
|
+
if (this.hasLabel) {
|
|
483
|
+
ctx.fillStyle = this.getLabelColor();
|
|
484
|
+
ctx.font = `${isActive ? 12 : this.fontSize}px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
485
|
+
|
|
486
|
+
const labelX = this.x + this.paddingLeft;
|
|
487
|
+
const labelY = this.focused || this.value.length > 0 ?
|
|
488
|
+
this.y + 12 : this.y + this.height / 2;
|
|
489
|
+
|
|
490
|
+
ctx.fillText(this.label, labelX, labelY);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Texte de saisie
|
|
494
|
+
if (this.value || (!this.hasLabel && !this.focused)) {
|
|
495
|
+
const displayText = this.value || this.placeholder;
|
|
496
|
+
ctx.fillStyle = this.value ? this.getTextColor() : this.getPlaceholderColor();
|
|
497
|
+
ctx.font = `${this.fontSize}px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
498
|
+
ctx.textAlign = 'left';
|
|
499
|
+
ctx.textBaseline = 'middle';
|
|
500
|
+
|
|
501
|
+
const textX = this.x + this.paddingLeft;
|
|
502
|
+
const textY = this.hasLabel && (this.focused || this.value.length > 0) ?
|
|
503
|
+
this.y + this.height / 2 + 8 : this.y + this.height / 2;
|
|
504
|
+
|
|
505
|
+
// Troncature du texte
|
|
506
|
+
const maxWidth = this.width - this.paddingLeft - this.paddingRight;
|
|
507
|
+
let displayTextAdjusted = displayText;
|
|
508
|
+
let textWidth = ctx.measureText(displayText).width;
|
|
509
|
+
|
|
510
|
+
if (textWidth > maxWidth) {
|
|
511
|
+
while (textWidth > maxWidth && displayTextAdjusted.length > 0) {
|
|
512
|
+
displayTextAdjusted = displayTextAdjusted.slice(0, -1);
|
|
513
|
+
textWidth = ctx.measureText(displayTextAdjusted + '...').width;
|
|
514
|
+
}
|
|
515
|
+
displayTextAdjusted += '...';
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
ctx.fillText(displayTextAdjusted, textX, textY);
|
|
519
|
+
|
|
520
|
+
// Curseur
|
|
521
|
+
if (this.focused && this.cursorVisible && this.value) {
|
|
522
|
+
ctx.fillStyle = this.getFocusColor();
|
|
523
|
+
ctx.fillRect(textX + textWidth, textY - 12, 2, 24);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Texte d'aide ou d'erreur
|
|
528
|
+
if (showError || this.helperText) {
|
|
529
|
+
const helpText = showError ? this.errorText : this.helperText;
|
|
530
|
+
ctx.fillStyle = showError ? this.m3Colors.error : this.m3Colors.onSurfaceVariant;
|
|
531
|
+
ctx.font = `12px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
532
|
+
ctx.textAlign = 'left';
|
|
533
|
+
ctx.textBaseline = 'top';
|
|
534
|
+
ctx.fillText(helpText, this.x + this.paddingLeft, this.y + this.height + 4);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Dessine l'input Material Design 3 - Outlined
|
|
540
|
+
* @param {CanvasRenderingContext2D} ctx - Contexte de dessin
|
|
541
|
+
* @private
|
|
542
|
+
*/
|
|
543
|
+
drawMaterialOutlinedInput(ctx) {
|
|
544
|
+
const isActive = this.focused || this.value.length > 0;
|
|
545
|
+
const showError = this.error && this.errorText;
|
|
546
|
+
|
|
547
|
+
// Background personnalisable
|
|
548
|
+
ctx.fillStyle = this.getBackgroundColor();
|
|
549
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, 4);
|
|
550
|
+
ctx.fill();
|
|
551
|
+
|
|
552
|
+
// Bordure avec épaisseur variable
|
|
553
|
+
ctx.strokeStyle = this.getBorderColor();
|
|
554
|
+
ctx.lineWidth = this.focused ? 2 : 1;
|
|
555
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, 4);
|
|
556
|
+
ctx.stroke();
|
|
557
|
+
|
|
558
|
+
// Fond pour le label (pour qu'il apparaisse au-dessus de la bordure)
|
|
559
|
+
if (this.hasLabel && (this.focused || this.value.length > 0)) {
|
|
560
|
+
ctx.fillStyle = this.getBackgroundColor();
|
|
561
|
+
ctx.fillRect(this.x + 12, this.y - 6, ctx.measureText(this.label).width + 8, 12);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Icône leading
|
|
565
|
+
if (this.leadingIcon) {
|
|
566
|
+
this.drawMaterialIcon(ctx, 'leading');
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Icône trailing
|
|
570
|
+
if (this.trailingIcon) {
|
|
571
|
+
this.drawMaterialIcon(ctx, 'trailing');
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Label flottant
|
|
575
|
+
if (this.hasLabel) {
|
|
576
|
+
ctx.fillStyle = this.getLabelColor();
|
|
577
|
+
ctx.font = `${isActive ? 12 : this.fontSize}px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
578
|
+
|
|
579
|
+
const labelX = this.x + this.paddingLeft;
|
|
580
|
+
const labelY = this.focused || this.value.length > 0 ?
|
|
581
|
+
this.y - 2 : this.y + this.height / 2;
|
|
582
|
+
|
|
583
|
+
ctx.fillText(this.label, labelX, labelY);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Texte de saisie
|
|
587
|
+
if (this.value || (!this.hasLabel && !this.focused)) {
|
|
588
|
+
const displayText = this.value || this.placeholder;
|
|
589
|
+
ctx.fillStyle = this.value ? this.getTextColor() : this.getPlaceholderColor();
|
|
590
|
+
ctx.font = `${this.fontSize}px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
591
|
+
ctx.textAlign = 'left';
|
|
592
|
+
ctx.textBaseline = 'middle';
|
|
593
|
+
|
|
594
|
+
const textX = this.x + this.paddingLeft;
|
|
595
|
+
const textY = this.y + this.height / 2;
|
|
596
|
+
|
|
597
|
+
// Troncature du texte
|
|
598
|
+
const maxWidth = this.width - this.paddingLeft - this.paddingRight;
|
|
599
|
+
let displayTextAdjusted = displayText;
|
|
600
|
+
let textWidth = ctx.measureText(displayText).width;
|
|
601
|
+
|
|
602
|
+
if (textWidth > maxWidth) {
|
|
603
|
+
while (textWidth > maxWidth && displayTextAdjusted.length > 0) {
|
|
604
|
+
displayTextAdjusted = displayTextAdjusted.slice(0, -1);
|
|
605
|
+
textWidth = ctx.measureText(displayTextAdjusted + '...').width;
|
|
606
|
+
}
|
|
607
|
+
displayTextAdjusted += '...';
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
ctx.fillText(displayTextAdjusted, textX, textY);
|
|
611
|
+
|
|
612
|
+
// Curseur
|
|
613
|
+
if (this.focused && this.cursorVisible && this.value) {
|
|
614
|
+
ctx.fillStyle = this.getFocusColor();
|
|
615
|
+
ctx.fillRect(textX + textWidth, textY - 12, 2, 24);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Texte d'aide ou d'erreur
|
|
620
|
+
if (showError || this.helperText) {
|
|
621
|
+
const helpText = showError ? this.errorText : this.helperText;
|
|
622
|
+
ctx.fillStyle = showError ? this.m3Colors.error : this.m3Colors.onSurfaceVariant;
|
|
623
|
+
ctx.font = `12px 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
624
|
+
ctx.textAlign = 'left';
|
|
625
|
+
ctx.textBaseline = 'top';
|
|
626
|
+
ctx.fillText(helpText, this.x + this.paddingLeft, this.y + this.height + 4);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Dessine l'input iOS Cupertino
|
|
632
|
+
* @param {CanvasRenderingContext2D} ctx - Contexte de dessin
|
|
633
|
+
* @private
|
|
634
|
+
*/
|
|
635
|
+
drawCupertinoInput(ctx) {
|
|
636
|
+
const showError = this.error && this.errorText;
|
|
637
|
+
|
|
638
|
+
// Background personnalisable
|
|
639
|
+
ctx.fillStyle = this.backgroundColor || this.cupertinoColors.background;
|
|
640
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, 10);
|
|
641
|
+
ctx.fill();
|
|
642
|
+
|
|
643
|
+
// Bordure
|
|
644
|
+
ctx.strokeStyle = this.disabled ? this.cupertinoColors.border + '80' :
|
|
645
|
+
showError ? this.cupertinoColors.error :
|
|
646
|
+
this.focused ? (this.focusColor || this.cupertinoColors.blue) :
|
|
647
|
+
(this.borderColor || this.cupertinoColors.border);
|
|
648
|
+
ctx.lineWidth = this.focused ? 2 : 1;
|
|
649
|
+
this.roundRect(ctx, this.x, this.y, this.width, this.height, 10);
|
|
650
|
+
ctx.stroke();
|
|
651
|
+
|
|
652
|
+
// Texte
|
|
653
|
+
if (this.value || this.placeholder) {
|
|
654
|
+
const displayText = this.value || this.placeholder;
|
|
655
|
+
ctx.fillStyle = this.disabled ? this.cupertinoColors.disabled :
|
|
656
|
+
this.value ? (this.textColor || this.cupertinoColors.label) :
|
|
657
|
+
(this.placeholderColor || this.cupertinoColors.placeholder);
|
|
658
|
+
ctx.font = `${this.fontSize}px -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
659
|
+
ctx.textAlign = 'left';
|
|
660
|
+
ctx.textBaseline = 'middle';
|
|
661
|
+
|
|
662
|
+
// Calculer la largeur maximale disponible
|
|
663
|
+
const maxWidth = this.width - 32;
|
|
664
|
+
let displayTextAdjusted = displayText;
|
|
665
|
+
let textWidth = ctx.measureText(displayText).width;
|
|
666
|
+
|
|
667
|
+
// Tronquer le texte si nécessaire
|
|
668
|
+
if (textWidth > maxWidth) {
|
|
669
|
+
while (textWidth > maxWidth && displayTextAdjusted.length > 0) {
|
|
670
|
+
displayTextAdjusted = displayTextAdjusted.slice(0, -1);
|
|
671
|
+
textWidth = ctx.measureText(displayTextAdjusted + '...').width;
|
|
672
|
+
}
|
|
673
|
+
displayTextAdjusted += '...';
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
ctx.fillText(displayTextAdjusted, this.x + 16, this.y + this.height / 2);
|
|
677
|
+
|
|
678
|
+
// Curseur
|
|
679
|
+
if (this.focused && this.cursorVisible && this.value) {
|
|
680
|
+
ctx.fillStyle = this.focusColor || this.cupertinoColors.blue;
|
|
681
|
+
ctx.fillRect(this.x + 16 + textWidth, this.y + 10, 2, this.height - 20);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Texte d'erreur
|
|
686
|
+
if (showError) {
|
|
687
|
+
ctx.fillStyle = this.cupertinoColors.error;
|
|
688
|
+
ctx.font = `13px -apple-system, BlinkMacSystemFont, sans-serif`;
|
|
689
|
+
ctx.textAlign = 'left';
|
|
690
|
+
ctx.textBaseline = 'top';
|
|
691
|
+
ctx.fillText(this.errorText, this.x + 16, this.y + this.height + 4);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Dessine l'input
|
|
697
|
+
* @param {CanvasRenderingContext2D} ctx - Contexte de dessin
|
|
698
|
+
*/
|
|
699
|
+
draw(ctx) {
|
|
700
|
+
ctx.save();
|
|
701
|
+
|
|
702
|
+
if (this.platform === 'material') {
|
|
703
|
+
if (this.variant === 'outlined') {
|
|
704
|
+
this.drawMaterialOutlinedInput(ctx);
|
|
705
|
+
} else {
|
|
706
|
+
this.drawMaterialFilledInput(ctx);
|
|
707
|
+
}
|
|
708
|
+
} else {
|
|
709
|
+
this.drawCupertinoInput(ctx);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
ctx.restore();
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Dessine un rectangle avec coins arrondis
|
|
717
|
+
*/
|
|
718
|
+
roundRect(ctx, x, y, width, height, radius) {
|
|
719
|
+
ctx.beginPath();
|
|
720
|
+
ctx.moveTo(x + radius, y);
|
|
721
|
+
ctx.lineTo(x + width - radius, y);
|
|
722
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
|
723
|
+
ctx.lineTo(x + width, y + height - radius);
|
|
724
|
+
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
|
725
|
+
ctx.lineTo(x + radius, y + height);
|
|
726
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
|
727
|
+
ctx.lineTo(x, y + radius);
|
|
728
|
+
ctx.quadraticCurveTo(x, y, x + radius, y);
|
|
729
|
+
ctx.closePath();
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Met à jour la valeur
|
|
734
|
+
* @param {string} newValue - Nouvelle valeur
|
|
735
|
+
*/
|
|
736
|
+
setValue(newValue) {
|
|
737
|
+
const oldValue = this.value;
|
|
738
|
+
this.value = newValue;
|
|
739
|
+
this.cursorPosition = this.value.length;
|
|
740
|
+
|
|
741
|
+
if (oldValue !== newValue) {
|
|
742
|
+
this.onChange(newValue);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* Change la variante Material
|
|
748
|
+
* @param {string} variant - 'filled' ou 'outlined'
|
|
749
|
+
*/
|
|
750
|
+
setVariant(variant) {
|
|
751
|
+
if (variant === 'filled' || variant === 'outlined') {
|
|
752
|
+
this.variant = variant;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Définit les couleurs personnalisées
|
|
758
|
+
* @param {Object} colors - Objet contenant les couleurs
|
|
759
|
+
* @param {string} [colors.backgroundColor] - Couleur de fond
|
|
760
|
+
* @param {string} [colors.borderColor] - Couleur de bordure
|
|
761
|
+
* @param {string} [colors.focusColor] - Couleur au focus
|
|
762
|
+
* @param {string} [colors.textColor] - Couleur du texte
|
|
763
|
+
* @param {string} [colors.placeholderColor] - Couleur du placeholder
|
|
764
|
+
* @param {string} [colors.labelColor] - Couleur du label
|
|
765
|
+
*/
|
|
766
|
+
setColors(colors) {
|
|
767
|
+
if (colors.backgroundColor !== undefined) this.backgroundColor = colors.backgroundColor;
|
|
768
|
+
if (colors.borderColor !== undefined) this.borderColor = colors.borderColor;
|
|
769
|
+
if (colors.focusColor !== undefined) this.focusColor = colors.focusColor;
|
|
770
|
+
if (colors.textColor !== undefined) this.textColor = colors.textColor;
|
|
771
|
+
if (colors.placeholderColor !== undefined) this.placeholderColor = colors.placeholderColor;
|
|
772
|
+
if (colors.labelColor !== undefined) this.labelColor = colors.labelColor;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Active/désactive l'état d'erreur
|
|
777
|
+
* @param {boolean} error - État d'erreur
|
|
778
|
+
* @param {string} errorText - Texte d'erreur
|
|
779
|
+
*/
|
|
780
|
+
setError(error, errorText = '') {
|
|
781
|
+
this.error = error;
|
|
782
|
+
this.errorText = errorText;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Active/désactive l'état désactivé
|
|
787
|
+
* @param {boolean} disabled - État désactivé
|
|
788
|
+
*/
|
|
789
|
+
setDisabled(disabled) {
|
|
790
|
+
this.disabled = disabled;
|
|
791
|
+
if (disabled && this.focused) {
|
|
792
|
+
this.onBlur();
|
|
793
|
+
this.destroyHiddenInput();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Configure les icônes
|
|
799
|
+
* @param {boolean} leading - Afficher l'icône à gauche
|
|
800
|
+
* @param {boolean} trailing - Afficher l'icône à droite
|
|
801
|
+
*/
|
|
802
|
+
setIcons(leading, trailing) {
|
|
803
|
+
this.leadingIcon = leading;
|
|
804
|
+
this.trailingIcon = trailing;
|
|
805
|
+
this.paddingLeft = leading ? 56 : 16;
|
|
806
|
+
this.paddingRight = trailing ? 56 : 16;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Nettoie les ressources
|
|
811
|
+
*/
|
|
812
|
+
destroy() {
|
|
813
|
+
this.destroyHiddenInput();
|
|
814
|
+
|
|
815
|
+
if (this.cursorInterval) {
|
|
816
|
+
clearInterval(this.cursorInterval);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
Input.allInputs.delete(this);
|
|
820
|
+
|
|
821
|
+
if (Input.allInputs.size === 0 && Input.globalClickHandler) {
|
|
822
|
+
document.removeEventListener('click', Input.globalClickHandler, true);
|
|
823
|
+
document.removeEventListener('touchstart', Input.globalClickHandler, true);
|
|
824
|
+
Input.globalClickHandler = null;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
super.destroy && super.destroy();
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
export default Input;
|