color-opacity-modifiers.test.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import { run, css, html } from './util/run'
  2. test('basic color opacity modifier', async () => {
  3. let config = {
  4. content: [{ raw: html`<div class="bg-red-500/50"></div>` }],
  5. }
  6. return run('@tailwind utilities', config).then((result) => {
  7. expect(result.css).toMatchFormattedCss(css`
  8. .bg-red-500\/50 {
  9. background-color: rgb(239 68 68 / 0.5);
  10. }
  11. `)
  12. })
  13. })
  14. test('colors with slashes are matched first', async () => {
  15. let config = {
  16. content: [{ raw: html`<div class="bg-red-500/50"></div>` }],
  17. theme: {
  18. extend: {
  19. colors: {
  20. 'red-500/50': '#ff0000',
  21. },
  22. },
  23. },
  24. }
  25. return run('@tailwind utilities', config).then((result) => {
  26. expect(result.css).toMatchFormattedCss(css`
  27. .bg-red-500\/50 {
  28. --tw-bg-opacity: 1;
  29. background-color: rgb(255 0 0 / var(--tw-bg-opacity));
  30. }
  31. `)
  32. })
  33. })
  34. test('arbitrary color opacity modifier', async () => {
  35. let config = {
  36. content: [{ raw: html`<div class="bg-red-500/[var(--opacity)]"></div>` }],
  37. }
  38. return run('@tailwind utilities', config).then((result) => {
  39. expect(result.css).toMatchFormattedCss(css`
  40. .bg-red-500\/\[var\(--opacity\)\] {
  41. background-color: rgb(239 68 68 / var(--opacity));
  42. }
  43. `)
  44. })
  45. })
  46. test('missing alpha generates nothing', async () => {
  47. let config = {
  48. content: [{ raw: html`<div class="bg-red-500/"></div>` }],
  49. }
  50. return run('@tailwind utilities', config).then((result) => {
  51. expect(result.css).toMatchFormattedCss(``)
  52. })
  53. })
  54. test('arbitrary color with opacity from scale', async () => {
  55. let config = {
  56. content: [{ raw: 'bg-[wheat]/50' }],
  57. theme: {},
  58. plugins: [],
  59. }
  60. return run('@tailwind utilities', config).then((result) => {
  61. expect(result.css).toMatchFormattedCss(css`
  62. .bg-\[wheat\]\/50 {
  63. background-color: rgb(245 222 179 / 0.5);
  64. }
  65. `)
  66. })
  67. })
  68. test('arbitrary color with arbitrary opacity', async () => {
  69. let config = {
  70. content: [{ raw: 'bg-[#bada55]/[0.2]' }],
  71. theme: {},
  72. plugins: [],
  73. }
  74. return run('@tailwind utilities', config).then((result) => {
  75. expect(result.css).toMatchFormattedCss(css`
  76. .bg-\[\#bada55\]\/\[0\.2\] {
  77. background-color: rgb(186 218 85 / 0.2);
  78. }
  79. `)
  80. })
  81. })
  82. test('undefined theme color with opacity from scale', async () => {
  83. let config = {
  84. content: [{ raw: 'bg-garbage/50' }],
  85. theme: {},
  86. plugins: [],
  87. }
  88. return run('@tailwind utilities', config).then((result) => {
  89. expect(result.css).toMatchFormattedCss(``)
  90. })
  91. })
  92. test('values not in the opacity config are ignored', async () => {
  93. let config = {
  94. content: [{ raw: html`<div class="bg-red-500/29"></div>` }],
  95. theme: {
  96. opacity: {
  97. 0: '0',
  98. 25: '0.25',
  99. 5: '0.5',
  100. 75: '0.75',
  101. 100: '1',
  102. },
  103. },
  104. }
  105. return run('@tailwind utilities', config).then((result) => {
  106. expect(result.css).toMatchFormattedCss(``)
  107. })
  108. })
  109. test('function colors are supported', async () => {
  110. let config = {
  111. content: [{ raw: html`<div class="bg-blue/50"></div>` }],
  112. theme: {
  113. colors: {
  114. blue: ({ opacityValue }) => {
  115. return `rgba(var(--colors-blue), ${opacityValue})`
  116. },
  117. },
  118. },
  119. }
  120. return run('@tailwind utilities', config).then((result) => {
  121. expect(result.css).toMatchFormattedCss(css`
  122. .bg-blue\/50 {
  123. background-color: rgba(var(--colors-blue), 0.5);
  124. }
  125. `)
  126. })
  127. })
  128. test('utilities that support any type are supported', async () => {
  129. let config = {
  130. content: [
  131. {
  132. raw: html`
  133. <div class="from-red-500/50"></div>
  134. <div class="fill-red-500/25"></div>
  135. <div class="placeholder-red-500/75"></div>
  136. `,
  137. },
  138. ],
  139. theme: {
  140. extend: {
  141. fill: (theme) => theme('colors'),
  142. },
  143. },
  144. plugins: [],
  145. }
  146. return run('@tailwind utilities', config).then((result) => {
  147. expect(result.css).toMatchFormattedCss(css`
  148. .from-red-500\/50 {
  149. --tw-gradient-from: rgb(239 68 68 / 0.5);
  150. --tw-gradient-to: rgb(239 68 68 / 0);
  151. --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
  152. }
  153. .fill-red-500\/25 {
  154. fill: rgb(239 68 68 / 0.25);
  155. }
  156. .placeholder-red-500\/75::placeholder {
  157. color: rgb(239 68 68 / 0.75);
  158. }
  159. `)
  160. })
  161. })
  162. test('opacity modifier in combination with partial custom properties', async () => {
  163. let config = {
  164. content: [
  165. {
  166. raw: html`
  167. <div class="bg-[hsl(var(--foo),50%,50%)]"></div>
  168. <div class="bg-[hsl(123,var(--foo),50%)]"></div>
  169. <div class="bg-[hsl(123,50%,var(--foo))]"></div>
  170. <div class="bg-[hsl(var(--foo),50%,50%)]/50"></div>
  171. <div class="bg-[hsl(123,var(--foo),50%)]/50"></div>
  172. <div class="bg-[hsl(123,50%,var(--foo))]/50"></div>
  173. <div class="bg-[hsl(var(--foo),var(--bar),var(--baz))]/50"></div>
  174. `,
  175. },
  176. ],
  177. corePlugins: { preflight: false },
  178. plugins: [],
  179. }
  180. let input = css`
  181. @tailwind utilities;
  182. `
  183. return run(input, config).then((result) => {
  184. expect(result.css).toMatchFormattedCss(css`
  185. .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\] {
  186. --tw-bg-opacity: 1;
  187. background-color: hsl(var(--foo) 50% 50% / var(--tw-bg-opacity));
  188. }
  189. .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\] {
  190. --tw-bg-opacity: 1;
  191. background-color: hsl(123 var(--foo) 50% / var(--tw-bg-opacity));
  192. }
  193. .bg-\[hsl\(123\2c 50\%\2c var\(--foo\)\)\] {
  194. --tw-bg-opacity: 1;
  195. background-color: hsl(123 50% var(--foo) / var(--tw-bg-opacity));
  196. }
  197. .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\]\/50 {
  198. background-color: hsl(var(--foo) 50% 50% / 0.5);
  199. }
  200. .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\]\/50 {
  201. background-color: hsl(123 var(--foo) 50% / 0.5);
  202. }
  203. .bg-\[hsl\(123\2c 50\%\2c var\(--foo\)\)\]\/50 {
  204. background-color: hsl(123 50% var(--foo) / 0.5);
  205. }
  206. .bg-\[hsl\(var\(--foo\)\2c var\(--bar\)\2c var\(--baz\)\)\]\/50 {
  207. background-color: hsl(var(--foo) var(--bar) var(--baz) / 0.5);
  208. }
  209. `)
  210. })
  211. })