# All files / src/layout LayoutTree.tsx

0% Statements 0/82
0% Branches 0/1
0% Functions 0/1
0% Lines 0/82

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83

     import { cnb } from "cnbuilder";
    import type { ReactElement } from "react";
    import { useEffect, useRef } from "react";
    import type { TreeItemNode } from "../tree";
    import { Tree } from "../tree";
    import { bem } from "../utils";
    import { DefaultLayoutNavigationItemRenderer } from "./DefaultLayoutNavigationItemRenderer";
    import { DefaultMiniLayoutNavigationItemRenderer } from "./DefaultLayoutNavigationMiniItemRenderer";
    import { useLayoutConfig } from "./LayoutProvider";
    import type { LayoutNavigationItem, LayoutTreeProps } from "./types";
    import { isTemporaryLayout } from "./utils";

    const styles = bem("rmd-layout-nav");

    /**
     * Renders the navigation tree for the Layout component that adds some
     * reasonable defaults to work with navigation items.
     */
    export function LayoutTree<T extends TreeItemNode = LayoutNavigationItem>(
      props: LayoutTreeProps<T>
    ): ReactElement {
      const {
        id: propId,
        "aria-labelledby": ariaLabelledBy,
        "aria-label": ariaLabel = ariaLabelledBy ? undefined : "Navigation",
        className,
        mini = false,
        sticky = false,
        navStyle,
        navClassName,
        navItems,
        selectedIds,
        miniItemRenderer = DefaultMiniLayoutNavigationItemRenderer,
        renderer = mini ? miniItemRenderer : DefaultLayoutNavigationItemRenderer,
        disableTemporaryAutoClose = false,
        ...remaining
      } = props;
      const { baseId, layout, hideNav, visible } = useLayoutConfig();
      const [selectedId] = selectedIds;
      const lastSelectedId = useRef(selectedId);
      const isTemporary = isTemporaryLayout(layout);

      const id = propId ?? `${baseId}-navigation-tree`;

      useEffect(() => {
        if (
          disableTemporaryAutoClose ||
          !isTemporary ||
          !visible ||
          lastSelectedId.current === selectedId
        ) {
          // need to update the lastSelectedId since the selectedId might've changed
          // by a route change OUTSIDE of the navigation drawer. if it isn't
          // updated, it'll automatically close the next time it is opened.
          lastSelectedId.current = selectedId;
          return;
        }

        lastSelectedId.current = selectedId;
        hideNav();
      }, [disableTemporaryAutoClose, isTemporary, visible, hideNav, selectedId]);

      return (
        <nav
          id={`${id}-nav`}
          style={navStyle}
          className={cnb(styles({ sticky, grow: !sticky }), navClassName)}
        >
          <Tree
            {...remaining}
            id={id}
            aria-label={ariaLabel as string}
            aria-labelledby={ariaLabelledBy}
            data={navItems}
            selectedIds={selectedIds}
            className={cnb("rmd-layout-tree", className)}
            renderer={renderer}
          />
        </nav>
      );
    }
    // );