Skip to content

Commit

Permalink
Merge branch 'next' into kasper/bump-user-event
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperpeulen authored Feb 15, 2024
2 parents 45abcf3 + be84a02 commit 0e66ecf
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 23 deletions.
19 changes: 18 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
- [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates)
- [Changed decorator order between preview.js and addons/frameworks](#changed-decorator-order-between-previewjs-and-addonsframeworks)
- [Dark mode detection](#dark-mode-detection)
- [`addons.setConfig` should now be imported from `@storybook/manager-api`.](#addonssetconfig-should-now-be-imported-from-storybookmanager-api)
- [7.0 core addons changes](#70-core-addons-changes)
- [Removed auto injection of @storybook/addon-actions decorator](#removed-auto-injection-of-storybookaddon-actions-decorator)
- [Addon-backgrounds: Removed deprecated grid parameter](#addon-backgrounds-removed-deprecated-grid-parameter)
Expand Down Expand Up @@ -468,7 +469,10 @@ In Storybook 7, these packages existed for backwards compatibility, but were mar
- `@storybook/store` - this package has been merged into `@storybook/preview-api`.
- `@storybook/api` - this package has been replaced with `@storybook/manager-api`.

This section explains the rationale, and the required changed you might have to make: [New Addons API](#new-addons-api)
These sections explain the rationale, and the required changes you might have to make:

- [New Addons API](#new-addons-api)
- [`addons.setConfig` should now be imported from `@storybook/manager-api`.](#addonssetconfig-should-now-be-imported-from-storybookmanager-api)

### Framework-specific Vite plugins have to be explicitly added

Expand Down Expand Up @@ -2029,6 +2033,19 @@ Earlier versions used the light theme by default, so if you don't set a theme an

To learn more about theming, read our [documentation](https://storybook.js.org/docs/react/configure/theming).

#### `addons.setConfig` should now be imported from `@storybook/manager-api`.

The previous package, `@storybook/addons`, is now deprecated and will be removed in 8.0.

```diff
- import { addons } from '@storybook/addons';
+ import { addons } from '@storybook/manager-api';

addons.setConfig({
// ...
})
```

### 7.0 core addons changes

#### Removed auto injection of @storybook/addon-actions decorator
Expand Down
1 change: 1 addition & 0 deletions code/addons/actions/src/runtime/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export function action(name: string, options: ActionOptions = {}): HandlerFuncti
channel.emit(EVENT_ID, actionDisplayToEmit);
};
handler.isAction = true;
handler.implicit = options.implicit;

return handler;
}
63 changes: 42 additions & 21 deletions code/addons/interactions/src/preview.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable no-underscore-dangle */
import type {
Args,
LoaderFunction,
ArgsEnhancer,
PlayFunction,
PlayFunctionContext,
Renderer,
StepLabel,
} from '@storybook/types';
import { fn, isMockFunction } from '@storybook/test';
import { instrument } from '@storybook/instrumenter';

export const { step: runStep } = instrument(
Expand All @@ -16,26 +16,47 @@ export const { step: runStep } = instrument(
{ intercept: true }
);

const instrumentSpies: LoaderFunction = ({ initialArgs }) => {
const argTypesWithAction = Object.entries(initialArgs).filter(
([, value]) =>
typeof value === 'function' &&
'_isMockFunction' in value &&
value._isMockFunction &&
!value._instrumented
);

return argTypesWithAction.reduce((acc, [key, value]) => {
const instrumented = instrument({ [key]: () => value }, { retain: true })[key];
acc[key] = instrumented();
// this enhancer is being called multiple times

value._instrumented = true;
return acc;
}, {} as Args);
const traverseArgs = (value: unknown, depth = 0, key?: string): any => {
// Make sure to not get in infinite loops with self referencing args
if (depth > 5) return value;
if (value == null) return value;
if (isMockFunction(value)) {
// Makes sure we get the arg name in the interactions panel
if (key) value.mockName(key);
return value;
}

// wrap explicit actions in a spy
if (
typeof value === 'function' &&
'isAction' in value &&
value.isAction &&
!('implicit' in value && value.implicit)
) {
const mock = fn(value as any);
if (key) mock.mockName(key);
return mock;
}

if (Array.isArray(value)) {
depth++;
return value.map((item) => traverseArgs(item, depth));
}

if (typeof value === 'object' && value.constructor === Object) {
depth++;
// We have to mutate the original object for this to survive HMR.
for (const [k, v] of Object.entries(value)) {
(value as Record<string, unknown>)[k] = traverseArgs(v, depth, k);
}
return value;
}
return value;
};

export const argsEnhancers = [instrumentSpies];
const wrapActionsInSpyFns: ArgsEnhancer<Renderer> = ({ initialArgs }) => traverseArgs(initialArgs);

export const argsEnhancers = [wrapActionsInSpyFns];

export const parameters = {
throwPlayFunctionExceptions: false,
Expand Down
4 changes: 3 additions & 1 deletion code/lib/instrumenter/src/instrumenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,9 @@ export class Instrumenter {
return { __element__: { prefix, localName, id, classNames, innerText } };
}
if (typeof value === 'function') {
return { __function__: { name: value.name } };
return {
__function__: { name: 'getMockName' in value ? value.getMockName() : value.name },
};
}
if (typeof value === 'symbol') {
return { __symbol__: { description: value.description } };
Expand Down

0 comments on commit 0e66ecf

Please sign in to comment.