Переглянути джерело

Allow for using x-show with an important modifier (#3002)

* Allow for using x-show with an important modifier
This sets the display property with the important property.
This is useful for overriding classes which itself set the display
property with !important

* Update packages/docs/src/en/directives/show.md

Co-authored-by: Ryan Chandler <ryangjchandler@gmail.com>

Co-authored-by: Ryan Chandler <ryangjchandler@gmail.com>
Tim 3 роки тому
батько
коміт
4654eb023e

+ 3 - 1
packages/alpinejs/src/directives/x-show.js

@@ -9,7 +9,9 @@ directive('show', (el, { modifiers, expression }, { effect }) => {
     // We're going to set this function on the element directly so that
     // other plugins like "Collapse" can overwrite them with their own logic.
     if (! el._x_doHide) el._x_doHide = () => {
-        mutateDom(() => el.style.display = 'none')
+        mutateDom(() => {
+            el.style.setProperty('display', 'none', modifiers.includes('important') ? 'important' : undefined)
+        })
     }
 
     if (! el._x_doShow) el._x_doShow = () => {

+ 17 - 0
packages/docs/src/en/directives/show.md

@@ -37,3 +37,20 @@ If you want to apply smooth transitions to the `x-show` behavior, you can use it
     </div>
 </div>
 ```
+
+<a name="using-the-important-modifier"></a>
+## Using the important modifier
+
+Sometimes you need to apply a little more force to actually hide an element. In cases where a CSS selector applies the `display` property with the `!important` flag, it will take precedence over the inline style set by Alpine.
+
+In these cases you may use the `.important` modifier to set the inline style to `display: none !important`.
+
+```alpine
+<div x-data="{ open: false }">
+    <button x-on:click="open = ! open">Toggle Dropdown</button>
+
+    <div x-show.important="open">
+        Dropdown Contents...
+    </div>
+</div>
+```

+ 18 - 1
tests/cypress/integration/directives/x-show.spec.js

@@ -158,4 +158,21 @@ test('x-show executes consecutive state changes in correct order',
         get('button#enable').should(beVisible())
         get('button#disable').should(beHidden())
     }
-)
+)
+
+test('x-show toggles display: none; with the !important property when using the .important modifier while respecting other style attributes',
+    html`
+        <div x-data="{ show: true }">
+            <span x-show.important="show" style="color: blue;">thing</span>
+
+            <button x-on:click="show = false"></button>
+        </div>
+    `,
+    ({ get }) => {
+        get('span').should(beVisible())
+        get('span').should(haveAttribute('style', 'color: blue;'))
+        get('button').click()
+        get('span').should(beHidden())
+        get('span').should(haveAttribute('style', 'color: blue; display: none !important;'))
+    }
+)