Skip to content

Commit

Permalink
Fix transition options inconsistency/bug (#261)
Browse files Browse the repository at this point in the history
* Fix issue with transitionOptions using toggle and toggleClass

Between leave() and enter() transitionOptions was inconsistent on how it
handled the toggleClass/toggle option. Now excepting both options.

* Speed up tests. Don't need to timeout that long
  • Loading branch information
jaywhy authored Oct 22, 2024
1 parent 9f93932 commit 2e98905
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
19 changes: 11 additions & 8 deletions src/transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ export async function transition(element, state, transitionOptions = {}) {
// data-transition-leave-from="bg-opacity-80"
// data-transition-leave-to="bg-opacity-0"
export async function enter(element, transitionOptions = {}) {
const transitionClasses = element.dataset.transitionEnter || transitionOptions.enter || 'enter'
const fromClasses = element.dataset.transitionEnterFrom || transitionOptions.enterFrom || 'enter-from'
const toClasses = element.dataset.transitionEnterTo || transitionOptions.enterTo || 'enter-to'
const toggleClass = element.dataset.toggleClass || transitionOptions.toggleClass || 'hidden'
const { transitionClasses, fromClasses, toClasses, toggleClass } = getTransitionOptions("Enter", element, transitionOptions)

return performTransitions(element, {
firstFrame() {
Expand All @@ -44,10 +41,7 @@ export async function enter(element, transitionOptions = {}) {
}

export async function leave(element, transitionOptions = {}) {
const transitionClasses = element.dataset.transitionLeave || transitionOptions.leave || 'leave'
const fromClasses = element.dataset.transitionLeaveFrom || transitionOptions.leaveFrom || 'leave-from'
const toClasses = element.dataset.transitionLeaveTo || transitionOptions.leaveTo || 'leave-to'
const toggleClass = element.dataset.toggleClass || transitionOptions.toggle || 'hidden'
const { transitionClasses, fromClasses, toClasses, toggleClass } = getTransitionOptions("Leave", element, transitionOptions)

return performTransitions(element, {
firstFrame() {
Expand All @@ -66,6 +60,15 @@ export async function leave(element, transitionOptions = {}) {
})
}

function getTransitionOptions(type, element, transitionOptions) {
return {
transitionClasses: element.dataset[`transition${type}`] || transitionOptions[type.toLowerCase()] || type.toLowerCase(),
fromClasses: element.dataset[`transition${type}From`] || transitionOptions[`${type.toLowerCase()}From`] || `${type.toLowerCase()}-from`,
toClasses: element.dataset[`transition${type}To`] || transitionOptions[`${type.toLowerCase()}To`] || `${type.toLowerCase()}-to`,
toggleClass: element.dataset.toggleClass || transitionOptions.toggleClass || transitionOptions.toggle || 'hidden'
}
}

function setupTransition(element) {
element._stimulus_transition = {
timeout: null,
Expand Down
60 changes: 58 additions & 2 deletions test/transition_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,37 @@ describe('Transition', () => {
await nextFrame()
expect(target.className.split(' ')).to.have.members(['foo', 'transition-opacity', 'ease-in-out', 'duration-100', 'opacity-0'])

await aTimeout(100)
await aTimeout(0)
expect(target.className.split(' ')).to.have.members(['foo', 'opacity-0', 'hidden'])
})

it('parses transitionOptions properly', async () => {
await fixture(html`
<div id="my-div" class="opacity-100">
This popover shows on hover
</div>
`)

const target = document.getElementById('my-div')

leave(target, {
leave: 'transition-opacity ease-in-out duration-100',
leaveFrom: 'opacity-100',
leaveTo: 'opacity-0',
toggleClass: 'my-hidden'
})

expect(target.className.split(' ')).to.have.members(['opacity-100'])

await nextFrame()
expect(target.className.split(' ')).to.have.members(['transition-opacity', 'ease-in-out', 'duration-100', 'opacity-100'])

await nextFrame()
expect(target.className.split(' ')).to.have.members(['opacity-0', 'transition-opacity', 'ease-in-out', 'duration-100'])

await aTimeout(0)
expect(target.className.split(' ')).to.have.members(['my-hidden', 'opacity-0'])
})
})

describe('enter()', () => {
Expand All @@ -131,9 +159,37 @@ describe('Transition', () => {
await nextFrame()
expect(target.className.split(' ')).to.have.members(['foo', 'transition-opacity', 'ease-in-out', 'duration-100', 'opacity-100'])

await aTimeout(100)
await aTimeout(0)
expect(target.className.split(' ')).to.have.members(['foo', 'opacity-100'])
})

it('parses transitionOptions properly', async () => {
await fixture(html`
<div id="my-div" class="my-hidden">
This popover shows on hover
</div>
`)

const target = document.getElementById('my-div')

enter(target, {
enter: 'transition-opacity ease-in-out duration-100',
enterFrom: 'opacity-0',
enterTo: 'opacity-100',
toggle: 'my-hidden'
})

expect(target.className.split(' ')).to.have.members(['my-hidden'])

await nextFrame()
expect(target.className.split(' ')).to.have.members(['opacity-0', 'transition-opacity', 'ease-in-out', 'duration-100'])

await nextFrame()
expect(target.className.split(' ')).to.have.members(['transition-opacity', 'ease-in-out', 'duration-100', 'opacity-100'])

await aTimeout(0)
expect(target.className.split(' ')).to.have.members(['opacity-100'])
})
})

describe('cancelTransition()', () => {
Expand Down

0 comments on commit 2e98905

Please sign in to comment.