typography-stylecss 0.7.2 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.test.js DELETED
@@ -1,1442 +0,0 @@
1
- const path = require('path')
2
- const tailwind = require('tailwindcss')
3
- const postcss = require('postcss')
4
- const typographyPlugin = require('.')
5
-
6
- let html = String.raw
7
- let css = String.raw
8
-
9
- let vars = `
10
- --tw-border-spacing-x: 0;
11
- --tw-border-spacing-y: 0;
12
- --tw-translate-x: 0;
13
- --tw-translate-y: 0;
14
- --tw-rotate: 0;
15
- --tw-skew-x: 0;
16
- --tw-skew-y: 0;
17
- --tw-scale-x: 1;
18
- --tw-scale-y: 1;
19
- --tw-pan-x: ;
20
- --tw-pan-y: ;
21
- --tw-pinch-zoom: ;
22
- --tw-scroll-snap-strictness: proximity;
23
- --tw-ordinal: ;
24
- --tw-slashed-zero: ;
25
- --tw-numeric-figure: ;
26
- --tw-numeric-spacing: ;
27
- --tw-numeric-fraction: ;
28
- --tw-ring-inset: ;
29
- --tw-ring-offset-width: 0px;
30
- --tw-ring-offset-color: #fff;
31
- --tw-ring-color: rgb(59 130 246 / 0.5);
32
- --tw-ring-offset-shadow: 0 0 #0000;
33
- --tw-ring-shadow: 0 0 #0000;
34
- --tw-shadow: 0 0 #0000;
35
- --tw-shadow-colored: 0 0 #0000;
36
- --tw-blur: ;
37
- --tw-brightness: ;
38
- --tw-contrast: ;
39
- --tw-grayscale: ;
40
- --tw-hue-rotate: ;
41
- --tw-invert: ;
42
- --tw-saturate: ;
43
- --tw-sepia: ;
44
- --tw-drop-shadow: ;
45
- --tw-backdrop-blur: ;
46
- --tw-backdrop-brightness: ;
47
- --tw-backdrop-contrast: ;
48
- --tw-backdrop-grayscale: ;
49
- --tw-backdrop-hue-rotate: ;
50
- --tw-backdrop-invert: ;
51
- --tw-backdrop-opacity: ;
52
- --tw-backdrop-saturate: ;
53
- --tw-backdrop-sepia: ;
54
- `
55
- let defaults = css`
56
- *,
57
- ::before,
58
- ::after {
59
- ${vars}
60
- }
61
- ::backdrop {
62
- ${vars}
63
- }
64
- `
65
-
66
- function run(config, plugin = tailwind) {
67
- let { currentTestName } = expect.getState()
68
- config = {
69
- ...{ plugins: [typographyPlugin], corePlugins: { preflight: false } },
70
- ...config,
71
- }
72
-
73
- return postcss(plugin(config)).process(
74
- ['@tailwind base;', '@tailwind components;', '@tailwind utilities'].join('\n'),
75
- {
76
- from: `${path.resolve(__filename)}?test=${currentTestName}`,
77
- }
78
- )
79
- }
80
-
81
- test('specificity is reduced with :where', async () => {
82
- let config = {
83
- content: [{ raw: html`<div class="prose"></div>` }],
84
- theme: {
85
- typography: {
86
- DEFAULT: {
87
- css: [
88
- {
89
- color: 'var(--tw-prose-body)',
90
- maxWidth: '65ch',
91
- '[class~="lead"]': {
92
- color: 'var(--tw-prose-lead)',
93
- },
94
- strong: {
95
- color: 'var(--tw-prose-bold)',
96
- fontWeight: '600',
97
- },
98
- 'ol[type="A"]': {
99
- listStyleType: 'upper-alpha',
100
- },
101
- 'blockquote p:first-of-type::before': {
102
- content: 'open-quote',
103
- },
104
- 'blockquote p:last-of-type::after': {
105
- content: 'close-quote',
106
- },
107
- 'h4 strong': {
108
- fontWeight: '700',
109
- },
110
- 'figure > *': {
111
- margin: 0,
112
- },
113
- 'ol > li::marker': {
114
- fontWeight: '400',
115
- color: 'var(--tw-prose-counters)',
116
- },
117
- '> ul > li p': {
118
- marginTop: '16px',
119
- marginBottom: '16px',
120
- },
121
- 'code::before': {
122
- content: '"&#96;"',
123
- },
124
- 'code::after': {
125
- content: '"&#96;"',
126
- },
127
- },
128
- ],
129
- },
130
- },
131
- },
132
- }
133
-
134
- return run(config).then((result) => {
135
- expect(result.css).toMatchFormattedCss(
136
- css`
137
- ${defaults}
138
-
139
- .prose {
140
- color: var(--tw-prose-body);
141
- max-width: 65ch;
142
- }
143
- .prose :where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
144
- color: var(--tw-prose-lead);
145
- }
146
- .prose :where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
147
- color: var(--tw-prose-bold);
148
- font-weight: 600;
149
- }
150
- .prose :where(ol[type='A']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
151
- list-style-type: upper-alpha;
152
- }
153
- .prose
154
- :where(blockquote p:first-of-type):not(:where([class~='not-prose'], [class~='not-prose']
155
- *))::before {
156
- content: open-quote;
157
- }
158
- .prose
159
- :where(blockquote p:last-of-type):not(:where([class~='not-prose'], [class~='not-prose']
160
- *))::after {
161
- content: close-quote;
162
- }
163
- .prose :where(h4 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
164
- font-weight: 700;
165
- }
166
- .prose :where(figure > *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
167
- margin: 0;
168
- }
169
- .prose :where(ol > li):not(:where([class~='not-prose'], [class~='not-prose'] *))::marker {
170
- font-weight: 400;
171
- color: var(--tw-prose-counters);
172
- }
173
- .prose
174
- :where(.prose > ul > li p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
175
- margin-top: 16px;
176
- margin-bottom: 16px;
177
- }
178
- .prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *))::before {
179
- content: '&#96;';
180
- }
181
- .prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *))::after {
182
- content: '&#96;';
183
- }
184
- `
185
- )
186
- })
187
- })
188
-
189
- test('variants', async () => {
190
- let config = {
191
- content: [{ raw: html`<div class="sm:prose hover:prose-lg lg:prose-lg"></div>` }],
192
- theme: {
193
- typography: {
194
- DEFAULT: {
195
- css: [
196
- {
197
- color: 'red',
198
- p: {
199
- color: 'lime',
200
- },
201
- '> ul > li': {
202
- color: 'purple',
203
- },
204
- },
205
- ],
206
- },
207
- lg: {
208
- css: {
209
- color: 'green',
210
- p: {
211
- color: 'tomato',
212
- },
213
- '> ul > li': {
214
- color: 'blue',
215
- },
216
- },
217
- },
218
- xl: {
219
- css: {
220
- color: 'yellow',
221
- '> ul > li': {
222
- color: 'hotpink',
223
- },
224
- },
225
- },
226
- },
227
- },
228
- }
229
-
230
- return run(config).then((result) => {
231
- expect(result.css).toMatchFormattedCss(
232
- css`
233
- ${defaults}
234
-
235
- .hover\:prose-lg:hover {
236
- color: green;
237
- }
238
- .hover\:prose-lg:hover :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
239
- color: tomato;
240
- }
241
- .hover\:prose-lg:hover
242
- :where(.hover\:prose-lg:hover
243
- > ul
244
- > li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
245
- color: blue;
246
- }
247
- @media (min-width: 640px) {
248
- .sm\:prose {
249
- color: red;
250
- }
251
- .sm\:prose :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
252
- color: lime;
253
- }
254
- .sm\:prose
255
- :where(.sm\:prose > ul > li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
256
- color: purple;
257
- }
258
- }
259
- @media (min-width: 1024px) {
260
- .lg\:prose-lg {
261
- color: green;
262
- }
263
- .lg\:prose-lg :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
264
- color: tomato;
265
- }
266
- .lg\:prose-lg
267
- :where(.lg\:prose-lg > ul > li):not(:where([class~='not-prose'], [class~='not-prose']
268
- *)) {
269
- color: blue;
270
- }
271
- }
272
- `
273
- )
274
- })
275
- })
276
-
277
- test('modifiers', async () => {
278
- let config = {
279
- content: [{ raw: html`<div class="prose prose-lg"></div>` }],
280
- theme: {
281
- typography: {
282
- DEFAULT: {
283
- css: [
284
- {
285
- color: 'var(--tw-prose-body)',
286
- maxWidth: '65ch',
287
- '[class~="lead"]': {
288
- color: 'var(--tw-prose-lead)',
289
- },
290
- strong: {
291
- color: 'var(--tw-prose-bold)',
292
- fontWeight: '600',
293
- },
294
- 'ol[type="A"]': {
295
- listStyleType: 'upper-alpha',
296
- },
297
- 'blockquote p:first-of-type::before': {
298
- content: 'open-quote',
299
- },
300
- 'blockquote p:last-of-type::after': {
301
- content: 'close-quote',
302
- },
303
- 'h4 strong': {
304
- fontWeight: '700',
305
- },
306
- 'figure > *': {
307
- margin: 0,
308
- },
309
- 'ol > li::marker': {
310
- fontWeight: '400',
311
- color: 'var(--tw-prose-counters)',
312
- },
313
- 'code::before': {
314
- content: '"&#96;"',
315
- },
316
- 'code::after': {
317
- content: '"&#96;"',
318
- },
319
- },
320
- ],
321
- },
322
- lg: {
323
- css: [
324
- {
325
- fontSize: '18px',
326
- lineHeight: '1.75',
327
- p: {
328
- marginTop: '24px',
329
- marginBottom: '24px',
330
- },
331
- '[class~="lead"]': {
332
- fontSize: '22px',
333
- },
334
- blockquote: {
335
- marginTop: '40px',
336
- marginBottom: '40px',
337
- },
338
- '> ul > li': {
339
- paddingLeft: '12px',
340
- },
341
- h1: {
342
- fontSize: '48px',
343
- marginTop: '0',
344
- marginBottom: '40px',
345
- },
346
- h2: {
347
- fontSize: '30px',
348
- marginTop: '56px',
349
- marginBottom: '32px',
350
- },
351
- h3: {
352
- fontSize: '24px',
353
- marginTop: '40px',
354
- marginBottom: '16px',
355
- },
356
- },
357
- ],
358
- },
359
- },
360
- },
361
- }
362
-
363
- return run(config).then((result) => {
364
- expect(result.css).toMatchFormattedCss(
365
- css`
366
- ${defaults}
367
-
368
- .prose {
369
- color: var(--tw-prose-body);
370
- max-width: 65ch;
371
- }
372
- .prose :where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
373
- color: var(--tw-prose-lead);
374
- }
375
- .prose :where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
376
- color: var(--tw-prose-bold);
377
- font-weight: 600;
378
- }
379
- .prose :where(ol[type='A']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
380
- list-style-type: upper-alpha;
381
- }
382
- .prose
383
- :where(blockquote p:first-of-type):not(:where([class~='not-prose'], [class~='not-prose']
384
- *))::before {
385
- content: open-quote;
386
- }
387
- .prose
388
- :where(blockquote p:last-of-type):not(:where([class~='not-prose'], [class~='not-prose']
389
- *))::after {
390
- content: close-quote;
391
- }
392
- .prose :where(h4 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
393
- font-weight: 700;
394
- }
395
- .prose :where(figure > *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
396
- margin: 0;
397
- }
398
- .prose :where(ol > li):not(:where([class~='not-prose'], [class~='not-prose'] *))::marker {
399
- font-weight: 400;
400
- color: var(--tw-prose-counters);
401
- }
402
- .prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *))::before {
403
- content: '&#96;';
404
- }
405
- .prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *))::after {
406
- content: '&#96;';
407
- }
408
- .prose-lg {
409
- font-size: 18px;
410
- line-height: 1.75;
411
- }
412
- .prose-lg :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
413
- margin-top: 24px;
414
- margin-bottom: 24px;
415
- }
416
- .prose-lg
417
- :where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
418
- font-size: 22px;
419
- }
420
- .prose-lg :where(blockquote):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
421
- margin-top: 40px;
422
- margin-bottom: 40px;
423
- }
424
- .prose-lg
425
- :where(.prose-lg > ul > li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
426
- padding-left: 12px;
427
- }
428
- .prose-lg :where(h1):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
429
- font-size: 48px;
430
- margin-top: 0;
431
- margin-bottom: 40px;
432
- }
433
- .prose-lg :where(h2):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
434
- font-size: 30px;
435
- margin-top: 56px;
436
- margin-bottom: 32px;
437
- }
438
- .prose-lg :where(h3):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
439
- font-size: 24px;
440
- margin-top: 40px;
441
- margin-bottom: 16px;
442
- }
443
- `
444
- )
445
- })
446
- })
447
-
448
- test('legacy target', async () => {
449
- let config = {
450
- plugins: [typographyPlugin({ target: 'legacy' })],
451
- content: [
452
- { raw: html`<div class="prose prose-h1:text-center prose-headings:text-ellipsis"></div>` },
453
- ],
454
- theme: {
455
- typography: {
456
- DEFAULT: {
457
- css: [
458
- {
459
- color: 'var(--tw-prose-body)',
460
- maxWidth: '65ch',
461
- '[class~="lead"]': {
462
- color: 'var(--tw-prose-lead)',
463
- },
464
- strong: {
465
- color: 'var(--tw-prose-bold)',
466
- fontWeight: '600',
467
- },
468
- 'ol[type="A"]': {
469
- listStyleType: 'upper-alpha',
470
- },
471
- 'blockquote p:first-of-type::before': {
472
- content: 'open-quote',
473
- },
474
- 'blockquote p:last-of-type::after': {
475
- content: 'close-quote',
476
- },
477
- 'h4 strong': {
478
- fontWeight: '700',
479
- },
480
- 'figure > *': {
481
- margin: 0,
482
- },
483
- 'ol > li::marker': {
484
- fontWeight: '400',
485
- color: 'var(--tw-prose-counters)',
486
- },
487
- 'code::before': {
488
- content: '"&#96;"',
489
- },
490
- 'code::after': {
491
- content: '"&#96;"',
492
- },
493
- },
494
- ],
495
- },
496
- },
497
- },
498
- }
499
-
500
- return run(config).then((result) => {
501
- expect(result.css).toMatchFormattedCss(
502
- css`
503
- ${defaults}
504
-
505
- .prose {
506
- color: var(--tw-prose-body);
507
- max-width: 65ch;
508
- }
509
- .prose [class~='lead'] {
510
- color: var(--tw-prose-lead);
511
- }
512
- .prose strong {
513
- color: var(--tw-prose-bold);
514
- font-weight: 600;
515
- }
516
- .prose ol[type='A'] {
517
- list-style-type: upper-alpha;
518
- }
519
- .prose blockquote p:first-of-type::before {
520
- content: open-quote;
521
- }
522
- .prose blockquote p:last-of-type::after {
523
- content: close-quote;
524
- }
525
- .prose h4 strong {
526
- font-weight: 700;
527
- }
528
- .prose figure > * {
529
- margin: 0;
530
- }
531
- .prose ol > li::marker {
532
- font-weight: 400;
533
- color: var(--tw-prose-counters);
534
- }
535
- .prose code::before {
536
- content: '&#96;';
537
- }
538
- .prose code::after {
539
- content: '&#96;';
540
- }
541
- .prose-headings\:text-ellipsis h1 {
542
- text-overflow: ellipsis;
543
- }
544
- .prose-headings\:text-ellipsis h2 {
545
- text-overflow: ellipsis;
546
- }
547
- .prose-headings\:text-ellipsis h3 {
548
- text-overflow: ellipsis;
549
- }
550
- .prose-headings\:text-ellipsis h4 {
551
- text-overflow: ellipsis;
552
- }
553
- .prose-headings\:text-ellipsis h5 {
554
- text-overflow: ellipsis;
555
- }
556
- .prose-headings\:text-ellipsis h6 {
557
- text-overflow: ellipsis;
558
- }
559
- .prose-headings\:text-ellipsis th {
560
- text-overflow: ellipsis;
561
- }
562
- .prose-h1\:text-center h1 {
563
- text-align: center;
564
- }
565
- `
566
- )
567
- })
568
- })
569
-
570
- test('custom class name', async () => {
571
- let config = {
572
- plugins: [typographyPlugin({ className: 'markdown' })],
573
- content: [{ raw: html`<div class="markdown"></div>` }],
574
- theme: {
575
- typography: {
576
- DEFAULT: {
577
- css: [
578
- {
579
- color: 'var(--tw-prose-body)',
580
- maxWidth: '65ch',
581
- '[class~="lead"]': {
582
- color: 'var(--tw-prose-lead)',
583
- },
584
- strong: {
585
- color: 'var(--tw-prose-bold)',
586
- fontWeight: '600',
587
- },
588
- 'ol[type="A"]': {
589
- listStyleType: 'upper-alpha',
590
- },
591
- 'blockquote p:first-of-type::before': {
592
- content: 'open-quote',
593
- },
594
- 'blockquote p:last-of-type::after': {
595
- content: 'close-quote',
596
- },
597
- 'h4 strong': {
598
- fontWeight: '700',
599
- },
600
- 'figure > *': {
601
- margin: 0,
602
- },
603
- 'ol > li::marker': {
604
- fontWeight: '400',
605
- color: 'var(--tw-prose-counters)',
606
- },
607
- 'code::before': {
608
- content: '"&#96;"',
609
- },
610
- 'code::after': {
611
- content: '"&#96;"',
612
- },
613
- },
614
- ],
615
- },
616
- },
617
- },
618
- }
619
-
620
- return run(config).then((result) => {
621
- expect(result.css).toMatchFormattedCss(
622
- css`
623
- ${defaults}
624
-
625
- .markdown {
626
- color: var(--tw-prose-body);
627
- max-width: 65ch;
628
- }
629
- .markdown
630
- :where([class~='lead']):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
631
- color: var(--tw-prose-lead);
632
- }
633
- .markdown :where(strong):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
634
- color: var(--tw-prose-bold);
635
- font-weight: 600;
636
- }
637
- .markdown
638
- :where(ol[type='A']):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
639
- list-style-type: upper-alpha;
640
- }
641
- .markdown
642
- :where(blockquote
643
- p:first-of-type):not(:where([class~='not-markdown'], [class~='not-markdown']
644
- *))::before {
645
- content: open-quote;
646
- }
647
- .markdown
648
- :where(blockquote
649
- p:last-of-type):not(:where([class~='not-markdown'], [class~='not-markdown'] *))::after {
650
- content: close-quote;
651
- }
652
- .markdown
653
- :where(h4 strong):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
654
- font-weight: 700;
655
- }
656
- .markdown
657
- :where(figure > *):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
658
- margin: 0;
659
- }
660
- .markdown
661
- :where(ol > li):not(:where([class~='not-markdown'], [class~='not-markdown'] *))::marker {
662
- font-weight: 400;
663
- color: var(--tw-prose-counters);
664
- }
665
- .markdown
666
- :where(code):not(:where([class~='not-markdown'], [class~='not-markdown'] *))::before {
667
- content: '&#96;';
668
- }
669
- .markdown
670
- :where(code):not(:where([class~='not-markdown'], [class~='not-markdown'] *))::after {
671
- content: '&#96;';
672
- }
673
- `
674
- )
675
- })
676
- })
677
-
678
- test('element variants', async () => {
679
- let config = {
680
- content: [
681
- {
682
- raw: html`<div
683
- class="
684
- prose
685
- prose-headings:underline
686
- prose-lead:italic
687
- prose-h1:text-3xl
688
- prose-h2:text-2xl
689
- prose-h3:text-xl
690
- prose-h4:text-lg
691
- prose-p:text-gray-700
692
- prose-a:font-bold
693
- prose-blockquote:italic
694
- prose-figure:mx-auto
695
- prose-figcaption:opacity-75
696
- prose-strong:font-medium
697
- prose-em:italic
698
- prose-kbd:border-b-2
699
- prose-code:font-mono
700
- prose-pre:font-mono
701
- prose-ol:pl-6
702
- prose-ul:pl-8
703
- prose-li:my-4
704
- prose-dl:pl-6
705
- prose-dt:pl-8
706
- prose-dd:my-4
707
- prose-table:my-8
708
- prose-thead:border-red-300
709
- prose-tr:border-red-200
710
- prose-th:text-left
711
- prose-td:align-center
712
- prose-img:rounded-lg
713
- prose-picture:my-8
714
- prose-video:my-12
715
- prose-hr:border-t-2
716
- "
717
- ></div>`,
718
- },
719
- ],
720
- theme: {
721
- typography: {
722
- DEFAULT: {
723
- css: [
724
- {
725
- color: 'var(--tw-prose-body)',
726
- '[class~="lead"]': {
727
- color: 'var(--tw-prose-lead)',
728
- },
729
- strong: {
730
- color: 'var(--tw-prose-bold)',
731
- fontWeight: '600',
732
- },
733
- 'h4 strong': {
734
- fontWeight: '700',
735
- },
736
- },
737
- ],
738
- },
739
- },
740
- },
741
- }
742
- return run(config).then((result) => {
743
- expect(result.css).toMatchFormattedCss(
744
- css`
745
- ${defaults}
746
-
747
- .prose {
748
- color: var(--tw-prose-body);
749
- }
750
- .prose :where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
751
- color: var(--tw-prose-lead);
752
- }
753
- .prose :where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
754
- color: var(--tw-prose-bold);
755
- font-weight: 600;
756
- }
757
- .prose :where(h4 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
758
- font-weight: 700;
759
- }
760
- .prose-headings\:underline
761
- :is(:where(h1, h2, h3, h4, h5, h6, th):not(:where([class~='not-prose'], [class~='not-prose']
762
- *))) {
763
- text-decoration-line: underline;
764
- }
765
- .prose-h1\:text-3xl
766
- :is(:where(h1):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
767
- font-size: 1.875rem;
768
- line-height: 2.25rem;
769
- }
770
- .prose-h2\:text-2xl
771
- :is(:where(h2):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
772
- font-size: 1.5rem;
773
- line-height: 2rem;
774
- }
775
- .prose-h3\:text-xl
776
- :is(:where(h3):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
777
- font-size: 1.25rem;
778
- line-height: 1.75rem;
779
- }
780
- .prose-h4\:text-lg
781
- :is(:where(h4):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
782
- font-size: 1.125rem;
783
- line-height: 1.75rem;
784
- }
785
- .prose-p\:text-gray-700
786
- :is(:where(p):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
787
- --tw-text-opacity: 1;
788
- color: rgb(55 65 81 / var(--tw-text-opacity));
789
- }
790
- .prose-a\:font-bold
791
- :is(:where(a):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
792
- font-weight: 700;
793
- }
794
- .prose-blockquote\:italic
795
- :is(:where(blockquote):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
796
- font-style: italic;
797
- }
798
- .prose-figure\:mx-auto
799
- :is(:where(figure):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
800
- margin-left: auto;
801
- margin-right: auto;
802
- }
803
- .prose-figcaption\:opacity-75
804
- :is(:where(figcaption):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
805
- opacity: 0.75;
806
- }
807
- .prose-strong\:font-medium
808
- :is(:where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
809
- font-weight: 500;
810
- }
811
- .prose-em\:italic
812
- :is(:where(em):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
813
- font-style: italic;
814
- }
815
- .prose-kbd\:border-b-2
816
- :is(:where(kbd):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
817
- border-bottom-width: 2px;
818
- }
819
- .prose-code\:font-mono
820
- :is(:where(code):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
821
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
822
- 'Courier New', monospace;
823
- }
824
- .prose-pre\:font-mono
825
- :is(:where(pre):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
826
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
827
- 'Courier New', monospace;
828
- }
829
- .prose-ol\:pl-6 :is(:where(ol):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
830
- padding-left: 1.5rem;
831
- }
832
- .prose-ul\:pl-8 :is(:where(ul):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
833
- padding-left: 2rem;
834
- }
835
- .prose-li\:my-4 :is(:where(li):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
836
- margin-top: 1rem;
837
- margin-bottom: 1rem;
838
- }
839
- .prose-dl\:pl-6 :is(:where(dl):not(:where([class~="not-prose"], [class~="not-prose"] *))) {
840
- padding-left: 1.5rem;
841
- }
842
- .prose-dt\:pl-8 :is(:where(dt):not(:where([class~="not-prose"], [class~="not-prose"] *))) {
843
- padding-left: 2rem;
844
- }
845
- .prose-dd\:my-4 :is(:where(dd):not(:where([class~="not-prose"], [class~="not-prose"] *))) {
846
- margin-top: 1rem;
847
- margin-bottom: 1rem;
848
- }
849
- .prose-table\:my-8
850
- :is(:where(table):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
851
- margin-top: 2rem;
852
- margin-bottom: 2rem;
853
- }
854
- .prose-thead\:border-red-300
855
- :is(:where(thead):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
856
- --tw-border-opacity: 1;
857
- border-color: rgb(252 165 165 / var(--tw-border-opacity));
858
- }
859
- .prose-tr\:border-red-200
860
- :is(:where(tr):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
861
- --tw-border-opacity: 1;
862
- border-color: rgb(254 202 202 / var(--tw-border-opacity));
863
- }
864
- .prose-th\:text-left
865
- :is(:where(th):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
866
- text-align: left;
867
- }
868
- .prose-img\:rounded-lg
869
- :is(:where(img):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
870
- border-radius: 0.5rem;
871
- }
872
- .prose-picture\:my-8
873
- :is(:where(picture):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
874
- margin-top: 2rem;
875
- margin-bottom: 2rem;
876
- }
877
- .prose-video\:my-12
878
- :is(:where(video):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
879
- margin-top: 3rem;
880
- margin-bottom: 3rem;
881
- }
882
- .prose-hr\:border-t-2
883
- :is(:where(hr):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
884
- border-top-width: 2px;
885
- }
886
- .prose-lead\:italic
887
- :is(:where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
888
- font-style: italic;
889
- }
890
- `
891
- )
892
- })
893
- })
894
-
895
- test('element variants with custom class name', async () => {
896
- let config = {
897
- plugins: [typographyPlugin({ className: 'markdown' })],
898
- content: [
899
- {
900
- raw: html`<div
901
- class="
902
- markdown
903
- markdown-headings:underline
904
- markdown-lead:italic
905
- markdown-h1:text-3xl
906
- markdown-h2:text-2xl
907
- markdown-h3:text-xl
908
- markdown-h4:text-lg
909
- markdown-p:text-gray-700
910
- markdown-a:font-bold
911
- markdown-blockquote:italic
912
- markdown-figure:mx-auto
913
- markdown-figcaption:opacity-75
914
- markdown-strong:font-medium
915
- markdown-em:italic
916
- markdown-kbd:border-b-2
917
- markdown-code:font-mono
918
- markdown-pre:font-mono
919
- markdown-ol:pl-6
920
- markdown-ul:pl-8
921
- markdown-li:my-4
922
- markdown-table:my-8
923
- markdown-thead:border-red-300
924
- markdown-tr:border-red-200
925
- markdown-th:text-left
926
- markdown-td:align-center
927
- markdown-img:rounded-lg
928
- markdown-video:my-12
929
- markdown-hr:border-t-2
930
- "
931
- ></div>`,
932
- },
933
- ],
934
- theme: {
935
- typography: {
936
- DEFAULT: {
937
- css: [
938
- {
939
- color: 'var(--tw-prose-body)',
940
- '[class~="lead"]': {
941
- color: 'var(--tw-prose-lead)',
942
- },
943
- strong: {
944
- color: 'var(--tw-prose-bold)',
945
- fontWeight: '600',
946
- },
947
- 'h4 strong': {
948
- fontWeight: '700',
949
- },
950
- },
951
- ],
952
- },
953
- },
954
- },
955
- }
956
- return run(config).then((result) => {
957
- expect(result.css).toMatchFormattedCss(
958
- css`
959
- ${defaults}
960
-
961
- .markdown {
962
- color: var(--tw-prose-body);
963
- }
964
- .markdown
965
- :where([class~='lead']):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
966
- color: var(--tw-prose-lead);
967
- }
968
- .markdown :where(strong):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
969
- color: var(--tw-prose-bold);
970
- font-weight: 600;
971
- }
972
- .markdown
973
- :where(h4 strong):not(:where([class~='not-markdown'], [class~='not-markdown'] *)) {
974
- font-weight: 700;
975
- }
976
- .markdown-headings\:underline
977
- :is(:where(h1, h2, h3, h4, h5, h6, th):not(:where([class~='not-markdown'], [class~='not-markdown']
978
- *))) {
979
- text-decoration-line: underline;
980
- }
981
- .markdown-h1\:text-3xl
982
- :is(:where(h1):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
983
- font-size: 1.875rem;
984
- line-height: 2.25rem;
985
- }
986
- .markdown-h2\:text-2xl
987
- :is(:where(h2):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
988
- font-size: 1.5rem;
989
- line-height: 2rem;
990
- }
991
- .markdown-h3\:text-xl
992
- :is(:where(h3):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
993
- font-size: 1.25rem;
994
- line-height: 1.75rem;
995
- }
996
- .markdown-h4\:text-lg
997
- :is(:where(h4):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
998
- font-size: 1.125rem;
999
- line-height: 1.75rem;
1000
- }
1001
- .markdown-p\:text-gray-700
1002
- :is(:where(p):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1003
- --tw-text-opacity: 1;
1004
- color: rgb(55 65 81 / var(--tw-text-opacity));
1005
- }
1006
- .markdown-a\:font-bold
1007
- :is(:where(a):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1008
- font-weight: 700;
1009
- }
1010
- .markdown-blockquote\:italic
1011
- :is(:where(blockquote):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1012
- font-style: italic;
1013
- }
1014
- .markdown-figure\:mx-auto
1015
- :is(:where(figure):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1016
- margin-left: auto;
1017
- margin-right: auto;
1018
- }
1019
- .markdown-figcaption\:opacity-75
1020
- :is(:where(figcaption):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1021
- opacity: 0.75;
1022
- }
1023
- .markdown-strong\:font-medium
1024
- :is(:where(strong):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1025
- font-weight: 500;
1026
- }
1027
- .markdown-em\:italic
1028
- :is(:where(em):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1029
- font-style: italic;
1030
- }
1031
- .markdown-kbd\:border-b-2
1032
- :is(:where(kbd):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1033
- border-bottom-width: 2px;
1034
- }
1035
- .markdown-code\:font-mono
1036
- :is(:where(code):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1037
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
1038
- 'Courier New', monospace;
1039
- }
1040
- .markdown-pre\:font-mono
1041
- :is(:where(pre):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1042
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
1043
- 'Courier New', monospace;
1044
- }
1045
- .markdown-ol\:pl-6
1046
- :is(:where(ol):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1047
- padding-left: 1.5rem;
1048
- }
1049
- .markdown-ul\:pl-8
1050
- :is(:where(ul):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1051
- padding-left: 2rem;
1052
- }
1053
- .markdown-li\:my-4
1054
- :is(:where(li):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1055
- margin-top: 1rem;
1056
- margin-bottom: 1rem;
1057
- }
1058
- .markdown-table\:my-8
1059
- :is(:where(table):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1060
- margin-top: 2rem;
1061
- margin-bottom: 2rem;
1062
- }
1063
- .markdown-thead\:border-red-300
1064
- :is(:where(thead):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1065
- --tw-border-opacity: 1;
1066
- border-color: rgb(252 165 165 / var(--tw-border-opacity));
1067
- }
1068
- .markdown-tr\:border-red-200
1069
- :is(:where(tr):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1070
- --tw-border-opacity: 1;
1071
- border-color: rgb(254 202 202 / var(--tw-border-opacity));
1072
- }
1073
- .markdown-th\:text-left
1074
- :is(:where(th):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1075
- text-align: left;
1076
- }
1077
- .markdown-img\:rounded-lg
1078
- :is(:where(img):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1079
- border-radius: 0.5rem;
1080
- }
1081
- .markdown-video\:my-12
1082
- :is(:where(video):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1083
- margin-top: 3rem;
1084
- margin-bottom: 3rem;
1085
- }
1086
- .markdown-hr\:border-t-2
1087
- :is(:where(hr):not(:where([class~='not-markdown'], [class~='not-markdown'] *))) {
1088
- border-top-width: 2px;
1089
- }
1090
- .markdown-lead\:italic
1091
- :is(:where([class~='lead']):not(:where([class~='not-markdown'], [class~='not-markdown']
1092
- *))) {
1093
- font-style: italic;
1094
- }
1095
- `
1096
- )
1097
- })
1098
- })
1099
-
1100
- test('customizing defaults with multiple values does not result in invalid css', async () => {
1101
- let config = {
1102
- plugins: [typographyPlugin()],
1103
- content: [
1104
- {
1105
- raw: html`<div class="prose"></div>`,
1106
- },
1107
- ],
1108
- theme: {
1109
- typography: {
1110
- DEFAULT: {
1111
- css: {
1112
- textAlign: ['-webkit-match-parent', 'match-parent'],
1113
- },
1114
- },
1115
- },
1116
- },
1117
- }
1118
- return run(config).then((result) => {
1119
- expect(result.css).toMatchFormattedCss(
1120
- css`
1121
- ${defaults}
1122
-
1123
- .prose {
1124
- text-align: -webkit-match-parent;
1125
- text-align: match-parent;
1126
- }
1127
- `
1128
- )
1129
- })
1130
- })
1131
-
1132
- it('should be possible to use nested syntax (&) when extending the config', () => {
1133
- let config = {
1134
- plugins: [typographyPlugin()],
1135
- content: [
1136
- {
1137
- raw: html`<div class="prose"></div>`,
1138
- },
1139
- ],
1140
- theme: {
1141
- extend: {
1142
- typography: {
1143
- DEFAULT: {
1144
- css: {
1145
- color: '#000',
1146
- a: {
1147
- color: '#888',
1148
- '&:hover': {
1149
- color: '#ff0000',
1150
- },
1151
- },
1152
- },
1153
- },
1154
- },
1155
- },
1156
- },
1157
- }
1158
-
1159
- return run(config).then((result) => {
1160
- expect(result.css).toIncludeCss(css`
1161
- .prose {
1162
- color: #000;
1163
- max-width: 65ch;
1164
- }
1165
- `)
1166
-
1167
- expect(result.css).toIncludeCss(css`
1168
- .prose :where(a):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
1169
- color: #888;
1170
- text-decoration: underline;
1171
- font-weight: 500;
1172
- }
1173
- `)
1174
-
1175
- expect(result.css).toIncludeCss(css`
1176
- .prose :where(a):not(:where([class~='not-prose'], [class~='not-prose'] *)):hover {
1177
- color: #ff0000;
1178
- }
1179
- `)
1180
- })
1181
- })
1182
-
1183
- it('should be possible to specify custom h5 and h6 styles', () => {
1184
- let config = {
1185
- plugins: [typographyPlugin()],
1186
- content: [
1187
- {
1188
- raw: html`<div class="prose prose-h5:text-sm prose-h6:text-xl"></div>`,
1189
- },
1190
- ],
1191
- }
1192
-
1193
- return run(config).then((result) => {
1194
- expect(result.css).toIncludeCss(css`
1195
- .prose-h5\:text-sm :is(:where(h5):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
1196
- font-size: 0.875rem;
1197
- line-height: 1.25rem;
1198
- }
1199
- .prose-h6\:text-xl :is(:where(h6):not(:where([class~='not-prose'], [class~='not-prose'] *))) {
1200
- font-size: 1.25rem;
1201
- line-height: 1.75rem;
1202
- }
1203
- `)
1204
- })
1205
- })
1206
-
1207
- it('should not break with multiple selectors with pseudo elements using variants', () => {
1208
- let config = {
1209
- darkMode: 'class',
1210
- plugins: [typographyPlugin()],
1211
- content: [
1212
- {
1213
- raw: html`<div class="dark:prose"></div>`,
1214
- },
1215
- ],
1216
- theme: {
1217
- typography: {
1218
- DEFAULT: {
1219
- css: {
1220
- 'ol li::before, ul li::before': {
1221
- color: 'red',
1222
- },
1223
- },
1224
- },
1225
- },
1226
- },
1227
- }
1228
-
1229
- return run(config).then((result) => {
1230
- expect(result.css).toIncludeCss(css`
1231
- .dark
1232
- .dark\:prose
1233
- :where(ol li, ul li):not(:where([class~='not-prose'], [class~='not-prose'] *))::before {
1234
- color: red;
1235
- }
1236
- `)
1237
- })
1238
- })
1239
-
1240
- it('lifts all common, trailing pseudo elements when the same across all selectors', () => {
1241
- let config = {
1242
- darkMode: 'class',
1243
- plugins: [typographyPlugin()],
1244
- content: [
1245
- {
1246
- raw: html`<div class="prose dark:prose"></div>`,
1247
- },
1248
- ],
1249
- theme: {
1250
- typography: {
1251
- DEFAULT: {
1252
- css: {
1253
- 'ol li::marker::before, ul li::marker::before': {
1254
- color: 'red',
1255
- },
1256
- },
1257
- },
1258
- },
1259
- },
1260
- }
1261
-
1262
- return run(config).then((result) => {
1263
- expect(result.css).toIncludeCss(css`
1264
- .prose
1265
- :where(ol li, ul li):not(:where([class~='not-prose'], [class~='not-prose']
1266
- *))::marker::before {
1267
- color: red;
1268
- }
1269
- `)
1270
-
1271
- // TODO: The output here is a bug in tailwindcss variant selector rewriting
1272
- // IT should be ::marker::before
1273
- expect(result.css).toIncludeCss(css`
1274
- .dark
1275
- .dark\:prose
1276
- :where(ol li, ul li):not(:where([class~='not-prose'], [class~='not-prose']
1277
- *))::before::marker {
1278
- color: red;
1279
- }
1280
- `)
1281
- })
1282
- })
1283
-
1284
- it('does not modify selectors with differing pseudo elements', () => {
1285
- let config = {
1286
- darkMode: 'class',
1287
- plugins: [typographyPlugin()],
1288
- content: [
1289
- {
1290
- raw: html`<div class="prose dark:prose"></div>`,
1291
- },
1292
- ],
1293
- theme: {
1294
- typography: {
1295
- DEFAULT: {
1296
- css: {
1297
- 'ol li::before, ul li::after': {
1298
- color: 'red',
1299
- },
1300
- },
1301
- },
1302
- },
1303
- },
1304
- }
1305
-
1306
- return run(config).then((result) => {
1307
- expect(result.css).toIncludeCss(css`
1308
- .prose
1309
- :where(ol li::before, ul li::after):not(:where([class~='not-prose'], [class~='not-prose']
1310
- *)) {
1311
- color: red;
1312
- }
1313
- `)
1314
-
1315
- // TODO: The output here is a bug in tailwindcss variant selector rewriting
1316
- expect(result.css).toIncludeCss(css`
1317
- .dark
1318
- .dark\:prose
1319
- :where(ol li, ul li):not(:where([class~='not-prose'], [class~='not-prose'] *))::before,
1320
- ::after {
1321
- color: red;
1322
- }
1323
- `)
1324
- })
1325
- })
1326
-
1327
- it('lifts only the common, trailing pseudo elements from selectors', () => {
1328
- let config = {
1329
- darkMode: 'class',
1330
- plugins: [typographyPlugin()],
1331
- content: [
1332
- {
1333
- raw: html`<div class="prose dark:prose"></div>`,
1334
- },
1335
- ],
1336
- theme: {
1337
- typography: {
1338
- DEFAULT: {
1339
- css: {
1340
- 'ol li::scroll-thumb::before, ul li::scroll-track::before': {
1341
- color: 'red',
1342
- },
1343
- },
1344
- },
1345
- },
1346
- },
1347
- }
1348
-
1349
- return run(config).then((result) => {
1350
- expect(result.css).toIncludeCss(css`
1351
- .prose
1352
- :where(ol li::scroll-thumb, ul
1353
- li::scroll-track):not(:where([class~='not-prose'], [class~='not-prose'] *))::before {
1354
- color: red;
1355
- }
1356
- `)
1357
-
1358
- // TODO: The output here is a bug in tailwindcss variant selector rewriting
1359
- expect(result.css).toIncludeCss(css`
1360
- .dark
1361
- .dark\:prose
1362
- :where(ol li, ul li):not(:where([class~='not-prose'], [class~='not-prose']
1363
- *))::scroll-thumb,
1364
- ::scroll-track,
1365
- ::before {
1366
- color: red;
1367
- }
1368
- `)
1369
- })
1370
- })
1371
-
1372
- it('ignores common non-trailing pseudo-elements in selectors', () => {
1373
- let config = {
1374
- darkMode: 'class',
1375
- plugins: [typographyPlugin()],
1376
- content: [
1377
- {
1378
- raw: html`<div class="prose dark:prose"></div>`,
1379
- },
1380
- ],
1381
- theme: {
1382
- typography: {
1383
- DEFAULT: {
1384
- css: {
1385
- 'ol li::before::scroll-thumb, ul li::before::scroll-track': {
1386
- color: 'red',
1387
- },
1388
- },
1389
- },
1390
- },
1391
- },
1392
- }
1393
-
1394
- return run(config).then((result) => {
1395
- expect(result.css).toIncludeCss(css`
1396
- .prose
1397
- :where(ol li::before::scroll-thumb, ul
1398
- li::before::scroll-track):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
1399
- color: red;
1400
- }
1401
- `)
1402
-
1403
- // TODO: The output here is a bug in tailwindcss variant selector rewriting
1404
- expect(result.css).toIncludeCss(css`
1405
- .dark
1406
- .dark\:prose
1407
- :where(ol li::scroll-thumb, ul
1408
- li::scroll-track):not(:where([class~='not-prose'], [class~='not-prose'] *))::before,
1409
- ::before {
1410
- color: red;
1411
- }
1412
- `)
1413
- })
1414
- })
1415
-
1416
- test('lead styles are inserted after paragraph styles', async () => {
1417
- let config = {
1418
- content: [{ raw: html`<div class="prose"></div>` }],
1419
- }
1420
-
1421
- return run(config).then((result) => {
1422
- expect(result.css).toIncludeCss(
1423
- css`
1424
- .prose {
1425
- color: var(--tw-prose-body);
1426
- max-width: 65ch;
1427
- }
1428
- .prose :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
1429
- margin-top: 1.25em;
1430
- margin-bottom: 1.25em;
1431
- }
1432
- .prose :where([class~='lead']):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
1433
- color: var(--tw-prose-lead);
1434
- font-size: 1.25em;
1435
- line-height: 1.6;
1436
- margin-top: 1.2em;
1437
- margin-bottom: 1.2em;
1438
- }
1439
- `
1440
- )
1441
- })
1442
- })