Skip to content
Open
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
62 changes: 49 additions & 13 deletions code/core/src/manager-api/modules/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SET_CONFIG } from 'storybook/internal/core-events';
import type {
API_Layout,
API_LayoutCustomisations,
API_LayoutOptions,
API_PanelPositions,
API_UI,
} from 'storybook/internal/types';
Expand Down Expand Up @@ -192,6 +193,38 @@ const getRecentVisibleSizes = (layoutState: API_Layout) => {
};
};

const applyLayoutOptions = (
layoutState: API_Layout,
options: API_LayoutOptions | undefined,
singleStory: boolean
) => {
const { showPanel, showSidebar, ...layoutOptions } = options ?? {};
const layoutKeys = Object.keys(layoutState) as (keyof API_Layout)[];
const nextLayoutState = toMerged(layoutState, pick(layoutOptions, layoutKeys)) as API_Layout;

if (showSidebar === false) {
nextLayoutState.recentVisibleSizes = getRecentVisibleSizes(nextLayoutState);
nextLayoutState.navSize = 0;
} else if (showSidebar === true && !singleStory) {
nextLayoutState.navSize = nextLayoutState.recentVisibleSizes.navSize;
}

if (showPanel === false) {
nextLayoutState.recentVisibleSizes = getRecentVisibleSizes(nextLayoutState);
nextLayoutState.bottomPanelHeight = 0;
nextLayoutState.rightPanelWidth = 0;
} else if (showPanel === true) {
nextLayoutState.bottomPanelHeight = nextLayoutState.recentVisibleSizes.bottomPanelHeight;
nextLayoutState.rightPanelWidth = nextLayoutState.recentVisibleSizes.rightPanelWidth;
}

if (singleStory) {
nextLayoutState.navSize = 0;
}

return nextLayoutState;
};

export const init: ModuleFn<SubAPI, SubState> = ({ store, provider, singleStory }) => {
const api = {
toggleFullscreen(nextState?: boolean) {
Expand Down Expand Up @@ -444,13 +477,14 @@ export const init: ModuleFn<SubAPI, SubState> = ({ store, provider, singleStory

return {
...defaultLayoutState,
layout: {
...toMerged(
defaultLayoutState.layout,
pick(options, Object.keys(defaultLayoutState.layout))
),
...(singleStory && { navSize: 0 }),
},
layout: applyLayoutOptions(
defaultLayoutState.layout,
{
...options.layout,
...pick(options, Object.keys(defaultLayoutState.layout)),
},
!!singleStory
),
layoutCustomisations: {
...defaultLayoutState.layoutCustomisations,
...(layoutCustomisations ?? {}),
Expand Down Expand Up @@ -513,12 +547,14 @@ export const init: ModuleFn<SubAPI, SubState> = ({ store, provider, singleStory
return;
}

const updatedLayout = {
...layout,
...(options.layout || {}),
...pick(options, Object.keys(layout)),
...(singleStory && { navSize: 0 }),
};
const updatedLayout = applyLayoutOptions(
layout,
{
...options.layout,
...pick(options, Object.keys(layout)),
},
!!singleStory
);

const updatedUi = {
...ui,
Expand Down
38 changes: 38 additions & 0 deletions code/core/src/manager-api/tests/layout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,44 @@

expect(getLastSetStateArgs()[0].selectedPanel).toEqual(panelName);
});

it('should hide the panel when layout.showPanel is false', () => {
layoutApi.setSizes({
bottomPanelHeight: 200,
rightPanelWidth: 250,
});

layoutApi.setOptions({ layout: { showPanel: false } });

expect(currentState.layout.bottomPanelHeight).toBe(0);
expect(currentState.layout.rightPanelWidth).toBe(0);
expect(currentState.layout.recentVisibleSizes.bottomPanelHeight).toBe(200);
expect(currentState.layout.recentVisibleSizes.rightPanelWidth).toBe(250);

layoutApi.togglePanel(true);

expect(currentState.layout.bottomPanelHeight).toBe(200);
expect(currentState.layout.rightPanelWidth).toBe(250);
});
});

describe('getInitialOptions', () => {
it('should apply layout.showPanel from the initial config', () => {
(provider.getConfig as Mock).mockReturnValue({
layout: { showPanel: false },
});

const { state } = initLayout({
store,
provider,
singleStory: false,
} as unknown as ModuleArgs);

expect(state.layout.bottomPanelHeight).toBe(0);

Check failure on line 522 in code/core/src/manager-api/tests/layout.test.ts

View workflow job for this annotation

GitHub Actions / Core Unit Tests, ubuntu-latest

[core] src/manager-api/tests/layout.test.ts > layout API > getInitialOptions > should apply layout.showPanel from the initial config

AssertionError: expected 300 to be +0 // Object.is equality - Expected + Received - 0 + 300 ❯ src/manager-api/tests/layout.test.ts:522:46
expect(state.layout.rightPanelWidth).toBe(0);
expect(state.layout.recentVisibleSizes.bottomPanelHeight).toBe(300);
expect(state.layout.recentVisibleSizes.rightPanelWidth).toBe(400);
});
});

describe('state getters', () => {
Expand Down
3 changes: 2 additions & 1 deletion code/core/src/types/modules/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { FC, PropsWithChildren, ReactElement, ReactNode } from 'react';

import type { RenderData as RouterData } from '../../router/types.ts';
import type { ThemeVars } from '../../theming/types.ts';
import type { API_LayoutCustomisations, API_SidebarOptions } from './api.ts';
import type { API_LayoutCustomisations, API_LayoutOptions, API_SidebarOptions } from './api.ts';
import type { API_HashEntry, API_StoryEntry } from './api-stories.ts';
import type {
Args,
Expand Down Expand Up @@ -479,6 +479,7 @@ export interface Addon_ToolbarConfig {
}
export interface Addon_Config {
theme?: ThemeVars;
layout?: API_LayoutOptions;
layoutCustomisations?: {
showPanel?: API_LayoutCustomisations['showPanel'];
showSidebar?: API_LayoutCustomisations['showSidebar'];
Expand Down
5 changes: 5 additions & 0 deletions code/core/src/types/modules/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ export interface API_Layout {
showToolbar: boolean;
}

export interface API_LayoutOptions extends Partial<API_Layout> {
showPanel?: boolean;
showSidebar?: boolean;
}

export interface API_LayoutCustomisations {
showPanel?: (state: State, defaultValue: boolean) => boolean | undefined;
showSidebar?: (state: State, defaultValue: boolean) => boolean | undefined;
Expand Down
Loading