Skip to main content

xengui/style/
style_builder.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use crate::{
4    BoxShadow, Overflow, Overscroll, ScrollbarGutter, TransitionProperty, properties::StyleValue, style::{ FontStyle, FontWeight, IntoThemed, LetterSpacing },
5};
6
7use super::{
8    AlignItems,
9    Background,
10    Border,
11    Outline,
12    Color,
13    Cursor,
14    Display,
15    Edges,
16    FlexDirection,
17    FlexWrap,
18    GridPlacement,
19    GridTrack,
20    JustifyContent,
21    Length,
22    LineHeight,
23    Position,
24    ScrollbarStyle,
25    Size,
26    Style,
27    TextAlign,
28    TextDecoration,
29};
30
31pub trait StyleBuilder: Sized {
32    fn style_mut(&mut self) -> &mut Style;
33
34    fn mark_dirty(&mut self) {}
35
36    fn width<M>(mut self, width: impl IntoThemed<Length, M>) -> Self {
37        self.style_mut().size.get_or_insert_with(Default::default).width = Some(
38            width.resolve_themed()
39        );
40
41        self.mark_dirty();
42
43        self
44    }
45
46    fn height<M>(mut self, height: impl IntoThemed<Length, M>) -> Self {
47        self.style_mut().size.get_or_insert_with(Default::default).height = Some(
48            height.resolve_themed()
49        );
50
51        self.mark_dirty();
52
53        self
54    }
55
56    fn size<W, H, MW, MH>(mut self, width: W, height: H) -> Self
57        where W: IntoThemed<Length, MW>, H: IntoThemed<Length, MH>
58    {
59        self.style_mut().size = Some(Size::new(width.resolve_themed(), height.resolve_themed()));
60
61        self.mark_dirty();
62
63        self
64    }
65
66    fn padding<M>(mut self, padding: impl IntoThemed<Edges, M>) -> Self {
67        self.style_mut().padding = Some(padding.resolve_themed());
68
69        self.mark_dirty();
70
71        self
72    }
73
74    fn color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
75        self.style_mut().color = Some(color.resolve_themed());
76
77        self.mark_dirty();
78
79        self
80    }
81
82    fn selection_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
83        self.style_mut().selection_color = Some(color.resolve_themed());
84
85        self.mark_dirty();
86
87        self
88    }
89
90    fn selection_background<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
91        self.style_mut().selection_background = Some(color.resolve_themed());
92
93        self.mark_dirty();
94
95        self
96    }
97
98    fn caret_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
99        self.style_mut().caret_color = Some(color.resolve_themed());
100
101        self.mark_dirty();
102
103        self
104    }
105
106    fn selection_border_width<M>(mut self, width: impl IntoThemed<Length, M>) -> Self {
107        self.style_mut().selection_border_width = Some(width.resolve_themed());
108
109        self.mark_dirty();
110
111        self
112    }
113
114    fn selection_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
115        self.style_mut().selection_border_color = Some(color.resolve_themed());
116
117        self.mark_dirty();
118
119        self
120    }
121
122    fn selection_border_radius<M>(mut self, radius: impl IntoThemed<Length, M>) -> Self {
123        self.style_mut().selection_border_radius = Some(radius.resolve_themed());
124
125        self.mark_dirty();
126
127        self
128    }
129
130    fn cursor(mut self, cursor: Cursor) -> Self {
131        self.style_mut().cursor = Some(cursor);
132
133        self.mark_dirty();
134
135        self
136    }
137
138    fn background<M>(mut self, background: impl IntoThemed<Background, M>) -> Self {
139        self.style_mut().background = Some(background.resolve_themed());
140
141        self.mark_dirty();
142
143        self
144    }
145
146    fn font_size<M>(mut self, size: impl IntoThemed<Length, M>) -> Self {
147        self.style_mut().font_size = Some(size.resolve_themed());
148
149        self.mark_dirty();
150
151        self
152    }
153
154    fn font_weight(mut self, weight: FontWeight) -> Self {
155        self.style_mut().font_weight = Some(weight);
156
157        self.mark_dirty();
158
159        self
160    }
161
162    fn font_style(mut self, style: FontStyle) -> Self {
163        self.style_mut().font_style = Some(style);
164
165        self.mark_dirty();
166
167        self
168    }
169
170    fn letter_spacing(mut self, spacing: impl Into<LetterSpacing>) -> Self {
171        self.style_mut().letter_spacing = Some(spacing.into());
172
173        self.mark_dirty();
174
175        self
176    }
177
178    fn text_align(mut self, align: TextAlign) -> Self {
179        self.style_mut().text_align = Some(align);
180
181        self.mark_dirty();
182
183        self
184    }
185
186    fn text_decoration(mut self, decoration: TextDecoration) -> Self {
187        self.style_mut().text_decoration = Some(decoration);
188
189        self.mark_dirty();
190
191        self
192    }
193
194    fn line_height(mut self, height: impl Into<LineHeight>) -> Self {
195        self.style_mut().line_height = Some(height.into());
196
197        self.mark_dirty();
198
199        self
200    }
201
202    fn margin<M>(mut self, margin: impl IntoThemed<Edges, M>) -> Self {
203        self.style_mut().margin = Some(margin.resolve_themed());
204
205        self.mark_dirty();
206
207        self
208    }
209
210    fn border<M>(mut self, border: impl IntoThemed<Border, M>) -> Self {
211        self.style_mut().border = Some(border.resolve_themed());
212
213        self.mark_dirty();
214
215        self
216    }
217
218    fn outline<M>(mut self, outline: impl IntoThemed<StyleValue<Outline>, M>) -> Self {
219        self.style_mut().outline = outline.resolve_themed();
220
221        self.mark_dirty();
222
223        self
224    }
225
226    fn box_shadow(mut self, shadows: impl Into<Vec<BoxShadow>>) -> Self {
227        self.style_mut().box_shadow = Some(shadows.into());
228        self.mark_dirty();
229        self
230    }
231
232    fn box_shadow_none(mut self) -> Self {
233        self.style_mut().box_shadow = None;
234        self.mark_dirty();
235        self
236    }
237
238    fn min_width<M>(mut self, width: impl IntoThemed<Length, M>) -> Self {
239        self.style_mut().min_size.get_or_insert_with(Default::default).width = Some(
240            width.resolve_themed()
241        );
242
243        self.mark_dirty();
244
245        self
246    }
247
248    fn min_height<M>(mut self, height: impl IntoThemed<Length, M>) -> Self {
249        self.style_mut().min_size.get_or_insert_with(Default::default).height = Some(
250            height.resolve_themed()
251        );
252
253        self.mark_dirty();
254
255        self
256    }
257
258    fn min_size<W, H, MW, MH>(mut self, width: W, height: H) -> Self
259        where W: IntoThemed<Length, MW>, H: IntoThemed<Length, MH>
260    {
261        self.style_mut().min_size = Some(
262            Size::new(width.resolve_themed(), height.resolve_themed())
263        );
264
265        self.mark_dirty();
266
267        self
268    }
269
270    fn max_width<M>(mut self, width: impl IntoThemed<Length, M>) -> Self {
271        self.style_mut().max_size.get_or_insert_with(Default::default).width = Some(
272            width.resolve_themed()
273        );
274
275        self.mark_dirty();
276
277        self
278    }
279
280    fn max_height<M>(mut self, height: impl IntoThemed<Length, M>) -> Self {
281        self.style_mut().max_size.get_or_insert_with(Default::default).height = Some(
282            height.resolve_themed()
283        );
284
285        self.mark_dirty();
286
287        self
288    }
289
290    fn max_size<W, H, MW, MH>(mut self, width: W, height: H) -> Self
291        where W: IntoThemed<Length, MW>, H: IntoThemed<Length, MH>
292    {
293        self.style_mut().max_size = Some(
294            Size::new(width.resolve_themed(), height.resolve_themed())
295        );
296
297        self.mark_dirty();
298
299        self
300    }
301
302    fn display(mut self, display: Display) -> Self {
303        self.style_mut().display = Some(display);
304
305        self.mark_dirty();
306
307        self
308    }
309
310    fn position(mut self, position: Position) -> Self {
311        self.style_mut().position = Some(position);
312
313        self.mark_dirty();
314
315        self
316    }
317
318    fn top<M>(mut self, value: impl IntoThemed<Length, M>) -> Self {
319        self.style_mut().top = Some(value.resolve_themed());
320
321        self.mark_dirty();
322
323        self
324    }
325
326    fn right<M>(mut self, value: impl IntoThemed<Length, M>) -> Self {
327        self.style_mut().right = Some(value.resolve_themed());
328
329        self.mark_dirty();
330
331        self
332    }
333
334    fn bottom<M>(mut self, value: impl IntoThemed<Length, M>) -> Self {
335        self.style_mut().bottom = Some(value.resolve_themed());
336
337        self.mark_dirty();
338
339        self
340    }
341
342    fn left<M>(mut self, value: impl IntoThemed<Length, M>) -> Self {
343        self.style_mut().left = Some(value.resolve_themed());
344
345        self.mark_dirty();
346
347        self
348    }
349
350    /// Paint order relative to siblings; higher values paint later, on top.
351    fn z_index(mut self, z_index: i32) -> Self {
352        self.style_mut().z_index = Some(z_index);
353
354        self.mark_dirty();
355
356        self
357    }
358
359    fn overflow_x(mut self, overflow: Overflow) -> Self {
360        self.style_mut().overflow_x = Some(overflow);
361
362        self.mark_dirty();
363
364        self
365    }
366
367    fn overflow_y(mut self, overflow: Overflow) -> Self {
368        self.style_mut().overflow_y = Some(overflow);
369
370        self.mark_dirty();
371
372        self
373    }
374
375    fn overflow(mut self, x: Overflow, y: Overflow) -> Self {
376        self.style_mut().overflow_x = Some(x);
377
378        self.style_mut().overflow_y = Some(y);
379
380        self.mark_dirty();
381
382        self
383    }
384
385    fn overscroll(mut self, overscroll: Overscroll) -> Self {
386        self.style_mut().overscroll = Some(overscroll);
387
388        self.mark_dirty();
389
390        self
391    }
392
393    fn flex_direction(mut self, direction: FlexDirection) -> Self {
394        self.style_mut().flex_direction = Some(direction);
395
396        self.mark_dirty();
397
398        self
399    }
400
401    fn flex_wrap(mut self, wrap: FlexWrap) -> Self {
402        self.style_mut().flex_wrap = Some(wrap);
403
404        self.mark_dirty();
405
406        self
407    }
408
409    fn flex_grow(mut self, grow: f32) -> Self {
410        self.style_mut().flex_grow = Some(grow);
411
412        self.mark_dirty();
413
414        self
415    }
416
417    fn flex_shrink(mut self, shrink: f32) -> Self {
418        self.style_mut().flex_shrink = Some(shrink);
419
420        self.mark_dirty();
421
422        self
423    }
424
425    fn flex_basis<M>(mut self, basis: impl IntoThemed<Length, M>) -> Self {
426        self.style_mut().flex_basis = Some(basis.resolve_themed());
427
428        self.mark_dirty();
429
430        self
431    }
432
433    fn align_items(mut self, align: AlignItems) -> Self {
434        self.style_mut().align_items = Some(align);
435
436        self.mark_dirty();
437
438        self
439    }
440
441    fn align_self(mut self, align: AlignItems) -> Self {
442        self.style_mut().align_self = Some(align);
443
444        self.mark_dirty();
445
446        self
447    }
448
449    fn justify_content(mut self, justify: JustifyContent) -> Self {
450        self.style_mut().justify_content = Some(justify);
451
452        self.mark_dirty();
453
454        self
455    }
456
457    fn align_content(mut self, align: JustifyContent) -> Self {
458        self.style_mut().align_content = Some(align);
459
460        self.mark_dirty();
461
462        self
463    }
464
465    fn gap<W, H, MW, MH>(mut self, horizontal: W, vertical: H) -> Self
466        where W: IntoThemed<Length, MW>, H: IntoThemed<Length, MH>
467    {
468        self.style_mut().gap = Some((horizontal.resolve_themed(), vertical.resolve_themed()));
469
470        self.mark_dirty();
471
472        self
473    }
474
475    fn grid_template_columns(mut self, columns: impl Into<Vec<GridTrack>>) -> Self {
476        self.style_mut().grid_template_columns = Some(columns.into());
477
478        self.mark_dirty();
479
480        self
481    }
482
483    fn grid_template_rows(mut self, rows: impl Into<Vec<GridTrack>>) -> Self {
484        self.style_mut().grid_template_rows = Some(rows.into());
485
486        self.mark_dirty();
487
488        self
489    }
490
491    fn grid_column(mut self, column: GridPlacement) -> Self {
492        self.style_mut().grid_column = Some(column);
493
494        self.mark_dirty();
495
496        self
497    }
498
499    fn grid_row(mut self, row: GridPlacement) -> Self {
500        self.style_mut().grid_row = Some(row);
501
502        self.mark_dirty();
503
504        self
505    }
506
507    fn scrollbar_gutter(mut self, gutter: ScrollbarGutter) -> Self {
508        self.style_mut().scrollbar_gutter = Some(gutter);
509
510        self.mark_dirty();
511
512        self
513    }
514
515    fn scrollbar_thickness(mut self, thickness: f32) -> Self {
516        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).thickness =
517            Some(thickness);
518
519        self.mark_dirty();
520
521        self
522    }
523
524    fn scrollbar_min_thumb_length(mut self, length: f32) -> Self {
525        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).min_thumb_length =
526            Some(length);
527
528        self.mark_dirty();
529
530        self
531    }
532
533    fn scrollbar_thumb_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
534        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).thumb_color = Some(
535            color.resolve_themed()
536        );
537        self.mark_dirty();
538        self
539    }
540
541    fn scrollbar_thumb_radius<M>(mut self, radius: impl IntoThemed<f32, M>) -> Self {
542        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).thumb_radius = Some(
543            radius.resolve_themed()
544        );
545        self.mark_dirty();
546        self
547    }
548
549    fn scrollbar_track_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
550        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).track_color = Some(
551            color.resolve_themed()
552        );
553        self.mark_dirty();
554        self
555    }
556
557    fn scrollbar_button_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
558        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).button_color = Some(
559            color.resolve_themed()
560        );
561        self.mark_dirty();
562        self
563    }
564
565    fn scrollbar_arrow_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
566        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).arrow_color = Some(
567            color.resolve_themed()
568        );
569
570        self.mark_dirty();
571
572        self
573    }
574
575    fn scrollbar_thumb_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
576        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).thumb_border_color =
577            Some(color.resolve_themed());
578
579        self.mark_dirty();
580
581        self
582    }
583
584    fn scrollbar_track_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
585        self.style_mut().scrollbar.get_or_insert_with(ScrollbarStyle::default).track_border_color =
586            Some(color.resolve_themed());
587
588        self.mark_dirty();
589
590        self
591    }
592
593    // Overrides applied only while the pointer is over the scrollbar's own
594
595    // track/thumb/buttons; unset fields fall back to the default scrollbar style.
596
597    fn scrollbar_hover_thickness(mut self, thickness: f32) -> Self {
598        self.style_mut().scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).thickness =
599            Some(thickness);
600
601        self.mark_dirty();
602
603        self
604    }
605
606    fn scrollbar_hover_min_thumb_length(mut self, length: f32) -> Self {
607        self
608
609            .style_mut()
610
611            .scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).min_thumb_length =
612            Some(length);
613
614        self.mark_dirty();
615
616        self
617    }
618
619    fn scrollbar_hover_thumb_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
620        self.style_mut().scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).thumb_color =
621            Some(color.resolve_themed());
622
623        self.mark_dirty();
624
625        self
626    }
627
628    fn scrollbar_hover_thumb_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
629        self
630
631            .style_mut()
632
633            .scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).thumb_border_color = Some(
634            color.resolve_themed()
635        );
636
637        self.mark_dirty();
638
639        self
640    }
641
642    fn scrollbar_hover_track_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
643        self.style_mut().scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).track_color =
644            Some(color.resolve_themed());
645
646        self.mark_dirty();
647
648        self
649    }
650
651    fn scrollbar_hover_track_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
652        self
653
654            .style_mut()
655
656            .scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).track_border_color = Some(
657            color.resolve_themed()
658        );
659
660        self.mark_dirty();
661
662        self
663    }
664
665    fn scrollbar_hover_button_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
666        self.style_mut().scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).button_color =
667            Some(color.resolve_themed());
668
669        self.mark_dirty();
670
671        self
672    }
673
674    fn scrollbar_hover_arrow_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
675        self.style_mut().scrollbar_hover.get_or_insert_with(ScrollbarStyle::default).arrow_color =
676            Some(color.resolve_themed());
677
678        self.mark_dirty();
679
680        self
681    }
682
683    // Active while the thumb is being dragged; unset fields fall back to
684
685    // the hover style, then the default.
686
687    fn scrollbar_pressed_thickness(mut self, thickness: f32) -> Self {
688        self.style_mut().scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).thickness =
689            Some(thickness);
690
691        self.mark_dirty();
692
693        self
694    }
695
696    fn scrollbar_pressed_min_thumb_length(mut self, length: f32) -> Self {
697        self
698
699            .style_mut()
700
701            .scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).min_thumb_length =
702            Some(length);
703
704        self.mark_dirty();
705
706        self
707    }
708
709    fn scrollbar_pressed_thumb_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
710        self.style_mut().scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).thumb_color =
711            Some(color.resolve_themed());
712
713        self.mark_dirty();
714
715        self
716    }
717
718    fn scrollbar_pressed_thumb_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
719        self
720
721            .style_mut()
722
723            .scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).thumb_border_color =
724            Some(color.resolve_themed());
725
726        self.mark_dirty();
727
728        self
729    }
730
731    fn scrollbar_pressed_track_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
732        self.style_mut().scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).track_color =
733            Some(color.resolve_themed());
734
735        self.mark_dirty();
736
737        self
738    }
739
740    fn scrollbar_pressed_track_border_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
741        self
742
743            .style_mut()
744
745            .scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).track_border_color =
746            Some(color.resolve_themed());
747
748        self.mark_dirty();
749
750        self
751    }
752
753    fn scrollbar_pressed_button_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
754        self
755
756            .style_mut()
757
758            .scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).button_color = Some(
759            color.resolve_themed()
760        );
761
762        self.mark_dirty();
763
764        self
765    }
766
767    fn scrollbar_pressed_arrow_color<M>(mut self, color: impl IntoThemed<Color, M>) -> Self {
768        self.style_mut().scrollbar_pressed.get_or_insert_with(ScrollbarStyle::default).arrow_color =
769            Some(color.resolve_themed());
770
771        self.mark_dirty();
772
773        self
774    }
775
776    fn scale(mut self, scale: f32) -> Self {
777        self.style_mut().scale = Some(scale);
778
779        self.mark_dirty();
780
781        self
782    }
783
784    fn content_scale(mut self, scale: f32) -> Self {
785        self.style_mut().content_scale = Some(scale);
786
787        self.mark_dirty();
788
789        self
790    }
791
792    fn transition(mut self, transition: crate::Transition) -> Self {
793        self.style_mut().transition = Some(transition);
794
795        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
796
797        self.style_mut().transition_properties = Some(props.union(TransitionProperty::DEFAULT));
798
799        self.mark_dirty();
800
801        self
802    }
803
804    fn transition_all(mut self, transition: crate::Transition) -> Self {
805        self.style_mut().transition = Some(transition);
806
807        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
808
809        self.style_mut().transition_properties = Some(props.union(TransitionProperty::ALL));
810
811        self.mark_dirty();
812
813        self
814    }
815
816    fn transition_colors(mut self, transition: crate::Transition) -> Self {
817        self.style_mut().transition_overrides.colors = Some(transition);
818
819        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
820
821        self.style_mut().transition_properties = Some(props.union(TransitionProperty::COLORS));
822
823        self.mark_dirty();
824
825        self
826    }
827
828    fn transition_opacity(mut self, transition: crate::Transition) -> Self {
829        self.style_mut().transition_overrides.opacity = Some(transition);
830
831        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
832
833        self.style_mut().transition_properties = Some(props.union(TransitionProperty::OPACITY));
834
835        self.mark_dirty();
836
837        self
838    }
839
840    // Reserved for the future box-shadow system; has no visible effect yet.
841
842    fn transition_shadow(mut self, transition: crate::Transition) -> Self {
843        self.style_mut().transition_overrides.shadow = Some(transition);
844
845        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
846
847        self.style_mut().transition_properties = Some(props.union(TransitionProperty::SHADOW));
848
849        self.mark_dirty();
850
851        self
852    }
853
854    fn transition_transform(mut self, transition: crate::Transition) -> Self {
855        self.style_mut().transition_overrides.transform = Some(transition);
856
857        let props = self.style_mut().transition_properties.unwrap_or(TransitionProperty::NONE);
858
859        self.style_mut().transition_properties = Some(props.union(TransitionProperty::TRANSFORM));
860
861        self.mark_dirty();
862
863        self
864    }
865
866    fn transition_none(mut self) -> Self {
867        self.style_mut().transition = None;
868
869        self.style_mut().transition_overrides = Default::default();
870
871        self.style_mut().transition_properties = Some(TransitionProperty::NONE);
872
873        self.mark_dirty();
874
875        self
876    }
877}
878
879#[derive(Default)]
880pub struct StylePatch(Style);
881
882impl StylePatch {
883    pub fn new() -> Self {
884        Self(Style::default())
885    }
886
887    pub fn build(self) -> Style {
888        self.0
889    }
890}
891
892impl StyleBuilder for StylePatch {
893    fn style_mut(&mut self) -> &mut Style {
894        &mut self.0
895    }
896}