smudge_text/style.rs
1//! The text style that widgets inherit through reactive context.
2//!
3//! There is no cascade: a widget that wants something other than the ambient
4//! style states it explicitly at mount. The style is provided under the
5//! current reactive owner with [`provide_text_style`] and read by descendants
6//! with [`current_text_style`].
7
8use parley::FontWeight;
9use smudge_core::reactive::{provide_context, use_context};
10use smudge_core::theme::{ColorToken, ColorValue};
11
12/// How a text widget lays out and paints its text.
13#[derive(Clone, Debug, PartialEq)]
14pub struct TextStyle {
15 /// The font family to resolve, named or generic.
16 pub family: parley::FontFamily<'static>,
17 /// The font size in logical pixels.
18 pub size: f32,
19 /// The weight the family is matched with.
20 pub weight: FontWeight,
21 /// The line height as a multiple of the font size.
22 pub line_height: f32,
23 /// The color the glyphs paint with, which may name a theme token and
24 /// resolves when the widget paints.
25 pub color: ColorValue,
26}
27
28impl Default for TextStyle {
29 fn default() -> Self {
30 TextStyle {
31 family: parley::FontFamily::named(crate::fonts::SANS_FAMILY),
32 size: 14.0,
33 weight: FontWeight::NORMAL,
34 line_height: 1.3,
35 color: ColorValue::Token(ColorToken::TEXT),
36 }
37 }
38}
39
40/// Provides the text style that widgets created under the current owner read.
41///
42/// A later call on an ancestor does not reach widgets that already read the
43/// style, because text styles are read once at mount.
44pub fn provide_text_style(style: TextStyle) {
45 provide_context(style);
46}
47
48/// Returns the text style of the closest ancestor that called
49/// [`provide_text_style`], or [`TextStyle::default`] when none did.
50pub fn current_text_style() -> TextStyle {
51 use_context::<TextStyle>().unwrap_or_default()
52}