encre_css/plugins/typography/
mod.rs

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