///|
/// Render Yami-kumo's semantic application shell. Optional slots are omitted
/// when absent; localized aria labels and current drawer state are explicit.
pub fn app_shell(
brand : Html,
main : Html,
navigation_trigger? : Html,
global_search? : Html,
header_actions? : Html,
account_menu? : Html,
rail? : Html,
sidebar? : Html,
tabs? : Html,
context_panel? : Html,
context_panel_label? : String = "Context panel",
bottom_bar? : Html,
sidebar_collapsed? : Bool = false,
mobile_sidebar_open? : Bool = false,
context_panel_open? : Bool = false,
primary_navigation_label? : String = "Primary",
workspace_navigation_label? : String = "Workspace navigation",
close_workspace_navigation_label? : String = "Close workspace navigation",
close_context_panel_label? : String = "Close Context panel",
) -> Html {
let brand_group_children : Array[Html] = []
match navigation_trigger {
Some(trigger) =>
brand_group_children.push(
raw_element("div", [text_attribute("class", "yk-navigation-trigger")], [
trigger,
]),
)
None => ()
}
brand_group_children.push(
raw_element("div", [text_attribute("class", "yk-brand")], [brand]),
)
let header_children : Array[Html] = [
raw_element(
"div",
[text_attribute("class", "yk-brand-group")],
brand_group_children,
),
raw_element(
"div",
[text_attribute("class", "yk-global-search")],
optional_children(global_search),
),
]
let header_end_children : Array[Html] = []
match header_actions {
Some(actions) =>
header_end_children.push(
raw_element("div", [text_attribute("class", "yk-header-actions")], [
actions,
]),
)
None => ()
}
match account_menu {
Some(account) =>
header_end_children.push(
raw_element("div", [text_attribute("class", "yk-account-menu")], [
account,
]),
)
None => ()
}
header_children.push(
raw_element(
"div",
[text_attribute("class", "yk-header-end")],
header_end_children,
),
)
let shell_children : Array[Html] = [
raw_element(
"header",
[text_attribute("class", "yk-topbar")],
header_children,
),
]
match rail {
Some(rail_node) =>
shell_children.push(
raw_element(
"nav",
[
text_attribute("class", "yk-rail"),
text_attribute("aria-label", primary_navigation_label),
],
[rail_node],
),
)
None => ()
}
match sidebar {
Some(sidebar_node) => {
shell_children.push(
raw_element(
"button",
[
text_attribute("type", "button"),
text_attribute("class", "yk-drawer-scrim yk-sidebar-scrim"),
text_attribute("aria-label", close_workspace_navigation_label),
],
[],
),
)
shell_children.push(
raw_element(
"aside",
[
text_attribute("id", "yk-mobile-navigation"),
text_attribute("class", "yk-sidebar"),
text_attribute("aria-label", workspace_navigation_label),
],
[sidebar_node],
),
)
}
None => ()
}
let workspace_children : Array[Html] = []
match tabs {
Some(tab_node) =>
workspace_children.push(
raw_element(
"nav",
[
text_attribute("class", "yk-tabs"),
text_attribute("aria-label", "Workspace tabs"),
],
[tab_node],
),
)
None => ()
}
workspace_children.push(
raw_element("main", [text_attribute("class", "yk-main")], [main]),
)
shell_children.push(
raw_element(
"section",
[
text_attribute("class", "yk-workspace"),
text_attribute("data-has-tabs", bool_name(tabs is Some(_))),
],
workspace_children,
),
)
match context_panel {
Some(panel_node) => {
shell_children.push(
raw_element(
"button",
[
text_attribute("type", "button"),
text_attribute("class", "yk-drawer-scrim yk-context-panel-scrim"),
text_attribute("aria-label", close_context_panel_label),
],
[],
),
)
shell_children.push(
raw_element(
"aside",
[
text_attribute("id", "yk-context-panel"),
text_attribute("class", "yk-context-panel"),
text_attribute("aria-label", context_panel_label),
],
[panel_node],
),
)
}
None => ()
}
match bottom_bar {
Some(bar) =>
shell_children.push(
raw_element("footer", [text_attribute("class", "yk-bottom-bar")], [bar]),
)
None => ()
}
raw_element(
"div",
[
text_attribute("class", "yk-shell"),
text_attribute("data-has-rail", bool_name(rail is Some(_))),
text_attribute("data-has-sidebar", bool_name(sidebar is Some(_))),
text_attribute("data-sidebar-collapsed", bool_name(sidebar_collapsed)),
text_attribute("data-mobile-sidebar-open", bool_name(mobile_sidebar_open)),
text_attribute(
"data-has-context-panel",
bool_name(context_panel is Some(_)),
),
text_attribute("data-context-panel-open", bool_name(context_panel_open)),
text_attribute("data-has-bottom-bar", bool_name(bottom_bar is Some(_))),
],
shell_children,
)
}
///|
fn optional_children(node : Html?) -> Array[Html] {
match node {
Some(value) => [value]
None => []
}
}