diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-01-03 16:37:20 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-01-24 16:54:33 +0100 |
| commit | 28017307e83ebfda4768c8a6476be7f0c31933e8 (patch) | |
| tree | 9fc62af3116d069861604abade598f4af3c932fd /gui/src | |
| parent | 33b9e2ee55587638b52c6f319f20b1efe0b8522e (diff) | |
| download | mullvadvpn-28017307e83ebfda4768c8a6476be7f0c31933e8.tar.xz mullvadvpn-28017307e83ebfda4768c8a6476be7f0c31933e8.zip | |
Force refow to make transition work
Transitions weren't executing unless a reflow was triggered. Adding a
`offsetHeight` solved this. I've also added comments to TransitionContainer.
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/components/TransitionContainer.tsx | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 92aec7828e..4dc354d924 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -92,11 +92,14 @@ export default class TransitionContainer extends React.Component<IProps, IState> const candidate = props.children; if (candidate && state.currentItem) { - // synchronize updates to the last added child. + // Synchronize updates to the last added child. Although the queue doesn't change, the child + // itself might need to change. That's why the queue-/next item is replaced by it again after + // calling `makeItem`. const itemQueueCount = state.itemQueue.length; const lastItemInQueue = itemQueueCount > 0 ? state.itemQueue[itemQueueCount - 1] : undefined; if (lastItemInQueue && lastItemInQueue.view.props.viewId === candidate.props.viewId) { + // Child is last item in queue. No change to the queue needed. return { itemQueue: [...state.itemQueue.slice(0, -1), TransitionContainer.makeItem(props)], }; @@ -105,18 +108,21 @@ export default class TransitionContainer extends React.Component<IProps, IState> state.nextItem && state.nextItem.view.props.viewId === candidate.props.viewId ) { + // Child is next item, no change to the queue needed. return { nextItem: TransitionContainer.makeItem(props) }; } else if ( itemQueueCount === 0 && !state.nextItem && state.currentItem.view.props.viewId === candidate.props.viewId ) { + // Child is current item and there's no new child, no change to the queue needed. return { currentItem: TransitionContainer.makeItem(props) }; } else { - // add new item + // Child is a new item and is added to the queue. return { itemQueue: [...state.itemQueue, TransitionContainer.makeItem(props)] }; } } else if (candidate && !state.currentItem) { + // Child is set as current item if there's no item already. return { currentItem: TransitionContainer.makeItem(props) }; } else { return null; @@ -130,6 +136,11 @@ export default class TransitionContainer extends React.Component<IProps, IState> this.state.nextItemStyle && this.state.nextItemTransition ) { + // Force browser reflow before starting transition. Without this animations won't run since + // the next view content hasn't been painted yet. It will just appear without a transition. + void this.nextContentRef.current?.offsetHeight; + + // Start transition this.setState((state) => ({ currentItemStyle: Object.assign({}, state.currentItemStyle, state.currentItemTransition), nextItemStyle: Object.assign({}, state.nextItemStyle, state.nextItemTransition), |
