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

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