1pub mod content;
3pub mod font_family;
4pub mod font_size;
5pub mod font_smoothing;
6pub mod font_style;
7pub mod font_variant_numeric;
8pub mod font_weight;
9pub mod letter_spacing;
10pub mod line_clamp;
11pub mod line_height;
12pub mod list_style_position;
13pub mod list_style_type;
14pub mod text_align;
15pub mod text_color;
16pub mod text_decoration;
17pub mod text_decoration_color;
18pub mod text_decoration_style;
19pub mod text_decoration_thickness;
20pub mod text_indent;
21pub mod text_overflow;
22pub mod text_transform;
23pub mod text_underline_offset;
24pub mod vertical_align;
25pub mod whitespace;
26pub mod text_wrap;
27pub mod word_break;
28
29#[cfg(test)]
30mod tests {
31 use crate::{generate, utils::testing::base_config};
32
33 use pretty_assertions::assert_eq;
34
35 #[test]
36 fn content() {
37 assert_eq!(
38 generate(["before:content-none"], &base_config()),
39 r".before\:content-none::before {
40 --en-content: none;
41 content: var(--en-content);
42}"
43 );
44 assert_eq!(
45 generate(["before:content-['1234_some_words']"], &base_config()),
46 r".before\:content-\[\'1234_some_words\'\]::before {
47 --en-content: '1234 some words';
48 content: var(--en-content);
49}"
50 );
51 assert_eq!(
52 generate(["before:content-[':-><-:']"], &base_config()),
53 r".before\:content-\[\'\:-\>\<-\:\'\]::before {
54 --en-content: ':-><-:';
55 content: var(--en-content);
56}"
57 );
58 assert_eq!(
59 generate(["before:content-['[inside]']"], &base_config()),
60 r".before\:content-\[\'\[inside\]\'\]::before {
61 --en-content: '[inside]';
62 content: var(--en-content);
63}"
64 );
65 }
66
67 #[test]
68 fn font_family() {
69 assert_eq!(
70 generate(["font-mono"], &base_config()),
71 r#".font-mono {
72 font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
73}"#
74 );
75 assert_eq!(
76 generate(["font-['Open_Sans',Roboto,sans-serif]"], &base_config()),
77 r".font-\[\'Open_Sans\'\,Roboto\,sans-serif\] {
78 font-family: 'Open Sans',Roboto,sans-serif;
79}"
80 );
81 assert_eq!(
82 generate(["font-[\u{fb17}\u{fb17}]"], &base_config()),
83 ".font-\\[\u{fb17}\u{fb17}\\] {
84 font-family: \u{fb17}\u{fb17};
85}"
86 );
87 }
88
89 #[test]
90 #[allow(clippy::too_many_lines)]
91 fn font_size() {
92 assert_eq!(
93 generate(["text-xs"], &base_config()),
94 ".text-xs {
95 font-size: 0.75rem;
96 line-height: 1rem;
97}"
98 );
99 assert_eq!(
100 generate(["text-sm"], &base_config()),
101 ".text-sm {
102 font-size: 0.875rem;
103 line-height: 1.25rem;
104}"
105 );
106 assert_eq!(
107 generate(["text-base"], &base_config()),
108 ".text-base {
109 font-size: 1rem;
110 line-height: 1.5rem;
111}"
112 );
113 assert_eq!(
114 generate(["text-lg"], &base_config()),
115 ".text-lg {
116 font-size: 1.125rem;
117 line-height: 1.75rem;
118}"
119 );
120 assert_eq!(
121 generate(["text-xl"], &base_config()),
122 ".text-xl {
123 font-size: 1.25rem;
124 line-height: 1.75rem;
125}"
126 );
127 assert_eq!(
128 generate(["text-2xl"], &base_config()),
129 ".text-2xl {
130 font-size: 1.5rem;
131 line-height: 2rem;
132}"
133 );
134 assert_eq!(
135 generate(["text-3xl"], &base_config()),
136 ".text-3xl {
137 font-size: 1.875rem;
138 line-height: 2.25rem;
139}"
140 );
141 assert_eq!(
142 generate(["text-4xl"], &base_config()),
143 ".text-4xl {
144 font-size: 2.25rem;
145 line-height: 2.5rem;
146}"
147 );
148 assert_eq!(
149 generate(["text-5xl"], &base_config()),
150 ".text-5xl {
151 font-size: 3rem;
152 line-height: 1;
153}"
154 );
155 assert_eq!(
156 generate(["text-6xl"], &base_config()),
157 ".text-6xl {
158 font-size: 3.75rem;
159 line-height: 1;
160}"
161 );
162 assert_eq!(
163 generate(["text-7xl"], &base_config()),
164 ".text-7xl {
165 font-size: 4.5rem;
166 line-height: 1;
167}"
168 );
169 assert_eq!(
170 generate(["text-8xl"], &base_config()),
171 ".text-8xl {
172 font-size: 6rem;
173 line-height: 1;
174}"
175 );
176 assert_eq!(
177 generate(["text-9xl"], &base_config()),
178 ".text-9xl {
179 font-size: 8rem;
180 line-height: 1;
181}"
182 );
183 assert_eq!(
184 generate(["text-[18px]"], &base_config()),
185 r".text-\[18px\] {
186 font-size: 18px;
187}"
188 );
189 assert_eq!(
190 generate(["text-[10%]"], &base_config()),
191 r".text-\[10\%\] {
192 font-size: 10%;
193}"
194 );
195 assert_eq!(
196 generate(["text-[x-large]"], &base_config()),
197 r".text-\[x-large\] {
198 font-size: x-large;
199}"
200 );
201 assert_eq!(
202 generate(["text-[smaller]"], &base_config()),
203 r".text-\[smaller\] {
204 font-size: smaller;
205}"
206 );
207 }
208
209 #[test]
210 fn font_smoothing() {
211 assert_eq!(
212 generate(["antialised"], &base_config()),
213 ".antialised {
214 -webkit-font-smoothing: antialiased;
215 -moz-osx-font-smoothing: grayscale;
216}"
217 );
218 assert_eq!(
219 generate(["subpixel-antialised"], &base_config()),
220 ".subpixel-antialised {
221 -webkit-font-smoothing: auto;
222 -moz-osx-font-smoothing: auto;
223}"
224 );
225 }
226
227 #[test]
228 fn font_style() {
229 assert_eq!(
230 generate(["italic"], &base_config()),
231 ".italic {
232 font-style: italic;
233}"
234 );
235 assert_eq!(
236 generate(["not-italic"], &base_config()),
237 ".not-italic {
238 font-style: normal;
239}"
240 );
241 }
242
243 #[test]
244 fn font_variant_numeric() {
245 assert_eq!(
246 generate(["normal-nums"], &base_config()),
247 ".normal-nums {
248 font-variant-numeric: normal;
249}"
250 );
251 assert_eq!(
252 generate(["ordinal"], &base_config()),
253 ".ordinal {
254 --en-ordinal: ordinal;
255 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
256}"
257 );
258 assert_eq!(
259 generate(["slashed-zero"], &base_config()),
260 ".slashed-zero {
261 --en-slashed-zero: slashed-zero;
262 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
263}"
264 );
265 assert_eq!(
266 generate(["lining-nums"], &base_config()),
267 ".lining-nums {
268 --en-numeric-figure: lining-nums;
269 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
270}"
271 );
272 assert_eq!(
273 generate(["oldstyle-nums"], &base_config()),
274 ".oldstyle-nums {
275 --en-numeric-figure: oldstyle-nums;
276 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
277}"
278 );
279 assert_eq!(
280 generate(["proportional-nums"], &base_config()),
281 ".proportional-nums {
282 --en-numeric-spacing: proportional-nums;
283 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
284}"
285 );
286 assert_eq!(
287 generate(["tabular-nums"], &base_config()),
288 ".tabular-nums {
289 --en-numeric-spacing: tabular-nums;
290 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
291}"
292 );
293 assert_eq!(
294 generate(["diagonal-fractions"], &base_config()),
295 ".diagonal-fractions {
296 --en-numeric-fraction: diagonal-fractions;
297 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
298}"
299 );
300 assert_eq!(
301 generate(["stacked-fractions"], &base_config()),
302 ".stacked-fractions {
303 --en-numeric-fraction: stacked-fractions;
304 font-variant-numeric: var(--en-ordinal) var(--en-slashed-zero) var(--en-numeric-figure) var(--en-numeric-spacing) var(--en-numeric-fraction);
305}"
306 );
307 }
308
309 #[test]
310 fn font_weight() {
311 assert_eq!(
312 generate(["font-thin"], &base_config()),
313 ".font-thin {
314 font-weight: 100;
315}"
316 );
317 assert_eq!(
318 generate(["font-extralight"], &base_config()),
319 ".font-extralight {
320 font-weight: 200;
321}"
322 );
323 assert_eq!(
324 generate(["font-light"], &base_config()),
325 ".font-light {
326 font-weight: 300;
327}"
328 );
329 assert_eq!(
330 generate(["font-normal"], &base_config()),
331 ".font-normal {
332 font-weight: 400;
333}"
334 );
335 assert_eq!(
336 generate(["font-medium"], &base_config()),
337 ".font-medium {
338 font-weight: 500;
339}"
340 );
341 assert_eq!(
342 generate(["font-semibold"], &base_config()),
343 ".font-semibold {
344 font-weight: 600;
345}"
346 );
347 assert_eq!(
348 generate(["font-bold"], &base_config()),
349 ".font-bold {
350 font-weight: 700;
351}"
352 );
353 assert_eq!(
354 generate(["font-extrabold"], &base_config()),
355 ".font-extrabold {
356 font-weight: 800;
357}"
358 );
359 assert_eq!(
360 generate(["font-black"], &base_config()),
361 ".font-black {
362 font-weight: 900;
363}"
364 );
365 assert_eq!(
366 generate(["font-[50]"], &base_config()),
367 r".font-\[50\] {
368 font-weight: 50;
369}"
370 );
371 }
372
373 #[test]
374 fn letter_spacing() {
375 assert_eq!(
376 generate(["tracking-tighter"], &base_config()),
377 ".tracking-tighter {
378 letter-spacing: -0.05em;
379}"
380 );
381 assert_eq!(
382 generate(["tracking-tight"], &base_config()),
383 ".tracking-tight {
384 letter-spacing: -0.025em;
385}"
386 );
387 assert_eq!(
388 generate(["tracking-normal"], &base_config()),
389 ".tracking-normal {
390 letter-spacing: 0;
391}"
392 );
393 assert_eq!(
394 generate(["tracking-wide"], &base_config()),
395 ".tracking-wide {
396 letter-spacing: 0.025em;
397}"
398 );
399 assert_eq!(
400 generate(["tracking-wider"], &base_config()),
401 ".tracking-wider {
402 letter-spacing: 0.05em;
403}"
404 );
405 assert_eq!(
406 generate(["tracking-widest"], &base_config()),
407 ".tracking-widest {
408 letter-spacing: 0.1em;
409}"
410 );
411 assert_eq!(
412 generate(["tracking-[10px]"], &base_config()),
413 r".tracking-\[10px\] {
414 letter-spacing: 10px;
415}"
416 );
417 }
418
419 #[test]
420 fn line_clamp() {
421 assert_eq!(
422 generate(["line-clamp-none"], &base_config()),
423 ".line-clamp-none {
424 -webkit-line-clamp: unset;
425}"
426 );
427 assert_eq!(
428 generate(["line-clamp-12"], &base_config()),
429 ".line-clamp-12 {
430 overflow: hidden;
431 display: -webkit-box;
432 -webkit-box-orient: vertical;
433 -webkit-line-clamp: 12;
434}"
435 );
436 }
437
438 #[test]
439 fn line_height() {
440 assert_eq!(
441 generate(["leading-none"], &base_config()),
442 ".leading-none {
443 line-height: 1;
444}"
445 );
446 assert_eq!(
447 generate(["leading-tight"], &base_config()),
448 ".leading-tight {
449 line-height: 1.25;
450}"
451 );
452 assert_eq!(
453 generate(["leading-snug"], &base_config()),
454 ".leading-snug {
455 line-height: 1.375;
456}"
457 );
458 assert_eq!(
459 generate(["leading-normal"], &base_config()),
460 ".leading-normal {
461 line-height: 1.5;
462}"
463 );
464 assert_eq!(
465 generate(["leading-relaxed"], &base_config()),
466 ".leading-relaxed {
467 line-height: 1.625;
468}"
469 );
470 assert_eq!(
471 generate(["leading-loose"], &base_config()),
472 ".leading-loose {
473 line-height: 2;
474}"
475 );
476 assert_eq!(
477 generate(["leading-4"], &base_config()),
478 ".leading-4 {
479 line-height: 1rem;
480}"
481 );
482 assert_eq!(
483 generate(["-leading-4"], &base_config()),
484 ".-leading-4 {
485 line-height: -1rem;
486}"
487 );
488 assert_eq!(
489 generate(["leading-1/2"], &base_config()),
490 r".leading-1\/2 {
491 line-height: 50%;
492}"
493 );
494 assert_eq!(
495 generate(["leading-[8]"], &base_config()),
496 r".leading-\[8\] {
497 line-height: 8;
498}"
499 );
500 assert_eq!(
501 generate(["leading-[16px]"], &base_config()),
502 r".leading-\[16px\] {
503 line-height: 16px;
504}"
505 );
506 assert_eq!(
507 generate(["leading-[22%]"], &base_config()),
508 r".leading-\[22\%\] {
509 line-height: 22%;
510}"
511 );
512 }
513
514 #[test]
515 fn list_style_position() {
516 assert_eq!(
517 generate(["list-inside"], &base_config()),
518 ".list-inside {
519 list-style-position: inside;
520}"
521 );
522 assert_eq!(
523 generate(["list-outside"], &base_config()),
524 ".list-outside {
525 list-style-position: outside;
526}"
527 );
528 }
529
530 #[test]
531 fn list_style_type() {
532 assert_eq!(
533 generate(["list-disc"], &base_config()),
534 ".list-disc {
535 list-style-type: disc;
536}"
537 );
538 assert_eq!(
539 generate(["list-decimal"], &base_config()),
540 ".list-decimal {
541 list-style-type: decimal;
542}"
543 );
544 assert_eq!(
545 generate(["list-none"], &base_config()),
546 ".list-none {
547 list-style-type: none;
548}"
549 );
550 assert_eq!(
551 generate(["list-[greek]"], &base_config()),
552 r".list-\[greek\] {
553 list-style-type: greek;
554}"
555 );
556 }
557
558 #[test]
559 fn text_align() {
560 assert_eq!(
561 generate(["text-center"], &base_config()),
562 ".text-center {
563 text-align: center;
564}"
565 );
566 assert_eq!(
567 generate(["text-justify"], &base_config()),
568 ".text-justify {
569 text-align: justify;
570}"
571 );
572 }
573
574 #[test]
575 fn text_color() {
576 assert_eq!(
577 generate(["text-red-400"], &base_config()),
578 ".text-red-400 {
579 color: oklch(70.4% .191 22.216);
580}"
581 );
582 assert_eq!(
583 generate(["text-[rgb(12,12,12)]"], &base_config()),
584 r".text-\[rgb\(12\,12\,12\)\] {
585 color: rgb(12,12,12);
586}"
587 );
588 assert_eq!(
589 generate(["text-[purple]"], &base_config()),
590 r".text-\[purple\] {
591 color: purple;
592}"
593 );
594 }
595
596 #[test]
597 fn text_decoration() {
598 assert_eq!(
599 generate(["underline"], &base_config()),
600 ".underline {
601 -webkit-text-decoration-line: underline;
602 text-decoration-line: underline;
603}"
604 );
605 assert_eq!(
606 generate(["no-underline"], &base_config()),
607 ".no-underline {
608 -webkit-text-decoration-line: none;
609 text-decoration-line: none;
610}"
611 );
612 }
613
614 #[test]
615 fn text_decoration_color() {
616 assert_eq!(
617 generate(["decoration-red-400"], &base_config()),
618 ".decoration-red-400 {
619 -webkit-text-decoration-color: oklch(70.4% .191 22.216);
620 text-decoration-color: oklch(70.4% .191 22.216);
621}"
622 );
623 assert_eq!(
624 generate(["decoration-[rgb(12,12,12)]"], &base_config()),
625 r".decoration-\[rgb\(12\,12\,12\)\] {
626 -webkit-text-decoration-color: rgb(12,12,12);
627 text-decoration-color: rgb(12,12,12);
628}"
629 );
630 assert_eq!(
631 generate(["decoration-[purple]"], &base_config()),
632 r".decoration-\[purple\] {
633 -webkit-text-decoration-color: purple;
634 text-decoration-color: purple;
635}"
636 );
637 }
638
639 #[test]
640 fn text_decoration_style() {
641 assert_eq!(
642 generate(["decoration-wavy"], &base_config()),
643 ".decoration-wavy {
644 text-decoration-style: wavy;
645}"
646 );
647 }
648
649 #[test]
650 fn text_decoration_thickness() {
651 assert_eq!(
652 generate(["decoration-auto"], &base_config()),
653 ".decoration-auto {
654 text-decoration-thickness: auto;
655}"
656 );
657 assert_eq!(
658 generate(["decoration-from-font"], &base_config()),
659 ".decoration-from-font {
660 text-decoration-thickness: from-font;
661}"
662 );
663 assert_eq!(
664 generate(["decoration-12"], &base_config()),
665 ".decoration-12 {
666 text-decoration-thickness: 12px;
667}"
668 );
669 assert_eq!(
670 generate(["decoration-[4.2rem]"], &base_config()),
671 r".decoration-\[4\.2rem\] {
672 text-decoration-thickness: 4.2rem;
673}"
674 );
675 assert_eq!(
676 generate(["decoration-[2%]"], &base_config()),
677 r".decoration-\[2\%\] {
678 text-decoration-thickness: 2%;
679}"
680 );
681 }
682
683 #[test]
684 fn text_indent() {
685 assert_eq!(
686 generate(["indent-2"], &base_config()),
687 ".indent-2 {
688 text-indent: 0.5rem;
689}"
690 );
691 assert_eq!(
692 generate(["-indent-2"], &base_config()),
693 ".-indent-2 {
694 text-indent: -0.5rem;
695}"
696 );
697 assert_eq!(
698 generate(["indent-[20px]"], &base_config()),
699 r".indent-\[20px\] {
700 text-indent: 20px;
701}"
702 );
703 }
704
705 #[test]
706 fn text_overflow() {
707 assert_eq!(
708 generate(["truncate"], &base_config()),
709 ".truncate {
710 overflow: hidden;
711 text-overflow: ellipsis;
712 white-space: nowrap;
713}"
714 );
715 assert_eq!(
716 generate(["text-ellipsis"], &base_config()),
717 ".text-ellipsis {
718 text-overflow: ellipsis;
719}"
720 );
721 assert_eq!(
722 generate(["text-clip"], &base_config()),
723 ".text-clip {
724 text-overflow: clip;
725}"
726 );
727 }
728
729 #[test]
730 fn text_transform() {
731 assert_eq!(
732 generate(["normal-case"], &base_config()),
733 ".normal-case {
734 text-transform: none;
735}"
736 );
737 assert_eq!(
738 generate(["uppercase"], &base_config()),
739 ".uppercase {
740 text-transform: uppercase;
741}"
742 );
743 }
744
745 #[test]
746 fn text_underline_offset() {
747 assert_eq!(
748 generate(["underline-offset-auto"], &base_config()),
749 ".underline-offset-auto {
750 text-underline-offset: auto;
751}"
752 );
753 assert_eq!(
754 generate(["underline-offset-12"], &base_config()),
755 ".underline-offset-12 {
756 text-underline-offset: 12px;
757}"
758 );
759 assert_eq!(
760 generate(["underline-offset-[2rem]"], &base_config()),
761 r".underline-offset-\[2rem\] {
762 text-underline-offset: 2rem;
763}"
764 );
765 assert_eq!(
766 generate(["underline-offset-[10%]"], &base_config()),
767 r".underline-offset-\[10\%\] {
768 text-underline-offset: 10%;
769}"
770 );
771 }
772
773 #[test]
774 fn vertical_align() {
775 assert_eq!(
776 generate(["align-sub"], &base_config()),
777 ".align-sub {
778 vertical-align: sub;
779}"
780 );
781 assert_eq!(
782 generate(["align-text-top"], &base_config()),
783 ".align-text-top {
784 vertical-align: text-top;
785}"
786 );
787 }
788
789 #[test]
790 fn whitespace() {
791 assert_eq!(
792 generate(["whitespace-normal"], &base_config()),
793 ".whitespace-normal {
794 white-space: normal;
795}"
796 );
797 assert_eq!(
798 generate(["whitespace-pre-wrap"], &base_config()),
799 ".whitespace-pre-wrap {
800 white-space: pre-wrap;
801}"
802 );
803 }
804
805 #[test]
806 fn text_wrap() {
807 assert_eq!(
808 generate(["text-wrap"], &base_config()),
809 ".text-wrap {
810 text-wrap: wrap;
811}"
812 );
813 assert_eq!(
814 generate(["text-pretty"], &base_config()),
815 ".text-pretty {
816 text-wrap: pretty;
817}"
818 );
819 }
820
821 #[test]
822 fn word_break() {
823 assert_eq!(
824 generate(["break-normal"], &base_config()),
825 ".break-normal {
826 overflow-wrap: normal;
827 word-break: normal;
828}"
829 );
830 assert_eq!(
831 generate(["break-keep"], &base_config()),
832 ".break-keep {
833 word-break: keep-all;
834}"
835 );
836 }
837}