diff --git a/code/core/src/manager/components/sidebar/Explorer.stories.tsx b/code/core/src/manager/components/sidebar/Explorer.stories.tsx index 67f4ba63b948..96151717f30e 100644 --- a/code/core/src/manager/components/sidebar/Explorer.stories.tsx +++ b/code/core/src/manager/components/sidebar/Explorer.stories.tsx @@ -82,6 +82,7 @@ export const Simple = () => ( }} isLoading={false} isBrowsing + hasEntries={true} /> ); @@ -94,5 +95,6 @@ export const WithRefs = () => ( }} isLoading={false} isBrowsing + hasEntries={true} /> ); diff --git a/code/core/src/manager/components/sidebar/Explorer.tsx b/code/core/src/manager/components/sidebar/Explorer.tsx index 4423fafb9f4d..bd312377bfde 100644 --- a/code/core/src/manager/components/sidebar/Explorer.tsx +++ b/code/core/src/manager/components/sidebar/Explorer.tsx @@ -9,11 +9,13 @@ import { useHighlighted } from './useHighlighted'; export interface ExplorerProps { isLoading: boolean; isBrowsing: boolean; + hasEntries: boolean; dataset: CombinedDataset; selected: Selection; } export const Explorer: FC = React.memo(function Explorer({ + hasEntries, isLoading, isBrowsing, dataset, @@ -43,6 +45,7 @@ export const Explorer: FC = React.memo(function Explorer({ key={refId} isLoading={isLoading} isBrowsing={isBrowsing} + hasEntries={hasEntries} selectedStoryId={selected?.refId === ref.id ? selected.storyId : null} highlightedRef={highlightedRef} setHighlighted={setHighlighted} diff --git a/code/core/src/manager/components/sidebar/NoResults.tsx b/code/core/src/manager/components/sidebar/NoResults.tsx new file mode 100644 index 000000000000..26c128aa4e6a --- /dev/null +++ b/code/core/src/manager/components/sidebar/NoResults.tsx @@ -0,0 +1,17 @@ +import { styled } from 'storybook/theming'; + +export const NoResults = styled.div(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + textAlign: 'center', + textWrap: 'balance', + gap: 4, + padding: '20px 0', + lineHeight: `18px`, + fontSize: `${theme.typography.size.s2}px`, + color: theme.color.defaultText, + small: { + color: theme.textMutedColor, + fontSize: `${theme.typography.size.s1}px`, + }, +})); diff --git a/code/core/src/manager/components/sidebar/RefBlocks.tsx b/code/core/src/manager/components/sidebar/RefBlocks.tsx index 96a8eb4e468e..fd2c54a2f8b8 100644 --- a/code/core/src/manager/components/sidebar/RefBlocks.tsx +++ b/code/core/src/manager/components/sidebar/RefBlocks.tsx @@ -10,6 +10,7 @@ import { ChevronDownIcon, LockIcon, SyncIcon } from '@storybook/icons'; import { styled } from 'storybook/theming'; import { Contained, Loader } from './Loader'; +import { NoResults } from './NoResults'; const { window: globalWindow } = global; @@ -135,29 +136,48 @@ const WideSpaced = styled(Spaced)({ flex: 1, }); -export const EmptyBlock: FC = ({ isMain }) => ( +export const EmptyBlock = ({ isMain, hasEntries }: { isMain: boolean; hasEntries: boolean }) => ( - - {isMain ? ( - <> - Oh no! Your Storybook is empty. Possible reasons why: -
    -
  • - The glob specified in main.js isn't correct. -
  • -
  • No stories are defined in your story files.
  • -
  • You're using filter-functions, and all stories are filtered away.
  • -
{' '} - - ) : ( - <> - This composed storybook is empty, maybe you're using filter-functions, and all stories - are filtered away. - - )} -
+ {hasEntries ? ( + + No stories found + Your selected filters did not match any stories. + + ) : isMain ? ( + + Oh no! Your Storybook is empty. This can happen when: +
    +
  • + Your{' '} + + stories glob configuration + {' '} + does not match any files.{' '} +
  • +
  • + You have{' '} + + no stories defined + {' '} + in your story files.{' '} +
  • +
+
+ ) : ( + + This composed Storybook is empty. Perhaps no stories match your selected filters. + + )}
diff --git a/code/core/src/manager/components/sidebar/Refs.stories.tsx b/code/core/src/manager/components/sidebar/Refs.stories.tsx index d183e41896b8..19598ee80aa5 100644 --- a/code/core/src/manager/components/sidebar/Refs.stories.tsx +++ b/code/core/src/manager/components/sidebar/Refs.stories.tsx @@ -172,6 +172,18 @@ const refs: Record = { export const Optimized = () => ( {}} + /> +); +export const NoEntries = () => ( + ( export const IsEmpty = () => ( ( export const StartInjectedUnknown = () => ( ( export const StartInjectedLoading = () => ( ( export const StartInjectedReady = () => ( ( export const Versions = () => ( ( export const VersionsMissingCurrent = () => ( ( export const Errored = () => ( ( export const Auth = () => ( ( export const Long = () => ( ( export const WithSourceCode = () => ( ; setHighlighted: (highlight: Highlight) => void; @@ -82,6 +83,7 @@ export const Ref: FC = React.memo(function Ref(props) { title = refId, isLoading: isLoadingMain, isBrowsing, + hasEntries, selectedStoryId, highlightedRef, setHighlighted, @@ -146,7 +148,7 @@ export const Ref: FC = React.memo(function Ref(props) { {/* @ts-expect-error (non strict) */} {state === 'error' && } {state === 'loading' && } - {state === 'empty' && } + {state === 'empty' && } {state === 'ready' && ( ({ - marginTop: 20, - textAlign: 'center', - fontSize: `${theme.typography.size.s2}px`, - lineHeight: `18px`, - color: theme.color.defaultText, - small: { - color: theme.textMutedColor, - fontSize: `${theme.typography.size.s1}px`, - }, -})); - const Mark = styled.mark(({ theme }) => ({ background: 'transparent', color: theme.color.secondary, @@ -312,7 +301,6 @@ export const SearchResults: FC<{
  • No components found -
    Find components by name or path.
  • diff --git a/code/core/src/manager/components/sidebar/Sidebar.stories.tsx b/code/core/src/manager/components/sidebar/Sidebar.stories.tsx index 8757ce4c2140..0644d84d5cad 100644 --- a/code/core/src/manager/components/sidebar/Sidebar.stories.tsx +++ b/code/core/src/manager/components/sidebar/Sidebar.stories.tsx @@ -162,6 +162,16 @@ export const Empty: Story = { }, }; +export const EmptyIndex: Story = { + args: { + index: {}, + indexJson: { + entries: {}, + v: 6, + }, + }, +}; + export const IndexError: Story = { args: { indexError, diff --git a/code/core/src/manager/components/sidebar/Sidebar.tsx b/code/core/src/manager/components/sidebar/Sidebar.tsx index 653e7762e05c..3306ae21c817 100644 --- a/code/core/src/manager/components/sidebar/Sidebar.tsx +++ b/code/core/src/manager/components/sidebar/Sidebar.tsx @@ -148,6 +148,7 @@ export const Sidebar = React.memo(function Sidebar({ const selected: Selection = useMemo(() => storyId && { storyId, refId }, [storyId, refId]); const dataset = useCombination(index, indexError, previewInitialized, allStatuses, refs); const isLoading = !index && !indexError; + const hasEntries = Object.keys(indexJson?.entries ?? {}).length > 0; const lastViewedProps = useLastViewed(selected); const { isMobile } = useLayout(); const api = useStorybookApi(); @@ -230,6 +231,7 @@ export const Sidebar = React.memo(function Sidebar({ selected={selected} isLoading={isLoading} isBrowsing={isBrowsing} + hasEntries={hasEntries} />