{"version":3,"file":"TreeNode.cjs","names":["useTreeNodeDragDrop","findElementAncestor","Box","Loader","Activity"],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport { Loader } from '../Loader';\nimport type { TreeDragDropPayload } from './move-tree-node/move-tree-node';\nimport type { RenderNode, TreeDragState, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\nimport { TreeAllowDrop, useTreeNodeDragDrop } from './use-tree-node-drag-drop';\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  onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n  allowDrop: TreeAllowDrop | undefined;\n  withDragHandle: boolean | undefined;\n  dragStateRef: React.RefObject<TreeDragState>;\n  data: TreeNodeData[];\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  onDragDrop,\n  allowDrop,\n  withDragHandle,\n  dragStateRef,\n  data,\n}: TreeNodeProps) {\n  const ref = useRef<HTMLLIElement>(null);\n  const hasLoadedChildren = Array.isArray(node.children);\n  const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;\n  const hasChildren = hasLoadedChildren || hasAsyncChildren;\n  const isLoading = controller.isNodeLoading(node.value);\n  const loadError = controller.getNodeLoadError(node.value);\n  const isExpanded = controller.expandedState[node.value] || false;\n\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      onDragDrop={onDragDrop}\n      allowDrop={allowDrop}\n      withDragHandle={withDragHandle}\n      dragStateRef={dragStateRef}\n      data={data}\n    />\n  ));\n\n  const { elementProps: dragElementProps, dragHandleProps } = useTreeNodeDragDrop({\n    nodeValue: node.value,\n    hasChildren,\n    data,\n    onDragDrop,\n    dragStateRef,\n    allowDrop,\n    withDragHandle,\n  });\n\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (event.nativeEvent.code === 'ArrowRight') {\n      event.stopPropagation();\n      event.preventDefault();\n\n      if (isExpanded) {\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 (isExpanded && hasChildren) {\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      if (expandOnClick) {\n        controller.toggleExpanded(node.value);\n      }\n\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    ...dragElementProps,\n  };\n\n  const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;\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: isExpanded,\n          hasChildren,\n          isLoading,\n          loadError,\n          elementProps,\n          dragHandleProps,\n        })\n      ) : (\n        <div {...elementProps}>{node.label}</div>\n      )}\n\n      {withLoadingIndicator && (\n        <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n          <li\n            {...getStyles('node', {\n              style: { '--label-offset': `calc(var(--level-offset) * ${level})` },\n            })}\n          >\n            <div {...getStyles('label')}>\n              <Loader size={16} />\n            </div>\n          </li>\n        </Box>\n      )}\n\n      {keepMounted && nested.length > 0 ? (\n        <Activity mode={isExpanded ? 'visible' : 'hidden'}>\n          <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n            {nested}\n          </Box>\n        </Activity>\n      ) : (\n        isExpanded &&\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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"}