1
1
'use strict' ;
2
2
3
3
const React = require ( 'react' ) ;
4
+ const inputSize = require ( './utils' ) . inputSize ;
4
5
5
6
/**
6
7
* The editing class constant.
@@ -17,6 +18,16 @@ const DUPLICATE = 'duplicate';
17
18
*/
18
19
const KEY_CLASS = 'editable-key' ;
19
20
21
+ /**
22
+ * Escape key code.
23
+ */
24
+ const ESC = 27 ;
25
+
26
+ /**
27
+ * Colon key code.
28
+ */
29
+ const COLON = 186 ;
30
+
20
31
/**
21
32
* General editable key component.
22
33
*/
@@ -38,15 +49,8 @@ class EditableKey extends React.Component {
38
49
* to the value field.
39
50
*/
40
51
componentDidMount ( ) {
41
- if ( this . element . isAdded ( ) ) {
42
- if ( this . props . insertIndex ) {
43
- // Focus for inserting new documents.
44
- if ( this . props . insertIndex === 1 && this . element . currentKey === '' ) {
45
- this . _node . focus ( ) ;
46
- }
47
- } else if ( ! this . isEditable ( ) && this . _node ) {
48
- this . _node . focus ( ) ;
49
- }
52
+ if ( this . isAutoFocusable ( ) ) {
53
+ this . _node . focus ( ) ;
50
54
}
51
55
}
52
56
@@ -61,16 +65,25 @@ class EditableKey extends React.Component {
61
65
type = 'text'
62
66
className = { this . style ( ) }
63
67
ref = { ( c ) => this . _node = c }
64
- size = { this . element . currentKey . length }
68
+ size = { inputSize ( this . renderValue ( ) ) }
69
+ tabIndex = { this . isEditable ( ) ? 0 : - 1 }
65
70
onBlur = { this . handleBlur . bind ( this ) }
66
71
onFocus = { this . handleFocus . bind ( this ) }
67
72
onChange = { this . handleChange . bind ( this ) }
68
73
onKeyDown = { this . handleKeyDown . bind ( this ) }
69
- value = { this . element . currentKey }
74
+ onKeyUp = { this . handleKeyUp . bind ( this ) }
75
+ value = { this . renderValue ( ) }
70
76
title = { this . renderTitle ( ) } />
71
77
) ;
72
78
}
73
79
80
+ /**
81
+ * Render the value of the key.
82
+ */
83
+ renderValue ( ) {
84
+ return this . element . parent . currentType === 'Array' ? this . props . index : this . element . currentKey ;
85
+ }
86
+
74
87
/**
75
88
* Render the title.
76
89
*
@@ -88,8 +101,27 @@ class EditableKey extends React.Component {
88
101
* @param {Event } evt - The event.
89
102
*/
90
103
handleKeyDown ( evt ) {
91
- if ( evt . keyCode === 27 ) {
92
- this . _node . blur ( ) ;
104
+ var value = evt . target . value ;
105
+ if ( evt . keyCode === ESC ) {
106
+ if ( value . length === 0 ) {
107
+ this . element . remove ( ) ;
108
+ } else {
109
+ this . _node . blur ( ) ;
110
+ }
111
+ }
112
+ }
113
+
114
+ /**
115
+ * If they key is a colon, tab to the next input.
116
+ */
117
+ handleKeyUp ( evt ) {
118
+ if ( evt . keyCode === COLON ) {
119
+ var value = evt . target . value ;
120
+ if ( value !== ':' ) {
121
+ this . element . rename ( value . replace ( ':' , '' ) ) ;
122
+ evt . target . value = '' ;
123
+ this . _node . nextSibling . nextSibling . focus ( ) ;
124
+ }
93
125
}
94
126
}
95
127
@@ -100,7 +132,7 @@ class EditableKey extends React.Component {
100
132
*/
101
133
handleChange ( evt ) {
102
134
var value = evt . target . value ;
103
- this . _node . size = value . length ;
135
+ this . _node . size = inputSize ( value ) ;
104
136
if ( this . isEditable ( ) ) {
105
137
if ( this . element . isDuplicateKey ( value ) ) {
106
138
this . setState ( { duplicate : true } ) ;
@@ -130,12 +162,30 @@ class EditableKey extends React.Component {
130
162
}
131
163
132
164
/**
133
- * Is this component editable?
165
+ * Is this component auto focusable?
166
+ *
167
+ * This is true if:
168
+ * - When a new element has been added and is a normal element.
169
+ * - When not being tabbed into.
170
+ *
171
+ * Is false if:
172
+ * - When a new array value has been added.
173
+ * - When the key is _id
134
174
*
135
175
* @returns {Boolean } If the component is editable.
136
176
*/
177
+ isAutoFocusable ( ) {
178
+ return this . element . isAdded ( ) && this . isEditable ( ) ;
179
+ }
180
+
181
+ /**
182
+ * Is the key able to be edited?
183
+ *
184
+ * @returns {Boolean } If the key can be edited.
185
+ */
137
186
isEditable ( ) {
138
- return this . element . isKeyEditable ( ) && this . element . parentElement . currentType !== 'Array' ;
187
+ return this . element . isKeyEditable ( ) &&
188
+ this . element . parent . currentType !== 'Array' ;
139
189
}
140
190
141
191
/**
0 commit comments