Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ec117c0
experiment(storybook): Version picker
ling1726 Oct 21, 2021
85e17c3
Change files
ling1726 Oct 21, 2021
a8db329
use fluent menu
ling1726 Oct 21, 2021
8dcc438
cleanup
ling1726 Oct 21, 2021
153d565
add network fetch
ling1726 Oct 25, 2021
c00b676
use addon
ling1726 Oct 25, 2021
4afccab
remove old
ling1726 Oct 25, 2021
f26fb4c
update deps
ling1726 Oct 25, 2021
5a797d9
update stypes
ling1726 Oct 25, 2021
89001c0
update md
ling1726 Oct 25, 2021
b9e145c
remove export
ling1726 Oct 25, 2021
e046069
Merge branch 'master' into experiment/storybook-version-picker
ling1726 Oct 26, 2021
75bc101
chore(storybook): Add theme picker to storybook toolbar
ling1726 Oct 26, 2021
e79117f
remove unnecessary changes
ling1726 Oct 26, 2021
e72aead
update change
ling1726 Oct 26, 2021
dabef22
chore(storybook): Add custom DocsContainer to react-components storybook
ling1726 Oct 26, 2021
5f699c2
Change files
ling1726 Oct 26, 2021
43525f3
add docstring
ling1726 Oct 26, 2021
69f0aee
remove font family style
ling1726 Oct 26, 2021
e3883ca
merge conflict
ling1726 Oct 26, 2021
4a534c3
init theme picker
ling1726 Oct 27, 2021
a34bc15
Merge branch 'master' into chore/storybook-doc-theme
ling1726 Nov 2, 2021
f6e2101
merge master
ling1726 Nov 2, 2021
1c91a68
revert manager
ling1726 Nov 2, 2021
29a5f64
revert .storybook
ling1726 Nov 2, 2021
0c8aa79
remove dupe export
ling1726 Nov 2, 2021
c4bc761
export
ling1726 Nov 2, 2021
9bcd9c4
README
ling1726 Nov 2, 2021
7a44e59
use active theme
ling1726 Nov 2, 2021
8488fd3
add docstring
ling1726 Nov 2, 2021
7404702
Change files
ling1726 Nov 2, 2021
25ee3fe
fix md
ling1726 Nov 2, 2021
184ac62
drop icon
ling1726 Nov 3, 2021
e6f621d
Merge branch 'master' into chore/storybook-doc-theme
ling1726 Nov 4, 2021
00a6b23
Merge remote-tracking branch 'origin/master' into chore/storybook-doc…
ling1726 Nov 5, 2021
208c565
update md
ling1726 Nov 5, 2021
80242ae
set global theme to react-components
ling1726 Nov 5, 2021
37eeb82
add container to page
ling1726 Nov 5, 2021
9c7d6e4
use type
ling1726 Nov 5, 2021
4b9e1d3
header styling
ling1726 Nov 5, 2021
94c5687
styling updates
ling1726 Nov 5, 2021
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
8 changes: 0 additions & 8 deletions .storybook/preview-head-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,6 @@
color: #616161;
}

#docs-root .docblock-argstable tbody tr:nth-child(even) td {
background: #fafafa;
}

#docs-root .docblock-argstable tbody tr td {
vertical-align: middle;
}
Expand All @@ -197,10 +193,6 @@
background: none;
}

#docs-root .docs-story > div > div[scale] {
padding: 48px 24px;
}

#docs-root .docs-story > div:last-child {
right: 31px;
border-radius: 24px;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "chore(react-components): Theme picker for storybook `--docs` mode",
"packageName": "@fluentui/react-components",
"email": "lingfangao@hotmail.com",
"dependentChangeType": "none"
}
3 changes: 2 additions & 1 deletion packages/react-components/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as rootPreview from '../../../.storybook/preview';
// import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer.stories';
import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer.stories';
import { FluentDocsPage } from '../src/DocsComponents/FluentDocsPage.stories';

