Просмотр исходного кода

Merge pull request #1556 from JacobPozaic/main

Fix x-bind:class directive using object syntax removes classes that are in a true condition when the class is also present in a false condition
Caleb Porzio 3 лет назад
Родитель
Сommit
0ae7e36534

+ 8 - 8
packages/alpinejs/src/utils/classes.js

@@ -35,13 +35,6 @@ function setClassesFromObject(el, classObject) {
     let added = []
     let removed = []
 
-    forAdd.forEach(i => {
-        if (! el.classList.contains(i)) {
-            el.classList.add(i)
-            added.push(i)
-        }
-    })
-
     forRemove.forEach(i => {
         if (el.classList.contains(i)) {
             el.classList.remove(i)
@@ -49,8 +42,15 @@ function setClassesFromObject(el, classObject) {
         }
     })
 
+    forAdd.forEach(i => {
+        if (! el.classList.contains(i)) {
+            el.classList.add(i)
+            added.push(i)
+        }
+    })
+
     return () => {
-        added.forEach(i => el.classList.remove(i))
         removed.forEach(i => el.classList.add(i))
+        added.forEach(i => el.classList.remove(i))
     }
 }

+ 30 - 0
tests/cypress/integration/directives/x-bind:class.spec.js

@@ -35,6 +35,36 @@ test('class attribute bindings are added by array syntax',
     ({ get }) => get('span').should(haveClasses(['foo', 'bar']))
 )
 
+test('class attribute bindings are added by object syntax',
+    html`
+        <div x-data="{ mode: 0 }">
+            <span class="foo baz"
+                  x-bind:class="{
+                      'foo bar border-blue-900' : mode === 0,
+                      'foo bar border-red-900' : mode === 1,
+                      'bar border-red-900' : mode === 2,
+                  }"
+            ></span>
+
+            <button @click="mode = (mode + 1) % 3">button</button>
+        </div>
+    `,
+    ({ get }) => {
+        get('span').should(haveClasses(['foo', 'baz']))
+        get('span').should(haveClasses(['bar', 'border-blue-900']))
+        get('span').should(notHaveClasses(['border-red-900']))
+        get('button').click()
+        get('span').should(haveClasses(['foo', 'baz']))
+        get('span').should(haveClasses(['bar', 'border-red-900']))
+        get('span').should(notHaveClasses(['border-blue-900']))
+        get('button').click()
+        get('span').should(haveClasses(['baz']))
+        get('span').should(haveClasses(['bar', 'border-red-900']))
+        get('span').should(notHaveClasses(['foo']))
+        get('span').should(notHaveClasses(['border-blue-900']))
+    }
+)
+
 test('classes are removed before being added',
     html`
         <div x-data="{ isOpen: true }">