From 17df475c11ad0eb07ae15f3d287301d433c31e0e Mon Sep 17 00:00:00 2001 From: jos Date: Wed, 3 Oct 2018 15:06:55 +0200 Subject: [PATCH] Move some logic to `TreeModeMenu` and some small tweaks and fixes --- src/jsoneditor/components/JSONNode.js | 4 +- src/jsoneditor/components/TreeMode.js | 47 +++++++------------ src/jsoneditor/components/jsoneditor.scss | 26 +++++----- .../components/menu/TreeModeMenu.js | 41 ++++++++-------- src/jsoneditor/components/style.scss | 8 +++- 5 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/jsoneditor/components/JSONNode.js b/src/jsoneditor/components/JSONNode.js index 8338e6e..50d7b6a 100644 --- a/src/jsoneditor/components/JSONNode.js +++ b/src/jsoneditor/components/JSONNode.js @@ -427,8 +427,8 @@ export default class JSONNode extends PureComponent { onMouseOver: this.updatePopoverDirection }, [ - h('i', {className: 'fa fa-exclamation-triangle'}), - h('div', {className: 'jsoneditor-popover jsoneditor-right'}, error.message) + h('i', {className: 'fa fa-exclamation-triangle', key: 'icon'}), + h('div', {className: 'jsoneditor-popover jsoneditor-right', 'key': 'message'}, error.message) ] ) } diff --git a/src/jsoneditor/components/TreeMode.js b/src/jsoneditor/components/TreeMode.js index 9a7cdd1..514f468 100644 --- a/src/jsoneditor/components/TreeMode.js +++ b/src/jsoneditor/components/TreeMode.js @@ -276,43 +276,31 @@ export default class TreeMode extends PureComponent { } 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, { key: 'menu', + selection: this.state.selection, + clipboard: this.state.clipboard, + history: this.state.history, + mode: this.props.mode, modes: this.props.modes, onChangeMode: this.props.onChangeMode, - canCut: hasSelection, - canCopy: hasSelection, - canPaste: hasClipboard && hasCursor, onCut: this.handleCut, onCopy: this.handleCopy, onPaste: this.handlePaste, - canInsert: hasCursor, - canDuplicate: hasSelection, - canRemove: hasSelection, onInsert: this.handleInsert, onDuplicate: this.handleDuplicate, onRemove: this.handleRemove, - canSort: hasSelection || hasCursor, - canTransform: hasSelection || hasCursor, canSearch: this.props.search, onSort: this.handleSort, onTransform: this.handleTransform, onToggleSearch: this.toggleSearch, enableHistory: this.props.history, - canUndo: this.canUndo(), - canRedo: this.canRedo(), onUndo: this.undo, onRedo: this.redo, }) @@ -1055,16 +1043,8 @@ export default class TreeMode extends PureComponent { this.redo() } - canUndo = () => { - return this.state.historyIndex < this.state.history.length - } - - canRedo = () => { - return this.state.historyIndex > 0 - } - undo = () => { - if (this.canUndo()) { + if (this.state.historyIndex < this.state.history.length) { const history = this.state.history const historyIndex = this.state.historyIndex const historyItem = history[historyIndex] @@ -1074,7 +1054,10 @@ export default class TreeMode extends PureComponent { const { eson, searchResult } = (this.state.searchText) ? applySearch(esonResult.json, this.state.searchText) - : { eson: esonResult.json, searchResult: null } + : { + eson: esonResult.json, + searchResult: { matches: null, active: null } + } this.setState({ json, @@ -1090,7 +1073,7 @@ export default class TreeMode extends PureComponent { } redo = () => { - if (this.canRedo()) { + if (this.state.historyIndex > 0) { const history = this.state.history const historyIndex = this.state.historyIndex - 1 const historyItem = history[historyIndex] @@ -1100,7 +1083,10 @@ export default class TreeMode extends PureComponent { const { eson, searchResult } = (this.state.searchText) ? applySearch(esonResult.json, this.state.searchText) - : { eson: esonResult.json, searchResult: null } + : { + eson: esonResult.json, + searchResult: { matches: null, active: null } + } this.setState({ json, @@ -1138,7 +1124,10 @@ export default class TreeMode extends PureComponent { const { eson, searchResult } = (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) { // update data and store history diff --git a/src/jsoneditor/components/jsoneditor.scss b/src/jsoneditor/components/jsoneditor.scss index d102f43..925a3bc 100644 --- a/src/jsoneditor/components/jsoneditor.scss +++ b/src/jsoneditor/components/jsoneditor.scss @@ -238,19 +238,19 @@ div.jsoneditor-value.jsoneditor-empty::after { } .jsoneditor-highlight { - background-color: yellow; + background-color: $highlight-color; } .jsoneditor-highlight:hover { - background-color: #f0f000; + background-color: $highlight-hover-color; } .jsoneditor-highlight-active { - background-color: #ffd700; + background-color: $highlight-active-color; } .jsoneditor-highlight-active:hover { - background-color: #f3cd00; + background-color: $highlight-active-hover-color; } .jsoneditor-button-placeholder { @@ -298,16 +298,16 @@ div.jsoneditor-node-container { &.jsoneditor-selected { .jsoneditor-node { - background-color: $selectedColor; + background-color: $selected-color; } .jsoneditor-delimiter-end { - background-color: $selectedColor; - border-left-color: $selectedColor; + background-color: $selected-color; + border-left-color: $selected-color; } .jsoneditor-list { - border-left-color: $selectedColor; + border-left-color: $selected-color; } } @@ -315,7 +315,7 @@ div.jsoneditor-node-container { &.jsoneditor-node-expanded { .jsoneditor-node-end { - background-color: $selectedColor; + background-color: $selected-color; > .jsoneditor-delimiter-end { background-color: white; @@ -324,7 +324,7 @@ div.jsoneditor-node-container { } &.jsoneditor-node-collapsed { - background-color: $selectedColor; + background-color: $selected-color; > .jsoneditor-node { background-color: white; @@ -335,7 +335,7 @@ div.jsoneditor-node-container { &.jsoneditor-selected-before-childs { > .jsoneditor-node > .jsoneditor-before-childs { - background-color: $selectedColor; + background-color: $selected-color; width: 40px; // FIXME: should use full remaining width } } @@ -434,8 +434,8 @@ div.jsoneditor-code { .jsoneditor-errors { width: 100%; - background-color: #ffef8b; - border-top: 1px solid #ffd700; + background-color: $error-background-color; + border-top: 1px solid $error-border-color; table { border-collapse: collapse; diff --git a/src/jsoneditor/components/menu/TreeModeMenu.js b/src/jsoneditor/components/menu/TreeModeMenu.js index abdea0e..ebe075a 100644 --- a/src/jsoneditor/components/menu/TreeModeMenu.js +++ b/src/jsoneditor/components/menu/TreeModeMenu.js @@ -1,3 +1,4 @@ +import isEmpty from 'lodash/isEmpty' import { createElement as h, PureComponent } from 'react' import DropDown from './DropDown' import PropTypes from 'prop-types' @@ -30,34 +31,27 @@ fontawesome.library.add( export default class TreeModeMenu extends PureComponent { static propTypes = { + selection: PropTypes.object, + clipboard: PropTypes.array, + history: PropTypes.array, + mode: PropTypes.string.isRequired, modes: PropTypes.arrayOf(PropTypes.string), onChangeMode: PropTypes.func.isRequired, - canCut: PropTypes.bool.isRequired, - canCopy: PropTypes.bool.isRequired, - canPaste: PropTypes.bool.isRequired, onCut: PropTypes.func.isRequired, onCopy: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired, - canInsert: PropTypes.bool.isRequired, - canDuplicate: PropTypes.bool.isRequired, - canRemove: PropTypes.bool.isRequired, onInsert: PropTypes.func.isRequired, onDuplicate: PropTypes.func.isRequired, onRemove: PropTypes.func.isRequired, - canSort: PropTypes.bool.isRequired, - canTransform: PropTypes.bool.isRequired, - canSearch: PropTypes.bool.isRequired, onSort: PropTypes.func.isRequired, onTransform: PropTypes.func.isRequired, onToggleSearch: PropTypes.func, enableHistory: PropTypes.bool, - canUndo: PropTypes.bool, - canRedo: PropTypes.bool, onUndo: PropTypes.func, onRedo: PropTypes.func } @@ -65,6 +59,11 @@ export default class TreeModeMenu extends PureComponent { render () { 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 if (this.props.modes ) { items = items.concat([ @@ -92,27 +91,28 @@ export default class TreeModeMenu extends PureComponent { key: 'cut', className: 'jsoneditor-cut', title: 'Cut current selection', - disabled: !this.props.canCut, + disabled: !hasSelectedContent, onClick: this.props.onCut }, h('i', {className: 'fa fa-cut'})), h('button', { key: 'copy', className: 'jsoneditor-copy', title: 'Copy current selection', - disabled: !this.props.canCopy, + disabled: !hasSelectedContent, onClick: this.props.onCopy }, h('i', {className: 'fa fa-copy'})), h('button', { key: 'paste', className: 'jsoneditor-paste', title: 'Paste copied selection', - disabled: !this.props.canPaste, + disabled: !(hasClipboard && hasCursor), onClick: this.props.onPaste }, 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([ h('div', {className: 'jsoneditor-menu-group', key: 'insert-duplicate-remove'}, [ h(DropDown, { @@ -126,14 +126,14 @@ export default class TreeModeMenu extends PureComponent { key: 'duplicate', className: 'jsoneditor-duplicate', title: 'Duplicate current selection', - disabled: !this.props.canDuplicate, + disabled: !hasSelectedContent, onClick: this.props.onDuplicate }, h('i', {className: 'fa fa-clone'})), h('button', { key: 'remove', className: 'jsoneditor-remove', title: 'Remove selection', - disabled: !this.props.canRemove, + disabled: !hasSelectedContent, onClick: this.props.onRemove }, h('i', {className: 'fa fa-times'})) ]) @@ -167,20 +167,23 @@ export default class TreeModeMenu extends PureComponent { // undo / redo 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([ h('div', {className: 'jsoneditor-menu-group', key: 'undo-redo'}, [ h('button', { key: 'undo', className: 'jsoneditor-undo', title: 'Undo last action', - disabled: !this.props.canUndo, + disabled: !canUndo, onClick: this.props.onUndo }, h('i', {className: 'fa fa-undo'})), h('button', { key: 'redo', className: 'jsoneditor-redo', title: 'Redo', - disabled: !this.props.canRedo, + disabled: !canRedo, onClick: this.props.onRedo }, h('i', {className: 'fa fa-redo'})) ]) diff --git a/src/jsoneditor/components/style.scss b/src/jsoneditor/components/style.scss index 5e4d098..c99a995 100644 --- a/src/jsoneditor/components/style.scss +++ b/src/jsoneditor/components/style.scss @@ -9,8 +9,14 @@ $theme-color: #3883fa; $theme-color-light: lighten($theme-color, 5); $floating-menu-background: #4d4d4d; $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; +$error-background-color: #ffef8b; +$error-border-color: #ffd700; $gray: #9d9d9d; $gray-icon: $gray; $light-gray: #c0c0c0;