repose_material/material3/
surface.rs1#![allow(non_snake_case)]
2
3use std::rc::Rc;
4
5use repose_core::*;
6use repose_ui::{
7 Box, TextStyle,
8 ViewExt,
9};
10
11use super::*;
12
13#[derive(Clone, Debug)]
15pub struct SurfaceConfig {
16 pub modifier: Modifier,
17 pub enabled: bool,
18 pub color: Color,
19 pub content_color: Color,
20 pub shape_radius: f32,
21 pub tonal_elevation: f32,
22 pub shadow_elevation: f32,
23 pub border: Option<(f32, Color)>,
24 pub interaction_source: Option<MutableInteractionSource>,
25}
26
27impl Default for SurfaceConfig {
28 fn default() -> Self {
29 Self {
30 modifier: Modifier::new(),
31 enabled: true,
32 color: SurfaceDefaults::color(),
33 content_color: SurfaceDefaults::content_color(),
34 shape_radius: SurfaceDefaults::SHAPE_RADIUS,
35 tonal_elevation: SurfaceDefaults::TONAL_ELEVATION,
36 shadow_elevation: SurfaceDefaults::SHADOW_ELEVATION,
37 border: None,
38 interaction_source: None,
39 }
40 }
41}
42
43pub fn Surface(config: SurfaceConfig, content: impl FnOnce() -> View) -> View {
46 let sf_source: Rc<MutableInteractionSource> = config
47 .interaction_source
48 .clone()
49 .map(Rc::new)
50 .unwrap_or_else(|| remember(MutableInteractionSource::new));
51 let mut m = Modifier::new()
52 .background(config.color)
53 .clip_rounded(config.shape_radius)
54 .interaction_source(&*sf_source)
55 .then(config.modifier);
56 if config.tonal_elevation > 0.0 {
57 m = m.state_elevation(StateElevation {
58 default: config.tonal_elevation,
59 hovered: config.tonal_elevation,
60 pressed: config.tonal_elevation,
61 disabled: 0.0,
62 });
63 }
64 if config.shadow_elevation > 0.0 {
65 m = m.shadow(config.shadow_elevation, 0.0);
66 }
67 if let Some((w, c)) = config.border {
68 m = m.border(w, c, config.shape_radius);
69 }
70 Box(m).color(config.content_color).child(content())
71}