Move some logic to `TreeModeMenu` and some small tweaks and fixes

This commit is contained in:
jos 2018-10-03 15:06:55 +02:00
parent 21d8db13d0
commit 17df475c11
5 changed files with 62 additions and 64 deletions

View File

@ -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)
] ]
) )
} }

View File

@ -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

View File

@ -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;

View File

@ -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'}))
]) ])

View File

@ -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;