variant-grouping.test.skip.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import { run, html, css } from './util/run'
  2. // TODO: Remove this once we enable this by default
  3. it('should not generate nested selectors if the feature flag is not enabled', () => {
  4. let config = {
  5. content: [{ raw: html`<div class="md:(underline,italic)"></div>` }],
  6. corePlugins: { preflight: false },
  7. plugins: [],
  8. }
  9. let input = css`
  10. @tailwind utilities;
  11. `
  12. return run(input, config).then((result) => {
  13. expect(result.css).toMatchFormattedCss(css`
  14. .italic {
  15. font-style: italic;
  16. }
  17. .underline {
  18. text-decoration-line: underline;
  19. }
  20. `)
  21. })
  22. })
  23. it('should be possible to group variants', () => {
  24. let config = {
  25. experimental: 'all',
  26. content: [{ raw: html`<div class="md:(underline,italic)"></div>` }],
  27. corePlugins: { preflight: false },
  28. plugins: [],
  29. }
  30. let input = css`
  31. @tailwind utilities;
  32. `
  33. return run(input, config).then((result) => {
  34. expect(result.css).toMatchFormattedCss(css`
  35. @media (min-width: 768px) {
  36. .md\:\(underline\2c italic\) {
  37. font-style: italic;
  38. text-decoration-line: underline;
  39. }
  40. }
  41. `)
  42. })
  43. })
  44. it('should be possible to group using constrained and arbitrary variants together', () => {
  45. let config = {
  46. experimental: 'all',
  47. content: [
  48. {
  49. raw: html`<div
  50. class="dark:[@supports(hover:hover)]:hover:[&>*]:([--potato:baked],bg-[#0088cc])"
  51. ></div>`,
  52. },
  53. ],
  54. corePlugins: { preflight: false },
  55. plugins: [],
  56. }
  57. let input = css`
  58. @tailwind utilities;
  59. `
  60. return run(input, config).then((result) => {
  61. expect(result.css).toMatchFormattedCss(css`
  62. @media (prefers-color-scheme: dark) {
  63. @supports (hover: hover) {
  64. .dark\:\[\@supports\(hover\:hover\)\]\:hover\:\[\&\>\*\]\:\(\[--potato\:baked\]\2c
  65. bg-\[\#0088cc\]\)
  66. > *:hover {
  67. --tw-bg-opacity: 1;
  68. background-color: rgb(0 136 204 / var(--tw-bg-opacity));
  69. --potato: baked;
  70. }
  71. }
  72. }
  73. `)
  74. })
  75. })
  76. it('should be possible to group multiple variants', () => {
  77. let config = {
  78. experimental: 'all',
  79. content: [{ raw: html`<div class="md:dark:(underline,italic)"></div>` }],
  80. corePlugins: { preflight: false },
  81. plugins: [],
  82. }
  83. let input = css`
  84. @tailwind utilities;
  85. `
  86. return run(input, config).then((result) => {
  87. expect(result.css).toMatchFormattedCss(css`
  88. @media (min-width: 768px) {
  89. @media (prefers-color-scheme: dark) {
  90. .md\:dark\:\(underline\2c italic\) {
  91. font-style: italic;
  92. text-decoration-line: underline;
  93. }
  94. }
  95. }
  96. `)
  97. })
  98. })
  99. it('should be possible to group nested grouped variants', () => {
  100. let config = {
  101. experimental: 'all',
  102. content: [{ raw: html`<div class="md:(underline,italic,hover:(uppercase,font-bold))"></div>` }],
  103. corePlugins: { preflight: false },
  104. plugins: [],
  105. }
  106. let input = css`
  107. @tailwind utilities;
  108. `
  109. return run(input, config).then((result) => {
  110. expect(result.css).toMatchFormattedCss(css`
  111. @media (min-width: 768px) {
  112. .md\:\(underline\2c italic\2c hover\:\(uppercase\2c font-bold\)\) {
  113. font-style: italic;
  114. text-decoration-line: underline;
  115. }
  116. .md\:\(underline\2c italic\2c hover\:\(uppercase\2c font-bold\)\):hover {
  117. font-weight: 700;
  118. text-transform: uppercase;
  119. }
  120. }
  121. `)
  122. })
  123. })
  124. it('should be possible to use nested multiple grouped variants', () => {
  125. let config = {
  126. experimental: 'all',
  127. content: [
  128. {
  129. raw: html`<div class="md:(text-black,dark:(text-white,hover:focus:text-gray-100))"></div>`,
  130. },
  131. ],
  132. corePlugins: { preflight: false },
  133. plugins: [],
  134. }
  135. let input = css`
  136. @tailwind utilities;
  137. `
  138. return run(input, config).then((result) => {
  139. expect(result.css).toMatchFormattedCss(css`
  140. @media (min-width: 768px) {
  141. .md\:\(text-black\2c dark\:\(text-white\2c hover\:focus\:text-gray-100\)\) {
  142. --tw-text-opacity: 1;
  143. color: rgb(0 0 0 / var(--tw-text-opacity));
  144. }
  145. @media (prefers-color-scheme: dark) {
  146. .md\:\(text-black\2c dark\:\(text-white\2c hover\:focus\:text-gray-100\)\) {
  147. --tw-text-opacity: 1;
  148. color: rgb(255 255 255 / var(--tw-text-opacity));
  149. }
  150. .md\:\(text-black\2c dark\:\(text-white\2c hover\:focus\:text-gray-100\)\):focus:hover {
  151. --tw-text-opacity: 1;
  152. color: rgb(243 244 246 / var(--tw-text-opacity));
  153. }
  154. }
  155. }
  156. `)
  157. })
  158. })
  159. it('should be possible to mix and match nesting and different variant combinations', () => {
  160. let config = {
  161. experimental: 'all',
  162. content: [
  163. {
  164. raw: html`<div
  165. class="md:[&>*]:(text-black,dark:(text-white,hover:[@supports(color:green)]:[&:nth-child(2n=1)]:text-gray-100))"
  166. ></div>`,
  167. },
  168. ],
  169. corePlugins: { preflight: false },
  170. plugins: [],
  171. }
  172. let input = css`
  173. @tailwind utilities;
  174. `
  175. return run(input, config).then((result) => {
  176. expect(result.css).toMatchFormattedCss(css`
  177. @media (min-width: 768px) {
  178. .md\:\[\&\>\*\]\:\(text-black\2c
  179. dark\:\(text-white\2c
  180. hover\:\[\@supports\(color\:green\)\]\:\[\&\:nth-child\(2n\=1\)\]\:text-gray-100\)\)
  181. > * {
  182. --tw-text-opacity: 1;
  183. color: rgb(0 0 0 / var(--tw-text-opacity));
  184. }
  185. @media (prefers-color-scheme: dark) {
  186. .md\:\[\&\>\*\]\:\(text-black\2c
  187. dark\:\(text-white\2c
  188. hover\:\[\@supports\(color\:green\)\]\:\[\&\:nth-child\(2n\=1\)\]\:text-gray-100\)\)
  189. > * {
  190. --tw-text-opacity: 1;
  191. color: rgb(255 255 255 / var(--tw-text-opacity));
  192. }
  193. @supports (color: green) {
  194. .md\:\[\&\>\*\]\:\(text-black\2c
  195. dark\:\(text-white\2c
  196. hover\:\[\@supports\(color\:green\)\]\:\[\&\:nth-child\(2n\=1\)\]\:text-gray-100\)\):nth-child(2n=1):hover
  197. > * {
  198. --tw-text-opacity: 1;
  199. color: rgb(243 244 246 / var(--tw-text-opacity));
  200. }
  201. }
  202. }
  203. }
  204. `)
  205. })
  206. })
  207. it('should group with variants defined in external plugins', () => {
  208. let config = {
  209. experimental: 'all',
  210. content: [
  211. {
  212. raw: html`
  213. <div class="ui-active:(bg-black,text-white) ui-selected:(bg-indigo-500,underline)"></div>
  214. `,
  215. },
  216. ],
  217. corePlugins: { preflight: false },
  218. plugins: [
  219. ({ addVariant }) => {
  220. addVariant('ui-active', ['&[data-ui-state~="active"]', '[data-ui-state~="active"] &'])
  221. addVariant('ui-selected', ['&[data-ui-state~="selected"]', '[data-ui-state~="selected"] &'])
  222. },
  223. ],
  224. }
  225. let input = css`
  226. @tailwind utilities;
  227. `
  228. return run(input, config).then((result) => {
  229. expect(result.css).toMatchFormattedCss(css`
  230. .ui-active\:\(bg-black\2c text-white\)[data-ui-state~='active'] {
  231. --tw-bg-opacity: 1;
  232. background-color: rgb(0 0 0 / var(--tw-bg-opacity));
  233. --tw-text-opacity: 1;
  234. color: rgb(255 255 255 / var(--tw-text-opacity));
  235. }
  236. [data-ui-state~='active'] .ui-active\:\(bg-black\2c text-white\) {
  237. --tw-bg-opacity: 1;
  238. background-color: rgb(0 0 0 / var(--tw-bg-opacity));
  239. --tw-text-opacity: 1;
  240. color: rgb(255 255 255 / var(--tw-text-opacity));
  241. }
  242. .ui-selected\:\(bg-indigo-500\2c underline\)[data-ui-state~='selected'] {
  243. --tw-bg-opacity: 1;
  244. background-color: rgb(99 102 241 / var(--tw-bg-opacity));
  245. text-decoration-line: underline;
  246. }
  247. [data-ui-state~='selected'] .ui-selected\:\(bg-indigo-500\2c underline\) {
  248. --tw-bg-opacity: 1;
  249. background-color: rgb(99 102 241 / var(--tw-bg-opacity));
  250. text-decoration-line: underline;
  251. }
  252. `)
  253. })
  254. })