Skip to content

Commit 81def7b

Browse files
committed
Merged branch develop into master
2 parents ef267af + f701984 commit 81def7b

File tree

11 files changed

+199
-35
lines changed

11 files changed

+199
-35
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11

2+
# 1.3.0
3+
## Feature
4+
- Add way to pass plus and minus menu element
5+
- Update Demo website to add custom inputs, ...
6+
7+
## Fix
8+
- Test if focus exists before using it on inputs
9+
- Add keywords on package.json
10+
211
# 1.2.0
312
## Feature
413
- Add possibility to edit 'function'

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,29 @@ The library will add a `onClick` props on element.
186186
| inputElement | Input Text Element to replace library one | Element | False | <input /> |
187187

188188
The library will add a `placeholder`, `ref`, `defaultValue` props on element.
189+
This item will be focus when possible.
189190

190191
### textareaElement
191192
| Key | Description | Type | Required | Default |
192193
|:---------------:|:-----------------------------------------:|:-----------:|:--------:|:------------:|
193194
| textareaElement | Textarea Element to replace library one | Element | False | <textarea /> |
194195

195196
The library will add a `ref`, `defaultValue` props on element.
197+
This item will be focus when possible.
198+
199+
### minusMenuElement
200+
| Key | Description | Type | Required | Default |
201+
|:----------------:|:-----------------------------------------:|:-----------:|:--------:|:-------------------:|
202+
| minusMenuElement | Minus Menu Element to replace library one | Element | False | <span> - </span> |
203+
204+
The library will add a `onClick`, `className` and `style` props on element.
205+
206+
### plusMenuElement
207+
| Key | Description | Type | Required | Default |
208+
|:---------------:|:----------------------------------------:|:-----------:|:--------:|:-------------------:|
209+
| plusMenuElement | Plus Menu Element to replace library one | Element | False | <span> + </span> |
210+
211+
The library will add a `onClick`, `className` and `style` props on element.
196212

197213
## Design
198214
The library provide CSS class on elements. All are prefixed by "rejt" to avoid conflict.

dev/components/Body.jsx

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class Body extends Component {
5656
textareaRef: null,
5757
readOnlyRef: null,
5858
readOnly: false,
59+
customInputRef: null,
60+
customInput: false,
61+
minusMenuRef: null,
62+
minusMenu: false,
5963
};
6064
// Bind
6165
this.onFullyUpdate = this.onFullyUpdate.bind(this);
@@ -67,6 +71,10 @@ class Body extends Component {
6771
this.handleChangeReadOnly = this.handleChangeReadOnly.bind(this);
6872
this.handleClearGlobalUpdateString = this.handleClearGlobalUpdateString.bind(this);
6973
this.handleClearDeltaUpdateString = this.handleClearDeltaUpdateString.bind(this);
74+
this.refCustomInputCheckbox = this.refCustomInputCheckbox.bind(this);
75+
this.handleChangeCustomInput = this.handleChangeCustomInput.bind(this);
76+
this.refMinusMenuCheckbox = this.refMinusMenuCheckbox.bind(this);
77+
this.handleChangeMinusMenu = this.handleChangeMinusMenu.bind(this);
7078
}
7179

