Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from "react"
- import { graphql, useStaticQuery } from "gatsby"
- // populates nodes with an array filled with each directory in slug
- const populateNodeDirectories = edges => {
- return edges.map(({ node }) => {
- node.directories = node.fields.slug
- .split("/")
- .filter(element => element.length > 0)
- return node
- })
- }
- const arraysEqual = (a, b) => {
- if (a === b) return true
- if (a == null || b == null) return false
- if (a.length !== b.length) return false
- for (let i = 0; i < a.length; ++i) {
- if (a[i] !== b[i]) return false
- }
- return true
- }
- // determines order of slugs such that parents come before children
- const compareSlugs = (a, b) => {
- const minDirCount = Math.min(a.directories.length, b.directories.length)
- for (let i = 0; i < minDirCount; i++) {
- if (a.directories[i] < b.directories[i]) {
- return -1
- }
- if (a.directories[i] > b.directories[i]) {
- return 1
- }
- }
- return a.directories.length - b.directories.length
- }
- // Determines order of nodes for display. display_order is nullable and has
- // higher priority over title
- const compareDisplayOrder = (a, b) => {
- const a_displayOrder = a.frontmatter.display_order
- const b_displayOrder = b.frontmatter.display_order
- if (a_displayOrder === b_displayOrder) {
- const a_title = a.frontmatter.title
- const b_title = b.frontmatter.title
- if (a_title > b_title) {
- return 1
- }
- if (a_title < b_title) {
- return -1
- }
- }
- if (a_displayOrder === null) {
- return 1
- }
- if (b_displayOrder === null) {
- return -1
- }
- if (a_displayOrder > b_displayOrder) {
- return 1
- }
- if (a_displayOrder < b_displayOrder) {
- return -1
- }
- return 0
- }
- const findParentNode = (nodes, childNode) => {
- const parentNode = nodes.find(node => {
- return isParentNode(node, childNode)
- })
- if (parentNode) {
- return parentNode
- } else {
- // iterates through each node on current level and recursively runs for all
- // children on those nodes until a parent node is found
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].children instanceof Array) {
- return findParentNode(nodes[i].children, childNode)
- }
- }
- }
- }
- const isParentNode = (parentNode, childNode) => {
- return arraysEqual(
- parentNode.directories,
- childNode.directories.slice(0, childNode.directories.length - 1)
- )
- }
- const groupNodes = nodes => {
- // requires nodes to be sorted by slug to work correctly
- nodes.sort(compareSlugs)
- let groupedNodes = []
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].directories.length === 0) {
- // skip home index node
- } else if (nodes[i].directories.length === 1) {
- // add root level nodes
- nodes[i].children = []
- groupedNodes.push(nodes[i])
- } else {
- // find parent node for current node and add it as a child
- const parentNode = findParentNode(groupedNodes, nodes[i])
- if (parentNode) {
- nodes[i].children = []
- parentNode.children.push(nodes[i])
- }
- }
- }
- return groupedNodes
- }
- const sortNodesByDisplayOrder = nodes => {
- nodes.sort(compareDisplayOrder)
- for (let i = 0; i < nodes.length; i++) {
- // iterates through each node on current level and recursively runs for all
- // children on those nodes until each node and all their children are sorted
- if (nodes[i].children instanceof Array) {
- sortNodesByDisplayOrder(nodes[i].children)
- }
- }
- return nodes
- }
- const getGroupedNodes = edges => {
- let nodes = populateNodeDirectories(edges)
- nodes = groupNodes(nodes)
- nodes = sortNodesByDisplayOrder(nodes)
- return nodes
- }
- const NavigationDrawer = () => {
- const data = useStaticQuery(graphql`
- query {
- allMarkdownRemark {
- edges {
- node {
- id
- frontmatter {
- title
- display_order
- }
- fields {
- slug
- }
- }
- }
- }
- }
- `)
- const nodes = getGroupedNodes(data.allMarkdownRemark.edges)
- {...}
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement