Move some logic to `TreeModeMenu` and some small tweaks and fixes
This commit is contained in:
parent
21d8db13d0
commit
17df475c11
|
@ -427,8 +427,8 @@ export default class JSONNode extends PureComponent {
|
||||||
onMouseOver: this.updatePopoverDirection
|
onMouseOver: this.updatePopoverDirection
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
h('i', {className: 'fa fa-exclamation-triangle'}),
|
h('i', {className: 'fa fa-exclamation-triangle', key: 'icon'}),
|
||||||
h('div', {className: 'jsoneditor-popover jsoneditor-right'}, error.message)
|
h('div', {className: 'jsoneditor-popover jsoneditor-right', 'key': 'message'}, error.message)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,43 +276,31 @@ export default class TreeMode extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenu () {
|
renderMenu () {
|
||||||
const hasCursor = true // FIXME: implement hasCursor
|
|
||||||
const hasSelection = this.state.selection ? this.state.selection.type !== 'none' : false
|
|
||||||
const hasClipboard = this.state.clipboard
|
|
||||||
? this.state.clipboard.length > 0
|
|
||||||
: false
|
|
||||||
|
|
||||||
return h(TreeModeMenu, {
|
return h(TreeModeMenu, {
|
||||||
key: 'menu',
|
key: 'menu',
|
||||||
|
|
||||||
|
selection: this.state.selection,
|
||||||
|
clipboard: this.state.clipboard,
|
||||||
|
history: this.state.history,
|
||||||
|
|
||||||
mode: this.props.mode,
|
mode: this.props.mode,
|
||||||
modes: this.props.modes,
|
modes: this.props.modes,
|
||||||
onChangeMode: this.props.onChangeMode,
|
onChangeMode: this.props.onChangeMode,
|
||||||
|
|
||||||
canCut: hasSelection,
|
|
||||||
canCopy: hasSelection,
|
|
||||||
canPaste: hasClipboard && hasCursor,
|
|
||||||
onCut: this.handleCut,
|
onCut: this.handleCut,
|
||||||
onCopy: this.handleCopy,
|
onCopy: this.handleCopy,
|
||||||
onPaste: this.handlePaste,
|
onPaste: this.handlePaste,
|
||||||
|
|
||||||
canInsert: hasCursor,
|
|
||||||
canDuplicate: hasSelection,
|
|
||||||
canRemove: hasSelection,
|
|
||||||
onInsert: this.handleInsert,
|
onInsert: this.handleInsert,
|
||||||
onDuplicate: this.handleDuplicate,
|
onDuplicate: this.handleDuplicate,
|
||||||
onRemove: this.handleRemove,
|
onRemove: this.handleRemove,
|
||||||
|
|
||||||
canSort: hasSelection || hasCursor,
|
|
||||||
canTransform: hasSelection || hasCursor,
|
|
||||||
canSearch: this.props.search,
|
canSearch: this.props.search,
|
||||||
onSort: this.handleSort,
|
onSort: this.handleSort,
|
||||||
onTransform: this.handleTransform,
|
onTransform: this.handleTransform,
|
||||||
onToggleSearch: this.toggleSearch,
|
onToggleSearch: this.toggleSearch,
|
||||||
|
|
||||||
enableHistory: this.props.history,
|
enableHistory: this.props.history,
|
||||||
canUndo: this.canUndo(),
|
|
||||||
canRedo: this.canRedo(),
|
|
||||||
onUndo: this.undo,
|
onUndo: this.undo,
|
||||||
onRedo: this.redo,
|
onRedo: this.redo,
|
||||||
})
|
})
|
||||||
|
@ -1055,16 +1043,8 @@ export default class TreeMode extends PureComponent {
|
||||||
this.redo()
|
this.redo()
|
||||||
}
|
}
|
||||||
|
|
||||||
canUndo = () => {
|
|
||||||
return this.state.historyIndex < this.state.history.length
|
|
||||||
}
|
|
||||||
|
|
||||||
canRedo = () => {
|
|
||||||
return this.state.historyIndex > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
undo = () => {
|
undo = () => {
|
||||||
if (this.canUndo()) {
|
if (this.state.historyIndex < this.state.history.length) {
|
||||||
const history = this.state.history
|
const history = this.state.history
|
||||||
const historyIndex = this.state.historyIndex
|
const historyIndex = this.state.historyIndex
|
||||||
const historyItem = history[historyIndex]
|
const historyItem = history[historyIndex]
|
||||||
|
@ -1074,7 +1054,10 @@ export default class TreeMode extends PureComponent {
|
||||||
|
|
||||||
const { eson, searchResult } = (this.state.searchText)
|
const { eson, searchResult } = (this.state.searchText)
|
||||||
? applySearch(esonResult.json, this.state.searchText)
|
? applySearch(esonResult.json, this.state.searchText)
|
||||||
: { eson: esonResult.json, searchResult: null }
|
: {
|
||||||
|
eson: esonResult.json,
|
||||||
|
searchResult: { matches: null, active: null }
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
json,
|
json,
|
||||||
|
@ -1090,7 +1073,7 @@ export default class TreeMode extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
redo = () => {
|
redo = () => {
|
||||||
if (this.canRedo()) {
|
if (this.state.historyIndex > 0) {
|
||||||
const history = this.state.history
|
const history = this.state.history
|
||||||
const historyIndex = this.state.historyIndex - 1
|
const historyIndex = this.state.historyIndex - 1
|
||||||
const historyItem = history[historyIndex]
|
const historyItem = history[historyIndex]
|
||||||
|
@ -1100,7 +1083,10 @@ export default class TreeMode extends PureComponent {
|
||||||
|
|
||||||
const { eson, searchResult } = (this.state.searchText)
|
const { eson, searchResult } = (this.state.searchText)
|
||||||
? applySearch(esonResult.json, this.state.searchText)
|
? applySearch(esonResult.json, this.state.searchText)
|
||||||
: { eson: esonResult.json, searchResult: null }
|
: {
|
||||||
|
eson: esonResult.json,
|
||||||
|
searchResult: { matches: null, active: null }
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
json,
|
json,
|
||||||
|
@ -1138,7 +1124,10 @@ export default class TreeMode extends PureComponent {
|
||||||
|
|
||||||
const { eson, searchResult } = (this.state.searchText)
|
const { eson, searchResult } = (this.state.searchText)
|
||||||
? applySearch(esonResult.json, this.state.searchText)
|
? applySearch(esonResult.json, this.state.searchText)
|
||||||
: { eson: esonResult.json, searchResult: null }
|
: {
|
||||||
|
eson: esonResult.json,
|
||||||
|
searchResult: { matches: null, active: null }
|
||||||
|
}
|
||||||
|
|
||||||
if (this.props.history !== false) {
|
if (this.props.history !== false) {
|
||||||
// update data and store history
|
// update data and store history
|
||||||
|
|
|
@ -238,19 +238,19 @@ div.jsoneditor-value.jsoneditor-empty::after {
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-highlight {
|
.jsoneditor-highlight {
|
||||||
background-color: yellow;
|
background-color: $highlight-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-highlight:hover {
|
.jsoneditor-highlight:hover {
|
||||||
background-color: #f0f000;
|
background-color: $highlight-hover-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-highlight-active {
|
.jsoneditor-highlight-active {
|
||||||
background-color: #ffd700;
|
background-color: $highlight-active-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-highlight-active:hover {
|
.jsoneditor-highlight-active:hover {
|
||||||
background-color: #f3cd00;
|
background-color: $highlight-active-hover-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-button-placeholder {
|
.jsoneditor-button-placeholder {
|
||||||
|
@ -298,16 +298,16 @@ div.jsoneditor-node-container {
|
||||||
|
|
||||||
&.jsoneditor-selected {
|
&.jsoneditor-selected {
|
||||||
.jsoneditor-node {
|
.jsoneditor-node {
|
||||||
background-color: $selectedColor;
|
background-color: $selected-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-delimiter-end {
|
.jsoneditor-delimiter-end {
|
||||||
background-color: $selectedColor;
|
background-color: $selected-color;
|
||||||
border-left-color: $selectedColor;
|
border-left-color: $selected-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-list {
|
.jsoneditor-list {
|
||||||
border-left-color: $selectedColor;
|
border-left-color: $selected-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ div.jsoneditor-node-container {
|
||||||
|
|
||||||
&.jsoneditor-node-expanded {
|
&.jsoneditor-node-expanded {
|
||||||
.jsoneditor-node-end {
|
.jsoneditor-node-end {
|
||||||
background-color: $selectedColor;
|
background-color: $selected-color;
|
||||||
|
|
||||||
> .jsoneditor-delimiter-end {
|
> .jsoneditor-delimiter-end {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -324,7 +324,7 @@ div.jsoneditor-node-container {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.jsoneditor-node-collapsed {
|
&.jsoneditor-node-collapsed {
|
||||||
background-color: $selectedColor;
|
background-color: $selected-color;
|
||||||
|
|
||||||
> .jsoneditor-node {
|
> .jsoneditor-node {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -335,7 +335,7 @@ div.jsoneditor-node-container {
|
||||||
&.jsoneditor-selected-before-childs {
|
&.jsoneditor-selected-before-childs {
|
||||||
|
|
||||||
> .jsoneditor-node > .jsoneditor-before-childs {
|
> .jsoneditor-node > .jsoneditor-before-childs {
|
||||||
background-color: $selectedColor;
|
background-color: $selected-color;
|
||||||
width: 40px; // FIXME: should use full remaining width
|
width: 40px; // FIXME: should use full remaining width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,8 +434,8 @@ div.jsoneditor-code {
|
||||||
|
|
||||||
.jsoneditor-errors {
|
.jsoneditor-errors {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #ffef8b;
|
background-color: $error-background-color;
|
||||||
border-top: 1px solid #ffd700;
|
border-top: 1px solid $error-border-color;
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import isEmpty from 'lodash/isEmpty'
|
||||||
import { createElement as h, PureComponent } from 'react'
|
import { createElement as h, PureComponent } from 'react'
|
||||||
import DropDown from './DropDown'
|
import DropDown from './DropDown'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
@ -30,34 +31,27 @@ fontawesome.library.add(
|
||||||
export default class TreeModeMenu extends PureComponent {
|
export default class TreeModeMenu extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
selection: PropTypes.object,
|
||||||
|
clipboard: PropTypes.array,
|
||||||
|
history: PropTypes.array,
|
||||||
|
|
||||||
mode: PropTypes.string.isRequired,
|
mode: PropTypes.string.isRequired,
|
||||||
modes: PropTypes.arrayOf(PropTypes.string),
|
modes: PropTypes.arrayOf(PropTypes.string),
|
||||||
onChangeMode: PropTypes.func.isRequired,
|
onChangeMode: PropTypes.func.isRequired,
|
||||||
|
|
||||||
canCut: PropTypes.bool.isRequired,
|
|
||||||
canCopy: PropTypes.bool.isRequired,
|
|
||||||
canPaste: PropTypes.bool.isRequired,
|
|
||||||
onCut: PropTypes.func.isRequired,
|
onCut: PropTypes.func.isRequired,
|
||||||
onCopy: PropTypes.func.isRequired,
|
onCopy: PropTypes.func.isRequired,
|
||||||
onPaste: PropTypes.func.isRequired,
|
onPaste: PropTypes.func.isRequired,
|
||||||
|
|
||||||
canInsert: PropTypes.bool.isRequired,
|
|
||||||
canDuplicate: PropTypes.bool.isRequired,
|
|
||||||
canRemove: PropTypes.bool.isRequired,
|
|
||||||
onInsert: PropTypes.func.isRequired,
|
onInsert: PropTypes.func.isRequired,
|
||||||
onDuplicate: PropTypes.func.isRequired,
|
onDuplicate: PropTypes.func.isRequired,
|
||||||
onRemove: PropTypes.func.isRequired,
|
onRemove: PropTypes.func.isRequired,
|
||||||
|
|
||||||
canSort: PropTypes.bool.isRequired,
|
|
||||||
canTransform: PropTypes.bool.isRequired,
|
|
||||||
canSearch: PropTypes.bool.isRequired,
|
|
||||||
onSort: PropTypes.func.isRequired,
|
onSort: PropTypes.func.isRequired,
|
||||||
onTransform: PropTypes.func.isRequired,
|
onTransform: PropTypes.func.isRequired,
|
||||||
onToggleSearch: PropTypes.func,
|
onToggleSearch: PropTypes.func,
|
||||||
|
|
||||||
enableHistory: PropTypes.bool,
|
enableHistory: PropTypes.bool,
|
||||||
canUndo: PropTypes.bool,
|
|
||||||
canRedo: PropTypes.bool,
|
|
||||||
onUndo: PropTypes.func,
|
onUndo: PropTypes.func,
|
||||||
onRedo: PropTypes.func
|
onRedo: PropTypes.func
|
||||||
}
|
}
|
||||||
|
@ -65,6 +59,11 @@ export default class TreeModeMenu extends PureComponent {
|
||||||
render () {
|
render () {
|
||||||
let items = []
|
let items = []
|
||||||
|
|
||||||
|
const { selection, clipboard } = this.props
|
||||||
|
const hasCursor = selection && selection.type !== 'none'
|
||||||
|
const hasSelectedContent = selection ? !isEmpty(selection.multi) : false
|
||||||
|
const hasClipboard = clipboard ? (clipboard.length > 0) : false
|
||||||
|
|
||||||
// mode
|
// mode
|
||||||
if (this.props.modes ) {
|
if (this.props.modes ) {
|
||||||
items = items.concat([
|
items = items.concat([
|
||||||
|
@ -92,27 +91,28 @@ export default class TreeModeMenu extends PureComponent {
|
||||||
key: 'cut',
|
key: 'cut',
|
||||||
className: 'jsoneditor-cut',
|
className: 'jsoneditor-cut',
|
||||||
title: 'Cut current selection',
|
title: 'Cut current selection',
|
||||||
disabled: !this.props.canCut,
|
disabled: !hasSelectedContent,
|
||||||
onClick: this.props.onCut
|
onClick: this.props.onCut
|
||||||
}, h('i', {className: 'fa fa-cut'})),
|
}, h('i', {className: 'fa fa-cut'})),
|
||||||
h('button', {
|
h('button', {
|
||||||
key: 'copy',
|
key: 'copy',
|
||||||
className: 'jsoneditor-copy',
|
className: 'jsoneditor-copy',
|
||||||
title: 'Copy current selection',
|
title: 'Copy current selection',
|
||||||
disabled: !this.props.canCopy,
|
disabled: !hasSelectedContent,
|
||||||
onClick: this.props.onCopy
|
onClick: this.props.onCopy
|
||||||
}, h('i', {className: 'fa fa-copy'})),
|
}, h('i', {className: 'fa fa-copy'})),
|
||||||
h('button', {
|
h('button', {
|
||||||
key: 'paste',
|
key: 'paste',
|
||||||
className: 'jsoneditor-paste',
|
className: 'jsoneditor-paste',
|
||||||
title: 'Paste copied selection',
|
title: 'Paste copied selection',
|
||||||
disabled: !this.props.canPaste,
|
disabled: !(hasClipboard && hasCursor),
|
||||||
onClick: this.props.onPaste
|
onClick: this.props.onPaste
|
||||||
}, h('i', {className: 'fa fa-paste'}))
|
}, h('i', {className: 'fa fa-paste'}))
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
// TODO: [insert structure / insert value / insert array / insert object] / duplicate / remove
|
// [insert structure / insert value / insert array / insert object] / duplicate / remove
|
||||||
|
// TODO: disable options of insert
|
||||||
items = items.concat([
|
items = items.concat([
|
||||||
h('div', {className: 'jsoneditor-menu-group', key: 'insert-duplicate-remove'}, [
|
h('div', {className: 'jsoneditor-menu-group', key: 'insert-duplicate-remove'}, [
|
||||||
h(DropDown, {
|
h(DropDown, {
|
||||||
|
@ -126,14 +126,14 @@ export default class TreeModeMenu extends PureComponent {
|
||||||
key: 'duplicate',
|
key: 'duplicate',
|
||||||
className: 'jsoneditor-duplicate',
|
className: 'jsoneditor-duplicate',
|
||||||
title: 'Duplicate current selection',
|
title: 'Duplicate current selection',
|
||||||
disabled: !this.props.canDuplicate,
|
disabled: !hasSelectedContent,
|
||||||
onClick: this.props.onDuplicate
|
onClick: this.props.onDuplicate
|
||||||
}, h('i', {className: 'fa fa-clone'})),
|
}, h('i', {className: 'fa fa-clone'})),
|
||||||
h('button', {
|
h('button', {
|
||||||
key: 'remove',
|
key: 'remove',
|
||||||
className: 'jsoneditor-remove',
|
className: 'jsoneditor-remove',
|
||||||
title: 'Remove selection',
|
title: 'Remove selection',
|
||||||
disabled: !this.props.canRemove,
|
disabled: !hasSelectedContent,
|
||||||
onClick: this.props.onRemove
|
onClick: this.props.onRemove
|
||||||
}, h('i', {className: 'fa fa-times'}))
|
}, h('i', {className: 'fa fa-times'}))
|
||||||
])
|
])
|
||||||
|
@ -167,20 +167,23 @@ export default class TreeModeMenu extends PureComponent {
|
||||||
|
|
||||||
// undo / redo
|
// undo / redo
|
||||||
if (this.props.mode !== 'view' && this.props.enableHistory !== false) {
|
if (this.props.mode !== 'view' && this.props.enableHistory !== false) {
|
||||||
|
const canUndo = this.props.historyIndex < this.props.history.length
|
||||||
|
const canRedo = this.props.historyIndex > 0
|
||||||
|
|
||||||
items = items.concat([
|
items = items.concat([
|
||||||
h('div', {className: 'jsoneditor-menu-group', key: 'undo-redo'}, [
|
h('div', {className: 'jsoneditor-menu-group', key: 'undo-redo'}, [
|
||||||
h('button', {
|
h('button', {
|
||||||
key: 'undo',
|
key: 'undo',
|
||||||
className: 'jsoneditor-undo',
|
className: 'jsoneditor-undo',
|
||||||
title: 'Undo last action',
|
title: 'Undo last action',
|
||||||
disabled: !this.props.canUndo,
|
disabled: !canUndo,
|
||||||
onClick: this.props.onUndo
|
onClick: this.props.onUndo
|
||||||
}, h('i', {className: 'fa fa-undo'})),
|
}, h('i', {className: 'fa fa-undo'})),
|
||||||
h('button', {
|
h('button', {
|
||||||
key: 'redo',
|
key: 'redo',
|
||||||
className: 'jsoneditor-redo',
|
className: 'jsoneditor-redo',
|
||||||
title: 'Redo',
|
title: 'Redo',
|
||||||
disabled: !this.props.canRedo,
|
disabled: !canRedo,
|
||||||
onClick: this.props.onRedo
|
onClick: this.props.onRedo
|
||||||
}, h('i', {className: 'fa fa-redo'}))
|
}, h('i', {className: 'fa fa-redo'}))
|
||||||
])
|
])
|
||||||
|
|
|
@ -9,8 +9,14 @@ $theme-color: #3883fa;
|
||||||
$theme-color-light: lighten($theme-color, 5);
|
$theme-color-light: lighten($theme-color, 5);
|
||||||
$floating-menu-background: #4d4d4d;
|
$floating-menu-background: #4d4d4d;
|
||||||
$floating-menu-color: #fff;
|
$floating-menu-color: #fff;
|
||||||
$selectedColor: #d3d3d3;
|
$selected-color: #ffe665;
|
||||||
|
$highlight-color: #ffe665;
|
||||||
|
$highlight-hover-color: #f0f000;
|
||||||
|
$highlight-active-color: #ffd700;
|
||||||
|
$highlight-active-hover-color: #f3cd00;
|
||||||
$warning-color: #FBB917;
|
$warning-color: #FBB917;
|
||||||
|
$error-background-color: #ffef8b;
|
||||||
|
$error-border-color: #ffd700;
|
||||||
$gray: #9d9d9d;
|
$gray: #9d9d9d;
|
||||||
$gray-icon: $gray;
|
$gray-icon: $gray;
|
||||||
$light-gray: #c0c0c0;
|
$light-gray: #c0c0c0;
|
||||||
|
|
Loading…
Reference in New Issue