match-utilities.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. import { run, html, css } from './util/run'
  2. test('match utilities with modifiers', async () => {
  3. let config = {
  4. content: [
  5. {
  6. raw: html`<div
  7. class="test test/foo test-1/foo test-2/foo test/[foo] test-1/[foo] test-[8]/[9]"
  8. ></div> `,
  9. },
  10. ],
  11. corePlugins: { preflight: false },
  12. plugins: [
  13. ({ matchUtilities }) => {
  14. matchUtilities(
  15. {
  16. test: (value, { modifier }) => ({
  17. color: `${value}_${modifier}`,
  18. }),
  19. },
  20. {
  21. values: {
  22. DEFAULT: 'default',
  23. bar: 'bar',
  24. '1': 'one',
  25. '2': 'two',
  26. '1/foo': 'onefoo',
  27. '[8]/[9]': 'eightnine',
  28. },
  29. modifiers: 'any',
  30. }
  31. )
  32. },
  33. ],
  34. }
  35. let input = css`
  36. @tailwind utilities;
  37. `
  38. let result = await run(input, config)
  39. expect(result.css).toMatchFormattedCss(css`
  40. .test {
  41. color: default_null;
  42. }
  43. .test-1\/\[foo\] {
  44. color: one_[foo];
  45. }
  46. .test-1\/foo {
  47. color: onefoo_null;
  48. }
  49. .test-2\/foo {
  50. color: two_foo;
  51. }
  52. .test-\[8\]\/\[9\] {
  53. color: eightnine_null;
  54. }
  55. .test\/\[foo\] {
  56. color: default_[foo];
  57. }
  58. .test\/foo {
  59. color: default_foo;
  60. }
  61. `)
  62. })
  63. test('match utilities with modifiers in the config', async () => {
  64. let config = {
  65. content: [
  66. {
  67. raw: html`<div class="test test/foo test-1/foo test/[bar] test-1/[bar]"></div> `,
  68. },
  69. ],
  70. corePlugins: { preflight: false },
  71. plugins: [
  72. ({ matchUtilities }) => {
  73. matchUtilities(
  74. {
  75. test: (value, { modifier }) => ({
  76. color: `${value}_${modifier}`,
  77. }),
  78. },
  79. {
  80. values: {
  81. DEFAULT: 'default',
  82. bar: 'bar',
  83. '1': 'one',
  84. },
  85. modifiers: {
  86. foo: 'mewtwo',
  87. },
  88. }
  89. )
  90. },
  91. ],
  92. }
  93. let input = css`
  94. @tailwind utilities;
  95. `
  96. let result = await run(input, config)
  97. expect(result.css).toMatchFormattedCss(css`
  98. .test {
  99. color: default_null;
  100. }
  101. .test-1\/\[bar\] {
  102. color: one_bar;
  103. }
  104. .test-1\/foo {
  105. color: one_mewtwo;
  106. }
  107. .test\/\[bar\] {
  108. color: default_bar;
  109. }
  110. .test\/foo {
  111. color: default_mewtwo;
  112. }
  113. `)
  114. })
  115. test('match utilities can omit utilities by returning null', async () => {
  116. let config = {
  117. content: [
  118. {
  119. raw: html`<div class="test test/good test/bad"></div> `,
  120. },
  121. ],
  122. corePlugins: { preflight: false },
  123. plugins: [
  124. ({ matchUtilities }) => {
  125. matchUtilities(
  126. {
  127. test: (value, { modifier }) =>
  128. modifier === 'bad'
  129. ? null
  130. : {
  131. color: `${value}_${modifier}`,
  132. },
  133. },
  134. {
  135. values: {
  136. DEFAULT: 'default',
  137. bar: 'bar',
  138. '1': 'one',
  139. },
  140. modifiers: 'any',
  141. }
  142. )
  143. },
  144. ],
  145. }
  146. let input = css`
  147. @tailwind utilities;
  148. `
  149. let result = await run(input, config)
  150. expect(result.css).toMatchFormattedCss(css`
  151. .test {
  152. color: default_null;
  153. }
  154. .test\/good {
  155. color: default_good;
  156. }
  157. `)
  158. })
  159. test('matching utilities with a basic configured value', () => {
  160. let config = {
  161. content: [{ raw: html`<div class="test-foo"></div>` }],
  162. theme: {},
  163. plugins: [
  164. function ({ matchUtilities }) {
  165. matchUtilities(
  166. {
  167. test: (value) => ({ value }),
  168. },
  169. {
  170. values: {
  171. foo: 'value_foo',
  172. },
  173. }
  174. )
  175. },
  176. ],
  177. corePlugins: [],
  178. }
  179. return run('@tailwind utilities', config).then((result) => {
  180. expect(result.css).toMatchFormattedCss(css`
  181. .test-foo {
  182. value: value_foo;
  183. }
  184. `)
  185. })
  186. })
  187. test('matching utilities with an arbitrary value and configured modifier', () => {
  188. let config = {
  189. content: [{ raw: html`<div class="test-[foo]/bar"></div>` }],
  190. theme: {},
  191. plugins: [
  192. function ({ matchUtilities }) {
  193. matchUtilities(
  194. {
  195. test: (value, { modifier }) => ({ value, modifier }),
  196. },
  197. {
  198. modifiers: {
  199. bar: 'configured_bar',
  200. },
  201. }
  202. )
  203. },
  204. ],
  205. corePlugins: [],
  206. }
  207. return run('@tailwind utilities', config).then((result) => {
  208. expect(result.css).toMatchFormattedCss(css`
  209. .test-\[foo\]\/bar {
  210. value: foo;
  211. modifier: configured_bar;
  212. }
  213. `)
  214. })
  215. })
  216. test('matching utilities with an configured value and an arbitrary modifier (raw)', () => {
  217. let config = {
  218. content: [{ raw: html`<div class="test-foo/[bar]"></div>` }],
  219. theme: {},
  220. plugins: [
  221. function ({ matchUtilities }) {
  222. matchUtilities(
  223. {
  224. test: (value, { modifier }) => ({ value, modifier }),
  225. },
  226. {
  227. values: {
  228. foo: 'configured_foo',
  229. },
  230. modifiers: 'any', // Raw `[value]`
  231. }
  232. )
  233. },
  234. ],
  235. corePlugins: [],
  236. }
  237. return run('@tailwind utilities', config).then((result) => {
  238. expect(result.css).toMatchFormattedCss(css`
  239. .test-foo\/\[bar\] {
  240. value: configured_foo;
  241. modifier: [bar];
  242. }
  243. `)
  244. })
  245. })
  246. test('matching utilities with an configured value and an arbitrary modifier (non-raw)', () => {
  247. let config = {
  248. content: [{ raw: html`<div class="test-foo/[bar]"></div>` }],
  249. theme: {},
  250. plugins: [
  251. function ({ matchUtilities }) {
  252. matchUtilities(
  253. {
  254. test: (value, { modifier }) => ({ value, modifier }),
  255. },
  256. {
  257. values: {
  258. foo: 'configured_foo',
  259. },
  260. modifiers: {},
  261. }
  262. )
  263. },
  264. ],
  265. corePlugins: [],
  266. }
  267. return run('@tailwind utilities', config).then((result) => {
  268. expect(result.css).toMatchFormattedCss(css`
  269. .test-foo\/\[bar\] {
  270. value: configured_foo;
  271. modifier: bar;
  272. }
  273. `)
  274. })
  275. })
  276. test('matching utilities with an configured value and a configured modifier', () => {
  277. let config = {
  278. content: [{ raw: html`<div class="test-foo/bar"></div>` }],
  279. theme: {},
  280. plugins: [
  281. function ({ matchUtilities }) {
  282. matchUtilities(
  283. {
  284. test: (value, { modifier }) => ({ value, modifier }),
  285. },
  286. {
  287. values: {
  288. foo: 'configured_foo',
  289. },
  290. modifiers: {
  291. bar: 'configured_bar',
  292. },
  293. }
  294. )
  295. },
  296. ],
  297. corePlugins: [],
  298. }
  299. return run('@tailwind utilities', config).then((result) => {
  300. expect(result.css).toMatchFormattedCss(css`
  301. .test-foo\/bar {
  302. value: configured_foo;
  303. modifier: configured_bar;
  304. }
  305. `)
  306. })
  307. })
  308. test('matching utilities with an arbitrary value and an arbitrary modifier (raw)', () => {
  309. let config = {
  310. content: [{ raw: html`<div class="test-[foo]/[bar]"></div>` }],
  311. theme: {},
  312. plugins: [
  313. function ({ matchUtilities }) {
  314. matchUtilities(
  315. {
  316. test: (value, { modifier }) => ({ value, modifier }),
  317. },
  318. {
  319. modifiers: 'any',
  320. }
  321. )
  322. },
  323. ],
  324. corePlugins: [],
  325. }
  326. return run('@tailwind utilities', config).then((result) => {
  327. expect(result.css).toMatchFormattedCss(css`
  328. .test-\[foo\]\/\[bar\] {
  329. value: foo;
  330. modifier: [bar];
  331. }
  332. `)
  333. })
  334. })
  335. test('matching utilities with an arbitrary value and an arbitrary modifier (non-raw)', () => {
  336. let config = {
  337. content: [{ raw: html`<div class="test-[foo]/[bar]"></div>` }],
  338. theme: {},
  339. plugins: [
  340. function ({ matchUtilities }) {
  341. matchUtilities(
  342. {
  343. test: (value, { modifier }) => ({ value, modifier }),
  344. },
  345. {
  346. modifiers: {},
  347. }
  348. )
  349. },
  350. ],
  351. corePlugins: [],
  352. }
  353. return run('@tailwind utilities', config).then((result) => {
  354. expect(result.css).toMatchFormattedCss(css`
  355. .test-\[foo\]\/\[bar\] {
  356. value: foo;
  357. modifier: bar;
  358. }
  359. `)
  360. })
  361. })
  362. test('matching utilities with a lookup value that looks like an arbitrary value and modifier', () => {
  363. let config = {
  364. content: [{ raw: html`<div class="test-[foo]/[bar]"></div>` }],
  365. theme: {},
  366. plugins: [
  367. function ({ matchUtilities }) {
  368. matchUtilities(
  369. {
  370. test: (value, { modifier }) => ({ value, modifier }),
  371. },
  372. {
  373. values: {
  374. '[foo]/[bar]': 'hello',
  375. },
  376. }
  377. )
  378. },
  379. ],
  380. corePlugins: [],
  381. }
  382. return run('@tailwind utilities', config).then((result) => {
  383. expect(result.css).toMatchFormattedCss(css`
  384. .test-\[foo\]\/\[bar\] {
  385. value: hello;
  386. }
  387. `)
  388. })
  389. })
  390. test('matching utilities with a lookup value that looks like an arbitrary value and modifier (with modifiers = any)', () => {
  391. let config = {
  392. content: [{ raw: html`<div class="test-[foo]/[bar]"></div>` }],
  393. theme: {},
  394. plugins: [
  395. function ({ matchUtilities }) {
  396. matchUtilities(
  397. {
  398. test: (value, { modifier }) => ({ value, modifier }),
  399. },
  400. {
  401. values: {
  402. '[foo]/[bar]': 'hello',
  403. },
  404. modifiers: 'any',
  405. }
  406. )
  407. },
  408. ],
  409. corePlugins: [],
  410. }
  411. return run('@tailwind utilities', config).then((result) => {
  412. expect(result.css).toMatchFormattedCss(css`
  413. .test-\[foo\]\/\[bar\] {
  414. value: hello;
  415. }
  416. `)
  417. })
  418. })
  419. test('matching utilities with a lookup value that looks like an arbitrary value and modifier (with modifiers = {})', () => {
  420. let config = {
  421. content: [{ raw: html`<div class="test-[foo]/[bar]"></div>` }],
  422. theme: {},
  423. plugins: [
  424. function ({ matchUtilities }) {
  425. matchUtilities(
  426. {
  427. test: (value, { modifier }) => ({ value, modifier }),
  428. },
  429. {
  430. values: {
  431. '[foo]/[bar]': 'hello',
  432. },
  433. modifiers: {},
  434. }
  435. )
  436. },
  437. ],
  438. corePlugins: [],
  439. }
  440. return run('@tailwind utilities', config).then((result) => {
  441. expect(result.css).toMatchFormattedCss(css`
  442. .test-\[foo\]\/\[bar\] {
  443. value: hello;
  444. }
  445. `)
  446. })
  447. })
  448. test('matching utilities with a lookup value that looks like an arbitrary value and a configured modifier', () => {
  449. let config = {
  450. content: [{ raw: html`<div class="test-[foo]/bar"></div>` }],
  451. theme: {},
  452. plugins: [
  453. function ({ matchUtilities }) {
  454. matchUtilities(
  455. {
  456. test: (value, { modifier }) => ({ value, modifier }),
  457. },
  458. {
  459. values: {
  460. '[foo]/bar': 'hello',
  461. },
  462. }
  463. )
  464. },
  465. ],
  466. corePlugins: [],
  467. }
  468. return run('@tailwind utilities', config).then((result) => {
  469. expect(result.css).toMatchFormattedCss(css`
  470. .test-\[foo\]\/bar {
  471. value: hello;
  472. }
  473. `)
  474. })
  475. })
  476. test('matching utilities with a lookup value that looks like a configured value and an arbitrary modifier', () => {
  477. let config = {
  478. content: [{ raw: html`<div class="test-foo/[bar]"></div>` }],
  479. theme: {},
  480. plugins: [
  481. function ({ matchUtilities }) {
  482. matchUtilities(
  483. {
  484. test: (value, { modifier }) => ({ value, modifier }),
  485. },
  486. {
  487. values: {
  488. 'foo/[bar]': 'hello',
  489. },
  490. }
  491. )
  492. },
  493. ],
  494. corePlugins: [],
  495. }
  496. return run('@tailwind utilities', config).then((result) => {
  497. expect(result.css).toMatchFormattedCss(css`
  498. .test-foo\/\[bar\] {
  499. value: hello;
  500. }
  501. `)
  502. })
  503. })
  504. test('matching utilities with a lookup value that does not match the configured type', () => {
  505. let config = {
  506. content: [{ raw: html`<div class="test-foo"></div>` }],
  507. theme: {},
  508. plugins: [
  509. function ({ matchUtilities }) {
  510. matchUtilities(
  511. {
  512. test: (value, { modifier }) => ({ value, modifier }),
  513. },
  514. {
  515. values: {
  516. foo: 'not-a-percentage',
  517. },
  518. type: ['percentage'],
  519. }
  520. )
  521. },
  522. ],
  523. corePlugins: [],
  524. }
  525. return run('@tailwind utilities', config).then((result) => {
  526. expect(result.css).toMatchFormattedCss(css`
  527. .test-foo {
  528. value: not-a-percentage;
  529. }
  530. `)
  531. })
  532. })