Closed paoloricciuti closed 5 months ago
tbh I don't have confidence in these changes. It's too hacky for me ^^
I would prefer I think a special case for the "play" function using maybe the storyContext to get the real function. I didn't test this path however.
Sure if you can point me towards how to use the storyContext to get the real function I would gladly implement this change. Also, the shared map should not be a problem because even if something gets override it will be overridden again during the render of the current story.
Open to discussion for the best solution tho.
THE PROBLEM
At the end of the day storybook expects a CSF which is structured something like this
to achieve this the vite plugin transform the
.stories.svelte
component and make use of theparse
function fromcollect-stories.ts
that instantiate a "headless" version of the component to collect this information (very clever trick btw).The problem with this approach however is that if there are closures in those parameters the scope over which they close is the one from the headless story and not the one actually rendered. This means that if you try to modify state from within the
play
function it will not be reflected in the actual mounted story. This is especially annoying if you have to use timing functions (setInterval
orsetTimeout
) because they need to be cleaned up but theonDestroy
from svelte doesn't have access to the same scope of theplay
functionEg.
THE SOLUTION
To fix this issue i made two small changes: i created a map of stories_name => stories arguments inside the context and when a
Story
is rendered it update this map. This Map is then imported fromcollect-stories.ts
and, if the argument is a function, the actual argument will get the actual argument from the map and call it (passing over every prop). This will ensure that the function will always be the one of the latest render of the story.I don't know if this is the right approach and i would love some feedback on it from someone with more experience on this addon.