Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSF: Allow overridding globals at the story level #26654

Merged
merged 121 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
2588fbd
Add globalOverrides concept to CSF
tmeasday Mar 26, 2024
2c09577
Override globals and emit old values on UPDATE_GLOBALS
tmeasday Mar 27, 2024
289f825
Always emit `UPDATE_GLOBALS` when selecting story
tmeasday Mar 27, 2024
2e4ffd4
Add `userGlobals` to manager globals code
tmeasday Mar 27, 2024
bd5e5d6
Disable toolbars when global is overridden
tmeasday Mar 27, 2024
3f5b00c
Improve the test case to include autodocs with multiple overrides
shilman Mar 27, 2024
ef80953
Update code/addons/toolbars/src/components/ToolbarMenuList.tsx
tmeasday Mar 27, 2024
2786bc8
Update code/lib/manager-api/src/index.tsx
tmeasday Mar 29, 2024
5356849
Upgrade CSF to version w/ globals on context
tmeasday Jun 25, 2024
d94b58c
Update API to include `storyGlobals`
tmeasday Jun 25, 2024
fcc3c02
Also emit storyGlobals on update
tmeasday Jun 25, 2024
3338701
Updated existing tests
tmeasday Jun 25, 2024
84def45
Update integration tests to account for various storyGlobals scenarios
tmeasday Jun 26, 2024
57ac8f6
Add end-to-end tests of toolbars/overrides
tmeasday Jun 26, 2024
8bb1298
Fix unused random import
tmeasday Jun 26, 2024
f96f934
Update `globals` test
tmeasday Jun 27, 2024
866dfd3
Fix url test
tmeasday Jun 27, 2024
425e870
Update snapshots in StoryStore tes
tmeasday Jun 27, 2024
c11a299
Update snapshots in normalize story test
tmeasday Jun 27, 2024
48d06e5
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 16, 2024
73cb16b
use canary of csf
ndelangen Jul 16, 2024
cc72801
add missing `storyGlobals` to test object
ndelangen Jul 16, 2024
ce5b681
add core templates to ui storybook
ndelangen Jul 17, 2024
add0674
remap core template stories a little
ndelangen Jul 17, 2024
ef8c846
add extra initialGlobals & globalTypes
ndelangen Jul 17, 2024
20220e8
fix mapping
ndelangen Jul 17, 2024
20a82fa
fix
ndelangen Jul 17, 2024
b2c4b40
use the feature ourselves for theme
ndelangen Jul 17, 2024
f7b3464
remove defaultValue
ndelangen Jul 17, 2024
c05dcb2
cleanup
ndelangen Jul 17, 2024
21cfe8b
enhancements fro background & viewports
ndelangen Jul 17, 2024
04919f7
fixes for viewports & backgrounds
ndelangen Jul 17, 2024
25db51b
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 17, 2024
20efb2a
duplicate rather than complicate
ndelangen Jul 17, 2024
1036b0e
re-use the previewAnnotation files
ndelangen Jul 18, 2024
a1a6a7d
fix e2e test
ndelangen Jul 18, 2024
c1b7e87
fixes
ndelangen Jul 18, 2024
c95544d
cleanup
ndelangen Jul 18, 2024
fd9d26f
disable the problematic stories for now
ndelangen Jul 18, 2024
6df5b90
fix https://www.chromatic.com/test?appId=635781f3500dd2c49e189caf&id=…
ndelangen Jul 18, 2024
45c88ce
oops
ndelangen Jul 18, 2024
80e7002
add comment for future me
ndelangen Jul 18, 2024
8920bb6
cleanup
ndelangen Jul 18, 2024
3aecb76
add test exclusion tag
ndelangen Jul 18, 2024
f7d02ae
cleanup
ndelangen Jul 18, 2024
0232e45
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 19, 2024
0356095
move `storyGlobals` type to types
ndelangen Jul 19, 2024
f122c3b
remove duplicate
ndelangen Jul 19, 2024
2a43164
fix the `globe` text showing in the reset of a toolbar
ndelangen Jul 19, 2024
0cd87ad
add icons ref
ndelangen Jul 19, 2024
861dd65
restructure the components
ndelangen Jul 19, 2024
971abc4
restructure the main storybook a bit
ndelangen Jul 19, 2024
9d1525a
fix
ndelangen Jul 19, 2024
9b3ceb2
add clear deprecation status to deprecated icons
ndelangen Jul 19, 2024
612a98a
fix
ndelangen Jul 19, 2024
599cce8
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 22, 2024
6daacfa
fix the switching to docs not resetting storyGlobals
ndelangen Jul 22, 2024
5b82a2e
add a version of viewport tool that uses globals exclusively
ndelangen Jul 22, 2024
9c5fc9f
improve the viewports addon
ndelangen Jul 23, 2024
997efa3
wip
ndelangen Jul 23, 2024
32a2d3d
cleanup
ndelangen Jul 23, 2024
999b619
cleanup
ndelangen Jul 23, 2024
4f9967d
restructuring
ndelangen Jul 23, 2024
6eaeb74
add
ndelangen Jul 24, 2024
b3669ab
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 24, 2024
eba7183
change back to use parameters for addon config
ndelangen Jul 24, 2024
301af1c
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 24, 2024
88ab1a2
fixes
ndelangen Jul 24, 2024
c22499b
add more
ndelangen Jul 24, 2024
3d312d5
fix
ndelangen Jul 25, 2024
248893d
fixing typings
ndelangen Jul 25, 2024
cafeaff
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 25, 2024
44163f5
always ensure the storyStore is ready to updateGlobals before proceed…
ndelangen Jul 25, 2024
3254d1b
cleanup
ndelangen Jul 25, 2024
df42f65
add disabled: false to default parameters of backgrounds
ndelangen Jul 25, 2024
453dfd6
fix link to moved story
ndelangen Jul 25, 2024
7e53f9e
add work-around hopefully reducing e2e test flake
ndelangen Jul 25, 2024
ee3f55c
testing a fix with yann
ndelangen Jul 25, 2024
9f8bc38
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 25, 2024
3aafff7
add retry for playwright test that is failing
ndelangen Jul 25, 2024
b7df747
Merge branch 'tom/23347-story-globals' of https://github.com/storyboo…
ndelangen Jul 25, 2024
1adbd1c
disable webkit in e2e tests for now,due to flake:
ndelangen Jul 26, 2024
94d7ab2
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 26, 2024
214d423
ignore CPC moving code in blame history
ndelangen Jul 26, 2024
86db1e6
simplify addon-toolbars, enable configuring via parameters, add featu…
ndelangen Jul 29, 2024
a14b228
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 29, 2024
e92e313
fix URL state for globals
ndelangen Jul 30, 2024
1b34ca2
Revert "simplify addon-toolbars, enable configuring via parameters, a…
ndelangen Jul 30, 2024
91f9ccb
Merge branch 'next' into tom/23347-story-globals
ndelangen Jul 30, 2024
d502f22
make the API change to viewport's globals/parameters addon opt-in via…
ndelangen Jul 30, 2024
9fb86c5
add extra story testing disabled in new pattern
ndelangen Jul 30, 2024
3e8fc2c
clarify the naming/color
ndelangen Jul 30, 2024
9eedc1b
add initialGlobals for toolbars, simplify decorator in main storybook
ndelangen Jul 30, 2024
a8f9779
override theme in chromatic or when playFunction, fixing some padding…
ndelangen Jul 30, 2024
7e74650
add more stories to toolbars stories
ndelangen Jul 30, 2024
04d25fc
improve typing
ndelangen Jul 30, 2024
df0f09d
consistent naming of disable, stronger typing on setting state
ndelangen Jul 30, 2024
3184e93
cleanup
ndelangen Jul 30, 2024
72dbdf3
cleanup
ndelangen Jul 30, 2024
fe3c81a
fix test, after story rename/addition
ndelangen Jul 30, 2024
0c925d9
fix
ndelangen Jul 30, 2024
8ff2eba
set initialGlobals of background to null
ndelangen Jul 30, 2024
c9a2376
chromatic preferred theme is stacked, not side-by-side
ndelangen Jul 30, 2024
a63999c
rename the theme global we use internally to `sb_theme`. add addon-th…
ndelangen Jul 31, 2024
6a273c1
fix lockfile
ndelangen Jul 31, 2024
f621766
fix
ndelangen Jul 31, 2024
690368d
improvements
ndelangen Jul 31, 2024
892fc28
improve
ndelangen Jul 31, 2024
a1b492c
improve
ndelangen Jul 31, 2024
9f3480c
improve
ndelangen Jul 31, 2024
9eabbc0
improve
ndelangen Jul 31, 2024
5da8c11
improvement
ndelangen Jul 31, 2024
46b7025
improvement
ndelangen Jul 31, 2024
10336b0
improvements
ndelangen Jul 31, 2024
8d09bac
update docs
ndelangen Jul 31, 2024
d82eaea
Cleanup
valentinpalkovic Aug 1, 2024
a37cd7f
Cleanup
valentinpalkovic Aug 1, 2024
6b1c226
Merge pull request #28765 from storybookjs/norbert/addon-themes-globals
ndelangen Aug 1, 2024
d02197e
Merge branch 'next' into tom/23347-story-globals
ndelangen Aug 1, 2024
99fb271
Merge branch 'tom/23347-story-globals' of https://github.com/storyboo…
ndelangen Aug 1, 2024
49d0155
Merge branch 'next' into tom/23347-story-globals
ndelangen Aug 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,37 @@ const managerApiPath = path.join(__dirname, '../core/src/manager-api');

