Skip to content
Merged
6 changes: 2 additions & 4 deletions code/core/src/csf/story.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { RemoveIndexSignature, Simplify, UnionToIntersection } from 'type-fest';

import type { ToolbarArgType } from '../toolbar';
import type { SBScalarType, SBType } from './SBType';
import type { CoreTypes } from './core-annotations';

Expand Down Expand Up @@ -165,10 +166,7 @@ export interface Globals {
[name: string]: any;
}
export interface GlobalTypes {
[name: string]: InputType;
}
export interface StrictGlobalTypes {
[name: string]: StrictInputType;
[name: string]: ToolbarArgType;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions code/core/src/manager-api/modules/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ export interface SubAPI {
export const init: ModuleFn<SubAPI, SubState> = ({ store, fullAPI, provider }) => {
const api: SubAPI = {
getGlobals() {
return store.getState().globals as Globals;
return store.getState().globals!;
},
getUserGlobals() {
return store.getState().userGlobals as Globals;
return store.getState().userGlobals!;
},
getStoryGlobals() {
return store.getState().storyGlobals as Globals;
return store.getState().storyGlobals!;
},
getGlobalTypes() {
return store.getState().globalTypes as GlobalTypes;
return store.getState().globalTypes!;
},
updateGlobals(newGlobals) {
// Only emit the message to the local ref
Expand Down
3 changes: 2 additions & 1 deletion code/core/src/manager-api/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import type {
API_TestEntry,
ArgTypes,
Args,
GlobalTypes,
Globals,
Parameters,
StoryId,
Expand Down Expand Up @@ -487,7 +488,7 @@ export function useGlobals(): [
return [api.getGlobals(), api.updateGlobals, api.getStoryGlobals(), api.getUserGlobals()];
}

export function useGlobalTypes(): ArgTypes {
export function useGlobalTypes(): GlobalTypes {
return useStorybookApi().getGlobalTypes();
}

Expand Down
10 changes: 5 additions & 5 deletions code/core/src/manager-api/tests/globals.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ describe('globals API', () => {

channel.emit(SET_GLOBALS, {
globals: { a: 'b' },
globalTypes: { a: { type: { name: 'string' } } },
globalTypes: { a: {} },
} satisfies SetGlobalsPayload);
expect(store.getState()).toEqual({
userGlobals: { a: 'b' },
storyGlobals: {},
globals: { a: 'b' },
globalTypes: { a: { type: { name: 'string' } } },
globalTypes: { a: {} },
});
});

Expand All @@ -88,13 +88,13 @@ describe('globals API', () => {

channel.emit(SET_GLOBALS, {
globals: { a: 'b' },
globalTypes: { a: { type: { name: 'string' } } },
globalTypes: { a: {} },
} satisfies SetGlobalsPayload);
expect(store.getState()).toEqual({
userGlobals: { a: 'b' },
storyGlobals: {},
globals: { a: 'b' },
globalTypes: { a: { type: { name: 'string' } } },
globalTypes: { a: {} },
});

expect(listener).toHaveBeenCalledWith({
Expand Down Expand Up @@ -138,7 +138,7 @@ describe('globals API', () => {
getEventMetadata.mockReturnValueOnce({ sourceType: 'external', ref: { id: 'ref' } } as any);
channel.emit(SET_GLOBALS, {
globals: { a: 'b' },
globalTypes: { a: { type: { name: 'string' } } },
globalTypes: { a: {} },
} satisfies SetGlobalsPayload);
expect(store.getState()).toEqual({
userGlobals: {},
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/preview-api/modules/store/GlobalsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { logger } from 'storybook/internal/client-logger';
import type { GlobalTypes, Globals } from 'storybook/internal/types';

import { DEEPLY_EQUAL, deepDiff } from './args';
import { getValuesFromArgTypes } from './csf/getValuesFromArgTypes';
import { getValuesFromGlobalTypes } from './csf/getValuesFromGlobalTypes';

export class GlobalsStore {
// We use ! here because TS doesn't analyse the .set() function to see if it actually get set
Expand All @@ -27,7 +27,7 @@ export class GlobalsStore {

this.allowedGlobalNames = new Set([...Object.keys(globals), ...Object.keys(globalTypes)]);

const defaultGlobals: Globals = getValuesFromArgTypes(globalTypes);
const defaultGlobals: Globals = getValuesFromGlobalTypes(globalTypes);
this.initialGlobals = { ...defaultGlobals, ...globals };

this.globals = this.initialGlobals;
Expand Down
6 changes: 3 additions & 3 deletions code/core/src/preview-api/modules/store/StoryStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const importFn = vi.fn(async (path) => {
const projectAnnotations: ProjectAnnotations<any> = composeConfigs([
{
initialGlobals: { a: 'b' },
globalTypes: { a: { type: 'string' } },
globalTypes: { a: { name: 'a' } },
argTypes: { a: { type: 'string' } },
render: vi.fn(),
},
Expand Down Expand Up @@ -88,7 +88,7 @@ describe('StoryStore', () => {
const store = new StoryStore(storyIndex, importFn, projectAnnotations);

expect(store.projectAnnotations!.globalTypes).toEqual({
a: { name: 'a', type: { name: 'string' } },
a: { name: 'a' },
});
expect(store.projectAnnotations!.argTypes).toEqual({
a: { name: 'a', type: { name: 'string' } },
Expand All @@ -100,7 +100,7 @@ describe('StoryStore', () => {

store.setProjectAnnotations(projectAnnotations);
expect(store.projectAnnotations!.globalTypes).toEqual({
a: { name: 'a', type: { name: 'string' } },
a: { name: 'a' },
});
expect(store.projectAnnotations!.argTypes).toEqual({
a: { name: 'a', type: { name: 'string' } },
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { GlobalTypes, Globals } from 'storybook/internal/types';

export const getValuesFromGlobalTypes = (globalTypes: GlobalTypes = {}): Globals =>
Object.entries(globalTypes).reduce<Globals>((acc, [arg, { defaultValue }]) => {
if (typeof defaultValue !== 'undefined') {
acc[arg] = defaultValue;
}
return acc;
}, {});
2 changes: 1 addition & 1 deletion code/core/src/preview-api/modules/store/csf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export * from './prepareStory';
export * from './normalizeComponentAnnotations';
export * from './normalizeProjectAnnotations';
export * from './normalizeArrays';
export * from './getValuesFromArgTypes';
export * from './getValuesFromGlobalTypes';
export * from './composeConfigs';
export * from './stepRunners';
export * from './portable-stories';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type {
ArgTypes,
GlobalTypes,
InputType,
StrictArgTypes,
StrictGlobalTypes,
StrictInputType,
} from 'storybook/internal/types';

Expand Down Expand Up @@ -34,6 +32,5 @@ export const normalizeInputType = (inputType: InputType, key: string): StrictInp
return normalized;
};

export const normalizeInputTypes = (
inputTypes: ArgTypes | GlobalTypes
): StrictArgTypes | StrictGlobalTypes => mapValues(inputTypes, normalizeInputType);
export const normalizeInputTypes = (inputTypes: ArgTypes): StrictArgTypes =>
mapValues(inputTypes, normalizeInputType);
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { normalizeInputTypes } from './normalizeInputTypes';
// That makes sense to me as it avoids the need for both WP + Vite to call composeConfigs at the right time.
export function normalizeProjectAnnotations<TRenderer extends Renderer>({
argTypes,
globalTypes,
argTypesEnhancers,
decorators,
loaders,
Expand All @@ -27,7 +26,6 @@ export function normalizeProjectAnnotations<TRenderer extends Renderer>({
}: ProjectAnnotations<TRenderer>): NormalizedProjectAnnotations<TRenderer> {
return {
...(argTypes && { argTypes: normalizeInputTypes(argTypes as ArgTypes) }),
...(globalTypes && { globalTypes: normalizeInputTypes(globalTypes) }),
decorators: normalizeArrays(decorators),
loaders: normalizeArrays(loaders),
beforeEach: normalizeArrays(beforeEach),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
import { ReporterAPI } from '../reporter-api';
import { composeConfigs } from './composeConfigs';
import { getCsfFactoryAnnotations } from './csf-factory-utils';
import { getValuesFromArgTypes } from './getValuesFromArgTypes';
import { getValuesFromGlobalTypes } from './getValuesFromGlobalTypes';
import { normalizeComponentAnnotations } from './normalizeComponentAnnotations';
import { normalizeProjectAnnotations } from './normalizeProjectAnnotations';
import { normalizeStory } from './normalizeStory';
Expand Down Expand Up @@ -131,7 +131,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
normalizedProjectAnnotations
);

const globalsFromGlobalTypes = getValuesFromArgTypes(normalizedProjectAnnotations.globalTypes);
const globalsFromGlobalTypes = getValuesFromGlobalTypes(normalizedProjectAnnotations.globalTypes);

const globals = {
...globalsFromGlobalTypes,
Expand Down
11 changes: 5 additions & 6 deletions code/core/src/toolbar/components/ToolbarManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,25 @@ import { Separator } from 'storybook/internal/components';

import { useGlobalTypes } from 'storybook/manager-api';

import type { ToolbarArgType } from '../types';
import { normalizeArgType } from '../utils/normalize-toolbar-arg-type';
import { ToolbarMenuSelect } from './ToolbarMenuSelect';

/** A smart component for handling manager-preview interactions. */
export const ToolbarManager: FC = () => {
const globalTypes = useGlobalTypes();
const globalIds = Object.keys(globalTypes).filter((id) => !!globalTypes[id].toolbar);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, lots of other ways of acheiving type safety here, this was just the quickest.

const hasToolbars = Object.keys(globalTypes).some((id) => !!globalTypes[id].toolbar);

if (!globalIds.length) {
if (!hasToolbars) {
return null;
}

return (
<>
<Separator />
{globalIds.map((id) => {
const normalizedArgType = normalizeArgType(id, globalTypes[id] as ToolbarArgType);
{Object.keys(globalTypes).map((id) => {
const normalizedArgType = normalizeArgType(id, globalTypes[id]);

return <ToolbarMenuSelect key={id} id={id} {...normalizedArgType} />;
return normalizedArgType && <ToolbarMenuSelect key={id} id={id} {...normalizedArgType} />;
})}
</>
);
Expand Down
Loading