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