Code Monkey home page Code Monkey logo

react-arborist's Issues

Remove unnecessary "height" prop, Support custom scroll bars

First of all, thanks for creating this package!

Currently, the tree only works with static widths and heights (using observers excluded).
However, since the tree height is already calculated in OuterElement in tree.tsx, I don't see why a static height would be required.

I did some quick tests - passing the calculated tree height to the enclosing position: relative div and changing the overflow values was already enough to get rid of the "height" prop requirement.

Bonus: Custom scroll bar libraries also started working correctly.

Easy api to prevent nodes from being selectable

This is possible today, but maybe we could make an easier api.

Today, you'd make a custom RowRenderer and NodeRenderer. Then in there, you'd prevent selection if that node meets a certain criteria. An Tree Prop would make it all easier.

accessor is not available

The docs say there's childrenAccessor and isOpenAccessor but I only see getChildren in the code ๐Ÿค” is this upcoming API?

Expose onSelect event to Tree component

Hi James,

I need to listen for the tree node select event via the Tree component.
Would it be possible to add this?

My use case is I'm using check-boxes to select multiple tree nodes using the handlers.select which has shift-click but I only want one event to fire.

Kind regards,
Marten

Why not use `renderer` prop on `Tree` for NodeRenderer?

I'm probably missing something, but it seems a little strange to me that the Tree component takes data for its children, rather than the more typical approach of children nodes being content to be passed in to a component. It seems like a more common approach would be to pass the node renderer as a prop to Tree. Which would probably mean that Tree would be a self-closing tag/component.

I notice here that the main Tree component implementation does, indeed, assign children to the renderer prop of TreeViewProvider, which appears to be the real workhorse component.

Suggestion:

  • create a renderer prop on Tree
  • deprecate use of Tree's children

Tree.onSelect

It might be cleaner to have an onSelect callback that can be placed on the root tree node. It only get's fired when an item gets selected. A group can only be selected during multi select.

New Api:

type TreeProps = {
  onSelect: () // only get's called when a single item is selected.
}

Then when the tree selects something programmatically, this code can run and does not need to be duplicated.

Demo with Dynamically Loaded Children

This should be possible with the current api, but it would be good to write a demo. If anyone has already done this, please post the code here! Thanks.

disabledDrop and target/source drop monitoring

Is there any facility in react-arborist to control dropping via source and target? More specifically can I limit dropping based on a combination of source key and target key? React DnD provides this via canDrop but disabledDrop is really just a static list. Thanks.

How can we use `renderContainer`?

Hi there,

I am trying to write a custom container for our tree but can't find any document on renderContainer? Just reading the code, the renderContainer provides no tree-api access, so not sure if it is even possible to have a custom one?

Thanks for the great works!

Cheers

Access to tree height after rendering

Is there a way to get the tree's height? The only way I've found is by multiplying the rowHeight with tree.visibleNodes() - but the latter is only available inside the node renderer.
I'd like to use custom scroll bars with this package.

Demo or code example of tree structure with connection lines

Hey the component is really cool but I would like to ask for an example with connection line (horizontal and vertical).
Is it possible to provide code example or add it to the api?
I tried doing it with css and custom render of the node but got confused.
Tnx!

How to move a node to the child of a leaf node?

Hello,

I'm looking for a way to move a node to the child of the other leaf node.

Currently, I can move nodes into exisiting folder nodes (it means they have children already)

Please help me!

Reorder with Tree.data set?

How does one drag/drop with the Tree.data attribute set (instead of the initialData). There are no drag and drop callbacks. Am I missing something? Also I would prefer to just use initialData, let the tree handle everything like it does by default, and have callbacks for when I add/edit/delete/drag nodes so I can update my database. Right now this isn't possible and I have to re-implement a lot of functionality in the callbacks because the callbacks don't work with initialData set.

Selected Ids Property

We need a way to mount the Tree component with a selection already in place.

Idea 1: I think a prop called initialSelectedIds would be a good option.

Idea 2: Or we do nothing and leave this to the user. They can get a tree ref, then use an effect for each time their "selection" criteria changes. Then use the tree's api to select that id.

Add keyboard interaction and ARIA roles

I saw your post on reddit. Nice tree control.

I wanted to give a suggestion that could help take it to the next level. Right now it is very mouse oriented. However, not everyone may prefer to use the mouse. If you look up the the tree role on MDN it documents keyboard interactions for a tree. That way users can operate it without taking their hands off the keyboard if they prefer (similar to Ctrl-C Ctrl-V for copy and paste).

Module parse failed: Unexpected token (394:7)

Failed to compile.

./node_modules/react-arborist/dist/module.js 394:7
Module parse failed: Unexpected token (394:7)
File was processed with these loaders:
 * ./node_modules/react-scripts/node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|     };
| 
>     el?.addEventListener("keydown", cb);
|     return () => {
|       el?.removeEventListener("keydown", cb);

Handler toggle is not working

Data

const treeData = {
  id: nanoid(),
  name: "Bookmarks",
  isOpen: true,
  children: [
    {
      id: nanoid(),
      name: "Brim Github",
      isOpen: true,
      children: [
        {
          id: nanoid(),
          name: "brim/pulls",
        },
        {
          id: nanoid(),
          name: "zed/pulls",
        },
        {
          id: nanoid(),
          name: "brim/releases",
        },
        {
          id: nanoid(),
          name: "brim/zson",
        },
        {
          id: nanoid(),
          name: "Level 3",
          isOpen: true,
          children: [
            { id: nanoid(), name: "amazon" },
            { id: nanoid(), name: "apple" },
            { id: nanoid(), name: "facebook" },
          ],
        },
      ],
    },
    {
      id: nanoid(),
      name: "Brim Zenhub",
      isOpen: true,
      children: [
        { id: nanoid(), name: "My Issues" },
        { id: nanoid(), name: "Brim All Issues" },
        { id: nanoid(), name: "MVP 0" },
        { id: nanoid(), name: "Manual Brim Test Cases" },
      ],
    },
    {
      id: nanoid(),
      name: "Meetings",
      isOpen: true,
      children: [
        { id: nanoid(), name: "Thursday" },
        { id: nanoid(), name: "Saturday" },
      ],
    },
    {
      id: nanoid(),
      name: "Personal",
      isOpen: true,
      children: [
        { id: nanoid(), name: "Imbox" },
        { id: nanoid(), name: "Facebook Marketplace" },
        { id: nanoid(), name: "Bank of America" },
        { id: nanoid(), name: "Mint" },
        { id: nanoid(), name: "Learn UI Design" },
      ],
    },
  ],
};

Element

function MaybeToggleButton({ toggle, isOpen, isFolder, isSelected }: any) {
  if (isFolder) {
    const Icon = isOpen ? treeMinusSmall : treePlusSmall;
    return (
      <button onClick={toggle} css={treeExpand}>
        <img src={Icon} alt="" />
      </button>
    );
  } else {
    return <div className="spacer" />;
  }
}

function Node({ innerRef, styles, data, state, handlers, tree }: any) {
  debugger;
  const folder = Array.isArray(data.children);
  const open = state.isOpen;
  const name = data.name;
  return (
    <div
      ref={innerRef}
      style={styles.row}
      className={clsx("tree-row", state)}
      onClick={(e) => handlers.select(e)}
      css={treeRow}
    >
      <div
        className="tree-row-contents"
        style={styles.indent}
        css={treeRowContents}
      >
        <MaybeToggleButton
          toggle={handlers.toggle}
          isOpen={open}
          isFolder={folder}
          isSelected={state.isSelected}
        />
        <div style={styles.indent}>{data.name}</div>
      </div>
    </div>
  );
}

Main Component

  <Tree
                          data={treeData}
                          hideRoot={true}
                          isOpen="isOpen"
                          getChildren="children"
                          indent={24}
                        >
                          {Node}
                        </Tree>

Drag Handle

Love what you have made!!

Learning so much by reading the source. Fantastic job.

I would love a drag handle ref option.

packages/react-arborist/src/components/row.tsx maybe expose optionally the dragRef ?

Thanks!

Demo Budget Tree

It'd be nice to have a demo where you have folders of expenses and each expense amount is on the right. The folders would sum the children and display it on the right.

Dragging around would update folder amounts like usual react stuff.

Feature request: alwaysOpen

I have a use-case where I never want to collapse the tree at any level. I just want a reorderable tree that's always expanded.

It would be good to allow a prop for this. Eg alwaysOpen / alwaysExpanded which did this.

It would also disable left/right arrow keys to expand/collapse branches)

Error with multiple trees

