- Addons can gather details about how a story is rendered. This is
- panel uses a tab pattern. Click the button below to fetch data for
- the other two tabs.
+ Addons can gather details about how a story is rendered. This is panel uses a tab pattern. Click the
+ button below to fetch data for the other two tabs.
-
- Request data
-
+ Request data
diff --git a/src/components/Tab.tsx b/src/components/Tab.tsx
index 42a3ef4..76dffa9 100644
--- a/src/components/Tab.tsx
+++ b/src/components/Tab.tsx
@@ -1,34 +1,31 @@
-import { LightningIcon } from "@storybook/icons";
-import React, { useCallback } from "react";
-import { Code, H1, IconButton, Link } from "storybook/internal/components";
-import { useGlobals, useParameter } from "storybook/manager-api";
-import { styled } from "storybook/theming";
+import { LightningIcon } from '@storybook/icons';
+import React, { useCallback } from 'react';
+import { Code, H1, IconButton, Link } from 'storybook/internal/components';
+import { useGlobals, useParameter } from 'storybook/manager-api';
+import { styled } from 'storybook/theming';
-import { KEY } from "../constants";
+import { KEY } from '../constants';
interface TabProps {
- active: boolean;
+ active?: boolean;
}
const TabWrapper = styled.div(({ theme }) => ({
background: theme.background.content,
- padding: "4rem 20px",
- minHeight: "100vh",
- boxSizing: "border-box",
+ padding: '4rem 20px',
+ minHeight: '100vh',
+ boxSizing: 'border-box',
}));
const TabInner = styled.div({
maxWidth: 768,
- marginLeft: "auto",
- marginRight: "auto",
+ marginLeft: 'auto',
+ marginRight: 'auto',
});
export const Tab: React.FC = ({ active }) => {
// https://storybook.js.org/docs/react/addons/addons-api#useparameter
- const config = useParameter(
- KEY,
- "fallback value of config from parameter",
- );
+ const config = useParameter(KEY, 'fallback value of config from parameter');
// https://storybook.js.org/docs/addons/addons-api#useglobals
const [globals, updateGlobals] = useGlobals();
@@ -50,19 +47,16 @@ export const Tab: React.FC = ({ active }) => {
My Addon ({KEY})
Your addon can create a custom tab in Storybook.
- You have full control over what content is being rendered here. You
- can use components from{" "}
+ You have full control over what content is being rendered here. You can use components from{' '}
storybook/internal/components
- {" "}
- to match the look and feel of Storybook, for example the{" "}
- <Code /> component below. Or build a completely
- custom UI.
+ {' '}
+ to match the look and feel of Storybook, for example the <Code /> component below. Or build
+ a completely custom UI.
{config}
- You can also have interactive UI here, like a button that updates a
- global:{" "}
+ You can also have interactive UI here, like a button that updates a global:{' '}
{
diff --git a/src/components/Tool.tsx b/src/components/Tool.tsx
index 082bba9..e908a97 100644
--- a/src/components/Tool.tsx
+++ b/src/components/Tool.tsx
@@ -1,8 +1,8 @@
-import React, { memo, useCallback, useEffect } from "react";
-import { useGlobals, type API } from "storybook/manager-api";
-import { IconButton } from "storybook/internal/components";
-import { ADDON_ID, KEY, TOOL_ID } from "../constants";
-import { LightningIcon } from "@storybook/icons";
+import React, { memo, useCallback, useEffect } from 'react';
+import { useGlobals, type API } from 'storybook/manager-api';
+import { IconButton } from 'storybook/internal/components';
+import { ADDON_ID, KEY, TOOL_ID } from '../constants';
+import { LightningIcon } from '@storybook/icons';
export const Tool = memo(function MyAddonSelector({ api }: { api: API }) {
const [globals, updateGlobals, storyGlobals] = useGlobals();
@@ -18,22 +18,16 @@ export const Tool = memo(function MyAddonSelector({ api }: { api: API }) {
useEffect(() => {
api.setAddonShortcut(ADDON_ID, {
- label: "Toggle Measure [O]",
- defaultShortcut: ["O"],
- actionName: "outline",
+ label: 'Toggle Measure [O]',
+ defaultShortcut: ['O'],
+ actionName: 'outline',
showInMenu: false,
action: toggle,
});
}, [toggle, api]);
return (
-
+
);
diff --git a/src/constants.ts b/src/constants.ts
index 72e975a..6a7c974 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,4 +1,4 @@
-export const ADDON_ID = "my-addon";
+export const ADDON_ID = 'my-addon';
export const TOOL_ID = `${ADDON_ID}/tool`;
export const PANEL_ID = `${ADDON_ID}/panel`;
export const TAB_ID = `${ADDON_ID}/tab`;
diff --git a/src/index.ts b/src/index.ts
index dafa948..33db1c1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,2 +1,5 @@
-// make it work with --isolatedModules
-export default {};
+import { definePreviewAddon } from 'storybook/internal/csf';
+
+import addonAnnotations from './preview';
+
+export default () => definePreviewAddon(addonAnnotations);
diff --git a/src/manager-helpers.tsx b/src/manager-helpers.tsx
new file mode 100644
index 0000000..94a18c6
--- /dev/null
+++ b/src/manager-helpers.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import type { API_HashEntry } from 'storybook/internal/types';
+import { ADDON_ID } from './constants';
+
+/**
+ * This opt-in helper can be manually imported by your users who want to
+ * use it, and ignored by those who don't.
+ */
+export function renderLabel(item: API_HashEntry) {
+ if (item.type !== 'story' && item.type !== 'docs') {
+ return;
+ }
+
+ if (item.title.startsWith(ADDON_ID)) {
+ return š {item.name};
+ }
+}
diff --git a/src/manager.tsx b/src/manager.tsx
index db55a1f..79fec63 100644
--- a/src/manager.tsx
+++ b/src/manager.tsx
@@ -1,10 +1,10 @@
-import React from "react";
-import { addons, types } from "storybook/manager-api";
+import React from 'react';
+import { addons, types } from 'storybook/manager-api';
-import { Panel } from "./components/Panel";
-import { Tab } from "./components/Tab";
-import { Tool } from "./components/Tool";
-import { ADDON_ID, PANEL_ID, TAB_ID, TOOL_ID } from "./constants";
+import { Panel } from './components/Panel';
+import { Tab } from './components/Tab';
+import { Tool } from './components/Tool';
+import { ADDON_ID, PANEL_ID, TAB_ID, TOOL_ID } from './constants';
/**
* Note: if you want to use JSX in this file, rename it to `manager.tsx`
@@ -16,24 +16,23 @@ addons.register(ADDON_ID, (api) => {
// Register a tool
addons.add(TOOL_ID, {
type: types.TOOL,
- title: "My addon",
- match: ({ viewMode, tabId }) =>
- !!((viewMode && viewMode.match(/^(story)$/)) || tabId === TAB_ID),
+ title: 'My addon',
+ match: ({ viewMode, tabId }) => !!((viewMode && viewMode.match(/^(story)$/)) || tabId === TAB_ID),
render: () => ,
});
// Register a panel
addons.add(PANEL_ID, {
type: types.PANEL,
- title: "My addon",
- match: ({ viewMode }) => viewMode === "story",
+ title: 'My addon',
+ match: ({ viewMode }) => viewMode === 'story',
render: ({ active }) => ,
});
// Register a tab
addons.add(TAB_ID, {
type: types.TAB,
- title: "My addon",
+ title: 'My addon',
render: ({ active }) => ,
});
});
diff --git a/src/preset.ts b/src/preset.ts
index a92f950..bc8e17e 100644
--- a/src/preset.ts
+++ b/src/preset.ts
@@ -3,12 +3,12 @@
// so often you want to delete this file and remove the reference to it in package.json#exports and package.json#bunder.nodeEntries
// Read more about presets at https://storybook.js.org/docs/addons/writing-presets
-export const viteFinal = async (config: any) => {
- console.log("This addon is augmenting the Vite config");
+export const viteFinal = async (config: unknown) => {
+ console.log('This addon is augmenting the Vite config');
return config;
};
-export const webpack = async (config: any) => {
- console.log("This addon is augmenting the Webpack config");
+export const webpack = async (config: unknown) => {
+ console.log('This addon is augmenting the Webpack config');
return config;
};
diff --git a/src/preview.ts b/src/preview.ts
index b71d09f..56001b2 100644
--- a/src/preview.ts
+++ b/src/preview.ts
@@ -8,11 +8,11 @@
*
* https://storybook.js.org/docs/react/writing-stories/decorators
*/
-import type { ProjectAnnotations, Renderer } from "storybook/internal/types";
+import type { ProjectAnnotations, Renderer } from 'storybook/internal/types';
-import { KEY } from "./constants";
-import { withGlobals } from "./withGlobals";
-import { withRoundTrip } from "./withRoundTrip";
+import { KEY } from './constants';
+import { withGlobals } from './withGlobals';
+import { withRoundTrip } from './withRoundTrip';
/**
* Note: if you want to use JSX in this file, rename it to `preview.tsx`
diff --git a/src/stories/Button.stories.ts b/src/stories/Button.stories.ts
index 38c379d..8def24d 100644
--- a/src/stories/Button.stories.ts
+++ b/src/stories/Button.stories.ts
@@ -1,20 +1,20 @@
-import type { Meta, StoryObj } from "@storybook/react-vite";
+import type { Meta, StoryObj } from '@storybook/react-vite';
-import { Button } from "./Button";
-import { fn } from "storybook/test";
+import { Button } from './Button';
+import { fn } from 'storybook/test';
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta: Meta = {
- title: "Example/Button",
+ title: 'Example/Button',
component: Button,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {
- backgroundColor: { control: "color" },
+ backgroundColor: { control: 'color' },
},
args: {
onClick: fn(),
},
- tags: ["autodocs"],
+ tags: ['autodocs'],
parameters: {
myAddonParameter: `
@@ -32,26 +32,26 @@ export const Primary: Story = {
// More on args: https://storybook.js.org/docs/react/writing-stories/args
args: {
primary: true,
- label: "Button",
+ label: 'Button',
},
};
export const Secondary: Story = {
args: {
- label: "Button",
+ label: 'Button',
},
};
export const Large: Story = {
args: {
- size: "large",
- label: "Button",
+ size: 'large',
+ label: 'Button',
},
};
export const Small: Story = {
args: {
- size: "small",
- label: "Button",
+ size: 'small',
+ label: 'Button',
},
};
diff --git a/src/stories/Button.tsx b/src/stories/Button.tsx
index c33be6e..66f8fd3 100644
--- a/src/stories/Button.tsx
+++ b/src/stories/Button.tsx
@@ -27,13 +27,7 @@ interface ButtonProps {
/**
* Primary UI component for user interaction
*/
-export const Button = ({
- primary = false,
- size = 'medium',
- backgroundColor,
- label,
- ...props
-}: ButtonProps) => {
+export const Button = ({ primary = false, size = 'medium', backgroundColor, label, ...props }: ButtonProps) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (