From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id EFBDF1FF18C for ; Fri, 27 Jun 2025 14:09:00 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 7601B13814; Fri, 27 Jun 2025 14:09:37 +0200 (CEST) From: Dominik Csapak To: yew-devel@lists.proxmox.com Date: Fri, 27 Jun 2025 14:08:59 +0200 Message-Id: <20250627120859.3723554-18-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250627120859.3723554-1-d.csapak@proxmox.com> References: <20250627120859.3723554-1-d.csapak@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.022 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [yew-devel] [PATCH yew-widget-toolkit 11/11] touch: fab menu: rework fab menu X-BeenThere: yew-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Yew framework devel list at Proxmox List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Yew framework devel list at Proxmox Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: yew-devel-bounces@lists.proxmox.com Sender: "yew-devel" This changes the way the fab menu is structured: * use the new FabMenuEntry for entries instead of full Fab's this way we have better control over the layout and functions * use a different markup so we can use flex-layout (see the necessary and corresponding pwt-assets patch) * remove the left/right direction and center alignment since they're almost never useful, and can be reimplemented if necessary (removal makes the css part easier) * introduce size and color options to better apply the material3 design Signed-off-by: Dominik Csapak --- src/touch/fab_menu.rs | 140 +++++++++++++++++++++++++++++++----------- src/touch/mod.rs | 4 +- 2 files changed, 106 insertions(+), 38 deletions(-) diff --git a/src/touch/fab_menu.rs b/src/touch/fab_menu.rs index 92f2331..6a4f3f7 100644 --- a/src/touch/fab_menu.rs +++ b/src/touch/fab_menu.rs @@ -1,10 +1,12 @@ use yew::prelude::*; +use crate::css::ColorScheme; use crate::props::{ContainerBuilder, EventSubscriber, WidgetBuilder}; -use crate::widget::Container; +use crate::widget::{Button, Container}; use pwt_macros::{builder, widget}; +use super::fab::FabSize; use super::Fab; /// [FabMenu] direction. @@ -12,23 +14,63 @@ use super::Fab; pub enum FabMenuDirection { Up, Down, - Left, - Right, } /// [FabMenu] alignment. #[derive(Copy, Clone, PartialEq)] pub enum FabMenuAlign { Start, - Center, End, } +/// An entry for a [FabMenu] +#[derive(PartialEq, Clone)] +pub struct FabMenuEntry { + pub text: AttrValue, + pub icon: AttrValue, + pub on_activate: Callback, +} + +impl FabMenuEntry { + pub fn new( + text: impl Into, + icon: impl Into, + on_activate: impl Into>, + ) -> Self { + Self { + text: text.into(), + icon: icon.into(), + on_activate: on_activate.into(), + } + } +} + +/// [FabMenu] Color +/// +/// Determines the color of the [Fab] and the [FabMenuEntry]. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub enum FabMenuColor { + #[default] + Primary, + Secondary, + Tertiary, +} + /// Favorite actions button Menu. #[widget(pwt=crate, comp=PwtFabMenu, @element)] #[derive(Properties, Clone, PartialEq)] #[builder] pub struct FabMenu { + /// The size of the [Fab] + #[prop_or_default] + #[builder] + pub size: FabSize, + + /// The color scheme to apply on the [Fab] and the [FabMenuEntry] + #[prop_or_default] + #[builder] + pub color: FabMenuColor, + /// Main button Icon (CSS class). #[prop_or_default] pub main_icon_class: Option, @@ -44,7 +86,7 @@ pub struct FabMenu { /// Menu alignment /// - #[prop_or(FabMenuAlign::Center)] + #[prop_or(FabMenuAlign::End)] #[builder] pub align: FabMenuAlign, @@ -52,7 +94,7 @@ pub struct FabMenu { /// /// We currently support up to 5 children. #[prop_or_default] - pub children: Vec, + pub children: Vec, } impl Default for FabMenu { @@ -94,13 +136,13 @@ impl FabMenu { } /// Builder style method to add a child button - pub fn with_child(mut self, child: impl Into) -> Self { + pub fn with_child(mut self, child: impl Into) -> Self { self.add_child(child); self } /// Method to add a child button - pub fn add_child(&mut self, child: impl Into) { + pub fn add_child(&mut self, child: impl Into) { self.children.push(child.into()); } } @@ -139,26 +181,33 @@ impl Component for PwtFabMenu { fn view(&self, ctx: &Context) -> Html { let props = ctx.props(); - let main_icon_class = match &props.main_icon_class { - Some(class) => class.clone(), - None => classes!("fa", "fa-plus"), + let main_icon_class = match (self.show_items, &props.main_icon_class) { + (false, Some(class)) => class.clone(), + (false, None) => classes!("fa", "fa-plus"), + (true, _) => classes!("fa", "fa-times"), + }; + + let (close_color, color) = match props.color { + FabMenuColor::Primary => (ColorScheme::Primary, ColorScheme::PrimaryContainer), + FabMenuColor::Secondary => (ColorScheme::Secondary, ColorScheme::SecondaryContainer), + FabMenuColor::Tertiary => (ColorScheme::Tertiary, ColorScheme::TertiaryContainer), }; + let main_button = Fab::new(main_icon_class) + .size(if self.show_items { + FabSize::Small + } else { + props.size + }) + .class(props.main_button_class.clone()) + .class(if self.show_items { close_color } else { color }) + .class(self.show_items.then_some("rounded")) + .on_activate(ctx.link().callback(|_| Msg::Toggle)); + let mut container = Container::new() .with_std_props(&props.std_props) .listeners(&props.listeners) .class("pwt-fab-menu-container") - .class(match props.align { - FabMenuAlign::Start => Some("pwt-fab-align-start"), - FabMenuAlign::End => Some("pwt-fab-align-end"), - FabMenuAlign::Center => None, - }) - .class(match props.direction { - FabMenuDirection::Up => "pwt-fab-direction-up", - FabMenuDirection::Down => "pwt-fab-direction-down", - FabMenuDirection::Left => "pwt-fab-direction-left", - FabMenuDirection::Right => "pwt-fab-direction-right", - }) .class(self.show_items.then_some("active")) .onkeydown({ let link = ctx.link().clone(); @@ -169,33 +218,50 @@ impl Component for PwtFabMenu { } }); - let main_button = Fab::new(main_icon_class) - .class(props.main_button_class.clone()) - .on_activate(ctx.link().callback(|_| Msg::Toggle)); - - container.add_child(main_button); - for (i, child) in props.children.iter().enumerate() { if i >= 5 { log::error!("FabMenu only supports 5 child buttons."); break; } - let orig_on_activate = child.on_activate.clone(); + + let on_activate = child.on_activate.clone(); let link = ctx.link().clone(); - let child_button = child - .clone() - .small() + let child = Button::new(child.text.clone()) + .icon_class(child.icon.clone()) + .class("medium") + .class(color) .class("pwt-fab-menu-item") .on_activate(move |event| { link.send_message(Msg::Toggle); - if let Some(on_activate) = &orig_on_activate { - on_activate.emit(event); - } + on_activate.emit(event); }); - container.add_child(child_button); + container.add_child(child); } - container.into() + Container::new() + .with_std_props(&props.std_props) + .listeners(&props.listeners) + .class("pwt-fab-menu-outer") + .class(match props.align { + FabMenuAlign::Start => Some("pwt-fab-align-start"), + FabMenuAlign::End => Some("pwt-fab-align-end"), + }) + .class(match props.direction { + FabMenuDirection::Up => "pwt-fab-direction-up", + FabMenuDirection::Down => "pwt-fab-direction-down", + }) + .with_child( + Container::new() + .class("pwt-fab-menu-main") + .class(match props.size { + FabSize::Small => "small", + FabSize::Standard => "", + FabSize::Large => "large", + }) + .with_child(main_button), + ) + .with_child(container) + .into() } } diff --git a/src/touch/mod.rs b/src/touch/mod.rs index f559689..acb27ae 100644 --- a/src/touch/mod.rs +++ b/src/touch/mod.rs @@ -11,7 +11,9 @@ mod fab; pub use fab::{Fab, FabSize, PwtFab}; mod fab_menu; -pub use fab_menu::{FabMenu, FabMenuAlign, FabMenuDirection, PwtFabMenu}; +pub use fab_menu::{ + FabMenu, FabMenuAlign, FabMenuColor, FabMenuDirection, FabMenuEntry, PwtFabMenu, +}; mod material_app; pub use material_app::PageController; -- 2.39.5 _______________________________________________ yew-devel mailing list yew-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel