import type {ReactNode} from 'react'; import {Children, Fragment} from 'react'; import styled from '@emotion/styled'; import SideBySide from 'sentry/components/stories/sideBySide'; import {space} from 'sentry/styles/space'; import {StoryTypes} from 'sentry/views/stories/storyTypes'; type StoryRenderFunction = () => ReactNode | ReactNode[]; type StoryContext = (storyName: string, story: StoryRenderFunction) => void; type SetupFunction = ( story: StoryContext, apiReference: (documentation: TypeLoader.ComponentDocWithFilename | undefined) => void ) => void; export default function storyBook( bookContext: string | React.ComponentType, setup: SetupFunction ): StoryRenderFunction { const stories: Array<{ name: string; render: StoryRenderFunction; }> = []; const APIDocumentation: TypeLoader.ComponentDocWithFilename[] = []; const storyFn: StoryContext = (name: string, render: StoryRenderFunction) => { stories.push({name, render}); }; const apiReferenceFn: ( documentation: TypeLoader.ComponentDocWithFilename | undefined ) => void = (documentation: TypeLoader.ComponentDocWithFilename | undefined) => { if (documentation) { APIDocumentation.push(documentation); } }; setup(storyFn, apiReferenceFn); return function RenderStory() { return ( {stories.map(({name, render}, i) => ( ))} {APIDocumentation.map((documentation, i) => ( ))} ); }; } function Story(props: {name: string; render: StoryRenderFunction}) { const children = props.render(); const isOneChild = Children.count(children) === 1; return ( {props.name} {isOneChild ? children : {children}} ); } function BookTitle(props: {bookContext: string | React.ComponentType}) { const {bookContext} = props; if (typeof bookContext === 'string') { return {bookContext}; } return ( {`<${bookContext.displayName ?? bookContext.name ?? bookContext.constructor.name}/>`} ); } const StorySection = styled('section')` margin-top: ${space(4)}; & > p { margin: ${space(3)} 0; } `; export const StoryTitle = styled('h3')` border-bottom: 1px solid ${p => p.theme.border}; scroll-margin-top: ${space(2)}; `;