const config: StorybookConfig = {
stories: [
{
directory: '../core/template/stories',
titlePrefix: 'core',
},
{
directory: '../core/src/manager',
titlePrefix: '@manager',
titlePrefix: 'manager',
},
{
directory: '../core/src/preview-api',
titlePrefix: '@preview',
titlePrefix: 'preview',
},
{
directory: '../core/src/components',
titlePrefix: '@components',
titlePrefix: 'components',
},
{
directory: '../lib/blocks/src',
titlePrefix: '@blocks',
titlePrefix: 'blocks',
},
{
directory: '../addons/controls/src',
titlePrefix: '@addons/controls',
titlePrefix: 'addons/controls',
},
{
directory: '../addons/onboarding/src',
titlePrefix: '@addons/onboarding',
titlePrefix: 'addons/onboarding',
},
{
directory: '../addons/interactions/src',
titlePrefix: '@addons/interactions',
titlePrefix: 'addons/interactions',
},
],
addons: [
Expand Down Expand Up @@ -81,7 +85,7 @@ const config: StorybookConfig = {
sourcemap: process.env.CI !== 'true',
},
}),
logLevel: 'debug',
// logLevel: 'debug',
};

export default config;
38 changes: 35 additions & 3 deletions code/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,21 @@ import {
styled,
useTheme,
} from 'storybook/internal/theming';
import { useArgs, DocsContext as DocsContextProps } from 'storybook/internal/preview-api';
import {
useArgs,
DocsContext as DocsContextProps,
useGlobals,
} from 'storybook/internal/preview-api';
import type { PreviewWeb } from 'storybook/internal/preview-api';
import type { ReactRenderer } from '@storybook/react';
import type { Channel } from 'storybook/internal/channels';