// load global styles
Expand Down Expand Up @@ -30,6 +30,7 @@ export const parameters = {
...rootPreview.parameters,
docs: {
...rootPreview.parameters.docs,
container: FluentDocsContainer,
page: FluentDocsPage,
// container: FluentDocsContainer,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import * as React from 'react';
import { DocsContainer, DocsContainerProps } from '@storybook/addon-docs';
import { DocsContainer, DocsContextProps } from '@storybook/addon-docs';
import { FluentStoryContext, THEME_ID, themes } from '@fluentui/react-storybook-addon';
import { FluentDocsHeader } from './FluentDocsHeader.stories';
import { FluentProvider, webLightTheme } from '../index';

interface FluentDocsContainerProps {
context: FluentStoryContext & DocsContextProps;
}

/**
* A container that wraps storybook's native docs container to add extra components to the docs experience
*/
export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => {
export const FluentDocsContainer: React.FC<FluentDocsContainerProps> = ({ children, context }) => {
const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]);

return (
<>
<FluentDocsHeader />
<FluentProvider theme={selectedTheme?.theme ?? webLightTheme}>
<FluentDocsHeader storybookGlobals={context.globals} />
</FluentProvider>
{/** TODO add table of contents */}
<DocsContainer context={context}>{children}</DocsContainer>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import * as React from 'react';
import { FluentGlobals, THEME_ID } from '@fluentui/react-storybook-addon';
import { makeStyles } from '../index';
import { ThemePicker } from './ThemePicker.stories';

const useStyles = makeStyles({
root: {
position: 'sticky',
root: theme => ({
position: 'fixed',
top: 0,
padding: '5px',
},
width: '100%',
background: theme.colorNeutralBackground3,
boxShadow: `${theme.shadow8}`,
borderBottom: `1px solid ${theme.colorTransparentStroke}`,
zIndex: 1000,
}),
});

/**
* Sticky header over the entire docs page
*/
export const FluentDocsHeader = () => {
export const FluentDocsHeader: React.FC<{ storybookGlobals: FluentGlobals }> = ({ storybookGlobals }) => {
const styles = useStyles();
return <div className={styles.root}>{/** TODO add theme+version picker */}</div>;
return (
<div className={styles.root}>
<ThemePicker selectedThemeId={storybookGlobals[THEME_ID]} />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as React from 'react';
import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles, MenuProps } from '../index';
import { themes, ThemeIds, THEME_ID } from '@fluentui/react-storybook-addon';
import addons from '@storybook/addons';

const useStyles = makeStyles({
menuButton: {
minWidth: '210px',
justifyContent: 'flex-start',
},

chevronIcon: {
marginLeft: 'auto',
},

menuPopover: {
minWidth: '210px',
},
});

/**
* Theme picker used in the react-components docs header
*/
export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedThemeId }) => {
const styles = useStyles();

const setGlobalTheme = (themeId: ThemeIds): void => {
addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } });
};
const onCheckedValueChange: MenuProps['onCheckedValueChange'] = (e, data) => {
setGlobalTheme(data.checkedItems[0] as ThemeIds);
};

const selectedTheme = themes.find(theme => theme.id === selectedThemeId);

return (
<Menu
onCheckedValueChange={onCheckedValueChange}
checkedValues={{ theme: selectedThemeId ? [selectedThemeId] : [] }}
>
<MenuTrigger>
<MenuButton className={styles.menuButton} menuIcon={{ className: styles.chevronIcon }}>
{selectedTheme?.label ?? 'Theme'}
</MenuButton>
</MenuTrigger>
<MenuPopover className={styles.menuPopover}>
<MenuList>
{themes.map(theme => (
<MenuItemRadio name="theme" value={theme.id} key={theme.id}>
{theme.label}
</MenuItemRadio>
))}
</MenuList>
</MenuPopover>
</Menu>
);
};
30 changes: 30 additions & 0 deletions packages/react-storybook-addon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,36 @@ These are not production-ready components and **should never be used in product*
- adds fluent theme switcher
- ![Fluent Theme Switcher](https://user-images.githubusercontent.com/20744592/138872560-8ef40c25-193c-47db-a216-7c1e86fe8cda.png)

**Theme management in storybook globals**

Exports types and utilities to set and consume the correct Fluent theme in storybook globals. Here's some example picker
that sets the Fluent them in storybook globals.

```tsx
import * as React from 'react';
import { themes, setGlobalTheme, FluentStoryContext, THEME_ID } from '@fluentui/react-storybook-addon';

// storybook context which can be accessed for example in decorators
// https://storybook.js.org/docs/react/writing-stories/decorators#context-for-mocking
export const ThemePicker: React.FC<{ context: FluentStoryContext }> = ({ context }) => {
const handleChange = e => {
setGlobalTheme(e.target.value);
};

const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]);

return (
<select onChange={handleChange}>
{themes.map(theme => (
<option selected={selectedTheme.id === theme.id} value={theme.id}>
{theme.label}
</option>
))}
</select>
);
};
```

## Getting Started

### Installation
Expand Down
49 changes: 47 additions & 2 deletions packages/react-storybook-addon/etc/react-storybook-addon.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,54 @@

```ts

import { Args } from '@storybook/api';
import { StoryContext } from '@storybook/addons';
import type { Theme } from '@fluentui/react-theme';

// @public
export interface FluentGlobals extends Args {
// (undocumented)
[THEME_ID]?: ThemeIds;
}

// @public (undocumented)
export interface FluentStoryContext extends StoryContext {
// (undocumented)
globals: FluentGlobals;
}

// @public (undocumented)
export const THEME_ID: "storybook/fluentui-react-addon/theme";

// @public (undocumented)
export type ThemeIds = typeof themes[number]['id'];

// @public (undocumented)
const _default: {};
export default _default;
export const themes: readonly [{
readonly id: "web-light";
readonly label: "Web Light";
readonly theme: Theme;
}, {
readonly id: "web-dark";
readonly label: "Web Dark";
readonly theme: Theme;
}, {
readonly id: "web-high-contrast";
readonly label: "Web High Contrast";
readonly theme: Theme;
}, {
readonly id: "teams-light";
readonly label: "Teams Light";
readonly theme: Theme;
}, {
readonly id: "teams-dark";
readonly label: "Teams Dark";
readonly theme: Theme;
}, {
readonly id: "teams-high-contrast";
readonly label: "Teams High Contrast";
readonly theme: Theme;
}];

// (No @packageDocumentation comment for this package)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ export const withFluentProvider = (StoryFn: StoryFunction<React.ReactElement>, c
const FluentExampleContainer: React.FC<{ theme: Theme }> = props => {
const { theme } = props;

const backgroundColor = theme.colorNeutralBackground1;
return <div style={{ padding: 10, backgroundColor: backgroundColor }}>{props.children}</div>;
const backgroundColor = theme.colorNeutralBackground2;
return <div style={{ padding: '48px 24px', backgroundColor: backgroundColor }}>{props.children}</div>;
};
4 changes: 3 additions & 1 deletion packages/react-storybook-addon/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export default {};
export type { FluentGlobals, FluentStoryContext } from './hooks';
export { themes, ThemeIds } from './theme';
export { THEME_ID } from './constants';