Skip to content

Commit

Permalink
1.0.0-beta.6: Improve code snippets and CD (#16)
Browse files Browse the repository at this point in the history
* Improve code snippets

* Update solid.yml

* Fix CD expressions

* Generate empty args for render function

* Update versions
  • Loading branch information
JonahPlusPlus authored Nov 13, 2024
1 parent fd2dfec commit 12e4633
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/solid-vite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ on:
description: Publish?
required: false
type: boolean
default: false
workflow_dispatch:
inputs:
publish:
description: Publish?
required: false
type: boolean
default: false
defaults:
run:
working-directory: packages/frameworks/solid-vite
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/solid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ on:
- packages/renderers/solid/**
release:
types: [published]
branches:
- main
workflow_dispatch:
inputs:
publish:
description: Publish?
required: false
type: boolean
default: false
defaults:
run:
working-directory: packages/renderers/solid
Expand All @@ -43,4 +42,5 @@ jobs:
needs: solid-workflow
uses: ./.github/workflows/solid-vite.yml
with:
publish: ${{ github.event_name == 'release' || inputs.publish }}
publish: ${{ (github.event_name == 'release') || (inputs.publish == true) }}
secrets: inherit
2 changes: 1 addition & 1 deletion packages/frameworks/solid-vite/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "storybook-solidjs-vite",
"type": "module",
"version": "1.0.0-beta.5",
"version": "1.0.0-beta.6",
"description": "Storybook for SolidJS and Vite: Develop SolidJS in isolation with Hot Reloading.",
"keywords": [
"storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/renderers/solid/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "storybook-solidjs",
"type": "module",
"version": "1.0.0-beta.5",
"version": "1.0.0-beta.6",
"description": "Storybook SolidJS renderer",
"keywords": [
"storybook"
Expand Down
71 changes: 71 additions & 0 deletions packages/renderers/solid/src/docs/sourceDecorator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,77 @@ test('component with typescript', () => {
`);
});

test('component with expression children', () => {
const newSrc = generateSolidSource(
'Component',
'{ args: { children: { do: () => { return 32; } } } }',
);

expect(newSrc).toMatchInlineSnapshot(`
"<Component>{{
do: () => {
return 32;
}
}}</Component>"
`);
});

test('component with render function', () => {
const newSrc = generateSolidSource(
'Component',
'{ render: () => <Component foo={32}>Hello</Component> }',
);

expect(newSrc).toMatchInlineSnapshot(
`"<Component foo={32}>Hello</Component>"`,
);
});

test('component with render function and args', () => {
const newSrc = generateSolidSource(
'Component',
'{ args: { foo: 32 }, render: (args) => <Component {...args}>Hello</Component> }',
);

expect(newSrc).toMatchInlineSnapshot(`
"const args = {
foo: 32
};
<Component {...args}>Hello</Component>"
`);
});

test('component with render function and missing args', () => {
const newSrc = generateSolidSource(
'Component',
'{ render: (args) => <Component {...args}>Hello</Component> }',
);

expect(newSrc).toMatchInlineSnapshot(`
"const args = {};
<Component {...args}>Hello</Component>"
`);
});

test('component with render function and args and ctx', () => {
const newSrc = generateSolidSource(
'Component',
'{ args: { foo: 32 }, render: (args, ctx) => <Component {...args}>Hello</Component> }',
);

expect(newSrc).toMatchInlineSnapshot(`
"const args = {
foo: 32
};
var ctx;
<Component {...args}>Hello</Component>"
`);
});

test('component missing story config', () => {
const newSrc = () => generateSolidSource('Component', '5 + 4');

Expand Down
117 changes: 104 additions & 13 deletions packages/renderers/solid/src/docs/sourceDecorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,65 @@ export const sourceDecorator = (
* Generate Solid JSX from story source.
*/
export function generateSolidSource(name: string, src: string): string {
const { attributes, children } = parseProps(src);
const ast = parser.parseExpression(src, { plugins: ['jsx', 'typescript'] });
const { attributes, children, original } = parseArgs(ast);
const render = parseRender(ast);

// If there is a render function, display it to the best of our ability.
if (render) {
const { body, params } = render;
let newSrc = '';

// Add arguments declaration.
if (params[0]) {
const args = original ?? {
type: 'ObjectExpression',
properties: [],
};

const argsStatement = {
type: 'VariableDeclaration',
kind: 'const',
declarations: [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: params[0],
},
init: args,
},
],
};

newSrc += generate(argsStatement, { compact: false }).code + '\n\n';
}

// Add context declaration.
if (params[1]) {
const ctxStatement = {
type: 'VariableDeclaration',
kind: 'var',
declarations: [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: params[1],
},
},
],
};

newSrc += generate(ctxStatement, { compact: false }).code + '\n\n';
}

newSrc += generate(body, { compact: false }).code;

return newSrc;
}

// Otherwise, render a component with the arguments.

const selfClosing = children == null || children.length == 0;

Expand Down Expand Up @@ -138,49 +196,82 @@ function toJSXChild(node: any): object {
if (t.isExpression(node)) {
return {
type: 'JSXExpressionContainer',
value: node,
expression: node,
};
}

return {
type: 'JSXExpressionContainer',
value: t.jsxEmptyExpression(),
expression: t.jsxEmptyExpression(),
};
}
/** Story render function. */
interface SolidRender {
body: object;
params: string[];
}

function parseRender(ast: any): SolidRender | null {
if (ast.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type';
// Find render property.
const renderProp = ast.properties.find((v: any) => {
if (v.type != 'ObjectProperty') return false;
if (v.key.type != 'Identifier') return false;
return v.key.name == 'render';
}) as any | undefined;
if (!renderProp) return null;

const renderFn = renderProp.value;
if (
renderFn.type != 'ArrowFunctionExpression' &&
renderFn.type != 'FunctionExpression'
) {
console.warn('`render` property is not a function, skipping...');
return null;
}

return {
body: renderFn.body,
params: renderFn.params.map((x: any) => x.name),
};
}

interface SolidProps {
/** Story arguments. */
interface SolidArgs {
attributes: object[];
children: object[] | null;
original: object | null;
}

/**
* Parses component properties from source expression.
* Parses component arguments from source expression.
*
* The source code will be in the form of a `Story` object.
*/
function parseProps(src: string): SolidProps {
const ast = parser.parseExpression(src, { plugins: ['jsx', 'typescript'] });
function parseArgs(ast: any): SolidArgs {
if (ast.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type';
// Find args property.
const args_prop = ast.properties.find((v: any) => {
const argsProp = ast.properties.find((v: any) => {
if (v.type != 'ObjectProperty') return false;
if (v.key.type != 'Identifier') return false;
return v.key.name == 'args';
}) as any | undefined;
// No args, so there aren't any properties or children.
if (!args_prop)
if (!argsProp)
return {
attributes: [],
children: null,
original: null,
};
// Get arguments.
const args = args_prop.value;
if (args.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type';
const original = argsProp.value;
if (original.type != 'ObjectExpression')
throw 'Expected `ObjectExpression` type';

// Construct props object, where values are source code slices.
const attributes: object[] = [];
let children: object[] | null = null;
for (const el of args.properties) {
for (const el of original.properties) {
let attr: object | null = null;

switch (el.type) {
Expand Down Expand Up @@ -210,7 +301,7 @@ function parseProps(src: string): SolidProps {
}
}

return { attributes, children };
return { attributes, children, original };
}

/**
Expand Down

0 comments on commit 12e4633

Please sign in to comment.