storybook-eol / react-treebeard Goto Github PK
View Code? Open in Web Editor NEWReact Tree View Component. Data-Driven, Fast, Efficient and Customisable.
Home Page: http://storybooks.github.io/react-treebeard
License: MIT License
React Tree View Component. Data-Driven, Fast, Efficient and Customisable.
Home Page: http://storybooks.github.io/react-treebeard
License: MIT License
React.createClass
has been deprecated and extracted to it's own package since React v15.5.0.
The following warning is displayed if that version of React is used:
Warning: Calendar: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.
See Migrating from React.createClass
to fix this.
This could be a temporary fix, but I think moving to ES6 classes is more appropriate :-)
CC: @alexcurtis
I see that the package.json file now allows react 15.x as a peer dependency, but when installing the package from npm, the peer dependencies still expect react 0.14. When do you expect to bump the version number and republish to NPM?
I ask because we just implemented this component in a project that depends on react 15, but our travis builds are now failing because of this peer dep.
Hi
I copy style.js file from examples. In this file i can change color of selector (selected item), but i don't undestand how set font color?
Hi
First thanks for the great library.
Quick question, from the react doc:
Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.
However we do mutate the state in the doc example of this repo:
if(this.state.cursor){this.state.cursor.active = false;}
I tried using setState with a spread operator but it would not work:
this.setState({ cursor: {...this.state.cursor, active:false} });
So it seems that the cursor is used as a pointer to the selected node. It works and may be completely valid but I guess it confuses me. Is it the normal way to go?
Thanks
Is it possible to detect a double click on a node? I can't see anything in the docs about it and haven't had much luck trying to implement it.
Thanks in advance.
Hey Alex, thanks for the awesome component you made.
In order to start this new year with an update on your repo, I'd like to suggest an improvement that would allow for deeper style customization:
Allow custom <li>
element styling.
In the project I'm using treebeard right now, I'm displaying a pretty big tree (JSON data is approx 3600 lines). Having this much data makes it hard to scan the page easily because of the fact every single entry is on its very own line.
To make it easier on the eye, I'd like last-level children to have css display
set to inline-block
(last level means to me they have no children attribute, or that they have one, but the children array is empty).
Yeah, sure! So, basically in your example, that would be the files. They would no more behave as block elements, but as inline-block elements. Here's a screenshot with your original on the left, and how I would like things to be displayed on the right (left the console opened so you check the very basic styles I applied to files):
Please note that I didn't change any of your data to make this screenshot, but in my usecase, I'd put any file before folders in the data source so it's more logical when you display files as inline-block. So index.js
would be listed first in src
, and then the component
folder (as it would make it easier to quickly spot which files belong to which folder when files are displayed first in the subtree). Same thing for Gulpfile.js
index.js
and package.json
that are currently displayed last, they'd have to be listed first in the root folder.
I guess it's pretty simple how it could work, in my idea, you would simply add a new data attribute, like display
that could be set to either "block" or "inline" (I'm omitting the -block here for brevity and I'm not sure that a display type of inline would ever be needed, so maybe the "-block" part could be optional).
The only minor potential issue that I see is that you need to make sure the "activeLink" css can also be set to a custom style matching whatever padding / margins you decide to put on the inline-block elements.
Does that make any sense to you?
having a project which uses office react.min.js externally. While trying to include this component, npm downloads react anyway and hence multiple version of react is loaded. Is there a way to get around with this?
Thank you
Hi alexcurtis
I've the the same problem as in issue #27
The tree is shown correctly on initial render but clicking nodes does nothing - can't expand/collapse, active node not highlighted.
Hi -- We're doing a quick evaluation, and lifted the code from the Readme Quick Start. It works correctly on first render, but clicks to toggle do not change the DOM or styles. I verified that this.onToggle is called, and the toggled state of individual nodes does change, but there are no changes to what's rendered. If I change the initial 'toggled' values in the data prop sent in, the initial render correctly reflects the toggled state. I built the ./example app and it works fine.
Wondering if there is some piece missing from the Quick Start instructions.
Hello and thanks for the great work!!
I tried today just to render the example found in the readme, but I have some issues.
Expanding a node works well but fire this error:
Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded
but I cannot collapse a node and I get the following errors from React:
Uncaught TypeError: Cannot read property 'componentWillEnter' of undefined
I use the last version of React, with browserify and reactify --es6
Maybe you can give me a hint on where the errors come from?
Thanks
Hey, would you consider switching href '#' to href 'javascript:;' in the header component? It is much safer to use.
Hi folks,
I wanted to try the plugin to see if we could use it in one of our project but npm fails to fetch the project from github because ssh is not going through our corporate proxy.
Here's a bit of the stacktrace :
npm ERR! Command failed: git -c core.longpaths=true clone --template=D:\Users\Clement.BTWNLCPSB69\AppData\Roaming\npm-cache\_git-remotes\_templates --mirror [email protected]:alexcurtis/react-utils.git D:\Users\Clement.BTWNLCPSB69\AppData\Roaming\npm-cache\_git-remotes\git-github-com-alexcurtis-react-utils-git-ea67acf1 npm ERR! Cloning into bare repository 'D:\Users\Clement.BTWNLCPSB69\AppData\Roaming\npm-cache\_git-remotes\git-github-com-alexcurtis-react-utils-git-ea67acf1'... npm ERR! ssh: connect to host github.com port 22: Connection refused
I don't really know what are the possibilities here, maybe publish the react-utils dependency in a proper npm repository?
Quick fix is to use thethering to bypass the proxy but it's not viable!
Cheers !
IE 9-11
object doesn't support property or method 'find'
Hey,
Sometimes its necessary, to only toggle if explicitly the trigger component was clicked.
Currently I'm overriding the Header and I put a click handler with preventDefault() on my node.
I think there should be a better way for handling that case. Maybe the onClick should be placed in the default decorator Header/Toggle component, and if overwritten, we handle it ourself.
Header: (props, toggle) => {
return (
<div style={props.style} onClick={toggle}>
{props.node.name}
</div>
);
}
Thanks for your god job first.
When I use this with redux and redux-simple-router, some question occur to me.
Following is my code:
ReactDOM.render((
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<Route path="services" component={ServiceList}/>
<Route path="service/:id" component={ServiceDetail}/>
</Route>
</Router>
</Provider>
), document.getElementById('container'));
var App = React.createClass({
render: function() {
return (
<div>
<Header/>
<div id="ocean-body">
<SideBar/>
<MainContent content={this.props.children}/>
</div>
</div>
);
}
});
render: function() {
return (
<div id="ocean-sidebar">
<ServiceTree tree={data} />
</div>
);
}
render: function() {
return (
<div id="service-tree">
<Treebeard
data={this.props.tree}
onToggle={this.onToggle}
/>
</div>
);
}
In addition, I customize the Header
decorators.Header = function (props) {
var style = props.style;
var node = props.node;
var linkUrl = node['isServiceUnit'] == '1' ? '/service/' + node.id : '/services';
return (
<div className="node-header" style={style.base}>
<div style={style.title}>
<Link to={linkUrl}>{props.node.name}</Link>
</div>
</div>
);
};
Problem is than when I Trigger a url router,some warnings will show as follow:
I am sorry for my poor English.
Hi, I have an array like this:
[
{file: /file1.txt, otherinfo: foo},
{file: /path/file2.txt, otherinfo: foo},
{file: /path/file3.txt, otherinfo: foo},
{file: /path/subpath/file.txt, otherinfo: foo},
{file: /file4.txt, otherinfo: foo},
{file: /folder/dir/file5.txt, otherinfo: foo}
]
How can I format data to passing it to react-treebeard?
Thanks
React.PropTypes
has been extracted to it's own package since React v15.5.0.
The following warning is displayed if that version of React is used:
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
CC: @alexcurtis
Can you make acceptable theme={null}
and add classes on every nodes?
I want style by classic css way
This is my simple render method:
render() {
const decorators = {
Loading: (props) => {
return (
<div style={props.style}>
loading...
</div>
);
},
Toggle: (props) => {
return (
<div style={props.style}>
<svg height={props.height} width={props.width}>
// Vector Toggle Here
</svg>
</div>
);
},
Header: (props) => {
return (
<div style={props.style}>
{props.node.name}
</div>
);
},
Container: (props) => {
return (
<div onClick={this.props.onClick}>
<decorators.Toggle />
<decorators.Header />
</div>
);
}
};
return (
<Treebeard
data={this.threeData}
decorators={decorators}
onToggle={this.onToggle}
/>
)
I defined data in constructor:
constructor(props) {
super(props);
this.threeData = {
name: 'root',
toggled: true,
children: [
{
name: 'parent',
children: [
{ name: 'child1' },
{ name: 'child2' }
]
},
{
name: 'loading parent',
loading: true,
children: []
},
{
name: 'parent',
children: [
{
name: 'nested parent',
children: [
{ name: 'nested child 1' },
{ name: 'nested child 2' }
]
}
]
}
]
};
}
But I get error: Uncaught TypeError: Cannot read property 'name' of undefined (when exucutes code inside Header method of decorators.
This could be derived from the children
attribute. If children is undefined, then it is a terminal node. If children is [empty]
array then it is a potential parent, that needs to load in its children. If children has elements, then it is definitely a parent node. Can anyone see any issues with this?
I've been trying to tweak this so when you open a new branch, the previously opened branch closes, but I can't get it to work. Would really appreciate if this could be done. Thanks.
ERROR in ./~/react-treebeard/index.js
Module build failed: ReferenceError: [BABEL] /Users/xiaoying/coder/go_path/src/helios/static/node_modules/react-treebeard/index.js: Using removed Babel 5 option: /Users/xiaoying/coder/go_path/src/helios/static/node_modules/react-treebeard/.babelrc.stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets
at Logger.error (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/logger.js:43:11)
at OptionManager.mergeOptions (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:305:20)
at OptionManager.addConfig (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:248:10)
at OptionManager.findConfigs (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:454:16)
at OptionManager.init (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:502:12)
at File.initOptions (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/index.js:243:89)
at new File (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/index.js:159:72)
at Pipeline.transform (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/pipeline.js:49:16)
at transpile (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-loader/index.js:14:22)
at Object.module.exports (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-loader/index.js:88:12)
@ ./containers/StockContainer.js 15:22-48
For a folder selection treeview, we need to be able to split 'selecting' a node from expanding/collapsing it. I got 95% of the way there by implementing a Container
decorator that composes Header
and Toggle
, but I hit a brick wall because of this:
renderHeader(decorators, animations){
return (
<NodeHeader
...
node={Object.assign({}, this.props.node)}
...
/>
);
}
The NodeHeader doesn't get a handle on the node object proper, presumably to prevent mutations, but that means my Header decorator can't set node.active
. It looks like changing the node can only be done via calling through to onClick, which calls through to onToggle with no way to represent that it should actually select instead of toggling.
Hi Alex,
We're using react-treebeard
in a closed environment where we can't have refs to external (i.e. github) modules.
Would it be possible to integrate react-utils
withreact-treebeard
or make it public in npm registry and reference that please?
I am talking about this line "react-utils": "github:alexcurtis/react-utils",
in package.json
Many thanks!
I commented out all code in the onToggle
event handler (and hence the data variable does not get modified), yet the view still toggles as normal.
As far as I can understand, the view is driven from the data
variable, so the view should only toggle if the corresponding toggled
parameter in the data
variable changes?
It would be a lot easier to customize if it was using css classes instead of inline styles.
This is a requirement or something? Or just it was not made with classes...because not?
Hello @alexcurtis ,
Is the project still maintained ? With the next release of react, React.propTypes
will be deprecated in favor of the prop-types packages.
Do you plan to upgrade ?
Thanks.
Hi Alex,
I got this error when I added Treebeard into the project:
Uncaught TypeError: Super expression must either be null or a function, not undefined
.
This exception is thrown by radium/lib/components/style.js:
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
In package.json file, Treebeard is using "radium": "^0.18.0"
, however It seems that Radium is relying some new features added in React 15.3
(see here), but we are using React 0.14.8
.
Any suggestions to integrate Treebeard in a React 0.14
based project? Do you think relying on an earlier version of Radium is possible since the React.PureComponent
was just added last month?Thanks.
Hello,
Firstly I would like to congratulate for making such a good treeview.
How can we use the drag and drop to move files around.
Thanks,
Deepak
Is there a way to open menu on right click of the node ?
Please update radiup lastest for fix this problem.
Warning: Unknown prop `_radiumDidResolveStyles` on <div> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
in div (created by Container)
in Container (created by NodeHeader)
in NodeHeader (created by TreeNode)
in li (created by TreeNode)
in TreeNode (created by TreeBeard)
in ul (created by TreeBeard)
in TreeBeard (created by _component)
in div (created by _component)
in div (created by _component)
in div (created by _component)
in div (created by _component)
in div (created by _component)
in _component (created by Container(_component))
in Container(_component)
in div
in Unknown
Basically, I don't want to have a "root" or "react-treebeard" (as it is in the example) parent object in the data structure, but rather an array of siblings.
I have modified data into a structure that mimics this but react-treebeard doesn't seem to render it, indicating that this may not be supported?
Can we put checkboxes inside the tree ?
Hello,
as you can see in the image, the child nodes are selected along with their parents (not the expected behavior, since only one node san be selected simultaneously in the demo). It somehow depends on node fetching, probably. The highlighted nodes were fetching their child nodes from the backend, populating them into the tree and the component was re-rendered.
Code:
if (this.state.cursor) {
this.state.cursor.active = false;
}
node.active = true;
if (node.children) {
node.toggled = toggled;
}
this.setState({cursor: node});
if (node.hasChildren && node.description) {
this.props.dispatch(fetchNode(node.id, node.applicationId));
}
}
Please notify me if something else is needed from me.
https://facebook.github.io/react/docs/transferring-props.html
I think in TreeBeard render method, add a parameter to pass on extra props to all nodes may be a good idea. I know I can write them in my nodes, but sometimes It's not elegant.
You can use JSX spread attributes to merge the old props with additional values:
<Component {...this.props} more="values" />
How does one get multiple instances of react-treebeard running on the same page?
If I add a second instance it uses the same decorators I assigned the first instance.
There seems to be a memory leak here. I think its originating from velocity-react but still haven't figured out how it is caused.
If you go to your demo and check for detached nodes you will see this number keeps rising and is not cleaned up.
Is it possible, would anyone please shove me in the right direction?
Error: Command failed: /bin/sh -c npm install --save react-treebeard
Unsupported URL Type: github:alexcurtis/react-utils
Runnng npm 2.5.1
I'm guessing the new format is part of npm 3.0? Or is this a typo in your package.json?
Hey,
Animations are great, but sometimes apps feel a bit snappier without these. I know we can overwrite them with some animation object like below, but just handing animations={false}
or animations={null}
would be a bit more intuitiv and comfortable.
<Treebeard animations={false}/>
Thats whats currently necessary:
var animations = {
toggle: (state) => {
return {};
},
drawer: (/* state */) => {
return {
enter: {},
leave: {}
};
}
}
<Treebeard animations={Animations}/>
I need to build trees in two of my projects. After studying existing solutions I believe my way to go might be:
One of my projects will have lists with maximal 500 nodes to build per level. The other can have several thousand nodes per level though - probably too much to tackle without react-virtualized.
Just to explain: The primary way to find data / navigate to nodes will be by a search box. As the data is very hierarchical, the tree will usually still be helpful to show these hierarchies though - even though there can be lots of nodes in a few instances (but not generally).
Is there a specific reason why you don't use a tool like react-virtualized?
Any chance react-treebeard might be updated to use a tool like react-virtualized?
I will probably not be able to offer a pull request for this functionality - my code will be too hacky and I will be very happy if/when I get my applications to work this way :-(
Hey again,
I thought it might be useful if you could declare node.active
on a node and have react-treebeard autoscroll on initial load, to get the active item into the view.
Would you consider something like that?
This is a raw workaround I would use without modifying your library.
var el = document.getElementById(this.activeElement);
document.getElementById(this.activeElement).scrollIntoView();
Header: props => {
if(props.node.active){
this.activeElement = 'tree-item-' + props.node.id;
}
return (
<div style={props.style.base} id={'tree-item-' + props.node.id}>
{...}
</div>
);
}
I notice the background colour of the last clicked item changes on the example.
I am trying to get a similar effect using treebeard in my project, however can't seem to get this to work (it doesn't seem to highlight by default), given the parameters available in the style
variable.
This is what my modification of the example looks like ("Basic" has been clicked on):
Hey,
Thanks for the very good looking tree view.
I found an issue when using decorators. The decorators are only applied to the level you put them on and don't get passed to the children.
Which seems a bit weird to me.
Is that intended or a bug ?
Say I do :
const decorators = { Loading: (props) => { return ( <div> LOADING! </div> ) }, };
const data = { name: 'Root', toggled: true, active: false, decorators: decorators, children: [ { name: 'parent', children: [ { name: 'child1' }, { name: 'child2' } ] }, { name: 'loading parent', loading: true, children: [] }, { name: 'parent', children: [ { name: 'nested parent', children: [ { name: 'nested child 1' }, { name: 'nested child 2' } ] } ] } ] };
loading parent child will still look like the default "loading..." and not the decorated one.
If I put loading:true on root only root will have the loading decorator.
``//import '../scss/index.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import Treebeard from './compoent/react-treebeard';
const data = {
name: 'root',
toggled: true,
children: [{
name: 'parent',
children: [{
name: 'child1'
}, {
name: 'child2'
}]
}, {
name: 'loading parent',
loading: true,
children: []
}, {
name: 'parent',
children: [{
name: 'nested parent',
children: [{
name: 'nested child 1'
}, {
name: 'nested child 2'
}]
}]
}]
};
class TreeExample extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.onToggle = this.onToggle.bind(this);
}
onToggle(node, toggled) {
if (this.state.cursor) {
this.state.cursor.active = false;
}
node.active = true;
if (node.children) {
node.toggled = toggled;
}
this.setState({
cursor: node
});
}
render() {
return ( < Treebeard data = {
data
}
onToggle = {
this.onToggle
}
/>
);
}
}
const content = document.getElementById('content');
ReactDOM.render( < TreeExample / > , content);
react-addons-test-utils
has been deprecated and has been put in the react-dom
package since React v15.5.0.
CC: @alexcurtis
Hi, I'm using the component to display a state coming from the server in real time.
The desired structure of my tree is:
As you can see the header component consist of the actual header and additional value.
I was wondering how difficult it will be to support displaying a 'value' field in the data sent to the tree component.
Thanks,
TMaster
ERROR in ./~/react-treebeard/index.js
Module build failed: ReferenceError: [BABEL] /Users/xiaoying/coder/go_path/src/helios/static/node_modules/react-treebeard/index.js: Using removed Babel 5 option: /Users/xiaoying/coder/go_path/src/helios/static/node_modules/react-treebeard/.babelrc.stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets
at Logger.error (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/logger.js:43:11)
at OptionManager.mergeOptions (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:305:20)
at OptionManager.addConfig (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:248:10)
at OptionManager.findConfigs (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:454:16)
at OptionManager.init (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/options/option-manager.js:502:12)
at File.initOptions (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/index.js:243:89)
at new File (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/file/index.js:159:72)
at Pipeline.transform (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-core/lib/transformation/pipeline.js:49:16)
at transpile (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-loader/index.js:14:22)
at Object.module.exports (/Users/xiaoying/coder/go_path/src/helios/static/node_modules/babel-loader/index.js:88:12)
@ ./containers/StockContainer.js 15:22-48
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.