From bee3531c799981d07d12d2be85a9ff7362d616a7 Mon Sep 17 00:00:00 2001 From: j3rem1e Date: Fri, 3 Nov 2023 22:19:19 +0100 Subject: [PATCH] Parse comments as Story description --- src/parser/collect-stories.ts | 23 ++++- src/parser/extract-stories.test.ts | 144 ++++++++++++++++++++++++++++- src/parser/extract-stories.ts | 24 ++++- stories/metaexport.stories.svelte | 1 + 4 files changed, 185 insertions(+), 7 deletions(-) diff --git a/src/parser/collect-stories.ts b/src/parser/collect-stories.ts index 3cf7c94..3eff8d4 100644 --- a/src/parser/collect-stories.ts +++ b/src/parser/collect-stories.ts @@ -5,6 +5,7 @@ import RenderContext from '../components/RenderContext.svelte'; import { combineParameters } from '@storybook/client-api'; import { extractId } from './extract-id.js'; import { logger } from '@storybook/client-logger'; +import type { StoryDef } from './extract-stories.ts'; /* Called from a webpack loader and a jest transformation. * @@ -35,7 +36,14 @@ const createFragment = document.createDocumentFragment ? () => document.createDocumentFragment() : () => document.createElement('div'); -export default (StoriesComponent, { stories = {}, allocatedIds = [] }, exportedMeta = undefined) => { +export default ( + StoriesComponent, + { + stories = {}, + allocatedIds = [], + }: { stories: Record; allocatedIds: string[] }, + exportedMeta = undefined +) => { const repositories = { meta: null as Meta | null, stories: [] as Story[], @@ -145,9 +153,20 @@ export default (StoriesComponent, { stories = {}, allocatedIds = [] }, exportedM }); } + const relStory = stories[storyId]; + if (relStory?.description) { + storyFn.parameters = combineParameters(storyFn.parameters || {}, { + docs: { + description: { + story: relStory.description, + }, + }, + }); + } + // eslint-disable-next-line no-param-reassign all[storyId] = storyFn; return all; - }, {}) as { [key: string]: { storyName: string; parameters: string; } }, + }, {}) as { [key: string]: { storyName: string; parameters: string } }, }; }; diff --git a/src/parser/extract-stories.test.ts b/src/parser/extract-stories.test.ts index bc90f22..66bdc82 100644 --- a/src/parser/extract-stories.test.ts +++ b/src/parser/extract-stories.test.ts @@ -253,7 +253,6 @@ describe('extractSource', () => { "hasArgs": false, "name": "Story1", "source": "
story 1
", - "storyId": "test--story-1", "template": false, }, }, @@ -293,7 +292,6 @@ describe('extractSource', () => { "hasArgs": false, "name": "Story1", "source": "
story 1
", - "storyId": "test--story-1", "template": false, }, }, @@ -332,7 +330,6 @@ describe('extractSource', () => { "hasArgs": false, "name": "Story1", "source": "
story 1
", - "storyId": "test--story-1", "template": false, }, }, @@ -396,4 +393,145 @@ describe('extractSource', () => { } `); }); + test('With description', () => { + expect( + extractStories(` + + + + + +
a story
+
+ `) + ).toMatchInlineSnapshot(` + { + "allocatedIds": [ + "default", + "Story", + "Button", + ], + "meta": {}, + "stories": { + "Desc": { + "description": "Story Description", + "hasArgs": false, + "name": "Desc", + "source": "
a story
", + "template": false, + }, + }, + } + `); + }); + test('With multiline description', () => { + expect( + extractStories(` + + + + + +
a story
+
+ `) + ).toMatchInlineSnapshot(` + { + "allocatedIds": [ + "default", + "Story", + "Button", + ], + "meta": {}, + "stories": { + "Desc": { + "description": "Story Description + + another line.", + "hasArgs": false, + "name": "Desc", + "source": "
a story
", + "template": false, + }, + }, + } + `); + }); + test('With unrelated nested description', () => { + expect( + extractStories(` + + +
+ +
+ +
a story
+
+ `) + ).toMatchInlineSnapshot(` + { + "allocatedIds": [ + "default", + "Story", + "Button", + ], + "meta": {}, + "stories": { + "Desc": { + "hasArgs": false, + "name": "Desc", + "source": "
a story
", + "template": false, + }, + }, + } + `); + }); + test('With unrelated description', () => { + expect( + extractStories(` + + + +
+ +
a story
+
+ `) + ).toMatchInlineSnapshot(` + { + "allocatedIds": [ + "default", + "Story", + "Button", + ], + "meta": {}, + "stories": { + "Desc": { + "hasArgs": false, + "name": "Desc", + "source": "
a story
", + "template": false, + }, + }, + } + `); + }); }); diff --git a/src/parser/extract-stories.ts b/src/parser/extract-stories.ts index 8afefaa..aa58e0f 100644 --- a/src/parser/extract-stories.ts +++ b/src/parser/extract-stories.ts @@ -4,10 +4,11 @@ import type { Node } from 'estree'; import dedent from 'dedent'; import { extractId } from './extract-id.js'; -interface StoryDef { +export interface StoryDef { name: string; template: boolean; source: string; + description?: string; hasArgs: boolean; } @@ -187,6 +188,7 @@ export function extractStories(component: string): StoriesDef { } }); } + let latestComment: string|undefined; svelte.walk(ast.html, { enter(node: any) { if ( @@ -224,19 +226,37 @@ export function extractStories(component: string): StoriesDef { // @ts-ignore source = dedent`${component.substr(start, end - start)}`; } - stories[isTemplate ? `tpl:${id}` : id] = { + const story = { name, template: isTemplate, source, hasArgs: node.attributes.find((att: any) => att.type === 'Let') != null, }; + if (!isTemplate && latestComment) { + // throws dedent expression is not callable. + // @ts-ignore + story.description = dedent`${latestComment}`; + } + stories[isTemplate ? `tpl:${id}` : id] = story; + latestComment = undefined; } } else if (node.type === 'InlineComponent' && node.name === localNames.Meta) { this.skip(); fillMetaFromAttributes(meta, node.attributes); + latestComment = undefined; + } else if (node.type === 'Comment') { + this.skip(); + + latestComment = node.data?.trim(); + return; } }, + leave(node: any) { + if (node.type !== "Comment" && node.type !== "Text") { + latestComment = undefined; + } + } }); return { meta, diff --git a/stories/metaexport.stories.svelte b/stories/metaexport.stories.svelte index 6d4e145..f444c75 100644 --- a/stories/metaexport.stories.svelte +++ b/stories/metaexport.stories.svelte @@ -25,6 +25,7 @@ +