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

fix!: CSS based loading spinner #1532

Merged
merged 20 commits into from
Sep 28, 2023

Conversation

bmingles
Copy link
Contributor

@bmingles bmingles commented Sep 20, 2023

  • Swapped our LoadingSpinner implementation with a simpler html / CSS only spinner
  • Fixes a layout shift after font load caused by font-size: $iris-panel-icon-font-size in .message-icon of LoadingOverlay
  • Fixes loading spinner backtracking due to multiple instances of spinners

Regression Tests Performed

  • LoadingOverlay - I added a synthetic wait to PluginUtils right after the manifest loading. Loading overlay is now seamless. No layout shift or backtracking

Verified the following look as they did before

Community

  • Styleguide indeterminate and progress spinners
  • Styleguide context menu spinners
  • Console "Running" spinner
  • AppMainContainer disconnection spinner
  • Command history tooltip elapsed spinner
  • Advanced filter spinner
  • Column statistics spinner
  • IrisGridCopyHandler slight adjustment such that spinner + text are centered
  • PartitionSelectorSearch spinner
  • Commit button in PendingDataBottomBar
  • Custom column builder "applying" spinner
  • Table CSV exporter spinner

Enterprise

  • Enterprise login spinner
  await new Promise(resolve => {
      setTimeout(resolve, 2000);
  });

fixes #1531

BREAKING CHANGE: Inline LoadingSpinner instances will need to be decorated with className="loading-spinner-vertical-align" for vertical alignment to work as before

