Skip to content

Commit

Permalink
feat: add material_ui composable
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Dec 9, 2024
1 parent 68d44a2 commit 5dad9a3
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 21 deletions.
14 changes: 8 additions & 6 deletions examples/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ impl Compose for BreedList {
SignalMut::set(breeds, json.message);
});

// Render the currently loaded breeds.
scroll_view(compose::from_iter((*breeds).clone(), |breed| Breed {
name: breed.0.clone(),
families: breed.1.clone(),
}))
.flex_gap(Val::Px(30.))
material_ui(
// Render the currently loaded breeds.
scroll_view(compose::from_iter((*breeds).clone(), |breed| Breed {
name: breed.0.clone(),
families: breed.1.clone(),
}))
.flex_gap(Val::Px(30.)),
)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ pub mod prelude {
#[cfg(feature = "material")]
#[cfg_attr(docsrs, doc(cfg(feature = "material")))]
pub use crate::ui::material::{
button, container, radio_button, text, Button, MaterialTheme, RadioButton, TypographyKind,
TypographyStyleKind,
button, container, material_ui, radio_button, text, Button, MaterialUi, RadioButton, Theme,
TypographyKind, TypographyStyleKind,
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/ui/material/button.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{container, MaterialTheme};
use super::{container, Theme};
use crate::{
compose::Compose,
ecs::{Modifier, Modify},
Expand Down Expand Up @@ -53,7 +53,7 @@ impl<'a, C> Button<'a, C> {

impl<C: Compose> Compose for Button<'_, C> {
fn compose(cx: Scope<Self>) -> impl Compose {
let theme = use_context::<MaterialTheme>(&cx)
let theme = use_context::<Theme>(&cx)
.cloned()
.unwrap_or_default();

Expand Down
4 changes: 2 additions & 2 deletions src/ui/material/container.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::MaterialTheme;
use super::Theme;
use crate::{
compose::Compose,
ecs::spawn,
Expand Down Expand Up @@ -67,7 +67,7 @@ impl<'a, C> Container<'a, C> {

impl<C: Compose> Compose for Container<'_, C> {
fn compose(cx: Scope<Self>) -> impl Compose {
let theme = use_context::<MaterialTheme>(&cx)
let theme = use_context::<Theme>(&cx)
.cloned()
.unwrap_or_default();

Expand Down
21 changes: 16 additions & 5 deletions src/ui/material/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::ops::Index;

use bevy_color::Color;
use std::ops::Index;

mod button;
pub use self::button::{button, Button};
Expand All @@ -11,11 +10,18 @@ pub use self::container::{container, Container};
mod radio;
pub use self::radio::{radio_button, RadioButton};

mod ui;
pub use self::ui::{material_ui, MaterialUi};

/// Text composables.
pub mod text;

/// Colors for a [`MaterialTheme`].
#[derive(Clone, PartialEq)]
pub struct Colors {
/// Background color.
pub background: Color,

/// Primary color.
pub primary: Color,

Expand All @@ -27,6 +33,7 @@ pub struct Colors {
}

/// Typography style.
#[derive(Clone, PartialEq)]
pub struct TypographyStyle {
/// Font size.
pub font_size: f32,
Expand All @@ -39,7 +46,7 @@ pub struct TypographyStyle {
}

/// Typography style kind.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TypographyStyleKind {
/// Small typography style.
Small,
Expand All @@ -52,6 +59,7 @@ pub enum TypographyStyleKind {
}

/// Typography design token.
#[derive(Clone, PartialEq)]
pub struct TypographyToken {
/// Small typography style.
pub small: TypographyStyle,
Expand Down Expand Up @@ -92,6 +100,7 @@ pub enum TypographyKind {
}

/// Typography for a [`MaterialTheme`].
#[derive(Clone, PartialEq)]
pub struct Typography {
/// Body typography.
pub body: TypographyToken,
Expand Down Expand Up @@ -120,18 +129,20 @@ impl Index<TypographyKind> for Typography {
}

/// Material UI theme.
pub struct MaterialTheme {
#[derive(Clone, PartialEq)]
pub struct Theme {
/// Theme colors.
pub colors: Colors,

/// Theme typography.
pub typography: Typography,
}

impl Default for MaterialTheme {
impl Default for Theme {
fn default() -> Self {
Self {
colors: Colors {
background: Color::WHITE,
primary: Color::srgb_u8(103, 80, 164),
surface_container: Color::srgb_u8(230, 224, 233),
text: Color::BLACK,
Expand Down
4 changes: 2 additions & 2 deletions src/ui/material/radio.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::MaterialTheme;
use super::Theme;
use crate::{
compose::Compose,
ecs::spawn,
Expand Down Expand Up @@ -66,7 +66,7 @@ impl RadioButton<'_> {

impl Compose for RadioButton<'_> {
fn compose(cx: Scope<Self>) -> impl Compose {
let theme = use_context::<MaterialTheme>(&cx)
let theme = use_context::<Theme>(&cx)
.cloned()
.unwrap_or_default();

Expand Down
4 changes: 2 additions & 2 deletions src/ui/material/text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{MaterialTheme, TypographyKind, TypographyStyleKind};
use super::{Theme, TypographyKind, TypographyStyleKind};
use crate::{
ecs::{spawn, Modifier, Modify},
prelude::Compose,
Expand Down Expand Up @@ -64,7 +64,7 @@ impl Text<'_> {

impl Compose for Text<'_> {
fn compose(cx: crate::Scope<Self>) -> impl Compose {
let theme = use_context::<MaterialTheme>(&cx)
let theme = use_context::<Theme>(&cx)
.cloned()
.unwrap_or_default();

Expand Down
63 changes: 63 additions & 0 deletions src/ui/material/ui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use super::Theme;
use crate::{
ecs::{spawn, Modifier, Modify},
prelude::Compose,
use_provider, Scope, Signal,
};
use actuate_macros::Data;
use bevy_ui::{BackgroundColor, FlexDirection, Node, Val};

/// Create a material UI composable.
///
/// This will provide a [`Theme`] and set the background for its content.
pub fn material_ui<'a, C: Compose>(content: C) -> MaterialUi<'a, C> {
MaterialUi {
content,
theme: Theme::default(),
modifier: Modifier::default(),
}
}

/// Material UI composable.
///
/// For more see [`material_ui`].
#[derive(Data)]
#[actuate(path = "crate")]
pub struct MaterialUi<'a, C> {
content: C,
theme: Theme,
modifier: Modifier<'a>,
}

impl<'a, C> MaterialUi<'a, C> {
/// Set the theme of this composable.
pub fn theme(mut self, theme: Theme) -> Self {
self.theme = theme;
self
}
}

impl<'a, C: Compose> Compose for MaterialUi<'a, C> {
fn compose(cx: Scope<Self>) -> impl Compose {
let theme = use_provider(&cx, || cx.me().theme.clone());

cx.me()
.modifier
.apply(spawn((
Node {
flex_direction: FlexDirection::Column,
width: Val::Percent(100.),
height: Val::Percent(100.),
..Default::default()
},
BackgroundColor(theme.colors.background),
)))
.content(unsafe { Signal::map_unchecked(cx.me(), |me| &me.content) })
}
}

impl<'a, C> Modify<'a> for MaterialUi<'a, C> {
fn modifier(&mut self) -> &mut Modifier<'a> {
&mut self.modifier
}
}

0 comments on commit 5dad9a3

Please sign in to comment.