'use client'; import { Fragment, type ReactNode } from 'react'; import { cn } from '@djangocfg/ui-core/lib'; import { useTreeContext } from '../context/TreeContext'; import { appearanceToStyle } from '../data/appearance'; import type { FlatRow, TreeRowRenderProps, TreeRowSlot } from '../types'; import { TreeRow } from './TreeRow'; import { TreeEmpty } from './TreeEmpty'; export interface TreeContentProps { /** Custom row renderer; falls back to . */ children?: TreeRowSlot; className?: string; /** Override aria-label for the container. */ ariaLabel?: string; /** * Container ARIA role. Defaults to `'tree'` for standalone composition * use. `` passes `'group'` because its own outer element * already carries `role="tree"` + `aria-activedescendant`. */ role?: 'tree' | 'group' | 'presentation'; } /** DOM id for a tree row — referenced by `aria-activedescendant`. */ export const treeRowDomId = (id: string) => `tree-row-${id}`; export function TreeContent({ children, className, ariaLabel, role = 'tree', }: TreeContentProps) { const { flatRows, labels, selected, focused, matchingIds, appearance, selectionMode } = useTreeContext(); if (flatRows.length === 0) { return {labels.empty}; } const isTree = role === 'tree'; return (
{flatRows.map((row: FlatRow) => { const slot: TreeRowRenderProps = { node: row.node, level: row.level, isSelected: selected.has(row.node.id), isExpanded: row.isExpanded, isFocused: focused === row.node.id, isFolder: row.isFolder, isLoading: row.isLoading, isMatchingSearch: matchingIds.has(row.node.id), }; const node: ReactNode = children ? children(slot) : ; return {node}; })}
); }