If you have 2 Tree components rendering at the same time a React Maximum update depth exceeded error is thrown. The line below is causing the error.

useLayoutEffect(() => {
    // @ts-ignore
    dispatch(actions.setVisibleIds(api.visibleIds, api.idToIndex));  // <- causes the error.
  }, [dispatch, api.visibleIds, api.idToIndex, props.root]);

Here is a codesandbox with a basic repro.

https://codesandbox.io/s/react-arborist-forked-xb7ezj

Thanks!

If a meta key is held, don't toggle the group.

If we create a simple handlers.onClick function, it should check if the meta key is held. If so, it needs to select the folder, not toggle it. Otherwise it toggles it.

If we create an onSelect property, it should not run if the meta keys are held down.

[Feature request] Ctrl + Z

Hello! I'm trying the demo and amazing package! The only thing i'm missing is an historic and a ctrl + Z, in case you did not have it already in mind!

I will try the package and if i end up using it I migth try to build that feature myself if you accept contributors :)

Cheers for the project!

README example renders nothing visible

I've created a new react apop using create-react-app and updated App.js with the example from the project's GitHub README so that I can start experimenting and learning, but the example given renders nothing for me. In the React Developer Tools, I can see the nodes are there, but I have no idea yet how to make them visible.

Shown below is what I see in the Components tab of the tools...

image

Following is my App.js...

import './App.css';
import { Tree } from "react-arborist";

const data = {
    id: "The Root",
    children: [{ id: "Node A" }, { id: "Node B" }]
}

function Node({ ref, styles, data }) {
    return (
        <div ref={ref} style={styles.row}>
            <div style={styles.indent}>
                {data.name}
            </div>
        </div>
    )
}

function App() {
    return (
        <div className="App">
            <div className="workspace-leaf-content" data-type="collection-manager">
                <div className="view-content">
                    
                    <h4>React Arborist Tree Component Test</h4>
                    
                    <Tree data={data}>{Node}</Tree>

                </div>
            </div>
        </div>
    );
}

export default App;

But, as you can see, nothing renders...

image

I am guessing the README just assumes one knows more than I do about React or something. I could use a hint! Or do you sell consulting hours?

How to get the current scroll position and the overall height of the scroll container?

I want to make a tree which would load data asynchronously upon user opening a tree node (which seems easy to do here) or upon scrolling down the tree root (in my use case root would have not only folders, but also lots and lots of items (thoughsands of them) and it wouldn't be a great experience for a user to load them all at once).
Is there a way to get the overall height of the scroll container and current scroll position to make the latter possible? Or if not, is there a better way to do what I need?

Document onClick and onContextMenu props in the tree.

We need to document the Tree's onClick and onContextMenu props. Those are attached to the tree container so that you can take action when the user clicks or rightclicks on an area of the tree that has no items. Maybe you clear the selection, or provide a different context menu.

Configurable keyboard shortcuts

All the keyboard shortcuts are listed in the DefaultContainer component. I could see how people would want to use their own keybindings.

Something like:

{
  "a": "createLeaf",
  "shift+a": "createInternal"
  "space": "activate",
  "meta+DownArrow": "activate"
}

Add API & DND support for moving nodes + hierarchy to a separate tree instance

We need to have two tree instances which allow users to move nodes (complete with their hierarchy) between them.

For the API, we'd have a button that onClick, moves all selected nodes from tree1 to tree2. The node will disappear from tree1, and appear in tree2. If it's parent nodes have no other children, they too will disappear. If any parent nodes already existed in tree2, they will merge.

Drag and drop would use the same move logic, it would just occur when a user drags a node.

I don't see any clear support for this yet.

External selection mgmt

This works pretty well. I've been comparing this package to a bunch of other react trees, and I am most hopeful this will work for my use case.

One thing I find strange is I can only access selection state from inside the Node renderer. Why not expose onSelect the same as you do with onEdit and onToggle, to make it easier for syncing with the selection state of the tree?

Related, you added an onClick prop (that isn't listed on the documentation page) and I'm wondering if that was meant to make it possible to configure external selection state synching? It fires the synthetic click event and not some computed state object so I'd be we wary using that to try and set up outside mgmt.

Am I missing something?

Guidance on how to make a node draggable.

While I've implemented the tree just fine, I'm stuck on how to make something actually draggable.

I tried adding isDraggable/isDroppable to the data nodes. No luck.

Any thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.