Newer
Older
},
widgets::{Background, Text},
};
use crate::TabTheme;
#[derive(Clone, PartialEq)]
enum TabHoverState {
None,
Inactive,
Active,
}
/// The actual tab, displayed in a [TabBar](crate::tab_bar::TabBar)
pub fn Tab(context: &mut KayakContext, content: String, selected: bool) {
let theme = context.create_consumer::<TabTheme>().unwrap_or_default();
let (focus_state, set_focus_state, ..) = use_state!(false);
let (hover_state, set_hover_state, ..) = use_state!(TabHoverState::None);
match hover_state {
TabHoverState::Inactive if selected => set_hover_state(TabHoverState::Active),
TabHoverState::Active if !selected => set_hover_state(TabHoverState::Inactive),
_ => {}
};
let event_handler = OnEvent::new(move |_, event| match event.event_type {
if selected {
set_hover_state(TabHoverState::Active);
} else {
set_hover_state(TabHoverState::Inactive);
set_hover_state(TabHoverState::None);
}
EventType::Focus => {
set_focus_state(true);
}
EventType::Blur => {
set_focus_state(false);
}
_ => {}
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
});
let tab_color = match hover_state {
TabHoverState::None if selected => theme.get().active_tab.normal,
TabHoverState::None => theme.get().inactive_tab.normal,
TabHoverState::Inactive => theme.get().inactive_tab.hovered,
TabHoverState::Active => theme.get().active_tab.hovered,
};
let pad_x = Units::Pixels(2.0);
let bg_styles = Style {
background_color: StyleProp::Value(tab_color),
layout_type: StyleProp::Value(LayoutType::Row),
padding_left: StyleProp::Value(pad_x),
padding_right: StyleProp::Value(pad_x),
..Default::default()
};
let border_width = Units::Pixels(2.0);
let border_styles = Style {
background_color: if focus_state {
StyleProp::Value(theme.get().focus)
} else {
StyleProp::Value(tab_color)
},
padding_left: StyleProp::Value(border_width),
padding_right: StyleProp::Value(border_width),
padding_top: StyleProp::Value(border_width),
padding_bottom: StyleProp::Value(border_width),
layout_type: StyleProp::Value(LayoutType::Row),
..Default::default()
};
let text_styles = Style {
background_color: if focus_state {
StyleProp::Value(theme.get().focus)
} else {
StyleProp::Value(tab_color)
},
color: StyleProp::Value(theme.get().text.normal),
top: StyleProp::Value(Units::Stretch(0.1)),
bottom: StyleProp::Value(Units::Stretch(1.0)),
width: StyleProp::Value(Units::Stretch(1.0)),
..Default::default()
};
self.styles = Some(Style {
render_command: StyleProp::Value(RenderCommand::Layout),
height: StyleProp::Value(Units::Pixels(theme.get().tab_height)),
max_width: StyleProp::Value(Units::Pixels(100.0)),
..styles.clone().unwrap_or_default()
});
rsx! {
<Background focusable={Some(true)} on_event={Some(event_handler)} styles={Some(border_styles)}>
<Background styles={Some(bg_styles)}>
<Text content={content} size={12.0} styles={Some(text_styles)} />
</Background>
</Background>
}