Explorar el Código

Merge pull request #16 from mhanberg/window-modifier

Window modifier for x-on directive
Caleb Porzio hace 5 años
padre
commit
c7d8fd36f4
Se han modificado 3 ficheros con 26 adiciones y 1 borrados
  1. 5 0
      README.md
  2. 3 1
      src/component.js
  3. 18 0
      test/on.spec.js

+ 5 - 0
README.md

@@ -162,6 +162,11 @@ Adding `.prevent` to an event listener will call `preventDefault` on the trigger
 
 Adding `.stop` to an event listener will call `stopPropagation` on the triggered event. In the above example, this means the "click" event won't bubble from the button to the outer `<div>`. Or in other words, when a user clicks the button, `foo` won't be set to `'bar'`.
 
+**`.window` modifier**
+**Example:** `<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>`
+
+Adding `.window` to an event listener will install the listener on the global window object instead of the DOM node on which it is declared. This is useful for when you want to modify component state when something changes with the window, like the resize event. In this example, when the window grows larger than 768 pixels wide, we will close the modal/dropdown, otherwise maintain the same state.
+
 ---
 
 ### `x-model`

+ 3 - 1
src/component.js

@@ -178,7 +178,9 @@ export default class Component {
                 this.runListenerHandler(expression, e)
             })
         } else {
-            el.addEventListener(event, e => {
+            const node = modifiers.includes('window') ? window : el
+
+            node.addEventListener(event, e => {
                 if (modifiers.includes('prevent')) e.preventDefault()
                 if (modifiers.includes('stop')) e.stopPropagation()
 

+ 18 - 0
test/on.spec.js

@@ -59,6 +59,24 @@ test('.prevent modifier', async () => {
     expect(document.querySelector('input').checked).toEqual(false)
 })
 
+test('.window modifier', async () => {
+    document.body.innerHTML = `
+        <div x-data="{ foo: 'bar' }">
+            <div x-on:click.window="foo = 'baz'"></div>
+
+            <span x-bind:foo="foo"></span>
+        </div>
+    `
+
+    projectX.start()
+
+    expect(document.querySelector('span').getAttribute('foo')).toEqual('bar')
+
+    document.body.click()
+
+    await wait(() => { expect(document.querySelector('span').getAttribute('foo')).toEqual('baz') })
+})
+
 test('click away', async () => {
     // Because jsDom doesn't support .offsetHeight and offsetWidth, we have to
     // make our own implementation using a specific class added to the class. Ugh.