Trees

Overview

Tree component is a nested recursive component. It means that a component contains children which have same structure as itself. To see what we are saying, let’s look at example below.

P.S: Note aside, it’s important to understand that tree is a functional feature. It’s up to you to design it your own way.

MenuTree is a complex component which, as you read, lists link from its children, but, in same time, allows you to display children link of its children (are you still there ?).

A similar feature will be a nested dropdown, where one or many children has itself a nested dropdown.

Still don’t get it ? Check example below.

Copied !

---
import Button from "$components/button/Button.astro";
import Icon from "$components/icon/Icon.astro";
import MenuTree from "$components/tree/menu/MenuTree.astro";
import type { TreeType } from "$components/tree/types";

const root: TreeType = {
  id: "root",
  children: [
    {
      id: "tree-1",
      label: "Tree 1",
      parent: "root",
      children: [
        {
          id: "tree-1-1",
          label: "Tree 1-1",
          parent: "tree-1",
          href: "#",
        },
        {
          id: "tree-1-2",
          label: "Tree 1-2",
          parent: "tree-1",
          children: [
            {
              id: "tree-1-2-1",
              label: "Tree 1-2-2",
              parent: "tree-1-2",
              href: "#",
            },
            {
              id: "tree-1-2-2",
              label: "Tree 1-2-2",
              parent: "tree-1-2",
              href: "#",
            },
            {
              id: "tree-1-2-3",
              label: "Tree 1-2-3",
              parent: "tree-1-2",
              href: "#",
            },
          ],
        },
      ],
    },
    {
      id: "tree-2",
      label: "Tree 2",
      parent: "root",
      children: [
        {
          id: "tree-2-1",
          label: "Tree 2-1",
          parent: "tree-2",
          href: "#",
        },
        {
          id: "tree-2-2",
          label: "Tree 2-2",
          parent: "tree-2",
          href: "#",
        },
        {
          id: "tree-2-3",
          label: "Tree 2-3",
          parent: "tree-2",
          href: "#",
        },
        {
          id: "tree-2-4",
          label: "Tree 2-4",
          parent: "tree-2",
          href: "#",
        },
      ],
    },
    {
      id: "tree-3",
      label: "Tree 3",
      parent: "root",
      href: "#",
    },
  ],
};
---

<MenuTree {root} class="bg-white rounded-lg border w-full [&>button]:p-4">
  <template x-if="selectedItem.parent">
    <div class="relative flex items-center justify-center p-4">
      <Button
        class="absolute top-1/2 -translate-y-1/2 left-4"
        text="Back"
        @click="goToParent(selectedItem.parent)"
      />
      <span x-text="selectedItem.label"></span>
    </div>
  </template>
  <nav class="divide-y-2 opacity-100">
    <template x-for="menu in selectedItem.children">
      <section class="hover:bg-slate-100">
        <button
          class="w-full cursor-default p-4 flex items-center justify-between"
          :class="{ 'cursor-pointer': menu.children }"
          @click="menu.children && selectItem(menu)"
          x-show="menu.children"
        >
          <span x-text="menu.label"></span>
          <template x-if="menu.children">
            <Icon name="arrow-right-s-line" />
          </template>
        </button>
        <div class="p-4" x-show="!menu.children">
          <a class="text-center hover:underline" :href="menu.href">
            <span x-text="menu.label"></span>
          </a>
        </div>
      </section>
    </template>
  </nav>
</MenuTree>