Skip to content

Commit

Permalink
Merge branch 'next' into tom/add-stats-json-flag
Browse files Browse the repository at this point in the history
  • Loading branch information
shilman authored Feb 23, 2024
2 parents 1f6f20d + 6bfc7e9 commit acafea6
Show file tree
Hide file tree
Showing 42 changed files with 4,661 additions and 81 deletions.
42 changes: 42 additions & 0 deletions code/addons/interactions/src/preview.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, expect, test } from 'vitest';
import { fn, isMockFunction } from '@storybook/test';
import { action } from '@storybook/addon-actions';

import { traverseArgs } from './preview';

describe('traverseArgs', () => {
const args = {
deep: {
deeper: {
fnKey: fn(),
actionKey: action('name'),
},
},
arg2: Object.freeze({ frozen: true }),
};

expect(args.deep.deeper.fnKey.getMockName()).toEqual('spy');

const traversed = traverseArgs(args) as typeof args;

test('The same structure is maintained', () =>
expect(traversed).toEqual({
deep: {
deeper: {
fnKey: args.deep.deeper.fnKey,
actionKey: args.deep.deeper.actionKey,
},
},
// We don't mutate frozen objects, but we do insert them back in the tree
arg2: args.arg2,
}));

test('The mock name is mutated to be the arg key', () =>
expect(traversed.deep.deeper.fnKey.getMockName()).toEqual('fnKey'));

const actionFn = traversed.deep.deeper.actionKey;

test('Actions are wrapped in a spy', () => expect(isMockFunction(actionFn)).toBeTruthy());
test('The spy of the action is also matching the arg key ', () =>
expect(isMockFunction(actionFn) && actionFn.getMockName()).toEqual('actionKey'));
});
8 changes: 5 additions & 3 deletions code/addons/interactions/src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const { step: runStep } = instrument(
{ intercept: true }
);

const traverseArgs = (value: unknown, depth = 0, key?: string): any => {
export const traverseArgs = (value: unknown, depth = 0, key?: string): unknown => {
// Make sure to not get in infinite loops with self referencing args
if (depth > 5) return value;
if (value == null) return value;
Expand Down Expand Up @@ -45,9 +45,11 @@ const traverseArgs = (value: unknown, depth = 0, key?: string): any => {

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);
if (Object.getOwnPropertyDescriptor(value, k).writable) {
// We have to mutate the original object for this to survive HMR.
(value as Record<string, unknown>)[k] = traverseArgs(v, depth, k);
}
}
return value;
}
Expand Down
78 changes: 50 additions & 28 deletions code/addons/themes/src/theme-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {

const IconButtonLabel = styled.div(({ theme }) => ({
fontSize: theme.typography.size.s2 - 1,
marginLeft: 10,
}));

const hasMultipleThemes = (themesList: ThemeAddonState['themesList']) => themesList.length > 1;
const hasTwoThemes = (themesList: ThemeAddonState['themesList']) => themesList.length === 2;

export const ThemeSwitcher = () => {
const { themeOverride } = useParameter<ThemeParameters>(
Expand Down Expand Up @@ -52,33 +52,55 @@ export const ThemeSwitcher = () => {
return themeName && <>{`${themeName} theme`}</>;
}, [themeOverride, themeDefault, selected]);

return hasMultipleThemes(themesList) ? (
<Fragment>
<WithTooltip
placement="top"
trigger="click"
closeOnOutsideClick
tooltip={({ onHide }) => {
return (
<TooltipLinkList
links={themesList.map((theme) => ({
id: theme,
title: theme,
active: selected === theme,
onClick: () => {
updateGlobals({ theme });
onHide();
},
}))}
/>
);
if (hasTwoThemes(themesList)) {
const currentTheme = selected || themeDefault;
const alternateTheme = themesList.find((theme) => theme !== currentTheme);
return (
<IconButton
key={THEME_SWITCHER_ID}
active={!themeOverride}
title="Theme"
onClick={() => {
updateGlobals({ theme: alternateTheme });
}}
>
<IconButton key={THEME_SWITCHER_ID} active={!themeOverride} title="Theme">
<PaintBrushIcon />
{label && <IconButtonLabel>{label}</IconButtonLabel>}
</IconButton>
</WithTooltip>
</Fragment>
) : null;
<PaintBrushIcon />
{label && <IconButtonLabel>{label}</IconButtonLabel>}
</IconButton>
);
}

if (hasMultipleThemes(themesList)) {
return (
<Fragment>
<WithTooltip
placement="top"
trigger="click"
closeOnOutsideClick
tooltip={({ onHide }) => {
return (
<TooltipLinkList
links={themesList.map((theme) => ({
id: theme,
title: theme,
active: selected === theme,
onClick: () => {
updateGlobals({ theme });
onHide();
},
}))}
/>
);
}}
>
<IconButton key={THEME_SWITCHER_ID} active={!themeOverride} title="Theme">
<PaintBrushIcon />
{label && <IconButtonLabel>{label}</IconButtonLabel>}
</IconButton>
</WithTooltip>
</Fragment>
);
}

return null;
};
6 changes: 5 additions & 1 deletion code/frameworks/vue3-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@
"@storybook/builder-vite": "workspace:*",
"@storybook/core-server": "workspace:*",
"@storybook/vue3": "workspace:*",
"find-package-json": "^1.2.0",
"magic-string": "^0.30.0",
"vue-docgen-api": "^4.40.0"
"typescript": "^5.0.0",
"vue-component-meta": "^1.8.27",
"vue-docgen-api": "^4.75.1"
},
"devDependencies": {
"@types/find-package-json": "^1.2.6",
"@types/node": "^18.0.0",
"typescript": "^5.3.2",
"vite": "^4.0.0"
Expand Down
Loading

0 comments on commit acafea6

Please sign in to comment.