MOVE setOptions to layout module

REMOVE merge from initial state
MOVE initial state of layout & ui to layout module
ADD merge of initial, restored to layout module
This commit is contained in:
Norbert de Langen 2019-03-01 15:58:50 +01:00
parent 16ff72322a
commit 7622f72ae3
5 changed files with 114 additions and 106 deletions

View File

@ -61,7 +61,7 @@ export class Provider extends Component {
storyId,
};
this.state = {};
this.state = store.getInitialState();
this.modules = [
initChannel,
@ -75,7 +75,7 @@ export class Provider extends Component {
].map(initModule => initModule(apiData));
// Create our initial state by combining the initial state of all modules, then overlaying any saved state
const state = store.getInitialState(getInitialState(...this.modules.map(m => m.state)));
const state = getInitialState(...this.modules.map(m => m.state));
// Get our API by combining the APIs exported by each module
const combo = Object.assign({ navigate }, ...this.modules.map(m => m.api));

View File

@ -1,89 +1,6 @@
import pick from 'lodash.pick';
import deprecate from 'util-deprecate';
import { create } from '@storybook/theming';
const deprecationMessage = (optionsMap, prefix) =>
`The options { ${Object.keys(optionsMap).join(', ')} } are deprecated -- use ${
prefix ? `${prefix}'s` : ''
} { ${Object.values(optionsMap).join(', ')} } instead.`;
const deprecatedThemeOptions = {
name: 'brandTitle',
url: 'brandUrl',
};
const applyDeprecatedThemeOptions = deprecate(({ name, url, theme }) => {
const vars = {
brandTitle: name,
brandUrl: url,
brandImage: null,
};
return { theme: create(vars, theme) };
}, deprecationMessage(deprecatedThemeOptions));
const checkDeprecatedThemeOptions = options => {
if (Object.keys(deprecatedThemeOptions).find(key => !!options[key])) {
return applyDeprecatedThemeOptions(options);
}
return {};
};
const deprecatedLayoutOptions = {
goFullScreen: 'isFullscreen',
showStoriesPanel: 'showNav',
showAddonPanel: 'showPanel',
addonPanelInRight: 'panelPosition',
};
const applyDeprecatedLayoutOptions = deprecate(options => {
const layoutUpdate = {};
['goFullScreen', 'showStoriesPanel', 'showAddonPanel'].forEach(option => {
if (typeof options[option] !== 'undefined') {
layoutUpdate[deprecatedLayoutOptions[option]] = options[option];
}
});
if (options.addonPanelInRight) {
layoutUpdate.panelPosition = 'right';
}
return layoutUpdate;
}, deprecationMessage(deprecatedLayoutOptions));
const checkDeprecatedLayoutOptions = options => {
if (Object.keys(deprecatedLayoutOptions).find(key => typeof options[key] !== 'undefined')) {
return applyDeprecatedLayoutOptions(options);
}
return {};
};
export default ({ provider, api, store }) => {
export default ({ provider, api }) => {
const providerAPI = {
...api,
setOptions: options => {
const { layout, ui, selectedPanel } = store.getState();
if (options) {
const updatedLayout = {
...layout,
...pick(options, Object.keys(layout)),
...checkDeprecatedLayoutOptions(options),
};
const updatedUi = {
...ui,
...pick(options, Object.keys(ui)),
...checkDeprecatedThemeOptions(options),
};
store.setState(
{
layout: updatedLayout,
ui: updatedUi,
selectedPanel: options.panel || options.selectedPanel || selectedPanel,
},
{ persistence: 'permanent' }
);
}
},
};
provider.handleAPI(providerAPI);

View File

@ -1,21 +1,6 @@
import { themes } from '@storybook/theming';
import merge from '../libs/merge';
const initial = {
ui: {
enableShortcuts: true,
sortStoriesByKind: false,
sidebarAnimations: true,
theme: themes.normal,
},
layout: {
isToolshown: true,
isFullscreen: false,
showPanel: true,
showNav: true,
panelPosition: 'bottom',
},
customQueryParams: {},
storiesConfigured: false,
};

View File

@ -1,3 +1,64 @@
import pick from 'lodash.pick';
import deprecate from 'util-deprecate';
import { create, themes } from '@storybook/theming';
import merge from '../libs/merge';
const deprecatedThemeOptions = {
name: 'brandTitle',
url: 'brandUrl',
};
const deprecatedLayoutOptions = {
goFullScreen: 'isFullscreen',
showStoriesPanel: 'showNav',
showAddonPanel: 'showPanel',
addonPanelInRight: 'panelPosition',
};
const deprecationMessage = (optionsMap, prefix) =>
`The options { ${Object.keys(optionsMap).join(', ')} } are deprecated -- use ${
prefix ? `${prefix}'s` : ''
} { ${Object.values(optionsMap).join(', ')} } instead.`;
const applyDeprecatedThemeOptions = deprecate(({ name, url, theme }) => {
const vars = {
brandTitle: name,
brandUrl: url,
brandImage: null,
};
return { theme: create(vars, theme) };
}, deprecationMessage(deprecatedThemeOptions));
const applyDeprecatedLayoutOptions = deprecate(options => {
const layoutUpdate = {};
['goFullScreen', 'showStoriesPanel', 'showAddonPanel'].forEach(option => {
if (typeof options[option] !== 'undefined') {
layoutUpdate[deprecatedLayoutOptions[option]] = options[option];
}
});
if (options.addonPanelInRight) {
layoutUpdate.panelPosition = 'right';
}
return layoutUpdate;
}, deprecationMessage(deprecatedLayoutOptions));
const checkDeprecatedThemeOptions = options => {
if (Object.keys(deprecatedThemeOptions).find(key => !!options[key])) {
return applyDeprecatedThemeOptions(options);
}
return {};
};
const checkDeprecatedLayoutOptions = options => {
if (Object.keys(deprecatedLayoutOptions).find(key => typeof options[key] !== 'undefined')) {
return applyDeprecatedLayoutOptions(options);
}
return {};
};
export default function({ store }) {
const api = {
toggleFullscreen(toggled) {
@ -69,7 +130,54 @@ export default function({ store }) {
};
});
},
setOptions: options => {
const { layout, ui, selectedPanel } = store.getState();
if (options) {
const updatedLayout = {
...layout,
...pick(options, Object.keys(layout)),
...checkDeprecatedLayoutOptions(options),
};
const updatedUi = {
...ui,
...pick(options, Object.keys(ui)),
...checkDeprecatedThemeOptions(options),
};
store.setState(
{
layout: updatedLayout,
ui: updatedUi,
selectedPanel: options.panel || options.selectedPanel || selectedPanel,
},
{ persistence: 'permanent' }
);
}
},
};
return { api };
const fromState = pick(store.getState(), 'layout', 'ui', 'selectedPanel');
const fromRestore = pick(store.getInitialState(), 'layout', 'ui', 'selectedPanel');
const initial = {
ui: {
enableShortcuts: true,
sortStoriesByKind: false,
sidebarAnimations: true,
theme: themes.normal,
},
layout: {
isToolshown: true,
isFullscreen: false,
showPanel: true,
showNav: true,
panelPosition: 'bottom',
},
};
const state = merge({}, fromRestore, fromState, initial);
return { api, state };
}

View File

@ -3,8 +3,6 @@
import { localStorage, sessionStorage } from 'global';
import { parse, stringify } from 'telejson';
import merge from '../libs/merge';
export const STORAGE_KEY = '@storybook/ui/store';
function get(storage) {
@ -32,11 +30,11 @@ export default class Store {
// The assumption is that this will be called once, to initialize the React state
// when the module is instanciated
getInitialState(base = {}) {
getInitialState() {
// We don't only merge at the very top level (the same way as React setState)
// when you set keys, so it makes sense to do the same in combining the two storage modes
// Really, you shouldn't store the same key in both places
return merge(base, { ...get(localStorage), ...get(sessionStorage) });
return { ...get(localStorage), ...get(sessionStorage) };
}
getState() {