Skip to content

how to maintain complete information when managing state #162

@brayan-jordan

Description

@brayan-jordan

in the selectedItems variable used in setState only the "id" of the object is stored, would it be possible to keep the complete object stored?

import {
  checkboxesFeature,
  hotkeysCoreFeature,
  selectionFeature,
  syncDataLoaderFeature,
  type TreeState,
} from '@headless-tree/core'
import { useTree } from '@headless-tree/react'
import type React from 'react'
import type { ITreeViewItem } from '@/types/ITreeViewItem'
import { Checkbox } from '../shadcn/Checkbox'
import { Tree, TreeItem, TreeItemLabel } from '../shadcn/Tree'

const indent = 20

interface TreeDataWrapperProps {
  data: ITreeViewItem[]
  selectedItems: Partial<TreeState<ITreeViewItem>>
  setSelectedItems: React.Dispatch<
    React.SetStateAction<Partial<TreeState<ITreeViewItem>>>
  >
}

export function TreeDataWrapper({
  data,
  selectedItems,
  setSelectedItems,
}: TreeDataWrapperProps) {
  const itemsMap = new Map<string, ITreeViewItem>()

  if (data) {
    const buildMap = (nodes: ITreeViewItem[]) => {
      nodes.forEach((node) => {
        itemsMap.set(node.id, node)
        if (node.children?.length) buildMap(node.children)
      })
    }
    buildMap(data)
  }

  const root = data.find((node) => node.parentId === null)

  const tree = useTree<ITreeViewItem>({
    initialState: {
      expandedItems: root ? [root.id] : [],
    },
    state: selectedItems,
    setState: setSelectedItems,
    rootItemId: root?.id ?? '',
    getItemName: (item) => item.getItemData().code,
    isItemFolder: (item) => (item.getItemData()?.children?.length ?? 0) > 0,
    dataLoader: {
      getItem: (itemId) => itemsMap.get(itemId)!,
      getChildren: (itemId) =>
        itemsMap.get(itemId)?.children?.map((c) => c.id) ?? [],
    },
    features: [
      syncDataLoaderFeature,
      selectionFeature,
      checkboxesFeature,
      hotkeysCoreFeature,
    ],
  })

  if (!root) {
    return <p>Nenhum item encontrado.</p>
  }

  return (
    <div className="flex h-full flex-col gap-2 *:first:grow">
      <Tree tree={tree}>
        {tree.getItems().map((item) => {
          const depth = item.getItemMeta().level

          return (
            <div
              key={item.getId()}
              className="flex items-center gap-1.5 not-last:pb-0.5"
              style={{ paddingLeft: depth * indent }}
            >
              <Checkbox
                checked={
                  {
                    checked: true,
                    unchecked: false,
                    indeterminate: 'indeterminate' as const,
                  }[item.getCheckedState()]
                }
                onCheckedChange={(checked) => {
                  const checkboxProps = item.getCheckboxProps()
                  checkboxProps.onChange?.({ target: { checked } })
                }}
              />
              <TreeItem item={item} className="flex-1 not-last:pb-0">
                <TreeItemLabel />
              </TreeItem>
            </div>
          )
        })}
      </Tree>
    </div>
  )
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions