Skip to content

Commit

Permalink
Merge pull request #12347 from BlackFenix2/next
Browse files Browse the repository at this point in the history
Addon-docs: Add Controls argument autodetection for svelte
  • Loading branch information
shilman authored Sep 2, 2020
2 parents f10d4aa + d01678d commit a9c1044
Show file tree
Hide file tree
Showing 15 changed files with 651 additions and 84 deletions.
4 changes: 4 additions & 0 deletions addons/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,16 @@
"react": ">=16.3.0",
"react-dom": "*",
"react-is": "^16.8.0",
"sveltedoc-parser": "^3.0.4",
"vue": "^2.6.10",
"vue-docgen-api": "^4.29.1",
"vue-docgen-loader": "^1.5.0",
"webpack": ">=4"
},
"peerDependenciesMeta": {
"sveltedoc-parser": {
"optional": true
},
"vue": {
"optional": true
},
Expand Down
1 change: 1 addition & 0 deletions addons/docs/src/frameworks/svelte/HOC.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
});
</script>

<svelte:options accessors={true} />
<div id={hash} />
4 changes: 4 additions & 0 deletions addons/docs/src/frameworks/svelte/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { extractArgTypes } from './extractArgTypes';
import { extractComponentDescription } from '../../lib/docgen';
import { prepareForInline } from './prepareForInline';

export const parameters = {
docs: {
inlineStories: true,
prepareForInline,
extractArgTypes,
extractComponentDescription,
},
};
94 changes: 94 additions & 0 deletions addons/docs/src/frameworks/svelte/extractArgTypes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import svelteDoc from 'sveltedoc-parser';
import * as fs from 'fs';
import { createArgTypes } from './extractArgTypes';

const content = fs.readFileSync(`${__dirname}/sample/MockButton.svelte`, 'utf-8');

describe('Extracting Arguments', () => {
it('should be svelte', () => {
expect(content).toMatchInlineSnapshot(`
<script>
import { createEventDispatcher, afterUpdate } from 'svelte';
export let text = '';
export let rounded = true;
const dispatch = createEventDispatcher();
function onClick(event) {
rounded = !rounded;
dispatch('click', event);
}
afterUpdate(() => {
dispatch('afterUpdate');
});
</script>
<style>
.rounded {
border-radius: 35px;
}
.button {
border: 3px solid;
padding: 10px 20px;
background-color: white;
outline: none;
}
</style>
<svelte:options accessors="{true}">
</svelte:options>
<button class="button"
class:rounded
on:click="{onClick}"
>
<strong>
{rounded ? 'Round' : 'Square'} corners
</strong>
<br>
{text}
<slot>
</slot>
</button>
`);
});

it('should generate ArgTypes', async () => {
const doc = await svelteDoc.parse({ fileContent: content, version: 3 });

const results = createArgTypes(doc);

expect(results).toMatchInlineSnapshot(`
Object {
"rounded": Object {
"control": Object {
"type": "boolean",
},
"defaultValue": true,
"description": null,
"name": "rounded",
"table": Object {
"defaultValue": Object {
"summary": true,
},
},
"type": Object {},
},
"text": Object {
"control": Object {
"type": "text",
},
"defaultValue": "",
"description": null,
"name": "text",
"table": Object {
"defaultValue": Object {
"summary": "",
},
},
"type": Object {},
},
}
`);
});
});
83 changes: 83 additions & 0 deletions addons/docs/src/frameworks/svelte/extractArgTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { ArgTypes } from '@storybook/api';

import { ArgTypesExtractor } from '../../lib/docgen';

type ComponentWithDocgen = {
__docgen: Docgen;
};

type Docgen = {
components: [];
computed: [];
data: [
{
defaultValue: any;
description: string;
keywords: [];
kind: string;
name: string;
readonly: boolean;
static: boolean;
type: { kind: string; text: string; type: string };
visibility: string;
}
];
description: null;
events: [];
keywords: [];
methods: [];
name: string;
refs: [];
slots: [];
version: number;
};

export const extractArgTypes: ArgTypesExtractor = (component) => {
// eslint-disable-next-line new-cap
const comp: ComponentWithDocgen = new component({ props: {} });
// eslint-disable-next-line no-underscore-dangle
const docs = comp.__docgen;

const results = createArgTypes(docs);

return results;
};

export const createArgTypes = (docs: Docgen) => {
const results: ArgTypes = {};
docs.data.forEach((item) => {
results[item.name] = {
control: { type: parseType(item.type.type) },
name: item.name,
description: item.description,
type: {},
defaultValue: item.defaultValue,
table: {
defaultValue: {
summary: item.defaultValue,
},
},
};
});

return results;
};

/**
* Function to convert the type from sveltedoc-parser to a storybook type
* @param typeName
* @returns string
*/
const parseType = (typeName: string) => {
switch (typeName) {
case 'string':
return 'text';

case 'enum':
return 'radio';
case 'any':
return 'object';
default:
return typeName;
}
};
13 changes: 13 additions & 0 deletions addons/docs/src/frameworks/svelte/preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import path from 'path';

import { Configuration } from 'webpack';

export function webpackFinal(webpackConfig: Configuration, options: any = {}) {
webpackConfig.module.rules.push({
test: /\.svelte$/,
loader: path.resolve(`${__dirname}/svelte-docgen-loader`),
enforce: 'pre',
});

return webpackConfig;
}
38 changes: 38 additions & 0 deletions addons/docs/src/frameworks/svelte/sample/MockButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script>
import { createEventDispatcher, afterUpdate } from 'svelte';
export let text = '';
export let rounded = true;
const dispatch = createEventDispatcher();
function onClick(event) {
rounded = !rounded;
dispatch('click', event);
}
afterUpdate(() => {
dispatch('afterUpdate');
});
</script>

<style>
.rounded {
border-radius: 35px;
}
.button {
border: 3px solid;
padding: 10px 20px;
background-color: white;
outline: none;
}
</style>

<svelte:options accessors={true} />
<button class="button" class:rounded on:click={onClick}>
<strong>{rounded ? 'Round' : 'Square'} corners</strong>
<br />
{text}
<slot />
</button>
38 changes: 38 additions & 0 deletions addons/docs/src/frameworks/svelte/svelte-docgen-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import svelteDoc from 'sveltedoc-parser';

import * as path from 'path';

/**
* webpack loader for sveltedoc-parser
* @param source raw svelte component
*/
export default async function svelteDocgen(source: string) {
// get filename for source content
// eslint-disable-next-line no-underscore-dangle
const file = path.basename(this._module.resource);

// set SvelteDoc options
const options = {
fileContent: source,
version: 3,
};

let docgen = '';

try {
const componentDoc = await svelteDoc.parse(options);

// populate filename in docgen
componentDoc.name = path.basename(file);

docgen = `
export const __docgen = ${JSON.stringify(componentDoc)};
`;
} catch (error) {
console.error(error);
}
// inject __docgen prop in svelte component
const output = source.replace('</script>', `${docgen}</script>`);

return output;
}
4 changes: 4 additions & 0 deletions addons/docs/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ declare module 'react-element-to-jsx-string' {

export default function render(element: React.ReactNode, options: Options): string;
}

declare module 'sveltedoc-parser' {
export function parse(options: any): Promise<any>;
}
1 change: 1 addition & 0 deletions app/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"core-js": "^3.0.1",
"global": "^4.3.2",
"regenerator-runtime": "^0.13.3",
"sveltedoc-parser": "^3.0.4",
"ts-dedent": "^1.1.1"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit a9c1044

Please sign in to comment.