Skip to content

Commit

Permalink
Add delay to empty state to prevent flickering
Browse files Browse the repository at this point in the history
  • Loading branch information
cdedreuille committed Aug 2, 2023
1 parent 8a5ce35 commit b22fd14
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 48 deletions.
12 changes: 5 additions & 7 deletions code/addons/controls/src/ControlsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import type { FC } from 'react';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import {
useArgs,
useGlobals,
useArgTypes,
useParameter,
useStorybookState,
useChannel,
} from '@storybook/manager-api';
import { STORY_PREPARED } from '@storybook/core-events';
import { PureArgsTable as ArgsTable, type PresetColor, type SortType } from '@storybook/blocks';

import type { ArgTypes } from '@storybook/types';
Expand All @@ -29,13 +27,13 @@ export const ControlsPanel: FC = () => {
const [globals] = useGlobals();
const rows = useArgTypes();
const { expanded, sort, presetColors } = useParameter<ControlsParameters>(PARAM_KEY, {});
const { path } = useStorybookState();
const { path, previewInitialized } = useStorybookState();

// If the story is prepared, then show the args table
// and reset the loading states
useChannel({
[STORY_PREPARED]: () => setIsLoading(false),
});
useEffect(() => {
if (previewInitialized) setIsLoading(false);
}, [previewInitialized]);

const hasControls = Object.values(rows).some((arg) => arg?.control);

Expand Down
11 changes: 4 additions & 7 deletions code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -343,13 +343,10 @@ export const ArgsTable: FC<ArgsTableProps> = (props) => {
);

// If there are no controls, show the empty state
if (
groups.ungrouped.length === 0 &&
Object.entries(groups.sections).length === 0 &&
Object.entries(groups.ungroupedSubsections).length === 0
) {
return <Empty />;
}
const hasNoUngrouped = groups.ungrouped.length === 0;
const hasNoSections = Object.entries(groups.sections).length === 0;
const hasNoUngroupedSubsections = Object.entries(groups.ungroupedSubsections).length === 0;
if (hasNoUngrouped && hasNoSections && hasNoUngroupedSubsections) return <Empty />;

let colSpan = 1;
if (updateArgs) colSpan += 1;
Expand Down
85 changes: 51 additions & 34 deletions code/ui/blocks/src/components/ArgsTable/Empty.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FC } from 'react';
import React from 'react';
import React, { useEffect, useState } from 'react';
import { styled } from '@storybook/theming';
import { Icon, Link } from '@storybook/components/experimental';

Expand Down Expand Up @@ -54,36 +54,53 @@ const VideoIcon = styled.div(({ theme }) => ({
justifyContent: 'center',
}));

export const Empty: FC = () => (
<Wrapper>
<Content>
<Title>Interactive story playground</Title>
<Description>
Controls give you an easy to use interface to test your components. Set your story args and
you&apos;ll see controls appearing here automatically.
</Description>
</Content>
<Links>
<Link
href="https://youtu.be/0gOfS6K0x0E"
target="_blank"
icon={
<VideoIcon>
<Icon.Play size={10} />
</VideoIcon>
}
withArrow
>
Watch 5m video
</Link>
<Divider />
<Link
href="https://storybook.js.org/docs/react/essentials/controls"
target="_blank"
withArrow
>
Read docs
</Link>
</Links>
</Wrapper>
);
export const Empty: FC = () => {
const [isLoading, setIsLoading] = useState(true);

// We are adding a small delay to avoid flickering when the story is loading.
// It takes a bit of time for the controls to appear, so we don't want
// to show the empty state for a split second.
useEffect(() => {
const load = setTimeout(() => {
setIsLoading(false);
}, 100);

return () => clearTimeout(load);
}, []);

if (isLoading) return null;

return (
<Wrapper>
<Content>
<Title>Interactive story playground</Title>
<Description>
Controls give you an easy to use interface to test your components. Set your story args
and you&apos;ll see controls appearing here automatically.
</Description>
</Content>
<Links>
<Link
href="https://youtu.be/0gOfS6K0x0E"
target="_blank"
icon={
<VideoIcon>
<Icon.Play size={10} />
</VideoIcon>
}
withArrow
>
Watch 5m video
</Link>
<Divider />
<Link
href="https://storybook.js.org/docs/react/essentials/controls"
target="_blank"
withArrow
>
Read docs
</Link>
</Links>
</Wrapper>
);
};

0 comments on commit b22fd14

Please sign in to comment.