= ({ children, context }) => {
+ const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]);
+
return (
<>
-
+
+
+
{/** TODO add table of contents */}
{children}
>
diff --git a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx
index b4f976813cb46b..c452fd98bd4f1c 100644
--- a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx
+++ b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx
@@ -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 {/** TODO add theme+version picker */}
;
+ return (
+
+
+
+ );
};
diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx
new file mode 100644
index 00000000000000..34e2079da0e4fa
--- /dev/null
+++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx
@@ -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 (
+
+ );
+};
diff --git a/packages/react-storybook-addon/README.md b/packages/react-storybook-addon/README.md
index 9a052541499df5..9bd2f2410b30d5 100644
--- a/packages/react-storybook-addon/README.md
+++ b/packages/react-storybook-addon/README.md
@@ -11,6 +11,36 @@ These are not production-ready components and **should never be used in product*
- adds fluent theme switcher
- 
+**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 (
+
+ );
+};
+```
+
## Getting Started
### Installation
diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md
index 4d5ec18c6dbadc..b1244a204d005a 100644
--- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md
+++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md
@@ -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)
diff --git a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx
index c520b7dde643a3..11f8b5a83c8101 100644
--- a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx
+++ b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx
@@ -27,6 +27,6 @@ export const withFluentProvider = (StoryFn: StoryFunction, c
const FluentExampleContainer: React.FC<{ theme: Theme }> = props => {
const { theme } = props;
- const backgroundColor = theme.colorNeutralBackground1;
- return {props.children}
;
+ const backgroundColor = theme.colorNeutralBackground2;
+ return {props.children}
;
};
diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts
index ff8b4c56321a33..3da679ee45e465 100644
--- a/packages/react-storybook-addon/src/index.ts
+++ b/packages/react-storybook-addon/src/index.ts
@@ -1 +1,3 @@
-export default {};
+export type { FluentGlobals, FluentStoryContext } from './hooks';
+export { themes, ThemeIds } from './theme';
+export { THEME_ID } from './constants';