Poor mans tab functionality

This commit is contained in:
Jeremy Wall 2022-10-29 10:15:22 -04:00
parent 40b6625620
commit e22dba5bed
9 changed files with 72 additions and 26 deletions

View File

@ -12,36 +12,53 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use sycamore::prelude::*;
use tracing::debug;
use super::Header;
#[derive(Clone, Prop)]
pub struct TabState<G: GenericNode> {
pub inner: View<G>,
pub selected: Option<String>,
}
#[component]
pub fn TabbedView<G: Html>(cx: Scope, state: TabState<G>) -> View<G> {
let tablist = create_signal(
cx,
vec![
("/ui/plan", "Plan"),
("/ui/inventory", "Inventory"),
("/ui/cook", "Cook"),
("/ui/categories", "Categories"),
],
);
let TabState { inner, selected } = state;
view! {cx,
Header { }
nav {
ul {
li { a(href="/ui/plan", class="no-print") { "Plan" } " > "
nav {
ul(class="tabs") {
Indexed(
iterable=tablist,
view=move |cx, (href, show)| {
debug!(?selected, show, "identifying tab");
let class = if selected.as_ref().map_or(false, |selected| selected == show) {
"no-print selected"
} else {
"no-print"
};
view! {cx,
li(class=class) { a(href=href) { (show) } }
}
}
li { a(href="/ui/inventory", class="no-print") { "Inventory" } " > "
}
li { a(href="/ui/cook", class="no-print") { "Cook" }
} " | "
li { a(href="/ui/categories", class="no-print") { "Categories" }
}
}
ul {
li { a(href="/ui/login") { "Login" } " | " }
li { a(href="https://github.com/zaphar/kitchen") { "Github" } }
}
)
}
ul {
li { a(href="/ui/login") { "Login" } " | " }
li { a(href="https://github.com/zaphar/kitchen") { "Github" } }
}
}
main(class=".conatiner-fluid") {
(state.inner)
(inner)
}
}
}

View File

@ -24,7 +24,8 @@ pub fn CategoryPage<G: Html>(cx: Scope) -> View<G> {
TabbedView(TabState {
inner: view! {cx,
Categories { }
}
},
selected: Some("Categories".to_owned()),
})
}
}

View File

@ -22,6 +22,7 @@ pub fn CookPage<G: Html>(cx: Scope) -> View<G> {
inner: view! {cx,
RecipeList { }
},
selected: Some("Cook".to_owned()),
})
}
}

View File

@ -22,6 +22,7 @@ pub fn InventoryPage<G: Html>(cx: Scope) -> View<G> {
inner: view! {cx,
ShoppingList {}
},
selected: Some("Inventory".to_owned()),
})
}
}

View File

@ -81,7 +81,8 @@ pub fn LoginForm<G: Html>(cx: Scope) -> View<G> {
pub fn LoginPage<G: Html>(cx: Scope) -> View<G> {
view! {cx,
TabbedView(TabState {
inner: view! {cx, LoginForm { } }
inner: view! {cx, LoginForm { } },
selected: None,
})
}
}

View File

@ -22,6 +22,7 @@ pub fn PlanPage<G: Html>(cx: Scope) -> View<G> {
inner: view! {cx,
RecipeSelector()
},
selected: Some("Plan".to_owned()),
})
}
}

View File

@ -28,7 +28,8 @@ pub fn RecipePage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
TabbedView(TabState {
inner: view! {cx,
Recipe(props.recipe)
}
},
selected: None,
})
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pages::*;
use crate::{api, app_state::*, components::*, router_integration::*};
use crate::{api, app_state::*, router_integration::*};
use tracing::{error, info, instrument};
use sycamore::{futures::spawn_local_scoped, prelude::*};

View File

@ -25,12 +25,6 @@
}
}
/*
:not(thead):not(tfoot) > * > td {
--font-size: 1.5rem;
}
*/
@media (min-width: 768px) {
:root {
--font-size: 35px;
@ -43,4 +37,33 @@
body {
padding: 8px;
}
:root {
--tab-border-color: black;
--tab-border-width: 3px;
--tab-border-style: solid;
--tab-border-radius: 15px;
}
@media (prefers-color-scheme: dark) {
:root {
--tab-border-color: lightgrey;
}
}
nav>ul.tabs>li {
border-style: none;
border-bottom-style: var(--tab-border-style);
border-bottom-color: var(--tab-border-color);
border-bottom-width: var(--tab-border-width);
}
nav>ul.tabs>li.selected {
border-style: var(--tab-border-style);
border-color: var(--tab-border-color);
border-width: var(--tab-border-width);
border-top-left-radius: var(--tab-border-radius);
border-top-right-radius: var(--tab-border-radius);
border-bottom-style: none;
}