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
use crate::node::{Node, NodeContainer};
use crate::{DefaultModifiers, Renderable};
use std::borrow::BorrowMut;
use crate::components::{Text, TextStyle};

#[derive(Debug, Clone)]
pub struct TableOfContentsItem {
    children: Vec<TableOfContentsItem>,
    pub label: String,
    pub referrer_id: String,
}

impl TableOfContentsItem {
    pub fn new(label: &str, referrer_id: &str) -> Self {
        Self {
            children: vec![],
            label: label.to_string(),
            referrer_id: referrer_id.to_string(),
        }
    }
    pub fn append_child(&mut self, item: TableOfContentsItem) -> Self {
        self.children.push(item);
        self.clone()
    }
}

#[derive(Debug, Clone)]
pub struct TableOfContents {
    node: Node,
    root_id: String,
    children: Vec<TableOfContentsItem>,
}

impl TableOfContents {
    pub fn new(root_id: &str) -> Self {
        Self {
            node: Default::default(),
            root_id: root_id.to_string(),
            children: vec![],
        }
    }
    pub fn append_child(&mut self, item: TableOfContentsItem) -> Self {
        self.children.push(item);
        self.clone()
    }
}

impl NodeContainer for TableOfContents {
    fn get_node(&mut self) -> &mut Node {
        self.node.borrow_mut()
    }
}

impl DefaultModifiers<TableOfContents> for TableOfContents {}

impl Renderable for TableOfContents {
    fn render(&self) -> Node {
        let mut toc = self
            .clone()
            .set_attr("data-root", &self.root_id)
            .add_class("table-of-contents");

        for child in &toc.children {
            toc.node.children.push({
                Text::new(&child.label, TextStyle::Label)
                    .add_class("table-of-contents__item")
                    .tag("a")
                    .set_attr("href", &child.referrer_id)
                    .render()
            });
        }

        toc.get_node().clone()
    }
}