diff --git a/code/addons/pseudo-states/src/constants.ts b/code/addons/pseudo-states/src/constants.ts index a01ae9a77340..6e169a007102 100644 --- a/code/addons/pseudo-states/src/constants.ts +++ b/code/addons/pseudo-states/src/constants.ts @@ -41,5 +41,3 @@ export const PSEUDO_STATES = { link: 'link', target: 'target', } as const; - -export type PseudoState = keyof typeof PSEUDO_STATES; diff --git a/code/addons/pseudo-states/src/index.ts b/code/addons/pseudo-states/src/index.ts index 40fcb0b5511a..b91e16697407 100644 --- a/code/addons/pseudo-states/src/index.ts +++ b/code/addons/pseudo-states/src/index.ts @@ -1,7 +1,10 @@ import { definePreviewAddon } from 'storybook/internal/csf'; import * as addonAnnotations from './preview'; +import type { PseudoTypes } from './types'; export { PARAM_KEY } from './constants'; -export default () => definePreviewAddon(addonAnnotations); +export type { PseudoTypes } from './types'; + +export default () => definePreviewAddon(addonAnnotations); diff --git a/code/addons/pseudo-states/src/preview/withPseudoState.ts b/code/addons/pseudo-states/src/preview/withPseudoState.ts index 75492b5684d3..25d8c8a92d97 100644 --- a/code/addons/pseudo-states/src/preview/withPseudoState.ts +++ b/code/addons/pseudo-states/src/preview/withPseudoState.ts @@ -12,18 +12,10 @@ import type { DecoratorFunction } from 'storybook/internal/types'; import { addons, useEffect, useMemo, useRef } from 'storybook/preview-api'; -import type { PseudoState } from '../constants'; import { PSEUDO_STATES } from '../constants'; +import type { PseudoParameter, PseudoState, PseudoStateConfig } from '../types'; import { rewriteStyleSheet } from './rewriteStyleSheet'; -type PseudoStateConfig = { - [P in PseudoState]?: boolean | string | string[]; -}; - -export interface PseudoParameter extends PseudoStateConfig { - rootSelector?: string; -} - const channel = addons.getChannel(); const shadowHosts = new Set(); diff --git a/code/addons/pseudo-states/src/types.test.ts b/code/addons/pseudo-states/src/types.test.ts new file mode 100644 index 000000000000..f01ef709ceed --- /dev/null +++ b/code/addons/pseudo-states/src/types.test.ts @@ -0,0 +1,40 @@ +import { describe, it } from 'vitest'; + +import { definePreview } from 'storybook/internal/csf'; + +describe('addon parameters', () => { + // Skip this tests - it's for the type checker only, and the preview import doesn't work in a non-DOM environment + it.skip('are injected to csf factory', async () => { + // Late import to prevent error referencing `Element` + const pseudoAddon = await import('.'); + + // Define preview with psuedo addon + const preview = definePreview({ addons: [pseudoAddon.default()] }); + + preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error focus should be bool/string + focus: 2, + }, + }, + }); + preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error this pseudo state doesn't exist + madeUpKey: true, + }, + }, + }); + // And now for something completely different - valid config + preview.meta({ + parameters: { + pseudo: { + rootSelector: 'body', + focus: true, + }, + }, + }); + }); +}); diff --git a/code/addons/pseudo-states/src/types.ts b/code/addons/pseudo-states/src/types.ts new file mode 100644 index 000000000000..3215f44105a2 --- /dev/null +++ b/code/addons/pseudo-states/src/types.ts @@ -0,0 +1,24 @@ +import type { PSEUDO_STATES } from './constants'; + +export type PseudoState = keyof typeof PSEUDO_STATES; + +export type PseudoStateConfig = { + [P in PseudoState]?: boolean | string | string[]; +}; + +export interface PseudoParameter extends PseudoStateConfig { + rootSelector?: string; +} + +export interface PseudoParameters { + /** + * Pseudo state configuration + * + * @see https://storybook.js.org/addons/storybook-addon-pseudo-states + */ + pseudo?: PseudoParameter; +} + +export interface PseudoTypes { + parameters: PseudoParameters; +}