{"version":3,"file":"Tree.cjs","names":["createVarsResolver","getSpacing","factory","useProps","useTree","useStyles","TreeNode","Box","classes"],"sources":["../../../src/components/Tree/Tree.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useClickOutside, useMergedRef } from '@mantine/hooks';\nimport {\n  Box,\n  BoxProps,\n  createVarsResolver,\n  ElementProps,\n  factory,\n  Factory,\n  getSpacing,\n  MantineSpacing,\n  StylesApiProps,\n  useProps,\n  useStyles,\n} from '../../core';\nimport { TreeNode } from './TreeNode';\nimport { TreeController, useTree } from './use-tree';\nimport classes from './Tree.module.css';\n\nexport interface TreeNodeData {\n  label: React.ReactNode;\n  value: string;\n  nodeProps?: Record<string, any>;\n  children?: TreeNodeData[];\n}\n\nexport interface RenderTreeNodePayload {\n  /** Node level in the tree */\n  level: number;\n\n  /** `true` if the node is expanded, applicable only for nodes with `children` */\n  expanded: boolean;\n\n  /** `true` if the node has non-empty `children` array */\n  hasChildren: boolean;\n\n  /** `true` if the node is selected */\n  selected: boolean;\n\n  /** Node data from the `data` prop of `Tree` */\n  node: TreeNodeData;\n\n  /** Tree controller instance, return value of `useTree` hook */\n  tree: TreeController;\n\n  /** Props to spread into the root node element */\n  elementProps: {\n    className: string;\n    style: React.CSSProperties;\n    onClick: (event: React.MouseEvent) => void;\n    'data-selected': boolean | undefined;\n    'data-value': string;\n  };\n}\n\nexport type RenderNode = (payload: RenderTreeNodePayload) => React.ReactNode;\n\nexport type TreeStylesNames = 'root' | 'node' | 'subtree' | 'label';\nexport type TreeCssVariables = {\n  root: '--level-offset';\n};\n\nexport interface TreeProps extends BoxProps, StylesApiProps<TreeFactory>, ElementProps<'ul'> {\n  /** Data used to render nodes */\n  data: TreeNodeData[];\n\n  /** Horizontal padding of each subtree level, key of `theme.spacing` or any valid CSS value @default 'lg' */\n  levelOffset?: MantineSpacing;\n\n  /** If set, tree node with children is expanded on click @default true */\n  expandOnClick?: 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  /** If set, tree node is selected on click @default false */\n  selectOnClick?: boolean;\n\n  /** Use-tree hook instance that can be used to manipulate component state */\n  tree?: TreeController;\n\n  /** A function to render tree node label */\n  renderNode?: RenderNode;\n\n  /** If set, selection is cleared when user clicks outside of the tree @default false */\n  clearSelectionOnOutsideClick?: boolean;\n\n  /** If set, tree nodes range can be selected with click when `Shift` key is pressed @default true */\n  allowRangeSelection?: boolean;\n\n  /** If set, subtree content is kept mounted when collapsed. React 19 `Activity` is used to preserve state. @default false */\n  keepMounted?: boolean;\n}\n\nfunction getFlatValues(data: TreeNodeData[]): string[] {\n  return data.reduce<string[]>((acc, item) => {\n    acc.push(item.value);\n    if (item.children) {\n      acc.push(...getFlatValues(item.children));\n    }\n    return acc;\n  }, []);\n}\n\nexport type TreeFactory = Factory<{\n  props: TreeProps;\n  ref: HTMLUListElement;\n  stylesNames: TreeStylesNames;\n  vars: TreeCssVariables;\n}>;\n\nconst defaultProps = {\n  expandOnClick: true,\n  allowRangeSelection: true,\n  expandOnSpace: true,\n} satisfies Partial<TreeProps>;\n\nconst varsResolver = createVarsResolver<TreeFactory>((_theme, { levelOffset }) => ({\n  root: {\n    '--level-offset': getSpacing(levelOffset),\n  },\n}));\n\nexport const Tree = factory<TreeFactory>((_props) => {\n  const props = useProps('Tree', defaultProps, _props);\n  const {\n    classNames,\n    className,\n    style,\n    styles,\n    unstyled,\n    vars,\n    data,\n    expandOnClick,\n    tree,\n    renderNode,\n    selectOnClick,\n    clearSelectionOnOutsideClick,\n    allowRangeSelection,\n    expandOnSpace,\n    levelOffset,\n    checkOnSpace,\n    keepMounted,\n    attributes,\n    ref,\n    ...others\n  } = props;\n\n  const defaultController = useTree();\n  const controller = tree || defaultController;\n\n  const getStyles = useStyles<TreeFactory>({\n    name: 'Tree',\n    classes,\n    props,\n    className,\n    style,\n    classNames,\n    styles,\n    unstyled,\n    attributes,\n    vars,\n    varsResolver,\n  });\n\n  const clickOutsideRef = useClickOutside(\n    () => clearSelectionOnOutsideClick && controller.clearSelected()\n  );\n\n  const mergedRef = useMergedRef(ref, clickOutsideRef);\n\n  const flatValues = useMemo(() => getFlatValues(data), [data]);\n\n  useEffect(() => {\n    controller.initialize(data);\n  }, [data]);\n\n  const nodes = data.map((node, index) => (\n    <TreeNode\n      key={node.value}\n      node={node}\n      getStyles={getStyles}\n      rootIndex={index}\n      expandOnClick={expandOnClick}\n      selectOnClick={selectOnClick}\n      controller={controller}\n      renderNode={renderNode}\n      flatValues={flatValues}\n      allowRangeSelection={allowRangeSelection}\n      expandOnSpace={expandOnSpace}\n      checkOnSpace={checkOnSpace}\n      keepMounted={keepMounted}\n    />\n  ));\n\n  return (\n    <Box\n      component=\"ul\"\n      ref={mergedRef}\n      {...getStyles('root')}\n      {...others}\n      role=\"tree\"\n      aria-multiselectable={controller.multiple}\n      data-tree-root\n    >\n      {nodes}\n    </Box>\n  );\n});\n\nTree.displayName = '@mantine/core/Tree';\nTree.classes = classes;\nTree.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;;;AAiGA,SAAS,cAAc,MAAgC;AACrD,QAAO,KAAK,QAAkB,KAAK,SAAS;AAC1C,MAAI,KAAK,KAAK,MAAM;AACpB,MAAI,KAAK,SACP,KAAI,KAAK,GAAG,cAAc,KAAK,SAAS,CAAC;AAE3C,SAAO;IACN,EAAE,CAAC;;AAUR,MAAM,eAAe;CACnB,eAAe;CACf,qBAAqB;CACrB,eAAe;CAChB;AAED,MAAM,eAAeA,6BAAAA,oBAAiC,QAAQ,EAAE,mBAAmB,EACjF,MAAM,EACJ,kBAAkBC,iBAAAA,WAAW,YAAY,EAC1C,EACF,EAAE;AAEH,MAAa,OAAOC,gBAAAA,SAAsB,WAAW;CACnD,MAAM,QAAQC,kBAAAA,SAAS,QAAQ,cAAc,OAAO;CACpD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,eACA,MACA,YACA,eACA,8BACA,qBACA,eACA,aACA,cACA,aACA,YACA,KACA,GAAG,WACD;CAEJ,MAAM,oBAAoBC,iBAAAA,SAAS;CACnC,MAAM,aAAa,QAAQ;CAE3B,MAAM,YAAYC,mBAAAA,UAAuB;EACvC,MAAM;EACN,SAAA,oBAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAMF,MAAM,aAAA,GAAA,eAAA,cAAyB,MAAA,GAAA,eAAA,uBAHvB,gCAAgC,WAAW,eAAe,CACjE,CAEmD;CAEpD,MAAM,cAAA,GAAA,MAAA,eAA2B,cAAc,KAAK,EAAE,CAAC,KAAK,CAAC;AAE7D,EAAA,GAAA,MAAA,iBAAgB;AACd,aAAW,WAAW,KAAK;IAC1B,CAAC,KAAK,CAAC;CAEV,MAAM,QAAQ,KAAK,KAAK,MAAM,UAC5B,iBAAA,GAAA,kBAAA,KAACC,iBAAAA,UAAD;EAEQ;EACK;EACX,WAAW;EACI;EACA;EACH;EACA;EACA;EACS;EACN;EACD;EACD;EACb,EAbK,KAAK,MAaV,CACF;AAEF,QACE,iBAAA,GAAA,kBAAA,KAACC,YAAAA,KAAD;EACE,WAAU;EACV,KAAK;EACL,GAAI,UAAU,OAAO;EACrB,GAAI;EACJ,MAAK;EACL,wBAAsB,WAAW;EACjC,kBAAA;YAEC;EACG,CAAA;EAER;AAEF,KAAK,cAAc;AACnB,KAAK,UAAUC,oBAAAA;AACf,KAAK,eAAe"}