From e22dba5bed7212879f56683a06eb1c3b11cda8f7 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 29 Oct 2022 10:15:22 -0400 Subject: [PATCH] Poor mans tab functionality --- web/src/components/tabs.rs | 49 +++++++++++++++++++++++++------------ web/src/pages/categories.rs | 3 ++- web/src/pages/cook.rs | 1 + web/src/pages/inventory.rs | 1 + web/src/pages/login.rs | 3 ++- web/src/pages/plan.rs | 1 + web/src/pages/recipe.rs | 3 ++- web/src/web.rs | 2 +- web/static/app.css | 35 +++++++++++++++++++++----- 9 files changed, 72 insertions(+), 26 deletions(-) diff --git a/web/src/components/tabs.rs b/web/src/components/tabs.rs index c67f723..8406c0d 100644 --- a/web/src/components/tabs.rs +++ b/web/src/components/tabs.rs @@ -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 { pub inner: View, + pub selected: Option, } #[component] pub fn TabbedView(cx: Scope, state: TabState) -> View { + 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) } } } diff --git a/web/src/pages/categories.rs b/web/src/pages/categories.rs index 627e6e6..d69bc83 100644 --- a/web/src/pages/categories.rs +++ b/web/src/pages/categories.rs @@ -24,7 +24,8 @@ pub fn CategoryPage(cx: Scope) -> View { TabbedView(TabState { inner: view! {cx, Categories { } - } + }, + selected: Some("Categories".to_owned()), }) } } diff --git a/web/src/pages/cook.rs b/web/src/pages/cook.rs index 4da3de8..183ab34 100644 --- a/web/src/pages/cook.rs +++ b/web/src/pages/cook.rs @@ -22,6 +22,7 @@ pub fn CookPage(cx: Scope) -> View { inner: view! {cx, RecipeList { } }, + selected: Some("Cook".to_owned()), }) } } diff --git a/web/src/pages/inventory.rs b/web/src/pages/inventory.rs index 454e83d..ff3b881 100644 --- a/web/src/pages/inventory.rs +++ b/web/src/pages/inventory.rs @@ -22,6 +22,7 @@ pub fn InventoryPage(cx: Scope) -> View { inner: view! {cx, ShoppingList {} }, + selected: Some("Inventory".to_owned()), }) } } diff --git a/web/src/pages/login.rs b/web/src/pages/login.rs index c9f392b..fd7a400 100644 --- a/web/src/pages/login.rs +++ b/web/src/pages/login.rs @@ -81,7 +81,8 @@ pub fn LoginForm(cx: Scope) -> View { pub fn LoginPage(cx: Scope) -> View { view! {cx, TabbedView(TabState { - inner: view! {cx, LoginForm { } } + inner: view! {cx, LoginForm { } }, + selected: None, }) } } diff --git a/web/src/pages/plan.rs b/web/src/pages/plan.rs index 7e842d2..a486d9e 100644 --- a/web/src/pages/plan.rs +++ b/web/src/pages/plan.rs @@ -22,6 +22,7 @@ pub fn PlanPage(cx: Scope) -> View { inner: view! {cx, RecipeSelector() }, + selected: Some("Plan".to_owned()), }) } } diff --git a/web/src/pages/recipe.rs b/web/src/pages/recipe.rs index 1a35808..55d7bd4 100644 --- a/web/src/pages/recipe.rs +++ b/web/src/pages/recipe.rs @@ -28,7 +28,8 @@ pub fn RecipePage(cx: Scope, props: RecipePageProps) -> View { TabbedView(TabState { inner: view! {cx, Recipe(props.recipe) - } + }, + selected: None, }) } } diff --git a/web/src/web.rs b/web/src/web.rs index 773969c..f103356 100644 --- a/web/src/web.rs +++ b/web/src/web.rs @@ -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::*}; diff --git a/web/static/app.css b/web/static/app.css index d3d0e2e..1604adb 100644 --- a/web/static/app.css +++ b/web/static/app.css @@ -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; } \ No newline at end of file