mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-07 07:21:17 +08:00
Merge branch 'next' into kasper/viewport
This commit is contained in:
commit
88a005964c
@ -342,9 +342,6 @@ export const parameters = {
|
||||
'slategray',
|
||||
],
|
||||
},
|
||||
viewport: {
|
||||
options: MINIMAL_VIEWPORTS,
|
||||
},
|
||||
themes: {
|
||||
disable: true,
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
export { globals } from './dist/preview';
|
||||
export * from './dist/preview';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { PARAM_KEY as KEY } from './constants';
|
||||
import { MINIMAL_VIEWPORTS } from './defaults';
|
||||
import type { GlobalState } from './types';
|
||||
|
||||
const modern: Record<string, GlobalState> = {
|
||||
@ -9,3 +10,11 @@ const modern: Record<string, GlobalState> = {
|
||||
const legacy = { viewport: 'reset', viewportRotated: false };
|
||||
|
||||
export const initialGlobals = FEATURES?.viewportStoryGlobals ? modern : legacy;
|
||||
|
||||
export const parameters = FEATURES?.viewportStoryGlobals
|
||||
? {
|
||||
[KEY]: {
|
||||
options: MINIMAL_VIEWPORTS,
|
||||
},
|
||||
}
|
||||
: {};
|
||||
|
@ -15,6 +15,8 @@
|
||||
props = {},
|
||||
/** @type {{[string]: () => {}}} Attach svelte event handlers */
|
||||
on,
|
||||
/** @type {any} whether this level of the decorator chain is the last, ie. the actual story */
|
||||
argTypes,
|
||||
} = storyFn();
|
||||
|
||||
let firstTime = true;
|
||||
@ -29,20 +31,16 @@
|
||||
Component,
|
||||
props,
|
||||
on,
|
||||
argTypes,
|
||||
};
|
||||
}
|
||||
return storyFn();
|
||||
}
|
||||
|
||||
// reactive, re-render on storyFn change
|
||||
$: ({ Component, props = {}, on } = getStoryFnValue(storyFn));
|
||||
|
||||
const eventsFromArgTypes = Object.fromEntries(
|
||||
Object.entries(storyContext.argTypes)
|
||||
.filter(([k, v]) => v.action && props[k] != null)
|
||||
.map(([k, v]) => [v.action, props[k]])
|
||||
);
|
||||
$: ({ Component, props = {}, on, argTypes } = getStoryFnValue(storyFn));
|
||||
|
||||
// set the argTypes context, read by the last SlotDecorator that renders the original story
|
||||
if (!Component) {
|
||||
showError({
|
||||
title: `Expecting a Svelte component from the story: "${name}" of "${title}".`,
|
||||
@ -55,4 +53,4 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<SlotDecorator {Component} {props} on={{ ...eventsFromArgTypes, ...on }} />
|
||||
<SlotDecorator {Component} {props} {on} {argTypes} />
|
||||
|
@ -6,20 +6,36 @@
|
||||
export let Component;
|
||||
export let props = {};
|
||||
export let on = undefined;
|
||||
export let argTypes = undefined;
|
||||
|
||||
let instance;
|
||||
let decoratorInstance;
|
||||
|
||||
const svelteVersion = VERSION[0];
|
||||
|
||||
/*
|
||||
Svelte Docgen will create argTypes for events with the name 'event_eventName'
|
||||
The Actions addon will convert these to args because they are type: 'action'
|
||||
We need to filter these args out so they are not passed to the component
|
||||
*/
|
||||
let propsWithoutDocgenEvents;
|
||||
$: propsWithoutDocgenEvents = Object.fromEntries(
|
||||
Object.entries(props).filter(([key]) => !key.startsWith('event_'))
|
||||
);
|
||||
|
||||
if (on && svelteVersion < 5) {
|
||||
if (argTypes && svelteVersion < 5) {
|
||||
const eventsFromArgTypes = Object.fromEntries(
|
||||
Object.entries(argTypes)
|
||||
.filter(([key, value]) => value.action && props[key] != null)
|
||||
.map(([key, value]) => [value.action, props[key]])
|
||||
);
|
||||
// Attach Svelte event listeners in Svelte v4
|
||||
// In Svelte v5 this is not possible anymore as instances are no longer classes with $on() properties, so it will be a no-op
|
||||
onMount(() => {
|
||||
Object.entries(on).forEach(([eventName, eventCallback]) => {
|
||||
// instance can be undefined if a decorator doesn't have <slot/>
|
||||
Object.entries({ ...eventsFromArgTypes, ...on }).forEach(([eventName, eventCallback]) => {
|
||||
// instance can be undefined if a decorator doesn't have a <slot/>
|
||||
const inst = instance ?? decoratorInstance;
|
||||
inst?.$on?.(eventName, eventCallback)
|
||||
inst?.$on?.(eventName, eventCallback);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -27,8 +43,8 @@
|
||||
|
||||
{#if decorator}
|
||||
<svelte:component this={decorator.Component} {...decorator.props} bind:this={decoratorInstance}>
|
||||
<svelte:component this={Component} {...props} bind:this={instance} />
|
||||
<svelte:component this={Component} {...propsWithoutDocgenEvents} bind:this={instance} />
|
||||
</svelte:component>
|
||||
{:else}
|
||||
<svelte:component this={Component} {...props} bind:this={instance} />
|
||||
<svelte:component this={Component} {...propsWithoutDocgenEvents} bind:this={instance} />
|
||||
{/if}
|
||||
|
@ -74,7 +74,8 @@ function prepareStory(
|
||||
};
|
||||
}
|
||||
|
||||
return preparedStory;
|
||||
// no innerStory means this is the last story in the decorator chain, so it should create events from argTypes
|
||||
return { ...preparedStory, argTypes: context.argTypes };
|
||||
}
|
||||
|
||||
export function decorateStory(storyFn: any, decorators: any[]) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user