{"version":3,"file":"TreeNode.cjs","names":["findElementAncestor","Activity","Box"],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport type { RenderNode, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\n\nfunction getValuesRange(anchor: string | null, value: string | undefined, flatValues: string[]) {\n  if (!anchor || !value) {\n    return [];\n  }\n\n  const anchorIndex = flatValues.indexOf(anchor);\n  const valueIndex = flatValues.indexOf(value);\n  const start = Math.min(anchorIndex, valueIndex);\n  const end = Math.max(anchorIndex, valueIndex);\n\n  return flatValues.slice(start, end + 1);\n}\n\ninterface TreeNodeProps {\n  node: TreeNodeData;\n  getStyles: GetStylesApi<TreeFactory>;\n  rootIndex: number | undefined;\n  controller: TreeController;\n  expandOnClick: boolean | undefined;\n  flatValues: string[];\n  isSubtree?: boolean;\n  level?: number;\n  renderNode: RenderNode | undefined;\n  selectOnClick: boolean | undefined;\n  allowRangeSelection: boolean | undefined;\n  expandOnSpace: boolean | undefined;\n  checkOnSpace: boolean | undefined;\n  keepMounted: boolean | undefined;\n}\n\nexport function TreeNode({\n  node,\n  getStyles,\n  rootIndex,\n  controller,\n  expandOnClick,\n  selectOnClick,\n  isSubtree,\n  level = 1,\n  renderNode,\n  flatValues,\n  allowRangeSelection,\n  expandOnSpace,\n  checkOnSpace,\n  keepMounted,\n}: TreeNodeProps) {\n  const ref = useRef<HTMLLIElement>(null);\n  const nested = (node.children || []).map((child) => (\n    <TreeNode\n      key={child.value}\n      node={child}\n      flatValues={flatValues}\n      getStyles={getStyles}\n      rootIndex={undefined}\n      level={level + 1}\n      controller={controller}\n      expandOnClick={expandOnClick}\n      isSubtree\n      renderNode={renderNode}\n      selectOnClick={selectOnClick}\n      allowRangeSelection={allowRangeSelection}\n      expandOnSpace={expandOnSpace}\n      checkOnSpace={checkOnSpace}\n      keepMounted={keepMounted}\n    />\n  ));\n\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (event.nativeEvent.code === 'ArrowRight') {\n      event.stopPropagation();\n      event.preventDefault();\n\n      if (controller.expandedState[node.value]) {\n        event.currentTarget.querySelector<HTMLLIElement>('[role=treeitem]')?.focus();\n      } else {\n        controller.expand(node.value);\n      }\n    }\n\n    if (event.nativeEvent.code === 'ArrowLeft') {\n      event.stopPropagation();\n      event.preventDefault();\n      if (controller.expandedState[node.value] && (node.children || []).length > 0) {\n        controller.collapse(node.value);\n      } else if (isSubtree) {\n        findElementAncestor(event.currentTarget as HTMLElement, '[role=treeitem]')?.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<HTMLLIElement>('[role=treeitem]')).filter(\n        (treeNode) => treeNode.style.display !== 'none'\n      );\n      const index = nodes.indexOf(event.currentTarget as HTMLLIElement);\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      if (event.shiftKey) {\n        const selectNode = nodes[nextIndex];\n\n        if (selectNode) {\n          controller.setSelectedState(\n            getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues)\n          );\n        }\n      }\n    }\n\n    if (event.nativeEvent.code === 'Space') {\n      if (expandOnSpace) {\n        event.stopPropagation();\n        event.preventDefault();\n        controller.toggleExpanded(node.value);\n      }\n\n      if (checkOnSpace) {\n        event.stopPropagation();\n        event.preventDefault();\n        controller.isNodeChecked(node.value)\n          ? controller.uncheckNode(node.value)\n          : controller.checkNode(node.value);\n      }\n    }\n  };\n\n  const handleNodeClick = (event: React.MouseEvent) => {\n    event.stopPropagation();\n\n    if (allowRangeSelection && event.shiftKey && controller.anchorNode) {\n      controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));\n      ref.current?.focus();\n    } else {\n      expandOnClick && controller.toggleExpanded(node.value);\n      selectOnClick && controller.select(node.value);\n      ref.current?.focus();\n    }\n  };\n\n  const selected = controller.selectedState.includes(node.value);\n  const elementProps = {\n    ...getStyles('label'),\n    onClick: handleNodeClick,\n    'data-selected': selected || undefined,\n    'data-value': node.value,\n  };\n\n  return (\n    <li\n      {...getStyles('node', {\n        style: { '--label-offset': `calc(var(--level-offset) * ${level - 1})` },\n      })}\n      role=\"treeitem\"\n      aria-selected={selected}\n      data-value={node.value}\n      data-selected={selected || undefined}\n      data-level={level}\n      tabIndex={rootIndex === 0 ? 0 : -1}\n      onKeyDown={handleKeyDown}\n      ref={ref}\n    >\n      {typeof renderNode === 'function' ? (\n        renderNode({\n          node,\n          level,\n          selected,\n          tree: controller,\n          expanded: controller.expandedState[node.value] || false,\n          hasChildren: Array.isArray(node.children) && node.children.length > 0,\n          elementProps,\n        })\n      ) : (\n        <div {...elementProps}>{node.label}</div>\n      )}\n\n      {keepMounted && nested.length > 0 ? (\n        <Activity mode={controller.expandedState[node.value] ? 'visible' : 'hidden'}>\n          <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n            {nested}\n          </Box>\n        </Activity>\n      ) : (\n        controller.expandedState[node.value] &&\n        nested.length > 0 && (\n          <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n            {nested}\n          </Box>\n        )\n      )}\n    </li>\n  );\n}\n\nTreeNode.displayName = '@mantine/core/TreeNode';\n"],"mappings":"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"}