1
- import keyHandlers from './keyHandlers' ;
2
1
import key from './key' ;
3
- import helpers from './helpers' ;
2
+ import * as helpers from './helpers' ;
4
3
import { getActionType , getHandlerForAction } from './actions' ;
5
4
import ValueHistory from './valueHistory' ;
6
- import { ACTION_TYPES , DRAG_STATES , RANGE } from './constants' ;
5
+ import { ActionType , DragState , Range } from './constants' ;
7
6
8
- /**
9
- * CONSTANTS
10
- */
11
7
const DEFAULTS = {
12
8
scale : 2 ,
13
- range : RANGE . ALL ,
9
+ range : Range . ALL ,
14
10
fixed : true ,
15
11
thousands : ',' ,
16
12
decimal : '.' ,
@@ -22,27 +18,15 @@ const DEFAULTS = {
22
18
invalidKeyCallback : ( ) => { }
23
19
} ;
24
20
25
- /**
26
- * FINPUT COMPONENT CLASS
27
- * @class
28
- */
21
+ type FinputElement = HTMLInputElement & { rawValue : number } ;
22
+
29
23
class Finput {
24
+ private readonly _element : FinputElement ;
25
+ private _options : any ;
26
+ private readonly _history : ValueHistory ;
27
+ private readonly _listeners : { [ key : string ] : { element : HTMLInputElement | Document , handler : EventListenerObject } } ;
28
+ private _dragState : DragState ;
30
29
31
- /**
32
- * Constructor
33
- * @param {DOM Element } The number input
34
- * @param {Options } Options for the number input's behaviour
35
- *
36
- * Detailed list of possible options:
37
- * @param {Options.scale } maximum number of decimal digits
38
- * @param {Options.range } Whether number can take any value or must be positive
39
- * @param {Options.fixed } After focus is lost - value is formatted to *scale* number of decimal places
40
- * @param {Options.thousands } Character to use for the thousands separator
41
- * @param {Options.decimal } Character to use for the decimal point
42
- * @param {Options.shortcuts } Object map of shortcut characters to multiplier (e.g. { k: 1000 })
43
- * @param {Options.invalidKeyCallback } Function callback that will be called on an invalid keypress
44
- * @param {Options.onFocusinCallback } Function callback that will be called via the onFocusin event
45
- */
46
30
constructor ( element , options ) {
47
31
this . _element = element ;
48
32
this . _options = {
@@ -88,20 +72,10 @@ class Finput {
88
72
} ;
89
73
}
90
74
91
- /**
92
- * Get numerical value of the given value
93
- * @param {value } Value to convert
94
- */
95
75
getRawValue ( value ) {
96
76
return helpers . formattedToRaw ( value , this . options ) ;
97
77
}
98
78
99
-
100
- /**
101
- * Sets the value, fully formatted, for the input
102
- * @param {val } New value to set
103
- * @param {notNull } When true, restricts setting the value if it is null.
104
- */
105
79
setValue ( val , notNull ) {
106
80
const newValue = helpers . fullFormat ( val , this . options ) ;
107
81
@@ -112,12 +86,8 @@ class Finput {
112
86
}
113
87
}
114
88
115
- /**
116
- * Sets and formats the value for the input
117
- * @param {val } New value to set
118
- */
119
- setRawValue ( val ) {
120
- let value ;
89
+ setRawValue ( val : any ) {
90
+ let value : string ;
121
91
if ( ! val ) {
122
92
value = '' ;
123
93
} else if ( typeof val === 'number' && ! isNaN ( val ) ) {
@@ -132,23 +102,10 @@ class Finput {
132
102
this . setValue ( newValue , false ) ;
133
103
}
134
104
135
- //
136
- // EVENT HANDLERS
137
- //
138
-
139
- /**
140
- * On focusing OUT of the input - format fully
141
- * @param {e } Focus event
142
- */
143
- onFocusout ( e ) {
144
- this . setValue ( this . element . value ) ;
105
+ onFocusout ( ) {
106
+ this . setValue ( this . element . value , false ) ;
145
107
}
146
108
147
- /**
148
- * On focusing IN of the input
149
- * DEFAULT: Select all text
150
- * @param {e } Focus event
151
- */
152
109
onFocusin ( e ) {
153
110
if ( this . options . onFocusinCallback ) {
154
111
let selection = this . options . onFocusinCallback ( e ) ;
@@ -163,17 +120,12 @@ class Finput {
163
120
}
164
121
}
165
122
166
- /**
167
- * On dropping something into the input - replace the WHOLE value
168
- * with this new value
169
- * @param {e } Drag event
170
- */
171
123
onDrop ( e ) {
172
124
switch ( this . _dragState ) {
173
- case DRAG_STATES . INTERNAL :
125
+ case DragState . INTERNAL :
174
126
// This case is handled by the 'onInput' function
175
127
break ;
176
- case DRAG_STATES . EXTERNAL :
128
+ case DragState . EXTERNAL :
177
129
const val = helpers . parseString ( e . dataTransfer . getData ( 'text' ) , this . options ) ;
178
130
this . setValue ( val , true ) ;
179
131
e . preventDefault ( ) ;
@@ -184,41 +136,25 @@ class Finput {
184
136
}
185
137
}
186
138
187
- /**
188
- * On start of ANY drag on page
189
- * @param {e } Drag event
190
- */
191
139
onDragstart ( e ) {
192
140
this . _dragState = ( e . target === this . element )
193
- ? DRAG_STATES . INTERNAL
194
- : DRAG_STATES . EXTERNAL ;
141
+ ? DragState . INTERNAL
142
+ : DragState . EXTERNAL ;
195
143
}
196
144
197
- /**
198
- * On end of ANY drag on page
199
- * @param {e } Drag event
200
- */
201
145
onDragend ( e ) {
202
- this . _dragState = DRAG_STATES . NONE ;
146
+ this . _dragState = DragState . NONE ;
203
147
}
204
148
205
- /**
206
- * On pasting something into the input
207
- * @param {e } Clipboard event
208
- */
209
- onPaste ( e ) {
149
+ onPaste ( e : ClipboardEvent ) {
210
150
// paste uses a DragEvent on IE and clipboard data is stored on the window
211
- const clipboardData = e . clipboardData || window . clipboardData ;
151
+ const clipboardData = e . clipboardData || ( window as any ) . clipboardData ;
212
152
const val = helpers . parseString ( clipboardData . getData ( 'text' ) , this . options ) ;
213
153
this . setValue ( val , true ) ;
214
154
e . preventDefault ( ) ;
215
155
}
216
156
217
- /**
218
- * On pressing any key inside the input
219
- * @param {e } Keyboard event
220
- */
221
- onKeydown ( e ) {
157
+ onKeydown ( e : KeyboardEvent ) {
222
158
const currentState = {
223
159
caretStart : this . element . selectionStart ,
224
160
caretEnd : this . element . selectionEnd ,
@@ -230,17 +166,17 @@ class Finput {
230
166
modifierKeys : key . getPressedModifiers ( e )
231
167
} ;
232
168
233
- const actionType = getActionType ( keyInfo , this . options ) ;
169
+ const actionType = getActionType ( keyInfo as any , this . options ) ;
234
170
const handler = getHandlerForAction ( actionType ) ;
235
171
const newState = handler ( currentState , keyInfo , this . options , this . _history ) ;
236
172
237
173
if ( ! newState . valid ) {
238
- this . options . invalidKeyCallback ( e ) ;
174
+ this . options . invalidKeyCallback ( ) ;
239
175
e . preventDefault ( ) ;
240
176
return ;
241
177
}
242
178
243
- const shouldHandleValue = actionType !== ACTION_TYPES . UNKNOWN ;
179
+ const shouldHandleValue = actionType !== ActionType . UNKNOWN ;
244
180
if ( ! shouldHandleValue ) {
245
181
return ;
246
182
}
@@ -262,31 +198,23 @@ class Finput {
262
198
const newCaretPos = newState . caretStart + offset ;
263
199
this . element . setSelectionRange ( newCaretPos , newCaretPos ) ;
264
200
265
- const shouldRecord = actionType !== ACTION_TYPES . UNDO && actionType !== ACTION_TYPES . REDO ;
201
+ const shouldRecord = actionType !== ActionType . UNDO && actionType !== ActionType . REDO ;
266
202
if ( shouldRecord ) {
267
203
this . _history . addValue ( valueWithThousandsDelimiter ) ;
268
204
}
269
205
}
270
206
271
- /**
272
- * Backup event if input changes for any other reason, just format value
273
- * @param {e } Event
274
- */
275
- onInput ( e ) {
276
- this . setValue ( this . element . value ) ;
207
+ onInput ( ) {
208
+ this . setValue ( this . element . value , false ) ;
277
209
}
278
210
279
- /**
280
- * Removes all listeners from the input
281
- */
282
211
removeListeners ( ) {
283
212
for ( let e in this . _listeners ) {
284
213
this . _listeners [ e ] . element . removeEventListener ( e , this . _listeners [ e ] . handler ) ;
285
214
}
286
215
}
287
216
}
288
217
289
- // Factory function
290
218
export default function ( element , options ) {
291
219
292
220
if ( ! element ) {
@@ -295,7 +223,7 @@ export default function(element, options) {
295
223
296
224
const input = new Finput ( element , options || { } ) ;
297
225
element . setRawValue = ( v ) => input . setRawValue ( v ) ;
298
- element . setValue = ( v ) => input . setValue ( v ) ;
226
+ element . setValue = ( v ) => input . setValue ( v , false ) ;
299
227
element . getOptions = ( ) => input . options ;
300
228
element . setOptions = ( o ) => input . options = o ;
301
229
0 commit comments