feat: Menu prop and Popover prop

This commit is contained in:
luoxiao 2024-07-27 18:04:36 +08:00
parent 875e7ffbbc
commit 767fb97e3a
6 changed files with 112 additions and 111 deletions

View file

@ -161,15 +161,15 @@ pub fn SiteHeader() -> impl IntoView {
</AutoCompletePrefix>
</AutoComplete>
<Menu
placement=MenuPlacement::BottomEnd
on_select=move |value : String| match value.as_str() {
"Dark" => change_theme(MouseEvent::new("click").unwrap()),
"Light" => change_theme(MouseEvent::new("click").unwrap()),
"github" => { _ = window().open_with_url("http://github.com/thaw-ui/thaw"); },//FIXME: breaks page
"discord" => { _ = window().open_with_url("https://discord.gg/YPxuprzu6M"); },//FIXME: breaks page
_ => navigate_signal.get()(&value, Default::default())
position=MenuPosition::BottomEnd
on_select=move |value : String| match value.as_str() {
"Dark" => change_theme(MouseEvent::new("click").unwrap()),
"Light" => change_theme(MouseEvent::new("click").unwrap()),
"github" => { _ = window().open_with_url("http://github.com/thaw-ui/thaw"); },//FIXME: breaks page
"discord" => { _ = window().open_with_url("https://discord.gg/YPxuprzu6M"); },//FIXME: breaks page
_ => navigate_signal.get()(&value, Default::default())
}
}
>
<MenuTrigger slot class="demo-header__menu-mobile">
<Button
@ -178,9 +178,9 @@ pub fn SiteHeader() -> impl IntoView {
attr:style="font-size: 22px; padding: 0px 6px;"
/>
</MenuTrigger>
<MenuItem key=theme_name label=theme_name/>
<MenuItem icon=icondata::AiGithubOutlined key="github" label="Github"/>
<MenuItem icon=icondata::BiDiscordAlt key="discord" label="Discord"/>
<MenuItem value=theme_name>{theme_name}</MenuItem>
<MenuItem icon=icondata::AiGithubOutlined value="github">"Github"</MenuItem>
<MenuItem icon=icondata::BiDiscordAlt value="discord">"Discord"</MenuItem>
{
use crate::pages::{gen_menu_data, MenuGroupOption, MenuItemOption};
gen_menu_data().into_iter().map(|data| {
@ -193,7 +193,7 @@ pub fn SiteHeader() -> impl IntoView {
children.into_iter().map(|item| {
let MenuItemOption { label, value } = item;
view! {
<MenuItem label key=value/>
<MenuItem value=value>{label}</MenuItem>
}
}).collect_view()
}

View file

@ -1,4 +1,4 @@
# Menu
# Menu
```rust demo
//let message = use_message();
@ -11,7 +11,7 @@
// }
//};
let on_select = move |key| println!("{}", key);
let on_select = move |value| println!("{}", value);
view! {
<Space>
@ -19,17 +19,17 @@ view! {
<MenuTrigger slot>
<Button>"Hover"</Button>
</MenuTrigger>
<MenuItem key="facebook" icon=icondata::AiFacebookOutlined label="Facebook"></MenuItem>
<MenuItem key="twitter" disabled=true icon=icondata::AiTwitterOutlined label="Twitter"></MenuItem>
<MenuItem value="facebook" icon=icondata::AiFacebookOutlined>"Facebook"</MenuItem>
<MenuItem value="twitter" disabled=true icon=icondata::AiTwitterOutlined>"Twitter"</MenuItem>
</Menu>
<Menu on_select>
<MenuTrigger slot>
<Button>"Click"</Button>
</MenuTrigger>
<MenuItem key="facebook" icon=icondata::AiFacebookOutlined label="Facebook"></MenuItem>
<MenuItem key="twitter" icon=icondata::AiTwitterOutlined label="Twitter"></MenuItem>
<MenuItem key="no_icon" disabled=true label="Mastodon"></MenuItem>
<MenuItem value="facebook" icon=icondata::AiFacebookOutlined>"Facebook"</MenuItem>
<MenuItem value="twitter" icon=icondata::AiTwitterOutlined>"Twitter"</MenuItem>
<MenuItem value="no_icon" disabled=true>"Mastodon"</MenuItem>
</Menu>
</Space>
}
@ -40,7 +40,7 @@ view! {
```rust demo
use leptos_meta::Style;
let on_select = move |key| println!("{}", key);
let on_select = move |value| println!("{}", value);
view! {
<Style>
@ -48,7 +48,7 @@ view! {
</Style>
<Grid x_gap=8 y_gap=8 cols=3 class="demo-menu">
<GridItem>
<Menu on_select placement=MenuPlacement::TopStart>
<Menu on_select position=MenuPosition::TopStart>
<MenuTrigger slot>
<Button>"Top Start"</Button>
</MenuTrigger>
@ -56,7 +56,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::Top>
<Menu on_select position=MenuPosition::Top>
<MenuTrigger slot>
<Button>"Top"</Button>
</MenuTrigger>
@ -64,7 +64,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::TopEnd>
<Menu on_select position=MenuPosition::TopEnd>
<MenuTrigger slot>
<Button>"Top End"</Button>
</MenuTrigger>
@ -72,7 +72,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::LeftStart>
<Menu on_select position=MenuPosition::LeftStart>
<MenuTrigger slot>
<Button>"Left Start"</Button>
</MenuTrigger>
@ -80,7 +80,7 @@ view! {
</Menu>
</GridItem>
<GridItem offset=1>
<Menu on_select placement=MenuPlacement::RightStart>
<Menu on_select position=MenuPosition::RightStart>
<MenuTrigger slot>
<Button>"Right Start"</Button>
</MenuTrigger>
@ -88,7 +88,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::Left>
<Menu on_select position=MenuPosition::Left>
<MenuTrigger slot>
<Button>"Left"</Button>
</MenuTrigger>
@ -96,7 +96,7 @@ view! {
</Menu>
</GridItem>
<GridItem offset=1>
<Menu on_select placement=MenuPlacement::Right>
<Menu on_select position=MenuPosition::Right>
<MenuTrigger slot>
<Button>"Right"</Button>
</MenuTrigger>
@ -104,7 +104,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::LeftEnd>
<Menu on_select position=MenuPosition::LeftEnd>
<MenuTrigger slot>
<Button>"Left End"</Button>
</MenuTrigger>
@ -112,7 +112,7 @@ view! {
</Menu>
</GridItem>
<GridItem offset=1>
<Menu on_select placement=MenuPlacement::RightEnd>
<Menu on_select position=MenuPosition::RightEnd>
<MenuTrigger slot>
<Button>"Right End"</Button>
</MenuTrigger>
@ -120,7 +120,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::BottomStart>
<Menu on_select position=MenuPosition::BottomStart>
<MenuTrigger slot>
<Button>"Bottom Start"</Button>
</MenuTrigger>
@ -128,7 +128,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::Bottom>
<Menu on_select position=MenuPosition::Bottom>
<MenuTrigger slot>
<Button>"Bottom"</Button>
</MenuTrigger>
@ -136,7 +136,7 @@ view! {
</Menu>
</GridItem>
<GridItem>
<Menu on_select placement=MenuPlacement::BottomEnd>
<Menu on_select position=MenuPosition::BottomEnd>
<MenuTrigger slot>
<Button>"Bottom End"</Button>
</MenuTrigger>
@ -149,35 +149,33 @@ view! {
### Menu Props
| Name | Type | Default | Description |
| ------------ | ----------------------------------- | ---------------------------- | ------------------------------------------- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu element. |
| on_select | `Callback<String>` | | Called when item is selected. |
| trigger_type | `MenuTriggerType` | `MenuTriggerType::Click` | Action that displays the menu. |
| placement | `MenuPlacement` | `MenuPlacement::Bottom` | Menu placement. |
| children | `Children` | | The content inside menu. |
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu element. |
| on_select | `Callback<String>` | | Called when item is selected. |
| trigger_type | `MenuTriggerType` | `MenuTriggerType::Click` | Action that displays the menu. |
| position | `MenuPosition` | `MenuPosition::Bottom` | Menu position. |
| children | `Children` | | The content inside menu. |
### MenuItem Props
| Name | Type | Default | Description |
| -------- | -------------------------------------------- | -------------------- | ------------------------------------------------ |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu item element. |
| key | `MaybeSignal<String>` | `Default::default()` | The key of the menu item. |
| label | `MaybeSignal<String>` | `Default::default()` | The label of the menu item. |
| icon | `OptionalMaybeSignal<icondata_core::Icon>` | `None` | The icon of the menu item. |
| disabled | `MaybeSignal<bool>` | `false` | Whether the menu item is disabled. |
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu item element. |
| value | `MaybeSignal<String>` | `Default::default()` | The value of the menu item. |
| label | `MaybeSignal<String>` | `Default::default()` | The label of the menu item. |
| icon | `OptionalMaybeSignal<icondata_core::Icon>` | `None` | The icon of the menu item. |
| disabled | `MaybeSignal<bool>` | `false` | Whether the menu item is disabled. |
### Menu Slots
| Name | Default | Description |
| --------------- | ------- | ------------------------------------------------ |
| Name | Default | Description |
| ----------- | ------- | -------------------------------------------- |
| MenuTrigger | `None` | The element or component that triggers menu. |
### MenuTriger Props
| Name | Type | Default | Description |
| ------------ | ----------------------------------- | ---------------------------- | -------------------------------------------------- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu trigger element. |
| children | `Children` | | The content inside menu trigger. |
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the menu trigger element. |
| children | `Children` | | The content inside menu trigger. |

View file

@ -30,7 +30,7 @@ view! {
</Style>
<Grid x_gap=8 y_gap=8 cols=3 class="demo-popover">
<GridItem>
<Popover placement=PopoverPlacement::TopStart>
<Popover position=PopoverPosition::TopStart>
<PopoverTrigger slot>
<Button>"Top Start"</Button>
</PopoverTrigger>
@ -38,7 +38,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::Top>
<Popover position=PopoverPosition::Top>
<PopoverTrigger slot>
<Button>"Top"</Button>
</PopoverTrigger>
@ -46,7 +46,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::TopEnd>
<Popover position=PopoverPosition::TopEnd>
<PopoverTrigger slot>
<Button>"Top End"</Button>
</PopoverTrigger>
@ -54,7 +54,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::LeftStart trigger_type=PopoverTriggerType::Click>
<Popover position=PopoverPosition::LeftStart trigger_type=PopoverTriggerType::Click>
<PopoverTrigger slot>
<Button>"Left Start"</Button>
</PopoverTrigger>
@ -62,7 +62,7 @@ view! {
</Popover>
</GridItem>
<GridItem offset=1>
<Popover placement=PopoverPlacement::RightStart>
<Popover position=PopoverPosition::RightStart>
<PopoverTrigger slot>
<Button>"Right Start"</Button>
</PopoverTrigger>
@ -70,7 +70,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::Left trigger_type=PopoverTriggerType::Click>
<Popover position=PopoverPosition::Left trigger_type=PopoverTriggerType::Click>
<PopoverTrigger slot>
<Button>"Left"</Button>
</PopoverTrigger>
@ -78,7 +78,7 @@ view! {
</Popover>
</GridItem>
<GridItem offset=1>
<Popover placement=PopoverPlacement::Right>
<Popover position=PopoverPosition::Right>
<PopoverTrigger slot>
<Button>"Right"</Button>
</PopoverTrigger>
@ -86,7 +86,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::LeftEnd>
<Popover position=PopoverPosition::LeftEnd>
<PopoverTrigger slot>
<Button>"Left End"</Button>
</PopoverTrigger>
@ -94,7 +94,7 @@ view! {
</Popover>
</GridItem>
<GridItem offset=1>
<Popover placement=PopoverPlacement::RightEnd>
<Popover position=PopoverPosition::RightEnd>
<PopoverTrigger slot>
<Button>"Right End"</Button>
</PopoverTrigger>
@ -102,7 +102,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::BottomStart>
<Popover position=PopoverPosition::BottomStart>
<PopoverTrigger slot>
<Button>"Bottom Start"</Button>
</PopoverTrigger>
@ -110,7 +110,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::Bottom>
<Popover position=PopoverPosition::Bottom>
<PopoverTrigger slot>
<Button>"Bottom"</Button>
</PopoverTrigger>
@ -118,7 +118,7 @@ view! {
</Popover>
</GridItem>
<GridItem>
<Popover placement=PopoverPlacement::BottomEnd>
<Popover position=PopoverPosition::BottomEnd>
<PopoverTrigger slot>
<Button>"Bottom End"</Button>
</PopoverTrigger>
@ -152,12 +152,12 @@ view! {
### Popover Props
| Name | Type | Default | Description |
| --------- | ----------------------------------- | ----------------------- | ----------------------------- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Content class of the popover. |
| placement | `PopoverPlacement` | `PopoverPlacement::Top` | Popover placement. |
| tooltip | `bool` | `false` | Tooltip. |
| children | `Children` | | The content inside popover. |
| Name | Type | Default | Description |
| -------- | ----------------------------------- | ---------------------- | ----------------------------- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Content class of the popover. |
| position | `PopoverPosition` | `PopoverPosition::Top` | Popover position. |
| tooltip | `bool` | `false` | Tooltip. |
| children | `Children` | | The content inside popover. |
### Popover Slots

View file

@ -9,10 +9,10 @@ use thaw_utils::{class_list, mount_style, OptionalMaybeSignal};
#[component]
pub fn MenuItem(
#[prop(optional, into)] icon: OptionalMaybeSignal<icondata_core::Icon>,
#[prop(into)] label: MaybeSignal<String>,
#[prop(into)] key: MaybeSignal<String>,
#[prop(into)] value: MaybeSignal<String>,
#[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] class: MaybeProp<String>,
children: Children,
) -> impl IntoView {
mount_style("menu-item", include_str!("./menu-item.css"));
@ -28,7 +28,7 @@ pub fn MenuItem(
if disabled.get() {
return;
}
on_select(key.get());
on_select(value.get());
};
view! {
@ -51,7 +51,7 @@ pub fn MenuItem(
<Icon icon=icon style="font-size: 18px; margin-right: 8px"/>
</OptionComp>
<span style="flex-grow: 1">{label}</span>
<span style="flex-grow: 1">{children()}</span>
</div>
}
}

View file

@ -29,7 +29,7 @@ pub fn Menu(
#[prop(optional, into)] class: MaybeProp<String>,
menu_trigger: MenuTrigger,
#[prop(optional)] trigger_type: MenuTriggerType,
#[prop(optional)] placement: MenuPlacement,
#[prop(optional)] position: MenuPosition,
#[prop(into)] on_select: ArcOneCallback<String>,
#[prop(optional, into)] appearance: Option<MaybeSignal<MenuAppearance>>,
children: Children,
@ -110,7 +110,7 @@ pub fn Menu(
>
{trigger_children()}
</div>
<Follower slot show=is_show_menu placement>
<Follower slot show=is_show_menu placement=position>
<CSSTransition
node_ref=menu_ref
name="menu-transition"
@ -163,7 +163,7 @@ impl MenuAppearance {
}
#[derive(Default)]
pub enum MenuPlacement {
pub enum MenuPosition {
Top,
#[default]
Bottom,
@ -179,21 +179,21 @@ pub enum MenuPlacement {
BottomEnd,
}
impl From<MenuPlacement> for FollowerPlacement {
fn from(value: MenuPlacement) -> Self {
impl From<MenuPosition> for FollowerPlacement {
fn from(value: MenuPosition) -> Self {
match value {
MenuPlacement::Top => Self::Top,
MenuPlacement::Bottom => Self::Bottom,
MenuPlacement::Left => Self::Left,
MenuPlacement::Right => Self::Right,
MenuPlacement::TopStart => Self::TopStart,
MenuPlacement::TopEnd => Self::TopEnd,
MenuPlacement::LeftStart => Self::LeftStart,
MenuPlacement::LeftEnd => Self::LeftEnd,
MenuPlacement::RightStart => Self::RightStart,
MenuPlacement::RightEnd => Self::RightEnd,
MenuPlacement::BottomStart => Self::BottomStart,
MenuPlacement::BottomEnd => Self::BottomEnd,
MenuPosition::Top => Self::Top,
MenuPosition::Bottom => Self::Bottom,
MenuPosition::Left => Self::Left,
MenuPosition::Right => Self::Right,
MenuPosition::TopStart => Self::TopStart,
MenuPosition::TopEnd => Self::TopEnd,
MenuPosition::LeftStart => Self::LeftStart,
MenuPosition::LeftEnd => Self::LeftEnd,
MenuPosition::RightStart => Self::RightStart,
MenuPosition::RightEnd => Self::RightEnd,
MenuPosition::BottomStart => Self::BottomStart,
MenuPosition::BottomEnd => Self::BottomEnd,
}
}
}

View file

@ -16,9 +16,12 @@ pub fn Popover(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional)] trigger_type: PopoverTriggerType,
popover_trigger: PopoverTrigger,
#[prop(optional)] placement: PopoverPlacement,
/// Configures the position of the Popover.
#[prop(optional)]
position: PopoverPosition,
/// A popover can appear styled with brand or inverted. When not specified, the default style is used.
#[prop(optional, into)] appearance: Option<MaybeSignal<PopoverAppearance>>,
#[prop(optional, into)]
appearance: Option<MaybeSignal<PopoverAppearance>>,
children: Children,
) -> impl IntoView {
mount_style("popover", include_str!("./popover.css"));
@ -117,7 +120,7 @@ pub fn Popover(
>
{trigger_children()}
</div>
<Follower slot show=is_show_popover placement>
<Follower slot show=is_show_popover placement=position>
<CSSTransition
node_ref=popover_ref
name="popover-transition"
@ -173,7 +176,7 @@ pub enum PopoverTriggerType {
impl Copy for PopoverTriggerType {}
#[derive(Default)]
pub enum PopoverPlacement {
pub enum PopoverPosition {
#[default]
Top,
Bottom,
@ -189,21 +192,21 @@ pub enum PopoverPlacement {
BottomEnd,
}
impl From<PopoverPlacement> for FollowerPlacement {
fn from(value: PopoverPlacement) -> Self {
impl From<PopoverPosition> for FollowerPlacement {
fn from(value: PopoverPosition) -> Self {
match value {
PopoverPlacement::Top => Self::Top,
PopoverPlacement::Bottom => Self::Bottom,
PopoverPlacement::Left => Self::Left,
PopoverPlacement::Right => Self::Right,
PopoverPlacement::TopStart => Self::TopStart,
PopoverPlacement::TopEnd => Self::TopEnd,
PopoverPlacement::LeftStart => Self::LeftStart,
PopoverPlacement::LeftEnd => Self::LeftEnd,
PopoverPlacement::RightStart => Self::RightStart,
PopoverPlacement::RightEnd => Self::RightEnd,
PopoverPlacement::BottomStart => Self::BottomStart,
PopoverPlacement::BottomEnd => Self::BottomEnd,
PopoverPosition::Top => Self::Top,
PopoverPosition::Bottom => Self::Bottom,
PopoverPosition::Left => Self::Left,
PopoverPosition::Right => Self::Right,
PopoverPosition::TopStart => Self::TopStart,
PopoverPosition::TopEnd => Self::TopEnd,
PopoverPosition::LeftStart => Self::LeftStart,
PopoverPosition::LeftEnd => Self::LeftEnd,
PopoverPosition::RightStart => Self::RightStart,
PopoverPosition::RightEnd => Self::RightEnd,
PopoverPosition::BottomStart => Self::BottomStart,
PopoverPosition::BottomEnd => Self::BottomEnd,
}
}
}