skeletonlabs / skeleton

A complete design system and component solution, built on Tailwind.
https://skeleton.dev
MIT License
4.95k stars 315 forks source link

NEXT: Tree View #2358

Open endigo9740 opened 9 months ago

endigo9740 commented 9 months ago

Zag Integration

Zag docs are currently unavilable, but Ark has an example: https://ark-ui.com/react/docs/components/tree-view

Update: the Zag team has confirmed this component will be available in the future, but Chakra v3 is taking priority. Unfortunately this component may not make it in time for the v3 launch. But we will provide it as soon as possible, potentially post-launch.

Maintainer Requests

The following requests are coming straight from the Skeleton team. These are highly likely be implemented:

Community Requests

The following requests have come from the community and are under consideration:

Bugs and Issues

Feedback

If you have additional updates or requests for this feature, please do so in the comments section below.

ThingEngineer commented 4 months ago

Feature Request - onChecked RecursiveTreeView event

The current 2 (non-optimal) methods of monitoring checkbox state - and related observations.

REPL for the topics below.

The REPL setup:

let nodes: TreeViewNode[] = [];
let checkedNodes: string[] = [];
let expandedNodes: string[] = [];

nodes = [
  {
    id: '1',
    content: 'Parent 1',
    children: [
      {
        id: '1.2',
        content: 'Child 1'
      }
    ]
  },
  {
    id: '2',
    content: 'Parent 2'
  }
];

// expandedNodes = ['1'];
// checkedNodes = ['2'];

$: if (browser) console.log('reactive --> expandedNodes:', expandedNodes);
$: if (browser) console.log('reactive --> checkedNodes:', checkedNodes);
</script>

<RecursiveTreeView
  selection
  multiple
  nodes={nodes}
  bind:checkedNodes={checkedNodes}
  bind:expandedNodes={expandedNodes}
  on:click={(e) => {
    console.log('click event -->', e.detail, 'checkedNodes:', checkedNodes);
  }}
  on:toggle={(e) => {
    console.log('toggle event -->', e.detail, 'expandedNodes:', expandedNodes);
  }}
/>

Expanding and Collapsing 'Parent 1' node from a fresh page load where expandedNodes = []

+page.svelte:46 toggle event --> {id: '1'} expandedNodes: ['1']
+page.svelte:29 reactive --> expandedNodes: ['1']
+page.svelte:46 toggle event --> {id: '1'} expandedNodes: []
+page.svelte:29 reactive --> expandedNodes: []

Notice that when toggling (opening and closing a parent tree view with 0 > children) the bound variable expandedNodes is updated before the custom event is dispatched so we can see that the node with id: 1 was toggled and we know it's state by checking expandedNodes for that id. Looking at the browser console.log output we can see that I expanded then collapsed the node with id:1 . That's great, as expected!

Method 1 - Click event + tracking previous vs current checkedNodes.

Checking and Unchecking the 'Parent 1' node from a fresh page load where checkedNodes = []

+page.svelte:43 click event --> {id: '1'} checkedNodes: []
+page.svelte:30 reactive --> checkedNodes: ['1']
+page.svelte:43 click event --> {id: '1'} checkedNodes: ['1']
+page.svelte:30 

Notice that when checking or unchecking the checkbox of any node the bound variable checkedNodes is not updated before the the custom event is dispatched so we can not see current state of the node with id: 1 that was just checked or unchecked (we don't know which).

Method 2 Reactivity - checkedNodes reactive statement.

State could be monitored via svelte's reactivity on your bound checkedNodes variable. But reactive events fire for checkedNodes on load when you are building your tree view, and while loading saved checked and expanded nodes. All that is fine, we can handle that by setting, checking and clearing flags but that could be avoided with a clean event that fires only when a node is checked or unchecked and that returns at minimum the id of the node and the current state of the checkbox.

endigo9740 commented 1 month ago

We're currently waiting on recommendations from Zag on this one: