{"version":3,"file":"FlatTreeNode.mjs","names":["classes"],"sources":["../../../src/components/Tree/FlatTreeNode.tsx"],"sourcesContent":["import { memo, useRef } from 'react';\nimport { findElementAncestor } from '../../core';\nimport type { RenderNode, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\nimport classes from './Tree.module.css';\n\nexport interface FlatTreeNodeProps {\n  /** Node data from tree data */\n  node: TreeNodeData;\n\n  /** Nesting level of the node, starts at 1 */\n  level: number;\n\n  /** Value of the parent node, `null` for root nodes */\n  parent: string | null;\n\n  /** Whether the node has children */\n  hasChildren: boolean;\n\n  /** Whether the node is expanded */\n  expanded: boolean;\n\n  /** Tree controller instance, return value of `useTree` hook */\n  tree: TreeController;\n\n  /** If set, tree node with children is expanded on click @default true */\n  expandOnClick?: boolean;\n\n  /** If set, tree node is selected on click @default false */\n  selectOnClick?: boolean;\n\n  /** If set, tree node with children is expanded on space key press @default true */\n  expandOnSpace?: boolean;\n\n  /** If set, tree node is checked on space key press @default false */\n  checkOnSpace?: boolean;\n\n  /** A function to render tree node label */\n  renderNode?: RenderNode;\n\n  /** Style to apply to the root element, used for virtualizer positioning */\n  style?: React.CSSProperties;\n\n  /** Tab index for the node */\n  tabIndex?: number;\n}\n\nexport const FlatTreeNode = memo(function FlatTreeNode({\n  node,\n  level,\n  parent,\n  hasChildren,\n  expanded,\n  tree,\n  expandOnClick = true,\n  selectOnClick,\n  expandOnSpace = true,\n  checkOnSpace,\n  renderNode,\n  style,\n  tabIndex = -1,\n}: FlatTreeNodeProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const isLoading = tree.isNodeLoading(node.value);\n  const loadError = tree.getNodeLoadError(node.value);\n  const selected = tree.selectedState.includes(node.value);\n\n  const handleClick = (event: React.MouseEvent) => {\n    event.stopPropagation();\n\n    if (expandOnClick && hasChildren) {\n      tree.toggleExpanded(node.value);\n    }\n\n    if (selectOnClick) {\n      tree.select(node.value);\n    }\n\n    ref.current?.focus();\n  };\n\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (event.nativeEvent.code === 'ArrowRight') {\n      event.stopPropagation();\n      event.preventDefault();\n\n      if (expanded && hasChildren) {\n        const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n        const nodes = root\n          ? Array.from(root.querySelectorAll<HTMLElement>('[role=treeitem]')).filter(\n              (treeNode) => treeNode.style.display !== 'none'\n            )\n          : [];\n        const index = nodes.indexOf(event.currentTarget as HTMLElement);\n        if (index !== -1) {\n          nodes[index + 1]?.focus();\n        }\n      } else if (hasChildren) {\n        tree.expand(node.value);\n      }\n    }\n\n    if (event.nativeEvent.code === 'ArrowLeft') {\n      event.stopPropagation();\n      event.preventDefault();\n\n      if (expanded && hasChildren) {\n        tree.collapse(node.value);\n      } else if (parent) {\n        const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n        const parentElement = root?.querySelector<HTMLElement>(\n          `[role=treeitem][data-value=\"${CSS.escape(parent)}\"]`\n        );\n        parentElement?.focus();\n      }\n    }\n\n    if (event.nativeEvent.code === 'ArrowDown' || event.nativeEvent.code === 'ArrowUp') {\n      const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n\n      if (!root) {\n        return;\n      }\n\n      event.stopPropagation();\n      event.preventDefault();\n      const nodes = Array.from(root.querySelectorAll<HTMLElement>('[role=treeitem]')).filter(\n        (treeNode) => treeNode.style.display !== 'none'\n      );\n      const index = nodes.indexOf(event.currentTarget as HTMLElement);\n\n      if (index === -1) {\n        return;\n      }\n\n      const nextIndex = event.nativeEvent.code === 'ArrowDown' ? index + 1 : index - 1;\n      nodes[nextIndex]?.focus();\n    }\n\n    if (event.nativeEvent.code === 'Space') {\n      if (expandOnSpace) {\n        event.stopPropagation();\n        event.preventDefault();\n        tree.toggleExpanded(node.value);\n      }\n\n      if (checkOnSpace) {\n        event.stopPropagation();\n        event.preventDefault();\n        if (tree.isNodeChecked(node.value)) {\n          tree.uncheckNode(node.value);\n        } else {\n          tree.checkNode(node.value);\n        }\n      }\n    }\n  };\n\n  const elementProps = {\n    className: classes.label,\n    style: {} as React.CSSProperties,\n    onClick: handleClick,\n    'data-selected': selected || undefined,\n    'data-value': node.value,\n  };\n\n  return (\n    <div\n      ref={ref}\n      className={classes.node}\n      style={{\n        ...({\n          '--label-offset': `calc(var(--level-offset, var(--mantine-spacing-lg)) * ${level - 1})`,\n        } as React.CSSProperties),\n        ...style,\n      }}\n      role=\"treeitem\"\n      aria-selected={selected}\n      aria-expanded={hasChildren ? expanded : undefined}\n      data-value={node.value}\n      data-selected={selected || undefined}\n      data-level={level}\n      tabIndex={tabIndex}\n      onKeyDown={handleKeyDown}\n    >\n      {typeof renderNode === 'function' ? (\n        renderNode({\n          node,\n          level,\n          selected,\n          tree,\n          expanded,\n          hasChildren,\n          isLoading,\n          loadError,\n          elementProps,\n          dragHandleProps: undefined,\n        })\n      ) : (\n        <div {...elementProps}>{node.label}</div>\n      )}\n    </div>\n  );\n});\n\nFlatTreeNode.displayName = '@mantine/core/FlatTreeNode';\n"],"mappings":"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"}