Comparing version 2.4.0 to 2.4.1
{ | ||
"main": "dist/alpine.js", | ||
"name": "alpinejs", | ||
"version": "2.4.0", | ||
"version": "2.4.1", | ||
"repository": { | ||
@@ -6,0 +6,0 @@ "type": "git", |
@@ -116,2 +116,3 @@ # Alpine.js | ||
| [`x-transition`](#x-transition) | Directives for applying classes to various stages of an element's transition | | ||
| [`x-spread`](#x-spread) | Allows you to bind an object of Alpine directives to an element for better reausibility | | ||
| [`x-cloak`](#x-cloak) | This attribute is removed when Alpine initializes. Useful for hiding pre-initialized DOM. | | ||
@@ -529,2 +530,47 @@ | ||
### `x-spread` | ||
**Example:** | ||
```html | ||
<div x-data="dropdown"> | ||
<button x-spread="trigger">Open Dropdown</button> | ||
<span x-spread="dialogue">Dropdown Contents</span> | ||
</div> | ||
<script> | ||
function dropdown() { | ||
return { | ||
open: false, | ||
trigger: { | ||
['@click']() { | ||
this.open = true | ||
}, | ||
}, | ||
dialogue: { | ||
['x-show']() { | ||
return this.open | ||
}, | ||
['@click.away']() { | ||
this.open = false | ||
}, | ||
} | ||
} | ||
} | ||
</script> | ||
``` | ||
`x-spread` allows you to extract an elements Alpine bindings into a reusable object. | ||
The object keys are the directives (Can be any directive including modifiers), and the values are callbacks to be evaluated by Alpine. | ||
> Note: The only anomoly with x-spread is when used with `x-for`. When the directive being "spread" is `x-for`, you should return a normal expression string from the callback. For example: `['x-for']() { return 'item in items' }`. | ||
```html | ||
<style> | ||
[x-cloak] { display: none; } | ||
</style> | ||
``` | ||
--- | ||
### `x-cloak` | ||
@@ -531,0 +577,0 @@ **Example:** `<div x-data="{}" x-cloak></div>` |
import { transitionIn, transitionOut } from '../utils' | ||
export function handleShowDirective(component, el, value, modifiers, initialUpdate = false) { | ||
// if value is changed resolve any previous pending transitions before starting a new one. | ||
if (el.__x_transition_remaining && el.__x_transition_last_value !== value) { | ||
el.__x_transition_remaining() | ||
} | ||
const hide = () => { | ||
@@ -22,5 +17,2 @@ el.style.display = 'none' | ||
if (initialUpdate === true) { | ||
// Assign current value to el to check later on for preventing transition overlaps. | ||
el.__x_transition_last_value = value | ||
if (value) { | ||
@@ -51,5 +43,2 @@ show() | ||
} | ||
// Assign current value to el. | ||
el.__x_transition_last_value = value | ||
} | ||
@@ -74,8 +63,5 @@ | ||
if (el.__x_transition_last_value !== value) { | ||
// We'll push the handler onto a stack to be handled later. | ||
component.showDirectiveStack.push(handle) | ||
component.showDirectiveStack.push(handle) | ||
component.showDirectiveLastElement = el | ||
} | ||
component.showDirectiveLastElement = el | ||
} |
@@ -411,3 +411,3 @@ | ||
// Assign current transition to el in case we need to force it. | ||
el.__x_transition_remaining = once(() => { | ||
setTimeout(() => { | ||
stages.hide() | ||
@@ -420,8 +420,3 @@ | ||
} | ||
// Safe to remove transition from el since it is completed. | ||
delete el.__x_transition_remaining | ||
}) | ||
setTimeout(el.__x_transition_remaining, duration); | ||
}, duration) | ||
}) | ||
@@ -434,12 +429,1 @@ }); | ||
} | ||
export function once(callback) { | ||
let called = false | ||
return function () { | ||
if (! called) { | ||
called = true | ||
callback.apply(this, arguments) | ||
} | ||
} | ||
} |
@@ -623,105 +623,1 @@ import Alpine from 'alpinejs' | ||
}) | ||
test('remaining transitions forced to complete if they exists', async () => { | ||
jest.spyOn(window, 'requestAnimationFrame').mockImplementation((callback) => { | ||
setTimeout(callback, 0) | ||
}); | ||
// Hardcoding 10ms animation time for later assertions. | ||
jest.spyOn(window, 'getComputedStyle').mockImplementation(el => { | ||
return { | ||
transitionDuration: '0s', | ||
animationDuration: '.1s' | ||
} | ||
}); | ||
document.body.innerHTML = ` | ||
<div x-data="{ show: false }"> | ||
<button x-on:click="show = ! show"></button> | ||
<span | ||
x-show="show" | ||
x-transition:enter="animation-enter" | ||
x-transition:leave="animation-leave" | ||
></span> | ||
</div> | ||
` | ||
Alpine.start() | ||
await wait(() => { expect(document.querySelector('span').getAttribute('style')).toEqual('display: none;') }) | ||
// Trigger animation in. | ||
document.querySelector('button').click() | ||
// Wait for the first requestAnimationFrame. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-enter')).toEqual(true) | ||
// Trigger animation out. | ||
document.querySelector('button').click() | ||
// Wait for the next requestAnimationFrame. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true) | ||
// Wait for the next requestAnimationFrame. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0) | ||
) | ||
// Trigger animation in. | ||
document.querySelector('button').click() | ||
// Wait for the next requestAnimationFrame. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-enter')).toEqual(true) | ||
// Trigger animation out. | ||
document.querySelector('button').click() | ||
// Wait for the next requestAnimationFrame. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 0) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true) | ||
// The leave class should still be there since the animationDuration property is 100ms. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 99) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true) | ||
// The class shouldn't be there anymore. | ||
await new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(); | ||
}, 10) | ||
) | ||
expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(false) | ||
}) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61
742
684037
12452