Rendering more like JSON
This commit is contained in:
parent
d53e5360a3
commit
9eb944d926
|
@ -52,7 +52,6 @@ export default class JSONNode extends PureComponent {
|
|||
|
||||
static propTypes = {
|
||||
prop: PropTypes.string, // in case of an object property
|
||||
index: PropTypes.number, // in case of an array item
|
||||
value: PropTypes.oneOfType([ PropTypes.object, PropTypes.array ]).isRequired,
|
||||
|
||||
emit: PropTypes.func.isRequired,
|
||||
|
@ -60,7 +59,6 @@ export default class JSONNode extends PureComponent {
|
|||
|
||||
// options
|
||||
options: PropTypes.shape({
|
||||
name: PropTypes.string, // name of the root item
|
||||
isPropertyEditable: PropTypes.func,
|
||||
isValueEditable: PropTypes.func,
|
||||
escapeUnicode: PropTypes.bool
|
||||
|
@ -96,14 +94,22 @@ export default class JSONNode extends PureComponent {
|
|||
renderJSONObject () {
|
||||
const meta = this.props.value[META]
|
||||
const props = meta.props
|
||||
const node = h('div', {
|
||||
const nodeStart = h('div', {
|
||||
key: 'node',
|
||||
onKeyDown: this.handleKeyDown,
|
||||
className: 'jsoneditor-node jsoneditor-object'
|
||||
}, [
|
||||
this.renderExpandButton(),
|
||||
// this.renderDelimiter('\u2610'),
|
||||
this.renderProperty(),
|
||||
this.renderReadonly(`{${props.length}}`, `Object containing ${props.length} items`),
|
||||
this.renderSeparator(),
|
||||
this.renderDelimiter('{', 'jsoneditor-delimiter-start'),
|
||||
!meta.expanded
|
||||
? [
|
||||
this.renderTag(`${props.length} props`, `Object containing ${props.length} properties`),
|
||||
this.renderDelimiter('}', 'jsoneditor-delimiter-start'),
|
||||
]
|
||||
: null,
|
||||
this.renderError(meta.error)
|
||||
])
|
||||
|
||||
|
@ -130,34 +136,45 @@ export default class JSONNode extends PureComponent {
|
|||
|
||||
const floatingMenu = this.renderFloatingMenu(MENU_ITEMS_OBJECT, meta.selected)
|
||||
const insertArea = this.renderInsertBeforeArea()
|
||||
const nodeEnd = meta.expanded
|
||||
? this.renderDelimiter('}', 'jsoneditor-delimiter-end')
|
||||
: null
|
||||
|
||||
return h('div', {
|
||||
'data-path': compileJSONPointer(meta.path),
|
||||
className: this.getContainerClassName(meta.selected, this.state.hover),
|
||||
onMouseOver: this.handleMouseOver,
|
||||
onMouseLeave: this.handleMouseLeave
|
||||
}, [node, floatingMenu, insertArea, childs])
|
||||
}, [nodeStart, floatingMenu, insertArea, childs, nodeEnd])
|
||||
}
|
||||
|
||||
renderJSONArray () {
|
||||
const meta = this.props.value[META]
|
||||
const node = h('div', {
|
||||
const count = this.props.value.length
|
||||
const nodeStart = h('div', {
|
||||
key: 'node',
|
||||
onKeyDown: this.handleKeyDown,
|
||||
className: 'jsoneditor-node jsoneditor-array'
|
||||
}, [
|
||||
this.renderExpandButton(),
|
||||
// this.renderDelimiter('\u2611'),
|
||||
this.renderProperty(),
|
||||
this.renderReadonly(`[${this.props.value.length}]`, `Array containing ${this.props.value.length} items`),
|
||||
this.renderSeparator(),
|
||||
this.renderDelimiter('[', 'jsoneditor-delimiter-start'),
|
||||
!meta.expanded
|
||||
? [
|
||||
this.renderTag(`${count} items`, `Array containing ${count} items`),
|
||||
this.renderDelimiter(']', 'jsoneditor-delimiter-start'),
|
||||
]
|
||||
: null,
|
||||
this.renderError(meta.error)
|
||||
])
|
||||
|
||||
let childs
|
||||
if (meta.expanded) {
|
||||
if (this.props.value.length > 0) {
|
||||
const items = this.props.value.map((item, index) => h(this.constructor, {
|
||||
if (count > 0) {
|
||||
const items = this.props.value.map(item => h(this.constructor, {
|
||||
key : item[META].id,
|
||||
index,
|
||||
value: item,
|
||||
options: this.props.options,
|
||||
emit: this.props.emit,
|
||||
|
@ -175,13 +192,16 @@ export default class JSONNode extends PureComponent {
|
|||
|
||||
const floatingMenu = this.renderFloatingMenu(MENU_ITEMS_ARRAY, meta.selected)
|
||||
const insertArea = this.renderInsertBeforeArea()
|
||||
const nodeEnd = meta.expanded
|
||||
? this.renderDelimiter(']', 'jsoneditor-delimiter-end')
|
||||
: null
|
||||
|
||||
return h('div', {
|
||||
'data-path': compileJSONPointer(meta.path),
|
||||
className: this.getContainerClassName(meta.selected, this.state.hover),
|
||||
onMouseOver: this.handleMouseOver,
|
||||
onMouseLeave: this.handleMouseLeave
|
||||
}, [node, floatingMenu, insertArea, childs])
|
||||
}, [nodeStart, floatingMenu, insertArea, childs, nodeEnd])
|
||||
}
|
||||
|
||||
renderJSONValue () {
|
||||
|
@ -192,9 +212,12 @@ export default class JSONNode extends PureComponent {
|
|||
className: 'jsoneditor-node'
|
||||
}, [
|
||||
this.renderPlaceholder(),
|
||||
// this.renderDelimiter('\u2611'),
|
||||
this.renderProperty(),
|
||||
this.renderSeparator(),
|
||||
this.renderValue(meta.value, meta.searchValue, this.props.options),
|
||||
// this.renderDelimiter('\u21B2'),
|
||||
// this.renderDelimiter('\u23CE'),
|
||||
this.renderError(meta.error)
|
||||
])
|
||||
|
||||
|
@ -247,54 +270,73 @@ export default class JSONNode extends PureComponent {
|
|||
return h('div', {key: 'readonly', className: 'jsoneditor-readonly', title}, text)
|
||||
}
|
||||
|
||||
renderTag (text, title = null) {
|
||||
return h('div', {
|
||||
key: 'readonly',
|
||||
className: 'jsoneditor-tag',
|
||||
onClick: this.handleExpand,
|
||||
title
|
||||
}, text)
|
||||
}
|
||||
|
||||
// TODO: simplify the method renderProperty
|
||||
|
||||
/**
|
||||
* Render a property field of a JSONNode
|
||||
*/
|
||||
renderProperty () {
|
||||
const isIndex = typeof this.props.index === 'number'
|
||||
const isProp = typeof this.props.prop === 'string'
|
||||
|
||||
if (!isProp && !isIndex) {
|
||||
// root node
|
||||
const rootName = JSONNode.getRootName(this.props.value, this.props.options)
|
||||
|
||||
return h('div', {
|
||||
key: 'property',
|
||||
className: 'jsoneditor-property jsoneditor-readonly',
|
||||
spellCheck: 'false',
|
||||
onBlur: this.handleChangeProperty
|
||||
}, rootName)
|
||||
if (!isProp) {
|
||||
return null
|
||||
}
|
||||
|
||||
const editable = !isIndex && (!this.props.options.isPropertyEditable || this.props.options.isPropertyEditable(this.props.value[META].path))
|
||||
const editable = !this.props.options.isPropertyEditable ||
|
||||
this.props.options.isPropertyEditable(this.props.value[META].path)
|
||||
|
||||
const emptyClassName = (this.props.prop != null && this.props.prop.length === 0) ? ' jsoneditor-empty' : ''
|
||||
const searchClassName = this.props.prop != null ? JSONNode.getSearchResultClass(this.props.value[META].searchProperty) : ''
|
||||
const escapedPropName = this.props.prop != null ? escapeHTML(this.props.prop, this.props.options.escapeUnicode) : null
|
||||
|
||||
if (editable) {
|
||||
return h('div', {
|
||||
key: 'property',
|
||||
className: 'jsoneditor-property' + emptyClassName + searchClassName,
|
||||
contentEditable: 'true',
|
||||
suppressContentEditableWarning: true,
|
||||
spellCheck: 'false',
|
||||
onBlur: this.handleChangeProperty
|
||||
}, escapedPropName)
|
||||
return [
|
||||
// this.renderDelimiter('"'),
|
||||
h('div', {
|
||||
key: 'property',
|
||||
className: 'jsoneditor-property' + emptyClassName + searchClassName,
|
||||
contentEditable: 'true',
|
||||
suppressContentEditableWarning: true,
|
||||
spellCheck: 'false',
|
||||
onBlur: this.handleChangeProperty
|
||||
}, escapedPropName),
|
||||
// this.renderDelimiter('" '),
|
||||
]
|
||||
}
|
||||
else {
|
||||
return h('div', {
|
||||
key: 'property',
|
||||
className: 'jsoneditor-property jsoneditor-readonly' + searchClassName,
|
||||
spellCheck: 'false'
|
||||
}, isIndex ? this.props.index : escapedPropName)
|
||||
}, escapedPropName)
|
||||
}
|
||||
}
|
||||
|
||||
renderSeparator() {
|
||||
return h('div', {key: 'separator', className: 'jsoneditor-separator'}, ':')
|
||||
const isProp = typeof this.props.prop === 'string'
|
||||
if (!isProp) {
|
||||
return null
|
||||
}
|
||||
|
||||
return h('div', {key: 'separator', className: 'jsoneditor-delimiter'}, ':')
|
||||
}
|
||||
|
||||
renderComma() {
|
||||
// TODO: don't render when it's the last item/prop
|
||||
return h('div', {key: 'comma', className: 'jsoneditor-delimiter'}, ',')
|
||||
}
|
||||
|
||||
renderDelimiter (text, className = '') {
|
||||
return h('div', {key: text, className: 'jsoneditor-delimiter ' + className}, text)
|
||||
}
|
||||
|
||||
renderValue (value, searchResult, options) {
|
||||
|
|
|
@ -179,26 +179,28 @@ div.jsoneditor-list {
|
|||
|
||||
/* no left padding for the root div element */
|
||||
.jsoneditor-contents > div.jsoneditor-list {
|
||||
padding-left: 2px;
|
||||
padding-bottom: 24px; }
|
||||
padding-left: 2px; }
|
||||
|
||||
.jsoneditor-property,
|
||||
.jsoneditor-value,
|
||||
.jsoneditor-readonly,
|
||||
.jsoneditor-separator {
|
||||
line-height: 20px;
|
||||
.jsoneditor-delimiter {
|
||||
line-height: 18px;
|
||||
font-family: droid sans mono, consolas, monospace, courier new, courier, sans-serif;
|
||||
font-size: 10pt; }
|
||||
|
||||
.jsoneditor-property,
|
||||
.jsoneditor-value,
|
||||
.jsoneditor-readonly {
|
||||
min-width: 24px;
|
||||
min-width: 16px;
|
||||
word-break: normal;
|
||||
padding: 0 5px;
|
||||
color: #1A1A1A;
|
||||
outline: none; }
|
||||
|
||||
.jsoneditor-readonly {
|
||||
min-width: auto; }
|
||||
|
||||
.jsoneditor-button-container {
|
||||
font-size: 0; }
|
||||
|
||||
|
@ -227,24 +229,39 @@ div.jsoneditor-list {
|
|||
.jsoneditor-mode-view .jsoneditor-value:hover {
|
||||
background-color: inherit; }
|
||||
|
||||
.jsoneditor-separator {
|
||||
color: #808080; }
|
||||
|
||||
.jsoneditor-delimiter,
|
||||
.jsoneditor-readonly {
|
||||
color: #808080; }
|
||||
color: #9d9d9d; }
|
||||
|
||||
.jsoneditor-delimiter-start {
|
||||
margin-left: 5px; }
|
||||
|
||||
.jsoneditor-delimiter-end {
|
||||
margin-left: 25px; }
|
||||
|
||||
.jsoneditor-readonly:focus,
|
||||
.jsoneditor-readonly:hover {
|
||||
border-color: transparent;
|
||||
background-color: inherit; }
|
||||
|
||||
.jsoneditor-tag {
|
||||
color: white;
|
||||
background: #c0c0c0;
|
||||
border-radius: 2px;
|
||||
padding: 0 4px;
|
||||
margin-left: 5px;
|
||||
margin-top: 2px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
font-size: 80%; }
|
||||
|
||||
.jsoneditor-value.jsoneditor-string {
|
||||
color: #008000; }
|
||||
|
||||
.jsoneditor-value.jsoneditor-object,
|
||||
.jsoneditor-value.jsoneditor-array {
|
||||
min-width: 16px;
|
||||
color: #808080; }
|
||||
color: #9d9d9d; }
|
||||
|
||||
.jsoneditor-value.jsoneditor-number {
|
||||
color: #ee422e; }
|
||||
|
@ -536,46 +553,25 @@ div.jsoneditor-node-container {
|
|||
div.jsoneditor-node-container div.jsoneditor-insert-area:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
top: -6px;
|
||||
right: 0;
|
||||
width: 60px;
|
||||
height: 20px;
|
||||
height: 18px;
|
||||
background: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected {
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover {
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border-color: #e5e5e5;
|
||||
background-color: #e5e5e5; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after.jsoneditor-selected-insert-area-before > div.jsoneditor-insert-area {
|
||||
border-color: #ffdb80;
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before.jsoneditor-hover {
|
||||
background-color: #e5e5e5; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before > div.jsoneditor-insert-area {
|
||||
border-color: #ffed99;
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover {
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border-color: #ffdb80;
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover {
|
||||
background-color: #e5e5e5; }
|
||||
background-color: #d3d3d3; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border-color: #e5e5e5;
|
||||
background-color: #e5e5e5; }
|
||||
border-color: #d3d3d3;
|
||||
background-color: #d3d3d3; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected {
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-after > div.jsoneditor-insert-area {
|
||||
border-color: #ffed99;
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container div.jsoneditor-floating-menu {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
|
|
|
@ -7,15 +7,16 @@ $contentsMinHeight: 150px;
|
|||
$theme-color: #3883fa; // TODO: create a central file with the theme colors
|
||||
$floating-menu-background: #4d4d4d;
|
||||
$floating-menu-color: #fff;
|
||||
// $selectedColor: #e5e5e5;
|
||||
$selectedColor: #ffed99;
|
||||
//$hoverColor: #f2f2f2;
|
||||
$hoverColor: #e5e5e5;
|
||||
$hoverColor: #d3d3d3;
|
||||
$hoverAndSelectedColor: #ffdb80;
|
||||
$gray: #9d9d9d;
|
||||
$light-gray: #c0c0c0;
|
||||
$input-padding: 5px;
|
||||
|
||||
// TODO: split this scss file into separate files per React component
|
||||
|
||||
$line-height: 20px;
|
||||
$line-height: 18px;
|
||||
$insert-area-height: 6px;
|
||||
|
||||
.jsoneditor {
|
||||
|
@ -136,13 +137,12 @@ div.jsoneditor-list {
|
|||
/* no left padding for the root div element */
|
||||
.jsoneditor-contents > div.jsoneditor-list {
|
||||
padding-left: 2px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.jsoneditor-property,
|
||||
.jsoneditor-value,
|
||||
.jsoneditor-readonly,
|
||||
.jsoneditor-separator {
|
||||
.jsoneditor-delimiter {
|
||||
line-height: $line-height;
|
||||
|
||||
font-family: $fontFamily;
|
||||
|
@ -152,15 +152,19 @@ div.jsoneditor-list {
|
|||
.jsoneditor-property,
|
||||
.jsoneditor-value,
|
||||
.jsoneditor-readonly {
|
||||
min-width: 24px;
|
||||
min-width: 16px;
|
||||
word-break: normal;
|
||||
|
||||
padding: 0 5px;
|
||||
padding: 0 $input-padding;
|
||||
|
||||
color: $black;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.jsoneditor-readonly {
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.jsoneditor-button-container {
|
||||
font-size: 0;
|
||||
}
|
||||
|
@ -201,12 +205,17 @@ div.jsoneditor-list {
|
|||
}
|
||||
|
||||
|
||||
.jsoneditor-separator {
|
||||
color: #808080;
|
||||
.jsoneditor-delimiter,
|
||||
.jsoneditor-readonly {
|
||||
color: $gray;
|
||||
}
|
||||
|
||||
.jsoneditor-readonly {
|
||||
color: #808080;
|
||||
.jsoneditor-delimiter-start {
|
||||
margin-left: $input-padding;
|
||||
}
|
||||
|
||||
.jsoneditor-delimiter-end {
|
||||
margin-left: $line-height + $input-padding + 2px;
|
||||
}
|
||||
|
||||
.jsoneditor-readonly:focus,
|
||||
|
@ -215,6 +224,18 @@ div.jsoneditor-list {
|
|||
background-color: inherit;
|
||||
}
|
||||
|
||||
.jsoneditor-tag {
|
||||
color: white;
|
||||
background: $light-gray;
|
||||
border-radius: 2px;
|
||||
padding: 0 4px;
|
||||
margin-left: $input-padding;
|
||||
margin-top: 2px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
||||
.jsoneditor-value.jsoneditor-string {
|
||||
color: #008000;
|
||||
|
@ -223,7 +244,7 @@ div.jsoneditor-list {
|
|||
.jsoneditor-value.jsoneditor-object,
|
||||
.jsoneditor-value.jsoneditor-array {
|
||||
min-width: 16px;
|
||||
color: #808080;
|
||||
color: $gray;
|
||||
}
|
||||
|
||||
.jsoneditor-value.jsoneditor-number {
|
||||
|
@ -250,7 +271,7 @@ div.jsoneditor-value.jsoneditor-url {
|
|||
div.jsoneditor-empty {
|
||||
border: 1px dotted lightgray;
|
||||
border-radius: 2px;
|
||||
padding: 0 5px;
|
||||
padding: 0 $input-padding;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
|
@ -609,61 +630,6 @@ div.jsoneditor-node-container {
|
|||
}
|
||||
}
|
||||
|
||||
&.jsoneditor-selected {
|
||||
background-color: $selectedColor;
|
||||
|
||||
&.jsoneditor-hover {
|
||||
background-color: $hoverAndSelectedColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: $selectedColor;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
border-color: $hoverColor;
|
||||
background-color: $hoverColor;
|
||||
}
|
||||
|
||||
&.jsoneditor-selected-insert-area-before {
|
||||
> div.jsoneditor-insert-area {
|
||||
border-color: $hoverAndSelectedColor;
|
||||
background-color: $hoverAndSelectedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.jsoneditor-selected-insert-area-before {
|
||||
background-color: inherit;
|
||||
|
||||
&.jsoneditor-hover {
|
||||
background-color: $hoverColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
border-color: $selectedColor;
|
||||
background-color: $selectedColor;
|
||||
}
|
||||
}
|
||||
|
||||
// hovering nested elements
|
||||
div.jsoneditor-hover {
|
||||
background-color: $hoverAndSelectedColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
border-color: $hoverAndSelectedColor;
|
||||
background-color: $hoverAndSelectedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.jsoneditor-hover {
|
||||
background-color: $hoverColor;
|
||||
|
||||
|
@ -677,6 +643,19 @@ div.jsoneditor-node-container {
|
|||
}
|
||||
}
|
||||
|
||||
&.jsoneditor-selected {
|
||||
background-color: $selectedColor;
|
||||
|
||||
&.jsoneditor-selected-insert-area-after {
|
||||
background-color: inherit;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
border-color: $selectedColor;
|
||||
background-color: $selectedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.jsoneditor-floating-menu {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
|
|
Loading…
Reference in New Issue