import '../renderers/react/template/components';

import { DocsContext } from '@storybook/blocks';

import { DocsPageWrapper } from '../lib/blocks/src/components';
import type { PartialStoryFn, StoryContext } from 'storybook/internal/types';

const { document } = global;

Expand Down Expand Up @@ -133,6 +140,7 @@ export const loaders = [
}
return { docsContext };
},
async () => ({ projectValue: 2 }),
];

export const decorators = [
Expand All @@ -159,10 +167,16 @@ export const decorators = [
/**
* This decorator renders the stories side-by-side, stacked or default based on the theme switcher in the toolbar
*/
(StoryFn, { globals, parameters, playFunction, args }) => {
(StoryFn, { globals, parameters, playFunction, args, userGlobals, storyGlobals, ...rest }) => {
console.log({ rest, userGlobals, globals });
const defaultTheme =
isChromatic() && !playFunction && args.autoplay !== true ? 'stacked' : 'light';
const theme = globals.theme || parameters.theme || defaultTheme;
const theme =
storyGlobals.theme || userGlobals.theme || globals.theme || parameters.theme || defaultTheme;

const [x, y] = useGlobals();

console.log({ x, y });

switch (theme) {
case 'side-by-side': {
Expand Down Expand Up @@ -257,9 +271,20 @@ export const decorators = [
</>
);
},
(storyFn: PartialStoryFn, context: StoryContext) => {
if (context.parameters.useProjectDecorator)
return storyFn({ args: { ...context.args, text: `project ${context.args.text}` } });
return storyFn();
},
];

export const parameters = {
projectParameter: 'projectParameter',
storyObject: {
a: 'project',
b: 'project',
c: 'project',
},
options: {
storySort: (a, b) =>
a.title === b.title ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
Expand Down Expand Up @@ -312,4 +337,11 @@ export const globalTypes = {
],
},
},
foo: { defaultValue: 'fooDefaultValue' },
bar: { defaultValue: 'barDefaultValue' },
};

export const initialGlobals = {
foo: 'fooValue',
baz: 'bazValue',
};
Copy link
Member

@ndelangen ndelangen Jul 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmeasday Can I get an explainer why defaultValue: 'fooDefaultValue' should ever be used?
How are initialGlobals.foo and globalTypes.foo.defaultValue connected?

At first glance, me and @valentinpalkovic both concluded that if you set a initialGlobal.foo, then globalTypes.foo.defaultValue should never be used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh pray tell? I don't recall but it does seem to be that they are synonyms for each other (and we should probably rename .defaultValue also.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just a loose end/oversight. Originally we designed args and globals side by side. Both schemas had a defaultValue. We removed argTypes.defaultValue but never removed globalTypes.defaultValue. We probably should figure out what to do in this project.

Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ export const Disabled: Story = {

export const Hovered: Story = {
...Done,
parameters: {
// Set light theme to avoid stacked theme in chromatic
theme: 'light',
},
globals: { theme: 'light' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.hover(canvas.getByRole('button'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ const meta = {
</StyledWrapper>
),
],
parameters: {
layout: 'fullscreen',
theme: 'light', // stacked will break interactions
},
parameters: { layout: 'fullscreen' },
globals: { theme: 'light' },
args: {
calls: new Map(getCalls(CallStates.DONE).map((call) => [call.id, call])),
controls: SubnavStories.args.controls,
Expand Down
2 changes: 1 addition & 1 deletion code/addons/links/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/addon-bundle.ts"
},
"dependencies": {
"@storybook/csf": "0.1.11",
"@storybook/csf": "0.1.12--canary.95.1b1fb52.0",
"@storybook/global": "^5.0.0",
"ts-dedent": "^2.0.0"
},
Expand Down
9 changes: 8 additions & 1 deletion code/addons/toolbars/src/components/ToolbarMenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Icons, IconButton, type IconsProps } from 'storybook/internal/component

interface ToolbarMenuButtonProps {
active: boolean;
disabled?: boolean;
title: string;
icon?: IconsProps['icon'];
description: string;
Expand All @@ -16,13 +17,19 @@ interface ToolbarMenuButtonProps {

export const ToolbarMenuButton: FC<ToolbarMenuButtonProps> = ({
active,
disabled,
title,
icon,
description,
onClick,
}) => {
return (
<IconButton active={active} title={description} onClick={onClick}>
<IconButton
active={active}
title={description}
disabled={disabled}
onClick={disabled ? () => {} : onClick}
>
{icon && <Icons icon={icon} __suppressDeprecationWarning={true} />}
{title ? `\xa0${title}` : null}
</IconButton>
Expand Down
6 changes: 4 additions & 2 deletions code/addons/toolbars/src/components/ToolbarMenuList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ export const ToolbarMenuList: FC<ToolbarMenuListProps> = withKeyboardCycle(
description,
toolbar: { icon: _icon, items, title: _title, preventDynamicIcon, dynamicTitle },
}) => {
const [globals, updateGlobals] = useGlobals();
const [globals, updateGlobals, storyGlobals] = useGlobals();
Copy link
Member Author

@tmeasday tmeasday Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the API that addons use to tell if the user has overridden a global value they are interested in.

If storyGlobals.X is set, then the value of globals.X is hard-coded (for now) and so showing a read/write UI is probably not sensible. Instead we'd recommend addons should either disable themselves or show a read-only API that indicates the global value is set to globals.X but cannot be changed.

If the addon wants to know the underlying userGlobals.X (what the global will go back to when the user browses away from the overriden story), there is a fourth return value, userGlobals. We talked about maybe showing that value in the "readonly" toolbar UI, but that might be confusing IMO.

const [isTooltipVisible, setIsTooltipVisible] = useState(false);

const currentValue = globals[id];
const hasGlobalValue = !!currentValue;
const isOverridden = id in storyGlobals;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be id in globals && !(id in userGlobals)?

Copy link
Member Author

@tmeasday tmeasday Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean:

id in globals && id in userGlobals

But that check won't work because in the typical case the field will be defined and equal in both places. So you'd want:

id in globals && id in userGlobals && !deepEqual(globals[id], userGlobals[id])

But technically that could be wrong too -- you might override the (story) global to the same as the current (user) value -- in which case the toolbar should still be disabled.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the conclusion on this topic?

let icon = _icon;
let title = _title;

Expand All @@ -42,7 +43,7 @@ export const ToolbarMenuList: FC<ToolbarMenuListProps> = withKeyboardCycle(
(value: string | undefined) => {
updateGlobals({ [id]: value });
},
[currentValue, updateGlobals]
[id, updateGlobals]
);

return (
Expand Down Expand Up @@ -79,6 +80,7 @@ export const ToolbarMenuList: FC<ToolbarMenuListProps> = withKeyboardCycle(
>
<ToolbarMenuButton
active={isTooltipVisible || hasGlobalValue}
disabled={isOverridden}
ndelangen marked this conversation as resolved.
Show resolved Hide resolved
description={description || ''}
icon={icon}
title={title || ''}
Expand Down
6 changes: 6 additions & 0 deletions code/addons/toolbars/template/stories/globals.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,9 @@ export default {
};

export const Basic = {};

export const Override = {
globals: {
locale: 'kr',
},
};
2 changes: 1 addition & 1 deletion code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@
"prep": "bun ./scripts/prep.ts"
},
"dependencies": {
"@storybook/csf": "0.1.11",
"@storybook/csf": "0.1.12--canary.95.1b1fb52.0",
"@types/express": "^4.17.21",
"@types/node": "^18.0.0",
"browser-assert": "^1.2.1",
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/common/js-package-manager/PNPMProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dedent from 'ts-dedent';
import { existsSync, readFileSync } from 'node:fs';
import { findUpSync } from 'find-up';
import path from 'node:path';
import { FindPackageVersionsError } from '@storybook/core-events/server-errors';
import { FindPackageVersionsError } from '@storybook/core/server-errors';

import { JsPackageManager } from './JsPackageManager';
import type { PackageJson } from './PackageJson';
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/common/js-package-manager/Yarn1Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
import dedent from 'ts-dedent';
import { findUpSync } from 'find-up';
import path from 'node:path';
import { FindPackageVersionsError } from '@storybook/core-events/server-errors';
import { FindPackageVersionsError } from '@storybook/core/server-errors';

import { createLogStream } from '../utils/cli';
import { JsPackageManager } from './JsPackageManager';
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/common/js-package-manager/Yarn2Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { existsSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { PosixFS, VirtualFS, ZipOpenFS } from '@yarnpkg/fslib';
import { getLibzipSync } from '@yarnpkg/libzip';
import { FindPackageVersionsError } from '@storybook/core-events/server-errors';
import { FindPackageVersionsError } from '@storybook/core/server-errors';

import { createLogStream } from '../utils/cli';
import { JsPackageManager } from './JsPackageManager';
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/components/components/tabs/tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ export const StatefulDynamicWithOpenTooltip = {
defaultViewport: 'sized',
viewports: customViewports,
},
theme: 'light',
chromatic: { viewports: [380] },
},
globals: { theme: 'light' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

Expand Down
Loading