mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
[WIP] Add EventsTree
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
"react-measure": "1.4.6",
|
||||
"react-mosaic-component": "^0.4.0",
|
||||
"react-sortable-hoc": "^0.6.3",
|
||||
"react-sortable-tree": "^0.1.21",
|
||||
"react-tap-event-plugin": "2.0.1",
|
||||
"react-virtualized": "9.3.0",
|
||||
"slug": "0.9.1",
|
||||
|
@@ -165,6 +165,9 @@ class CommentEvent extends Component {
|
||||
children.push(
|
||||
React.createElement('p', {
|
||||
key: 'p',
|
||||
style: {
|
||||
whiteSpace: 'pre-line',
|
||||
},
|
||||
dangerouslySetInnerHTML: {
|
||||
__html: commentEvent
|
||||
.getComment()
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import EventsList from './EventsList';
|
||||
import EventsTree from './EventsTree';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
@@ -23,10 +24,7 @@ export default class EventsSheet extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<EventsList
|
||||
eventsList={this.props.events}
|
||||
callbacks={this.props.callbacks}
|
||||
/>
|
||||
<EventsTree events={this.props.events}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -139,9 +139,6 @@ export default class EventsSheetContainer extends BaseEditor {
|
||||
onEditEventTemplate: () => console.log('onEditEventTemplate'),
|
||||
}}
|
||||
/>
|
||||
<PlaceholderMessage>
|
||||
This editor is not finished yet.
|
||||
</PlaceholderMessage>
|
||||
{this.state.newInstruction.instruction &&
|
||||
<InstructionEditorDialog
|
||||
{...this.state.newInstruction}
|
||||
|
217
newIDE/app/src/EventsSheet/EventsTree/NodeRenderer.js
Normal file
217
newIDE/app/src/EventsSheet/EventsTree/NodeRenderer.js
Normal file
@@ -0,0 +1,217 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import baseStyles from './node-renderer-default.scss';
|
||||
import { isDescendant } from './utils/tree-data-utils';
|
||||
|
||||
let styles = baseStyles;
|
||||
|
||||
class NodeRendererDefault extends Component {
|
||||
render() {
|
||||
const {
|
||||
scaffoldBlockPxWidth,
|
||||
toggleChildrenVisibility,
|
||||
connectDragPreview,
|
||||
connectDragSource,
|
||||
isDragging,
|
||||
canDrop,
|
||||
canDrag,
|
||||
node,
|
||||
draggedNode,
|
||||
path,
|
||||
treeIndex,
|
||||
isSearchMatch,
|
||||
isSearchFocus,
|
||||
buttons,
|
||||
className,
|
||||
style,
|
||||
didDrop,
|
||||
/* eslint-disable no-unused-vars */
|
||||
isOver: _isOver, // Not needed, but preserved for other renderers
|
||||
parentNode: _parentNode, // Needed for drag-and-drop utils
|
||||
endDrag: _endDrag, // Needed for drag-and-drop utils
|
||||
startDrag: _startDrag, // Needed for drag-and-drop utils
|
||||
/* eslint-enable no-unused-vars */
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
let handle;
|
||||
if (canDrag) {
|
||||
if (typeof node.children === 'function' && node.expanded) {
|
||||
// Show a loading symbol on the handle when the children are expanded
|
||||
// and yet still defined by a function (a callback to fetch the children)
|
||||
handle = (
|
||||
<div className={styles.loadingHandle}>
|
||||
<div className={styles.loadingCircle}>
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
<div className={styles.loadingCirclePoint} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
// Show the handle used to initiate a drag-and-drop
|
||||
handle = connectDragSource(<div className={styles.moveHandle} />, {
|
||||
dropEffect: 'copy',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const isDraggedDescendant = draggedNode && isDescendant(draggedNode, node);
|
||||
const isLandingPadActive = !didDrop && isDragging;
|
||||
|
||||
return (
|
||||
<div style={{ height: '100%' }} {...otherProps}>
|
||||
{toggleChildrenVisibility &&
|
||||
node.children &&
|
||||
node.children.length > 0 &&
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label={node.expanded ? 'Collapse' : 'Expand'}
|
||||
className={
|
||||
node.expanded ? styles.collapseButton : styles.expandButton
|
||||
}
|
||||
style={{ left: -0.5 * scaffoldBlockPxWidth }}
|
||||
onClick={() =>
|
||||
toggleChildrenVisibility({
|
||||
node,
|
||||
path,
|
||||
treeIndex,
|
||||
})}
|
||||
/>
|
||||
|
||||
{node.expanded &&
|
||||
!isDragging &&
|
||||
<div
|
||||
style={{ width: scaffoldBlockPxWidth }}
|
||||
className={styles.lineChildren}
|
||||
/>}
|
||||
</div>}
|
||||
|
||||
<div className={styles.rowWrapper}>
|
||||
{/* Set the row preview to be used during drag and drop */}
|
||||
{connectDragPreview(
|
||||
<div
|
||||
className={
|
||||
styles.row +
|
||||
(isLandingPadActive ? ` ${styles.rowLandingPad}` : '') +
|
||||
(isLandingPadActive && !canDrop
|
||||
? ` ${styles.rowCancelPad}`
|
||||
: '') +
|
||||
(isSearchMatch ? ` ${styles.rowSearchMatch}` : '') +
|
||||
(isSearchFocus ? ` ${styles.rowSearchFocus}` : '') +
|
||||
(className ? ` ${className}` : '')
|
||||
}
|
||||
style={{
|
||||
opacity: isDraggedDescendant ? 0.5 : 1,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
{handle}
|
||||
|
||||
<div
|
||||
className={
|
||||
styles.rowContents +
|
||||
(!canDrag ? ` ${styles.rowContentsDragDisabled}` : '')
|
||||
}
|
||||
>
|
||||
<div className={styles.rowLabel}>
|
||||
<span
|
||||
className={
|
||||
styles.rowTitle +
|
||||
(node.subtitle ? ` ${styles.rowTitleWithSubtitle}` : '')
|
||||
}
|
||||
>
|
||||
{typeof node.title === 'function'
|
||||
? node.title({
|
||||
node,
|
||||
path,
|
||||
treeIndex,
|
||||
})
|
||||
: node.title}
|
||||
</span>
|
||||
|
||||
{node.subtitle &&
|
||||
<span className={styles.rowSubtitle}>
|
||||
{typeof node.subtitle === 'function'
|
||||
? node.subtitle({
|
||||
node,
|
||||
path,
|
||||
treeIndex,
|
||||
})
|
||||
: node.subtitle}
|
||||
</span>}
|
||||
</div>
|
||||
|
||||
<div className={styles.rowToolbar}>
|
||||
{buttons.map((btn, index) =>
|
||||
<div
|
||||
key={index} // eslint-disable-line react/no-array-index-key
|
||||
className={styles.toolbarButton}
|
||||
>
|
||||
{btn}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NodeRendererDefault.defaultProps = {
|
||||
isSearchMatch: false,
|
||||
isSearchFocus: false,
|
||||
canDrag: false,
|
||||
toggleChildrenVisibility: null,
|
||||
buttons: [],
|
||||
className: '',
|
||||
style: {},
|
||||
parentNode: null,
|
||||
draggedNode: null,
|
||||
canDrop: false,
|
||||
};
|
||||
|
||||
NodeRendererDefault.propTypes = {
|
||||
node: PropTypes.shape({}).isRequired,
|
||||
path: PropTypes.arrayOf(
|
||||
PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
||||
).isRequired,
|
||||
treeIndex: PropTypes.number.isRequired,
|
||||
isSearchMatch: PropTypes.bool,
|
||||
isSearchFocus: PropTypes.bool,
|
||||
canDrag: PropTypes.bool,
|
||||
scaffoldBlockPxWidth: PropTypes.number.isRequired,
|
||||
toggleChildrenVisibility: PropTypes.func,
|
||||
buttons: PropTypes.arrayOf(PropTypes.node),
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.shape({}),
|
||||
|
||||
// Drag and drop API functions
|
||||
// Drag source
|
||||
connectDragPreview: PropTypes.func.isRequired,
|
||||
connectDragSource: PropTypes.func.isRequired,
|
||||
parentNode: PropTypes.shape({}), // Needed for drag-and-drop utils
|
||||
startDrag: PropTypes.func.isRequired, // Needed for drag-and-drop utils
|
||||
endDrag: PropTypes.func.isRequired, // Needed for drag-and-drop utils
|
||||
isDragging: PropTypes.bool.isRequired,
|
||||
didDrop: PropTypes.bool.isRequired,
|
||||
draggedNode: PropTypes.shape({}),
|
||||
// Drop target
|
||||
isOver: PropTypes.bool.isRequired,
|
||||
canDrop: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default NodeRendererDefault;
|
131
newIDE/app/src/EventsSheet/EventsTree/index.js
Normal file
131
newIDE/app/src/EventsSheet/EventsTree/index.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
SortableTreeWithoutDndContext as SortableTree,
|
||||
getNodeAtPath,
|
||||
} from 'react-sortable-tree';
|
||||
import EventsRenderingService from '../EventsRenderingService';
|
||||
import { mapFor } from '../../Utils/MapFor';
|
||||
|
||||
//TODO: Any change (event not equal to its last height or new event should trigger a recomputeRowHeights)
|
||||
const eventHeights = {};
|
||||
|
||||
class EventRenderer extends Component {
|
||||
componentDidMount() {
|
||||
const height = this._container.clientHeight;
|
||||
console.log(this.props.event.ptr, ' has height ', height);
|
||||
eventHeights[this.props.event.ptr] = height;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {event} = this.props;
|
||||
const EventComponent = EventsRenderingService.getEventComponent(event);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={container => this._container = container}
|
||||
>
|
||||
{EventComponent && <EventComponent event={event}/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const renderEvent = ({ node }) => {
|
||||
const event = node.event;
|
||||
|
||||
return <EventRenderer event={event} key={event.ptr}/>;
|
||||
};
|
||||
|
||||
const toTreeData = (eventsList, flatData = []) => {
|
||||
const treeData = mapFor(0, eventsList.getEventsCount(), i => {
|
||||
const event = eventsList.getEventAt(i);
|
||||
flatData.push(event);
|
||||
|
||||
return {
|
||||
title: renderEvent,
|
||||
event,
|
||||
eventsList,
|
||||
expanded: true,
|
||||
key: event.ptr,
|
||||
children: toTreeData(event.getSubEvents(), flatData).treeData,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
treeData,
|
||||
flatData,
|
||||
};
|
||||
};
|
||||
|
||||
const getNodeKey = ({ treeIndex }) => treeIndex;
|
||||
|
||||
export default class Tree extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
...toTreeData(props.events),
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._list.wrappedInstance.recomputeRowHeights();
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
_onMoveNode = ({ treeData, path, node }) => {
|
||||
// Get the event list where the event should be moved to.
|
||||
const targetPath = path.slice(0, -1);
|
||||
const target = getNodeAtPath({
|
||||
getNodeKey,
|
||||
treeData: treeData,
|
||||
path: targetPath,
|
||||
});
|
||||
const targetNode = target.node;
|
||||
const targetEventsList = targetNode && targetNode.event
|
||||
? targetNode.event.getSubEvents()
|
||||
: this.props.events;
|
||||
const targetPosition = targetNode && targetNode.children
|
||||
? targetNode.children.indexOf(node)
|
||||
: 0;
|
||||
|
||||
// Get the moved event and its list from the moved node.
|
||||
const { event, eventsList } = node;
|
||||
|
||||
// Do the move
|
||||
const newEvent = event.clone();
|
||||
eventsList.removeEvent(event);
|
||||
targetEventsList.insertEvent(newEvent, targetPosition);
|
||||
newEvent.delete();
|
||||
|
||||
this.setState(toTreeData(this.props.events), () => {
|
||||
this._list.wrappedInstance.recomputeRowHeights();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ height: 400 }}>
|
||||
<SortableTree
|
||||
treeData={this.state.treeData}
|
||||
scaffoldBlockPxWidth={22}
|
||||
onChange={() => {}}
|
||||
onMoveNode={this._onMoveNode}
|
||||
rowHeight={({index}) => {
|
||||
const extraBorderMargin = 30;
|
||||
console.log(eventHeights);
|
||||
const event = this.state.flatData[index];
|
||||
console.log(index, "is", event);
|
||||
if (!event) return 60;
|
||||
|
||||
console.log(eventHeights[event.ptr]);
|
||||
return (eventHeights[event.ptr] + extraBorderMargin) || 60;
|
||||
}}
|
||||
reactVirtualizedListProps={{
|
||||
ref: list => this._list = list,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -73,7 +73,7 @@ export default class Instruction extends Component {
|
||||
);
|
||||
|
||||
return React.createElement(
|
||||
'span',
|
||||
'div',
|
||||
{
|
||||
className: 'instruction ' +
|
||||
(instruction.dragging ? 'dragged-instruction ' : '') +
|
||||
|
@@ -85,6 +85,45 @@ export const testLayoutInstance1 = testLayout.getInitialInstances().insertNewIni
|
||||
testLayoutInstance1.setX(10);
|
||||
testLayoutInstance1.setY(15);
|
||||
|
||||
//Create a few events
|
||||
//Add a new "standard" event to the scene:
|
||||
var evt = testLayout.getEvents().insertNewEvent(project, "BuiltinCommonInstructions::Standard", 0);
|
||||
var evt2 = testLayout.getEvents().insertNewEvent(project, "BuiltinCommonInstructions::Standard", 1);
|
||||
var standardEvt = gd.asStandardEvent(evt); //We need to "cast" the event to use its specific methods (getConditions and getActions):
|
||||
|
||||
const makeKeyPressedCondition = () => {
|
||||
const condition = new gd.Instruction();
|
||||
condition.setType("KeyPressed");
|
||||
condition.setParametersCount(2);
|
||||
condition.setParameter(1, "Space");
|
||||
return condition;
|
||||
}
|
||||
|
||||
const makeDeleteAction = (objectToDelete) => {
|
||||
var action = new gd.Instruction(); //Add a simple action
|
||||
action.setType("Delete");
|
||||
action.setParametersCount(2);
|
||||
action.setParameter(0, objectToDelete);
|
||||
return action;
|
||||
}
|
||||
|
||||
standardEvt.getConditions().push_back(makeKeyPressedCondition());
|
||||
standardEvt.getActions().push_back(makeDeleteAction("MyCharacter"));
|
||||
|
||||
//Add a few sub events:
|
||||
{
|
||||
const subEvent = evt.getSubEvents().insertNewEvent(project, "BuiltinCommonInstructions::Standard", 0);
|
||||
const subStandardEvt = gd.asStandardEvent(subEvent);
|
||||
subStandardEvt.getConditions().push_back(makeKeyPressedCondition());
|
||||
subStandardEvt.getActions().push_back(makeDeleteAction("MyCharacter1"));
|
||||
subStandardEvt.getActions().push_back(makeDeleteAction("MyCharacter2"));
|
||||
}
|
||||
{
|
||||
const subEvent = evt.getSubEvents().insertNewEvent(project, "BuiltinCommonInstructions::Comment", 0);
|
||||
const subCommentEvt = gd.asCommentEvent(subEvent);
|
||||
subCommentEvt.setComment("Kain is deified. The clans tell tales of him, few know the truth. He was mortal once, as were we all. However, his contempt for humanity drove him to create me and my brethren. I am Raziel, first born of his lieutenants. I stood with Kain and my brethren at the dawn of the empire. I have served him a millennium. Over time we became less human and more ... divine.");
|
||||
}
|
||||
|
||||
// Global objects
|
||||
const globalTextObject = new gd.TextObject('GlobalTextObject');
|
||||
const globalTiledSpriteObject = new gd.TiledSpriteObject('GlobalTiledSpriteObject');
|
||||
|
@@ -23,10 +23,14 @@ import EmptyEditor from '../ObjectEditor/Editors/EmptyEditor';
|
||||
import ShapePainterEditor from '../ObjectEditor/Editors/ShapePainterEditor';
|
||||
import AdMobEditor from '../ObjectEditor/Editors/AdMobEditor';
|
||||
import ObjectsList from '../ObjectsList';
|
||||
import InstancePropertiesEditor from '../InstancesEditor/InstancePropertiesEditor';
|
||||
import InstancePropertiesEditor
|
||||
from '../InstancesEditor/InstancePropertiesEditor';
|
||||
import SerializedObjectDisplay from './SerializedObjectDisplay';
|
||||
import EventsTree from '../EventsSheet/EventsTree';
|
||||
import muiDecorator from './MuiDecorator';
|
||||
import paperDecorator from './PaperDecorator';
|
||||
import DragDropContextProvider
|
||||
from '../Utils/DragDropHelpers/DragDropContextProvider';
|
||||
import {
|
||||
project,
|
||||
shapePainterObject,
|
||||
@@ -104,16 +108,12 @@ storiesOf('LocalS3Export', module)
|
||||
storiesOf('LocalMobileExport', module)
|
||||
.addDecorator(paperDecorator)
|
||||
.addDecorator(muiDecorator)
|
||||
.add('default', () => (
|
||||
<LocalMobileExport />
|
||||
));
|
||||
.add('default', () => <LocalMobileExport />);
|
||||
|
||||
storiesOf('LocalFolderPicker', module)
|
||||
.addDecorator(paperDecorator)
|
||||
.addDecorator(muiDecorator)
|
||||
.add('default', () => (
|
||||
<LocalFolderPicker floatingLabelText="Export folder" />
|
||||
))
|
||||
.add('default', () => <LocalFolderPicker floatingLabelText="Export folder" />)
|
||||
.add('full width', () => (
|
||||
<LocalFolderPicker floatingLabelText="Export folder" fullWidth />
|
||||
));
|
||||
@@ -135,6 +135,10 @@ storiesOf('DragHandle', module)
|
||||
.addDecorator(muiDecorator)
|
||||
.add('default', () => <DragHandle />);
|
||||
|
||||
storiesOf('EventsTree', module).add('default', () => (
|
||||
<DragDropContextProvider><EventsTree events={testLayout.getEvents()} /></DragDropContextProvider>
|
||||
));
|
||||
|
||||
storiesOf('TextEditor', module)
|
||||
.addDecorator(paperDecorator)
|
||||
.addDecorator(muiDecorator)
|
||||
@@ -192,16 +196,14 @@ storiesOf('AdMobEditor', module)
|
||||
storiesOf('EmptyEditor', module)
|
||||
.addDecorator(paperDecorator)
|
||||
.addDecorator(muiDecorator)
|
||||
.add('default', () => (
|
||||
<EmptyEditor />
|
||||
));
|
||||
.add('default', () => <EmptyEditor />);
|
||||
|
||||
storiesOf('ObjectsList', module)
|
||||
.addDecorator(paperDecorator)
|
||||
.addDecorator(muiDecorator)
|
||||
.add('default', () => (
|
||||
<SerializedObjectDisplay object={testLayout}>
|
||||
<div style={{height: 250}}>
|
||||
<div style={{ height: 250 }}>
|
||||
<ObjectsList
|
||||
getThumbnail={() => 'res/unknown32.png'}
|
||||
project={project}
|
||||
|
@@ -4413,6 +4413,10 @@ lodash.isarray@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
|
||||
|
||||
lodash.isequal@^4.4.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
lodash.keys@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
|
||||
@@ -4450,7 +4454,7 @@ lodash.templatesettings@^4.0.0:
|
||||
dependencies:
|
||||
lodash._reinterpolate "~3.0.0"
|
||||
|
||||
lodash.throttle@^4.1.1:
|
||||
lodash.throttle@^4.0.1, lodash.throttle@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
|
||||
@@ -5118,6 +5122,10 @@ performance-now@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
|
||||
pify@^2.0.0, pify@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
@@ -5638,6 +5646,12 @@ quote-stream@~0.0.0:
|
||||
minimist "0.0.8"
|
||||
through2 "~0.4.1"
|
||||
|
||||
raf@^3.2.0:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.2.tgz#0c13be0b5b49b46f76d6669248d527cf2b02fe27"
|
||||
dependencies:
|
||||
performance-now "^2.1.0"
|
||||
|
||||
randomatic@^1.1.3:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb"
|
||||
@@ -5708,12 +5722,26 @@ react-dev-utils@^2.0.1:
|
||||
strip-ansi "3.0.1"
|
||||
text-table "0.2.0"
|
||||
|
||||
react-display-name@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.0.tgz#0e1f7086e45a32d07764df35ed32ff16f1259790"
|
||||
|
||||
react-dnd-html5-backend@2.3.0, react-dnd-html5-backend@^2.1.2:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-2.3.0.tgz#a45ce593f5c6944aa01114b368117c56c954804e"
|
||||
dependencies:
|
||||
lodash "^4.2.0"
|
||||
|
||||
react-dnd-scrollzone@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dnd-scrollzone/-/react-dnd-scrollzone-4.0.0.tgz#d707170c0cd3b7ab3d991dd6a8cc0b3712454139"
|
||||
dependencies:
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
lodash.throttle "^4.0.1"
|
||||
prop-types "^15.5.9"
|
||||
raf "^3.2.0"
|
||||
react-display-name "^0.2.0"
|
||||
|
||||
react-dnd@2.3.0, react-dnd@^2.1.4:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-2.3.0.tgz#aede61c06b968554dcf2a2445657cdbb3100be49"
|
||||
@@ -5884,6 +5912,17 @@ react-sortable-hoc@^0.6.3:
|
||||
lodash "^4.12.0"
|
||||
prop-types "^15.5.7"
|
||||
|
||||
react-sortable-tree@^0.1.21:
|
||||
version "0.1.21"
|
||||
resolved "https://registry.yarnpkg.com/react-sortable-tree/-/react-sortable-tree-0.1.21.tgz#26a05de2012ffa46a5a4db2b71274371257daeb8"
|
||||
dependencies:
|
||||
lodash.isequal "^4.4.0"
|
||||
prop-types "^15.5.8"
|
||||
react-dnd "^2.1.4"
|
||||
react-dnd-html5-backend "^2.1.2"
|
||||
react-dnd-scrollzone "^4.0.0"
|
||||
react-virtualized "^9.9.0"
|
||||
|
||||
react-split-pane@^0.1.63:
|
||||
version "0.1.63"
|
||||
resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.63.tgz#fadb3960cc659911dd05ffbc88acee4be9f53583"
|
||||
@@ -5929,6 +5968,16 @@ react-virtualized:
|
||||
dom-helpers "^2.4.0 || ^3.0.0"
|
||||
loose-envify "^1.3.0"
|
||||
|
||||
react-virtualized@^9.9.0:
|
||||
version "9.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.9.0.tgz#799a6f23819eeb82860d59b82fad33d1d420325e"
|
||||
dependencies:
|
||||
babel-runtime "^6.11.6"
|
||||
classnames "^2.2.3"
|
||||
dom-helpers "^2.4.0 || ^3.0.0"
|
||||
loose-envify "^1.3.0"
|
||||
prop-types "^15.5.4"
|
||||
|
||||
react@15.4.2:
|
||||
version "15.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef"
|
||||
|
Reference in New Issue
Block a user