Skip to content

Commit

Permalink
Supports for tags in <Meta/>
Browse files Browse the repository at this point in the history
  • Loading branch information
j3rem1e committed Aug 30, 2023
1 parent c68b02c commit 5c86b26
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 3 deletions.
19 changes: 18 additions & 1 deletion src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,24 @@ interface Slots {
/**
* Meta.
*/
export class Meta extends SvelteComponent<BaseMeta<any> & BaseAnnotations<any, DecoratorReturnType>> { }
export class Meta extends SvelteComponent<
BaseMeta<any> & BaseAnnotations<any, DecoratorReturnType> & {
/**
* Enable the tag 'autodocs'.
*
* @see [Automatic documentation](https://storybook.js.org/docs/svelte/writing-docs/autodocs)
*/
autodocs?: boolean;
/**
* List of tags to add to the stories.
*
* It should be a static array of strings.
*
* @example
* tags={['autodocs']}
*/
tags?: string[];
}> { }
/**
* Story.
*/
Expand Down
118 changes: 118 additions & 0 deletions src/parser/extract-stories.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,124 @@ describe('extractSource', () => {
}
`);
});
test('Add tags autodocs', () => {
expect(
extractStories(`
<script>
import { Story, Meta } from '@storybook/addon-svelte-csf';
</script>
<Meta title='test' autodocs/>
<Story name="Story1">
<div>story 1</div>
</Story>
`)
).toMatchInlineSnapshot(`
{
"allocatedIds": [
"default",
"Story",
"Meta",
],
"meta": {
"id": undefined,
"tags": [
"autodocs",
],
"title": "test",
},
"stories": {
"Story1": {
"hasArgs": false,
"name": "Story1",
"source": "<div>story 1</div>",
"storyId": "test--story-1",
"template": false,
},
},
}
`);
});
test('Add tags', () => {
expect(
extractStories(`
<script>
import { Story, Meta } from '@storybook/addon-svelte-csf';
</script>
<Meta title='test' tags={['a','b']}/>
<Story name="Story1">
<div>story 1</div>
</Story>
`)
).toMatchInlineSnapshot(`
{
"allocatedIds": [
"default",
"Story",
"Meta",
],
"meta": {
"id": undefined,
"tags": [
"a",
"b",
],
"title": "test",
},
"stories": {
"Story1": {
"hasArgs": false,
"name": "Story1",
"source": "<div>story 1</div>",
"storyId": "test--story-1",
"template": false,
},
},
}
`);
});
test('Add Only one tag', () => {
expect(
extractStories(`
<script>
import { Story, Meta } from '@storybook/addon-svelte-csf';
</script>
<Meta title='test' tags='a'/>
<Story name="Story1">
<div>story 1</div>
</Story>
`)
).toMatchInlineSnapshot(`
{
"allocatedIds": [
"default",
"Story",
"Meta",
],
"meta": {
"id": undefined,
"tags": [
"a",
],
"title": "test",
},
"stories": {
"Story1": {
"hasArgs": false,
"name": "Story1",
"source": "<div>story 1</div>",
"storyId": "test--story-1",
"template": false,
},
},
}
`);
});
test('Duplicate Id', () => {
expect(
extractStories(`
Expand Down
56 changes: 56 additions & 0 deletions src/parser/extract-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface StoryDef {
interface MetaDef {
title?: string;
id?: string;
tags?: string[];
}

interface StoriesDef {
Expand Down Expand Up @@ -44,6 +45,57 @@ function getStaticAttribute(name: string, node: any): string | undefined {
throw new Error(`Attribute ${name} is not static`);
}

function getStaticBooleanAttribute(name: string, node: any): boolean | undefined {
// extract the attribute
const attribute = node.attributes.find(
(att: any) => att.type === 'Attribute' && att.name === name
);

if (!attribute) {
return undefined;
}

const { value } = attribute;

// expect the attribute to be static and a boolean
if (typeof value === 'boolean') {
return value;
}

throw new Error(`Attribute ${name} is not a static boolean`);
}

function getMetaTags(node: any): string[] {

const finalTags = getStaticBooleanAttribute('autodocs', node) ? ["autodocs"] : [];

const tags = node.attributes.find((att: any) => att.type === 'Attribute' && att.name === 'tags');
if (tags) {
let valid = false;

const { value } = tags;
if (value && value.length === 1 ) {
const { type, expression, data } = value[0];
if (type === 'Text') {
// tags="autodocs"
finalTags.push(data);
valid = true;
} else if (type === 'MustacheTag' && expression.type === 'ArrayExpression') {
// tags={["autodocs"]}
const { elements } = expression;
elements.forEach((e : any) => finalTags.push(e.value));
valid = true;
}
}

if (!valid) {
throw new Error('Attribute tags should be a static string array or a string');
}
}

return finalTags;
}

/**
* Parse a Svelte component and extract stories.
* @param component Component Source
Expand Down Expand Up @@ -143,6 +195,10 @@ export function extractStories(component: string): StoriesDef {

meta.title = getStaticAttribute('title', node);
meta.id = getStaticAttribute('id', node);
const tags = getMetaTags(node);
if (tags.length > 0) {
meta.tags = tags;
}
}
},
});
Expand Down
2 changes: 1 addition & 1 deletion src/preset/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function svelteIndexer(fileName, { makeTitle }) {
const defs = extractStories(code);

return {
meta: { title: makeTitle(defs.meta.title) },
meta: { title: makeTitle(defs.meta.title), tags: defs.meta.tags },
stories: Object.entries(defs.stories)
.filter(([id, story]) => !story.template)
.map(([id, story]) => ({
Expand Down
2 changes: 1 addition & 1 deletion stories/button.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
</script>

<Meta title="Button" component={Button}/>
<Meta title="Button" component={Button} autodocs/>

<Template let:args>
<Button {...args} on:click={handleClick}>
Expand Down

0 comments on commit 5c86b26

Please sign in to comment.