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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use std::borrow::BorrowMut;
use uuid::Uuid;

use crate::{DefaultModifiers, Renderable};
use crate::components::{Alignment, Appendable, ChildContainer, HStack, Text, TextStyle, View};
use crate::components::icons::IconPack;
use crate::node::{Node, NodeContainer};

#[derive(Debug, Clone)]
pub struct TabView {
    node: Node,
    children: Vec<TabViewItem>,
}

impl TabView {
    pub fn new() -> Self {
        Self {
            node: Default::default(),
            children: vec![],
        }
    }

    pub fn append_child(&mut self, child: TabViewItem) -> Self {
        self.children.push(child);
        self.clone()
    }
}

impl DefaultModifiers<TabView> for TabView {}

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

impl Renderable for TabView {
    fn render(&self) -> Node {
        let mut tab_view = self
            .clone()
            .add_class("tab-view");

        tab_view.node.children.push({
            let mut tab_bar = HStack::new(Alignment::Stretch)
                .add_class("tab-view__tab-container");
            self.children.iter()
                .for_each(|child| {
                    tab_bar.append_child({
                        let mut tab = View::new()
                            .set_attr("data-tabId", &child.id.to_string())
                            .add_class("tab-view__tab-container__tab")
                            .append_child({
                                Text::new(&child.title, TextStyle::Label)
                            });
                        if child.open {
                            tab.set_attr("data-is-open", "data-is-open");
                            tab.add_class("tab-view__tab-container__tab--active");
                        }
                        tab
                    });
                });
            tab_bar
        }.render());

        tab_view.node.children.push({
            let mut tabs_contents = View::new()
                .add_class("tab-view__content-container");
            self.children.iter()
                .for_each(|child| {
                    tabs_contents.append_child({
                        let mut tab_content = View::new()
                            .add_class("")
                            .set_attr("data-tabId", &child.id.to_string())
                            .add_class("tab-view__content-container__content");
                        child.children.clone().into_iter().for_each(|child| {
                            tab_content.append_child(child);
                        });
                        tab_content
                    });
                });
            tabs_contents
        }.render());


        tab_view.get_node().clone()
    }
}

#[derive(Debug, Clone)]
pub struct TabViewItem {
    node: Node,
    pub id: Uuid,
    pub title: String,
    pub icon: Option<Box<dyn IconPack>>,
    pub open: bool,
    children: Vec<Box<dyn Renderable>>,
}

impl TabViewItem {
    pub fn new(title: &str) -> TabViewItem {
        TabViewItem {
            node: Default::default(),
            id: Uuid::new_v4(),
            title: title.to_string(),
            icon: None,
            open: false,
            children: vec![],
        }
    }

    /// If set to true, this tab will be opened by default
    pub fn open(&mut self, is_open: bool) -> Self {
        self.open = is_open;
        self.clone()
    }
}

impl DefaultModifiers<TabViewItem> for TabViewItem {}

impl Appendable for TabViewItem {}

impl ChildContainer for TabViewItem {
    fn get_children(&mut self) -> &mut Vec<Box<dyn Renderable>> {
        return self.children.borrow_mut();
    }
}

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

impl Renderable for TabViewItem {
    fn render(&self) -> Node {
        let mut tab_view_item = self
            .clone()
            .add_class("tab-view-item");

        tab_view_item.get_node().clone()
    }
}