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

Chore: (Docs) Tweaks to the Addon API documentation #21928

Merged
merged 1 commit into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
285 changes: 136 additions & 149 deletions docs/addons/addons-api.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/snippets/common/args-usage-with-addons.js.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
```js
// your-addon/manager.js
// my-addon/src/manager.js|ts

import { useArgs } from '@storybook/manager-api';

Expand Down
9 changes: 3 additions & 6 deletions docs/snippets/common/storybook-addon-panel-initial.js.mdx
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
```js
// .storybook/my-addon/manager.js
// my-addon/src/manager.js|ts

import React from 'react';

import { addons, types } from '@storybook/manager-api';
import { addons, types } from '@storybook/preview-api';

import { AddonPanel } from '@storybook/components';

const ADDON_ID = 'myaddon';
const PANEL_ID = `${ADDON_ID}/panel`;

// give a unique name for the panel
const MyPanel = () => <div>MyAddon</div>;

addons.register(ADDON_ID, (api) => {
addons.add(PANEL_ID, {
type: types.PANEL,
title: 'My Addon',
render: ({ active, key }) => (
<AddonPanel active={active} key={key}>
<MyPanel />
<div> Storybook addon panel </div>
</AddonPanel>
),
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.setQueryParams({
bbc: null,
exampleParameter: null,
});
});
```
41 changes: 41 additions & 0 deletions docs/snippets/common/storybook-addons-api-getchannel.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
```js
// my-addon/src/manager.js|ts

import React, { useCallback } from 'react';

import { FORCE_RE_RENDER } from '@storybook/core-events';

import { addons } from '@storybook/preview-api';

import { useGlobals } from '@storybook/manager-api';

import { IconButton, Icons } from '@storybook/components';

const ExampleToolbar = () => {
const [globals, updateGlobals] = useGlobals();

const isActive = globals['my-param-key'] || false;

// Function that will update the global value and trigger a UI refresh.
const refreshAndUpdateGlobal = () => {
updateGlobals({
['my-param-key']: !isActive,
}),
// Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
addons.getChannel().emit(FORCE_RE_RENDER);
};

const toggleToolbarAddon = useCallback(() => refreshAndUpdateGlobal(), [isActive]);

return (
<IconButton
key="Example"
active={isActive}
title="Show the toolbar addon"
onClick={toggleToolbarAddon}
>
<Icons icon="outline" />
</IconButton>
);
};
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.getQueryParam('bbc');
api.getQueryParam('exampleParameter');
});
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
const href = api.getUrlState({
Expand Down
4 changes: 3 additions & 1 deletion docs/snippets/common/storybook-addons-api-imports.js.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
```js
// .storybook/my-addon/manager.js
// my-addon/src/manager.js|ts

import { addons } from '@storybook/preview-api';

import { useStorybookApi } from '@storybook/manager-api';
```
24 changes: 12 additions & 12 deletions docs/snippets/common/storybook-addons-api-makedecorator.js.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
```js
// .storybook/my-addon/manager.js
// my-addon/src/decorator.js|ts

import { makeDecorator } from '@storybook/preview-api';

export makeDecorator({
export const withAddonDecorator = makeDecorator({
name: 'withSomething',
parameterName: 'something',
wrapper: (storyFn, context, { parameters }) => {
// Do something with `parameters`, which are set via { something: ... }

// Note you may alter the story output if you like.
// Although generally that's not advised.

return storyFn(context);
}
})
parameterName: 'CustomParameter',
skipIfNoParametersOrOptions: true
wrapper: (getStory, context, { parameters }) => {
/*
* Write your custom logic here based on the parameters passed in Storybook's stories.
* Although not advised, you can also alter the story output based on the parameters.
*/
return getStory(context);
},
});
```
5 changes: 3 additions & 2 deletions docs/snippets/common/storybook-addons-api-on.js.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.on('some-event', (eventData) => console.log(eventData));
// Logs the event data to the browser console whenever the event is emitted.
api.on('custom-addon-event', (eventData) => console.log(eventData));
});
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
```js
// .storybook/my-addon/manager.js
// my-addon/src/manager.js|ts

import { addons } from '@storybook/preview-api';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.selectInCurrentKind('Basic');
api.selectInCurrentKind('Default');
});
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.selectStory('Button', 'Basic');
api.selectStory('Button', 'Default');
});
```
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

addons.register('my-organisation/my-addon', (api) => {
api.setQueryParams({
abc: 'this is abc',
bbc: 'this is bbc',
exampleParameter: 'Sets the example parameter value',
anotherParameter: 'Sets the another parameter value',
});
});
```
27 changes: 22 additions & 5 deletions docs/snippets/common/storybook-addons-api-useaddonstate.js.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
```js
// /my-addon/manager.js
// my-addon/manager.js|ts

import React from 'react';

import { useAddonState } from '@storybook/manager-api';

import { AddonPanel, Button, IconButton } from '@storybook/components';

