Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor logic to prevent breaking changes in useToastState #6270

Merged
merged 14 commits into from Apr 30, 2024

Conversation

LFDanLu
Copy link
Member

@LFDanLu LFDanLu commented Apr 26, 2024

Closes #4244

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

Test toast stories. Behavior should still be that new toasts are inserted at the bottom of the stack. Toast exit animations should still work

🧢 Your Project:

RSP

@rspbot
Copy link

rspbot commented Apr 26, 2024

snowystinger
snowystinger previously approved these changes Apr 26, 2024
@rspbot
Copy link

rspbot commented Apr 26, 2024

@ktabors
Copy link
Member

ktabors commented Apr 26, 2024

Never mind, I fixed it. Sorry I'm breaking it. I wrote some tests that found one bug that I fixed and a second bug I'll work on tomorrow.

The first bug: The close() code assumed all Toasts being closed are visible. When programmatically removing an item that isn't visible the this.visibleToasts.find() returned undefined and we can't set a prop on that.

Details about the second unfixed bug:

  • There are two Toasts and it removes the first Toast so only the third Toast is left.
  • this.visibleItems is empty while this.queue has one item, the third Toast.

@rspbot
Copy link

rspbot commented Apr 26, 2024

@LFDanLu LFDanLu changed the title Refactor logic to prevent breaking changes in useToastState (WIP) Refactor logic to prevent breaking changes in useToastState Apr 26, 2024
@rspbot
Copy link

rspbot commented Apr 26, 2024

@LFDanLu LFDanLu changed the title (WIP) Refactor logic to prevent breaking changes in useToastState Refactor logic to prevent breaking changes in useToastState Apr 26, 2024
Comment on lines 168 to 171
remove(key: string) {
let index = this.queue.findIndex(t => t.key === key);
this.visibleToasts = this.visibleToasts.filter(t => t.key !== key);
this.updateVisibleToasts(index);
this.queue = this.queue.filter(t => t.key !== key);
this.updateVisibleToasts('remove');
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure about whether or not to have this.queue = this.queue.filter(t => t.key !== key); in here or not. The code works without it assuming the user calls close and then remove and would allow us to remove the key input argument. However, if the user calls just remove then we need the aforementioned line to make sure the queue is properly updated and thus visibleToasts gets updated as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically it does work, the remove() is just doing some cleanup to the dom by removing the object from the dom.

The close button not closing until you move the mouse was related to close() not remove(), right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably good to keep it to be safe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the extra update to the queue in the remove call is to ensure the queue as our source of truth is still up to date in case the user only calls remove.

The close button not closing until you move the mouse was related to close() not remove(), right?

yeah it previous happened to use since we weren't always making an update to visibleToast that would cause a state change

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got rid of the extra update to queue in the remove call since this was prematurely removing toasts that get pushed out of visibility by higher priority toasts. In RSP the flow that happens when a toast is pushed out of visibility is as follows:
new toast add animates in -> toast that is no longer visible gets close called by its onAnimationEnd

@rspbot
Copy link

rspbot commented Apr 26, 2024

@@ -159,30 +155,27 @@ export class ToastQueue<T> {
if (index >= 0) {
this.queue[index].onClose?.();
this.queue.splice(index, 1);
let closedToast = this.visibleToasts.find(t => t.key === key);
if (closedToast) {
closedToast.animation = 'exiting';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if there will be problems due to mutating the toast, which is passed into props of a component...

this.visibleToasts = toasts;
if (action === 'close' && this.hasExitAnimation) {
// Cause a rerender to happen for exit animation
this.visibleToasts = this.visibleToasts.map(t => t);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One change in logic here is that previously, if the number of visible toasts exceeded the maxVisibleToasts setting, the toasts that got pushed off the end would animate out. Now they won't. Only toasts that are explicitly closed by clicking the X button will animate. Is that expected?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh didn't realize that was a case here. Will revisit how we apply the .animation then and see if we can move it back into here somehow

…he visibleToast list due to a higher priority toast being added
@rspbot
Copy link

rspbot commented Apr 29, 2024

… from the queue

this mimics the exitAnimation call to close that RSP toast does
@rspbot
Copy link

rspbot commented Apr 29, 2024

@LFDanLu
Copy link
Member Author

LFDanLu commented Apr 29, 2024

You can test the behavior of the toasts with priority in the toast story here on this branch as well: #6290

@rspbot
Copy link

rspbot commented Apr 29, 2024

ktabors
ktabors previously approved these changes Apr 30, 2024
} else {
this.queue.unshift(toast);
}
this.queue.splice(low, 0, toast);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a breaking change or was this.queue.unshift(toast); a bug we hadn't found?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reverts the logic to what is currently released

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I just remembered that and was coming back to delete it, but you responded.

snowystinger
snowystinger previously approved these changes Apr 30, 2024
@rspbot
Copy link

rspbot commented Apr 30, 2024

@rspbot
Copy link

rspbot commented Apr 30, 2024

devongovett
devongovett previously approved these changes Apr 30, 2024
@LFDanLu LFDanLu dismissed stale reviews from devongovett, snowystinger, and ktabors via 735fcab April 30, 2024 17:09
@rspbot
Copy link

rspbot commented Apr 30, 2024

Copy link
Member

@devongovett devongovett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok for this release but we are planning to refactor this more later

@rspbot
Copy link

rspbot commented Apr 30, 2024

@rspbot
Copy link

rspbot commented Apr 30, 2024

## API Changes

unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any', access: 'private' }
unknown top level export { type: 'any', access: 'private' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'identifier', name: 'Column' }
unknown top level export { type: 'identifier', name: 'Column' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }

@LFDanLu LFDanLu merged commit 1bd538f into main Apr 30, 2024
25 checks passed
@LFDanLu LFDanLu deleted the toast_state_take_2 branch April 30, 2024 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Toast] exiting attribute should apply to the target on close
5 participants