{"version":3,"file":"TreeNode.cjs","sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { useRef } from 'react';\nimport { 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}\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}: 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    />\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]'));\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      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    'data-hovered': controller.hoveredNode === node.value || undefined,\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-hovered={controller.hoveredNode === node.value || undefined}\n      data-level={level}\n      tabIndex={rootIndex === 0 ? 0 : -1}\n      onKeyDown={handleKeyDown}\n      ref={ref}\n      onMouseOver={(event) => {\n        event.stopPropagation();\n        controller.setHoveredNode(node.value);\n      }}\n      onMouseLeave={(event) => {\n        event.stopPropagation();\n        controller.setHoveredNode(null);\n      }}\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      {controller.expandedState[node.value] && nested.length > 0 && (\n        <ul role=\"group\" {...getStyles('subtree')} data-level={level}>\n          {nested}\n        </ul>\n      )}\n    </li>\n  );\n}\n\nTreeNode.displayName = '@raikou/core/TreeNode';\n"],"names":["useRef","jsx","findElementAncestor","jsxs"],"mappings":"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"}