tailwind_rs_core/utilities/
backgrounds.rs

1//! Background utilities for tailwind-rs
2//!
3//! This module provides utilities for background colors, background images,
4//! background gradients, background positioning, background sizing, and background repeat.
5
6use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10/// Background attachment values
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum BackgroundAttachment {
13    /// Fixed attachment
14    Fixed,
15    /// Local attachment
16    Local,
17    /// Scroll attachment
18    Scroll,
19}
20
21/// Background clip values
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub enum BackgroundClip {
24    /// Border clip
25    Border,
26    /// Padding clip
27    Padding,
28    /// Content clip
29    Content,
30    /// Text clip
31    Text,
32}
33
34/// Background origin values
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
36pub enum BackgroundOrigin {
37    /// Border origin
38    Border,
39    /// Padding origin
40    Padding,
41    /// Content origin
42    Content,
43}
44
45/// Background position values
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
47pub enum BackgroundPosition {
48    /// Bottom position
49    Bottom,
50    /// Center position
51    Center,
52    /// Left position
53    Left,
54    /// Left bottom position
55    LeftBottom,
56    /// Left top position
57    LeftTop,
58    /// Right position
59    Right,
60    /// Right bottom position
61    RightBottom,
62    /// Right top position
63    RightTop,
64    /// Top position
65    Top,
66}
67
68/// Background repeat values
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
70pub enum BackgroundRepeat {
71    /// No repeat
72    NoRepeat,
73    /// Repeat
74    Repeat,
75    /// Repeat X
76    RepeatX,
77    /// Repeat Y
78    RepeatY,
79    /// Round repeat
80    Round,
81    /// Space repeat
82    Space,
83}
84
85/// Background size values
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
87pub enum BackgroundSize {
88    /// Auto size
89    Auto,
90    /// Cover size
91    Cover,
92    /// Contain size
93    Contain,
94}
95
96/// Background image values
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
98pub enum BackgroundImage {
99    /// None image
100    None,
101    /// Linear gradient
102    LinearGradient,
103    /// Radial gradient
104    RadialGradient,
105    /// Conic gradient
106    ConicGradient,
107}
108
109/// Gradient direction values
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
111pub enum GradientDirection {
112    /// To right
113    ToRight,
114    /// To left
115    ToLeft,
116    /// To top
117    ToTop,
118    /// To bottom
119    ToBottom,
120    /// To top right
121    ToTopRight,
122    /// To top left
123    ToTopLeft,
124    /// To bottom right
125    ToBottomRight,
126    /// To bottom left
127    ToBottomLeft,
128}
129
130/// Gradient stop values
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
132pub enum GradientStop {
133    /// From stop
134    From,
135    /// Via stop
136    Via,
137    /// To stop
138    To,
139}
140
141impl BackgroundAttachment {
142    pub fn to_class_name(&self) -> String {
143        match self {
144            BackgroundAttachment::Fixed => "fixed".to_string(),
145            BackgroundAttachment::Local => "local".to_string(),
146            BackgroundAttachment::Scroll => "scroll".to_string(),
147        }
148    }
149
150    pub fn to_css_value(&self) -> String {
151        match self {
152            BackgroundAttachment::Fixed => "fixed".to_string(),
153            BackgroundAttachment::Local => "local".to_string(),
154            BackgroundAttachment::Scroll => "scroll".to_string(),
155        }
156    }
157}
158
159impl BackgroundClip {
160    pub fn to_class_name(&self) -> String {
161        match self {
162            BackgroundClip::Border => "border".to_string(),
163            BackgroundClip::Padding => "padding".to_string(),
164            BackgroundClip::Content => "content".to_string(),
165            BackgroundClip::Text => "text".to_string(),
166        }
167    }
168
169    pub fn to_css_value(&self) -> String {
170        match self {
171            BackgroundClip::Border => "border-box".to_string(),
172            BackgroundClip::Padding => "padding-box".to_string(),
173            BackgroundClip::Content => "content-box".to_string(),
174            BackgroundClip::Text => "text".to_string(),
175        }
176    }
177}
178
179impl BackgroundOrigin {
180    pub fn to_class_name(&self) -> String {
181        match self {
182            BackgroundOrigin::Border => "border".to_string(),
183            BackgroundOrigin::Padding => "padding".to_string(),
184            BackgroundOrigin::Content => "content".to_string(),
185        }
186    }
187
188    pub fn to_css_value(&self) -> String {
189        match self {
190            BackgroundOrigin::Border => "border-box".to_string(),
191            BackgroundOrigin::Padding => "padding-box".to_string(),
192            BackgroundOrigin::Content => "content-box".to_string(),
193        }
194    }
195}
196
197impl BackgroundPosition {
198    pub fn to_class_name(&self) -> String {
199        match self {
200            BackgroundPosition::Bottom => "bottom".to_string(),
201            BackgroundPosition::Center => "center".to_string(),
202            BackgroundPosition::Left => "left".to_string(),
203            BackgroundPosition::LeftBottom => "left-bottom".to_string(),
204            BackgroundPosition::LeftTop => "left-top".to_string(),
205            BackgroundPosition::Right => "right".to_string(),
206            BackgroundPosition::RightBottom => "right-bottom".to_string(),
207            BackgroundPosition::RightTop => "right-top".to_string(),
208            BackgroundPosition::Top => "top".to_string(),
209        }
210    }
211
212    pub fn to_css_value(&self) -> String {
213        match self {
214            BackgroundPosition::Bottom => "bottom".to_string(),
215            BackgroundPosition::Center => "center".to_string(),
216            BackgroundPosition::Left => "left".to_string(),
217            BackgroundPosition::LeftBottom => "left bottom".to_string(),
218            BackgroundPosition::LeftTop => "left top".to_string(),
219            BackgroundPosition::Right => "right".to_string(),
220            BackgroundPosition::RightBottom => "right bottom".to_string(),
221            BackgroundPosition::RightTop => "right top".to_string(),
222            BackgroundPosition::Top => "top".to_string(),
223        }
224    }
225}
226
227impl BackgroundRepeat {
228    pub fn to_class_name(&self) -> String {
229        match self {
230            BackgroundRepeat::NoRepeat => "no-repeat".to_string(),
231            BackgroundRepeat::Repeat => "repeat".to_string(),
232            BackgroundRepeat::RepeatX => "repeat-x".to_string(),
233            BackgroundRepeat::RepeatY => "repeat-y".to_string(),
234            BackgroundRepeat::Round => "round".to_string(),
235            BackgroundRepeat::Space => "space".to_string(),
236        }
237    }
238
239    pub fn to_css_value(&self) -> String {
240        match self {
241            BackgroundRepeat::NoRepeat => "no-repeat".to_string(),
242            BackgroundRepeat::Repeat => "repeat".to_string(),
243            BackgroundRepeat::RepeatX => "repeat-x".to_string(),
244            BackgroundRepeat::RepeatY => "repeat-y".to_string(),
245            BackgroundRepeat::Round => "round".to_string(),
246            BackgroundRepeat::Space => "space".to_string(),
247        }
248    }
249}
250
251impl BackgroundSize {
252    pub fn to_class_name(&self) -> String {
253        match self {
254            BackgroundSize::Auto => "auto".to_string(),
255            BackgroundSize::Cover => "cover".to_string(),
256            BackgroundSize::Contain => "contain".to_string(),
257        }
258    }
259
260    pub fn to_css_value(&self) -> String {
261        match self {
262            BackgroundSize::Auto => "auto".to_string(),
263            BackgroundSize::Cover => "cover".to_string(),
264            BackgroundSize::Contain => "contain".to_string(),
265        }
266    }
267}
268
269impl BackgroundImage {
270    pub fn to_class_name(&self) -> String {
271        match self {
272            BackgroundImage::None => "none".to_string(),
273            BackgroundImage::LinearGradient => "gradient-to-r".to_string(),
274            BackgroundImage::RadialGradient => "radial-gradient".to_string(),
275            BackgroundImage::ConicGradient => "conic-gradient".to_string(),
276        }
277    }
278
279    pub fn to_css_value(&self) -> String {
280        match self {
281            BackgroundImage::None => "none".to_string(),
282            BackgroundImage::LinearGradient => {
283                "linear-gradient(to right, var(--tw-gradient-stops))".to_string()
284            }
285            BackgroundImage::RadialGradient => {
286                "radial-gradient(ellipse at center, var(--tw-gradient-stops))".to_string()
287            }
288            BackgroundImage::ConicGradient => {
289                "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))".to_string()
290            }
291        }
292    }
293}
294
295impl GradientDirection {
296    pub fn to_class_name(&self) -> String {
297        match self {
298            GradientDirection::ToRight => "to-r".to_string(),
299            GradientDirection::ToLeft => "to-l".to_string(),
300            GradientDirection::ToTop => "to-t".to_string(),
301            GradientDirection::ToBottom => "to-b".to_string(),
302            GradientDirection::ToTopRight => "to-tr".to_string(),
303            GradientDirection::ToTopLeft => "to-tl".to_string(),
304            GradientDirection::ToBottomRight => "to-br".to_string(),
305            GradientDirection::ToBottomLeft => "to-bl".to_string(),
306        }
307    }
308
309    pub fn to_css_value(&self) -> String {
310        match self {
311            GradientDirection::ToRight => "to right".to_string(),
312            GradientDirection::ToLeft => "to left".to_string(),
313            GradientDirection::ToTop => "to top".to_string(),
314            GradientDirection::ToBottom => "to bottom".to_string(),
315            GradientDirection::ToTopRight => "to top right".to_string(),
316            GradientDirection::ToTopLeft => "to top left".to_string(),
317            GradientDirection::ToBottomRight => "to bottom right".to_string(),
318            GradientDirection::ToBottomLeft => "to bottom left".to_string(),
319        }
320    }
321}
322
323impl GradientStop {
324    pub fn to_class_name(&self) -> String {
325        match self {
326            GradientStop::From => "from".to_string(),
327            GradientStop::Via => "via".to_string(),
328            GradientStop::To => "to".to_string(),
329        }
330    }
331
332    pub fn to_css_value(&self) -> String {
333        match self {
334            GradientStop::From => "from".to_string(),
335            GradientStop::Via => "via".to_string(),
336            GradientStop::To => "to".to_string(),
337        }
338    }
339}
340
341impl fmt::Display for BackgroundAttachment {
342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343        write!(f, "{}", self.to_class_name())
344    }
345}
346
347impl fmt::Display for BackgroundClip {
348    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349        write!(f, "{}", self.to_class_name())
350    }
351}
352
353impl fmt::Display for BackgroundOrigin {
354    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
355        write!(f, "{}", self.to_class_name())
356    }
357}
358
359impl fmt::Display for BackgroundPosition {
360    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361        write!(f, "{}", self.to_class_name())
362    }
363}
364
365impl fmt::Display for BackgroundRepeat {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        write!(f, "{}", self.to_class_name())
368    }
369}
370
371impl fmt::Display for BackgroundSize {
372    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373        write!(f, "{}", self.to_class_name())
374    }
375}
376
377impl fmt::Display for BackgroundImage {
378    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379        write!(f, "{}", self.to_class_name())
380    }
381}
382
383impl fmt::Display for GradientDirection {
384    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385        write!(f, "{}", self.to_class_name())
386    }
387}
388
389impl fmt::Display for GradientStop {
390    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391        write!(f, "{}", self.to_class_name())
392    }
393}
394
395/// Trait for adding background attachment utilities to a class builder
396pub trait BackgroundAttachmentUtilities {
397    fn background_attachment(self, attachment: BackgroundAttachment) -> Self;
398}
399
400impl BackgroundAttachmentUtilities for ClassBuilder {
401    fn background_attachment(self, attachment: BackgroundAttachment) -> Self {
402        self.class(format!("bg-{}", attachment.to_class_name()))
403    }
404}
405
406/// Trait for adding background clip utilities to a class builder
407pub trait BackgroundClipUtilities {
408    fn background_clip(self, clip: BackgroundClip) -> Self;
409}
410
411impl BackgroundClipUtilities for ClassBuilder {
412    fn background_clip(self, clip: BackgroundClip) -> Self {
413        self.class(format!("bg-clip-{}", clip.to_class_name()))
414    }
415}
416
417/// Trait for adding background origin utilities to a class builder
418pub trait BackgroundOriginUtilities {
419    fn background_origin(self, origin: BackgroundOrigin) -> Self;
420}
421
422impl BackgroundOriginUtilities for ClassBuilder {
423    fn background_origin(self, origin: BackgroundOrigin) -> Self {
424        self.class(format!("bg-origin-{}", origin.to_class_name()))
425    }
426}
427
428/// Trait for adding background position utilities to a class builder
429pub trait BackgroundPositionUtilities {
430    fn background_position(self, position: BackgroundPosition) -> Self;
431}
432
433impl BackgroundPositionUtilities for ClassBuilder {
434    fn background_position(self, position: BackgroundPosition) -> Self {
435        self.class(format!("bg-{}", position.to_class_name()))
436    }
437}
438
439/// Trait for adding background repeat utilities to a class builder
440pub trait BackgroundRepeatUtilities {
441    fn background_repeat(self, repeat: BackgroundRepeat) -> Self;
442}
443
444impl BackgroundRepeatUtilities for ClassBuilder {
445    fn background_repeat(self, repeat: BackgroundRepeat) -> Self {
446        self.class(format!("bg-{}", repeat.to_class_name()))
447    }
448}
449
450/// Trait for adding background size utilities to a class builder
451pub trait BackgroundSizeUtilities {
452    fn background_size(self, size: BackgroundSize) -> Self;
453}
454
455impl BackgroundSizeUtilities for ClassBuilder {
456    fn background_size(self, size: BackgroundSize) -> Self {
457        self.class(format!("bg-{}", size.to_class_name()))
458    }
459}
460
461/// Trait for adding background image utilities to a class builder
462pub trait BackgroundImageUtilities {
463    fn background_image(self, image: BackgroundImage) -> Self;
464}
465
466impl BackgroundImageUtilities for ClassBuilder {
467    fn background_image(self, image: BackgroundImage) -> Self {
468        self.class(format!("bg-{}", image.to_class_name()))
469    }
470}
471
472/// Trait for adding gradient direction utilities to a class builder
473pub trait GradientDirectionUtilities {
474    fn gradient_direction(self, direction: GradientDirection) -> Self;
475}
476
477impl GradientDirectionUtilities for ClassBuilder {
478    fn gradient_direction(self, direction: GradientDirection) -> Self {
479        self.class(format!("bg-gradient-{}", direction.to_class_name()))
480    }
481}
482
483/// Trait for adding gradient stop utilities to a class builder
484pub trait GradientStopUtilities {
485    fn gradient_from(self, color: crate::utilities::colors::Color) -> Self;
486    fn gradient_via(self, color: crate::utilities::colors::Color) -> Self;
487    fn gradient_to(self, color: crate::utilities::colors::Color) -> Self;
488}
489
490impl GradientStopUtilities for ClassBuilder {
491    fn gradient_from(self, color: crate::utilities::colors::Color) -> Self {
492        self.class(format!("from-{}", color.to_class_name()))
493    }
494
495    fn gradient_via(self, color: crate::utilities::colors::Color) -> Self {
496        self.class(format!("via-{}", color.to_class_name()))
497    }
498
499    fn gradient_to(self, color: crate::utilities::colors::Color) -> Self {
500        self.class(format!("to-{}", color.to_class_name()))
501    }
502}
503
504#[cfg(test)]
505mod tests {
506    use super::*;
507    use crate::utilities::colors::{Color, ColorPalette, ColorShade};
508
509    #[test]
510    fn test_background_attachment_utilities() {
511        let classes = ClassBuilder::new()
512            .background_attachment(BackgroundAttachment::Fixed)
513            .background_attachment(BackgroundAttachment::Local)
514            .background_attachment(BackgroundAttachment::Scroll)
515            .build();
516
517        let css_classes = classes.to_css_classes();
518        assert!(css_classes.contains("bg-fixed"));
519        assert!(css_classes.contains("bg-local"));
520        assert!(css_classes.contains("bg-scroll"));
521    }
522
523    #[test]
524    fn test_background_clip_utilities() {
525        let classes = ClassBuilder::new()
526            .background_clip(BackgroundClip::Border)
527            .background_clip(BackgroundClip::Padding)
528            .background_clip(BackgroundClip::Content)
529            .background_clip(BackgroundClip::Text)
530            .build();
531
532        let css_classes = classes.to_css_classes();
533        assert!(css_classes.contains("bg-clip-border"));
534        assert!(css_classes.contains("bg-clip-padding"));
535        assert!(css_classes.contains("bg-clip-content"));
536        assert!(css_classes.contains("bg-clip-text"));
537    }
538
539    #[test]
540    fn test_background_origin_utilities() {
541        let classes = ClassBuilder::new()
542            .background_origin(BackgroundOrigin::Border)
543            .background_origin(BackgroundOrigin::Padding)
544            .background_origin(BackgroundOrigin::Content)
545            .build();
546
547        let css_classes = classes.to_css_classes();
548        assert!(css_classes.contains("bg-origin-border"));
549        assert!(css_classes.contains("bg-origin-padding"));
550        assert!(css_classes.contains("bg-origin-content"));
551    }
552
553    #[test]
554    fn test_background_position_utilities() {
555        let classes = ClassBuilder::new()
556            .background_position(BackgroundPosition::Bottom)
557            .background_position(BackgroundPosition::Center)
558            .background_position(BackgroundPosition::Left)
559            .background_position(BackgroundPosition::Right)
560            .background_position(BackgroundPosition::Top)
561            .build();
562
563        let css_classes = classes.to_css_classes();
564        assert!(css_classes.contains("bg-bottom"));
565        assert!(css_classes.contains("bg-center"));
566        assert!(css_classes.contains("bg-left"));
567        assert!(css_classes.contains("bg-right"));
568        assert!(css_classes.contains("bg-top"));
569    }
570
571    #[test]
572    fn test_background_repeat_utilities() {
573        let classes = ClassBuilder::new()
574            .background_repeat(BackgroundRepeat::NoRepeat)
575            .background_repeat(BackgroundRepeat::Repeat)
576            .background_repeat(BackgroundRepeat::RepeatX)
577            .background_repeat(BackgroundRepeat::RepeatY)
578            .background_repeat(BackgroundRepeat::Round)
579            .background_repeat(BackgroundRepeat::Space)
580            .build();
581
582        let css_classes = classes.to_css_classes();
583        assert!(css_classes.contains("bg-no-repeat"));
584        assert!(css_classes.contains("bg-repeat"));
585        assert!(css_classes.contains("bg-repeat-x"));
586        assert!(css_classes.contains("bg-repeat-y"));
587        assert!(css_classes.contains("bg-round"));
588        assert!(css_classes.contains("bg-space"));
589    }
590
591    #[test]
592    fn test_background_size_utilities() {
593        let classes = ClassBuilder::new()
594            .background_size(BackgroundSize::Auto)
595            .background_size(BackgroundSize::Cover)
596            .background_size(BackgroundSize::Contain)
597            .build();
598
599        let css_classes = classes.to_css_classes();
600        assert!(css_classes.contains("bg-auto"));
601        assert!(css_classes.contains("bg-cover"));
602        assert!(css_classes.contains("bg-contain"));
603    }
604
605    #[test]
606    fn test_background_image_utilities() {
607        let classes = ClassBuilder::new()
608            .background_image(BackgroundImage::None)
609            .background_image(BackgroundImage::LinearGradient)
610            .background_image(BackgroundImage::RadialGradient)
611            .background_image(BackgroundImage::ConicGradient)
612            .build();
613
614        let css_classes = classes.to_css_classes();
615        assert!(css_classes.contains("bg-none"));
616        assert!(css_classes.contains("bg-gradient-to-r"));
617        assert!(css_classes.contains("bg-radial-gradient"));
618        assert!(css_classes.contains("bg-conic-gradient"));
619    }
620
621    #[test]
622    fn test_gradient_direction_utilities() {
623        let classes = ClassBuilder::new()
624            .gradient_direction(GradientDirection::ToRight)
625            .gradient_direction(GradientDirection::ToLeft)
626            .gradient_direction(GradientDirection::ToTop)
627            .gradient_direction(GradientDirection::ToBottom)
628            .gradient_direction(GradientDirection::ToTopRight)
629            .gradient_direction(GradientDirection::ToTopLeft)
630            .gradient_direction(GradientDirection::ToBottomRight)
631            .gradient_direction(GradientDirection::ToBottomLeft)
632            .build();
633
634        let css_classes = classes.to_css_classes();
635        assert!(css_classes.contains("bg-gradient-to-r"));
636        assert!(css_classes.contains("bg-gradient-to-l"));
637        assert!(css_classes.contains("bg-gradient-to-t"));
638        assert!(css_classes.contains("bg-gradient-to-b"));
639        assert!(css_classes.contains("bg-gradient-to-tr"));
640        assert!(css_classes.contains("bg-gradient-to-tl"));
641        assert!(css_classes.contains("bg-gradient-to-br"));
642        assert!(css_classes.contains("bg-gradient-to-bl"));
643    }
644
645    #[test]
646    fn test_gradient_stop_utilities() {
647        let classes = ClassBuilder::new()
648            .gradient_from(Color::new(ColorPalette::Blue, ColorShade::Shade500))
649            .gradient_via(Color::new(ColorPalette::Purple, ColorShade::Shade500))
650            .gradient_to(Color::new(ColorPalette::Pink, ColorShade::Shade500))
651            .build();
652
653        let css_classes = classes.to_css_classes();
654        assert!(css_classes.contains("from-blue-500"));
655        assert!(css_classes.contains("via-purple-500"));
656        assert!(css_classes.contains("to-pink-500"));
657    }
658
659    #[test]
660    fn test_complex_background_combination() {
661        let classes = ClassBuilder::new()
662            .background_attachment(BackgroundAttachment::Fixed)
663            .background_clip(BackgroundClip::Padding)
664            .background_origin(BackgroundOrigin::Border)
665            .background_position(BackgroundPosition::Center)
666            .background_repeat(BackgroundRepeat::NoRepeat)
667            .background_size(BackgroundSize::Cover)
668            .background_image(BackgroundImage::LinearGradient)
669            .gradient_direction(GradientDirection::ToRight)
670            .gradient_from(Color::new(ColorPalette::Blue, ColorShade::Shade500))
671            .gradient_to(Color::new(ColorPalette::Red, ColorShade::Shade500))
672            .build();
673
674        let css_classes = classes.to_css_classes();
675        assert!(css_classes.contains("bg-fixed"));
676        assert!(css_classes.contains("bg-clip-padding"));
677        assert!(css_classes.contains("bg-origin-border"));
678        assert!(css_classes.contains("bg-center"));
679        assert!(css_classes.contains("bg-no-repeat"));
680        assert!(css_classes.contains("bg-cover"));
681        assert!(css_classes.contains("bg-gradient-to-r"));
682        assert!(css_classes.contains("from-blue-500"));
683        assert!(css_classes.contains("to-red-500"));
684    }
685
686    /// Test that all Week 8 background utilities are implemented
687    #[test]
688    fn test_week8_background_utilities() {
689        // Test all Week 8 background utilities
690        let classes = ClassBuilder::new()
691            // Background Properties
692            .background_attachment(BackgroundAttachment::Fixed)
693            .background_attachment(BackgroundAttachment::Local)
694            .background_attachment(BackgroundAttachment::Scroll)
695            .background_clip(BackgroundClip::Border)
696            .background_clip(BackgroundClip::Padding)
697            .background_clip(BackgroundClip::Content)
698            .background_clip(BackgroundClip::Text)
699            .background_position(BackgroundPosition::Bottom)
700            .background_position(BackgroundPosition::Center)
701            .background_position(BackgroundPosition::Left)
702            .background_position(BackgroundPosition::Right)
703            .background_position(BackgroundPosition::Top)
704            .background_repeat(BackgroundRepeat::Repeat)
705            .background_repeat(BackgroundRepeat::NoRepeat)
706            .background_repeat(BackgroundRepeat::RepeatX)
707            .background_repeat(BackgroundRepeat::RepeatY)
708            .background_repeat(BackgroundRepeat::Round)
709            .background_repeat(BackgroundRepeat::Space)
710            .background_size(BackgroundSize::Auto)
711            .background_size(BackgroundSize::Cover)
712            .background_size(BackgroundSize::Contain)
713            .build();
714
715        let css_classes = classes.to_css_classes();
716
717        // Background Properties
718        assert!(css_classes.contains("bg-fixed"));
719        assert!(css_classes.contains("bg-local"));
720        assert!(css_classes.contains("bg-scroll"));
721        assert!(css_classes.contains("bg-clip-border"));
722        assert!(css_classes.contains("bg-clip-padding"));
723        assert!(css_classes.contains("bg-clip-content"));
724        assert!(css_classes.contains("bg-clip-text"));
725        assert!(css_classes.contains("bg-bottom"));
726        assert!(css_classes.contains("bg-center"));
727        assert!(css_classes.contains("bg-left"));
728        assert!(css_classes.contains("bg-right"));
729        assert!(css_classes.contains("bg-top"));
730        assert!(css_classes.contains("bg-repeat"));
731        assert!(css_classes.contains("bg-no-repeat"));
732        assert!(css_classes.contains("bg-repeat-x"));
733        assert!(css_classes.contains("bg-repeat-y"));
734        assert!(css_classes.contains("bg-round"));
735        assert!(css_classes.contains("bg-space"));
736        assert!(css_classes.contains("bg-auto"));
737        assert!(css_classes.contains("bg-cover"));
738        assert!(css_classes.contains("bg-contain"));
739    }
740}