summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-01-03 16:37:20 +0100
committerOskar Nyberg <oskar@mullvad.net>2022-01-24 16:54:33 +0100
commit28017307e83ebfda4768c8a6476be7f0c31933e8 (patch)
tree9fc62af3116d069861604abade598f4af3c932fd /gui
parent33b9e2ee55587638b52c6f319f20b1efe0b8522e (diff)
downloadmullvadvpn-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')
-rw-r--r--gui/src/renderer/components/TransitionContainer.tsx15
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),