1#![allow(non_snake_case)]
2
3use dioxus_core::{Callback, Element, EventHandler};
4use dioxus_core_macro::{Props, component, rsx};
5use dioxus_hooks::use_signal;
6use dioxus_signals::WritableExt as _;
7
8use crate as dioxus_elements;
9use crate::Key;
10use crate::drawing::DrawList;
11use crate::schema::{
12 Alignment, Arrangement, ButtonVariant, ColorRole, IconRole, MaterialRole, MotionRole, Paint,
13 ShapeRole, SlotRole, SpaceRole, TextAlign, TextOverflow, TypeRole,
14};
15use std::cell::Cell;
16use std::rc::Rc;
17
18#[derive(Clone, Debug)]
20pub struct KeyEvent {
21 key: Key,
22 shift_key: bool,
23 ctrl_key: bool,
24 alt_key: bool,
25 meta_key: bool,
26 consumed: Rc<Cell<bool>>,
27}
28
29impl KeyEvent {
30 pub(crate) fn new(
31 key: Key,
32 shift_key: bool,
33 ctrl_key: bool,
34 alt_key: bool,
35 meta_key: bool,
36 ) -> Self {
37 Self {
38 key,
39 shift_key,
40 ctrl_key,
41 alt_key,
42 meta_key,
43 consumed: Rc::new(Cell::new(false)),
44 }
45 }
46
47 pub fn key(&self) -> Key {
48 self.key
49 }
50
51 pub fn shift_key(&self) -> bool {
52 self.shift_key
53 }
54
55 pub fn ctrl_key(&self) -> bool {
56 self.ctrl_key
57 }
58
59 pub fn alt_key(&self) -> bool {
60 self.alt_key
61 }
62
63 pub fn meta_key(&self) -> bool {
64 self.meta_key
65 }
66
67 pub fn consume(&self) {
68 self.consumed.set(true);
69 }
70
71 pub fn consumed(&self) -> bool {
72 self.consumed.get()
73 }
74}
75
76fn role(value: Option<impl Into<u16>>) -> i64 {
79 value.map_or(0, |value| i64::from(value.into()))
80}
81
82fn opt_dp(value: Option<f32>) -> Option<f64> {
86 value.map(f64::from)
87}
88
89fn opt_role(value: Option<impl Into<u16>>) -> Option<i64> {
90 value.map(|value| i64::from(value.into()))
91}
92
93fn opt_paint(value: Option<Paint>) -> Option<i64> {
94 value.map(|paint| paint.to_bits() as i64)
95}
96
97fn dp(value: Option<f32>) -> f64 {
98 f64::from(value.unwrap_or(0.0))
99}
100
101#[component]
102pub fn Column(
103 #[props(default)]
106 observe_size: Option<i64>,
107 #[props(default)]
110 motion: Option<MotionRole>,
111 #[props(default)]
114 material: Option<MaterialRole>,
115 #[props(default)] weight: Option<f32>,
116 #[props(default)] width: Option<f32>,
117 #[props(default)] height: Option<f32>,
118 #[props(default)] padding: Option<f32>,
119 #[props(default)] padding_role: Option<SpaceRole>,
120 #[props(default)] background: Option<Paint>,
121 #[props(default)] shape_role: Option<ShapeRole>,
122 #[props(default)] corner_radius: Option<f32>,
123 #[props(default)] border_width: Option<f32>,
124 #[props(default)] border_color: Option<Paint>,
125 #[props(default)] elevation: Option<f32>,
126 #[props(default)] fill_max_width: bool,
127 #[props(default)] fill_max_height: bool,
128 #[props(default)] arrangement: Option<Arrangement>,
129 #[props(default)] spacing: Option<f32>,
130 #[props(default)] space_role: Option<SpaceRole>,
131 #[props(default)] alignment: Option<Alignment>,
132 children: Element,
133) -> Element {
134 rsx! {
135 column {
136 observe_size,
137 motion: opt_role(motion),
138 material: opt_role(material),
139 weight: opt_dp(weight),
140 width: opt_dp(width),
141 height: opt_dp(height),
142 padding: opt_dp(padding),
143 padding_role: opt_role(padding_role),
144 background: opt_paint(background),
145 shape_role: opt_role(shape_role),
146 corner_radius: opt_dp(corner_radius),
147 border_width: opt_dp(border_width),
148 border_color: opt_paint(border_color),
149 elevation: opt_dp(elevation),
150 fill_max_width,
151 fill_max_height,
152 arrangement: role(arrangement),
153 spacing: dp(spacing),
154 space_role: role(space_role),
155 alignment: role(alignment),
156 {children}
157 }
158 }
159}
160
161#[component]
162pub fn Row(
163 #[props(default)]
166 observe_size: Option<i64>,
167 #[props(default)]
170 motion: Option<MotionRole>,
171 #[props(default)]
174 material: Option<MaterialRole>,
175 #[props(default)] weight: Option<f32>,
176 #[props(default)] width: Option<f32>,
177 #[props(default)] height: Option<f32>,
178 #[props(default)] padding: Option<f32>,
179 #[props(default)] padding_role: Option<SpaceRole>,
180 #[props(default)] background: Option<Paint>,
181 #[props(default)] shape_role: Option<ShapeRole>,
182 #[props(default)] corner_radius: Option<f32>,
183 #[props(default)] border_width: Option<f32>,
184 #[props(default)] border_color: Option<Paint>,
185 #[props(default)] elevation: Option<f32>,
186 #[props(default)] fill_max_width: bool,
187 #[props(default)] fill_max_height: bool,
188 #[props(default)] arrangement: Option<Arrangement>,
189 #[props(default)] spacing: Option<f32>,
190 #[props(default)] space_role: Option<SpaceRole>,
191 #[props(default)] alignment: Option<Alignment>,
192 children: Element,
193) -> Element {
194 rsx! {
195 row {
196 observe_size,
197 motion: opt_role(motion),
198 material: opt_role(material),
199 weight: opt_dp(weight),
200 width: opt_dp(width),
201 height: opt_dp(height),
202 padding: opt_dp(padding),
203 padding_role: opt_role(padding_role),
204 background: opt_paint(background),
205 shape_role: opt_role(shape_role),
206 corner_radius: opt_dp(corner_radius),
207 border_width: opt_dp(border_width),
208 border_color: opt_paint(border_color),
209 elevation: opt_dp(elevation),
210 fill_max_width,
211 fill_max_height,
212 arrangement: role(arrangement),
213 spacing: dp(spacing),
214 space_role: role(space_role),
215 alignment: role(alignment),
216 {children}
217 }
218 }
219}
220
221#[component]
222pub fn ComposeBox(
223 #[props(default)]
226 observe_size: Option<i64>,
227 #[props(default)]
230 motion: Option<MotionRole>,
231 #[props(default)]
234 material: Option<MaterialRole>,
235 #[props(default)] weight: Option<f32>,
236 #[props(default)] width: Option<f32>,
237 #[props(default)] height: Option<f32>,
238 #[props(default)] padding: Option<f32>,
239 #[props(default)] padding_role: Option<SpaceRole>,
240 #[props(default)] background: Option<Paint>,
241 #[props(default)] shape_role: Option<ShapeRole>,
242 #[props(default)] corner_radius: Option<f32>,
243 #[props(default)] border_width: Option<f32>,
244 #[props(default)] border_color: Option<Paint>,
245 #[props(default)] elevation: Option<f32>,
246 #[props(default)] fill_max_width: bool,
247 #[props(default)] fill_max_height: bool,
248 #[props(default)] alignment: Option<Alignment>,
249 children: Element,
250) -> Element {
251 rsx! {
252 composebox {
253 observe_size,
254 motion: opt_role(motion),
255 material: opt_role(material),
256 weight: opt_dp(weight),
257 width: opt_dp(width),
258 height: opt_dp(height),
259 padding: opt_dp(padding),
260 padding_role: opt_role(padding_role),
261 background: opt_paint(background),
262 shape_role: opt_role(shape_role),
263 corner_radius: opt_dp(corner_radius),
264 border_width: opt_dp(border_width),
265 border_color: opt_paint(border_color),
266 elevation: opt_dp(elevation),
267 fill_max_width,
268 fill_max_height,
269 alignment: role(alignment),
270 {children}
271 }
272 }
273}
274
275#[component]
278pub fn ScrollColumn(
279 #[props(default)] weight: Option<f32>,
280 #[props(default)] width: Option<f32>,
281 #[props(default)] height: Option<f32>,
282 #[props(default)] padding: Option<f32>,
283 #[props(default)] padding_role: Option<SpaceRole>,
284 #[props(default)] background: Option<Paint>,
285 #[props(default)] shape_role: Option<ShapeRole>,
286 #[props(default)] corner_radius: Option<f32>,
287 #[props(default)] border_width: Option<f32>,
288 #[props(default)] border_color: Option<Paint>,
289 #[props(default)] elevation: Option<f32>,
290 #[props(default)] fill_max_width: bool,
291 #[props(default)] fill_max_height: bool,
292 children: Element,
293) -> Element {
294 rsx! {
295 scrollcolumn {
296 weight: opt_dp(weight),
297 width: opt_dp(width),
298 height: opt_dp(height),
299 padding: opt_dp(padding),
300 padding_role: opt_role(padding_role),
301 background: opt_paint(background),
302 shape_role: opt_role(shape_role),
303 corner_radius: opt_dp(corner_radius),
304 border_width: opt_dp(border_width),
305 border_color: opt_paint(border_color),
306 elevation: opt_dp(elevation),
307 fill_max_width,
308 fill_max_height,
309 {children}
310 }
311 }
312}
313
314#[component]
318pub fn Text(
319 #[props(default)] weight: Option<f32>,
320 #[props(default)] width: Option<f32>,
321 #[props(default)] height: Option<f32>,
322 #[props(default)] padding: Option<f32>,
323 #[props(default)] padding_role: Option<SpaceRole>,
324 #[props(default)] background: Option<Paint>,
325 #[props(default)] shape_role: Option<ShapeRole>,
326 #[props(default)] corner_radius: Option<f32>,
327 #[props(default)] border_width: Option<f32>,
328 #[props(default)] border_color: Option<Paint>,
329 #[props(default)] elevation: Option<f32>,
330 #[props(default)] fill_max_width: bool,
331 #[props(default)] fill_max_height: bool,
332 #[props(default)]
335 spans: crate::spans::TextSpans,
336 #[props(into)] text: String,
337 #[props(default)] type_role: Option<TypeRole>,
338 #[props(default)] font_size: Option<f32>,
339 #[props(default)] font_weight: Option<u16>,
340 #[props(default)] line_height: Option<f32>,
341 #[props(default)] letter_spacing: Option<f32>,
342 #[props(default)] color: Option<Paint>,
343 #[props(default)] text_align: Option<TextAlign>,
344 #[props(default)] max_lines: Option<u32>,
345 #[props(default)] overflow: Option<TextOverflow>,
346) -> Element {
347 rsx! {
348 text {
349 weight: opt_dp(weight),
350 width: opt_dp(width),
351 height: opt_dp(height),
352 padding: opt_dp(padding),
353 padding_role: opt_role(padding_role),
354 background: opt_paint(background),
355 shape_role: opt_role(shape_role),
356 corner_radius: opt_dp(corner_radius),
357 border_width: opt_dp(border_width),
358 border_color: opt_paint(border_color),
359 elevation: opt_dp(elevation),
360 fill_max_width,
361 fill_max_height,
362 spans: (!spans.is_empty()).then_some(spans),
365 text,
366 type_role: role(type_role),
367 font_size: dp(font_size),
368 font_weight: i64::from(font_weight.unwrap_or(0)),
369 line_height: dp(line_height),
370 letter_spacing: dp(letter_spacing),
371 color: color.map_or(0, |paint| paint.to_bits() as i64),
372 text_align: role(text_align),
373 max_lines: i64::from(max_lines.unwrap_or(0)),
374 overflow: role(overflow),
375 }
376 }
377}
378
379#[component]
380pub fn TextField(
381 #[props(default)] weight: Option<f32>,
382 #[props(default)] width: Option<f32>,
383 #[props(default)] height: Option<f32>,
384 #[props(default)] padding: Option<f32>,
385 #[props(default)] padding_role: Option<SpaceRole>,
386 #[props(default)] background: Option<Paint>,
387 #[props(default)] shape_role: Option<ShapeRole>,
388 #[props(default)] corner_radius: Option<f32>,
389 #[props(default)] border_width: Option<f32>,
390 #[props(default)] border_color: Option<Paint>,
391 #[props(default)] elevation: Option<f32>,
392 #[props(default)] fill_max_width: bool,
393 #[props(default)] fill_max_height: bool,
394 #[props(into, default)] placeholder: String,
395 #[props(default = true)] enabled: bool,
396 #[props(default)] multiline: bool,
397 #[props(default)]
400 type_role: Option<TypeRole>,
401 #[props(default)] on_value_change: EventHandler<String>,
402 #[props(default)] on_submit: EventHandler<String>,
403 #[props(default)] on_focus_lost: EventHandler<()>,
404 #[props(default)] on_key_down: EventHandler<KeyEvent>,
405) -> Element {
406 rsx! {
407 textfield {
408 weight: opt_dp(weight),
409 width: opt_dp(width),
410 height: opt_dp(height),
411 padding: opt_dp(padding),
412 padding_role: opt_role(padding_role),
413 background: opt_paint(background),
414 shape_role: opt_role(shape_role),
415 corner_radius: opt_dp(corner_radius),
416 border_width: opt_dp(border_width),
417 border_color: opt_paint(border_color),
418 elevation: opt_dp(elevation),
419 fill_max_width,
420 fill_max_height,
421 placeholder,
422 enabled,
423 multiline,
424 type_role: role(type_role),
425 onvaluechange: move |event| on_value_change.call((*event.data()).clone()),
426 onsubmit: move |event| on_submit.call((*event.data()).clone()),
427 onfocuslost: move |_| on_focus_lost.call(()),
428 onkeydown: move |event| on_key_down.call((*event.data()).clone()),
429 }
430 }
431}
432
433#[component]
436pub fn Button(
437 #[props(default)] weight: Option<f32>,
438 #[props(default)] width: Option<f32>,
439 #[props(default)] height: Option<f32>,
440 #[props(default)] padding: Option<f32>,
441 #[props(default)] padding_role: Option<SpaceRole>,
442 #[props(default)] background: Option<Paint>,
443 #[props(default)] shape_role: Option<ShapeRole>,
444 #[props(default)] corner_radius: Option<f32>,
445 #[props(default)] border_width: Option<f32>,
446 #[props(default)] border_color: Option<Paint>,
447 #[props(default)] elevation: Option<f32>,
448 #[props(default)] fill_max_width: bool,
449 #[props(default)] fill_max_height: bool,
450 #[props(into)] text: String,
451 #[props(default)]
458 icon: Option<IconRole>,
459 #[props(default = true)] enabled: bool,
460 #[props(default)] variant: Option<ButtonVariant>,
461 #[props(default)]
465 color: Option<Paint>,
466 #[props(default)] on_click: EventHandler<()>,
467) -> Element {
468 rsx! {
469 button {
470 weight: opt_dp(weight),
471 width: opt_dp(width),
472 height: opt_dp(height),
473 padding: opt_dp(padding),
474 padding_role: opt_role(padding_role),
475 background: opt_paint(background),
476 shape_role: opt_role(shape_role),
477 corner_radius: opt_dp(corner_radius),
478 border_width: opt_dp(border_width),
479 border_color: opt_paint(border_color),
480 elevation: opt_dp(elevation),
481 fill_max_width,
482 fill_max_height,
483 text,
484 icon: opt_role(icon),
485 enabled,
486 variant: role(variant),
487 color: opt_paint(color),
488 onclick: move |_| on_click.call(()),
489 }
490 }
491}
492
493#[component]
503pub fn Separator(#[props(default)] color: Option<Paint>) -> Element {
504 rsx! {
505 Divider { background: color }
506 }
507}
508
509#[component]
510pub fn Spacer(
511 #[props(default)] weight: Option<f32>,
512 #[props(default)] width: Option<f32>,
513 #[props(default)] height: Option<f32>,
514 #[props(default)] padding: Option<f32>,
515 #[props(default)] padding_role: Option<SpaceRole>,
516 #[props(default)] background: Option<Paint>,
517 #[props(default)] shape_role: Option<ShapeRole>,
518 #[props(default)] corner_radius: Option<f32>,
519 #[props(default)] border_width: Option<f32>,
520 #[props(default)] border_color: Option<Paint>,
521 #[props(default)] elevation: Option<f32>,
522 #[props(default)] fill_max_width: bool,
523 #[props(default)] fill_max_height: bool,
524) -> Element {
525 rsx! {
526 spacer {
527 weight: opt_dp(weight),
528 width: opt_dp(width),
529 height: opt_dp(height),
530 padding: opt_dp(padding),
531 padding_role: opt_role(padding_role),
532 background: opt_paint(background),
533 shape_role: opt_role(shape_role),
534 corner_radius: opt_dp(corner_radius),
535 border_width: opt_dp(border_width),
536 border_color: opt_paint(border_color),
537 elevation: opt_dp(elevation),
538 fill_max_width,
539 fill_max_height,
540 }
541 }
542}
543
544#[derive(Clone, Debug, PartialEq)]
551pub struct FileDrop {
552 paths: Vec<String>,
553}
554
555impl FileDrop {
556 pub fn new(joined: &str) -> Self {
561 Self {
562 paths: joined
563 .split('\0')
564 .filter(|path| !path.is_empty())
565 .map(str::to_owned)
566 .collect(),
567 }
568 }
569
570 pub fn paths(&self) -> &[String] {
572 &self.paths
573 }
574}
575
576#[derive(Clone, Copy, Debug, Eq, PartialEq)]
578pub struct RangeRequest {
579 start: u32,
580 count: u32,
581}
582
583impl RangeRequest {
584 pub(crate) fn new(start: u32, count: u32) -> Self {
585 Self { start, count }
586 }
587
588 pub fn start(&self) -> usize {
589 self.start as usize
590 }
591
592 pub fn count(&self) -> usize {
593 self.count as usize
594 }
595}
596
597#[component]
606pub fn LazyColumn(
607 #[props(default)] weight: Option<f32>,
608 #[props(default)] width: Option<f32>,
609 #[props(default)] height: Option<f32>,
610 #[props(default)] padding: Option<f32>,
611 #[props(default)] padding_role: Option<SpaceRole>,
612 #[props(default)] background: Option<Paint>,
613 #[props(default)] shape_role: Option<ShapeRole>,
614 #[props(default)] corner_radius: Option<f32>,
615 #[props(default)] border_width: Option<f32>,
616 #[props(default)] border_color: Option<Paint>,
617 #[props(default)] elevation: Option<f32>,
618 #[props(default)] fill_max_width: bool,
619 #[props(default)] fill_max_height: bool,
620 item_count: usize,
621 #[props(default)] key_of: Option<Callback<usize, String>>,
622 item: Callback<usize, Element>,
623) -> Element {
624 let mut range = use_signal(|| (0_usize, 0_usize));
625 let (start, count) = range();
626 let first = start.min(item_count);
627 let last = first.saturating_add(count).min(item_count);
628 rsx! {
629 lazycolumn {
630 weight: opt_dp(weight),
631 width: opt_dp(width),
632 height: opt_dp(height),
633 padding: opt_dp(padding),
634 padding_role: opt_role(padding_role),
635 background: opt_paint(background),
636 shape_role: opt_role(shape_role),
637 corner_radius: opt_dp(corner_radius),
638 border_width: opt_dp(border_width),
639 border_color: opt_paint(border_color),
640 elevation: opt_dp(elevation),
641 fill_max_width,
642 fill_max_height,
643 item_count: item_count as i64,
644 onrangerequest: move |event: dioxus_core::Event<RangeRequest>| {
645 let requested = event.data();
646 range.set((requested.start(), requested.count()));
647 },
648 for index in first..last {
649 {
650 let item_key = key_of
651 .map_or_else(|| index.to_string(), |key_of| key_of.call(index));
652 rsx! {
653 composebox { key: "{item_key}", item_key, {item.call(index)} }
654 }
655 }
656 }
657 }
658 }
659}
660
661#[component]
665pub fn Card(
666 #[props(default)]
669 observe_size: Option<i64>,
670 #[props(default)]
673 motion: Option<MotionRole>,
674 #[props(default)]
677 material: Option<MaterialRole>,
678 #[props(default)] weight: Option<f32>,
679 #[props(default)] width: Option<f32>,
680 #[props(default)] height: Option<f32>,
681 #[props(default)] padding: Option<f32>,
682 #[props(default)] padding_role: Option<SpaceRole>,
683 #[props(default)] background: Option<Paint>,
684 #[props(default)] shape_role: Option<ShapeRole>,
685 #[props(default)] corner_radius: Option<f32>,
686 #[props(default)] border_width: Option<f32>,
687 #[props(default)] border_color: Option<Paint>,
688 #[props(default)] elevation: Option<f32>,
689 #[props(default)] fill_max_width: bool,
690 #[props(default)] fill_max_height: bool,
691 children: Element,
692) -> Element {
693 rsx! {
694 card {
695 observe_size,
696 motion: opt_role(motion),
697 material: opt_role(material),
698 weight: opt_dp(weight),
699 width: opt_dp(width),
700 height: opt_dp(height),
701 padding: opt_dp(padding),
702 padding_role: opt_role(padding_role),
703 background: opt_paint(background),
704 shape_role: opt_role(shape_role),
705 corner_radius: opt_dp(corner_radius),
706 border_width: opt_dp(border_width),
707 border_color: opt_paint(border_color),
708 elevation: opt_dp(elevation),
709 fill_max_width,
710 fill_max_height,
711 {children}
712 }
713 }
714}
715
716#[component]
719pub fn Surface(
720 #[props(default)]
723 observe_size: Option<i64>,
724 #[props(default)]
727 motion: Option<MotionRole>,
728 #[props(default)]
731 material: Option<MaterialRole>,
732 #[props(default)] weight: Option<f32>,
733 #[props(default)] width: Option<f32>,
734 #[props(default)] height: Option<f32>,
735 #[props(default)] padding: Option<f32>,
736 #[props(default)] padding_role: Option<SpaceRole>,
737 #[props(default)] background: Option<Paint>,
738 #[props(default)] shape_role: Option<ShapeRole>,
739 #[props(default)] corner_radius: Option<f32>,
740 #[props(default)] border_width: Option<f32>,
741 #[props(default)] border_color: Option<Paint>,
742 #[props(default)] elevation: Option<f32>,
743 #[props(default)] fill_max_width: bool,
744 #[props(default)] fill_max_height: bool,
745 children: Element,
746) -> Element {
747 rsx! {
748 surface {
749 observe_size,
750 motion: opt_role(motion),
751 material: opt_role(material),
752 weight: opt_dp(weight),
753 width: opt_dp(width),
754 height: opt_dp(height),
755 padding: opt_dp(padding),
756 padding_role: opt_role(padding_role),
757 background: opt_paint(background),
758 shape_role: opt_role(shape_role),
759 corner_radius: opt_dp(corner_radius),
760 border_width: opt_dp(border_width),
761 border_color: opt_paint(border_color),
762 elevation: opt_dp(elevation),
763 fill_max_width,
764 fill_max_height,
765 {children}
766 }
767 }
768}
769
770#[component]
775pub fn Dialog(
776 #[props(default)] weight: Option<f32>,
777 #[props(default)] width: Option<f32>,
778 #[props(default)] height: Option<f32>,
779 #[props(default)] padding: Option<f32>,
780 #[props(default)] padding_role: Option<SpaceRole>,
781 #[props(default)] background: Option<Paint>,
782 #[props(default)] shape_role: Option<ShapeRole>,
783 #[props(default)] corner_radius: Option<f32>,
784 #[props(default)] border_width: Option<f32>,
785 #[props(default)] border_color: Option<Paint>,
786 #[props(default)] elevation: Option<f32>,
787 #[props(default)] fill_max_width: bool,
788 #[props(default)] fill_max_height: bool,
789 #[props(default)] open: bool,
790 #[props(default)] on_dismiss: EventHandler<()>,
791 children: Element,
792) -> Element {
793 rsx! {
794 dialog {
795 weight: opt_dp(weight),
796 width: opt_dp(width),
797 height: opt_dp(height),
798 padding: opt_dp(padding),
799 padding_role: opt_role(padding_role),
800 background: opt_paint(background),
801 shape_role: opt_role(shape_role),
802 corner_radius: opt_dp(corner_radius),
803 border_width: opt_dp(border_width),
804 border_color: opt_paint(border_color),
805 elevation: opt_dp(elevation),
806 fill_max_width,
807 fill_max_height,
808 open,
809 ondismiss: move |_| on_dismiss.call(()),
810 {children}
811 }
812 }
813}
814
815#[component]
822pub fn Menu(
823 #[props(default)] weight: Option<f32>,
824 #[props(default)] width: Option<f32>,
825 #[props(default)] height: Option<f32>,
826 #[props(default)] padding: Option<f32>,
827 #[props(default)] padding_role: Option<SpaceRole>,
828 #[props(default)] background: Option<Paint>,
829 #[props(default)] shape_role: Option<ShapeRole>,
830 #[props(default)] corner_radius: Option<f32>,
831 #[props(default)] border_width: Option<f32>,
832 #[props(default)] border_color: Option<Paint>,
833 #[props(default)] elevation: Option<f32>,
834 #[props(default)] fill_max_width: bool,
835 #[props(default)] fill_max_height: bool,
836 #[props(default)] expanded: bool,
837 #[props(default)] on_dismiss: EventHandler<()>,
838 anchor: Element,
839 children: Element,
840) -> Element {
841 rsx! {
842 menu {
843 weight: opt_dp(weight),
844 width: opt_dp(width),
845 height: opt_dp(height),
846 padding: opt_dp(padding),
847 padding_role: opt_role(padding_role),
848 background: opt_paint(background),
849 shape_role: opt_role(shape_role),
850 corner_radius: opt_dp(corner_radius),
851 border_width: opt_dp(border_width),
852 border_color: opt_paint(border_color),
853 elevation: opt_dp(elevation),
854 fill_max_width,
855 fill_max_height,
856 open: expanded,
857 ondismiss: move |_| on_dismiss.call(()),
858 {anchor}
859 {children}
860 }
861 }
862}
863
864#[component]
870pub fn Tabs(
871 #[props(default)] weight: Option<f32>,
872 #[props(default)] width: Option<f32>,
873 #[props(default)] height: Option<f32>,
874 #[props(default)] padding: Option<f32>,
875 #[props(default)] padding_role: Option<SpaceRole>,
876 #[props(default)] background: Option<Paint>,
877 #[props(default)]
883 color: Option<Paint>,
884 #[props(default)] shape_role: Option<ShapeRole>,
885 #[props(default)] corner_radius: Option<f32>,
886 #[props(default)] border_width: Option<f32>,
887 #[props(default)] border_color: Option<Paint>,
888 #[props(default)] elevation: Option<f32>,
889 #[props(default)] fill_max_width: bool,
890 #[props(default)] fill_max_height: bool,
891 #[props(default)] selected_index: usize,
892 children: Element,
893) -> Element {
894 rsx! {
895 tabs {
896 weight: opt_dp(weight),
897 width: opt_dp(width),
898 height: opt_dp(height),
899 padding: opt_dp(padding),
900 padding_role: opt_role(padding_role),
901 background: opt_paint(background),
902 color: opt_paint(color),
903 shape_role: opt_role(shape_role),
904 corner_radius: opt_dp(corner_radius),
905 border_width: opt_dp(border_width),
906 border_color: opt_paint(border_color),
907 elevation: opt_dp(elevation),
908 fill_max_width,
909 fill_max_height,
910 selected_index: selected_index as i64,
911 {children}
912 }
913 }
914}
915
916#[component]
919pub fn TopAppBar(
920 #[props(default)] weight: Option<f32>,
921 #[props(default)] width: Option<f32>,
922 #[props(default)] height: Option<f32>,
923 #[props(default)] padding: Option<f32>,
924 #[props(default)] padding_role: Option<SpaceRole>,
925 #[props(default)] background: Option<Paint>,
926 #[props(default)] shape_role: Option<ShapeRole>,
927 #[props(default)] corner_radius: Option<f32>,
928 #[props(default)] border_width: Option<f32>,
929 #[props(default)] border_color: Option<Paint>,
930 #[props(default)] elevation: Option<f32>,
931 #[props(default)] fill_max_width: bool,
932 #[props(default)] fill_max_height: bool,
933 #[props(default)]
942 title: String,
943 children: Element,
944) -> Element {
945 rsx! {
946 topappbar {
947 weight: opt_dp(weight),
948 width: opt_dp(width),
949 height: opt_dp(height),
950 padding: opt_dp(padding),
951 padding_role: opt_role(padding_role),
952 background: opt_paint(background),
953 shape_role: opt_role(shape_role),
954 corner_radius: opt_dp(corner_radius),
955 border_width: opt_dp(border_width),
956 border_color: opt_paint(border_color),
957 elevation: opt_dp(elevation),
958 fill_max_width,
959 fill_max_height,
960 text: title,
961 {children}
962 }
963 }
964}
965
966#[component]
970pub fn LazyRow(
971 #[props(default)] weight: Option<f32>,
972 #[props(default)] width: Option<f32>,
973 #[props(default)] height: Option<f32>,
974 #[props(default)] padding: Option<f32>,
975 #[props(default)] padding_role: Option<SpaceRole>,
976 #[props(default)] background: Option<Paint>,
977 #[props(default)] shape_role: Option<ShapeRole>,
978 #[props(default)] corner_radius: Option<f32>,
979 #[props(default)] border_width: Option<f32>,
980 #[props(default)] border_color: Option<Paint>,
981 #[props(default)] elevation: Option<f32>,
982 #[props(default)] fill_max_width: bool,
983 #[props(default)] fill_max_height: bool,
984 item_count: usize,
985 #[props(default)] key_of: Option<Callback<usize, String>>,
986 item: Callback<usize, Element>,
987) -> Element {
988 let mut range = use_signal(|| (0_usize, 0_usize));
989 let (start, count) = range();
990 let first = start.min(item_count);
991 let last = first.saturating_add(count).min(item_count);
992 rsx! {
993 lazyrow {
994 weight: opt_dp(weight),
995 width: opt_dp(width),
996 height: opt_dp(height),
997 padding: opt_dp(padding),
998 padding_role: opt_role(padding_role),
999 background: opt_paint(background),
1000 shape_role: opt_role(shape_role),
1001 corner_radius: opt_dp(corner_radius),
1002 border_width: opt_dp(border_width),
1003 border_color: opt_paint(border_color),
1004 elevation: opt_dp(elevation),
1005 fill_max_width,
1006 fill_max_height,
1007 item_count: item_count as i64,
1008 onrangerequest: move |event: dioxus_core::Event<RangeRequest>| {
1009 let requested = event.data();
1010 range.set((requested.start(), requested.count()));
1011 },
1012 for index in first..last {
1013 {
1014 let item_key = key_of
1015 .map_or_else(|| index.to_string(), |key_of| key_of.call(index));
1016 rsx! {
1017 composebox { key: "{item_key}", item_key, {item.call(index)} }
1018 }
1019 }
1020 }
1021 }
1022 }
1023}
1024
1025#[component]
1029pub fn Tooltip(
1030 #[props(default)] weight: Option<f32>,
1031 #[props(default)] width: Option<f32>,
1032 #[props(default)] height: Option<f32>,
1033 #[props(default)] padding: Option<f32>,
1034 #[props(default)] padding_role: Option<SpaceRole>,
1035 #[props(default)] background: Option<Paint>,
1036 #[props(default)] shape_role: Option<ShapeRole>,
1037 #[props(default)] corner_radius: Option<f32>,
1038 #[props(default)] border_width: Option<f32>,
1039 #[props(default)] border_color: Option<Paint>,
1040 #[props(default)] elevation: Option<f32>,
1041 #[props(default)] fill_max_width: bool,
1042 #[props(default)] fill_max_height: bool,
1043 #[props(into)] text: String,
1044 children: Element,
1045) -> Element {
1046 rsx! {
1047 tooltip {
1048 weight: opt_dp(weight),
1049 width: opt_dp(width),
1050 height: opt_dp(height),
1051 padding: opt_dp(padding),
1052 padding_role: opt_role(padding_role),
1053 background: opt_paint(background),
1054 shape_role: opt_role(shape_role),
1055 corner_radius: opt_dp(corner_radius),
1056 border_width: opt_dp(border_width),
1057 border_color: opt_paint(border_color),
1058 elevation: opt_dp(elevation),
1059 fill_max_width,
1060 fill_max_height,
1061 text,
1062 {children}
1063 }
1064 }
1065}
1066
1067#[component]
1077pub fn Canvas(
1078 #[props(default)] weight: Option<f32>,
1079 #[props(default)] width: Option<f32>,
1080 #[props(default)] height: Option<f32>,
1081 #[props(default)] padding: Option<f32>,
1082 #[props(default)] padding_role: Option<SpaceRole>,
1083 #[props(default)] background: Option<Paint>,
1084 #[props(default)] shape_role: Option<ShapeRole>,
1085 #[props(default)] corner_radius: Option<f32>,
1086 #[props(default)] border_width: Option<f32>,
1087 #[props(default)] border_color: Option<Paint>,
1088 #[props(default)] elevation: Option<f32>,
1089 #[props(default)] fill_max_width: bool,
1090 #[props(default)] fill_max_height: bool,
1091 commands: DrawList,
1092) -> Element {
1093 rsx! {
1094 canvas {
1095 weight: opt_dp(weight),
1096 width: opt_dp(width),
1097 height: opt_dp(height),
1098 padding: opt_dp(padding),
1099 padding_role: opt_role(padding_role),
1100 background: opt_paint(background),
1101 shape_role: opt_role(shape_role),
1102 corner_radius: opt_dp(corner_radius),
1103 border_width: opt_dp(border_width),
1104 border_color: opt_paint(border_color),
1105 elevation: opt_dp(elevation),
1106 fill_max_width,
1107 fill_max_height,
1108 commands,
1109 }
1110 }
1111}
1112
1113#[component]
1116pub fn Image(
1117 #[props(default)] weight: Option<f32>,
1118 #[props(default)] width: Option<f32>,
1119 #[props(default)] height: Option<f32>,
1120 #[props(default)] padding: Option<f32>,
1121 #[props(default)] padding_role: Option<SpaceRole>,
1122 #[props(default)] background: Option<Paint>,
1123 #[props(default)] shape_role: Option<ShapeRole>,
1124 #[props(default)] corner_radius: Option<f32>,
1125 #[props(default)] border_width: Option<f32>,
1126 #[props(default)] border_color: Option<Paint>,
1127 #[props(default)] elevation: Option<f32>,
1128 #[props(default)] fill_max_width: bool,
1129 #[props(default)] fill_max_height: bool,
1130 asset_id: u32,
1131) -> Element {
1132 rsx! {
1133 image {
1134 weight: opt_dp(weight),
1135 width: opt_dp(width),
1136 height: opt_dp(height),
1137 padding: opt_dp(padding),
1138 padding_role: opt_role(padding_role),
1139 background: opt_paint(background),
1140 shape_role: opt_role(shape_role),
1141 corner_radius: opt_dp(corner_radius),
1142 border_width: opt_dp(border_width),
1143 border_color: opt_paint(border_color),
1144 elevation: opt_dp(elevation),
1145 fill_max_width,
1146 fill_max_height,
1147 asset: i64::from(asset_id),
1148 }
1149 }
1150}
1151
1152#[component]
1155pub fn Icon(
1156 #[props(default)] weight: Option<f32>,
1157 #[props(default)] width: Option<f32>,
1158 #[props(default)] height: Option<f32>,
1159 #[props(default)] padding: Option<f32>,
1160 #[props(default)] padding_role: Option<SpaceRole>,
1161 #[props(default)] background: Option<Paint>,
1162 #[props(default)] shape_role: Option<ShapeRole>,
1163 #[props(default)] corner_radius: Option<f32>,
1164 #[props(default)] border_width: Option<f32>,
1165 #[props(default)] border_color: Option<Paint>,
1166 #[props(default)] elevation: Option<f32>,
1167 #[props(default)] fill_max_width: bool,
1168 #[props(default)] fill_max_height: bool,
1169 asset_id: u32,
1170 #[props(default)] color: Option<Paint>,
1171) -> Element {
1172 rsx! {
1173 icon {
1174 weight: opt_dp(weight),
1175 width: opt_dp(width),
1176 height: opt_dp(height),
1177 padding: opt_dp(padding),
1178 padding_role: opt_role(padding_role),
1179 background: opt_paint(background),
1180 shape_role: opt_role(shape_role),
1181 corner_radius: opt_dp(corner_radius),
1182 border_width: opt_dp(border_width),
1183 border_color: opt_paint(border_color),
1184 elevation: opt_dp(elevation),
1185 fill_max_width,
1186 fill_max_height,
1187 asset: i64::from(asset_id),
1188 color: color.map_or(0, |paint| paint.to_bits() as i64),
1189 }
1190 }
1191}
1192
1193#[component]
1203pub fn DatePicker(
1204 #[props(default)] weight: Option<f32>,
1205 #[props(default)] width: Option<f32>,
1206 #[props(default)] height: Option<f32>,
1207 #[props(default)] padding: Option<f32>,
1208 #[props(default)] padding_role: Option<SpaceRole>,
1209 #[props(default)] background: Option<Paint>,
1210 #[props(default)] shape_role: Option<ShapeRole>,
1211 #[props(default)] corner_radius: Option<f32>,
1212 #[props(default)] border_width: Option<f32>,
1213 #[props(default)] border_color: Option<Paint>,
1214 #[props(default)] elevation: Option<f32>,
1215 #[props(default)] fill_max_width: bool,
1216 #[props(default)] fill_max_height: bool,
1217 value: i64,
1219 #[props(default)] min: Option<i64>,
1220 #[props(default)] max: Option<i64>,
1221 #[props(default = true)] enabled: bool,
1222 #[props(default)] on_change: EventHandler<i64>,
1223) -> Element {
1224 rsx! {
1225 datepicker {
1226 weight: opt_dp(weight),
1227 width: opt_dp(width),
1228 height: opt_dp(height),
1229 padding: opt_dp(padding),
1230 padding_role: opt_role(padding_role),
1231 background: opt_paint(background),
1232 shape_role: opt_role(shape_role),
1233 corner_radius: opt_dp(corner_radius),
1234 border_width: opt_dp(border_width),
1235 border_color: opt_paint(border_color),
1236 elevation: opt_dp(elevation),
1237 fill_max_width,
1238 fill_max_height,
1239 value,
1240 min: min.unwrap_or(i64::MIN),
1241 max: max.unwrap_or(i64::MAX),
1242 enabled,
1243 onchange: move |event: dioxus_core::Event<f64>| on_change.call(*event.data() as i64),
1244 }
1245 }
1246}
1247
1248#[component]
1253pub fn TimePicker(
1254 #[props(default)] weight: Option<f32>,
1255 #[props(default)] width: Option<f32>,
1256 #[props(default)] height: Option<f32>,
1257 #[props(default)] padding: Option<f32>,
1258 #[props(default)] padding_role: Option<SpaceRole>,
1259 #[props(default)] background: Option<Paint>,
1260 #[props(default)] shape_role: Option<ShapeRole>,
1261 #[props(default)] corner_radius: Option<f32>,
1262 #[props(default)] border_width: Option<f32>,
1263 #[props(default)] border_color: Option<Paint>,
1264 #[props(default)] elevation: Option<f32>,
1265 #[props(default)] fill_max_width: bool,
1266 #[props(default)] fill_max_height: bool,
1267 value: u32,
1269 #[props(default)] min: Option<u32>,
1270 #[props(default)] max: Option<u32>,
1271 #[props(default = true)] enabled: bool,
1272 #[props(default)] on_change: EventHandler<u32>,
1273) -> Element {
1274 rsx! {
1275 timepicker {
1276 weight: opt_dp(weight),
1277 width: opt_dp(width),
1278 height: opt_dp(height),
1279 padding: opt_dp(padding),
1280 padding_role: opt_role(padding_role),
1281 background: opt_paint(background),
1282 shape_role: opt_role(shape_role),
1283 corner_radius: opt_dp(corner_radius),
1284 border_width: opt_dp(border_width),
1285 border_color: opt_paint(border_color),
1286 elevation: opt_dp(elevation),
1287 fill_max_width,
1288 fill_max_height,
1289 value: i64::from(value),
1290 min: i64::from(min.unwrap_or(0)),
1291 max: i64::from(max.unwrap_or(MINUTES_IN_A_DAY - 1)),
1292 enabled,
1293 onchange: move |event: dioxus_core::Event<f64>| {
1294 on_change.call((*event.data() as i64).clamp(0, i64::from(MINUTES_IN_A_DAY - 1)) as u32)
1295 },
1296 }
1297 }
1298}
1299
1300const MINUTES_IN_A_DAY: u32 = 24 * 60;
1301
1302#[component]
1305pub fn Dropdown(
1306 #[props(default)] weight: Option<f32>,
1307 #[props(default)] width: Option<f32>,
1308 #[props(default)] height: Option<f32>,
1309 #[props(default)] padding: Option<f32>,
1310 #[props(default)] padding_role: Option<SpaceRole>,
1311 #[props(default)] background: Option<Paint>,
1312 #[props(default)] shape_role: Option<ShapeRole>,
1313 #[props(default)] corner_radius: Option<f32>,
1314 #[props(default)] border_width: Option<f32>,
1315 #[props(default)] border_color: Option<Paint>,
1316 #[props(default)] elevation: Option<f32>,
1317 #[props(default)] fill_max_width: bool,
1318 #[props(default)] fill_max_height: bool,
1319 #[props(default)] selected_index: usize,
1320 #[props(default = true)] enabled: bool,
1321 #[props(default)] on_change: EventHandler<usize>,
1322 children: Element,
1323) -> Element {
1324 rsx! {
1325 dropdown {
1326 weight: opt_dp(weight),
1327 width: opt_dp(width),
1328 height: opt_dp(height),
1329 padding: opt_dp(padding),
1330 padding_role: opt_role(padding_role),
1331 background: opt_paint(background),
1332 shape_role: opt_role(shape_role),
1333 corner_radius: opt_dp(corner_radius),
1334 border_width: opt_dp(border_width),
1335 border_color: opt_paint(border_color),
1336 elevation: opt_dp(elevation),
1337 fill_max_width,
1338 fill_max_height,
1339 selected_index: selected_index as i64,
1340 enabled,
1341 onchange: move |event: dioxus_core::Event<f64>| {
1342 on_change.call((*event.data() as i64).max(0) as usize)
1343 },
1344 {children}
1345 }
1346 }
1347}
1348
1349#[component]
1356pub fn Checkbox(
1357 #[props(default)] weight: Option<f32>,
1358 #[props(default)] width: Option<f32>,
1359 #[props(default)] height: Option<f32>,
1360 #[props(default)] padding: Option<f32>,
1361 #[props(default)] padding_role: Option<SpaceRole>,
1362 #[props(default)] background: Option<Paint>,
1363 #[props(default)] shape_role: Option<ShapeRole>,
1364 #[props(default)] corner_radius: Option<f32>,
1365 #[props(default)] border_width: Option<f32>,
1366 #[props(default)] border_color: Option<Paint>,
1367 #[props(default)] elevation: Option<f32>,
1368 #[props(default)] fill_max_width: bool,
1369 #[props(default)] fill_max_height: bool,
1370 #[props(default)] checked: bool,
1371 #[props(default = true)] enabled: bool,
1372 #[props(default)] on_change: EventHandler<bool>,
1373) -> Element {
1374 rsx! {
1375 checkbox {
1376 weight: opt_dp(weight),
1377 width: opt_dp(width),
1378 height: opt_dp(height),
1379 padding: opt_dp(padding),
1380 padding_role: opt_role(padding_role),
1381 background: opt_paint(background),
1382 shape_role: opt_role(shape_role),
1383 corner_radius: opt_dp(corner_radius),
1384 border_width: opt_dp(border_width),
1385 border_color: opt_paint(border_color),
1386 elevation: opt_dp(elevation),
1387 fill_max_width,
1388 fill_max_height,
1389 checked,
1390 enabled,
1391 onchange: move |event: dioxus_core::Event<f64>| on_change.call(is_on(*event.data())),
1392 }
1393 }
1394}
1395
1396#[component]
1403pub fn RadioButton(
1404 #[props(default)] weight: Option<f32>,
1405 #[props(default)] width: Option<f32>,
1406 #[props(default)] height: Option<f32>,
1407 #[props(default)] padding: Option<f32>,
1408 #[props(default)] padding_role: Option<SpaceRole>,
1409 #[props(default)] background: Option<Paint>,
1410 #[props(default)] shape_role: Option<ShapeRole>,
1411 #[props(default)] corner_radius: Option<f32>,
1412 #[props(default)] border_width: Option<f32>,
1413 #[props(default)] border_color: Option<Paint>,
1414 #[props(default)] elevation: Option<f32>,
1415 #[props(default)] fill_max_width: bool,
1416 #[props(default)] fill_max_height: bool,
1417 #[props(default)] selected: bool,
1418 #[props(default = true)] enabled: bool,
1419 #[props(default)] on_change: EventHandler<bool>,
1420) -> Element {
1421 rsx! {
1422 radiobutton {
1423 weight: opt_dp(weight),
1424 width: opt_dp(width),
1425 height: opt_dp(height),
1426 padding: opt_dp(padding),
1427 padding_role: opt_role(padding_role),
1428 background: opt_paint(background),
1429 shape_role: opt_role(shape_role),
1430 corner_radius: opt_dp(corner_radius),
1431 border_width: opt_dp(border_width),
1432 border_color: opt_paint(border_color),
1433 elevation: opt_dp(elevation),
1434 fill_max_width,
1435 fill_max_height,
1436 checked: selected,
1437 enabled,
1438 onchange: move |event: dioxus_core::Event<f64>| on_change.call(is_on(*event.data())),
1439 }
1440 }
1441}
1442
1443#[component]
1446pub fn Switch(
1447 #[props(default)] weight: Option<f32>,
1448 #[props(default)] width: Option<f32>,
1449 #[props(default)] height: Option<f32>,
1450 #[props(default)] padding: Option<f32>,
1451 #[props(default)] padding_role: Option<SpaceRole>,
1452 #[props(default)] background: Option<Paint>,
1453 #[props(default)] shape_role: Option<ShapeRole>,
1454 #[props(default)] corner_radius: Option<f32>,
1455 #[props(default)] border_width: Option<f32>,
1456 #[props(default)] border_color: Option<Paint>,
1457 #[props(default)] elevation: Option<f32>,
1458 #[props(default)] fill_max_width: bool,
1459 #[props(default)] fill_max_height: bool,
1460 #[props(default)] checked: bool,
1461 #[props(default = true)] enabled: bool,
1462 #[props(default)] on_change: EventHandler<bool>,
1463) -> Element {
1464 rsx! {
1465 switch {
1466 weight: opt_dp(weight),
1467 width: opt_dp(width),
1468 height: opt_dp(height),
1469 padding: opt_dp(padding),
1470 padding_role: opt_role(padding_role),
1471 background: opt_paint(background),
1472 shape_role: opt_role(shape_role),
1473 corner_radius: opt_dp(corner_radius),
1474 border_width: opt_dp(border_width),
1475 border_color: opt_paint(border_color),
1476 elevation: opt_dp(elevation),
1477 fill_max_width,
1478 fill_max_height,
1479 checked,
1480 enabled,
1481 onchange: move |event: dioxus_core::Event<f64>| on_change.call(is_on(*event.data())),
1482 }
1483 }
1484}
1485
1486#[component]
1493pub fn Slider(
1494 #[props(default)] weight: Option<f32>,
1495 #[props(default)] width: Option<f32>,
1496 #[props(default)] height: Option<f32>,
1497 #[props(default)] padding: Option<f32>,
1498 #[props(default)] padding_role: Option<SpaceRole>,
1499 #[props(default)] background: Option<Paint>,
1500 #[props(default)]
1506 color: Option<Paint>,
1507 #[props(default)] shape_role: Option<ShapeRole>,
1508 #[props(default)] corner_radius: Option<f32>,
1509 #[props(default)] border_width: Option<f32>,
1510 #[props(default)] border_color: Option<Paint>,
1511 #[props(default)] elevation: Option<f32>,
1512 #[props(default)] fill_max_width: bool,
1513 #[props(default)] fill_max_height: bool,
1514 #[props(default)] value: f32,
1515 #[props(default = 0.0)] min: f32,
1516 #[props(default = 1.0)] max: f32,
1517 #[props(default)] steps: u32,
1518 #[props(default = true)] enabled: bool,
1519 #[props(default)] on_change: EventHandler<f32>,
1520) -> Element {
1521 rsx! {
1522 slider {
1523 weight: opt_dp(weight),
1524 width: opt_dp(width),
1525 height: opt_dp(height),
1526 padding: opt_dp(padding),
1527 padding_role: opt_role(padding_role),
1528 background: opt_paint(background),
1529 color: opt_paint(color),
1530 shape_role: opt_role(shape_role),
1531 corner_radius: opt_dp(corner_radius),
1532 border_width: opt_dp(border_width),
1533 border_color: opt_paint(border_color),
1534 elevation: opt_dp(elevation),
1535 fill_max_width,
1536 fill_max_height,
1537 value: f64::from(value),
1538 min: f64::from(min),
1539 max: f64::from(max),
1540 steps: i64::from(steps),
1541 enabled,
1542 onchange: move |event: dioxus_core::Event<f64>| on_change.call(*event.data() as f32),
1543 }
1544 }
1545}
1546
1547#[component]
1553pub fn ProgressIndicator(
1554 #[props(default)] weight: Option<f32>,
1555 #[props(default)] width: Option<f32>,
1556 #[props(default)] height: Option<f32>,
1557 #[props(default)] padding: Option<f32>,
1558 #[props(default)] padding_role: Option<SpaceRole>,
1559 #[props(default)] background: Option<Paint>,
1560 #[props(default)] shape_role: Option<ShapeRole>,
1561 #[props(default)] corner_radius: Option<f32>,
1562 #[props(default)] border_width: Option<f32>,
1563 #[props(default)] border_color: Option<Paint>,
1564 #[props(default)] elevation: Option<f32>,
1565 #[props(default)] fill_max_width: bool,
1566 #[props(default)] fill_max_height: bool,
1567 #[props(default)] value: f32,
1568 #[props(default = true)] determinate: bool,
1569 #[props(default)] circular: bool,
1570) -> Element {
1571 rsx! {
1572 progressindicator {
1573 weight: opt_dp(weight),
1574 width: opt_dp(width),
1575 height: opt_dp(height),
1576 padding: opt_dp(padding),
1577 padding_role: opt_role(padding_role),
1578 background: opt_paint(background),
1579 shape_role: opt_role(shape_role),
1580 corner_radius: opt_dp(corner_radius),
1581 border_width: opt_dp(border_width),
1582 border_color: opt_paint(border_color),
1583 elevation: opt_dp(elevation),
1584 fill_max_width,
1585 fill_max_height,
1586 value: f64::from(value),
1587 determinate,
1588 circular,
1589 }
1590 }
1591}
1592
1593#[component]
1596pub fn Divider(
1597 #[props(default)] weight: Option<f32>,
1598 #[props(default)] width: Option<f32>,
1599 #[props(default)] height: Option<f32>,
1600 #[props(default)] padding: Option<f32>,
1601 #[props(default)] padding_role: Option<SpaceRole>,
1602 #[props(default)] background: Option<Paint>,
1603 #[props(default)] shape_role: Option<ShapeRole>,
1604 #[props(default)] corner_radius: Option<f32>,
1605 #[props(default)] border_width: Option<f32>,
1606 #[props(default)] border_color: Option<Paint>,
1607 #[props(default)] elevation: Option<f32>,
1608 #[props(default)] fill_max_width: bool,
1609 #[props(default)] fill_max_height: bool,
1610 #[props(default)] vertical: bool,
1611) -> Element {
1612 rsx! {
1613 divider {
1614 weight: opt_dp(weight),
1615 width: opt_dp(width),
1616 height: opt_dp(height),
1617 padding: opt_dp(padding),
1618 padding_role: opt_role(padding_role),
1619 background: opt_paint(background),
1620 shape_role: opt_role(shape_role),
1621 corner_radius: opt_dp(corner_radius),
1622 border_width: opt_dp(border_width),
1623 border_color: opt_paint(border_color),
1624 elevation: opt_dp(elevation),
1625 fill_max_width,
1626 fill_max_height,
1627 vertical,
1628 }
1629 }
1630}
1631
1632fn is_on(value: f64) -> bool {
1637 value != 0.0
1638}
1639
1640#[component]
1658pub fn Navigation(
1659 #[props(default)] weight: Option<f32>,
1660 #[props(default)] width: Option<f32>,
1661 #[props(default)] height: Option<f32>,
1662 #[props(default)] padding: Option<f32>,
1663 #[props(default)] padding_role: Option<SpaceRole>,
1664 #[props(default)] background: Option<Paint>,
1665 #[props(default)] shape_role: Option<ShapeRole>,
1666 #[props(default)] corner_radius: Option<f32>,
1667 #[props(default)] border_width: Option<f32>,
1668 #[props(default)] border_color: Option<Paint>,
1669 #[props(default)] elevation: Option<f32>,
1670 #[props(default)] fill_max_width: bool,
1671 #[props(default)] fill_max_height: bool,
1672 #[props(default)] selected_index: usize,
1673 #[props(default)]
1678 head: Option<Element>,
1679 #[props(default)]
1681 foot: Option<Element>,
1682 children: Element,
1683) -> Element {
1684 rsx! {
1685 navigation {
1686 weight: opt_dp(weight),
1687 width: opt_dp(width),
1688 height: opt_dp(height),
1689 padding: opt_dp(padding),
1690 padding_role: opt_role(padding_role),
1691 background: opt_paint(background),
1692 shape_role: opt_role(shape_role),
1693 corner_radius: opt_dp(corner_radius),
1694 border_width: opt_dp(border_width),
1695 border_color: opt_paint(border_color),
1696 elevation: opt_dp(elevation),
1697 fill_max_width,
1698 fill_max_height,
1699 selected_index: selected_index as i64,
1700 if let Some(head) = head {
1703 scaffoldslot { slot: i64::from(u16::from(SlotRole::TopBar)), {head} }
1704 }
1705 if let Some(foot) = foot {
1706 scaffoldslot { slot: i64::from(u16::from(SlotRole::BottomBar)), {foot} }
1707 }
1708 {children}
1709 }
1710 }
1711}
1712
1713#[component]
1724pub fn NavigationItem(
1725 #[props(default)] weight: Option<f32>,
1726 #[props(default)] width: Option<f32>,
1727 #[props(default)] height: Option<f32>,
1728 #[props(default)] padding: Option<f32>,
1729 #[props(default)] padding_role: Option<SpaceRole>,
1730 #[props(default)] background: Option<Paint>,
1731 #[props(default)] shape_role: Option<ShapeRole>,
1732 #[props(default)] corner_radius: Option<f32>,
1733 #[props(default)] border_width: Option<f32>,
1734 #[props(default)] border_color: Option<Paint>,
1735 #[props(default)] elevation: Option<f32>,
1736 #[props(default)] fill_max_width: bool,
1737 #[props(default)] fill_max_height: bool,
1738 #[props(default)] text: String,
1739 #[props(default)] icon: Option<IconRole>,
1740 #[props(default)]
1747 color: Option<Paint>,
1748 #[props(default = true)] enabled: bool,
1749 #[props(default)]
1755 section: Option<String>,
1756 #[props(default)] on_click: EventHandler<()>,
1757) -> Element {
1758 rsx! {
1759 navigationitem {
1760 weight: opt_dp(weight),
1761 width: opt_dp(width),
1762 height: opt_dp(height),
1763 padding: opt_dp(padding),
1764 padding_role: opt_role(padding_role),
1765 background: opt_paint(background),
1766 shape_role: opt_role(shape_role),
1767 corner_radius: opt_dp(corner_radius),
1768 border_width: opt_dp(border_width),
1769 border_color: opt_paint(border_color),
1770 elevation: opt_dp(elevation),
1771 fill_max_width,
1772 fill_max_height,
1773 text,
1774 icon: opt_role(icon),
1775 color: opt_paint(color),
1776 enabled,
1777 section,
1778 onclick: move |_| on_click.call(()),
1779 }
1780 }
1781}
1782
1783#[component]
1796pub fn Sheet(
1797 #[props(default)] weight: Option<f32>,
1798 #[props(default)] width: Option<f32>,
1799 #[props(default)] height: Option<f32>,
1800 #[props(default)] padding: Option<f32>,
1801 #[props(default)] padding_role: Option<SpaceRole>,
1802 #[props(default)] background: Option<Paint>,
1803 #[props(default)] shape_role: Option<ShapeRole>,
1804 #[props(default)] corner_radius: Option<f32>,
1805 #[props(default)] border_width: Option<f32>,
1806 #[props(default)] border_color: Option<Paint>,
1807 #[props(default)] elevation: Option<f32>,
1808 #[props(default)] fill_max_width: bool,
1809 #[props(default)] fill_max_height: bool,
1810 #[props(default)] open: bool,
1811 #[props(default)] on_dismiss: EventHandler<()>,
1812 children: Element,
1813) -> Element {
1814 rsx! {
1815 sheet {
1816 weight: opt_dp(weight),
1817 width: opt_dp(width),
1818 height: opt_dp(height),
1819 padding: opt_dp(padding),
1820 padding_role: opt_role(padding_role),
1821 background: opt_paint(background),
1822 shape_role: opt_role(shape_role),
1823 corner_radius: opt_dp(corner_radius),
1824 border_width: opt_dp(border_width),
1825 border_color: opt_paint(border_color),
1826 elevation: opt_dp(elevation),
1827 fill_max_width,
1828 fill_max_height,
1829 open,
1830 ondismiss: move |_| on_dismiss.call(()),
1831 {children}
1832 }
1833 }
1834}
1835
1836#[component]
1865pub fn Scaffold(
1866 #[props(default)]
1871 background: Option<Paint>,
1872 #[props(default)]
1880 material: Option<MaterialRole>,
1881 #[props(default)]
1883 top_bar: Option<Element>,
1884 #[props(default)]
1886 bottom_bar: Option<Element>,
1887 #[props(default)]
1889 floating_action: Option<Element>,
1890 children: Element,
1892) -> Element {
1893 rsx! {
1894 scaffold {
1895 background: opt_paint(background),
1896 material: opt_role(material),
1897 if let Some(bar) = top_bar {
1898 scaffoldslot { slot: i64::from(u16::from(SlotRole::TopBar)), {bar} }
1899 }
1900 if let Some(bar) = bottom_bar {
1901 scaffoldslot { slot: i64::from(u16::from(SlotRole::BottomBar)), {bar} }
1902 }
1903 if let Some(action) = floating_action {
1904 scaffoldslot {
1905 slot: i64::from(u16::from(SlotRole::FloatingAction)),
1906 {action}
1907 }
1908 }
1909 scaffoldslot { slot: i64::from(u16::from(SlotRole::Content)), {children} }
1910 }
1911 }
1912}
1913
1914#[component]
1928pub fn LazyGrid(
1929 #[props(default)] weight: Option<f32>,
1930 #[props(default)] width: Option<f32>,
1931 #[props(default)] height: Option<f32>,
1932 #[props(default)] padding: Option<f32>,
1933 #[props(default)] padding_role: Option<SpaceRole>,
1934 #[props(default)] background: Option<Paint>,
1935 #[props(default)] shape_role: Option<ShapeRole>,
1936 #[props(default)] corner_radius: Option<f32>,
1937 #[props(default)] border_width: Option<f32>,
1938 #[props(default)] border_color: Option<Paint>,
1939 #[props(default)] elevation: Option<f32>,
1940 #[props(default)] fill_max_width: bool,
1941 #[props(default)] fill_max_height: bool,
1942 #[props(default)]
1944 columns: Option<u32>,
1945 #[props(default)]
1947 min_column_width: Option<f32>,
1948 item_count: usize,
1949 #[props(default)] key_of: Option<Callback<usize, String>>,
1950 item: Callback<usize, Element>,
1951) -> Element {
1952 let mut range = use_signal(|| (0_usize, 0_usize));
1953 let (start, count) = range();
1954 let first = start.min(item_count);
1955 let last = first.saturating_add(count).min(item_count);
1956 rsx! {
1957 lazygrid {
1958 weight: opt_dp(weight),
1959 width: opt_dp(width),
1960 height: opt_dp(height),
1961 padding: opt_dp(padding),
1962 padding_role: opt_role(padding_role),
1963 background: opt_paint(background),
1964 shape_role: opt_role(shape_role),
1965 corner_radius: opt_dp(corner_radius),
1966 border_width: opt_dp(border_width),
1967 border_color: opt_paint(border_color),
1968 elevation: opt_dp(elevation),
1969 fill_max_width,
1970 fill_max_height,
1971 item_count: item_count as i64,
1972 columns: columns.map(i64::from),
1973 min_column_width: min_column_width.map(f64::from),
1974 onrangerequest: move |event: dioxus_core::Event<RangeRequest>| {
1975 let requested = event.data();
1976 range.set((requested.start(), requested.count()));
1977 },
1978 for index in first..last {
1979 {
1980 let item_key = key_of
1981 .map_or_else(|| index.to_string(), |key_of| key_of.call(index));
1982 rsx! {
1983 composebox { key: "{item_key}", item_key, {item.call(index)} }
1984 }
1985 }
1986 }
1987 }
1988 }
1989}
1990
1991#[component]
2001pub fn FileDropTarget(
2002 #[props(default)] weight: Option<f32>,
2003 #[props(default)] width: Option<f32>,
2004 #[props(default)] height: Option<f32>,
2005 #[props(default)] padding: Option<f32>,
2006 #[props(default)] padding_role: Option<SpaceRole>,
2007 #[props(default)] background: Option<Paint>,
2008 #[props(default)] shape_role: Option<ShapeRole>,
2009 #[props(default)] corner_radius: Option<f32>,
2010 #[props(default)] border_width: Option<f32>,
2011 #[props(default)] border_color: Option<Paint>,
2012 #[props(default)] elevation: Option<f32>,
2013 #[props(default)] fill_max_width: bool,
2014 #[props(default)] fill_max_height: bool,
2015 #[props(default)] alignment: Option<Alignment>,
2016 #[props(default)]
2020 on_files_entered: EventHandler<()>,
2021 #[props(default)]
2023 on_files_dropped: EventHandler<FileDrop>,
2024 children: Element,
2025) -> Element {
2026 rsx! {
2027 filedroptarget {
2028 weight: opt_dp(weight),
2029 width: opt_dp(width),
2030 height: opt_dp(height),
2031 padding: opt_dp(padding),
2032 padding_role: opt_role(padding_role),
2033 background: opt_paint(background),
2034 shape_role: opt_role(shape_role),
2035 corner_radius: opt_dp(corner_radius),
2036 border_width: opt_dp(border_width),
2037 border_color: opt_paint(border_color),
2038 elevation: opt_dp(elevation),
2039 fill_max_width,
2040 fill_max_height,
2041 alignment: opt_role(alignment),
2042 onfilesentered: move |_: dioxus_core::Event<()>| on_files_entered.call(()),
2043 onfilesdropped: move |event: dioxus_core::Event<FileDrop>| {
2044 on_files_dropped.call(event.data().as_ref().clone());
2045 },
2046 {children}
2047 }
2048 }
2049}
2050
2051#[component]
2067pub fn Badge(
2068 #[props(default)] weight: Option<f32>,
2069 #[props(default)] width: Option<f32>,
2070 #[props(default)] height: Option<f32>,
2071 #[props(default)] padding: Option<f32>,
2072 #[props(default)] padding_role: Option<SpaceRole>,
2073 #[props(default)] background: Option<Paint>,
2074 #[props(default)] shape_role: Option<ShapeRole>,
2075 #[props(default)] corner_radius: Option<f32>,
2076 #[props(default)] border_width: Option<f32>,
2077 #[props(default)] border_color: Option<Paint>,
2078 #[props(default)] elevation: Option<f32>,
2079 #[props(default)] fill_max_width: bool,
2080 #[props(default)] fill_max_height: bool,
2081 #[props(default)]
2084 value: Option<u32>,
2085 #[props(default)]
2087 text: Option<String>,
2088 #[props(default)]
2090 color: Option<ColorRole>,
2091 #[props(default)] children: Element,
2092) -> Element {
2093 rsx! {
2094 badge {
2095 weight: opt_dp(weight),
2096 width: opt_dp(width),
2097 height: opt_dp(height),
2098 padding: opt_dp(padding),
2099 padding_role: opt_role(padding_role),
2100 background: opt_paint(background),
2101 shape_role: opt_role(shape_role),
2102 corner_radius: opt_dp(corner_radius),
2103 border_width: opt_dp(border_width),
2104 border_color: opt_paint(border_color),
2105 elevation: opt_dp(elevation),
2106 fill_max_width,
2107 fill_max_height,
2108 count: value.map(i64::from),
2109 text,
2110 color: opt_paint(color.map(Paint::Role)),
2111 {children}
2112 }
2113 }
2114}
2115
2116#[component]
2131pub fn SelectionContainer(
2132 #[props(default)] weight: Option<f32>,
2133 #[props(default)] width: Option<f32>,
2134 #[props(default)] height: Option<f32>,
2135 #[props(default)] padding: Option<f32>,
2136 #[props(default)] padding_role: Option<SpaceRole>,
2137 #[props(default)] background: Option<Paint>,
2138 #[props(default)] shape_role: Option<ShapeRole>,
2139 #[props(default)] corner_radius: Option<f32>,
2140 #[props(default)] border_width: Option<f32>,
2141 #[props(default)] border_color: Option<Paint>,
2142 #[props(default)] elevation: Option<f32>,
2143 #[props(default)] fill_max_width: bool,
2144 #[props(default)] fill_max_height: bool,
2145 children: Element,
2146) -> Element {
2147 rsx! {
2148 selectioncontainer {
2149 weight: opt_dp(weight),
2150 width: opt_dp(width),
2151 height: opt_dp(height),
2152 padding: opt_dp(padding),
2153 padding_role: opt_role(padding_role),
2154 background: opt_paint(background),
2155 shape_role: opt_role(shape_role),
2156 corner_radius: opt_dp(corner_radius),
2157 border_width: opt_dp(border_width),
2158 border_color: opt_paint(border_color),
2159 elevation: opt_dp(elevation),
2160 fill_max_width,
2161 fill_max_height,
2162 {children}
2163 }
2164 }
2165}