1use crate::theme::tokens::{ThemeTokens, Color, SpacingScale, RadiusScale, TypographyScale};
7use std::fmt::Write;
8
9#[derive(Default, Clone)]
27pub struct Style {
28 pub display: Option<String>,
30 pub flex_direction: Option<String>,
31 pub flex_wrap: Option<String>,
32 pub align_items: Option<String>,
33 pub align_self: Option<String>,
34 pub justify_content: Option<String>,
35 pub justify_items: Option<String>,
36 pub gap: Option<String>,
37 pub row_gap: Option<String>,
38 pub column_gap: Option<String>,
39
40 pub padding: Option<String>,
42 pub padding_top: Option<String>,
43 pub padding_right: Option<String>,
44 pub padding_bottom: Option<String>,
45 pub padding_left: Option<String>,
46 pub margin: Option<String>,
47 pub margin_top: Option<String>,
48 pub margin_right: Option<String>,
49 pub margin_bottom: Option<String>,
50 pub margin_left: Option<String>,
51
52 pub background_color: Option<String>,
54 pub color: Option<String>,
55 pub border_color: Option<String>,
56
57 pub font_size: Option<String>,
59 pub font_weight: Option<String>,
60 pub font_family: Option<String>,
61 pub line_height: Option<String>,
62 pub text_align: Option<String>,
63 pub text_decoration: Option<String>,
64 pub letter_spacing: Option<String>,
65
66 pub border_radius: Option<String>,
68 pub border: Option<String>,
69 pub border_top: Option<String>,
70 pub border_right: Option<String>,
71 pub border_bottom: Option<String>,
72 pub border_left: Option<String>,
73 pub border_width: Option<String>,
74 pub box_shadow: Option<String>,
75
76 pub width: Option<String>,
78 pub height: Option<String>,
79 pub min_width: Option<String>,
80 pub min_height: Option<String>,
81 pub max_width: Option<String>,
82 pub max_height: Option<String>,
83
84 pub position: Option<String>,
86 pub top: Option<String>,
87 pub right: Option<String>,
88 pub bottom: Option<String>,
89 pub left: Option<String>,
90 pub z_index: Option<String>,
91
92 pub cursor: Option<String>,
94 pub opacity: Option<String>,
95 pub transition: Option<String>,
96 pub transform: Option<String>,
97 pub overflow: Option<String>,
98 pub visibility: Option<String>,
99 pub pointer_events: Option<String>,
100 pub user_select: Option<String>,
101 pub white_space: Option<String>,
102 pub word_break: Option<String>,
103 pub outline: Option<String>,
104 pub resize: Option<String>,
105}
106
107impl Style {
108 pub fn new() -> Self {
110 Self::default()
111 }
112
113 pub fn flex(mut self) -> Self {
119 self.display = Some("flex".into());
120 self
121 }
122
123 pub fn block(mut self) -> Self {
125 self.display = Some("block".into());
126 self
127 }
128
129 pub fn inline_block(mut self) -> Self {
131 self.display = Some("inline-block".into());
132 self
133 }
134
135 pub fn inline_flex(mut self) -> Self {
137 self.display = Some("inline-flex".into());
138 self
139 }
140
141 pub fn grid(mut self) -> Self {
143 self.display = Some("grid".into());
144 self
145 }
146
147 pub fn hidden(mut self) -> Self {
149 self.display = Some("none".into());
150 self
151 }
152
153 pub fn flex_col(mut self) -> Self {
155 self.flex_direction = Some("column".into());
156 self
157 }
158
159 pub fn flex_row(mut self) -> Self {
161 self.flex_direction = Some("row".into());
162 self
163 }
164
165 pub fn flex_wrap(mut self) -> Self {
167 self.flex_wrap = Some("wrap".into());
168 self
169 }
170
171 pub fn flex_nowrap(mut self) -> Self {
173 self.flex_wrap = Some("nowrap".into());
174 self
175 }
176
177 pub fn items_center(mut self) -> Self {
179 self.align_items = Some("center".into());
180 self
181 }
182
183 pub fn items_start(mut self) -> Self {
185 self.align_items = Some("flex-start".into());
186 self
187 }
188
189 pub fn items_end(mut self) -> Self {
191 self.align_items = Some("flex-end".into());
192 self
193 }
194
195 pub fn items_stretch(mut self) -> Self {
197 self.align_items = Some("stretch".into());
198 self
199 }
200
201 pub fn self_center(mut self) -> Self {
203 self.align_self = Some("center".into());
204 self
205 }
206
207 pub fn justify_center(mut self) -> Self {
209 self.justify_content = Some("center".into());
210 self
211 }
212
213 pub fn justify_start(mut self) -> Self {
215 self.justify_content = Some("flex-start".into());
216 self
217 }
218
219 pub fn justify_end(mut self) -> Self {
221 self.justify_content = Some("flex-end".into());
222 self
223 }
224
225 pub fn justify_between(mut self) -> Self {
227 self.justify_content = Some("space-between".into());
228 self
229 }
230
231 pub fn justify_around(mut self) -> Self {
233 self.justify_content = Some("space-around".into());
234 self
235 }
236
237 pub fn justify_evenly(mut self) -> Self {
239 self.justify_content = Some("space-evenly".into());
240 self
241 }
242
243 pub fn gap(mut self, spacing: &SpacingScale, size: &str) -> Self {
245 let val = spacing.get(size);
246 self.gap = Some(format!("{}px", val));
247 self
248 }
249
250 pub fn gap_px(mut self, px: u16) -> Self {
252 self.gap = Some(format!("{}px", px));
253 self
254 }
255
256 pub fn row_gap(mut self, spacing: &SpacingScale, size: &str) -> Self {
258 let val = spacing.get(size);
259 self.row_gap = Some(format!("{}px", val));
260 self
261 }
262
263 pub fn column_gap(mut self, spacing: &SpacingScale, size: &str) -> Self {
265 let val = spacing.get(size);
266 self.column_gap = Some(format!("{}px", val));
267 self
268 }
269
270 pub fn p(mut self, spacing: &SpacingScale, size: &str) -> Self {
276 let val = spacing.get(size);
277 self.padding = Some(format!("{}px", val));
278 self
279 }
280
281 pub fn p_px(mut self, px: u16) -> Self {
283 self.padding = Some(format!("{}px", px));
284 self
285 }
286
287 pub fn px(mut self, spacing: &SpacingScale, size: &str) -> Self {
289 let val = spacing.get(size);
290 self.padding_left = Some(format!("{}px", val));
291 self.padding_right = Some(format!("{}px", val));
292 self
293 }
294
295 pub fn px_px(mut self, px: u16) -> Self {
297 self.padding_left = Some(format!("{}px", px));
298 self.padding_right = Some(format!("{}px", px));
299 self
300 }
301
302 pub fn py(mut self, spacing: &SpacingScale, size: &str) -> Self {
304 let val = spacing.get(size);
305 self.padding_top = Some(format!("{}px", val));
306 self.padding_bottom = Some(format!("{}px", val));
307 self
308 }
309
310 pub fn py_px(mut self, px: u16) -> Self {
312 self.padding_top = Some(format!("{}px", px));
313 self.padding_bottom = Some(format!("{}px", px));
314 self
315 }
316
317 pub fn pt(mut self, spacing: &SpacingScale, size: &str) -> Self {
319 let val = spacing.get(size);
320 self.padding_top = Some(format!("{}px", val));
321 self
322 }
323
324 pub fn pr(mut self, spacing: &SpacingScale, size: &str) -> Self {
326 let val = spacing.get(size);
327 self.padding_right = Some(format!("{}px", val));
328 self
329 }
330
331 pub fn pb(mut self, spacing: &SpacingScale, size: &str) -> Self {
333 let val = spacing.get(size);
334 self.padding_bottom = Some(format!("{}px", val));
335 self
336 }
337
338 pub fn pl(mut self, spacing: &SpacingScale, size: &str) -> Self {
340 let val = spacing.get(size);
341 self.padding_left = Some(format!("{}px", val));
342 self
343 }
344
345 pub fn pt_px(mut self, px: u16) -> Self {
347 self.padding_top = Some(format!("{}px", px));
348 self
349 }
350
351 pub fn pr_px(mut self, px: u16) -> Self {
353 self.padding_right = Some(format!("{}px", px));
354 self
355 }
356
357 pub fn pb_px(mut self, px: u16) -> Self {
359 self.padding_bottom = Some(format!("{}px", px));
360 self
361 }
362
363 pub fn pl_px(mut self, px: u16) -> Self {
365 self.padding_left = Some(format!("{}px", px));
366 self
367 }
368
369 pub fn m(mut self, spacing: &SpacingScale, size: &str) -> Self {
371 let val = spacing.get(size);
372 self.margin = Some(format!("{}px", val));
373 self
374 }
375
376 pub fn m_px(mut self, px: u16) -> Self {
378 self.margin = Some(format!("{}px", px));
379 self
380 }
381
382 pub fn mx(mut self, spacing: &SpacingScale, size: &str) -> Self {
384 let val = spacing.get(size);
385 self.margin_left = Some(format!("{}px", val));
386 self.margin_right = Some(format!("{}px", val));
387 self
388 }
389
390 pub fn my(mut self, spacing: &SpacingScale, size: &str) -> Self {
392 let val = spacing.get(size);
393 self.margin_top = Some(format!("{}px", val));
394 self.margin_bottom = Some(format!("{}px", val));
395 self
396 }
397
398 pub fn mt(mut self, spacing: &SpacingScale, size: &str) -> Self {
400 let val = spacing.get(size);
401 self.margin_top = Some(format!("{}px", val));
402 self
403 }
404
405 pub fn mr(mut self, spacing: &SpacingScale, size: &str) -> Self {
407 let val = spacing.get(size);
408 self.margin_right = Some(format!("{}px", val));
409 self
410 }
411
412 pub fn mb(mut self, spacing: &SpacingScale, size: &str) -> Self {
414 let val = spacing.get(size);
415 self.margin_bottom = Some(format!("{}px", val));
416 self
417 }
418
419 pub fn mb_px(mut self, px: i16) -> Self {
421 self.margin_bottom = Some(format!("{}px", px));
422 self
423 }
424
425 pub fn ml(mut self, spacing: &SpacingScale, size: &str) -> Self {
427 let val = spacing.get(size);
428 self.margin_left = Some(format!("{}px", val));
429 self
430 }
431
432 pub fn bg(mut self, color: &Color) -> Self {
438 self.background_color = Some(color.to_rgba());
439 self
440 }
441
442 pub fn bg_hex(mut self, hex: &str) -> Self {
444 self.background_color = Some(hex.into());
445 self
446 }
447
448 pub fn text_color(mut self, color: &Color) -> Self {
450 self.color = Some(color.to_rgba());
451 self
452 }
453
454 pub fn text_hex(mut self, hex: &str) -> Self {
456 self.color = Some(hex.into());
457 self
458 }
459
460 pub fn border_color(mut self, color: &Color) -> Self {
462 self.border_color = Some(color.to_rgba());
463 self
464 }
465
466 pub fn text(mut self, typography: &TypographyScale, size: &str) -> Self {
472 let t = typography.get(size);
473 self.font_size = Some(format!("{}px", t.size));
474 self.font_weight = Some(t.weight.to_string());
475 self.font_family = Some(t.family.clone());
476 self.line_height = Some(t.line_height.to_string());
477 if let Some(ls) = t.letter_spacing {
478 self.letter_spacing = Some(format!("{}em", ls));
479 }
480 self
481 }
482
483 pub fn font_size(mut self, size: u16) -> Self {
485 self.font_size = Some(format!("{}px", size));
486 self
487 }
488
489 pub fn font_weight(mut self, weight: u16) -> Self {
491 self.font_weight = Some(weight.to_string());
492 self
493 }
494
495 pub fn font_family(mut self, family: &str) -> Self {
497 self.font_family = Some(family.into());
498 self
499 }
500
501 pub fn line_height(mut self, height: f32) -> Self {
503 self.line_height = Some(height.to_string());
504 self
505 }
506
507 pub fn text_align(mut self, align: &str) -> Self {
509 self.text_align = Some(align.into());
510 self
511 }
512
513 pub fn text_center(mut self) -> Self {
515 self.text_align = Some("center".into());
516 self
517 }
518
519 pub fn text_left(mut self) -> Self {
521 self.text_align = Some("left".into());
522 self
523 }
524
525 pub fn text_right(mut self) -> Self {
527 self.text_align = Some("right".into());
528 self
529 }
530
531 pub fn text_align_left(mut self) -> Self {
533 self.text_align = Some("left".into());
534 self
535 }
536
537 pub fn no_underline(mut self) -> Self {
539 self.text_decoration = Some("none".into());
540 self
541 }
542
543 pub fn underline(mut self) -> Self {
545 self.text_decoration = Some("underline".into());
546 self
547 }
548
549 pub fn rounded(mut self, radius: &RadiusScale, size: &str) -> Self {
555 let val = radius.get(size);
556 self.border_radius = Some(format!("{}px", val));
557 self
558 }
559
560 pub fn rounded_px(mut self, px: u16) -> Self {
562 self.border_radius = Some(format!("{}px", px));
563 self
564 }
565
566 pub fn rounded_full(mut self) -> Self {
568 self.border_radius = Some("9999px".into());
569 self
570 }
571
572 pub fn border(mut self, width: u8, color: &Color) -> Self {
574 self.border = Some(format!("{}px solid {}", width, color.to_rgba()));
575 self
576 }
577
578 pub fn border_width(mut self, width: u8) -> Self {
580 self.border_width = Some(format!("{}px", width));
581 self
582 }
583
584 pub fn border_top(mut self, width: u8, color: &Color) -> Self {
586 self.border_top = Some(format!("{}px solid {}", width, color.to_rgba()));
587 self
588 }
589
590 pub fn border_right(mut self, width: u8, color: &Color) -> Self {
592 self.border_right = Some(format!("{}px solid {}", width, color.to_rgba()));
593 self
594 }
595
596 pub fn border_bottom(mut self, width: u8, color: &Color) -> Self {
598 self.border_bottom = Some(format!("{}px solid {}", width, color.to_rgba()));
599 self
600 }
601
602 pub fn border_left(mut self, width: u8, color: &Color) -> Self {
604 self.border_left = Some(format!("{}px solid {}", width, color.to_rgba()));
605 self
606 }
607
608 pub fn shadow(mut self, shadow: &str) -> Self {
610 self.box_shadow = Some(shadow.into());
611 self
612 }
613
614 pub fn shadow_themed(mut self, theme: &ThemeTokens, size: &str) -> Self {
616 self.box_shadow = Some(theme.shadows.get(size).clone());
617 self
618 }
619
620 pub fn shadow_none(mut self) -> Self {
622 self.box_shadow = Some("none".into());
623 self
624 }
625
626 pub fn w(mut self, width: &str) -> Self {
632 self.width = Some(width.into());
633 self
634 }
635
636 pub fn w_px(mut self, px: u16) -> Self {
638 self.width = Some(format!("{}px", px));
639 self
640 }
641
642 pub fn w_percent(mut self, pct: u8) -> Self {
644 self.width = Some(format!("{}%", pct));
645 self
646 }
647
648 pub fn w_full(mut self) -> Self {
650 self.width = Some("100%".into());
651 self
652 }
653
654 pub fn h(mut self, height: &str) -> Self {
656 self.height = Some(height.into());
657 self
658 }
659
660 pub fn h_px(mut self, px: u16) -> Self {
662 self.height = Some(format!("{}px", px));
663 self
664 }
665
666 pub fn h_percent(mut self, pct: u8) -> Self {
668 self.height = Some(format!("{}%", pct));
669 self
670 }
671
672 pub fn h_full(mut self) -> Self {
674 self.height = Some("100%".into());
675 self
676 }
677
678 pub fn min_w(mut self, width: &str) -> Self {
680 self.min_width = Some(width.into());
681 self
682 }
683
684 pub fn min_w_px(mut self, px: u16) -> Self {
686 self.min_width = Some(format!("{}px", px));
687 self
688 }
689
690 pub fn min_h(mut self, height: &str) -> Self {
692 self.min_height = Some(height.into());
693 self
694 }
695
696 pub fn min_h_px(mut self, px: u16) -> Self {
698 self.min_height = Some(format!("{}px", px));
699 self
700 }
701
702 pub fn max_w(mut self, width: &str) -> Self {
704 self.max_width = Some(width.into());
705 self
706 }
707
708 pub fn max_w_px(mut self, px: u16) -> Self {
710 self.max_width = Some(format!("{}px", px));
711 self
712 }
713
714 pub fn max_h(mut self, height: &str) -> Self {
716 self.max_height = Some(height.into());
717 self
718 }
719
720 pub fn max_h_px(mut self, px: u16) -> Self {
722 self.max_height = Some(format!("{}px", px));
723 self
724 }
725
726 pub fn position(mut self, value: &str) -> Self {
732 self.position = Some(value.into());
733 self
734 }
735
736 pub fn relative(mut self) -> Self {
738 self.position = Some("relative".into());
739 self
740 }
741
742 pub fn absolute(mut self) -> Self {
744 self.position = Some("absolute".into());
745 self
746 }
747
748 pub fn fixed(mut self) -> Self {
750 self.position = Some("fixed".into());
751 self
752 }
753
754 pub fn sticky(mut self) -> Self {
756 self.position = Some("sticky".into());
757 self
758 }
759
760 pub fn top(mut self, value: &str) -> Self {
762 self.top = Some(value.into());
763 self
764 }
765
766 pub fn right(mut self, value: &str) -> Self {
768 self.right = Some(value.into());
769 self
770 }
771
772 pub fn bottom(mut self, value: &str) -> Self {
774 self.bottom = Some(value.into());
775 self
776 }
777
778 pub fn left(mut self, value: &str) -> Self {
780 self.left = Some(value.into());
781 self
782 }
783
784 pub fn z_index(mut self, z: i16) -> Self {
786 self.z_index = Some(z.to_string());
787 self
788 }
789
790 pub fn cursor(mut self, cursor: &str) -> Self {
796 self.cursor = Some(cursor.into());
797 self
798 }
799
800 pub fn cursor_pointer(mut self) -> Self {
802 self.cursor = Some("pointer".into());
803 self
804 }
805
806 pub fn opacity(mut self, opacity: f32) -> Self {
808 self.opacity = Some(opacity.clamp(0.0, 1.0).to_string());
809 self
810 }
811
812 pub fn transition(mut self, transition: &str) -> Self {
814 self.transition = Some(transition.into());
815 self
816 }
817
818 pub fn transform(mut self, transform: &str) -> Self {
820 self.transform = Some(transform.into());
821 self
822 }
823
824 pub fn overflow_hidden(mut self) -> Self {
826 self.overflow = Some("hidden".into());
827 self
828 }
829
830 pub fn overflow_auto(mut self) -> Self {
832 self.overflow = Some("auto".into());
833 self
834 }
835
836 pub fn overflow_scroll(mut self) -> Self {
838 self.overflow = Some("scroll".into());
839 self
840 }
841
842 pub fn invisible(mut self) -> Self {
844 self.visibility = Some("hidden".into());
845 self
846 }
847
848 pub fn visible(mut self) -> Self {
850 self.visibility = Some("visible".into());
851 self
852 }
853
854 pub fn pointer_events_none(mut self) -> Self {
856 self.pointer_events = Some("none".into());
857 self
858 }
859
860 pub fn pointer_events_auto(mut self) -> Self {
862 self.pointer_events = Some("auto".into());
863 self
864 }
865
866 pub fn select_none(mut self) -> Self {
868 self.user_select = Some("none".into());
869 self
870 }
871
872 pub fn whitespace_nowrap(mut self) -> Self {
874 self.white_space = Some("nowrap".into());
875 self
876 }
877
878 pub fn break_all(mut self) -> Self {
880 self.word_break = Some("break-all".into());
881 self
882 }
883
884 pub fn outline(mut self, value: &str) -> Self {
886 self.outline = Some(value.into());
887 self
888 }
889
890 pub fn resize(mut self, value: &str) -> Self {
892 self.resize = Some(value.into());
893 self
894 }
895
896 pub fn flex_shrink(mut self, value: u8) -> Self {
898 self.transform = Some(format!("flex-shrink: {}", value));
901 self
902 }
903
904 pub fn bg_transparent(mut self) -> Self {
906 self.background_color = Some("transparent".into());
907 self
908 }
909
910 pub fn flex_grow(mut self, value: u8) -> Self {
912 let existing = self.transform.unwrap_or_default();
914 self.transform = Some(format!("{} flex-grow: {};", existing, value));
915 self
916 }
917
918 pub fn min_h_full(mut self) -> Self {
920 self.min_height = Some("100%".into());
921 self
922 }
923
924 pub fn build(self) -> String {
930 let mut style = String::new();
931
932 write_if_some(&mut style, "display", &self.display);
934 write_if_some(&mut style, "flex-direction", &self.flex_direction);
935 write_if_some(&mut style, "flex-wrap", &self.flex_wrap);
936 write_if_some(&mut style, "align-items", &self.align_items);
937 write_if_some(&mut style, "align-self", &self.align_self);
938 write_if_some(&mut style, "justify-content", &self.justify_content);
939 write_if_some(&mut style, "justify-items", &self.justify_items);
940 write_if_some(&mut style, "gap", &self.gap);
941 write_if_some(&mut style, "row-gap", &self.row_gap);
942 write_if_some(&mut style, "column-gap", &self.column_gap);
943
944 write_if_some(&mut style, "padding", &self.padding);
946 write_if_some(&mut style, "padding-top", &self.padding_top);
947 write_if_some(&mut style, "padding-right", &self.padding_right);
948 write_if_some(&mut style, "padding-bottom", &self.padding_bottom);
949 write_if_some(&mut style, "padding-left", &self.padding_left);
950 write_if_some(&mut style, "margin", &self.margin);
951 write_if_some(&mut style, "margin-top", &self.margin_top);
952 write_if_some(&mut style, "margin-right", &self.margin_right);
953 write_if_some(&mut style, "margin-bottom", &self.margin_bottom);
954 write_if_some(&mut style, "margin-left", &self.margin_left);
955
956 write_if_some(&mut style, "background-color", &self.background_color);
958 write_if_some(&mut style, "color", &self.color);
959 write_if_some(&mut style, "border-color", &self.border_color);
960
961 write_if_some(&mut style, "font-size", &self.font_size);
963 write_if_some(&mut style, "font-weight", &self.font_weight);
964 write_if_some(&mut style, "font-family", &self.font_family);
965 write_if_some(&mut style, "line-height", &self.line_height);
966 write_if_some(&mut style, "text-align", &self.text_align);
967 write_if_some(&mut style, "text-decoration", &self.text_decoration);
968 write_if_some(&mut style, "letter-spacing", &self.letter_spacing);
969
970 write_if_some(&mut style, "border-radius", &self.border_radius);
972 write_if_some(&mut style, "border", &self.border);
973 write_if_some(&mut style, "border-top", &self.border_top);
974 write_if_some(&mut style, "border-right", &self.border_right);
975 write_if_some(&mut style, "border-bottom", &self.border_bottom);
976 write_if_some(&mut style, "border-left", &self.border_left);
977 write_if_some(&mut style, "border-width", &self.border_width);
978 write_if_some(&mut style, "box-shadow", &self.box_shadow);
979
980 write_if_some(&mut style, "width", &self.width);
982 write_if_some(&mut style, "height", &self.height);
983 write_if_some(&mut style, "min-width", &self.min_width);
984 write_if_some(&mut style, "min-height", &self.min_height);
985 write_if_some(&mut style, "max-width", &self.max_width);
986 write_if_some(&mut style, "max-height", &self.max_height);
987
988 write_if_some(&mut style, "position", &self.position);
990 write_if_some(&mut style, "top", &self.top);
991 write_if_some(&mut style, "right", &self.right);
992 write_if_some(&mut style, "bottom", &self.bottom);
993 write_if_some(&mut style, "left", &self.left);
994 write_if_some(&mut style, "z-index", &self.z_index);
995
996 write_if_some(&mut style, "cursor", &self.cursor);
998 write_if_some(&mut style, "opacity", &self.opacity);
999 write_if_some(&mut style, "transition", &self.transition);
1000 write_if_some(&mut style, "transform", &self.transform);
1001 write_if_some(&mut style, "overflow", &self.overflow);
1002 write_if_some(&mut style, "visibility", &self.visibility);
1003 write_if_some(&mut style, "pointer-events", &self.pointer_events);
1004 write_if_some(&mut style, "user-select", &self.user_select);
1005 write_if_some(&mut style, "white-space", &self.white_space);
1006 write_if_some(&mut style, "word-break", &self.word_break);
1007 write_if_some(&mut style, "outline", &self.outline);
1008 write_if_some(&mut style, "resize", &self.resize);
1009
1010 style
1011 }
1012
1013 pub fn merge(mut self, other: Style) -> Self {
1015 if other.display.is_some() { self.display = other.display; }
1017 if other.flex_direction.is_some() { self.flex_direction = other.flex_direction; }
1018 if other.flex_wrap.is_some() { self.flex_wrap = other.flex_wrap; }
1019 if other.align_items.is_some() { self.align_items = other.align_items; }
1020 if other.align_self.is_some() { self.align_self = other.align_self; }
1021 if other.justify_content.is_some() { self.justify_content = other.justify_content; }
1022 if other.justify_items.is_some() { self.justify_items = other.justify_items; }
1023 if other.gap.is_some() { self.gap = other.gap; }
1024 if other.row_gap.is_some() { self.row_gap = other.row_gap; }
1025 if other.column_gap.is_some() { self.column_gap = other.column_gap; }
1026
1027 if other.padding.is_some() { self.padding = other.padding; }
1029 if other.padding_top.is_some() { self.padding_top = other.padding_top; }
1030 if other.padding_right.is_some() { self.padding_right = other.padding_right; }
1031 if other.padding_bottom.is_some() { self.padding_bottom = other.padding_bottom; }
1032 if other.padding_left.is_some() { self.padding_left = other.padding_left; }
1033 if other.margin.is_some() { self.margin = other.margin; }
1034 if other.margin_top.is_some() { self.margin_top = other.margin_top; }
1035 if other.margin_right.is_some() { self.margin_right = other.margin_right; }
1036 if other.margin_bottom.is_some() { self.margin_bottom = other.margin_bottom; }
1037 if other.margin_left.is_some() { self.margin_left = other.margin_left; }
1038
1039 if other.background_color.is_some() { self.background_color = other.background_color; }
1041 if other.color.is_some() { self.color = other.color; }
1042 if other.border_color.is_some() { self.border_color = other.border_color; }
1043
1044 if other.font_size.is_some() { self.font_size = other.font_size; }
1046 if other.font_weight.is_some() { self.font_weight = other.font_weight; }
1047 if other.font_family.is_some() { self.font_family = other.font_family; }
1048 if other.line_height.is_some() { self.line_height = other.line_height; }
1049 if other.text_align.is_some() { self.text_align = other.text_align; }
1050 if other.text_decoration.is_some() { self.text_decoration = other.text_decoration; }
1051 if other.letter_spacing.is_some() { self.letter_spacing = other.letter_spacing; }
1052
1053 if other.border_radius.is_some() { self.border_radius = other.border_radius; }
1055 if other.border.is_some() { self.border = other.border; }
1056 if other.border_top.is_some() { self.border_top = other.border_top; }
1057 if other.border_right.is_some() { self.border_right = other.border_right; }
1058 if other.border_bottom.is_some() { self.border_bottom = other.border_bottom; }
1059 if other.border_left.is_some() { self.border_left = other.border_left; }
1060 if other.border_width.is_some() { self.border_width = other.border_width; }
1061 if other.box_shadow.is_some() { self.box_shadow = other.box_shadow; }
1062
1063 if other.width.is_some() { self.width = other.width; }
1065 if other.height.is_some() { self.height = other.height; }
1066 if other.min_width.is_some() { self.min_width = other.min_width; }
1067 if other.min_height.is_some() { self.min_height = other.min_height; }
1068 if other.max_width.is_some() { self.max_width = other.max_width; }
1069 if other.max_height.is_some() { self.max_height = other.max_height; }
1070
1071 if other.position.is_some() { self.position = other.position; }
1073 if other.top.is_some() { self.top = other.top; }
1074 if other.right.is_some() { self.right = other.right; }
1075 if other.bottom.is_some() { self.bottom = other.bottom; }
1076 if other.left.is_some() { self.left = other.left; }
1077 if other.z_index.is_some() { self.z_index = other.z_index; }
1078
1079 if other.cursor.is_some() { self.cursor = other.cursor; }
1081 if other.opacity.is_some() { self.opacity = other.opacity; }
1082 if other.transition.is_some() { self.transition = other.transition; }
1083 if other.transform.is_some() { self.transform = other.transform; }
1084 if other.overflow.is_some() { self.overflow = other.overflow; }
1085 if other.visibility.is_some() { self.visibility = other.visibility; }
1086 if other.pointer_events.is_some() { self.pointer_events = other.pointer_events; }
1087 if other.user_select.is_some() { self.user_select = other.user_select; }
1088 if other.white_space.is_some() { self.white_space = other.white_space; }
1089 if other.word_break.is_some() { self.word_break = other.word_break; }
1090 if other.outline.is_some() { self.outline = other.outline; }
1091 if other.resize.is_some() { self.resize = other.resize; }
1092
1093 self
1094 }
1095}
1096
1097fn write_if_some(style: &mut String, property: &str, value: &Option<String>) {
1099 if let Some(v) = value {
1100 write!(style, "{}:{};", property, v).unwrap();
1101 }
1102}
1103
1104#[cfg(test)]
1105mod tests {
1106 use super::*;
1107 use crate::theme::tokens::ThemeTokens;
1108
1109 #[test]
1110 fn test_basic_style() {
1111 let style = Style::new()
1112 .flex()
1113 .items_center()
1114 .build();
1115
1116 assert!(style.contains("display:flex"));
1117 assert!(style.contains("align-items:center"));
1118 }
1119
1120 #[test]
1121 fn test_style_with_theme() {
1122 let theme = ThemeTokens::light();
1123 let style = Style::new()
1124 .flex()
1125 .gap(&theme.spacing, "md")
1126 .bg(&theme.colors.primary)
1127 .rounded(&theme.radius, "md")
1128 .build();
1129
1130 assert!(style.contains("display:flex"));
1131 assert!(style.contains("gap:16px"));
1132 assert!(style.contains("background-color:"));
1133 assert!(style.contains("border-radius:8px"));
1134 }
1135
1136 #[test]
1137 fn test_style_merge() {
1138 let base = Style::new().flex().items_center();
1139 let override_style = Style::new().justify_center();
1140
1141 let merged = base.merge(override_style);
1142 let style_str = merged.build();
1143
1144 assert!(style_str.contains("display:flex"));
1145 assert!(style_str.contains("align-items:center"));
1146 assert!(style_str.contains("justify-content:center"));
1147 }
1148}