import { SectionType, StoryPageSection, TabSection, } from '../../typings/story-section'; import { StoryConfig } from '../../typings/story-config'; import { Example, Tabs, IncludedComponent } from '../../typings/story'; import React from 'react'; import { width } from '../../ui/Tabs/core/constants/tab-prop-types'; const example = (props: { source: string; loading?: boolean }) => { return { type: SectionType.Example, title: 'Demo', source: props.source, compact: true, hideCodeEditor: true, loading: props.loading, wide: true, }; }; const examples = ( examplesContent: Example[], examplesCode: Record, examplesConfig: Record, ) => { if (!examplesContent || !examplesContent.length) { return []; } return examplesContent .map((item, index) => ({ type: SectionType.Example, key: index, title: item.title, text: item.description, source: examplesCode[item.example], compact: true, wide: item.wide, figmaLink: item.figmaLink, examplesPreviewWrapper: examplesConfig?.examplesPreviewWrapper, })) .filter(example => example.source); }; const description = (props: { title?: string; description?: string; loading?: boolean; width?: string; }) => ({ type: SectionType.Description, text: props.description, title: props.title, loading: props.loading, width, }); const importExample = ( storyConfig: StoryConfig, props: { loading?: boolean }, ) => ({ title: 'Import', type: SectionType.ImportExample, source: storyConfig.exampleImport, loading: props.loading, }); const demo = (props: { demo: React.ReactNode; loading?: boolean }) => { const { demo: Demo, loading } = props; if (!Demo) { return null; } return { title: 'Demo', type: SectionType.Demo, loading, component: Demo, }; }; const doDont = (props: { do: string[]; dont: string[]; loading?: boolean }) => { if (!props.do?.length && !props.dont?.length) { return null; } return { type: SectionType.DoDont, do: props.do && { list: props.do }, dont: props.dont && { list: props.dont }, loading: props.loading, }; }; const divider = () => ({ type: SectionType.Divider }); const title = (text: string) => ({ type: SectionType.Title, title: text }); const includedComponents = (props: IncludedComponent[]) => ({ title: 'Included Components', type: SectionType.IncludedComponents, component: props, }); const designTab = (props: StoryPageSection, storyConfig: StoryConfig) => { const { content } = props; const showCommonUseCaseExamples = props.content.commonUseCaseExamples?.length; const showIncludedComponents = props.content.includedComponents?.length; const showDeveloperExamples = props.content.developerExamples?.length; const showAccessibilityExamples = props.content.accessibilityExamples?.length; const examplesConfig = { examplesPreviewWrapper: storyConfig.story?.examplesPreviewWrapper, }; return { title: 'Design', type: SectionType.Tab, sections: [ typeof props.demo === 'string' ? example({ source: props.demo, loading: props.loading }) : demo({ demo: props.demo, loading: props.loading }), description({ title: content.title || 'Usage', description: content.description, loading: props.loading, width: '60%', }), doDont({ do: content.do, dont: content.dont, loading: props.loading }), importExample(storyConfig, { loading: props.loading }), showIncludedComponents && includedComponents(content.includedComponents), divider(), title('Variations'), ...examples( props.content.featureExamples, props.examples, examplesConfig, ), showDeveloperExamples && divider(), showDeveloperExamples && title('Developer examples'), ...examples( props.content.developerExamples, props.examples, examplesConfig, ), showAccessibilityExamples && divider(), showAccessibilityExamples && title('Accessibility considerations'), ...examples( props.content.accessibilityExamples, props.examples, examplesConfig, ), showCommonUseCaseExamples && divider(), showCommonUseCaseExamples && title('Common use cases'), ...examples( props.content.commonUseCaseExamples, props.examples, examplesConfig, ), divider(), title('Feedback'), description({ description: storyConfig.config.feedbackText }), ].filter(item => !!item), }; }; const apiTab = () => ({ title: 'API', type: SectionType.Tab, sections: [ { type: SectionType.Api, }, ], }); const testkitTab = () => ({ title: 'Testkit', type: SectionType.Tab, sections: [ { type: SectionType.Testkit, }, ], }); const playgroundTab = (props: StoryPageSection, storyConfig: StoryConfig) => ({ title: 'Playground', type: SectionType.Tab, sections: [ { type: SectionType.Playground, }, ], }); const tabs = (props: StoryPageSection, storyConfig: StoryConfig) => { const defaultTabs = { design: designTab(props, storyConfig), api: apiTab(), testkit: testkitTab(), playground: playgroundTab(props, storyConfig), }; const defaultUserTabsValue = (defaultabs: Tabs) => [ defaultabs.design, defaultabs.api, defaultabs.testkit, ]; const { tabs: userTabs = defaultUserTabsValue } = props; return userTabs(defaultTabs) .filter(item => !(item.title === 'Testkit' && storyConfig?.config?.story?.testkit === false)) .reduce((result, tab) => { if (!tab.title) { return result; } if (defaultTabs[tab.title.toLowerCase()]) { return [...result, defaultTabs[tab.title.toLowerCase()]]; } const pluginSection = tab.node && { type: SectionType.Plugin, handler: () => tab.node, }; return [ ...result, { title: tab.title, type: SectionType.Tab, sections: [ ...(tab.sections ? tab.sections : []), ...(tab.node ? [pluginSection] : []), ], }, ]; }, [] as TabSection[]); }; export const storyPage = ( props: StoryPageSection, storyConfig: StoryConfig, ) => [ { type: SectionType.Header, sourceUrl: `${storyConfig.config.repoBaseURL}/${storyConfig.storyName}`, source: storyConfig.config.story?.source, loading: props.loading, }, { type: SectionType.Tabs, tabs: tabs(props, storyConfig), }, ];