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

API: Remove deprecations from manager and preview api #25536

Merged
merged 6 commits into from
Jan 10, 2024
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
37 changes: 37 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
- [Web Components](#web-components)
- [Dropping default babel plugins in Webpack5-based projects](#dropping-default-babel-plugins-in-webpack5-based-projects)
- [Deprecations which are now removed](#deprecations-which-are-now-removed)
- [Methods and properties from AddonStore](#methods-and-properties-from-addonstore)
- [Methods and properties from PreviewAPI](#methods-and-properties-from-previewapi)
- [Removals in @storybook/types](#removals-in-storybooktypes)
- [--use-npm flag in storybook CLI](#--use-npm-flag-in-storybook-cli)
- [`setGlobalConfig` from `@storybook/react`](#setglobalconfig-from-storybookreact)
- [StorybookViteConfig type from @storybook/builder-vite](#storybookviteconfig-type-from-storybookbuilder-vite)
Expand Down Expand Up @@ -790,6 +793,40 @@ Until the 8.0 release, Storybook provided the `@babel/preset-env` preset for Web

### Deprecations which are now removed

#### Methods and properties from AddonStore

The following methods and properties from the class `AddonStore` in `@storybook/manager-api` are now removed:

- `serverChannel` -> Use `channel` instead
- `getServerChannel` -> Use `getChannel` instead
- `setServerChannel` -> Use `setChannel` instead
- `hasServerChannel` -> Use `hasChannel` instead
- `addPanel`

The following methods and properties from the class `AddonStore` in `@storybook/preview-api` are now removed:

- `serverChannel` -> Use `channel` instead
- `getServerChannel` -> Use `getChannel` instead
- `setServerChannel` -> Use `setChannel` instead
- `hasServerChannel` -> Use `hasChannel` instead

#### Methods and properties from PreviewAPI

The following exports from `@storybook/preview-api` are now removed:

- `useSharedState`
- `useAddonState`

Please file an issue if you need these APIs.

#### Removals in @storybook/types

The following exports from `@storybook/types` are now removed:

- `API_ADDON` -> Use `Addon_Type` instead
- `API_COLLECTION` -> Use `Addon_Collection` instead
- `API_Panels`

#### --use-npm flag in storybook CLI

The `--use-npm` is now removed. Use `--package-manager=npm` instead. [More info here](#cli-option---use-npm-deprecated).
Expand Down
69 changes: 5 additions & 64 deletions code/lib/manager-api/src/lib/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ export function isSupportedType(type: Addon_Types): boolean {
return !!Object.values(Addon_TypesEnum).find((typeVal) => typeVal === type);
}

interface DeprecatedAddonWithId {
/**
* @deprecated will be removed in 8.0, when registering addons, please use the addon id as the first argument
*/
id?: string;
}

export class AddonStore {
constructor() {
this.promise = new Promise((res) => {
Expand All @@ -49,11 +42,6 @@ export class AddonStore {

private channel: Channel | undefined;

/**
* @deprecated will be removed in 8.0
*/
private serverChannel: Channel | undefined;

private promise: any;

private resolve: any;
Expand All @@ -67,38 +55,15 @@ export class AddonStore {
return this.channel!;
};

/**
* @deprecated will be removed in 8.0, use getChannel instead
*/
getServerChannel = (): Channel => {
if (!this.serverChannel) {
throw new Error('Accessing non-existent serverChannel');
}

return this.serverChannel;
};

ready = (): Promise<Channel> => this.promise;

hasChannel = (): boolean => !!this.channel;

/**
* @deprecated will be removed in 8.0, please use the normal channel instead
*/
hasServerChannel = (): boolean => !!this.serverChannel;

setChannel = (channel: Channel): void => {
this.channel = channel;
this.resolve();
};

/**
* @deprecated will be removed in 8.0, please use the normal channel instead
*/
setServerChannel = (channel: Channel): void => {
this.serverChannel = channel;
};

getElements<
T extends
| Addon_Types
Expand All @@ -112,30 +77,6 @@ export class AddonStore {
return this.elements[type];
}

/**
* Adds a panel to the addon store.
* @param {string} id - The id of the panel.
* @param {Addon_Type} options - The options for the panel.
* @returns {void}
*
* @deprecated Use the 'add' method instead.
* @example
* addons.add('My Panel', {
* title: 'My Title',
* type: types.PANEL,
* render: () => <div>My Content</div>,
* });
*/
addPanel = (
id: string,
options: Omit<Addon_BaseType, 'type' | 'id'> & DeprecatedAddonWithId
): void => {
this.add(id, {
type: Addon_TypesEnum.PANEL,
...options,
});
};

/**
* Adds an addon to the addon store.
* @param {string} id - The id of the addon.
Expand All @@ -146,14 +87,14 @@ export class AddonStore {
id: string,
addon:
| Addon_BaseType
| (Omit<Addon_SidebarTopType, 'id'> & DeprecatedAddonWithId)
| (Omit<Addon_SidebarBottomType, 'id'> & DeprecatedAddonWithId)
| (Omit<Addon_PageType, 'id'> & DeprecatedAddonWithId)
| (Omit<Addon_WrapperType, 'id'> & DeprecatedAddonWithId)
| Omit<Addon_SidebarTopType, 'id'>
| Omit<Addon_SidebarBottomType, 'id'>
| Omit<Addon_PageType, 'id'>
| Omit<Addon_WrapperType, 'id'>
): void {
const { type } = addon;
const collection = this.getElements(type);
collection[id] = { id, ...addon };
collection[id] = { ...addon, id };
}

setConfig = (value: Addon_Config) => {
Expand Down
47 changes: 6 additions & 41 deletions code/lib/manager-api/src/modules/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type {
Addon_Collection,
Addon_Types,
Addon_TypesMapping,
API_Panels,
API_StateMerger,
} from '@storybook/types';
import { Addon_TypesEnum } from '@storybook/types';
Expand All @@ -21,7 +20,7 @@ export interface SubAPI {
* @protected This is used internally in storybook's manager.
* @template T - The type of the elements in the collection.
* @param {Addon_Types | Addon_TypesEnum.experimental_PAGE} type - The type of the elements to retrieve.
* @returns {API_Collection<T>} - A collection of elements of the specified type.
* @returns {Addon_Collection<T>} - A collection of elements of the specified type.
*/
getElements: <
T extends
Expand All @@ -32,21 +31,6 @@ export interface SubAPI {
>(
type: T
) => Addon_Collection<Addon_TypesMapping[T]>;
/**
* Returns a collection of all panels.
* This is the same as calling getElements('panel')
* @protected This is used internally in storybook's manager.
* @deprecated please use getElements('panel') instead. This API will be removed in storybook 8.0.
* @returns {API_Panels} - A collection of all panels.
*/
getPanels: () => API_Panels;
/**
* Returns a collection of panels currently enabled for the selected story.
* @protected This is used internally in storybook's manager.
* @deprecated please use getElements('panel') instead, and do the filtering manually. This API will be removed in storybook 8.0.
* @returns {API_Panels} - A collection of all panels.
*/
getStoryPanels: () => API_Panels;
/**
* Returns the id of the currently selected panel.
* @returns {string} - The ID of the currently selected panel.
Expand Down Expand Up @@ -82,7 +66,11 @@ export interface SubAPI {
getAddonState<S>(addonId: string): S;
}

export function ensurePanel(panels: API_Panels, selectedPanel?: string, currentPanel?: string) {
export function ensurePanel(
panels: Addon_Collection<Addon_BaseType>,
selectedPanel?: string,
currentPanel?: string
) {
const keys = Object.keys(panels);

if (keys.indexOf(selectedPanel!) >= 0) {
Expand All @@ -98,29 +86,6 @@ export function ensurePanel(panels: API_Panels, selectedPanel?: string, currentP
export const init: ModuleFn<SubAPI, SubState> = ({ provider, store, fullAPI }): any => {
const api: SubAPI = {
getElements: (type) => provider.getElements(type),
getPanels: () => api.getElements(Addon_TypesEnum.PANEL),
getStoryPanels: () => {
const allPanels = api.getElements(Addon_TypesEnum.PANEL);
const { storyId } = store.getState();
const story = fullAPI.getData(storyId);

if (!allPanels || !story || story.type !== 'story') {
return allPanels;
}

const { parameters } = story;

const filteredPanels: Addon_Collection<Addon_BaseType> = {};
Object.entries(allPanels).forEach(([id, panel]) => {
const { paramKey }: any = panel;
if (paramKey && parameters && parameters[paramKey] && parameters[paramKey].disable) {
return;
}
filteredPanels[id] = panel;
});

return filteredPanels;
},
getSelectedPanel: (): any => {
const { selectedPanel } = store.getState();
return ensurePanel(api.getElements(Addon_TypesEnum.PANEL), selectedPanel, selectedPanel);
Expand Down
62 changes: 0 additions & 62 deletions code/lib/manager-api/src/tests/addons.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,68 +47,6 @@ describe('Addons API', () => {
});
});

describe('#getPanels', () => {
it('should return provider panels', () => {
// given
const { api } = initAddons({ provider, store });

// when
const panels = api.getPanels();

// then
expect(panels).toBe(PANELS);
});
});

describe('#getStoryPanels', () => {
it('should return all panels by default', () => {
// given
const { api } = initAddons({ provider, store, fullAPI: { getData: () => undefined } });

// when
const filteredPanels = api.getStoryPanels();

// then
expect(filteredPanels).toBe(PANELS);
});

it('should filter disabled addons', () => {
// given
const storyId = 'story 1';
const storiesHash = {
[storyId]: {
type: 'story',
parameters: {
a11y: { disable: true },
},
},
};

const storeWithStory = {
getState: () => ({
storyId,
storiesHash,
}),
setState: vi.fn(),
};

const { api } = initAddons({
provider,
store: storeWithStory,
fullAPI: { getData: (id) => storiesHash[id] },
});

// when
const filteredPanels = api.getStoryPanels();

// then
expect(filteredPanels).toEqual({
actions: PANELS.actions,
knobs: PANELS.knobs,
});
});
});

describe('#getSelectedPanel', () => {
it('should return provider panels', () => {
// given
Expand Down
28 changes: 0 additions & 28 deletions code/lib/preview-api/src/modules/addons/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ export class AddonStore {

private channel: Channel | undefined;

/**
* @deprecated will be removed in 8.0, please use channel instead
*/
private serverChannel: Channel | undefined;

private promise: any;

private resolve: any;
Expand All @@ -32,37 +27,14 @@ export class AddonStore {
return this.channel;
};

/**
* @deprecated will be removed in 8.0, please use getChannel instead
*/
getServerChannel = (): Channel => {
if (!this.serverChannel) {
throw new Error('Accessing non-existent serverChannel');
}

return this.serverChannel;
};

ready = (): Promise<Channel> => this.promise;

hasChannel = (): boolean => !!this.channel;

/**
* @deprecated will be removed in 8.0, please use the normal channel instead
*/
hasServerChannel = (): boolean => !!this.serverChannel;

setChannel = (channel: Channel): void => {
this.channel = channel;
this.resolve();
};

/**
* @deprecated will be removed in 8.0, please use the normal channel instead
*/
setServerChannel = (channel: Channel): void => {
this.serverChannel = channel;
};
}

// Enforce addons store to be a singleton
Expand Down
3 changes: 0 additions & 3 deletions code/lib/preview-api/src/modules/preview-web/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ export class Preview<TRenderer extends Renderer> {
previewEntryError?: Error;

constructor(protected channel: Channel = addons.getChannel()) {
if (addons.hasServerChannel()) {
this.serverChannel = addons.getServerChannel();
}
this.storyStore = new StoryStore();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { describe, beforeEach, it, expect, vi } from 'vitest';
import React from 'react';
import { global } from '@storybook/global';
import type { RenderContext } from '@storybook/types';
import { addons, mockChannel as createMockChannel } from '../addons';
import { addons } from '../addons';

import { PreviewWeb } from './PreviewWeb';
import { WebView } from './WebView';
Expand Down Expand Up @@ -67,7 +67,6 @@ beforeEach(() => {
// projectAnnotations.parameters.docs.renderer = () => new DocsRenderer() as any;

addons.setChannel(mockChannel as any);
addons.setServerChannel(createMockChannel());

vi.mocked(WebView.prototype).prepareForDocs.mockReturnValue('docs-element' as any);
vi.mocked(WebView.prototype).prepareForStory.mockReturnValue('story-element' as any);
Expand Down
Loading