Moved tree mode menu in a separate component
This commit is contained in:
parent
3028617ff7
commit
0fb816d074
|
@ -63,6 +63,7 @@ import {
|
||||||
search,
|
search,
|
||||||
syncEson
|
syncEson
|
||||||
} from '../eson'
|
} from '../eson'
|
||||||
|
import TreeModeMenu from './menu/TreeModeMenu'
|
||||||
|
|
||||||
const AJV_OPTIONS = {
|
const AJV_OPTIONS = {
|
||||||
allErrors: true,
|
allErrors: true,
|
||||||
|
@ -71,7 +72,6 @@ const AJV_OPTIONS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_HISTORY_ITEMS = 1000 // maximum number of undo/redo items to be kept in memory
|
const MAX_HISTORY_ITEMS = 1000 // maximum number of undo/redo items to be kept in memory
|
||||||
const SEARCH_DEBOUNCE = 300 // milliseconds
|
|
||||||
const SCROLL_DURATION = 400 // milliseconds
|
const SCROLL_DURATION = 400 // milliseconds
|
||||||
|
|
||||||
export default class TreeMode extends PureComponent {
|
export default class TreeMode extends PureComponent {
|
||||||
|
@ -268,74 +268,28 @@ export default class TreeMode extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenu () {
|
renderMenu () {
|
||||||
let items = [
|
return h(TreeModeMenu, {
|
||||||
h('button', {
|
mode: this.props.mode,
|
||||||
key: 'expand-all',
|
modes: this.props.modes,
|
||||||
className: 'jsoneditor-expand-all',
|
onChangeMode: this.props.onChangeMode,
|
||||||
title: 'Expand all objects and arrays',
|
|
||||||
onClick: this.handleExpandAll
|
|
||||||
}),
|
|
||||||
h('button', {
|
|
||||||
key: 'collapse-all',
|
|
||||||
className: 'jsoneditor-collapse-all',
|
|
||||||
title: 'Collapse all objects and arrays',
|
|
||||||
onClick: this.handleCollapseAll
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
if (this.props.mode !== 'view' && this.props.history !== false) {
|
onExpandAll: this.handleExpandAll,
|
||||||
items = items.concat([
|
onCollapseAll: this.handleCollapseAll,
|
||||||
h('div', {key: 'history-separator', className: 'jsoneditor-vertical-menu-separator'}),
|
|
||||||
|
|
||||||
h('button', {
|
enableHistory: this.props.history,
|
||||||
key: 'undo',
|
canUndo: this.canUndo(),
|
||||||
className: 'jsoneditor-undo',
|
canRedo: this.canRedo(),
|
||||||
title: 'Undo last action',
|
onUndo: this.undo,
|
||||||
disabled: !this.canUndo(),
|
onRedo: this.redo,
|
||||||
onClick: this.undo
|
|
||||||
}),
|
|
||||||
h('button', {
|
|
||||||
key: 'redo',
|
|
||||||
className: 'jsoneditor-redo',
|
|
||||||
title: 'Redo',
|
|
||||||
disabled: !this.canRedo(),
|
|
||||||
onClick: this.redo
|
|
||||||
})
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.modes ) {
|
enableSearch: this.props.search,
|
||||||
items = items.concat([
|
searchResult: this.state.searchResult,
|
||||||
h('div', {key: 'mode-separator', className: 'jsoneditor-vertical-menu-separator'}),
|
onSearch: this.handleSearch,
|
||||||
|
onSearchNext: this.handleNext,
|
||||||
|
onSearchPrevious: this.handlePrevious,
|
||||||
|
|
||||||
h(ModeButton, {
|
findKeyBinding: this.findKeyBinding,
|
||||||
key: 'mode',
|
})
|
||||||
modes: this.props.modes,
|
|
||||||
mode: this.props.mode,
|
|
||||||
onChangeMode: this.props.onChangeMode,
|
|
||||||
onError: this.props.onError
|
|
||||||
})
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.searchResult !== false) {
|
|
||||||
// option search is true or undefined
|
|
||||||
items = items.concat([
|
|
||||||
h('div', {key: 'search', className: 'jsoneditor-menu-panel-right'},
|
|
||||||
h(Search, {
|
|
||||||
text: this.state.searchResult.text,
|
|
||||||
resultCount: this.state.searchResult.matches ? this.state.searchResult.matches.length : 0,
|
|
||||||
onChange: this.handleSearch,
|
|
||||||
onNext: this.handleNext,
|
|
||||||
onPrevious: this.handlePrevious,
|
|
||||||
findKeyBinding: this.findKeyBinding,
|
|
||||||
delay: SEARCH_DEBOUNCE
|
|
||||||
})
|
|
||||||
)
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
return h('div', {key: 'menu', className: 'jsoneditor-menu'}, items)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,19 +1,6 @@
|
||||||
|
@import './style.scss';
|
||||||
@import './popover.scss';
|
@import './popover.scss';
|
||||||
|
|
||||||
$fontFamily: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif;
|
|
||||||
$fontSize: 10pt;
|
|
||||||
$black: #1A1A1A;
|
|
||||||
$contentsMinHeight: 150px;
|
|
||||||
$theme-color: #3883fa; // TODO: create a central file with the theme colors
|
|
||||||
$floating-menu-background: #4d4d4d;
|
|
||||||
$floating-menu-color: #fff;
|
|
||||||
$selectedColor: #ffed99;
|
|
||||||
$hoverColor: #d3d3d3;
|
|
||||||
$hoverAndSelectedColor: #ffdb80;
|
|
||||||
$gray: #9d9d9d;
|
|
||||||
$light-gray: #c0c0c0;
|
|
||||||
$input-padding: 5px;
|
|
||||||
|
|
||||||
// TODO: split this scss file into separate files per React component
|
// TODO: split this scss file into separate files per React component
|
||||||
|
|
||||||
$line-height: 20px;
|
$line-height: 20px;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createElement as h, Component } from 'react'
|
import { createElement as h, Component } from 'react'
|
||||||
import ModeMenu from './ModeMenu'
|
import ModeSelector from './ModeSelector'
|
||||||
import { toCapital } from '../../utils/stringUtils'
|
import { toCapital } from '../../utils/stringUtils'
|
||||||
|
|
||||||
export default class ModeButton extends Component {
|
export default class ModeButton extends Component {
|
||||||
|
@ -24,7 +24,7 @@ export default class ModeButton extends Component {
|
||||||
onClick: this.handleOpen
|
onClick: this.handleOpen
|
||||||
}, `${toCapital(props.mode)} \u25BC`),
|
}, `${toCapital(props.mode)} \u25BC`),
|
||||||
|
|
||||||
h(ModeMenu, {
|
h(ModeSelector, {
|
||||||
key: 'menu',
|
key: 'menu',
|
||||||
...props,
|
...props,
|
||||||
open: state.open,
|
open: state.open,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { keyComboFromEvent } from '../../utils/keyBindings'
|
||||||
const MENU_CLASS_NAME = 'jsoneditor-actionmenu'
|
const MENU_CLASS_NAME = 'jsoneditor-actionmenu'
|
||||||
const MODE_MENU_CLASS_NAME = MENU_CLASS_NAME + ' jsoneditor-modemenu'
|
const MODE_MENU_CLASS_NAME = MENU_CLASS_NAME + ' jsoneditor-modemenu'
|
||||||
|
|
||||||
export default class ModeMenu extends Component {
|
export default class ModeSelector extends Component {
|
||||||
/**
|
/**
|
||||||
* {{open, modes, mode, onChangeMode, onRequestClose, onError}} props
|
* {{open, modes, mode, onChangeMode, onRequestClose, onError}} props
|
||||||
*/
|
*/
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { createElement as h, PureComponent } from 'react'
|
||||||
|
import ModeButton from './ModeButton'
|
||||||
|
import Search from './Search'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
const SEARCH_DEBOUNCE = 300 // milliseconds
|
||||||
|
|
||||||
|
export default class TreeModeMenu extends PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
mode: PropTypes.string.isRequired,
|
||||||
|
modes: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
onChangeMode: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
onExpandAll: PropTypes.func.isRequired,
|
||||||
|
onCollapseAll: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
enableHistory: PropTypes.bool,
|
||||||
|
canUndo: PropTypes.bool,
|
||||||
|
canRedo: PropTypes.bool,
|
||||||
|
onUndo: PropTypes.func,
|
||||||
|
onRedo: PropTypes.func,
|
||||||
|
|
||||||
|
enableSearch: PropTypes.bool,
|
||||||
|
searchResult: PropTypes.string,
|
||||||
|
onSearch: PropTypes.func,
|
||||||
|
onSearchNext: PropTypes.func,
|
||||||
|
onSearchPrevious: PropTypes.func,
|
||||||
|
|
||||||
|
findKeyBinding: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let items = [
|
||||||
|
h('button', {
|
||||||
|
key: 'expand-all',
|
||||||
|
className: 'jsoneditor-expand-all',
|
||||||
|
title: 'Expand all objects and arrays',
|
||||||
|
onClick: this.props.onExpandAll
|
||||||
|
}),
|
||||||
|
h('button', {
|
||||||
|
key: 'collapse-all',
|
||||||
|
className: 'jsoneditor-collapse-all',
|
||||||
|
title: 'Collapse all objects and arrays',
|
||||||
|
onClick: this.props.onCollapseAll
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
if (this.props.mode !== 'view' && this.props.enableHistory !== false) {
|
||||||
|
items = items.concat([
|
||||||
|
h('div', {key: 'history-separator', className: 'jsoneditor-vertical-menu-separator'}),
|
||||||
|
|
||||||
|
h('button', {
|
||||||
|
key: 'undo',
|
||||||
|
className: 'jsoneditor-undo',
|
||||||
|
title: 'Undo last action',
|
||||||
|
disabled: !this.props.canUndo,
|
||||||
|
onClick: this.props.onUndo
|
||||||
|
}),
|
||||||
|
h('button', {
|
||||||
|
key: 'redo',
|
||||||
|
className: 'jsoneditor-redo',
|
||||||
|
title: 'Redo',
|
||||||
|
disabled: !this.props.canRedo,
|
||||||
|
onClick: this.props.onRedo
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.modes ) {
|
||||||
|
items = items.concat([
|
||||||
|
h('div', {key: 'mode-separator', className: 'jsoneditor-vertical-menu-separator'}),
|
||||||
|
|
||||||
|
h(ModeButton, {
|
||||||
|
key: 'mode',
|
||||||
|
modes: this.props.modes,
|
||||||
|
mode: this.props.mode,
|
||||||
|
onChangeMode: this.props.onChangeMode,
|
||||||
|
onError: this.props.onError
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.enableSearch !== false) {
|
||||||
|
// option search is true or undefined
|
||||||
|
items = items.concat([
|
||||||
|
h('div', {key: 'search', className: 'jsoneditor-menu-panel-right'},
|
||||||
|
h(Search, {
|
||||||
|
text: this.props.searchResult.text,
|
||||||
|
resultCount: this.props.searchResult.matches ? this.props.searchResult.matches.length : 0,
|
||||||
|
onChange: this.props.onSearch,
|
||||||
|
onNext: this.props.onSearchNext,
|
||||||
|
onPrevious: this.props.onSearchPrevious,
|
||||||
|
findKeyBinding: this.props.findKeyBinding,
|
||||||
|
delay: SEARCH_DEBOUNCE
|
||||||
|
})
|
||||||
|
)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
return h('div', {key: 'menu', className: 'jsoneditor-menu'}, items)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
$fontFamily: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif;
|
||||||
|
$fontSize: 10pt;
|
||||||
|
$black: #1A1A1A;
|
||||||
|
$contentsMinHeight: 150px;
|
||||||
|
$theme-color: #3883fa;
|
||||||
|
$theme-color-light: lighten($theme-color, 5);
|
||||||
|
$floating-menu-background: #4d4d4d;
|
||||||
|
$floating-menu-color: #fff;
|
||||||
|
$selectedColor: #ffed99;
|
||||||
|
$hoverColor: #d3d3d3;
|
||||||
|
$hoverAndSelectedColor: #ffdb80;
|
||||||
|
$gray: #9d9d9d;
|
||||||
|
$light-gray: #c0c0c0;
|
||||||
|
$input-padding: 5px;
|
Loading…
Reference in New Issue