dioxus_ui_system/
config.rs1use std::sync::{Mutex, OnceLock};
22
23#[derive(Clone, Debug, Default)]
25pub struct Config {
26 pub button_size: Option<String>,
28 pub button_variant: Option<String>,
30 pub card_padding: Option<String>,
32 pub input_size: Option<String>,
34 pub spacing_unit: Option<u8>,
36 pub border_radius: Option<String>,
38 pub enable_transitions: bool,
40}
41
42impl Config {
43 pub fn new() -> Self {
45 Self {
46 enable_transitions: true,
47 ..Default::default()
48 }
49 }
50
51 pub fn with_button_size(mut self, size: impl Into<String>) -> Self {
53 self.button_size = Some(size.into());
54 self
55 }
56
57 pub fn with_button_variant(mut self, variant: impl Into<String>) -> Self {
59 self.button_variant = Some(variant.into());
60 self
61 }
62
63 pub fn with_card_padding(mut self, padding: impl Into<String>) -> Self {
65 self.card_padding = Some(padding.into());
66 self
67 }
68
69 pub fn with_input_size(mut self, size: impl Into<String>) -> Self {
71 self.input_size = Some(size.into());
72 self
73 }
74
75 pub fn with_spacing_unit(mut self, unit: u8) -> Self {
77 self.spacing_unit = Some(unit);
78 self
79 }
80
81 pub fn with_border_radius(mut self, radius: impl Into<String>) -> Self {
83 self.border_radius = Some(radius.into());
84 self
85 }
86
87 pub fn with_transitions(mut self, enabled: bool) -> Self {
89 self.enable_transitions = enabled;
90 self
91 }
92}
93
94static GLOBAL_CONFIG: OnceLock<Mutex<Config>> = OnceLock::new();
96
97pub fn global_config() -> std::sync::MutexGuard<'static, Config> {
99 GLOBAL_CONFIG
100 .get_or_init(|| Mutex::new(Config::new()))
101 .lock()
102 .expect("Config mutex poisoned")
103}
104
105pub fn set_global_config(config: Config) {
107 let mut global = global_config();
108 *global = config;
109}
110
111pub struct ComponentConfig;
115
116impl ComponentConfig {
117 pub fn builder() -> ConfigBuilder {
119 ConfigBuilder::new()
120 }
121
122 pub fn reset() {
124 set_global_config(Config::new());
125 }
126}
127
128#[derive(Clone, Debug, Default)]
130pub struct ConfigBuilder {
131 config: Config,
132}
133
134impl ConfigBuilder {
135 pub fn new() -> Self {
137 Self {
138 config: Config::new(),
139 }
140 }
141
142 pub fn build(self) {
144 set_global_config(self.config);
145 }
146
147 pub fn button_size(mut self, size: impl Into<String>) -> Self {
149 self.config.button_size = Some(size.into());
150 self
151 }
152
153 pub fn button_variant(mut self, variant: impl Into<String>) -> Self {
155 self.config.button_variant = Some(variant.into());
156 self
157 }
158
159 pub fn card_padding(mut self, padding: impl Into<String>) -> Self {
161 self.config.card_padding = Some(padding.into());
162 self
163 }
164
165 pub fn input_size(mut self, size: impl Into<String>) -> Self {
167 self.config.input_size = Some(size.into());
168 self
169 }
170
171 pub fn spacing_unit(mut self, unit: u8) -> Self {
173 self.config.spacing_unit = Some(unit);
174 self
175 }
176
177 pub fn border_radius(mut self, radius: impl Into<String>) -> Self {
179 self.config.border_radius = Some(radius.into());
180 self
181 }
182
183 pub fn transitions(mut self, enabled: bool) -> Self {
185 self.config.enable_transitions = enabled;
186 self
187 }
188}
189
190pub trait ConfigurableComponent {
192 fn component_type() -> &'static str;
194
195 fn apply_defaults(props: &mut Self);
197}
198
199#[macro_export]
201macro_rules! config_or_default {
202 ($config_field:expr, $default:expr) => {
203 $config_field
204 .as_ref()
205 .map(|s| s.as_str())
206 .unwrap_or($default)
207 };
208}