Skip to content

Story-level setupApp and responsiveDisabled are dropped when a Svelte story has explicit variants #466

Description

@50rayn

<Hst.Story setupApp={…}> and <Hst.Story responsiveDisabled> are silently dropped as soon as the story declares explicit <Hst.Variant> children. Vue inherits both; Svelte does not, and nothing warns.

Where it goes

client/MountStory.svelte:20-27 forwards story-level props in one branch only:

{#if story.variants.length === 1 && story.variants[0].id === '_default'}
  <MountVariant {...inheritedFromStory} {...$$restProps} implicit>
{:else}
  <slot />
{/if}

A story-level prop lands in $$restProps (MountStory declares none of its own), so the {:else} branch discards it. MountVariant.svelte is the only writer of setupApp and responsiveDisabled onto the variant, and both are read from the variant alone — render.ts:141 for one, TopBar.vue and StoryResponsivePreview.vue for the other. No story-level fallback exists anywhere.

Verified in a browser against a built preview: a story-level setupApp runs for an implicit variant, does not run for an explicit variant with no handler of its own, and the variant-level handler runs.

The fix is already in the file

MountVariant.svelte:30 inherits the story's controls slot through context:

controls: $$slots.controls ?? storySlots.controls,

fed by setContext('__pvtSlots', $$slots) in MountStory.svelte:9. Slots got the treatment; props never did. A setContext('__pvtStoryProps', …) alongside it, and a ?? getContext('__pvtStoryProps')?.x default on each inherited prop in MountVariant, closes it in about four lines. Vue does the equivalent by copying non-omitted story keys onto each variant vnode in plugin-vue/src/client/app/Story.ts.

omitInheritStoryProps in @poveste/shared already exists to say which keys must not travel, so the allowlist question is answered.

Not affected — checked

source and initState are fine: RenderStory.svelte re-applies them at render time regardless of branch. I probed source specifically — a story-level value does reach an explicit variant. autoPropsDisabled is inert for Svelte either way (#233).

So the scope is exactly two props.

Why it is worth fixing rather than documenting

The caveat currently exists in three places — guide/svelte/app-setup.md, reference/svelte/story.md and reference/svelte/variant.md — and #464 adds a fourth for responsiveDisabled. Four copies of one sentence that must stay in sync, describing a four-line bug.

There is also a second-order cost: a warning box on two props teaches the reader that the unboxed props inherit. Every caveat added makes the remaining silence more misleading.

Fixing the code deletes all four.

Coverage

Nothing pins any of this. grep -rn setupApp examples e2e returns nothing — no book uses it, no spec asserts it. The conformance harness (e2e/stories.ts SHARED_STORIES) is the right home: a story with explicit variants and a story-level handler, asserted in all four books.

Related: #464, #233.

Metadata

Metadata

Assignees

No one assigned

    Labels

    a:pluginsPlugin API and official pluginsa:svelteSvelte plugin, SvelteKit, Hst surfacesprint:4-bugsIndependent correctness bugs; runs in parallel with any sprint

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions