diff --git a/src/lib.rs b/src/lib.rs
index e8bf91d..3dd1a49 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,6 +12,7 @@ mod progress;
mod slider;
mod space;
mod table;
+mod tabs;
mod teleport;
mod theme;
mod utils;
@@ -27,6 +28,7 @@ pub use modal::*;
pub use progress::*;
pub use slider::*;
pub use space::*;
+pub use tabs::*;
pub use table::*;
pub use theme::Theme;
pub use wave::*;
diff --git a/src/tabs/mod.rs b/src/tabs/mod.rs
new file mode 100644
index 0000000..2953299
--- /dev/null
+++ b/src/tabs/mod.rs
@@ -0,0 +1,64 @@
+mod tab;
+use crate::{utils::mount_style::mount_style, theme::use_theme, Theme};
+use leptos::*;
+use stylers::style_sheet_str;
+pub use tab::*;
+
+#[component]
+pub fn Tabs(cx: Scope, active_key: RwSignal<&'static str>, children: Children) -> impl IntoView {
+ let class_name = mount_style("tabs", || style_sheet_str!("./src/tabs/tabs.css"));
+ let tab_options_vec = create_rw_signal(cx, vec![]);
+ provide_context(
+ cx,
+ TabsInjectionKey {
+ active_key: active_key.clone(),
+ tab_options_vec: tab_options_vec.clone(),
+ },
+ );
+ let theme = use_theme(cx, Theme::light);
+ let css_vars = create_memo(cx, move |_| {
+ let mut css_vars = String::new();
+ let theme = theme.get();
+ let color_primary = theme.common.color_primary.clone();
+ css_vars.push_str(&format!("--label-active-background-color: {color_primary};"));
+ css_vars
+ });
+ view! { cx, class=class_name,
+
+
+
+ { options.label }
+
+ }>
+
+
+
+
+ { children(cx) }
+
+
+ }
+}
+
+#[derive(Clone)]
+pub struct TabsInjectionKey {
+ active_key: RwSignal<&'static str>,
+ tab_options_vec: RwSignal>,
+}
+
+impl TabsInjectionKey {
+ pub fn get_key(&self) -> &str {
+ self.active_key.get()
+ }
+
+ pub(crate) fn push_tab_options(&self, options: TabOptions) {
+ self.tab_options_vec.update(|v| {
+ v.push(options);
+ });
+ }
+}
+
+pub fn use_tabs(cx: Scope) -> TabsInjectionKey {
+ use_context::(cx).expect("TabsInjectionKey not exist")
+}
diff --git a/src/tabs/tab.css b/src/tabs/tab.css
new file mode 100644
index 0000000..d28c3f8
--- /dev/null
+++ b/src/tabs/tab.css
@@ -0,0 +1,3 @@
+.melt-tab--hidden {
+ display: none;
+}
diff --git a/src/tabs/tab.rs b/src/tabs/tab.rs
new file mode 100644
index 0000000..be4fedf
--- /dev/null
+++ b/src/tabs/tab.rs
@@ -0,0 +1,22 @@
+use super::use_tabs;
+use crate::utils::mount_style::mount_style;
+use leptos::*;
+use stylers::style_sheet_str;
+
+#[derive(Clone)]
+pub(crate) struct TabOptions {
+ pub key: &'static str,
+ pub label: &'static str,
+}
+
+#[component]
+pub fn Tab(cx: Scope, key: &'static str, label: &'static str, children: Children) -> impl IntoView {
+ let class_name = mount_style("tab", || style_sheet_str!("./src/tabs/tab.css"));
+ let tabs = use_tabs(cx);
+ tabs.push_tab_options(TabOptions { key, label });
+ view! { cx, class=class_name,
+
+ { children(cx) }
+
+ }
+}
diff --git a/src/tabs/tabs.css b/src/tabs/tabs.css
new file mode 100644
index 0000000..59e62ca
--- /dev/null
+++ b/src/tabs/tabs.css
@@ -0,0 +1,20 @@
+.melt-tabs__label-list {
+ position: relative;
+}
+
+.melt-tabs__label {
+ padding: 0 20px;
+ display: inline-block;
+ height: 40px;
+ line-height: 40px;
+ cursor: pointer;
+}
+
+.melt-tabs-label__active {
+ position: absolute;
+ height: 3px;
+ background-color: var(--label-active-background-color);
+ border-radius: 3px;
+ bottom: 0;
+ left: 0;
+}
\ No newline at end of file