Skip to content

feat: add tree view #3585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 45 commits into
base: main
Choose a base branch
from

Conversation

dev-viinz
Copy link

@dev-viinz dev-viinz commented Jul 1, 2025

Linked Issue

Closes #3468

Description

Implements the Zag.js TreeView.
In this draft I'm starting with the svelte component until it's finalized, to then "port" it over to react.
Current Progress:

  • Add svelte component
  • Svelte component done
  • Add react component
  • React component done
  • Add changeset

Checklist

Please read and apply all contribution requirements.

  • Your branch should be prefixed with: docs/, feature/, chore/, bugfix/
  • Contributions should target the main branch
  • Documentation should be updated to describe all relevant changes
  • Run pnpm check in the root of the monorepo
  • Run pnpm format in the root of the monorepo
  • Run pnpm lint in the root of the monorepo
  • Run pnpm test in the root of the monorepo
  • If you modify /package projects, please supply a Changeset

Changsets

View our documentation to learn more about Changesets. To create a Changeset:

  1. Navigate to the root of the monorepo in your terminal
  2. Run pnpm changeset and follow the prompts
  3. Commit and push the changeset before flagging your PR ready for review.

Copy link

changeset-bot bot commented Jul 1, 2025

🦋 Changeset detected

Latest commit: 5cce0f4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@skeletonlabs/skeleton-svelte Minor
@skeletonlabs/skeleton-react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Jul 1, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
www.skeleton.dev ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 7, 2025 10:17pm

@endigo9740

This comment was marked as resolved.

@endigo9740

This comment was marked as resolved.

@dev-viinz

This comment was marked as resolved.

@endigo9740

This comment was marked as resolved.

@dev-viinz

This comment was marked as resolved.

@endigo9740

This comment was marked as resolved.

@endigo9740
Copy link
Contributor

Conversation continued from here: #3585 (comment)

@dev-viinz Ok, so I've had a chance to go hands on with this today and unfortunately I don't have great news...

After reviewing how Zag is implementing the TreeView in detail I've determined it's not well suited to a template-driven approach where you define the structure using multiple sub-components. The primary culprit for this is the way the #each block is used here:

{#each node.children || [] as childNode, index}
    {@render treeNode({ node: childNode, indexPath: [...indexPath, index], api })}
{/each}

Each item to know both it's node and indexed position within the DOM tree. For example:

  • 0: first node element
  • 1: second node element
  • 2: third node element

We ran into a similar issue with the Skeleton v2 Stepper component. And while it's not impossible to deal with it requires some really annoying work arounds.

  • In your case you had to break from the source and implement all the update/register/unregister logic.
  • In the last version of our v2 Stepper, we used a Context API to essentially self-register each node (and thus index) with the parent. But this pattern immediately breaks down when the DOM structure of the component change in an unpredictable manner (ex: using #if blocks, etc)

This is more than likely a case where the pattern works well in React (which the Chakra team are well versed in), but not so much in other frameworks like Svelte. JSX plays by a different set of rules since so much can be inlined and multiple components registered in the same file.

Your solution works, but it's broken our rules about the keeping Zag's source structure in place - which leads to extra maintenance overhead. As much as it pains me to say it, the most practical solution I can think of would be to revert back to the original monolithic single component solution. The upside is the structure and data flow becomes much simpler, while the downside is users lose access to the UX of multiple components and the isolated scope for customization. This isn't going to play well with our proposed v4 changes either.

On a final note, I'm not sure if you're aware of Ark UI. Their the first-party counterpart to Zag - where they actually implement the Zag primitives into a functional component library. They DO provide a foundation that's a lot close to our proposed v4 solution (with many sub-components), but with the trade off of a requiring a HUGE number of components and what looks to be a ton of complexity. See the source here:

https://github.com/chakra-ui/ark/tree/main/packages/svelte/src/lib/components/tree-view

It might be worth researching what their doing, as they seem to be solving some of these issues. But I'm not going to lie, their implementation is a beast. There's SO much going on here I'm not sure that's a reasonable ask. Plus I am also a bit leery of the user-facing DX for juggling so many small parts.

What I am going to to do is suggest you push pause until you hear back from me. Then I'm going to brainstorm with the team and see if they have any other suggestions. We can resume once we have an battle plan in place - which may or may not include moving forward with your current implementation. Please be prepared for that.

@endigo9740
Copy link
Contributor

endigo9740 commented Aug 8, 2025

@dev-viinz quick follow up - I talked a bit with @Hugos68 on this. He doesn't have enough working knowledge of the TreeView source code to provide an informed response yet, but I think between us we do believe there may be a way to solve this. Especially since Ark is doing this - just with a ton of extra overhead and complexity :D

I may try to carve out some time next week to run through and better understand how they're accomplishing this. One quick item of note though - they're using a script module to share some state. Not sure what exactly yet. But this may be worth looking into.

Either way we can pick up on this next week. If you have any other ideas I'm all ears.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Tree View Component
2 participants