Skip to content

Commit 2e0806f

Browse files
author
Jiří Fencl
committed
fix: 🐛 improve widget state handling and async render support
- Allow stories to provide only state without props by relaxing guard condition - Clear widget.state before setState to prevent stale load()-generated keys from persisting - Ensure Storybook args.widget.state remains authoritative during widget reuse - Make render calls async-aware by awaiting them in lifecycle.update and fallback branches - Add test coverage for state clearing behavior and state-only widget creation - Fix documentation: add missing WidgetDescription function in custom render example - Fix documentation: correct CSF3 to CSF2 in Preact stories description
1 parent 0f9b42b commit 2e0806f

3 files changed

Lines changed: 20 additions & 8 deletions

File tree

packages/tool-storybook/src/__tests__/indexSpec.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,27 @@ describe('Merkur tool storybook', () => {
4343
});
4444
});
4545

46-
it('should return empty widget for not defined props', async () => {
46+
it('should return empty widget when widget is not defined', async () => {
4747
let loader = createWidgetLoader({ widgetProperties, render });
4848

49-
delete storyArgs.args.widget.props;
49+
delete storyArgs.args.widget;
5050
let { widget } = await loader(storyArgs);
5151

5252
expect(widget).toEqual(null);
5353
});
5454

55+
it('should return widget instance when only state is provided (without props)', async () => {
56+
let loader = createWidgetLoader({ widgetProperties, render });
57+
58+
storyArgs.args.widget = { state: { count: 42 } };
59+
let { widget } = await loader(storyArgs);
60+
61+
expect(widget.name).toEqual(widgetProperties.name);
62+
expect(widget.version).toEqual(widgetProperties.version);
63+
expect(widget.state).toEqual({ count: 42 });
64+
expect(widget.props).toEqual({});
65+
});
66+
5567
it('should return widget instance for defined props', async () => {
5668
let loader = createWidgetLoader({ widgetProperties, render });
5769

packages/tool-storybook/src/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function createWidgetLoader({ render, widgetProperties }) {
2121
lastStory = {};
2222
}
2323

24-
if (!args?.args?.widget?.props) {
24+
if (!args?.args?.widget) {
2525
return { widget: null };
2626
}
2727

@@ -49,7 +49,7 @@ function createWidgetLoader({ render, widgetProperties }) {
4949
if (lifeCycle && typeof lifeCycle.update === 'function') {
5050
await lifeCycle.update(widget);
5151
} else {
52-
render(widget);
52+
await render(widget);
5353
}
5454
return { widget };
5555
}
@@ -72,7 +72,7 @@ function createWidgetLoader({ render, widgetProperties }) {
7272
if (lifeCycle && typeof lifeCycle.update === 'function') {
7373
await lifeCycle.update(widget);
7474
} else {
75-
render(widget);
75+
await render(widget);
7676
}
7777
return { widget };
7878
}
@@ -89,8 +89,8 @@ function createWidgetLoader({ render, widgetProperties }) {
8989
);
9090
}
9191
lifeCycle.mount = () => {};
92-
lifeCycle.update = () => {
93-
render(widget);
92+
lifeCycle.update = async () => {
93+
return await render(widget);
9494
};
9595
lifeCycle.unmount = () => {};
9696

website/docs/storybook-integration-into-merkur.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ The `bindEvents` function is crucial for vanilla widgets as it reconnects event
395395
- **Preact widgets**:
396396
- Use `.jsx` extension and JSX syntax
397397
- Decorators provide context and handle re-rendering
398-
- Stories use CSF3 format with `Template.bind({})`
398+
- Stories use CSF2 format with `Template.bind({})`
399399
- Components receive individual props
400400
401401
- **Vanilla widgets**:

0 commit comments

Comments
 (0)