aboutsummaryrefslogtreecommitdiff
path: root/src/components/Sidebar/utils.js
blob: b555e603907d2f623d1e4a4d0f2eb3b004bcdcc0 (plain) (blame)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { Children } from "react";
import { withPrefix } from "gatsby";

const simplifyChildren = (children, prefix, depth = 0) => {
  return Children.toArray(children).reduce((items, item) => {
    if (!item.props || !item.props.children) {
      return items;
    }

    if (item.props.mdxType === "a") {
      let href = item.props.href;
      if (href.startsWith(prefix)) {
        href = href.slice(prefix.length);
      }
      return items.concat({
        link: href,
        title: item.props.children
      });
    }

    if (depth > 0 && item.props.mdxType === "ul") {
      const last = items[items.length - 1];

      items[items.length - 1] = {
        ...last,
        items: simplifyChildren(item.props.children, prefix)
      };

      return items;
    }

    return items.concat(
      simplifyChildren(item.props.children, prefix, depth + 1)
    );
  }, []);
};

const extendItem = item => {
  if (item.items) {
    for (const childItem of item.items) {
      childItem.level = item.level + 1;
      childItem.parentLink = item.link;

      extendItem(childItem);
    }
  }
};

export const getItems = (children, prefix) => {
  const items = simplifyChildren(children, prefix);

  for (const item of items) {
    item.level = 0;

    extendItem(item);
  }

  return items;
};

const isItemActive = (item, location) => {
  const linkMatchesPathname = withPrefix(item.link) === location.pathname;

  if (linkMatchesPathname) {
    return item;
  }

  return false;
};

export const getActiveItem = (items, location) => {
  for (const item of items) {
    if (item.items) {
      const activeSubItem = getActiveItem(item.items, location);

      if (activeSubItem) {
        return activeSubItem;
      }
    }

    if (item.link) {
      if (isItemActive(item, location)) {
        return item;
      }
    }
  }

  return false;
};

const isItemParentActive = (items, parentLink) => {
  for (const item of items) {
    if (item.link === parentLink) {
      return item;
    }

    if (item.items) {
      for (const childItem of item.items) {
        const activeChildItem = isItemParentActive([childItem], parentLink);

        if (activeChildItem) {
          return activeChildItem;
        }
      }
    }
  }

  return false;
};

export const getActiveItemParentLinks = (
  items,
  activeItem,
  activeItemParentLinks
) => {
  if (activeItem.parentLink) {
    const activeParent = isItemParentActive(items, activeItem.parentLink);

    activeItemParentLinks.push(activeParent.link);

    return getActiveItemParentLinks(items, activeParent, activeItemParentLinks);
  }

  return activeItemParentLinks;
};