.loading-spinner {
--primary-color: var(--dh-accent-color, #4c7dee);
/* stylelint-disable-next-line alpha-value-notation */
--secondary-color: rgba(240, 240, 240, 0.5);
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be based on a variable. A hardcoded value here would look terrible on a light theme for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any thoughts on what it should be tied to?

Copy link
Contributor

Choose a reason for hiding this comment

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

in theory a gray-XXX value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll tie it to a semantic color for now and refine it once I get into the color mapping

.message-icon {
font-size: $iris-panel-icon-font-size;
height: $iris-panel-icon-font-size;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I set height + line height explicitly to avoid a layout shift after font load. The previous height was 96px based on 1.5 line-height from body. Converting to flexbox with a gap of 20px seems to match the layout as before but without the layout shift

@bmingles bmingles mentioned this pull request Sep 25, 2023
13 tasks
Comment on lines 33 to 34
* @param animationName
* @param startTime
Copy link
Member

Choose a reason for hiding this comment

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

Params need descriptions. Also as it is now, you could make startTime default to 0 (since that's the only value you actually pass in).

Comment on lines +46 to +55
animations.forEach(a => {
// eslint-disable-next-line no-param-reassign
a.startTime = startTime;
});
}
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if I'm reading this incorrectly, but looking at the example on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Animation/startTime#examples
They're setting the new animation to be the same as the existing start time; here you're resetting all of the animations to the same startTime (which is always 0, since that's the only value you pass in). Wouldn't that mean that an existing animation would jump back when a new one is added? Whereas we should just be syncing the new animation to any existing loading spinner that's already shown.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My observation when I dug into this is that the startTime is usually null by default (also was not what I expected from the docs). My understanding is that it's kind of a static value that determines the basis of when animations are calculated. Setting explicitly to zero later if the animation is already based on zero shouldn't impact the existing animation.

Copy link
Member

Choose a reason for hiding this comment

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

Interesting. Can't say I fully understand it, but it does look like they're in sync and doesn't reset the existing animations, so cool.

@@ -594,7 +594,7 @@ class ContextMenu extends PureComponent<ContextMenuProps, ContextMenuState> {
if (pendingItems.length > 0) {
pendingElement = (
<div className="loading">
<LoadingSpinner />
<LoadingSpinner className="mimic-fa-layers-vertical-align" />
Copy link
Member

Choose a reason for hiding this comment

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

Not crazy about needing to provide a long class name in many of these cases... should we have a verticalAlign prop or something that maps to a class name instead? Or any other way to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking eventually we should use flex positioning for all of the cases and gradually get rid of the "hack" class. It's kind of a flag that this is styled in a deprecated way. That said, I'm not a big fan of it either, was just trying to not muck with too much of the existing layout. I'm fine to change this to a prop instead.

Copy link
Member

Choose a reason for hiding this comment

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

Or just a different class name; like we have loading-spinner-large, maybe loading-spinner-vertical-align

@bmingles bmingles force-pushed the 1531-loading-spinner-stutter branch from deef131 to 7898ba7 Compare September 25, 2023 21:42
@bmingles bmingles changed the title fix: CSS based loading spinner fix!: CSS based loading spinner Sep 26, 2023
@bmingles bmingles marked this pull request as ready for review September 26, 2023 15:54
mofojed
mofojed previously approved these changes Sep 27, 2023
Copy link
Member

@mofojed mofojed left a comment

Choose a reason for hiding this comment

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

Side note, I imagine we're going to move to Spectrum's ProgressCircle at some point for loading spinner: https://react-spectrum.adobe.com/react-spectrum/ProgressCircle.html
I wonder if that will cause this issue to come up again.

@mofojed
Copy link
Member

mofojed commented Sep 27, 2023

A lot of the tests will need to be updated to look for this new loading spinner... we should have a consistent way of determining that in the tests. data-testid is probably the easiest; accessibility roles like the aria-live don't really apply to the loading spinner itself, just to the element behind it... whatever you think may be best.

@bmingles
Copy link
Contributor Author

data-testid should be used the same way it was on the original spinner.

For aria roles, here's what Spectrum uses on their indeterminate spinner. I could see us adding those.

image

@codecov
Copy link

codecov bot commented Sep 27, 2023

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (49723ec) 46.41% compared to head (77480a8) 46.42%.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1532   +/-   ##
=======================================
  Coverage   46.41%   46.42%           
=======================================
  Files         564      564           
  Lines       35765    35775   +10     
  Branches     8946     8950    +4     
=======================================
+ Hits        16599    16607    +8     
- Misses      19116    19118    +2     
  Partials       50       50           
Flag Coverage Δ
unit 46.42% <78.57%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
packages/auth-plugins/src/LoginForm.tsx 91.66% <ø> (ø)
packages/code-studio/src/styleguide/Progress.tsx 66.66% <ø> (ø)
packages/code-studio/src/styleguide/Tooltips.tsx 71.42% <ø> (ø)
packages/components/src/LoadingSpinner.tsx 80.00% <100.00%> (-20.00%) ⬇️
...ges/components/src/context-actions/ContextMenu.tsx 39.03% <ø> (ø)
.../src/command-history/CommandHistoryItemTooltip.tsx 83.33% <100.00%> (ø)
...console-history/ConsoleHistoryResultInProgress.tsx 66.66% <ø> (ø)
packages/iris-grid/src/ColumnStatistics.tsx 3.33% <ø> (ø)
packages/iris-grid/src/IrisGridCopyHandler.tsx 83.33% <100.00%> (+0.10%) ⬆️
packages/iris-grid/src/PartitionSelectorSearch.tsx 69.75% <ø> (ø)
... and 5 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bmingles bmingles requested a review from mofojed September 27, 2023 15:11
@mofojed
Copy link
Member

mofojed commented Sep 27, 2023

Ah yea, using role="progressbar" makes sense, that would be better for tests to use than the data-testid. https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/progressbar_role
Not all tests were using the data-testid so those failing now can be updated to look for that role instead, and/or you could have a utility function for checking if there's a loading element.

@bmingles bmingles force-pushed the 1531-loading-spinner-stutter branch from aeeb5ce to 77480a8 Compare September 27, 2023 22:03
@bmingles
Copy link
Contributor Author

@mofojed all tests have been updated, and e2e are passing as well.

@bmingles bmingles merged commit f06fbb0 into deephaven:main Sep 28, 2023
@bmingles bmingles deleted the 1531-loading-spinner-stutter branch September 28, 2023 13:42
@github-actions github-actions bot locked and limited conversation to collaborators Sep 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DH-15686: Loading Spinner Stutter
3 participants