Open zikaari opened 2 years ago
Overall, I really like the changes that are currently in the pipeline. Generalizing aspen to encompass more than just filesystem trees will allow for many unique experiences:
Functional components are very cool. Is it possible to raise the handle state up though? For example, could it be possible to declaratively specify that you want a certain prompt to exist?
Right now, aspen relies on a lot of imperative function calls that need to be kept around and cleaned up after by the caller, which isn't very fun. It would be nice if more of the library was declarative instead of imperative, since callback hell is the main not-very-fun part. Promises help somewhat (I use async
functions heavily), but dealing with them in React is kind of annoying.
Great to hear. My two main issues have also been:
path
and name
, many trees just have id
, children
and data
.children?.length > 0
).selectedItems
, visibleItems
, onChangeSelection(selectedItems)
props and translate it to treeHandle calls. Ended up being a strange mix between controlled and uncontrolled components. Ideally, react-aspen would offer a controlled component that works just like standard inputs or selects, i.e. taking props like mentioned above./edit: I just read the 2.0.0 changelog and it seems it's addressing my first point perfectly. :+1:
Another thing that would be nice is having some extra functions built-in or at least one-line examples of how to achieve them with the API. Examples:
On the other hand, I don't care so much about context menus and reordering, although those might certainly be useful in some cases.
Here are two different trees I built for our app showing two very different use cases:
https://user-images.githubusercontent.com/898549/142715200-4361acae-abe3-420a-93dc-13981af779e6.mov
https://user-images.githubusercontent.com/898549/142715202-5aa39099-c31a-481a-a00f-c6f630eedf4c.mov
@graup I've had moderate success implementing multiple select and keyboard bindings in my implementation of Aspen. You can just apply the decoration to multiple items at the same time, and as long as you account for that functionality, everything will Just Work.
Although the imperative style does still bother me - and of course, you have to reimplement all the FileTreeX stuff from scratch (I never did use FileTreeX, anyway - it looked far too simple for my use case).
I'd love to show it off but it's all proprietary for at least the next month.
Hi,
I really appreciate your efforts for creating such a wonderful high performance tree. I liked the road map and would like to have below things to be considered as well.
Thanks, Khushboo
On Thu, Nov 18, 2021 at 7:27 PM Neek Sandhu @.***> wrote:
This thread will be used to track and discuss the next leap in super-performant tree rendering on planet Earth - Aspen 2.
The next version of Aspen has the following core goals:
- Even better performance
- More versatility, i.e not being limited to just "file trees"
- More lightweight, i.e removing as many dependencies as possible
- Codebase enhancements, i.e using functional components, and switching to a monorepo
The stepping-stone has already been set over at aspen-next branch in this repository. Everything you see there is subject to change as the project advances to the beta stage. Many features from current Aspen are yet to be ported over to Aspen 2, but the core framework has already been laid out. The breaking changes can be reviewed in the changelog https://github.com/NeekSandhu/aspen/blob/aspen-next/CHANGELOG.md, this will keep on evolving as the project advances.
You can subscribe to this issue by clicking Subscribe on the right to be notified on the progress of Aspen 2, including the beta release, and up to the final release.
cc @LoganDark https://github.com/LoganDark @fintara https://github.com/fintara @graup https://github.com/graup @rodgomesc https://github.com/rodgomesc @adamgruber https://github.com/adamgruber @khushboovashi https://github.com/khushboovashi Since you folks use react-aspen in production, your feedback is very important in the direction Aspen will follow.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NeekSandhu/aspen/issues/19, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADNOKSKPA3YOW7CFECJFSO3UMUA3JANCNFSM5IJVWTFA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
Hi, I really appreciate your efforts for creating such a wonderful high performance tree. I liked the road map and would like to have below things to be considered as well.
- There should be an option to choose between fixed or dynamic sized tree
You mean abandoning the virtual list? Since right now react-aspen uses a virtual list (window list or something) that requires you to specify a width/height.
- The important tree item events (like add/update/delete/load/select) should be triggered, so those events can be listened to outside component
You mean echoing events that the watcher emits back up? Could be useful.
- Search Tree Item
This can be implemented without too much difficulty. Since Aspen 2 is going to be generic over the metadata you store (like name, path, etc.) this is impossible to it to implement directly.
- Refresh the tree items
This is a good one. It can already be implemented by doing reading and then telling Aspen to update stuff, but it would be good for convenience.
- Item path should be id based
What do you mean item path? Currently, as it's a list, items are indexed by their position in the list. Also, having a reference to an entry means you can access it forever.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974580487 - Is it possible to raise the handle state up though? For example, could it be possible to declaratively specify that you want a certain prompt to exist?
No. Aspen MUST have the authority to force terminate a prompt under certain circumstances, for example, when the node to which the prompt is bound is removed. In a scenario like that - code like this becomes contradicting -
<Tree ...>
<RenamePrompt node={...} />
</Tree>
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974596605 - Type (File or Directory) is often implicit (depending on if children?.length > 0)
Aspen is async first library. The count of children is unknown upfront, and stays unknown until requested by calling Tree#expand(branch)
. Plus, a node could actually be a true directory but just not have any children, then a check like this will be unreliable.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974596605 - I had to re-create a directory-like structure with paths just to translate this tree to a file system tree and also specifically turn off some of the path handling (like OS-style separators and sorting, those are things I don't want to think about.)
Paths are now gone, forever. It's just pure raw tree nodes, you get to choose what kind of data those nodes actually represent (through the data
property on Leaf
or Branch
). Aspen 1 relied on path-fx
library for it to work, it won't anymore.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974596605 - Expanding/collapsing all or a list of items
It will be now accessible through a recursive: boolean
argument to Tree.expand
and Tree.collapse
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974596605 - I found myself writing wrapper React components that take selectedItems, visibleItems, onChangeSelection(selectedItems) props and translate it to treeHandle calls. Ended up being a strange mix between controlled and uncontrolled components. Ideally, react-aspen would offer a controlled component that works just like standard inputs or selects, i.e. taking props like mentioned above.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-974596605 and https://github.com/NeekSandhu/aspen/issues/19#issuecomment-975306767 - Search and item selection
The goal of Aspen 2 (when somebody does yarn add react-aspen
) is to be super lightweight, minimal, and bloat-free. Not only in terms of bundle size, but also the API footprint. Features like this, and even more like keyboard navigation are best if they are made available through separate packages. This will allow users to opt-in as they deem fit. I welcome you all to contribute to the Aspen project and would love to see more packages under the packages/*
directory. If not, you can publish it under your own account, and then have it featured in the readme of Aspen.
I can totally imagine a package like react-aspen-select
, that exports hooks like useTreeSelect(tree: Tree)
. Or imagine react-aspen-search
with useTreeSearch(tree: Tree, matchFn: ((node: TreeNode) => number)))
. And everything just works. Let me know if this sparks interest among one (or more) of you.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-975306767 - There should be an option to choose between fixed or dynamic sized tree
@LoganDark We can use the variable size list from react-window
instead of FixedSizeList
conditionally depending on the props supplied to the Tree
component at runtime.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-975306767 - The important tree item events (like add/update/delete/load/select) should be triggered, so those events can be listened to outside component
Events for initial load, addition, and removal will be listenable on the Tree
instance using a similar syntax that's already available with Aspen 1.
https://github.com/NeekSandhu/aspen/issues/19#issuecomment-975306767 - Refresh the tree items
Aspen 2 already has Tree#amend
, which you can use to insert and re-sort the children of a branch. The reason Aspen never directly exposes a "hard-reload" method is that this would mean loss of expansion state of the child (and grandchildren). If this were to be exposed, what do you expect the call signature to be that also makes the implication clear that it'll cause a loss of expansion state for its children?
I can totally imagine a package like
react-aspen-select
, that exports hooks likeuseTreeSelect(tree: Tree)
. Or imaginereact-aspen-search
withuseTreeSearch(tree: Tree, matchFn: ((node: TreeNode) => number)))
. And everything just works. Let me know if this sparks interest among one (or more) of you.
Love it, totally up for contributing to both of those ideas.
I can totally imagine a package like
react-aspen-select
, that exports hooks likeuseTreeSelect(tree: Tree)
. Or imaginereact-aspen-search
withuseTreeSearch(tree: Tree, matchFn: ((node: TreeNode) => number)))
. And everything just works. Let me know if this sparks interest among one (or more) of you.
I totally missed this when I first read your comment. This sounds really cool. I'd probably be able to contribute my select that supports click and ctrl+click and shift+click and ctrl+shift+click and...
Awesome! While you guys are definitely encouraged to use your own creativity in the implementation, I think it's worth sharing a plausible approach to this -
React-ARIA by Adobe is a good example. For the sake of our use-case ignore the "aria" aspect of this package, and instead just look at how this package works in general.
Take for example the useSelect. This hook is agnostic of the UI, which has been the motto of Aspen from day zero. The user calls the hook, it returns some stuff, some of it contains the workable data, in our case the selectedItems
, or searchResults
, and some of it is props that need to be bound the some UI element, could be the entire item row, or something inside of it. And guess what, everything just works. Beautifully.
We can jump into this after the first beta release since the API and behaviour will be pretty much stable thereafter.
@LoganDark Will your implementation support "checkbox" driven selection/deselection as well?
@graup Would you like to collaborate with Logan on the selection package, or is there something else altogether that you'd like to kick-off (depending on what you deem important for Superb.ai).
Either way, it'll be nice to have an API proposal beforehand so we all can review and see if it can be one-size-fits-all.
I'll do an alpha release by next Monday (I'll post here the installation instructions). We'll talk discuss feature parity with Aspen 1, and in general, discuss any flaws before advancing on to the beta release soon after that.
@LoganDark Will your implementation support "checkbox" driven selection/deselection as well?
Unfortunately it does not at the moment. It's mostly implemented as a monstrous onClick handler. I can provide it but can't really help with extracting it into a separate package yet. I do also have a bunch of keybind handlers, mostly arrow keys and shift+arrow keys, for manipulating the selection.
I can provide it but can't really help with extracting it into a separate package yet
No rush. Aspen itself hasn't reached beta yet. I'll ask you after the alpha release again to check if and when you can help by publishing it (just so everyone is in sync with status of things).
I have a feeling that checkbox selection might just be low-hanging fruit for us.
The following API might be exposed which people can then bind to checkbox event listeners -
const { addToSelection, removeFromSelection } = useTreeSelect(...)
Again, just a rough idea. Time will tell.
How about generalizing the "selection" package? We can just make it a useCustomTreeState()
and support all kinds of user defined states (aka decorations) like selected
, disabled
, ... plus addToState
, removeFromState
, setState
.
Are you keeping the decorations concept? Actually it works fairly well, just the API is not so useful. We can just make a const { addToSelection, removeFromSelection, setSelection } = useDecoration('selection', CascadeMode)
. It can also handle more complicated logic (like de-selecting an item that was selected by cascade -> item should be negated).
I could draw up a proposal for this in a new issue.
We can just make it a
useCustomTreeState()
and support all kinds of user defined states (aka decorations) likeselected
,disabled
, ... plusaddToState
,removeFromState
,setState
.
The only problem I see with this is that the end-user will have to do the plumbing by themself defeating the original vision of plug-n-play lego bricks.
I could draw up a proposal for this in a new issue.
I have enabled GitHub Discussions for this repo. I'd love to see how well that space works, please use Discussions for this discussion by clicking the Discussion tab above.
⚠Important announcement, please read - https://github.com/zikaari/aspen/issues/23
This thread will be used to track and discuss the next leap in super-performant tree rendering on planet Earth - Aspen 2.
The next version of Aspen has the following core goals:
The stepping-stone has already been set over at
aspen-next
branch in this repository. Everything you see there is subject to change as the project advances to the beta stage. Many features from current Aspen are yet to be ported over to Aspen 2, but the core framework has already been laid out. The breaking changes can be reviewed in the changelog, this will keep on evolving as the project advances.You can subscribe to this issue by clicking
Subscribe
on the right to be notified on the progress of Aspen 2, including the beta release, and up to the final release.cc @LoganDark @fintara @graup @rodgomesc @adamgruber @khushboovashi Since you folks use
react-aspen
in production, your feedback is very important in the direction Aspen will follow.