* [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements
@ 2026-08-10 14:34 Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit-assets 1/4] navigation rail: style the expand button Dominik Csapak
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Dominik Csapak @ 2026-08-10 14:34 UTC (permalink / raw)
To: yew-devel
Move the automatic expand/collapse logic to the navigation rail
and add an (opt-in) button there too for activating it manually.
Also add a pass-through option for the rail group alignment there.
Possible future work:
* Add proper animations
* make 'leading' element know about the expanded/collapsed state
(e.g. so a fab button can render its label correctly)
* possibly make the group-alignment start by default, like it's described
in material design.
proxmox-yew-widget-toolkit-assets:
Dominik Csapak (1):
navigation rail: style the expand button
scss/_navigation_rail.scss | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
proxmox-yew-widget-toolkit:
Dominik Csapak (3):
touch: navigation rail: move auto layout from AdaptiveScaffold
touch: navigation rail: add an optional expand button
touch: adaptive scaffold: pass the rail group alignment through
src/touch/adaptive_scaffold.rs | 67 ++++++++----------
src/touch/navigation_rail.rs | 126 +++++++++++++++++++++++++++++++--
2 files changed, 150 insertions(+), 43 deletions(-)
Summary over all repositories:
3 files changed, 167 insertions(+), 43 deletions(-)
--
Generated by murpp 0.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH yew-widget-toolkit-assets 1/4] navigation rail: style the expand button
2026-08-10 14:34 [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements Dominik Csapak
@ 2026-08-10 14:34 ` Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 2/4] touch: navigation rail: move auto layout from AdaptiveScaffold Dominik Csapak
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2026-08-10 14:34 UTC (permalink / raw)
To: yew-devel
Style the optional expand button the widget toolkit's NavigationRail
renders at the top of the rail. The action icon defaults to the accent
color, which would compete with the selected item, so draw it in the
rail's own foreground color instead. Following Material, the expanded
variant aligns it at the inline start, lined up with the item icons.
Also remove the background circle color that stems from the ActionIcon.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
scss/_navigation_rail.scss | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/scss/_navigation_rail.scss b/scss/_navigation_rail.scss
index 588fab7..9bb664a 100644
--- a/scss/_navigation_rail.scss
+++ b/scss/_navigation_rail.scss
@@ -17,6 +17,16 @@
@include elevation-background-color($level: 0);
+ .pwt-navigation-rail-expand-button {
+ .pwt-action-icon {
+ // the accent color is reserved for the selected item
+ color: var(--pwt-color-on-surface);
+
+ // hide the background for the action icon
+ @include state-layer($base: transparent, $color: transparent);
+ }
+ }
+
.pwt-navigation-rail-tabs {
display: flex;
flex-direction: column;
@@ -99,6 +109,13 @@
min-width: 220px;
max-width: 360px;
+ // the expanded rail lines its content up at the inline start, the margin matches the item
+ // padding so the button keeps sitting above the item icons
+ .pwt-navigation-rail-expand-button {
+ align-self: flex-start;
+ margin-inline-start: var(--pwt-spacer-2);
+ }
+
.pwt-navigation-rail-tabs {
align-self: stretch;
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH yew-widget-toolkit 2/4] touch: navigation rail: move auto layout from AdaptiveScaffold
2026-08-10 14:34 [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit-assets 1/4] navigation rail: style the expand button Dominik Csapak
@ 2026-08-10 14:34 ` Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 3/4] touch: navigation rail: add an optional expand button Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 4/4] touch: adaptive scaffold: pass the rail group alignment through Dominik Csapak
3 siblings, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2026-08-10 14:34 UTC (permalink / raw)
To: yew-devel
The rail knows best when its own layout has to change, so let it
subscribe to the breakpoint itself instead of having every parent
compute the flag. This way the expanded variant also works when the
rail is used directly, e.g. in a plain Scaffold, and the new
`expanded` override allows pinning one of the two variants.
The AdaptiveScaffold keeps a pass-through for the breakpoint, but
loses its second media query. Its large query no longer implies the
rail layout on its own, the wide query alone decides between rail and
bottom bar now. This is OK since the wide query was true when the large
query triggered.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/touch/adaptive_scaffold.rs | 48 ++++++----------------
src/touch/navigation_rail.rs | 73 +++++++++++++++++++++++++++++++---
2 files changed, 79 insertions(+), 42 deletions(-)
diff --git a/src/touch/adaptive_scaffold.rs b/src/touch/adaptive_scaffold.rs
index 3ef6527..db378e9 100644
--- a/src/touch/adaptive_scaffold.rs
+++ b/src/touch/adaptive_scaffold.rs
@@ -18,17 +18,13 @@ use super::{NavigationBar, NavigationRail, Scaffold};
/// matches the value PMG, PVE and PBS dashboards use to decide between rail and bar layouts.
const DEFAULT_WIDE_QUERY: &str = "(min-width: 768px)";
-/// Default media query selecting the large layout. Mirrors Material Design's large breakpoint,
-/// where the expanded navigation rail is the recommended navigator.
-const DEFAULT_LARGE_QUERY: &str = "(min-width: 1200px)";
-
/// Material-style scaffold that adapts its primary navigator to the viewport width.
///
/// Below the configured wide viewport breakpoint a [Scaffold] with a bottom [NavigationBar] is
/// rendered (the touch-first layout used on phones and narrow windows). Above it the layout
/// becomes a [NavigationRail] anchored to the inline-start side, with the application bar and body
-/// to its right. Above the additional large breakpoint the rail switches to its expanded variant,
-/// which places icon and label side by side and widens each item into a full-width pill.
+/// to its right. The rail switches to its expanded variant on its own once the viewport gets large
+/// enough, see [NavigationRail::expanded_query].
///
/// Both navigators are populated from the same [TabBarItem] list and share the same selection /
/// router wiring, so a single declaration drives both layouts. The active layout swaps at runtime
@@ -96,12 +92,12 @@ pub struct AdaptiveScaffold {
#[prop_or(AttrValue::Static(DEFAULT_WIDE_QUERY))]
pub wide_query: AttrValue,
- /// CSS media query that selects the large layout, which renders
- /// the [NavigationRail] in its expanded (wide) variant. Defaults
- /// to `(min-width: 1200px)`.
+ /// CSS media query that selects the rail's expanded (wide) variant
+ /// (rail layout only, see [NavigationRail::expanded_query]).
+ /// Unset keeps the rail's own default.
#[builder(IntoPropValue, into_prop_value)]
- #[prop_or(AttrValue::Static(DEFAULT_LARGE_QUERY))]
- pub large_query: AttrValue,
+ #[prop_or_default]
+ pub rail_expanded_query: Option<AttrValue>,
/// Selection forwarded to the active navigator.
#[builder(IntoPropValue, into_prop_value)]
@@ -169,15 +165,12 @@ impl AdaptiveScaffold {
#[doc(hidden)]
pub enum Msg {
WideChanged(bool),
- LargeChanged(bool),
}
#[doc(hidden)]
pub struct PwtAdaptiveScaffold {
is_wide: bool,
- is_large: bool,
wide_query: Option<ViewportQuery>,
- large_query: Option<ViewportQuery>,
}
impl PwtAdaptiveScaffold {
@@ -186,6 +179,9 @@ impl PwtAdaptiveScaffold {
if let Some(leading) = &props.rail_leading {
rail = rail.leading(leading.clone());
}
+ if let Some(expanded_query) = &props.rail_expanded_query {
+ rail = rail.expanded_query(expanded_query.clone());
+ }
if let Some(default_active) = &props.default_active {
rail = rail.default_active(default_active.clone());
}
@@ -222,16 +218,10 @@ impl Component for PwtAdaptiveScaffold {
ctx.props().wide_query.as_str(),
ctx.link().callback(Msg::WideChanged),
);
- let (is_large, large_query) = ViewportQuery::subscribe(
- ctx.props().large_query.as_str(),
- ctx.link().callback(Msg::LargeChanged),
- );
Self {
is_wide,
- is_large,
wide_query,
- large_query,
}
}
@@ -244,13 +234,6 @@ impl Component for PwtAdaptiveScaffold {
self.is_wide = matches;
true
}
- Msg::LargeChanged(matches) => {
- if self.is_large == matches {
- return false;
- }
- self.is_large = matches;
- true
- }
}
}
@@ -261,12 +244,6 @@ impl Component for PwtAdaptiveScaffold {
ctx.link().callback(Msg::WideChanged),
);
}
- if ctx.props().large_query != old_props.large_query {
- (self.is_large, self.large_query) = ViewportQuery::subscribe(
- ctx.props().large_query.as_str(),
- ctx.link().callback(Msg::LargeChanged),
- );
- }
true
}
@@ -285,9 +262,8 @@ impl Component for PwtAdaptiveScaffold {
}
// Only the navigator slot differs; the rail versus bar switch lives in Scaffold itself.
- // A matching large query implies the rail layout even if the wide query is disjoint.
- scaffold = if self.is_wide || self.is_large {
- scaffold.navigation_rail(Self::build_rail(props).expanded(self.is_large))
+ scaffold = if self.is_wide {
+ scaffold.navigation_rail(Self::build_rail(props))
} else {
scaffold.navigation_bar(Self::build_bar(props))
};
diff --git a/src/touch/navigation_rail.rs b/src/touch/navigation_rail.rs
index 090d5a2..7cbc494 100644
--- a/src/touch/navigation_rail.rs
+++ b/src/touch/navigation_rail.rs
@@ -6,6 +6,7 @@ use yew::prelude::*;
use yew::virtual_dom::{Key, VComp, VNode};
use crate::css::JustifyContent;
+use crate::dom::ViewportQuery;
use crate::prelude::*;
use crate::props::{ContainerBuilder, EventSubscriber, WidgetBuilder};
use crate::state::{NavigationContext, NavigationContextExt, Selection};
@@ -15,6 +16,10 @@ use crate::widget::TabBarItem;
use pwt_macros::builder;
+/// Default media query selecting the expanded layout. Mirrors Material Design's large breakpoint,
+/// where the expanded navigation rail is the recommended navigator.
+const DEFAULT_EXPANDED_QUERY: &str = "(min-width: 1200px)";
+
/// Navigation rail
///
/// # Automatic routing.
@@ -22,6 +27,13 @@ use pwt_macros::builder;
/// [NavigationRail] supports fully automatic routing if you put the rail inside
/// a [NavigationContainer](crate::state::NavigationContainer) and
/// set the router flag.
+///
+/// # Collapsed and expanded layout.
+///
+/// The rail renders collapsed (icon above label) on smaller viewports and expanded (icon and label
+/// side by side, each item a full-width pill) as soon as
+/// [expanded_query](Self::expanded_query) matches. Set [expanded](Self::expanded) to pin one of the
+/// two variants instead.
// Note: This is Similatr to TabBar without keyboard support.
#[derive(Properties, Clone, PartialEq)]
@@ -39,11 +51,20 @@ pub struct NavigationRail {
#[prop_or(JustifyContent::Center)]
pub group_alignment: JustifyContent,
- /// Render the expanded (wide) rail variant with icon and label side by side, matching
- /// Material Design's expanded navigation rail for large viewports.
- #[builder]
+ /// Pin the layout variant instead of selecting it by viewport width.
+ ///
+ /// `Some(true)` always renders the expanded (wide) variant with icon and label side by side,
+ /// `Some(false)` always the collapsed one. `None` (the default) follows
+ /// [expanded_query](Self::expanded_query).
+ #[builder(IntoPropValue, into_prop_value)]
#[prop_or_default]
- pub expanded: bool,
+ pub expanded: Option<bool>,
+
+ /// CSS media query that selects the expanded (wide) variant. Defaults to
+ /// `(min-width: 1200px)`, Material Design's large breakpoint.
+ #[builder(IntoPropValue, into_prop_value)]
+ #[prop_or(AttrValue::Static(DEFAULT_EXPANDED_QUERY))]
+ pub expanded_query: AttrValue,
/// Navigation bar items.
items: Vec<TabBarItem>,
@@ -129,12 +150,18 @@ impl NavigationRail {
pub enum Msg {
Select(Option<Key>, bool),
SelectionChange(Selection),
+ ExpandedQueryChange(bool),
}
#[doc(hidden)]
pub struct PwtNavigationRail {
active: Option<Key>,
selection: Selection,
+ expanded: bool,
+ /// Last known match state of `expanded_query`, so a changing `expanded` property can fall back
+ /// to the automatic layout.
+ query_matches: bool,
+ expanded_query: Option<ViewportQuery>,
_nav_ctx_handle: Option<ContextHandle<NavigationContext>>,
}
@@ -167,6 +194,14 @@ impl PwtNavigationRail {
selection
}
+
+ fn set_expanded(&mut self, expanded: bool) -> bool {
+ if self.expanded == expanded {
+ return false;
+ }
+ self.expanded = expanded;
+ true
+ }
}
impl Component for PwtNavigationRail {
@@ -205,9 +240,17 @@ impl Component for PwtNavigationRail {
on_select.emit(active.clone());
}
+ let (query_matches, expanded_query) = ViewportQuery::subscribe(
+ props.expanded_query.as_str(),
+ ctx.link().callback(Msg::ExpandedQueryChange),
+ );
+
Self {
selection,
active,
+ expanded: props.expanded.unwrap_or(query_matches),
+ query_matches,
+ expanded_query,
_nav_ctx_handle,
}
}
@@ -266,6 +309,14 @@ impl Component for PwtNavigationRail {
true
}
+ Msg::ExpandedQueryChange(matches) => {
+ self.query_matches = matches;
+ // an explicitly pinned layout ignores the viewport
+ match props.expanded {
+ Some(_) => false,
+ None => self.set_expanded(matches),
+ }
+ }
}
}
@@ -274,6 +325,16 @@ impl Component for PwtNavigationRail {
if props.selection != old_props.selection {
self.selection = Self::init_selection(ctx, props.selection.clone(), &self.active);
}
+ let query_changed = props.expanded_query != old_props.expanded_query;
+ if query_changed {
+ (self.query_matches, self.expanded_query) = ViewportQuery::subscribe(
+ props.expanded_query.as_str(),
+ ctx.link().callback(Msg::ExpandedQueryChange),
+ );
+ }
+ if query_changed || props.expanded != old_props.expanded {
+ self.set_expanded(props.expanded.unwrap_or(self.query_matches));
+ }
true
}
@@ -311,7 +372,7 @@ impl Component for PwtNavigationRail {
);
// the collapsed rail anchors the badge to the icon corner, the expanded
// variant places it after the label instead
- let corner_badge = if props.expanded { None } else { badge.take() };
+ let corner_badge = if self.expanded { None } else { badge.take() };
Some(html! {<div {class}><i class={icon_class}/>{corner_badge}</div>})
}
None => None,
@@ -343,7 +404,7 @@ impl Component for PwtNavigationRail {
Container::new()
.class("pwt-navigation-rail")
- .class(props.expanded.then_some("pwt-navigation-rail-expanded"))
+ .class(self.expanded.then_some("pwt-navigation-rail-expanded"))
.with_optional_child(props.leading.clone())
.with_child(
Container::new()
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH yew-widget-toolkit 3/4] touch: navigation rail: add an optional expand button
2026-08-10 14:34 [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit-assets 1/4] navigation rail: style the expand button Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 2/4] touch: navigation rail: move auto layout from AdaptiveScaffold Dominik Csapak
@ 2026-08-10 14:34 ` Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 4/4] touch: adaptive scaffold: pass the rail group alignment through Dominik Csapak
3 siblings, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2026-08-10 14:34 UTC (permalink / raw)
To: yew-devel
Material Design's expressive navigation rail offers a menu button that
switches between the collapsed and the expanded layout, so users can
keep the labels visible on a medium window or reclaim the space on a
large one. The button is opt-in, existing rails keep following the
viewport alone.
Add a passthrough for AdaptiveScaffold too.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/touch/adaptive_scaffold.rs | 9 ++++-
src/touch/navigation_rail.rs | 60 +++++++++++++++++++++++++++++++---
2 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/src/touch/adaptive_scaffold.rs b/src/touch/adaptive_scaffold.rs
index db378e9..d70b1d8 100644
--- a/src/touch/adaptive_scaffold.rs
+++ b/src/touch/adaptive_scaffold.rs
@@ -99,6 +99,12 @@ pub struct AdaptiveScaffold {
#[prop_or_default]
pub rail_expanded_query: Option<AttrValue>,
+ /// Let users switch the rail between its collapsed and expanded
+ /// layout (rail layout only, see [NavigationRail::expand_button]).
+ #[builder]
+ #[prop_or_default]
+ pub rail_expand_button: bool,
+
/// Selection forwarded to the active navigator.
#[builder(IntoPropValue, into_prop_value)]
#[prop_or_default]
@@ -191,7 +197,8 @@ impl PwtAdaptiveScaffold {
if let Some(on_select) = &props.on_select {
rail = rail.on_select(on_select.clone());
}
- rail.router(props.router)
+ rail.expand_button(props.rail_expand_button)
+ .router(props.router)
}
fn build_bar(props: &AdaptiveScaffold) -> NavigationBar {
diff --git a/src/touch/navigation_rail.rs b/src/touch/navigation_rail.rs
index 7cbc494..05c5a01 100644
--- a/src/touch/navigation_rail.rs
+++ b/src/touch/navigation_rail.rs
@@ -10,7 +10,8 @@ use crate::dom::ViewportQuery;
use crate::prelude::*;
use crate::props::{ContainerBuilder, EventSubscriber, WidgetBuilder};
use crate::state::{NavigationContext, NavigationContextExt, Selection};
-use crate::widget::Container;
+use crate::tr;
+use crate::widget::{ActionIcon, Container};
use crate::widget::TabBarItem;
@@ -20,6 +21,12 @@ use pwt_macros::builder;
/// where the expanded navigation rail is the recommended navigator.
const DEFAULT_EXPANDED_QUERY: &str = "(min-width: 1200px)";
+/// Icon of the expand button in the collapsed layout, Material Design's menu icon.
+const EXPAND_ICON: &str = "fa fa-bars";
+
+/// Icon of the expand button in the expanded layout, Material Design's menu-open icon.
+const COLLAPSE_ICON: &str = "fa fa-outdent";
+
/// Navigation rail
///
/// # Automatic routing.
@@ -34,6 +41,9 @@ const DEFAULT_EXPANDED_QUERY: &str = "(min-width: 1200px)";
/// side by side, each item a full-width pill) as soon as
/// [expanded_query](Self::expanded_query) matches. Set [expanded](Self::expanded) to pin one of the
/// two variants instead.
+///
+/// Setting [expand_button](Self::expand_button) additionally lets users switch between the two
+/// layouts themselves.
// Note: This is Similatr to TabBar without keyboard support.
#[derive(Properties, Clone, PartialEq)]
@@ -66,6 +76,22 @@ pub struct NavigationRail {
#[prop_or(AttrValue::Static(DEFAULT_EXPANDED_QUERY))]
pub expanded_query: AttrValue,
+ /// Show a button at the top of the rail that toggles between the collapsed and the expanded
+ /// layout.
+ ///
+ /// A manual toggle stays in effect until the layout gets selected anew, either by the viewport
+ /// crossing [expanded_query](Self::expanded_query) or by a changed
+ /// [expanded](Self::expanded) property.
+ #[builder]
+ #[prop_or_default]
+ pub expand_button: bool,
+
+ /// Callback emitted whenever the layout switches between collapsed and expanded, with `true`
+ /// meaning expanded.
+ #[builder_cb(IntoEventCallback, into_event_callback, bool)]
+ #[prop_or_default]
+ pub on_expand_change: Option<Callback<bool>>,
+
/// Navigation bar items.
items: Vec<TabBarItem>,
@@ -151,6 +177,7 @@ pub enum Msg {
Select(Option<Key>, bool),
SelectionChange(Selection),
ExpandedQueryChange(bool),
+ ToggleExpanded,
}
#[doc(hidden)]
@@ -195,11 +222,16 @@ impl PwtNavigationRail {
selection
}
- fn set_expanded(&mut self, expanded: bool) -> bool {
+ fn set_expanded(&mut self, props: &NavigationRail, expanded: bool) -> bool {
if self.expanded == expanded {
return false;
}
self.expanded = expanded;
+
+ if let Some(on_expand_change) = &props.on_expand_change {
+ on_expand_change.emit(expanded);
+ }
+
true
}
}
@@ -314,9 +346,10 @@ impl Component for PwtNavigationRail {
// an explicitly pinned layout ignores the viewport
match props.expanded {
Some(_) => false,
- None => self.set_expanded(matches),
+ None => self.set_expanded(props, matches),
}
}
+ Msg::ToggleExpanded => self.set_expanded(props, !self.expanded),
}
}
@@ -333,7 +366,7 @@ impl Component for PwtNavigationRail {
);
}
if query_changed || props.expanded != old_props.expanded {
- self.set_expanded(props.expanded.unwrap_or(self.query_matches));
+ self.set_expanded(props, props.expanded.unwrap_or(self.query_matches));
}
true
}
@@ -402,9 +435,28 @@ impl Component for PwtNavigationRail {
.into()
});
+ let expand_button = props.expand_button.then(|| {
+ let (icon_class, aria_label) = match self.expanded {
+ true => (COLLAPSE_ICON, tr!("Collapse the navigation rail")),
+ false => (EXPAND_ICON, tr!("Expand the navigation rail")),
+ };
+
+ // the container gives the button the same icon column as the items, so both line up
+ Container::new()
+ .class("pwt-navigation-rail-expand-button")
+ .with_child(
+ ActionIcon::new(icon_class)
+ .tabindex(0)
+ .aria_label(aria_label)
+ .attribute("aria-expanded", self.expanded.to_string())
+ .on_activate(ctx.link().callback(|_| Msg::ToggleExpanded)),
+ )
+ });
+
Container::new()
.class("pwt-navigation-rail")
.class(self.expanded.then_some("pwt-navigation-rail-expanded"))
+ .with_optional_child(expand_button)
.with_optional_child(props.leading.clone())
.with_child(
Container::new()
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH yew-widget-toolkit 4/4] touch: adaptive scaffold: pass the rail group alignment through
2026-08-10 14:34 [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements Dominik Csapak
` (2 preceding siblings ...)
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 3/4] touch: navigation rail: add an optional expand button Dominik Csapak
@ 2026-08-10 14:34 ` Dominik Csapak
3 siblings, 0 replies; 5+ messages in thread
From: Dominik Csapak @ 2026-08-10 14:34 UTC (permalink / raw)
To: yew-devel
The rail's group alignment is as much a layout choice as its leading
widget or its expand button, so forward it here too instead of making
callers drop down to a plain Scaffold just for that.
Also add the doc comment the property was missing on the rail itself.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/touch/adaptive_scaffold.rs | 10 ++++++++++
src/touch/navigation_rail.rs | 1 +
2 files changed, 11 insertions(+)
diff --git a/src/touch/adaptive_scaffold.rs b/src/touch/adaptive_scaffold.rs
index d70b1d8..a85328c 100644
--- a/src/touch/adaptive_scaffold.rs
+++ b/src/touch/adaptive_scaffold.rs
@@ -6,6 +6,7 @@ use yew::virtual_dom::{Key, VComp, VNode};
use pwt_macros::builder;
+use crate::css::JustifyContent;
use crate::dom::ViewportQuery;
use crate::prelude::*;
use crate::props::IntoOptionalKey;
@@ -105,6 +106,12 @@ pub struct AdaptiveScaffold {
#[prop_or_default]
pub rail_expand_button: bool,
+ /// Determines the navigation group alignment (rail layout only, see
+ /// [NavigationRail::group_alignment]).
+ #[builder(IntoPropValue, into_prop_value)]
+ #[prop_or_default]
+ pub rail_group_alignment: Option<JustifyContent>,
+
/// Selection forwarded to the active navigator.
#[builder(IntoPropValue, into_prop_value)]
#[prop_or_default]
@@ -188,6 +195,9 @@ impl PwtAdaptiveScaffold {
if let Some(expanded_query) = &props.rail_expanded_query {
rail = rail.expanded_query(expanded_query.clone());
}
+ if let Some(group_alignment) = &props.rail_group_alignment {
+ rail = rail.group_alignment(*group_alignment);
+ }
if let Some(default_active) = &props.default_active {
rail = rail.default_active(default_active.clone());
}
diff --git a/src/touch/navigation_rail.rs b/src/touch/navigation_rail.rs
index 05c5a01..fccc619 100644
--- a/src/touch/navigation_rail.rs
+++ b/src/touch/navigation_rail.rs
@@ -57,6 +57,7 @@ pub struct NavigationRail {
#[prop_or_default]
pub leading: Option<Html>,
+ /// Determines the alignment of the navigation group.
#[builder]
#[prop_or(JustifyContent::Center)]
pub group_alignment: JustifyContent,
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-10 14:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 14:34 [PATCH yew-widget-toolkit/yew-widget-toolkit-assets 0/4] adaptive scaffold/navigation rail improvements Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit-assets 1/4] navigation rail: style the expand button Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 2/4] touch: navigation rail: move auto layout from AdaptiveScaffold Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 3/4] touch: navigation rail: add an optional expand button Dominik Csapak
2026-08-10 14:34 ` [PATCH yew-widget-toolkit 4/4] touch: adaptive scaffold: pass the rail group alignment through Dominik Csapak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox