-
Notifications
You must be signed in to change notification settings - Fork 36
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
[Request] A simple way to bind component story state to args #164
Comments
Okay so I dug in to the source code a bit more and actually ended up coming up with a much nicer workaround than the one in the OP (4 lines of code instead of 18). However I am still curious to know if this is indeed a supported use case and/or if there's a nicer way to do it. <script lang="ts">
import { getContext } from 'svelte';
import { Story, Template } from '@storybook/addon-svelte-csf';
let loading = false;
let error = '';
// WORKAROUND: Update state to match the args on mount and when the args change
// (Much more concise than the alternative in the OP)
const { argsStore } = getContext('storybook-registration-context-component') || {};
$: if (argsStore) {
({ loading, error } = $argsStore);
}
async function handleSubmit() {
loading = true;
error = '';
setTimeout(() => {
loading = false;
error = 'An error occurred, please try again.';
}, 1000);
}
</script>
<Template>
<Form bind:loading bind:error on:submit={handleSubmit} />
</Template> EDIT: Third time's the charm? After playing with the above solution a bit more I realised that changes to the bound variables from inside the component could reset the state to match the initial args. This is my latest iteration which avoids that issue... const { argsStore } = getContext('storybook-registration-context-component') || {};
argsStore?.subscribe((args) => {
({ loading, error } = args);
}); |
You should probably use an intermediate component to do that. I don't think it's a good practice to mix args with test states.. |
Issue
I would like an easy way to have story state that is bound to the component but can still be controlled via args.
When writing stories for React it's very simple to have story state where the initial value is based on the story args, e.g.
This allows you to have stories that 1) share a template, 2) show how the component reacts to different props, 3) are still fully interactive!
As a bonus, making it so the story state reacts to changes in the "Controls" panel is a bit more work but still straightforward:
Reproducing this in
addon-svelte-csf
has proven difficult because I haven't found an easy way to access the story args in the initial render of the story. I've come up with a workaround (see below) but it feels very hacky and I would love to know if there's a built-in way to do it instead.EDIT: See my comment below the OP, I ended up coming up with a much nicer workaround.
Example workaround
Note: This workaround has a limitation in that changes to state that happen inside the story code (e.g. form submission changing the loading state) will not update the story args, but this is the same as in my React example above and I think this is acceptable if not expected.
Form.svelte
:Form.stories.svelte
:The text was updated successfully, but these errors were encountered: