Move away from abstract classes in favour of interfaces

This commit is contained in:
Tom Coleman 2022-11-04 13:56:51 +11:00
parent 4b481fb3f0
commit 8290a1678e
4 changed files with 20 additions and 23 deletions

View File

@ -1,11 +1,11 @@
import type { Store_SelectionSpecifier, Store_Selection } from '@storybook/types';
export abstract class SelectionStore {
public selectionSpecifier: Store_SelectionSpecifier | null = null;
export interface SelectionStore {
selectionSpecifier: Store_SelectionSpecifier | null;
public selection?: Store_Selection;
selection?: Store_Selection;
abstract setSelection(selection: Store_Selection): void;
setSelection(selection: Store_Selection): void;
abstract setQueryParams(queryParams: qs.ParsedQs): void;
setQueryParams(queryParams: qs.ParsedQs): void;
}

View File

@ -3,7 +3,7 @@ import qs from 'qs';
import type { ViewMode, Store_SelectionSpecifier, Store_Selection } from '@storybook/types';
import { parseArgsParam } from './parseArgsParam';
import { SelectionStore } from './SelectionStore';
import type { SelectionStore } from './SelectionStore';
const { history, document } = global;
@ -84,13 +84,12 @@ export const getSelectionSpecifierFromPath: () => Store_SelectionSpecifier | nul
return null;
};
export class UrlStore extends SelectionStore {
export class UrlStore implements SelectionStore {
selectionSpecifier: Store_SelectionSpecifier | null;
selection?: Store_Selection;
constructor() {
super();
this.selectionSpecifier = getSelectionSpecifierFromPath();
}

View File

@ -1,24 +1,24 @@
import type { Store_Story } from '@storybook/types';
export abstract class View<TStorybookRoot> {
export interface View<TStorybookRoot> {
// Get ready to render a story, returning the element to render to
abstract prepareForStory(story: Store_Story<any>): TStorybookRoot;
prepareForStory(story: Store_Story<any>): TStorybookRoot;
abstract prepareForDocs(): TStorybookRoot;
prepareForDocs(): TStorybookRoot;
abstract showErrorDisplay(err: { message?: string; stack?: string }): void;
showErrorDisplay(err: { message?: string; stack?: string }): void;
abstract showNoPreview(): void;
showNoPreview(): void;
abstract showPreparingStory(options: { immediate: boolean }): void;
showPreparingStory(options: { immediate: boolean }): void;
abstract showPreparingDocs(): void;
showPreparingDocs(): void;
abstract showMain(): void;
showMain(): void;
abstract showDocs(): void;
showDocs(): void;
abstract showStory(): void;
showStory(): void;
abstract showStoryDuringRender(): void;
showStoryDuringRender(): void;
}

View File

@ -5,7 +5,7 @@ import { dedent } from 'ts-dedent';
import qs from 'qs';
import type { Store_Story } from '@storybook/types';
import { View } from './View';
import type { View } from './View';
const { document } = global;
@ -37,7 +37,7 @@ const ansiConverter = new AnsiToHtml({
escapeXML: true,
});
export class WebView extends View<HTMLElement> {
export class WebView implements View<HTMLElement> {
private currentLayoutClass?: typeof layoutClassMap[keyof typeof layoutClassMap] | null;
private testing = false;
@ -45,8 +45,6 @@ export class WebView extends View<HTMLElement> {
private preparingTimeout?: ReturnType<typeof setTimeout>;
constructor() {
super();
// Special code for testing situations
// eslint-disable-next-line @typescript-eslint/naming-convention
const { __SPECIAL_TEST_PARAMETER__ } = qs.parse(document.location.search, {