photon_ui/theme/mod.rs
1//! The Beam Design Language theme system for photon-ui.
2//!
3//! Provides color palettes, semantic tokens, ANSI rendering, and
4//! composable text styles for terminal UIs.
5//!
6//! # Quick start
7//!
8//! ```
9//! use photon_ui::theme::{
10//! Palette,
11//! Style,
12//! Theme,
13//! stylize,
14//! };
15//!
16//! Theme::set(Theme::Light);
17//! let accent = Theme::palette().accent();
18//! let styled = stylize("Hello", &Style::new().fg(accent).bold());
19//! ```
20//!
21//! # Switching themes on demand
22//!
23//! ```
24//! use photon_ui::theme::{
25//! Palette,
26//! Theme,
27//! };
28//!
29//! Theme::set(Theme::Dark);
30//! assert_eq!(Theme::palette().background().to_hex(), "#1f1f1f");
31//!
32//! Theme::set(Theme::Light);
33//! assert_eq!(Theme::palette().background().to_hex(), "#fffaed");
34//! ```
35//!
36//! # Custom palettes
37//!
38//! Implement [`Palette`] and install it globally with [`Theme::set_palette`].
39//! While installed, components resolve colors through the custom palette
40//! instead of the built-in Light/Dark themes.
41//!
42//! ```
43//! use std::sync::Arc;
44//!
45//! use photon_ui::theme::{
46//! Color,
47//! Palette,
48//! PaletteHandle,
49//! Theme,
50//! };
51//!
52//! #[derive(Debug)]
53//! struct NeonPalette;
54//!
55//! impl Palette for NeonPalette {
56//! fn background(&self) -> Color {
57//! Color::from_hex("#0a0a0a").unwrap()
58//! }
59//!
60//! fn surface(&self) -> Color {
61//! Color::from_hex("#141414").unwrap()
62//! }
63//!
64//! fn field(&self) -> Color {
65//! Color::from_hex("#1e1e1e").unwrap()
66//! }
67//!
68//! fn text(&self) -> Color {
69//! Color::from_hex("#f0f0f0").unwrap()
70//! }
71//!
72//! fn text_muted(&self) -> Color {
73//! Color::from_hex("#888888").unwrap()
74//! }
75//!
76//! fn text_on_accent(&self) -> Color {
77//! Color::from_hex("#ffffff").unwrap()
78//! }
79//!
80//! fn accent(&self) -> Color {
81//! Color::from_hex("#ff00ff").unwrap()
82//! }
83//!
84//! fn accent_hover(&self) -> Color {
85//! Color::from_hex("#ff44ff").unwrap()
86//! }
87//!
88//! fn border(&self) -> Color {
89//! Color::from_hex("#333333").unwrap()
90//! }
91//!
92//! fn border_muted(&self) -> Color {
93//! Color::from_hex("#222222").unwrap()
94//! }
95//!
96//! fn focus(&self) -> Color {
97//! Color::from_hex("#ff00ff").unwrap()
98//! }
99//!
100//! fn success(&self) -> Color {
101//! Color::from_hex("#00ff00").unwrap()
102//! }
103//!
104//! fn warning(&self) -> Color {
105//! Color::from_hex("#ffff00").unwrap()
106//! }
107//!
108//! fn error(&self) -> Color {
109//! Color::from_hex("#ff0000").unwrap()
110//! }
111//!
112//! fn info(&self) -> Color {
113//! Color::from_hex("#00ffff").unwrap()
114//! }
115//! }
116//!
117//! Theme::set_palette(Arc::new(NeonPalette));
118//! assert_eq!(Theme::palette().accent().to_hex(), "#ff00ff");
119//! Theme::clear_palette();
120//! ```
121
122pub mod ansi;
123pub mod color;
124pub mod palette;
125pub mod style;
126
127pub use ansi::{
128 ColorMode,
129 RESET,
130 bg,
131 fg,
132};
133pub use color::Color;
134pub use palette::{
135 Palette,
136 PaletteHandle,
137 Theme,
138};
139pub use style::{
140 Style,
141 stylize,
142 stylize_padded,
143};