Skip to content

Commit

Permalink
Merge pull request #17753 from storybookjs/tom/sb-26-wait-100ms-befor…
Browse files Browse the repository at this point in the history
…e-showing-preparing

UI: Wait 100ms before showing spinner and fix story overlaying it
  • Loading branch information
shilman authored Mar 28, 2022
2 parents cefdaa0 + 0266f52 commit 68a73b8
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 5 deletions.
14 changes: 14 additions & 0 deletions examples/official-storybook/stories/core/loaders.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,17 @@ export const Story = (args, { loaded }) => (
<div>Loaded Value is {JSON.stringify(loaded, null, 2)}</div>
);
Story.loaders = [async () => ({ storyValue: 3 })];

export const ZIndex = (args, { loaded }) => (
<div
style={{
position: 'relative',
zIndex: 1000,
width: '100px',
height: '100px',
background: 'coral',
}}
>
This story has a very high <code>z-index</code>
</div>
);
5 changes: 5 additions & 0 deletions examples/official-storybook/stories/core/rendering.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,8 @@ ArgsChange.decorators = [
return <StoryFn />;
},
];

// Ensure that this story gets focus when browsed to
// see https://github.com/storybookjs/storybook/issues/16847
// eslint-disable-next-line jsx-a11y/no-autofocus
export const AutoFocus = () => <input autoFocus />;
14 changes: 14 additions & 0 deletions lib/core-common/templates/base-preview-head.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
<base target="_parent" />

<style>
/* While we aren't showing the main block yet, but still preparing, we want everything the user
has rendered, which may or may not be in #root, to be display none */
.sb-show-preparing-story:not(.sb-show-main) > :not(.sb-preparing-story) {
display: none;
}

.sb-show-preparing-docs:not(.sb-show-main) > :not(.sb-preparing-docs) {
display: none;
}

/* Hide our own blocks when we aren't supposed to be showing them */
:not(.sb-show-preparing-story) > .sb-preparing-story,
:not(.sb-show-preparing-docs) > .sb-preparing-docs,
:not(.sb-show-nopreview) > .sb-nopreview,
Expand Down Expand Up @@ -140,6 +151,9 @@
.sb-preparing-story,
.sb-preparing-docs {
background-color: white;
/* Maximum possible z-index. It would be better to use stacking contexts to ensure it's always
on top, but this isn't possible as it would require making CSS changes that could affect user code */
z-index: 2147483647;
}

.sb-loader {
Expand Down
8 changes: 6 additions & 2 deletions lib/preview-web/src/PreviewWeb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ export class PreviewWeb<TFramework extends AnyFramework> {

// Show a spinner while we load the next story
if (selection.viewMode === 'story') {
this.view.showPreparingStory();
this.view.showPreparingStory({ immediate: viewModeChanged });
} else {
this.view.showPreparingDocs();
}
Expand All @@ -454,7 +454,11 @@ export class PreviewWeb<TFramework extends AnyFramework> {
>(
this.channel,
this.storyStore,
this.renderToDOM,
(...args) => {
// At the start of renderToDOM we make the story visible (see note in WebView)
this.view.showStoryDuringRender();
return this.renderToDOM(...args);
},
this.mainStoryCallbacks(storyId),
storyId,
'story'
Expand Down
30 changes: 27 additions & 3 deletions lib/preview-web/src/WebView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Story } from '@storybook/store';

const { document } = global;

const PREPARING_DELAY = 100;

const layoutClassMap = {
centered: 'sb-main-centered',
fullscreen: 'sb-main-fullscreen',
Expand Down Expand Up @@ -39,6 +41,8 @@ export class WebView {

testing = false;

preparingTimeout: ReturnType<typeof setTimeout> = null;

constructor() {
// Special code for testing situations
const { __SPECIAL_TEST_PARAMETER__ } = qs.parse(document.location.search, {
Expand Down Expand Up @@ -111,6 +115,7 @@ export class WebView {
}

showMode(mode: Mode) {
clearTimeout(this.preparingTimeout);
Object.keys(Mode).forEach((otherMode) => {
if (otherMode === mode) {
document.body.classList.add(classes[otherMode]);
Expand Down Expand Up @@ -145,12 +150,22 @@ export class WebView {
this.docsRoot()?.setAttribute('hidden', 'true');
}

showPreparingStory() {
this.showMode(Mode.PREPARING_STORY);
showPreparingStory({ immediate = false } = {}) {
clearTimeout(this.preparingTimeout);

if (immediate) {
this.showMode(Mode.PREPARING_STORY);
} else {
this.preparingTimeout = setTimeout(
() => this.showMode(Mode.PREPARING_STORY),
PREPARING_DELAY
);
}
}

showPreparingDocs() {
this.showMode(Mode.PREPARING_DOCS);
clearTimeout(this.preparingTimeout);
this.preparingTimeout = setTimeout(() => this.showMode(Mode.PREPARING_DOCS), PREPARING_DELAY);
}

showMain() {
Expand All @@ -166,4 +181,13 @@ export class WebView {
this.docsRoot().setAttribute('hidden', 'true');
this.storyRoot().removeAttribute('hidden');
}

showStoryDuringRender() {
// When 'showStory' is called (at the start of rendering) we get rid of our display:none
// from all children of the root (but keep the preparing spinner visible). This may mean
// that very weird and high z-index stories are briefly visible.
// See https://github.com/storybookjs/storybook/issues/16847 and
// http://localhost:9011/?path=/story/core-rendering--auto-focus (official SB)
document.body.classList.add(classes.MAIN);
}
}

0 comments on commit 68a73b8

Please sign in to comment.