-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SolidJS framework feedback #20584
SolidJS framework feedback #20584
Conversation
Marked this as "Ready for Review" just to trigger full CI suite. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a thorough review, it looks really good!
One thing that I think should be fixed though, is that it doesn't work if stories don't have a render
property. For some reason it doesn't pick up your exported render
function from render.tsx
, and I'm unsure how that is supposed to work exactly.
Maybe @tmeasday has some guidance about that?
'@storybook/solid': { | ||
vite: '@storybook/solid', | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this, as no one will be migrating from an old solid setup because that doesn't exist.
applyLoaders, | ||
unboundStoryFn, | ||
playFunction, | ||
prepareContext: prepareStoryContext, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no reason to rename this to prepareStoryContext
, just keep prepareContext
// This function is invoked at StoryRender.ts, with this | ||
// the context is prepared before invoking the render function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This function is invoked at StoryRender.ts, with this | |
// the context is prepared before invoking the render function. | |
// prepareContext is invoked at StoryRender.render() | |
// the context is prepared before invoking the render function, instead of here directly | |
// to ensure args don't loose there special properties set by the renderer | |
// eg. reactive proxies set by frameworks like SolidJS or Vue |
@@ -0,0 +1,7 @@ | |||
import { parameters as docsParams } from './docs/config'; | |||
|
|||
export const parameters = { framework: 'solid', ...docsParams }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the other renderers
export const parameters = { framework: 'solid', ...docsParams }; | |
export const parameters = { framework: 'solid' as const, ...docsParams }; |
/** | ||
* Checks when the story requires to be remounted. | ||
* Elements outside the story requires a whole re-render. | ||
* e.g. dark theme, show grid, etc... | ||
*/ | ||
const remount = (force: boolean, context: StoryContext<SolidRenderer>) => { | ||
let flag = false; | ||
|
||
if (force) { | ||
flag = true; | ||
} else if (!Object.is(globals, context.globals)) { | ||
// Globals refers to storybook visualization options. | ||
globals = context.globals; | ||
flag = true; | ||
} | ||
return flag; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Is the point here to force a re-mount when globals change?
- Nit: I think the logic can be simplified a little bit.
/** | |
* Checks when the story requires to be remounted. | |
* Elements outside the story requires a whole re-render. | |
* e.g. dark theme, show grid, etc... | |
*/ | |
const remount = (force: boolean, context: StoryContext<SolidRenderer>) => { | |
let flag = false; | |
if (force) { | |
flag = true; | |
} else if (!Object.is(globals, context.globals)) { | |
// Globals refers to storybook visualization options. | |
globals = context.globals; | |
flag = true; | |
} | |
return flag; | |
}; | |
/** | |
* Checks when the story requires to be remounted. | |
* Elements outside the story requires a whole re-render. | |
* e.g. dark theme, show grid, etc... | |
*/ | |
const shouldRemount = (force: boolean, context: StoryContext<SolidRenderer>) => { | |
if (force) { | |
return true; | |
} | |
if (!Object.is(globals, context.globals)) { | |
// Globals refers to storybook visualization options. | |
globals = context.globals; | |
return true; | |
} | |
return false; | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Yes because fine-grained updates are not possible in React, so it needs to re-run the component to update the storybook canvas with globals. In globals doesn't matter if the component re-renders because they don't have a direct relationship with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the "correct" behaviour. Globals should cause a re-render in the same way that args do.
* If remount is required, the whole root node is re-rendered. | ||
*/ | ||
if (remount(forceRemount, storyContext)) { | ||
disposeStory?.(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here and the singleton store assumes that only one story will be rendered at once. But in docs mode that is not the case because there we render multiple stories at the same time.
In this case that will mean that they all read and write from the same singleton store above - conflicting - and on this line they'll dispose each other immediately.
You can reproduce this by adding multiple stories and checking the autodocs page, it will only show the last story of the page because the others will have been disposed.
You'd probably need a map of stories being rendered similar to what we have in the Svelte renderer. https://github.com/storybookjs/storybook/blob/next/code/renderers/svelte/src/render.ts#L14
You can key the map by canvasElement
which will be unique, and I think the value would then be a combination of a store and a dispose function.
Let me know if you need further assistance with this.
You can of course postpone this change, and say that the initial version doesn't support docs mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this clarification, this is something that I have pending after having fine-grained updates working.
|
||
// More on writing stories with args: https://storybook.js.org/docs/7.0/html/writing-stories/args | ||
export const Primary = { | ||
args: {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should probably be some content on the button to not confuse people.
args: {}, | |
args: { children: 'Click Me' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I started with an elementary template for simplifying my workflow. But then I was planning to re-create again the default example templates that have the other frameworks (using React as a reference)
|
||
// More on writing stories with args: https://storybook.js.org/docs/7.0/html/writing-stories/args | ||
export const Primary: Story = { | ||
args: {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
args: {}, | |
args: { children: 'Click Me' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, the same as the previous comment.
@@ -0,0 +1,21 @@ | |||
import { Meta, Story, Canvas } from '@storybook/addon-docs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As stories defined in MDX is being deprecated in 7.0 I suggest you remove this template file.
Changes to
|
It should be picking it up from the
I think I need some more context about this, shall we discuss @JReinhold? |
Thanks @JReinhold for the deep review, I will start working today with your code suggestions. Related to this:
I have this story example on my local env. and is working without problems. Could you please provide your failing story to take a look? export const Secondary = {
args: {
disabled: true,
children: "Hello World",
},
}; Related to splitting up the PR:
So I'm pending for 1 and 2 bullets to be confirmed for continuing the development of the solidjs storybook extension. |
We discussed the preview changes, where arg type mapping is pulled "up" the rendering chain. The concern was that it is a breaking change in that now decorators will receive mapped/filtered args, whereas in the past they have not. It seems like that's better behaviour anyway. After surveying a little internally we've decided we are OK with pushing forward with that change. One thing I'd like to see if we are making that change is some unit tests demonstrating the mapping applying to decorators. |
Sorry about that, I interpreted an error wrong. Everything is working as expected, it was just a brainfart on my end.
I've created a repo here and given you admin access: https://github.com/storybookjs/solidjs . When I get time I'll add some basic tooling if you want me to. It'll be a monorepo for anything solid related, as the Solid renderer and Solid-Vite framework will probably be developed together. The first step towards making the necessary changes to core will be to make a separate PR for them, so we can see tests running. And as Tom said we also want a few unit tests, something that I can probably help out with if you need that. |
Thanks @JReinhold and @tmeasday for your feedback. I've accepted too the repo invitation, so I will start the solid framework migration as soon I have PR the core change. |
Hi @JReinhold and @tmeasday, I've just PRed the core changes. I'm not able to label the PR, so I added it inside the description as a Breaking Change. I modified 2 unit test files however they are failing due to snapshots. Locally I ran both tests with the -u flag, they are passing however the console threw me 0 snapshots for each file. I attach PR #20755 and I continue aware of your comments for moving forward with points 1 and 3 or if the current PR needs more changes.
|
Not for merging
This PR is the initial work on a SolidJS framework. As agreed with @JReinhold it is not meant to be merged, it is meant to collect feedback and suggestions. Once that has been done, this PR will be closed and the work will be solidified in a new repo.