1use vizia_style::{ColorStop, CornerRadius, Rect};
2
3use super::internal;
4use crate::prelude::*;
5
6pub trait StyleModifiers: internal::Modifiable {
8 fn id(mut self, id: impl Into<String>) -> Self {
27 let id = id.into();
29 let entity = self.entity();
30 self.context().style.ids.insert(entity, id.clone());
31 self.context().needs_restyle(entity);
32
33 self.context().entity_identifiers.insert(id, entity);
34
35 self
36 }
37
38 fn class(mut self, name: &str) -> Self {
55 let entity = self.entity();
56 if let Some(class_list) = self.context().style.classes.get_mut(entity) {
57 class_list.insert(name.to_string());
58 }
59
60 self.context().needs_restyle(entity);
61
62 self
63 }
64
65 fn toggle_class(mut self, name: &str, applied: impl Res<bool>) -> Self {
67 let name = name.to_owned();
68 let entity = self.entity();
69 let current = self.current();
70 self.context().with_current(current, |cx| {
71 applied.set_or_bind(cx, move |cx, applied| {
72 let applied = applied.get_value(cx);
73 if let Some(class_list) = cx.style.classes.get_mut(entity) {
74 if applied {
75 class_list.insert(name.clone());
76 } else {
77 class_list.remove(&name);
78 }
79 }
80
81 cx.needs_restyle(entity);
82 });
83 });
84
85 self
86 }
87
88 fn checked<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
93 let entity = self.entity();
94 let current = self.current();
95 if let Some(abilities) = self.context().style.abilities.get_mut(entity) {
97 abilities.set(Abilities::CHECKABLE, true);
98 }
99
100 self.context().with_current(current, move |cx| {
101 state.set_or_bind(cx, move |cx, val| {
102 let val = val.get_value(cx).into();
103 if let Some(pseudo_classes) = cx.style.pseudo_classes.get_mut(entity) {
104 pseudo_classes.set(PseudoClassFlags::CHECKED, val);
105 }
106 cx.needs_restyle(entity);
107 cx.style.needs_access_update(entity);
108 });
109 });
110
111 self
112 }
113
114 fn focused<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
119 let entity = self.entity();
120 let current = self.current();
121
122 self.context().with_current(current, |cx| {
123 state.set_or_bind(cx, move |cx, val| {
124 let val = val.get_value(cx).into();
125
126 if val {
127 cx.with_current(entity, |cx| cx.focus());
128 }
130
131 cx.needs_restyle(entity);
132 });
133 });
134
135 self
136 }
137
138 fn focused_with_visibility<U: Into<bool>>(
140 mut self,
141 focus: impl Res<U> + Copy + 'static,
142 visibility: impl Res<U> + Copy + 'static,
143 ) -> Self {
144 let entity = self.entity();
145 let current = self.current();
146
147 self.context().with_current(current, move |cx| {
148 focus.set_or_bind(cx, move |cx, f| {
149 visibility.set_or_bind(cx, move |cx, v| {
150 let focus = f.get_value(cx).into();
151 let visibility = v.get_value(cx).into();
152 if focus {
153 cx.with_current(entity, |cx| cx.focus_with_visibility(visibility));
155 cx.needs_restyle(entity);
156 }
157 });
158 });
159 });
160
161 self
162 }
163
164 fn read_only<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
166 let entity = self.entity();
167 let current = self.current();
168 self.context().with_current(current, |cx| {
169 state.set_or_bind(cx, move |cx, val| {
170 let val = val.get_value(cx).into();
171 if let Some(pseudo_classes) = cx.style.pseudo_classes.get_mut(entity) {
172 pseudo_classes.set(PseudoClassFlags::READ_ONLY, val);
173 }
174
175 cx.needs_restyle(entity);
176 });
177 });
178
179 self
180 }
181
182 fn read_write<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
184 let entity = self.entity();
185 let current = self.current();
186 self.context().with_current(current, |cx| {
187 state.set_or_bind(cx, move |cx, val| {
188 let val = val.get_value(cx).into();
189 if let Some(pseudo_classes) = cx.style.pseudo_classes.get_mut(entity) {
190 pseudo_classes.set(PseudoClassFlags::READ_WRITE, val);
191 }
192
193 cx.needs_restyle(entity);
194 });
195 });
196
197 self
198 }
199
200 fn focus_within<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
202 let entity = self.entity();
203 let current = self.current();
204 self.context().with_current(current, |cx| {
205 state.set_or_bind(cx, move |cx, val| {
206 let val = val.get_value(cx).into();
207 if let Some(pseudo_classes) = cx.style.pseudo_classes.get_mut(entity) {
208 pseudo_classes.set(PseudoClassFlags::FOCUS_WITHIN, val);
209 }
210
211 cx.needs_restyle(entity);
212 });
213 });
214
215 self
216 }
217
218 fn placeholder_shown<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
220 let entity = self.entity();
221 let current = self.current();
222 self.context().with_current(current, |cx| {
223 state.set_or_bind(cx, move |cx, val| {
224 let val = val.get_value(cx).into();
225 if let Some(pseudo_classes) = cx.style.pseudo_classes.get_mut(entity) {
226 pseudo_classes.set(PseudoClassFlags::PLACEHOLDER_SHOWN, val);
227 }
228
229 cx.needs_restyle(entity);
230 });
231 });
232
233 self
234 }
235
236 modifier!(
237 disabled,
241 bool,
242 SystemFlags::RESTYLE | SystemFlags::REACCESS
243 );
244
245 modifier!(
246 display,
250 Display,
251 SystemFlags::RELAYOUT | SystemFlags::REDRAW | SystemFlags::REFLOW
252 );
253
254 modifier!(
255 visibility,
259 Visibility,
260 SystemFlags::REDRAW
261 );
262
263 modifier!(
264 opacity,
268 Opacity,
269 SystemFlags::REDRAW
270 );
271
272 fn z_index<U: Into<i32>>(mut self, value: impl Res<U>) -> Self {
277 let entity = self.entity();
278 let cx = self.context();
280 let value = value.get_value(cx).into();
281 cx.style.z_index.insert(entity, value);
282 cx.needs_redraw(entity);
283 self
286 }
287
288 modifier!(
289 ignore_clipping,
293 bool,
294 SystemFlags::RECLIP | SystemFlags::REDRAW
295 );
296
297 fn clip_path<U: Into<ClipPath>>(mut self, value: impl Res<U>) -> Self {
299 let entity = self.entity();
300 let current = self.current();
301 self.context().with_current(current, |cx| {
302 value.set_or_bind(cx, move |cx, v| {
303 let value = v.get_value(cx).into();
304 cx.style.clip_path.insert(entity, value);
305 cx.needs_reclip(entity);
306 cx.needs_redraw(entity);
307 });
308 });
309
310 self
311 }
312
313 fn overflow<U: Into<Overflow>>(mut self, value: impl Res<U>) -> Self {
315 let entity = self.entity();
316 let current = self.current();
317 self.context().with_current(current, |cx| {
318 value.set_or_bind(cx, move |cx, v| {
319 let value = v.get_value(cx).into();
320 cx.style.overflowx.insert(entity, value);
321 cx.style.overflowy.insert(entity, value);
322 cx.needs_reclip(entity);
323 cx.needs_redraw(entity);
324 });
325 });
326
327 self
328 }
329
330 modifier!(
331 overflowx,
335 Overflow,
336 SystemFlags::RECLIP | SystemFlags::REDRAW
337 );
338
339 modifier!(
340 overflowy,
344 Overflow,
345 SystemFlags::RECLIP | SystemFlags::REDRAW
346 );
347
348 fn filter<U: Into<Filter>>(mut self, value: impl Res<U>) -> Self {
350 let entity = self.entity();
351 let current = self.current();
352 self.context().with_current(current, |cx| {
353 value.set_or_bind(cx, move |cx, v| {
354 let value = v.get_value(cx).into();
355 cx.style.filter.insert(entity, value);
356
357 cx.needs_redraw(entity);
358 });
359 });
360
361 self
362 }
363
364 fn backdrop_filter<U: Into<Filter>>(mut self, value: impl Res<U>) -> Self {
366 let entity = self.entity();
367 let current = self.current();
368 self.context().with_current(current, |cx| {
369 value.set_or_bind(cx, move |cx, v| {
370 let value = v.get_value(cx).into();
371 cx.style.backdrop_filter.insert(entity, value);
372
373 cx.needs_redraw(entity);
374 });
375 });
376
377 self
378 }
379
380 fn shadow<U: Into<Shadow>>(mut self, value: impl Res<U>) -> Self {
382 let entity = self.entity();
383 let current = self.current();
384 self.context().with_current(current, |cx| {
385 value.set_or_bind(cx, move |cx, v| {
386 let value = v.get_value(cx).into();
387 if let Some(shadows) = cx.style.shadow.get_inline_mut(entity) {
388 shadows.push(value);
389 } else {
390 cx.style.shadow.insert(entity, vec![value]);
391 }
392
393 cx.needs_redraw(entity);
394 });
395 });
396
397 self
398 }
399
400 fn shadows<U: Into<Vec<Shadow>>>(mut self, value: impl Res<U>) -> Self {
402 let entity = self.entity();
403 let current = self.current();
404 self.context().with_current(current, |cx| {
405 value.set_or_bind(cx, move |cx, v| {
406 let value = v.get_value(cx).into();
407
408 cx.style.shadow.insert(entity, value);
409
410 cx.needs_redraw(entity);
411 });
412 });
413
414 self
415 }
416
417 fn background_gradient<U: Into<Gradient>>(mut self, value: impl Res<U>) -> Self {
419 let entity = self.entity();
420 let current = self.current();
421 self.context().with_current(current, |cx| {
422 value.set_or_bind(cx, move |cx, v| {
423 let value = v.get_value(cx).into();
424 if let Some(background_images) = cx.style.background_image.get_inline_mut(entity) {
425 background_images.push(ImageOrGradient::Gradient(value));
426 } else {
427 cx.style
428 .background_image
429 .insert(entity, vec![ImageOrGradient::Gradient(value)]);
430 }
431
432 cx.needs_redraw(entity);
433 });
434 });
435
436 self
437 }
438
439 modifier!(
441 background_color,
443 Color,
444 SystemFlags::REDRAW
445 );
446
447 modifier!(
448 background_position,
450 Vec<Position>,
451 SystemFlags::REDRAW
452 );
453
454 modifier!(
455 background_size,
457 Vec<BackgroundSize>,
458 SystemFlags::REDRAW
459 );
460
461 modifier!(
462 background_repeat,
464 Vec<BackgroundRepeat>,
465 SystemFlags::REDRAW
466 );
467
468 fn background_image<'i, U: Into<BackgroundImage<'i>>>(mut self, value: impl Res<U>) -> Self {
470 let entity = self.entity();
471 let current = self.current();
472 self.context().with_current(current, |cx| {
473 value.set_or_bind(cx, move |cx, val| {
474 let image = val.get_value(cx).into();
475 let image = match image {
476 BackgroundImage::Gradient(gradient) => {
477 Some(ImageOrGradient::Gradient(*gradient))
478 }
479 BackgroundImage::Url(url) => Some(ImageOrGradient::Image(url.url.to_string())),
480
481 _ => None,
482 };
483
484 if let Some(image) = image {
485 cx.style.background_image.insert(entity, vec![image]);
486 }
487
488 cx.needs_redraw(entity);
489 });
490 });
491
492 self
493 }
494
495 fn border_width<U: Into<LengthOrPercentage>>(mut self, value: impl Res<U>) -> Self {
499 let entity = self.entity();
500 value.set_or_bind(self.context(), move |cx, v| {
501 let w: LengthOrPercentage = v.get_value(cx).into();
502 cx.style.border_top_width.insert(entity, w.clone());
503 cx.style.border_right_width.insert(entity, w.clone());
504 cx.style.border_bottom_width.insert(entity, w.clone());
505 cx.style.border_left_width.insert(entity, w);
506 cx.cache.path.remove(entity);
507 cx.style.system_flags |= SystemFlags::RELAYOUT | SystemFlags::REDRAW;
508 cx.set_system_flags(entity, SystemFlags::RELAYOUT | SystemFlags::REDRAW);
509 });
510 self
511 }
512
513 fn border_top_width<U: Into<LengthOrPercentage>>(mut self, value: impl Res<U>) -> Self {
515 let entity = self.entity();
516 value.set_or_bind(self.context(), move |cx, v| {
517 cx.style.border_top_width.insert(entity, v.get_value(cx).into());
518 cx.cache.path.remove(entity);
519 cx.style.system_flags |= SystemFlags::RELAYOUT | SystemFlags::REDRAW;
520 cx.set_system_flags(entity, SystemFlags::RELAYOUT | SystemFlags::REDRAW);
521 });
522 self
523 }
524
525 fn border_right_width<U: Into<LengthOrPercentage>>(mut self, value: impl Res<U>) -> Self {
527 let entity = self.entity();
528 value.set_or_bind(self.context(), move |cx, v| {
529 cx.style.border_right_width.insert(entity, v.get_value(cx).into());
530 cx.cache.path.remove(entity);
531 cx.style.system_flags |= SystemFlags::RELAYOUT | SystemFlags::REDRAW;
532 cx.set_system_flags(entity, SystemFlags::RELAYOUT | SystemFlags::REDRAW);
533 });
534 self
535 }
536
537 fn border_bottom_width<U: Into<LengthOrPercentage>>(mut self, value: impl Res<U>) -> Self {
539 let entity = self.entity();
540 value.set_or_bind(self.context(), move |cx, v| {
541 cx.style.border_bottom_width.insert(entity, v.get_value(cx).into());
542 cx.cache.path.remove(entity);
543 cx.style.system_flags |= SystemFlags::RELAYOUT | SystemFlags::REDRAW;
544 cx.set_system_flags(entity, SystemFlags::RELAYOUT | SystemFlags::REDRAW);
545 });
546 self
547 }
548
549 fn border_left_width<U: Into<LengthOrPercentage>>(mut self, value: impl Res<U>) -> Self {
551 let entity = self.entity();
552 value.set_or_bind(self.context(), move |cx, v| {
553 cx.style.border_left_width.insert(entity, v.get_value(cx).into());
554 cx.cache.path.remove(entity);
555 cx.style.system_flags |= SystemFlags::RELAYOUT | SystemFlags::REDRAW;
556 cx.set_system_flags(entity, SystemFlags::RELAYOUT | SystemFlags::REDRAW);
557 });
558 self
559 }
560
561 fn border_color(mut self, value: impl Res<Color>) -> Self {
563 let entity = self.entity();
564 value.set_or_bind(self.context(), move |cx, v| {
565 let c = v.get_value(cx);
566 cx.style.border_top_color.insert(entity, c);
567 cx.style.border_right_color.insert(entity, c);
568 cx.style.border_bottom_color.insert(entity, c);
569 cx.style.border_left_color.insert(entity, c);
570 cx.needs_redraw(entity);
571 });
572 self
573 }
574
575 modifier!(
576 border_top_color,
578 Color,
579 SystemFlags::REDRAW
580 );
581
582 modifier!(
583 border_right_color,
585 Color,
586 SystemFlags::REDRAW
587 );
588
589 modifier!(
590 border_bottom_color,
592 Color,
593 SystemFlags::REDRAW
594 );
595
596 modifier!(
597 border_left_color,
599 Color,
600 SystemFlags::REDRAW
601 );
602
603 fn border_style(mut self, value: impl Res<BorderStyleKeyword>) -> Self {
605 let entity = self.entity();
606 value.set_or_bind(self.context(), move |cx, v| {
607 let s = v.get_value(cx);
608 cx.style.border_top_style.insert(entity, s);
609 cx.style.border_right_style.insert(entity, s);
610 cx.style.border_bottom_style.insert(entity, s);
611 cx.style.border_left_style.insert(entity, s);
612 cx.needs_redraw(entity);
613 });
614 self
615 }
616
617 modifier!(
618 border_top_style,
620 BorderStyleKeyword,
621 SystemFlags::REDRAW
622 );
623
624 modifier!(
625 border_right_style,
627 BorderStyleKeyword,
628 SystemFlags::REDRAW
629 );
630
631 modifier!(
632 border_bottom_style,
634 BorderStyleKeyword,
635 SystemFlags::REDRAW
636 );
637
638 modifier!(
639 border_left_style,
641 BorderStyleKeyword,
642 SystemFlags::REDRAW
643 );
644
645 modifier!(
646 corner_top_left_radius,
648 LengthOrPercentage,
649 SystemFlags::REDRAW
650 );
651
652 modifier!(
653 corner_top_right_radius,
655 LengthOrPercentage,
656 SystemFlags::REDRAW
657 );
658
659 modifier!(
660 corner_bottom_left_radius,
662 LengthOrPercentage,
663 SystemFlags::REDRAW
664 );
665
666 modifier!(
667 corner_bottom_right_radius,
669 LengthOrPercentage,
670 SystemFlags::REDRAW
671 );
672
673 fn corner_radius<U: std::fmt::Debug + Into<CornerRadius>>(
675 mut self,
676 value: impl Res<U>,
677 ) -> Self {
678 let entity = self.entity();
679 let current = self.current();
680 self.context().with_current(current, |cx| {
681 value.set_or_bind(cx, move |cx, v| {
682 let value = v.get_value(cx).into();
683 cx.style.corner_top_left_radius.insert(entity, value.top_left);
684 cx.style.corner_top_right_radius.insert(entity, value.top_right);
685 cx.style.corner_bottom_left_radius.insert(entity, value.bottom_left);
686 cx.style.corner_bottom_right_radius.insert(entity, value.bottom_right);
687
688 cx.needs_redraw(entity);
689 });
690 });
691
692 self
693 }
694
695 modifier!(
696 corner_top_left_shape,
698 CornerShape,
699 SystemFlags::REDRAW
700 );
701
702 modifier!(
703 corner_top_right_shape,
705 CornerShape,
706 SystemFlags::REDRAW
707 );
708
709 modifier!(
710 corner_bottom_left_shape,
712 CornerShape,
713 SystemFlags::REDRAW
714 );
715
716 modifier!(
717 corner_bottom_right_shape,
719 CornerShape,
720 SystemFlags::REDRAW
721 );
722
723 fn corner_shape<U: std::fmt::Debug + Into<Rect<CornerShape>>>(
725 mut self,
726 value: impl Res<U>,
727 ) -> Self {
728 let entity = self.entity();
729 let current = self.current();
730 self.context().with_current(current, |cx| {
731 value.set_or_bind(cx, move |cx, v| {
732 let value = v.get_value(cx).into();
733 cx.style.corner_top_left_shape.insert(entity, value.0);
734 cx.style.corner_top_right_shape.insert(entity, value.1);
735 cx.style.corner_bottom_right_shape.insert(entity, value.2);
736 cx.style.corner_bottom_left_shape.insert(entity, value.3);
737
738 cx.needs_redraw(entity);
739 });
740 });
741
742 self
743 }
744
745 modifier!(
746 corner_top_left_smoothing,
748 f32,
749 SystemFlags::REDRAW
750 );
751
752 modifier!(
753 corner_top_right_smoothing,
755 f32,
756 SystemFlags::REDRAW
757 );
758
759 modifier!(
760 corner_bottom_left_smoothing,
762 f32,
763 SystemFlags::REDRAW
764 );
765
766 modifier!(
767 corner_bottom_right_smoothing,
769 f32,
770 SystemFlags::REDRAW
771 );
772
773 fn corner_smoothing<U: std::fmt::Debug + Into<Rect<f32>>>(
775 mut self,
776 value: impl Res<U>,
777 ) -> Self {
778 let entity = self.entity();
779 let current = self.current();
780 self.context().with_current(current, |cx| {
781 value.set_or_bind(cx, move |cx, v| {
782 let value = v.get_value(cx).into();
783 cx.style.corner_top_left_smoothing.insert(entity, value.0);
784 cx.style.corner_top_right_smoothing.insert(entity, value.1);
785 cx.style.corner_bottom_left_smoothing.insert(entity, value.2);
786 cx.style.corner_bottom_right_smoothing.insert(entity, value.3);
787
788 cx.needs_redraw(entity);
789 });
790 });
791
792 self
793 }
794
795 modifier!(
797 outline_width,
799 LengthOrPercentage,
800 SystemFlags::REDRAW
801 );
802
803 modifier!(
804 outline_color,
806 Color,
807 SystemFlags::REDRAW
808 );
809
810 modifier!(
811 outline_offset,
813 LengthOrPercentage,
814 SystemFlags::REDRAW
815 );
816
817 modifier!(
818 fill,
820 Color,
821 SystemFlags::REDRAW
822 );
823
824 modifier!(
826 cursor,
828 CursorIcon,
829 SystemFlags::empty()
830 );
831
832 fn pointer_events<U: Into<PointerEvents>>(mut self, value: impl Res<U>) -> Self {
834 let entity = self.entity();
835 let current = self.current();
836 self.context().with_current(current, |cx| {
837 value.set_or_bind(cx, move |cx, v| {
838 let value = v.get_value(cx).into();
839 cx.style.pointer_events.insert(entity, value);
840 });
841 });
842
843 self
844 }
845
846 fn transform<U: Into<Vec<Transform>>>(mut self, value: impl Res<U>) -> Self {
848 let entity = self.entity();
849 let current = self.current();
850 self.context().with_current(current, |cx| {
851 value.set_or_bind(cx, move |cx, v| {
852 let value = v.get_value(cx).into();
853 cx.style.transform.insert(entity, value);
854 cx.needs_retransform(entity);
855 cx.needs_redraw(entity);
856 });
857 });
858
859 self
860 }
861
862 fn transform_origin<U: Into<Position>>(mut self, value: impl Res<U>) -> Self {
864 let entity = self.entity();
865 let current = self.current();
866 self.context().with_current(current, |cx| {
867 value.set_or_bind(cx, move |cx, v| {
868 let value = v.get_value(cx).into();
869 let x = value.x.to_length_or_percentage();
870 let y = value.y.to_length_or_percentage();
871 cx.style.transform_origin.insert(entity, Translate { x, y });
872 cx.needs_retransform(entity);
873 cx.needs_redraw(entity);
874 });
875 });
876
877 self
878 }
879
880 modifier!(
882 translate,
886 Translate,
887 SystemFlags::RETRANSFORM | SystemFlags::REDRAW
888 );
889
890 modifier!(
892 rotate,
896 Angle,
897 SystemFlags::RETRANSFORM | SystemFlags::REDRAW
898 );
899
900 modifier!(
902 scale,
906 Scale,
907 SystemFlags::RETRANSFORM | SystemFlags::REDRAW
908 );
909}
910
911impl<V: View> StyleModifiers for Handle<'_, V> {}
912
913#[derive(Debug, Clone)]
915pub struct LinearGradientBuilder {
916 direction: LineDirection,
917 stops: Vec<ColorStop<LengthOrPercentage>>,
918}
919
920impl Default for LinearGradientBuilder {
921 fn default() -> Self {
922 Self::new()
923 }
924}
925
926impl LinearGradientBuilder {
927 pub fn new() -> Self {
929 LinearGradientBuilder { direction: LineDirection::default(), stops: Vec::new() }
930 }
931
932 pub fn with_direction(direction: impl Into<LineDirection>) -> Self {
934 LinearGradientBuilder { direction: direction.into(), stops: Vec::new() }
935 }
936
937 fn build(self) -> Gradient {
938 Gradient::Linear(LinearGradient { direction: self.direction, stops: self.stops })
939 }
940
941 pub fn add_stop(mut self, stop: impl Into<ColorStop<LengthOrPercentage>>) -> Self {
943 self.stops.push(stop.into());
944
945 self
946 }
947}
948
949impl From<LinearGradientBuilder> for Gradient {
950 fn from(value: LinearGradientBuilder) -> Self {
951 value.build()
952 }
953}
954
955#[derive(Debug, Clone)]
957pub struct ShadowBuilder {
958 shadow: Shadow,
959}
960
961impl Default for ShadowBuilder {
962 fn default() -> Self {
963 Self::new()
964 }
965}
966
967impl ShadowBuilder {
968 pub fn new() -> Self {
970 Self { shadow: Shadow::default() }
971 }
972
973 fn build(self) -> Shadow {
974 self.shadow
975 }
976
977 pub fn x_offset(mut self, offset: impl Into<Length>) -> Self {
979 self.shadow.x_offset = offset.into();
980
981 self
982 }
983
984 pub fn y_offset(mut self, offset: impl Into<Length>) -> Self {
986 self.shadow.y_offset = offset.into();
987
988 self
989 }
990
991 pub fn blur(mut self, radius: Length) -> Self {
993 self.shadow.blur_radius = Some(radius);
994
995 self
996 }
997
998 pub fn spread(mut self, radius: Length) -> Self {
1000 self.shadow.spread_radius = Some(radius);
1001
1002 self
1003 }
1004
1005 pub fn color(mut self, color: Color) -> Self {
1007 self.shadow.color = Some(color);
1008
1009 self
1010 }
1011
1012 pub fn inset(mut self) -> Self {
1014 self.shadow.inset = true;
1015
1016 self
1017 }
1018}
1019
1020impl From<ShadowBuilder> for Shadow {
1021 fn from(value: ShadowBuilder) -> Self {
1022 value.build()
1023 }
1024}