resolve-defaults-at-rules.test.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. import { run, html, css } from './util/run'
  2. test('basic utilities', async () => {
  3. let config = {
  4. content: [{ raw: html`<div class="rotate-3 skew-y-6 scale-x-110"></div>` }],
  5. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  6. }
  7. let input = css`
  8. @tailwind base;
  9. /* --- */
  10. @tailwind utilities;
  11. `
  12. return run(input, config).then((result) => {
  13. expect(result.css).toMatchFormattedCss(css`
  14. *,
  15. ::before,
  16. ::after {
  17. --tw-translate-x: 0;
  18. --tw-translate-y: 0;
  19. --tw-rotate: 0;
  20. --tw-skew-x: 0;
  21. --tw-skew-y: 0;
  22. --tw-scale-x: 1;
  23. --tw-scale-y: 1;
  24. }
  25. ::backdrop {
  26. --tw-translate-x: 0;
  27. --tw-translate-y: 0;
  28. --tw-rotate: 0;
  29. --tw-skew-x: 0;
  30. --tw-skew-y: 0;
  31. --tw-scale-x: 1;
  32. --tw-scale-y: 1;
  33. }
  34. /* --- */
  35. .rotate-3 {
  36. --tw-rotate: 3deg;
  37. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  38. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  39. scaleY(var(--tw-scale-y));
  40. }
  41. .skew-y-6 {
  42. --tw-skew-y: 6deg;
  43. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  44. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  45. scaleY(var(--tw-scale-y));
  46. }
  47. .scale-x-110 {
  48. --tw-scale-x: 1.1;
  49. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  50. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  51. scaleY(var(--tw-scale-y));
  52. }
  53. `)
  54. })
  55. })
  56. test('with pseudo-class variants', async () => {
  57. let config = {
  58. content: [
  59. { raw: html`<div class="hover:scale-x-110 focus:rotate-3 hover:focus:skew-y-6"></div>` },
  60. ],
  61. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  62. }
  63. let input = css`
  64. @tailwind base;
  65. /* --- */
  66. @tailwind utilities;
  67. `
  68. return run(input, config).then((result) => {
  69. expect(result.css).toMatchFormattedCss(css`
  70. *,
  71. ::before,
  72. ::after {
  73. --tw-translate-x: 0;
  74. --tw-translate-y: 0;
  75. --tw-rotate: 0;
  76. --tw-skew-x: 0;
  77. --tw-skew-y: 0;
  78. --tw-scale-x: 1;
  79. --tw-scale-y: 1;
  80. }
  81. ::backdrop {
  82. --tw-translate-x: 0;
  83. --tw-translate-y: 0;
  84. --tw-rotate: 0;
  85. --tw-skew-x: 0;
  86. --tw-skew-y: 0;
  87. --tw-scale-x: 1;
  88. --tw-scale-y: 1;
  89. }
  90. /* --- */
  91. .hover\:scale-x-110:hover {
  92. --tw-scale-x: 1.1;
  93. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  94. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  95. scaleY(var(--tw-scale-y));
  96. }
  97. .focus\:rotate-3:focus {
  98. --tw-rotate: 3deg;
  99. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  100. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  101. scaleY(var(--tw-scale-y));
  102. }
  103. .hover\:focus\:skew-y-6:focus:hover {
  104. --tw-skew-y: 6deg;
  105. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  106. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  107. scaleY(var(--tw-scale-y));
  108. }
  109. `)
  110. })
  111. })
  112. test('with pseudo-element variants', async () => {
  113. let config = {
  114. content: [{ raw: html`<div class="before:scale-x-110 after:rotate-3"></div>` }],
  115. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  116. }
  117. let input = css`
  118. @tailwind base;
  119. /* --- */
  120. @tailwind utilities;
  121. `
  122. return run(input, config).then((result) => {
  123. expect(result.css).toMatchFormattedCss(css`
  124. *,
  125. ::before,
  126. ::after {
  127. --tw-translate-x: 0;
  128. --tw-translate-y: 0;
  129. --tw-rotate: 0;
  130. --tw-skew-x: 0;
  131. --tw-skew-y: 0;
  132. --tw-scale-x: 1;
  133. --tw-scale-y: 1;
  134. }
  135. ::backdrop {
  136. --tw-translate-x: 0;
  137. --tw-translate-y: 0;
  138. --tw-rotate: 0;
  139. --tw-skew-x: 0;
  140. --tw-skew-y: 0;
  141. --tw-scale-x: 1;
  142. --tw-scale-y: 1;
  143. }
  144. /* --- */
  145. .before\:scale-x-110::before {
  146. content: var(--tw-content);
  147. --tw-scale-x: 1.1;
  148. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  149. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  150. scaleY(var(--tw-scale-y));
  151. }
  152. .after\:rotate-3::after {
  153. content: var(--tw-content);
  154. --tw-rotate: 3deg;
  155. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  156. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  157. scaleY(var(--tw-scale-y));
  158. }
  159. `)
  160. })
  161. })
  162. test('with multi-class variants', async () => {
  163. let config = {
  164. content: [{ raw: html`<div class="group-hover:scale-x-110 peer-focus:rotate-3"></div>` }],
  165. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  166. }
  167. let input = css`
  168. @tailwind base;
  169. /* --- */
  170. @tailwind utilities;
  171. `
  172. return run(input, config).then((result) => {
  173. expect(result.css).toMatchFormattedCss(css`
  174. *,
  175. ::before,
  176. ::after {
  177. --tw-translate-x: 0;
  178. --tw-translate-y: 0;
  179. --tw-rotate: 0;
  180. --tw-skew-x: 0;
  181. --tw-skew-y: 0;
  182. --tw-scale-x: 1;
  183. --tw-scale-y: 1;
  184. }
  185. ::backdrop {
  186. --tw-translate-x: 0;
  187. --tw-translate-y: 0;
  188. --tw-rotate: 0;
  189. --tw-skew-x: 0;
  190. --tw-skew-y: 0;
  191. --tw-scale-x: 1;
  192. --tw-scale-y: 1;
  193. }
  194. /* --- */
  195. .group:hover .group-hover\:scale-x-110 {
  196. --tw-scale-x: 1.1;
  197. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  198. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  199. scaleY(var(--tw-scale-y));
  200. }
  201. .peer:focus ~ .peer-focus\:rotate-3 {
  202. --tw-rotate: 3deg;
  203. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  204. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  205. scaleY(var(--tw-scale-y));
  206. }
  207. `)
  208. })
  209. })
  210. test('with multi-class pseudo-element variants', async () => {
  211. let config = {
  212. content: [
  213. { raw: html`<div class="group-hover:before:scale-x-110 peer-focus:after:rotate-3"></div>` },
  214. ],
  215. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  216. }
  217. let input = css`
  218. @tailwind base;
  219. /* --- */
  220. @tailwind utilities;
  221. `
  222. return run(input, config).then((result) => {
  223. expect(result.css).toMatchFormattedCss(css`
  224. *,
  225. ::before,
  226. ::after {
  227. --tw-translate-x: 0;
  228. --tw-translate-y: 0;
  229. --tw-rotate: 0;
  230. --tw-skew-x: 0;
  231. --tw-skew-y: 0;
  232. --tw-scale-x: 1;
  233. --tw-scale-y: 1;
  234. }
  235. ::backdrop {
  236. --tw-translate-x: 0;
  237. --tw-translate-y: 0;
  238. --tw-rotate: 0;
  239. --tw-skew-x: 0;
  240. --tw-skew-y: 0;
  241. --tw-scale-x: 1;
  242. --tw-scale-y: 1;
  243. }
  244. /* --- */
  245. .group:hover .group-hover\:before\:scale-x-110::before {
  246. content: var(--tw-content);
  247. --tw-scale-x: 1.1;
  248. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  249. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  250. scaleY(var(--tw-scale-y));
  251. }
  252. .peer:focus ~ .peer-focus\:after\:rotate-3::after {
  253. content: var(--tw-content);
  254. --tw-rotate: 3deg;
  255. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  256. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  257. scaleY(var(--tw-scale-y));
  258. }
  259. `)
  260. })
  261. })
  262. test('with multi-class pseudo-element and pseudo-class variants', async () => {
  263. let config = {
  264. content: [
  265. {
  266. raw: html`<div
  267. class="group-hover:hover:before:scale-x-110 peer-focus:focus:after:rotate-3"
  268. ></div>`,
  269. },
  270. ],
  271. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  272. }
  273. let input = css`
  274. @tailwind base;
  275. /* --- */
  276. @tailwind utilities;
  277. `
  278. return run(input, config).then((result) => {
  279. expect(result.css).toMatchFormattedCss(css`
  280. *,
  281. ::before,
  282. ::after {
  283. --tw-translate-x: 0;
  284. --tw-translate-y: 0;
  285. --tw-rotate: 0;
  286. --tw-skew-x: 0;
  287. --tw-skew-y: 0;
  288. --tw-scale-x: 1;
  289. --tw-scale-y: 1;
  290. }
  291. ::backdrop {
  292. --tw-translate-x: 0;
  293. --tw-translate-y: 0;
  294. --tw-rotate: 0;
  295. --tw-skew-x: 0;
  296. --tw-skew-y: 0;
  297. --tw-scale-x: 1;
  298. --tw-scale-y: 1;
  299. }
  300. /* --- */
  301. .group:hover .group-hover\:hover\:before\:scale-x-110:hover::before {
  302. content: var(--tw-content);
  303. --tw-scale-x: 1.1;
  304. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  305. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  306. scaleY(var(--tw-scale-y));
  307. }
  308. .peer:focus ~ .peer-focus\:focus\:after\:rotate-3:focus::after {
  309. content: var(--tw-content);
  310. --tw-rotate: 3deg;
  311. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  312. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  313. scaleY(var(--tw-scale-y));
  314. }
  315. `)
  316. })
  317. })
  318. test('with apply', async () => {
  319. let config = {
  320. content: [{ raw: html`<div class="foo"></div>` }],
  321. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  322. }
  323. let input = css`
  324. @tailwind base;
  325. /* --- */
  326. @tailwind utilities;
  327. @layer utilities {
  328. .foo {
  329. @apply rotate-3;
  330. }
  331. }
  332. .bar {
  333. @apply before:scale-110;
  334. }
  335. .baz::before {
  336. @apply rotate-45;
  337. }
  338. .whats ~ .next > span:hover {
  339. @apply skew-x-6;
  340. }
  341. .media-queries {
  342. @apply md:rotate-45;
  343. }
  344. .a,
  345. .b,
  346. .c {
  347. @apply skew-y-3;
  348. }
  349. .a,
  350. .b {
  351. @apply rotate-45;
  352. }
  353. .a::before,
  354. .b::after {
  355. @apply rotate-90;
  356. }
  357. .recursive {
  358. @apply foo;
  359. }
  360. `
  361. return run(input, config).then((result) => {
  362. expect(result.css).toMatchFormattedCss(css`
  363. *,
  364. ::before,
  365. ::after {
  366. --tw-translate-x: 0;
  367. --tw-translate-y: 0;
  368. --tw-rotate: 0;
  369. --tw-skew-x: 0;
  370. --tw-skew-y: 0;
  371. --tw-scale-x: 1;
  372. --tw-scale-y: 1;
  373. }
  374. ::backdrop {
  375. --tw-translate-x: 0;
  376. --tw-translate-y: 0;
  377. --tw-rotate: 0;
  378. --tw-skew-x: 0;
  379. --tw-skew-y: 0;
  380. --tw-scale-x: 1;
  381. --tw-scale-y: 1;
  382. }
  383. /* --- */
  384. .foo {
  385. --tw-rotate: 3deg;
  386. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  387. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  388. scaleY(var(--tw-scale-y));
  389. }
  390. .bar::before {
  391. content: var(--tw-content);
  392. --tw-scale-x: 1.1;
  393. --tw-scale-y: 1.1;
  394. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  395. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  396. scaleY(var(--tw-scale-y));
  397. }
  398. .baz::before {
  399. --tw-rotate: 45deg;
  400. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  401. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  402. scaleY(var(--tw-scale-y));
  403. }
  404. .whats ~ .next > span:hover {
  405. --tw-skew-x: 6deg;
  406. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  407. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  408. scaleY(var(--tw-scale-y));
  409. }
  410. @media (min-width: 768px) {
  411. .media-queries {
  412. --tw-rotate: 45deg;
  413. transform: translate(var(--tw-translate-x), var(--tw-translate-y))
  414. rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
  415. scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
  416. }
  417. }
  418. .a,
  419. .b,
  420. .c {
  421. --tw-skew-y: 3deg;
  422. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  423. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  424. scaleY(var(--tw-scale-y));
  425. }
  426. .a,
  427. .b {
  428. --tw-rotate: 45deg;
  429. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  430. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  431. scaleY(var(--tw-scale-y));
  432. }
  433. .a::before,
  434. .b::after {
  435. --tw-rotate: 90deg;
  436. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  437. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  438. scaleY(var(--tw-scale-y));
  439. }
  440. .recursive {
  441. --tw-rotate: 3deg;
  442. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  443. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  444. scaleY(var(--tw-scale-y));
  445. }
  446. `)
  447. })
  448. })
  449. test('legacy pseudo-element syntax is supported', async () => {
  450. let config = {
  451. experimental: { optimizeUniversalDefaults: true },
  452. content: [{ raw: html`<div class="foo"></div>` }],
  453. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  454. }
  455. let input = css`
  456. @tailwind base;
  457. /* --- */
  458. @tailwind utilities;
  459. .a:before {
  460. @apply rotate-45;
  461. }
  462. .b:after {
  463. @apply rotate-3;
  464. }
  465. .c:first-line {
  466. @apply rotate-1;
  467. }
  468. .d:first-letter {
  469. @apply rotate-6;
  470. }
  471. `
  472. return run(input, config).then((result) => {
  473. expect(result.css).toMatchFormattedCss(css`
  474. .a:before,
  475. .b:after,
  476. .c:first-line,
  477. .d:first-letter {
  478. --tw-translate-x: 0;
  479. --tw-translate-y: 0;
  480. --tw-rotate: 0;
  481. --tw-skew-x: 0;
  482. --tw-skew-y: 0;
  483. --tw-scale-x: 1;
  484. --tw-scale-y: 1;
  485. }
  486. /* --- */
  487. .a:before {
  488. --tw-rotate: 45deg;
  489. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  490. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  491. scaleY(var(--tw-scale-y));
  492. }
  493. .b:after {
  494. --tw-rotate: 3deg;
  495. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  496. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  497. scaleY(var(--tw-scale-y));
  498. }
  499. .c:first-line {
  500. --tw-rotate: 1deg;
  501. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  502. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  503. scaleY(var(--tw-scale-y));
  504. }
  505. .d:first-letter {
  506. --tw-rotate: 6deg;
  507. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  508. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  509. scaleY(var(--tw-scale-y));
  510. }
  511. `)
  512. })
  513. })
  514. test('with borders', async () => {
  515. let config = {
  516. content: [{ raw: html`<div class="border border-red-500 md:border-2"></div>` }],
  517. corePlugins: ['borderWidth', 'borderColor', 'borderOpacity'],
  518. }
  519. let input = css`
  520. @tailwind base;
  521. /* --- */
  522. @tailwind utilities;
  523. `
  524. return run(input, config).then((result) => {
  525. expect(result.css).toMatchFormattedCss(css`
  526. /* --- */
  527. .border {
  528. border-width: 1px;
  529. }
  530. .border-red-500 {
  531. --tw-border-opacity: 1;
  532. border-color: rgb(239 68 68 / var(--tw-border-opacity));
  533. }
  534. @media (min-width: 768px) {
  535. .md\:border-2 {
  536. border-width: 2px;
  537. }
  538. }
  539. `)
  540. })
  541. })
  542. test('with shadows', async () => {
  543. let config = {
  544. content: [{ raw: html`<div class="shadow ring-1 ring-black/25 md:shadow-xl"></div>` }],
  545. corePlugins: ['boxShadow', 'ringColor', 'ringWidth'],
  546. }
  547. let input = css`
  548. @tailwind base;
  549. /* --- */
  550. @tailwind utilities;
  551. `
  552. return run(input, config).then((result) => {
  553. expect(result.css).toMatchFormattedCss(css`
  554. *,
  555. ::before,
  556. ::after {
  557. --tw-ring-inset: ;
  558. --tw-ring-offset-width: 0px;
  559. --tw-ring-offset-color: #fff;
  560. --tw-ring-color: rgb(59 130 246 / 0.5);
  561. --tw-ring-offset-shadow: 0 0 #0000;
  562. --tw-ring-shadow: 0 0 #0000;
  563. --tw-shadow: 0 0 #0000;
  564. --tw-shadow-colored: 0 0 #0000;
  565. }
  566. ::backdrop {
  567. --tw-ring-inset: ;
  568. --tw-ring-offset-width: 0px;
  569. --tw-ring-offset-color: #fff;
  570. --tw-ring-color: rgb(59 130 246 / 0.5);
  571. --tw-ring-offset-shadow: 0 0 #0000;
  572. --tw-ring-shadow: 0 0 #0000;
  573. --tw-shadow: 0 0 #0000;
  574. --tw-shadow-colored: 0 0 #0000;
  575. }
  576. /* --- */
  577. .shadow {
  578. --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  579. --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color),
  580. 0 1px 2px -1px var(--tw-shadow-color);
  581. box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
  582. var(--tw-shadow);
  583. }
  584. .ring-1 {
  585. --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
  586. var(--tw-ring-offset-color);
  587. --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width))
  588. var(--tw-ring-color);
  589. box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  590. }
  591. .ring-black\/25 {
  592. --tw-ring-color: rgb(0 0 0 / 0.25);
  593. }
  594. @media (min-width: 768px) {
  595. .md\:shadow-xl {
  596. --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  597. --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color),
  598. 0 8px 10px -6px var(--tw-shadow-color);
  599. box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
  600. var(--tw-shadow);
  601. }
  602. }
  603. `)
  604. })
  605. })
  606. test('when no utilities that need the defaults are used', async () => {
  607. let config = {
  608. content: [{ raw: html`<div class=""></div>` }],
  609. corePlugins: ['transform', 'scale', 'rotate', 'skew'],
  610. }
  611. let input = css`
  612. @tailwind base;
  613. /* --- */
  614. @tailwind utilities;
  615. `
  616. return run(input, config).then((result) => {
  617. expect(result.css).toMatchFormattedCss(css`
  618. *,
  619. ::before,
  620. ::after {
  621. --tw-translate-x: 0;
  622. --tw-translate-y: 0;
  623. --tw-rotate: 0;
  624. --tw-skew-x: 0;
  625. --tw-skew-y: 0;
  626. --tw-scale-x: 1;
  627. --tw-scale-y: 1;
  628. }
  629. ::backdrop {
  630. --tw-translate-x: 0;
  631. --tw-translate-y: 0;
  632. --tw-rotate: 0;
  633. --tw-skew-x: 0;
  634. --tw-skew-y: 0;
  635. --tw-scale-x: 1;
  636. --tw-scale-y: 1;
  637. }
  638. /* --- */
  639. `)
  640. })
  641. })
  642. test('when a utility uses defaults but they do not exist', async () => {
  643. let config = {
  644. content: [{ raw: html`<div class="rotate-3"></div>` }],
  645. corePlugins: ['rotate'],
  646. }
  647. let input = css`
  648. @tailwind base;
  649. /* --- */
  650. @tailwind utilities;
  651. `
  652. return run(input, config).then((result) => {
  653. expect(result.css).toMatchFormattedCss(css`
  654. /* --- */
  655. .rotate-3 {
  656. --tw-rotate: 3deg;
  657. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  658. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  659. scaleY(var(--tw-scale-y));
  660. }
  661. `)
  662. })
  663. })
  664. test('selectors are reduced to the lowest possible specificity', async () => {
  665. let config = {
  666. experimental: { optimizeUniversalDefaults: true },
  667. content: [{ raw: html`<div class="foo"></div>` }],
  668. corePlugins: [],
  669. }
  670. let input = css`
  671. @defaults test {
  672. --color: black;
  673. }
  674. /* --- */
  675. .foo {
  676. @defaults test;
  677. background-color: var(--color);
  678. }
  679. #app {
  680. @defaults test;
  681. border-color: var(--color);
  682. }
  683. span#page {
  684. @defaults test;
  685. color: var(--color);
  686. }
  687. div[data-foo='bar']#other {
  688. @defaults test;
  689. fill: var(--color);
  690. }
  691. div[data-bar='baz'] {
  692. @defaults test;
  693. stroke: var(--color);
  694. }
  695. article {
  696. @defaults test;
  697. --article: var(--color);
  698. }
  699. div[data-foo='bar']#another::before {
  700. @defaults test;
  701. fill: var(--color);
  702. }
  703. `
  704. return run(input, config).then((result) => {
  705. expect(result.css).toMatchFormattedCss(css`
  706. .foo,
  707. [id='app'],
  708. [id='page'],
  709. [id='other'],
  710. [data-bar='baz'],
  711. article,
  712. [id='another']::before {
  713. --color: black;
  714. }
  715. /* --- */
  716. .foo {
  717. background-color: var(--color);
  718. }
  719. #app {
  720. border-color: var(--color);
  721. }
  722. span#page {
  723. color: var(--color);
  724. }
  725. div[data-foo='bar']#other {
  726. fill: var(--color);
  727. }
  728. div[data-bar='baz'] {
  729. stroke: var(--color);
  730. }
  731. article {
  732. --article: var(--color);
  733. }
  734. div[data-foo='bar']#another::before {
  735. fill: var(--color);
  736. }
  737. `)
  738. })
  739. })
  740. test('No defaults without @tailwind base', () => {
  741. let config = {
  742. experimental: { optimizeUniversalDefaults: true },
  743. content: [{ raw: html`<div class="scale-150"></div>` }],
  744. corePlugins: { preflight: false },
  745. }
  746. // Optimize universal defaults doesn't work well with isolated modules
  747. // We require you to use @tailwind base to inject the defaults
  748. let input = css`
  749. @tailwind components;
  750. @tailwind utilities;
  751. `
  752. return run(input, config).then((result) => {
  753. return expect(result.css).toMatchFormattedCss(css`
  754. .scale-150 {
  755. --tw-scale-x: 1.5;
  756. --tw-scale-y: 1.5;
  757. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  758. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  759. scaleY(var(--tw-scale-y));
  760. }
  761. `)
  762. })
  763. })
  764. test('no defaults and apply without @tailwind base', () => {
  765. let config = {
  766. experimental: { optimizeUniversalDefaults: true },
  767. content: [{ raw: html`<div class="my-card"></div>` }],
  768. corePlugins: { preflight: false },
  769. }
  770. // Optimize universal defaults doesn't work well with isolated modules
  771. // We require you to use @tailwind base to inject the defaults
  772. let input = css`
  773. @tailwind components;
  774. @tailwind utilities;
  775. .my-card {
  776. @apply scale-150;
  777. }
  778. `
  779. return run(input, config).then((result) => {
  780. return expect(result.css).toMatchFormattedCss(css`
  781. .my-card {
  782. --tw-scale-x: 1.5;
  783. --tw-scale-y: 1.5;
  784. transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
  785. skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
  786. scaleY(var(--tw-scale-y));
  787. }
  788. `)
  789. })
  790. })