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 all 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
3 changes: 2 additions & 1 deletion .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
34e364a0ca1d93555d36a7367d78e8e229493de8
c0896915fb7fb9a8dd416b9aebca17abd909d1c1
a41c227037e7e7249b8b376f838f4f8bcc3e3e59
13c46e6c0b7f3dd8cf4ba42d1cfd6714f4777d54
13c46e6c0b7f3dd8cf4ba42d1cfd6714f4777d54
0a4522a3f84773f39daec4820c49b8a92e9f9d11
6 changes: 5 additions & 1 deletion code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const config: StorybookConfig = {
directory: '../addons/toolbars/template/stories',
titlePrefix: 'addons/toolbars',
},
{
directory: '../addons/themes/template/stories',
titlePrefix: 'addons/themes',
},
{
directory: '../addons/onboarding/src',
titlePrefix: 'addons/onboarding',
Expand All @@ -83,6 +87,7 @@ const config: StorybookConfig = {
],
addons: [
'@storybook/addon-links',
'@storybook/addon-themes',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-storysource',
Expand Down Expand Up @@ -119,7 +124,6 @@ const config: StorybookConfig = {
},
features: {
viewportStoryGlobals: true,
themesStoryGlobals: true,
backgroundsStoryGlobals: true,
},
viteFinal: (viteConfig, { configType }) =>
Expand Down
104 changes: 80 additions & 24 deletions code/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ import {
} from 'storybook/internal/theming';
import { useArgs, DocsContext as DocsContextProps } from 'storybook/internal/preview-api';
import type { PreviewWeb } from 'storybook/internal/preview-api';
import type { ReactRenderer } from '@storybook/react';
import type { ReactRenderer, Decorator } from '@storybook/react';
import type { Channel } from 'storybook/internal/channels';

import { DocsContext } from '@storybook/blocks';
import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';

import { DocsPageWrapper } from '../lib/blocks/src/components';

const { document } = global;

const ThemeBlock = styled.div<{ side: 'left' | 'right' }>(
const ThemeBlock = styled.div<{ side: 'left' | 'right'; layout: string }>(
{
position: 'absolute',
top: 0,
Expand All @@ -31,8 +32,10 @@ const ThemeBlock = styled.div<{ side: 'left' | 'right' }>(
height: '100vh',
bottom: 0,
overflow: 'auto',
padding: 10,
},
({ layout }) => ({
padding: layout === 'fullscreen' ? 0 : '1rem',
}),
({ theme }) => ({
background: theme.background.content,
color: theme.color.defaultText,
Expand All @@ -49,14 +52,17 @@ const ThemeBlock = styled.div<{ side: 'left' | 'right' }>(
}
);

const ThemeStack = styled.div(
const ThemeStack = styled.div<{ layout: string }>(
{
position: 'relative',
minHeight: 'calc(50vh - 15px)',
flex: 1,
},
({ theme }) => ({
background: theme.background.content,
color: theme.color.defaultText,
}),
({ layout }) => ({
padding: layout === 'fullscreen' ? 0 : '1rem',
})
);

Expand All @@ -80,6 +86,25 @@ const PlayFnNotice = styled.div(
})
);

const StackContainer = ({ children, layout }) => (
<div
style={{
height: '100%',
display: 'flex',
flexDirection: 'column',
// margin: layout === 'fullscreen' ? 0 : '-1rem',
}}
>
<style dangerouslySetInnerHTML={{ __html: 'html, body, #storybook-root { height: 100%; }' }} />
{layout === 'fullscreen' ? null : (
<style
dangerouslySetInnerHTML={{ __html: 'html, body { padding: 0!important; margin: 0; }' }}
/>
)}
{children}
</div>
);

const ThemedSetRoot = () => {
const theme = useTheme();

Expand Down Expand Up @@ -159,10 +184,20 @@ 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 }) => {
const defaultTheme =
isChromatic() && !playFunction && args.autoplay !== true ? 'stacked' : 'light';
const theme = globals.theme || parameters.theme || defaultTheme;
(StoryFn, { globals, playFunction, args, storyGlobals, parameters }) => {
let theme = globals.sb_theme;
let showPlayFnNotice = false;

// this makes the decorator be out of 'phase' with the actually selected theme in the toolbar
// but this is acceptable, I guess
// we need to ensure only a single rendering in chromatic
// a more 'correct' approach would be to set a specific theme global on every story that has a playFunction
if (playFunction && args.autoplay !== false && !(theme === 'light' || theme === 'dark')) {
theme = 'light';
showPlayFnNotice = true;
} else if (isChromatic() && !storyGlobals.sb_theme && !playFunction) {
theme = 'stacked';
}

switch (theme) {
case 'side-by-side': {
Expand All @@ -172,12 +207,12 @@ export const decorators = [
<Global styles={createReset} />
</ThemeProvider>
<ThemeProvider theme={convert(themes.light)}>
<ThemeBlock side="left" data-side="left">
<ThemeBlock side="left" data-side="left" layout={parameters.layout}>
<StoryFn />
</ThemeBlock>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeBlock side="right" data-side="right">
<ThemeBlock side="right" data-side="right" layout={parameters.layout}>
<StoryFn />
</ThemeBlock>
</ThemeProvider>
Expand All @@ -190,16 +225,18 @@ export const decorators = [
<ThemeProvider theme={convert(themes.light)}>
<Global styles={createReset} />
</ThemeProvider>
<ThemeProvider theme={convert(themes.light)}>
<ThemeStack data-side="left">
<StoryFn />
</ThemeStack>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeStack data-side="right">
<StoryFn />
</ThemeStack>
</ThemeProvider>
<StackContainer layout={parameters.layout}>
<ThemeProvider theme={convert(themes.light)}>
<ThemeStack data-side="left" layout={parameters.layout}>
<StoryFn />
</ThemeStack>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeStack data-side="right" layout={parameters.layout}>
<StoryFn />
</ThemeStack>
</ThemeProvider>
</StackContainer>
</Fragment>
);
}
Expand All @@ -209,7 +246,7 @@ export const decorators = [
<ThemeProvider theme={convert(themes[theme])}>
<Global styles={createReset} />
<ThemedSetRoot />
{!parameters.theme && isChromatic() && playFunction && (
{showPlayFnNotice && (
<>
<PlayFnNotice>
<span>
Expand All @@ -233,7 +270,7 @@ export const decorators = [
*
* If parameters.withRawArg is not set, this decorator will do nothing
*/
(StoryFn, { parameters, args, hooks }) => {
(StoryFn, { parameters, args }) => {
const [, updateArgs] = useArgs();
if (!parameters.withRawArg) {
return <StoryFn />;
Expand All @@ -246,6 +283,7 @@ export const decorators = [
...args,
onChange: (newValue) => {
updateArgs({ [parameters.withRawArg]: newValue });
// @ts-expect-error onChange is not a valid arg
args.onChange?.(newValue);
},
}}
Expand All @@ -257,7 +295,7 @@ export const decorators = [
</>
);
},
];
] satisfies Decorator[];

export const parameters = {
options: {
Expand Down Expand Up @@ -295,4 +333,22 @@ export const parameters = {
'slategray',
],
},
viewport: {
options: MINIMAL_VIEWPORTS,
},
themes: {
disable: true,
},
backgrounds: {
options: {
light: { name: 'light', value: '#edecec' },
dark: { name: 'dark', value: '#262424' },
blue: { name: 'blue', value: '#1b1a2c' },
},
grid: {
cellSize: 15,
cellAmount: 10,
opacity: 0.4,
},
},
};
2 changes: 1 addition & 1 deletion code/addons/backgrounds/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"./src/manager.tsx"
],
"previewEntries": [
"./src/preview.tsx"
"./src/preview.ts"
]
},
"gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae16",
Expand Down
145 changes: 145 additions & 0 deletions code/addons/backgrounds/src/components/Tool.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import React, { useState, memo, Fragment, useCallback } from 'react';

import { useGlobals, useParameter } from 'storybook/internal/manager-api';
import { IconButton, WithTooltip, TooltipLinkList } from 'storybook/internal/components';

import { CircleIcon, GridIcon, PhotoIcon, RefreshIcon } from '@storybook/icons';
import { PARAM_KEY as KEY } from '../constants';
import type { Background, BackgroundMap, Config, GlobalStateUpdate } from '../types';

type Link = Parameters<typeof TooltipLinkList>['0']['links'][0];

const emptyBackgroundMap: BackgroundMap = {};

export const BackgroundTool = memo(function BackgroundSelector() {
const config = useParameter<Config>(KEY);
const [globals, updateGlobals, storyGlobals] = useGlobals();
const [isTooltipVisible, setIsTooltipVisible] = useState(false);

const { options = emptyBackgroundMap, disable = true } = config || {};
if (disable) {
return null;
}

const data = globals[KEY] || {};
const backgroundName: string = data.value;
const isGridActive = data.grid || false;

const item = options[backgroundName];
const isLocked = !!storyGlobals?.[KEY];
const length = Object.keys(options).length;

return (
<Pure
{...{
length,
backgroundMap: options,
item,
updateGlobals,
backgroundName,
setIsTooltipVisible,
isLocked,
isGridActive,
isTooltipVisible,
}}
/>
);
});

interface PureProps {
length: number;
backgroundMap: BackgroundMap;
item: Background | undefined;
updateGlobals: ReturnType<typeof useGlobals>['1'];
backgroundName: string | undefined;
setIsTooltipVisible: React.Dispatch<React.SetStateAction<boolean>>;
isLocked: boolean;
isGridActive: boolean;
isTooltipVisible: boolean;
}

const Pure = memo(function PureTool(props: PureProps) {
const {
item,
length,
updateGlobals,
setIsTooltipVisible,
backgroundMap,
backgroundName,
isLocked,
isGridActive: isGrid,
isTooltipVisible,
} = props;

const update = useCallback(
(input: GlobalStateUpdate) => {
updateGlobals({
[KEY]: input,
});
},
[updateGlobals]
);

return (
<Fragment>
<IconButton
key="grid"
active={isGrid}
disabled={isLocked}
title="Apply a grid to the preview"
onClick={() => update({ value: backgroundName, grid: !isGrid })}
>
<GridIcon />
</IconButton>

{length > 0 ? (
<WithTooltip
key="background"
placement="top"
closeOnOutsideClick
tooltip={({ onHide }) => {
return (
<TooltipLinkList
links={[
...(!!item
? [
{
id: 'reset',
title: 'Reset background',
icon: <RefreshIcon />,
onClick: () => {
update({ value: undefined, grid: isGrid });
onHide();
},
},
]
: []),
...Object.entries(backgroundMap).map<Link>(([k, value]) => ({
id: k,
title: value.name,
icon: <CircleIcon color={value?.value || 'grey'} />,
active: k === backgroundName,
onClick: () => {
update({ value: k, grid: isGrid });
onHide();
},
})),
]}
/>
);
}}
onVisibleChange={setIsTooltipVisible}
>
<IconButton
disabled={isLocked}
key="background"
title="Change the background of the preview"
active={!!item || isTooltipVisible}
>
<PhotoIcon />
</IconButton>
</WithTooltip>
) : null}
</Fragment>
);
});
Loading
Loading