diff --git a/static/app/components/core/button/index.mdx b/static/app/components/core/button/index.mdx
index e587d128f4e697..1c7651ef2fe06f 100644
--- a/static/app/components/core/button/index.mdx
+++ b/static/app/components/core/button/index.mdx
@@ -11,12 +11,6 @@ resources:
WCAG 2.4.7: https://www.w3.org/TR/WCAG22/#focus-visible
WCAG 2.5.8: https://www.w3.org/TR/WCAG22/#target-size-minimum
WAI-ARIA Button Practices: https://www.w3.org/WAI/ARIA/apg/patterns/button/
-next:
- link: '/stories/?name=app%2Fcomponents%2Fcore%2Fbutton%2FbuttonBar.stories.tsx'
- label: ButtonBar
-prev:
- link: '?name=app%2Fcomponents%2Fcore%2Fbadge%2Ftag.stories.tsx'
- label: Tag
---
import {Button} from 'sentry/components/core/button';
diff --git a/static/app/stories/view/storyFooter.tsx b/static/app/stories/view/storyFooter.tsx
index a4af4c6b9f32c1..796c7836af2ba6 100644
--- a/static/app/stories/view/storyFooter.tsx
+++ b/static/app/stories/view/storyFooter.tsx
@@ -1,35 +1,80 @@
import styled from '@emotion/styled';
+import qs from 'query-string';
import {LinkButton} from 'sentry/components/core/button/linkButton';
import {Flex} from 'sentry/components/core/layout';
import {IconArrow} from 'sentry/icons';
-import {isMDXStory} from 'sentry/stories/view/useStoriesLoader';
+import {useStoryBookFilesByCategory} from 'sentry/stories/view/storySidebar';
+import type {StoryTreeNode} from 'sentry/stories/view/storyTree';
+import type {StoryDescriptor} from 'sentry/stories/view/useStoriesLoader';
import {useStory} from 'sentry/stories/view/useStory';
import {space} from 'sentry/styles/space';
+import {useLocation} from 'sentry/utils/useLocation';
export function StoryFooter() {
+ const location = useLocation();
+
const {story} = useStory();
- if (!isMDXStory(story)) return null;
- const {prev, next} = story.exports.frontmatter ?? {};
+ const categories = useStoryBookFilesByCategory();
+ const pagination = findPreviousAndNextStory(story, categories);
+
+ const prevLocationDescriptor = qs.stringify({
+ ...location.query,
+ name: pagination?.prev?.story.filesystemPath,
+ });
+ const nextLocationDescriptor = qs.stringify({
+ ...location.query,
+ name: pagination?.next?.story.filesystemPath,
+ });
return (
- {typeof prev === 'object' && 'link' in prev && (
- }>
+ {pagination?.prev && (
+ }
+ >
Previous
- {prev.label}
+ {pagination.prev.story.label}
)}
- {typeof next === 'object' && 'link' in next && (
- }>
+ {pagination?.next && (
+ }
+ >
Next
- {next.label}
+ {pagination.next.story.label}
)}
);
}
+function findPreviousAndNextStory(
+ story: StoryDescriptor,
+ categories: ReturnType
+): {
+ next: {category: string; story: StoryTreeNode} | undefined;
+ prev: {category: string; story: StoryTreeNode} | undefined;
+} | null {
+ const stories = Object.entries(categories).flatMap(([key, category]) =>
+ category.map(s => ({category: key, story: s}))
+ );
+
+ const currentIndex = stories.findIndex(s => s.story.filesystemPath === story.filename);
+
+ if (currentIndex === -1) {
+ return null;
+ }
+
+ return {
+ prev: stories[currentIndex - 1] ?? undefined,
+ next: stories[currentIndex + 1] ?? undefined,
+ };
+}
+
const Card = styled(LinkButton)`
display: flex;
flex-direction: column;
diff --git a/static/app/stories/view/storySidebar.tsx b/static/app/stories/view/storySidebar.tsx
index b1349a02a64399..a2d3f4d236ed94 100644
--- a/static/app/stories/view/storySidebar.tsx
+++ b/static/app/stories/view/storySidebar.tsx
@@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import {space} from 'sentry/styles/space';
+import type {StoryTreeNode} from './storyTree';
import {StoryTree, useStoryTree} from './storyTree';
import {useStoryBookFiles} from './useStoriesLoader';
@@ -29,9 +30,13 @@ export function StorySidebar() {
);
}
-export function useStoryBookFilesByCategory() {
+export function useStoryBookFilesByCategory(): Record<
+ 'foundations' | 'core' | 'shared',
+ StoryTreeNode[]
+> {
const files = useStoryBookFiles();
const filesByOwner = useMemo(() => {
+ // The order of keys here is important and used by the pagination in storyFooter
const map: Record<'foundations' | 'core' | 'shared', string[]> = {
foundations: [],
core: [],
diff --git a/static/app/stories/view/useStoriesLoader.tsx b/static/app/stories/view/useStoriesLoader.tsx
index 1af8698fe43c78..79ad179f9d84e4 100644
--- a/static/app/stories/view/useStoriesLoader.tsx
+++ b/static/app/stories/view/useStoriesLoader.tsx
@@ -12,16 +12,12 @@ export interface StoryResources {
js?: string;
}
-type FrontmatterPagination = boolean | {label: string; link: string};
-
interface MDXStoryDescriptor {
exports: {
default: React.ComponentType | any;
frontmatter?: {
description: string;
title: string;
- next?: FrontmatterPagination;
- prev?: FrontmatterPagination;
resources?: StoryResources;
source?: string;
types?: string;