x-bind-class.spec.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { beHidden, beVisible, haveText, beChecked, haveAttribute, haveClasses, haveValue, notBeChecked, notHaveAttribute, notHaveClasses, test, html } from '../../utils'
  2. test('class attribute bindings are merged by string syntax',
  3. html`
  4. <div x-data="{ isOn: false }">
  5. <span class="foo" x-bind:class="isOn ? 'bar': ''"></span>
  6. <button @click="isOn = ! isOn">button</button>
  7. </div>
  8. `,
  9. ({ get }) => {
  10. get('span').should(haveClasses(['foo']))
  11. get('span').should(notHaveClasses(['bar']))
  12. get('button').click()
  13. get('span').should(haveClasses(['foo']))
  14. get('span').should(haveClasses(['bar']))
  15. }
  16. )
  17. test('class attribute bindings are added by string syntax',
  18. html`
  19. <div x-data="{ initialClass: 'foo' }">
  20. <span x-bind:class="initialClass"></span>
  21. </div>
  22. `,
  23. ({ get }) => get('span').should(haveClasses(['foo']))
  24. )
  25. test('class attribute bindings are added by array syntax',
  26. html`
  27. <div x-data="{ initialClass: 'foo' }">
  28. <span x-bind:class="[initialClass, 'bar']"></span>
  29. </div>
  30. `,
  31. ({ get }) => get('span').should(haveClasses(['foo', 'bar']))
  32. )
  33. test('class attribute bindings are added by object syntax',
  34. html`
  35. <div x-data="{ mode: 0 }">
  36. <span class="foo baz"
  37. x-bind:class="{
  38. 'foo bar border-blue-900' : mode === 0,
  39. 'foo bar border-red-900' : mode === 1,
  40. 'bar border-red-900' : mode === 2,
  41. }"
  42. ></span>
  43. <button @click="mode = (mode + 1) % 3">button</button>
  44. </div>
  45. `,
  46. ({ get }) => {
  47. get('span').should(haveClasses(['foo', 'baz']))
  48. get('span').should(haveClasses(['bar', 'border-blue-900']))
  49. get('span').should(notHaveClasses(['border-red-900']))
  50. get('button').click()
  51. get('span').should(haveClasses(['foo', 'baz']))
  52. get('span').should(haveClasses(['bar', 'border-red-900']))
  53. get('span').should(notHaveClasses(['border-blue-900']))
  54. get('button').click()
  55. get('span').should(haveClasses(['baz']))
  56. get('span').should(haveClasses(['bar', 'border-red-900']))
  57. get('span').should(notHaveClasses(['foo']))
  58. get('span').should(notHaveClasses(['border-blue-900']))
  59. }
  60. )
  61. test('classes are removed before being added',
  62. html`
  63. <div x-data="{ isOpen: true }">
  64. <span class="text-red" :class="isOpen ? 'block' : 'hidden'">
  65. Span
  66. </span>
  67. <button @click="isOpen = !isOpen">click me</button>
  68. </div>
  69. `,
  70. ({ get }) => {
  71. get('span').should(haveClasses(['block', 'text-red']))
  72. get('button').click()
  73. get('span').should(haveClasses(['hidden', 'text-red']))
  74. get('span').should(notHaveClasses(['block']))
  75. }
  76. )
  77. test('extra whitespace in class binding string syntax is ignored',
  78. html`
  79. <div x-data>
  80. <span x-bind:class="' foo bar '"></span>
  81. </div>
  82. `,
  83. ({ get }) => get('span').should(haveClasses(['foo', 'bar']))
  84. )
  85. test('undefined class binding resolves to empty string',
  86. html`
  87. <div x-data="{ errorClass: (hasError) => { if (hasError) { return 'red' } } }">
  88. <span id="error" x-bind:class="errorClass(true)">should be red</span>
  89. <span id="empty" x-bind:class="errorClass(false)">should be empty</span>
  90. </div>
  91. `,
  92. ({ get }) => {
  93. get('span:nth-of-type(1)').should(haveClasses(['red']))
  94. get('span:nth-of-type(2)').should(notHaveClasses(['red']))
  95. }
  96. )