7280
onFullyUpdate(newJson) {
@@ -89,6 +97,30 @@ class Body extends Component {
8997
this.state.readOnlyRef = node;
9098
}
9199

100+
refMinusMenuCheckbox(node) {
101+
this.state.minusMenuRef = node;
102+
}
103+
104+
handleChangeMinusMenu() {
105+
const { minusMenuRef } = this.state;
106+
107+
this.setState({
108+
minusMenu: minusMenuRef.checked,
109+
});
110+
}
111+
112+
refCustomInputCheckbox(node) {
113+
this.state.customInputRef = node;
114+
}
115+
116+
handleChangeCustomInput() {
117+
const { customInputRef } = this.state;
118+
119+
this.setState({
120+
customInput: customInputRef.checked,
121+
});
122+
}
123+
92124
handleSubmit() {
93125
const { textareaRef } = this.state;
94126
// Get data
@@ -134,7 +166,7 @@ class Body extends Component {
134166
}
135167

136168
render() {
137-
const { json, deltaUpdateString, globalUpdateString, readOnly } = this.state;
169+
const { json, deltaUpdateString, globalUpdateString, readOnly, customInput, minusMenu } = this.state;
138170

139171
const style1 = {
140172
width: '100%',
@@ -150,14 +182,38 @@ class Body extends Component {
150182
margin: '0 15px',
151183
minWidth: '200px',
152184
};
185+
const style5 = {
186+
backgroundColor: 'black',
187+
color: 'yellow',
188+
border: '1px solid green',
189+
};
190+
const customInputElement = customInput ? <input style={style5} /> : undefined;
191+
const minusMenuElement = minusMenu ? <button>Remove</button> : undefined;
192+
153193
return (
154194
<div>
155195
<div style={style4}>
156-
<input
157-
type="checkbox"
158-
ref={this.refReadOnlyCheckbox}
159-
onChange={this.handleChangeReadOnly}
160-
/>Read Only
196+
<span>
197+
<input
198+
type="checkbox"
199+
ref={this.refReadOnlyCheckbox}
200+
onChange={this.handleChangeReadOnly}
201+
/>Read Only
202+
</span>
203+
<span>
204+
<input
205+
type="checkbox"
206+
ref={this.refCustomInputCheckbox}
207+
onChange={this.handleChangeCustomInput}
208+
/>Custom input
209+
</span>
210+
<span>
211+
<input
212+
type="checkbox"
213+
ref={this.refMinusMenuCheckbox}
214+
onChange={this.handleChangeMinusMenu}
215+
/>Custom minus menu
216+
</span>
161217
</div>
162218
<table style={style1}>
163219
<thead>
@@ -189,6 +245,8 @@ class Body extends Component {
189245
onFullyUpdate={this.onFullyUpdate}
190246
onDeltaUpdate={this.onDeltaUpdate}
191247
readOnly={readOnly}
248+
inputElement={customInputElement}
249+
minusMenuElement={minusMenuElement}
192250
/>
193251
</div>
194252
</td>

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
{
22
"name": "react-editable-json-tree",
3-
"version": "1.2.0",
3+
"version": "1.3.0",
44
"description": "React Editable Json Tree",
55
"main": "dist/JsonTree.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
88
"serve": "gulp serve",
99
"release": "gulp release"
1010
},
11+
"keywords": [
12+
"React",
13+
"Editable",
14+
"Json",
15+
"Tree",
16+
"Customizable"
17+
],
1118
"repository": {
1219
"type": "git",
1320
"url": "git@github.com:oxyno-zeta/react-editable-json-tree.git"

src/JsonTree.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const propTypes = {
2929
editButtonElement: PropTypes.element,
3030
inputElement: PropTypes.element,
3131
textareaElement: PropTypes.element,
32+
minusMenuElement: PropTypes.element,
33+
plusMenuElement: PropTypes.element,
3234
};
3335
// Default props
3436
const defaultProps = {
@@ -94,6 +96,8 @@ class JsonTree extends Component {
9496
editButtonElement,
9597
inputElement,
9698
textareaElement,
99+
minusMenuElement,
100+
plusMenuElement,
97101
} = this.props;
98102

99103
// Node type
@@ -115,6 +119,8 @@ class JsonTree extends Component {
115119
editButtonElement={editButtonElement}
116120
inputElement={inputElement}
117121
textareaElement={textareaElement}
122+
minusMenuElement={minusMenuElement}
123+
plusMenuElement={plusMenuElement}
118124
/>);
119125
} else {
120126
node = 'Data must be an Array or Object';

src/components/JsonAddValue.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ class JsonAddValue extends Component {
5050
const { inputRefKey, inputRefValue } = this.state;
5151
const { onlyValue } = this.props;
5252

53-
if (inputRefKey) {
53+
if (inputRefKey && (typeof inputRefKey.focus === 'function')) {
5454
inputRefKey.focus();
5555
}
5656

57-
if (onlyValue && inputRefValue) {
57+
if (onlyValue && inputRefValue && (typeof inputRefValue.focus === 'function')) {
5858
inputRefValue.focus();
5959
}
6060
}

src/components/JsonArray.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@ const propTypes = {
3333
editButtonElement: PropTypes.element,
3434
inputElement: PropTypes.element,
3535
textareaElement: PropTypes.element,
36+
minusMenuElement: PropTypes.element,
37+
plusMenuElement: PropTypes.element,
3638
};
3739
// Default props
3840
const defaultProps = {
3941
keyPath: [],
4042
deep: 0,
43+
minusMenuElement: <span> - </span>,
44+
plusMenuElement: <span> + </span>,
4145
};
4246

4347
/* ************************************* */
@@ -196,16 +200,20 @@ class JsonArray extends Component {
196200

197201
renderCollapsed() {
198202
const { name, data, keyPath, deep } = this.state;
199-
const { handleRemove, readOnly, getStyle, dataType } = this.props;
203+
const { handleRemove, readOnly, getStyle, dataType, minusMenuElement } = this.props;
200204

201205
const { minus, collapsed } = getStyle(name, data, keyPath, deep, dataType);
202206
const collapseValue = ' [...]';
203207
const numberOfItems = data.length;
204208
let minusElement = null;
205209
// Check if readOnly is activated
206210
if (!readOnly) {
207-
minusElement = (deep !== 0) ?
208-
(<span className="rejt-minus-menu" onClick={handleRemove} style={minus}> - </span>) : null;
211+
const minusMenuLayout = React.cloneElement(minusMenuElement, {
212+
onClick: handleRemove,
213+
className: 'rejt-minus-menu',
214+
style: minus,
215+
});
216+
minusElement = (deep !== 0) ? minusMenuLayout : null;
209217
}
210218

211219
const itemName = (numberOfItems > 1) ? 'items' : 'item';
@@ -232,14 +240,20 @@ class JsonArray extends Component {
232240
editButtonElement,
233241
inputElement,
234242
textareaElement,
243+
minusMenuElement,
244+
plusMenuElement,
235245
} = this.props;
236246
const { minus, plus, delimiter, ul, addForm } = getStyle(name, data, keyPath, deep, dataType);
237247

238248
let minusElement = null;
239249
// Check if readOnly is activated
240250
if (!readOnly) {
241-
minusElement = (deep !== 0) ?
242-
(<span className="rejt-minus-menu" onClick={handleRemove} style={minus}> - </span>) : null;
251+
const minusMenuLayout = React.cloneElement(minusMenuElement, {
252+
onClick: handleRemove,
253+
className: 'rejt-minus-menu',
254+
style: minus,
255+
});
256+
minusElement = (deep !== 0) ? minusMenuLayout : null;
243257
}
244258

245259
const list = data
@@ -261,12 +275,19 @@ class JsonArray extends Component {
261275
editButtonElement={editButtonElement}
262276
inputElement={inputElement}
263277
textareaElement={textareaElement}
278+
minusMenuElement={minusMenuElement}
279+
plusMenuElement={plusMenuElement}
264280
/>);
265281

266282
const onlyValue = true;
267283
let menu = null;
268284
// Check if readOnly is activated
269285
if (!readOnly) {
286+
const plusMenuLayout = React.cloneElement(plusMenuElement, {
287+
onClick: this.handleAddMode,
288+
className: 'rejt-plus-menu',
289+
style: plus,
290+
});
270291
menu = addFormVisible ?
271292
(<span className="rejt-add-form" style={addForm}><JsonAddValue
272293
handleAdd={this.handleAddValueAdd}
@@ -277,7 +298,7 @@ class JsonArray extends Component {
277298
inputElement={inputElement}
278299
/></span>) :
279300
(<span>
280-
<span className="rejt-plus-menu" onClick={this.handleAddMode} style={plus}> + </span> {minusElement}
301+
{plusMenuLayout} {minusElement}
281302
</span>);
282303
}
283304

src/components/JsonFunctionValue.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const propTypes = {
2929
editButtonElement: PropTypes.element,
3030
cancelButtonElement: PropTypes.element,
3131
textareaElement: PropTypes.element,
32+
minusMenuElement: PropTypes.element,
3233
};
3334
// Default props
3435
const defaultProps = {
@@ -39,6 +40,7 @@ const defaultProps = {
3940
editButtonElement: <button>e</button>,
4041
cancelButtonElement: <button>c</button>,
4142
textareaElement: <textarea />,
43+
minusMenuElement: <span> - </span>,
4244
};
4345

4446
/* ************************************* */
@@ -77,7 +79,7 @@ class JsonValue extends Component {
7779
const { editEnabled, inputRef } = this.state;
7880
const { readOnly } = this.props;
7981

80-
if (editEnabled && !readOnly) {
82+
if (editEnabled && !readOnly && (typeof inputRef.focus === 'function')) {
8183
inputRef.focus();
8284
}
8385
}
@@ -129,6 +131,7 @@ class JsonValue extends Component {
129131
editButtonElement,
130132
cancelButtonElement,
131133
textareaElement,
134+
minusMenuElement,
132135
} = this.props;
133136

134137
const style = getStyle(name, value, keyPath, deep, dataType);
@@ -142,24 +145,25 @@ class JsonValue extends Component {
142145
const cancelButtonElementLayout = React.cloneElement(cancelButtonElement, {
143146
onClick: this.handleCancelEdit,
144147
});
145-
const inputElementLayout = React.cloneElement(textareaElement, {
148+
const textareaElementLayout = React.cloneElement(textareaElement, {
146149
ref: this.refInput,
147150
defaultValue: originalValue,
148151
});
149152

150153
result = (<span className="rejt-edit-form" style={style.editForm}>
151-
{inputElementLayout} {cancelButtonElementLayout}{editButtonElementLayout}
154+
{textareaElementLayout} {cancelButtonElementLayout}{editButtonElementLayout}
152155
</span>);
153156
minusElement = null;
154157
} else {
155158
result = (<span className="rejt-value" style={style.value} onClick={readOnly ? null : this.handleEditMode}>
156159
{value}
157160
</span>);
158-
minusElement = (readOnly) ? null : (<span
159-
className="rejt-minus-menu"
160-
onClick={handleRemove}
161-
style={style.minus}
162-
> - </span>);
161+
const minusMenuLayout = React.cloneElement(minusMenuElement, {
162+
onClick: handleRemove,
163+
className: 'rejt-minus-menu',
164+
style: style.minus,
165+
});
166+
minusElement = (readOnly) ? null : minusMenuLayout;
163167
}
164168

165169
const handlers = {

0 commit comments

Comments
 (0)