1use 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 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 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 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 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 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 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#[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}