export const Panel = () => {
const [state, setState] = useAddonState('my/addon-id', 'initial state');
const [state, setState] = useAddonState('addon-unique-identifier', 'initial state');

return <button onClick={() => setState('a new value')}>the state = "{state}"</button>;
return (
<AddonPanel key="custom-panel" active="true">
<Button onClick={() => setState('Example')}>
Click to update Storybook's internal state
</Button>
</AddonPanel>
);
};
export const Tool = () => {
const [state, setState] = useAddonState('my/addon-id', 'initial state');
const [state, setState] = useAddonState('addon-unique-identifier', 'initial state');

return <button onClick={() => setState('a new value')}>the state = "{state}"</button>;
return (
<IconButton
key="custom-toolbar"
active="true"
title="Enable my addon"
onClick={() => setState('Example')}
>
<Icons icon="lightning" />
</IconButton>
);
};
```
28 changes: 24 additions & 4 deletions docs/snippets/common/storybook-addons-api-useapi.js.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
```js
// /my-addon/manager.js
// my-addon/manager.js|ts

import React from 'react';
import React, { useEffect, useCallback } from 'react';

import { Icons, IconButton } from '@storybook/components';

import { useStorybookApi } from '@storybook/manager-api';

export const Panel = () => {
const state = useStorybookApi();
const api = useStorybookApi();

const toggleMyTool = useCallback(() => {
// Custom logic to toggle the addon here
}, []);

useEffect(() => {
api.setAddonShortcut('custom-toolbar-addon', {
label: 'Enable toolbar addon',
defaultShortcut: ['G'],
actionName: 'Toggle',
showInMenu: false,
action: toggleAddon,
});
}, [api]);

return <div>do something with storybook's api</div>;
return (
<IconButton key="custom-toolbar" active="true" title="Show a toolbar addon">
<Icons icon="arrowdown" />
</IconButton>
);
};
```
13 changes: 9 additions & 4 deletions docs/snippets/common/storybook-addons-api-usechannel.js.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
```js
// /my-addon/manager.js
// my-addon/manager.js|ts

import React from 'react';

import { AddonPanel, Button } from '@storybook/components';

import { STORY_CHANGED } from '@storybook/core-events';

export const Panel = () => {
// Creates a Storybook API channel and subscribes to the STORY_CHANGED event
const emit = useChannel({
STORY_CHANGED: (...args) => console.log(...args),
});

return (
<button onClick={() => emit('my-event-type', { some: 'data' })}>
clicking this will emit an event
</button>
<AddonPanel key="custom-panel" active="true">
<Button onClick={() => emit('my-event-type', { sampleData: 'example' })}>
Emit a Storybook API event with custom data
</Button>
</AddonPanel>
);
};
```
14 changes: 9 additions & 5 deletions docs/snippets/common/storybook-addons-api-useglobal.js.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
```js
// /my-addon/manager.js
// my-addon/manager.js|ts

import React from 'react';

import { AddonPanel, Button } from '@storybook/components';

import { useGlobals } from '@storybook/manager-api';

export const Panel = () => {
const [globals, updateGlobals] = useGlobals();

const isActive = globals['my-param-key'] || false;
const isActive = globals['my-param-key'] || false; // 👈 Sets visibility based on the global value.

return (
<button onClick={() => updateGlobals({ ['my-param-key']: !isActive })}>
{isActive ? 'Hide me!' : 'Show me!'}
</button>
<AddonPanel key="custom-panel" active={isActive}>
<Button onClick={() => updateGlobals({ ['my-param-key']: !isActive })}>
{isActive ? 'Hide the addon panel' : 'Show the panel'}
</Button>
</AddonPanel>
);
};
```
18 changes: 12 additions & 6 deletions docs/snippets/common/storybook-addons-api-useparameter.js.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
```js
// /my-addon/manager.js
// my-addon/manager.js|ts

import React from 'react';

import { AddonPanel } from '@storybook/components';

import { useParameter } from '@storybook/manager-api';

export const Panel = () => {
const value = useParameter('parameter-key', 'default value');
// Connects to Storybook's API and retrieves the value of the custom parameter for the current story
const value = useParameter('custom-parameter', 'initial value');

return (
<div>
for the currently selected story, the parameter for "parameter-key" is:
{value}
</div>
<AddonPanel key="custom-panel" active="true">
{value === 'initial value' ? (
<h2>The story doesn't contain custom parameters. Defaulting to the initial value.</h2>
) : (
<h2>You've set {value} as the parameter.</h2>
)}
</AddonPanel>
);
};
```
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
```js
// /my-addon/manager.js
// my-addon/src/manager.js|ts

import React from 'react';

import { AddonPanel } from '@storybook/components';

import { useStorybookState } from '@storybook/manager-api';

export const Panel = () => {
const state = useStorybookState();

return <div>do something with storybook's state</div>;
return (
<AddonPanel {...props}>
{state.viewMode !== 'docs' ? (
<h2>Do something with the documentation</h2>
) : (
<h2>Show the panel when viewing the story</h2>
)}
</AddonPanel>
);
};
```