dropdown_demo/
dropdown_demo.rs

1//! Dropdown 组件演示
2//!
3//! 展示 Dropdown 组件的基础用法和高级用法,包括:
4//! - 基础下拉菜单
5//! - 不同触发方式
6//! - 不同位置
7//! - 禁用项
8//! - 点击事件
9
10use adui_dioxus::{
11    App, Button, ButtonType, Dropdown, DropdownItem, DropdownPlacement, DropdownTrigger, ThemeMode,
12    ThemeProvider, Title, TitleLevel, use_message, use_theme,
13};
14use dioxus::prelude::*;
15
16fn main() {
17    dioxus::launch(app);
18}
19
20fn app() -> Element {
21    rsx! {
22        ThemeProvider {
23            App {
24                DropdownDemo {}
25            }
26        }
27    }
28}
29
30fn default_items() -> Vec<DropdownItem> {
31    vec![
32        DropdownItem::new("new", "新建文档"),
33        DropdownItem::new("open", "打开..."),
34        DropdownItem::new("share", "分享"),
35        DropdownItem {
36            key: "disabled".into(),
37            label: "禁用项".into(),
38            disabled: true,
39        },
40    ]
41}
42
43#[component]
44fn DropdownDemo() -> Element {
45    let theme = use_theme();
46    let mut mode = use_signal(|| ThemeMode::Light);
47    let api = use_message();
48    let last_click = use_signal(String::new);
49
50    use_effect(move || {
51        theme.set_mode(*mode.read());
52    });
53
54    rsx! {
55        div {
56            style: "padding: 24px; background: var(--adui-color-bg-base); min-height: 100vh; color: var(--adui-color-text);",
57
58            // 控制工具栏
59            div {
60                style: "display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 24px; padding: 12px; background: var(--adui-color-bg-container); border-radius: var(--adui-radius); border: 1px solid var(--adui-color-border);",
61                span { style: "font-weight: 600;", "主题控制:" }
62                Button {
63                    r#type: ButtonType::Default,
64                    onclick: move |_| *mode.write() = ThemeMode::Light,
65                    "Light"
66                }
67                Button {
68                    r#type: ButtonType::Default,
69                    onclick: move |_| *mode.write() = ThemeMode::Dark,
70                    "Dark"
71                }
72            }
73
74            Title { level: TitleLevel::H2, style: "margin-bottom: 16px;", "基础用法" }
75
76            // 基础下拉菜单
77            DemoSection {
78                title: "基础下拉菜单",
79                div {
80                    style: "display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start;",
81                    Dropdown {
82                        items: default_items(),
83                        trigger: DropdownTrigger::Click,
84                        placement: Some(DropdownPlacement::BottomLeft),
85                        on_click: {
86                            let mut sig = last_click;
87                            let api = api.clone();
88                            move |key: String| {
89                                sig.set(key.clone());
90                                if let Some(msg) = api.clone() {
91                                    msg.info(format!("选择菜单项: {}", key));
92                                }
93                            }
94                        },
95                        children: rsx! {
96                            Button {
97                                r#type: ButtonType::Default,
98                                "基础下拉菜单"
99                            }
100                        },
101                    }
102                }
103            }
104
105            // 不同触发方式
106            DemoSection {
107                title: "不同触发方式",
108                div {
109                    style: "display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start;",
110                    Dropdown {
111                        items: default_items(),
112                        trigger: DropdownTrigger::Click,
113                        children: rsx! {
114                            Button {
115                                r#type: ButtonType::Default,
116                                "Click 触发"
117                            }
118                        },
119                    }
120                    Dropdown {
121                        items: default_items(),
122                        trigger: DropdownTrigger::Hover,
123                        children: rsx! {
124                            Button {
125                                r#type: ButtonType::Default,
126                                "Hover 触发"
127                            }
128                        },
129                    }
130                }
131            }
132
133            // 不同位置
134            DemoSection {
135                title: "不同位置",
136                div {
137                    style: "display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start;",
138                    Dropdown {
139                        items: default_items(),
140                        trigger: DropdownTrigger::Click,
141                        placement: Some(DropdownPlacement::BottomLeft),
142                        children: rsx! {
143                            Button {
144                                r#type: ButtonType::Default,
145                                "Bottom Left"
146                            }
147                        },
148                    }
149                    Dropdown {
150                        items: default_items(),
151                        trigger: DropdownTrigger::Click,
152                        placement: Some(DropdownPlacement::BottomRight),
153                        children: rsx! {
154                            Button {
155                                r#type: ButtonType::Default,
156                                "Bottom Right"
157                            }
158                        },
159                    }
160                }
161            }
162
163            Title { level: TitleLevel::H2, style: "margin: 32px 0 16px 0;", "高级用法" }
164
165            // 禁用项
166            DemoSection {
167                title: "禁用项",
168                Dropdown {
169                    items: default_items(),
170                    trigger: DropdownTrigger::Click,
171                    on_click: {
172                        let mut sig = last_click;
173                        let api = api.clone();
174                        move |key: String| {
175                            sig.set(key.clone());
176                            if let Some(msg) = api.clone() {
177                                msg.info(format!("选择菜单项: {}", key));
178                            }
179                        }
180                    },
181                    children: rsx! {
182                        Button {
183                            r#type: ButtonType::Default,
184                            "包含禁用项的下拉菜单"
185                        }
186                    },
187                }
188            }
189
190            // 点击反馈
191            DemoSection {
192                title: "点击反馈",
193                div {
194                    style: "display: flex; flex-direction: column; gap: 12px;",
195                    Dropdown {
196                        items: default_items(),
197                        trigger: DropdownTrigger::Click,
198                        on_click: {
199                            let mut sig = last_click;
200                            let api = api.clone();
201                            move |key: String| {
202                                sig.set(key.clone());
203                                if let Some(msg) = api.clone() {
204                                    msg.success(format!("已选择: {}", key));
205                                }
206                            }
207                        },
208                        children: rsx! {
209                            Button {
210                                r#type: ButtonType::Primary,
211                                "点击查看反馈"
212                            }
213                        },
214                    }
215                    if !last_click.read().is_empty() {
216                        div {
217                            style: "padding: 8px; background: var(--adui-color-fill-quaternary); border-radius: var(--adui-radius); font-size: 12px; color: var(--adui-color-text-secondary);",
218                            "最近一次点击的 key: ",
219                            {last_click.read().clone()}
220                        }
221                    }
222                }
223            }
224        }
225    }
226}
227
228// 统一的demo section组件
229#[derive(Props, Clone, PartialEq)]
230struct DemoSectionProps {
231    title: &'static str,
232    children: Element,
233}
234
235#[component]
236fn DemoSection(props: DemoSectionProps) -> Element {
237    rsx! {
238        div {
239            style: "margin-bottom: 24px; padding: 16px; background: var(--adui-color-bg-container); border: 1px solid var(--adui-color-border); border-radius: var(--adui-radius);",
240            div {
241                style: "font-weight: 600; margin-bottom: 12px; color: var(--adui-color-text); font-size: 14px;",
242                {props.title}
243            }
244            {props.children}
245        }
246    }
247}