use hikari_palette::classes::*;
use tairitsu_style::ClassesBuilder;
use crate::prelude::*;
use crate::theme::use_layout_direction;
#[component]
pub fn Header(
children: Element,
#[props(default = true)] bordered: bool,
#[props(default = false)] show_menu_toggle: bool,
on_menu_toggle: Option<EventHandler<MouseEvent>>,
#[props(default)] rtl: Option<bool>,
#[props(default)] class: String,
#[props(default)] right_content: Option<Element>,
) -> Element {
let layout_direction = use_layout_direction();
let is_rtl = rtl.unwrap_or_else(|| layout_direction.is_rtl());
let content_classes = ClassesBuilder::new()
.add_typed(Display::Flex)
.add_typed(AlignItems::Center)
.add_typed(Gap::Gap3)
.add_typed(MinWidth::MinW0)
.add_typed(Flex::Shrink0)
.build();
let header_builder = ClassesBuilder::new()
.add_typed(components::Header::Header)
.add_typed(components::Header::Sticky)
.add_typed(components::Header::Md)
.add_typed_if(components::Header::Transparent, !bordered)
.add_typed_if(components::Header::Rtl, is_rtl)
.add(&class);
let header_classes = header_builder.build();
let (left_class, right_class) = if is_rtl {
("hi-header-right", "hi-header-left")
} else {
("hi-header-left", "hi-header-right")
};
rsx! {
header { class: header_classes,
div { class: left_class,
if show_menu_toggle {
button {
class: "hi-header-toggle",
onclick: move |e| {
if let Some(handler) = &on_menu_toggle {
handler.call(e);
}
},
"aria-label": "Toggle menu",
svg {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
view_box: "0 0 24 24",
stroke: "currentColor",
stroke_width: "2",
stroke_linecap: "round",
stroke_linejoin: "round",
path { d: "M4 6h16M4 12h16M4 18h16" }
}
}
}
div { class: content_classes, {children} }
}
if let Some(right) = right_content {
div { class: right_class, {right} }
}
}
}
}
pub struct HeaderComponent;
impl crate::styled::StyledComponent for HeaderComponent {
fn styles() -> &'static str {
r#"
.hi-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
height: 64px;
min-height: 64px;
padding: 0 1rem;
margin: 0;
border-radius: 0;
background: var(--hi-surface);
backdrop-filter: blur(4px);
border-bottom: 1px solid var(--hi-border);
box-shadow: 0 1px 3px var(--hi-black-10, rgba(0, 0, 0, 0.05));
position: relative;
}
.hi-header-sticky {
position: sticky;
top: 0;
z-index: 100;
}
.hi-header-transparent {
background: transparent;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
box-shadow: none;
border-bottom: 1px solid transparent;
}
.hi-header-left {
display: flex;
align-items: center;
gap: 1rem;
flex: 0 1 auto;
min-width: 0;
}
.hi-header-right {
display: flex;
align-items: center;
gap: 0.75rem;
flex: 1;
justify-content: flex-end;
}
.hi-header-toggle {
display: none;
align-items: center;
justify-content: center;
}
@media (max-width: 768px) {
.hi-header-toggle {
display: inline-flex;
}
.hi-header {
padding: 0 0.75rem;
}
}
@media (min-width: 768px) {
.hi-header {
padding: 0 1rem;
}
}
@media (min-width: 1024px) {
.hi-header {
padding: 0 1rem;
}
}
"#
}
fn name() -> &'static str {
"header"
}
}