Skip to content

Commit

Permalink
transition
Browse files Browse the repository at this point in the history
  • Loading branch information
Sasha Kondrashov committed Mar 3, 2024
1 parent 6f64485 commit c2d905b
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 63 deletions.
23 changes: 14 additions & 9 deletions src/addons/TransitionablePortal/TransitionablePortal.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react'

import { TransitionEventData, TransitionProps } from '../../modules/Transition/Transition'
import { TransitionProps, TRANSITION_STATUSES } from '../../modules/Transition/Transition'
import { PortalProps } from '../Portal/Portal'

export interface TransitionablePortalProps extends StrictTransitionablePortalProps {
Expand All @@ -15,33 +15,37 @@ export interface StrictTransitionablePortalProps {
* Called when a close event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props and internal state.
* @param {object} props - All props.
* @param {object} state - Internal state.
*/
onClose?: (nothing: null, data: PortalProps & TransitionablePortalState) => void
onClose?: (nothing: null, props: PortalProps, state: TransitionablePortalState) => void

/**
* Callback on each transition that changes visibility to hidden.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {object} state - Internal state.
*/
onHide?: (nothing: null, data: TransitionEventData & TransitionablePortalState) => void
onHide?: (nothing: null, props: TransitionProps, state: TransitionablePortalState) => void

/**
* Called when an open event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props and internal state.
* @param {object} props - All props.
* @param {object} state - Internal state.
*/
onOpen?: (nothing: null, data: PortalProps & TransitionablePortalState) => void
onOpen?: (nothing: null, props: PortalProps, state: TransitionablePortalState) => void

/**
* Callback on animation start.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {object} state - Internal state.
*/
onStart?: (nothing: null, data: TransitionEventData & TransitionablePortalState) => void
onStart?: (nothing: null, props: TransitionProps, state: TransitionablePortalState) => void

/** Controls whether or not the portal is displayed. */
open?: boolean
Expand All @@ -51,6 +55,7 @@ export interface StrictTransitionablePortalProps {
}

export interface TransitionablePortalState {
transitionStatus: TRANSITION_STATUSES
portalOpen: boolean
transitionVisible: boolean
}
Expand Down
25 changes: 16 additions & 9 deletions src/addons/TransitionablePortal/TransitionablePortal.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,28 @@ function TransitionablePortal(props) {
setPortalOpen(true)
}

const handleTransitionHide = (nothing, data) => {
const handleTransitionHide = (nothing, data, status) => {
debug('handleTransitionHide()')

setTransitionVisible(false)
_.invoke(props, 'onClose', null, { ...data, portalOpen: false, transitionVisible: false })
_.invoke(props, 'onHide', null, { ...data, portalOpen, transitionVisible: false })
_.invoke(props, 'onClose', null, data, {
transitionStatus: status,
portalOpen: false,
transitionVisible: false,
})
_.invoke(props, 'onHide', null, data, {
transitionStatus: status,
portalOpen,
transitionVisible: false,
})
}

const handleTransitionStart = (nothing, data) => {
const handleTransitionStart = (nothing, data, status) => {
debug('handleTransitionStart()')
const { status } = data
const nextTransitionVisible = status === TRANSITION_STATUS_ENTERING

_.invoke(props, 'onStart', null, {
...data,
_.invoke(props, 'onStart', null, data, {
transitionStatus: status,
portalOpen,
transitionVisible: nextTransitionVisible,
})
Expand All @@ -99,8 +106,8 @@ function TransitionablePortal(props) {
}

setTransitionVisible(nextTransitionVisible)
_.invoke(props, 'onOpen', null, {
...data,
_.invoke(props, 'onOpen', null, data, {
transitionStatus: status,
transitionVisible: nextTransitionVisible,
portalOpen: true,
})
Expand Down
24 changes: 12 additions & 12 deletions src/modules/Transition/Transition.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,37 @@ export interface StrictTransitionProps {
* Callback on each transition that changes visibility to shown.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {TRANSITION_STATUSES} status - Transition status.
*/
onComplete?: (nothing: null, data: TransitionEventData) => void
onComplete?: (nothing: null, props: TransitionProps, status: TRANSITION_STATUSES) => void

/**
* Callback on each transition that changes visibility to hidden.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {TRANSITION_STATUSES} status - Transition status.
*/
onHide?: (nothing: null, data: TransitionEventData) => void
onHide?: (nothing: null, props: TransitionProps, status: TRANSITION_STATUSES) => void

/**
* Callback on each transition that changes visibility to shown.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {TRANSITION_STATUSES} status - Transition status.
*/
onShow?: (nothing: null, data: TransitionEventData) => void
onShow?: (nothing: null, props: TransitionProps, status: TRANSITION_STATUSES) => void

/**
* Callback on animation start.
*
* @param {null}
* @param {object} data - All props with status.
* @param {object} props - All props.
* @param {TRANSITION_STATUSES} status - Transition status.
*/
onStart?: (nothing: null, data: TransitionEventData) => void
onStart?: (nothing: null, props: TransitionProps, status: TRANSITION_STATUSES) => void

/** React's key of the element. */
reactKey?: string
Expand All @@ -70,10 +74,6 @@ export interface StrictTransitionProps {
unmountOnHide?: boolean
}

export interface TransitionEventData extends TransitionProps {
status: TRANSITION_STATUSES
}

export interface TransitionPropDuration {
hide: number
show: number
Expand Down
6 changes: 3 additions & 3 deletions src/modules/Transition/Transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ export default class Transition extends React.Component {
}

if (!prevState.animating && this.state.animating) {
_.invoke(this.props, 'onStart', null, { ...this.props, status: this.state.status })
_.invoke(this.props, 'onStart', null, this.props, this.state.status)
}

if (prevState.animating && !this.state.animating) {
const callback = this.state.status === TRANSITION_STATUS_ENTERED ? 'onShow' : 'onHide'

_.invoke(this.props, 'onComplete', null, { ...this.props, status: this.state.status })
_.invoke(this.props, callback, null, { ...this.props, status: this.state.status })
_.invoke(this.props, 'onComplete', null, this.props, this.state.status)
_.invoke(this.props, callback, null, this.props, this.state.status)
}
}

Expand Down
25 changes: 15 additions & 10 deletions test/specs/addons/TransitionablePortal/TransitionablePortal-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('TransitionablePortal', () => {
})

describe('onClose', () => {
it('is called with (null, data) on a click outside', (done) => {
it('is called on a click outside', (done) => {
const onClose = sandbox.spy()
const wrapper = mount(
<TransitionablePortal
Expand All @@ -41,7 +41,7 @@ describe('TransitionablePortal', () => {

assertWithTimeout(() => {
onClose.should.have.been.calledOnce()
onClose.should.have.been.calledWithMatch(null, { portalOpen: false })
onClose.should.have.been.calledWithMatch(null, {}, { portalOpen: false })

wrapper.unmount()
}, done)
Expand All @@ -60,7 +60,7 @@ describe('TransitionablePortal', () => {
})

describe('onHide', () => {
it('is called with (null, data) when exiting transition finished', (done) => {
it('is called when exiting transition finished', (done) => {
const onHide = sandbox.spy()
const wrapper = mount(
<TransitionablePortal
Expand All @@ -75,27 +75,32 @@ describe('TransitionablePortal', () => {
wrapper.setProps({ open: false })
assertWithTimeout(() => {
onHide.should.have.been.calledOnce()
onHide.should.have.been.calledWithMatch(null, {
...quickTransition,
portalOpen: false,
transitionVisible: false,
})
onHide.should.have.been.calledWithMatch(
null,
{
...quickTransition,
},
{
portalOpen: false,
transitionVisible: false,
},
)

wrapper.unmount()
}, done)
})
})

describe('onOpen', () => {
it('is called with (null, data) when opens', () => {
it('is called when opens', () => {
const onOpen = sandbox.spy()
const wrapper = mount(
<TransitionablePortal {...requiredProps} onOpen={onOpen} trigger={<button />} />,
)

wrapper.find('button').simulate('click')
onOpen.should.have.been.calledOnce()
onOpen.should.have.been.calledWithMatch(null, { portalOpen: true })
onOpen.should.have.been.calledWithMatch(null, {}, { portalOpen: true })
})

it('renders contents', () => {
Expand Down
52 changes: 32 additions & 20 deletions test/specs/modules/Transition/Transition-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,16 +396,19 @@ describe('Transition', () => {
})

describe('onComplete', () => {
it('is called with (null, props) when transition completed', (done) => {
it('is called when transition completes', (done) => {
const onComplete = sandbox.spy()
const handleComplete = (...args) => {
onComplete(...args)

onComplete.should.have.been.calledOnce()
onComplete.should.have.been.calledWithMatch(null, {
duration: 0,
status: TRANSITION_STATUS_ENTERED,
})
onComplete.should.have.been.calledWithMatch(
null,
{
duration: 0,
},
TRANSITION_STATUS_ENTERED,
)

done()
}
Expand Down Expand Up @@ -440,16 +443,19 @@ describe('Transition', () => {
})

describe('onHide', () => {
it('is called with (null, props) when hidden', (done) => {
it('is called when hidden', (done) => {
const onHide = sandbox.spy()
const handleHide = (...args) => {
onHide(...args)

onHide.should.have.been.calledOnce()
onHide.should.have.been.calledWithMatch(null, {
duration: 0,
status: TRANSITION_STATUS_EXITED,
})
onHide.should.have.been.calledWithMatch(
null,
{
duration: 0,
},
TRANSITION_STATUS_EXITED,
)

done()
}
Expand Down Expand Up @@ -509,16 +515,19 @@ describe('Transition', () => {
})

describe('onShow', () => {
it('is called with (null, props) when shown', (done) => {
it('is called when shown', (done) => {
const onShow = sandbox.spy()
const handleShow = (...args) => {
onShow(...args)

onShow.should.have.been.calledOnce()
onShow.should.have.been.calledWithMatch(null, {
duration: 0,
status: TRANSITION_STATUS_ENTERED,
})
onShow.should.have.been.calledWithMatch(
null,
{
duration: 0,
},
TRANSITION_STATUS_ENTERED,
)

done()
}
Expand Down Expand Up @@ -552,16 +561,19 @@ describe('Transition', () => {
})

describe('onStart', () => {
it('is called with (null, props) when transition started', (done) => {
it('is called when transition started', (done) => {
const onStart = sandbox.spy()
const handleStart = (...args) => {
onStart(...args)

onStart.should.have.been.calledOnce()
onStart.should.have.been.calledWithMatch(null, {
duration: 0,
status: TRANSITION_STATUS_ENTERING,
})
onStart.should.have.been.calledWithMatch(
null,
{
duration: 0,
},
TRANSITION_STATUS_ENTERING,
)

done()
}
Expand Down

0 comments on commit c2d905b

Please sign in to comment.