diff --git a/core/config/src/index.ts b/core/config/src/index.ts
index b127740c1..94c26c483 100644
--- a/core/config/src/index.ts
+++ b/core/config/src/index.ts
@@ -14,6 +14,7 @@ export const configFileNames = [
export interface ConfigrationResult {
config: Configuration;
configPath: string;
+ configFilePath: string;
}
/**
* return the configration folder from command-line parameters
@@ -54,12 +55,15 @@ export const loadConfiguration = (
configFileNames.includes(file.toLowerCase()),
);
- return configFile
- ? {
- config: require(path.resolve(configPath, configFile)),
- configPath,
- }
- : undefined;
+ if (configFile) {
+ const configFilePath = path.resolve(configPath, configFile);
+ return {
+ config: require(configFilePath),
+ configFilePath,
+ configPath,
+ };
+ }
+ return undefined;
};
/**
diff --git a/core/loader/src/replaceSource.ts b/core/loader/src/replaceSource.ts
index 890c4a6b1..a1ded2f81 100644
--- a/core/loader/src/replaceSource.ts
+++ b/core/loader/src/replaceSource.ts
@@ -3,9 +3,16 @@ export interface StoryPath {
relPath: string;
}
-export const replaceSource = (stories: StoryPath[], hashKey: string) => {
+export const replaceSource = (
+ stories: StoryPath[],
+ configFilePath: string | undefined,
+ hashKey: string,
+) => {
const imports = `
const imports = {};
+const configJSON = ${
+ configFilePath ? `require("${configFilePath}")` : 'undefined'
+ };
${stories
.map(story => `imports['${story.absPath}'] = require(${story.relPath});`)
.join('\n')}
@@ -59,6 +66,7 @@ ${stories
const newContent = `
${imports}
${storeConst}
+store.config = configJSON;
${loadStories}
${hmr}
${exports}
diff --git a/core/loader/src/runtimeLoader.ts b/core/loader/src/runtimeLoader.ts
index 3c5a4699d..ad828818c 100644
--- a/core/loader/src/runtimeLoader.ts
+++ b/core/loader/src/runtimeLoader.ts
@@ -16,6 +16,7 @@ module.exports = function(content: string) {
);
content = replaceSource(
stories,
+ config?.configFilePath,
`__COMPILATION_HASH__${params.compilationHash}`,
);
return content;
diff --git a/core/loader/src/store.ts b/core/loader/src/store.ts
index 4ff30a132..7d1ae4f78 100644
--- a/core/loader/src/store.ts
+++ b/core/loader/src/store.ts
@@ -2,9 +2,14 @@ import {
StoriesStore,
StoryComponents,
StoryPackages,
+ Configuration,
} from '@component-controls/specification';
export interface LoadingStore {
+ /**
+ * global configuration from project config file
+ */
+ config?: Configuration;
/**
* global store of packages
*/
diff --git a/core/specification/src/configuration.ts b/core/specification/src/configuration.ts
index b8ed1d194..470bf55a7 100644
--- a/core/specification/src/configuration.ts
+++ b/core/specification/src/configuration.ts
@@ -17,4 +17,13 @@ export interface Configuration {
* example: [story => {story()}]
*/
decorators?: StoryRenderFn[];
+ /**
+ * global options object
+ */
+ options?: {
+ /**
+ * story sorting function
+ */
+ storySort?: (a: string, b: string) => number;
+ };
}
diff --git a/core/specification/src/stories.ts b/core/specification/src/stories.ts
index 486d5644c..75c7c8893 100644
--- a/core/specification/src/stories.ts
+++ b/core/specification/src/stories.ts
@@ -1,7 +1,7 @@
import { CodeLocation, PackageInfo, StoryRenderFn } from './utility';
import { StoryComponent } from './components';
import { ComponentControls } from './controls';
-
+import { Configuration } from './configuration';
/**
* an identifier/variable.argument in the source code
*/
@@ -271,6 +271,10 @@ export interface StoryPackages {
* store of stories information in memory after the loader is applied
*/
export interface StoriesStore {
+ /**
+ * global configuration for config file
+ */
+ config?: Configuration;
/**
* list of story files, or groups
*/
diff --git a/core/store/src/Store/Store.ts b/core/store/src/Store/Store.ts
index ba4e84b1b..53915f6d6 100644
--- a/core/store/src/Store/Store.ts
+++ b/core/store/src/Store/Store.ts
@@ -1,4 +1,4 @@
-import { StoriesStore } from '@component-controls/specification';
+import { StoriesStore, Configuration } from '@component-controls/specification';
import { BroadcastChannel } from 'broadcast-channel';
import {
StoreObserver,
@@ -121,6 +121,10 @@ export class Store implements StoryStore {
const store = this.getStore();
return store ? store.docs : undefined;
};
+
+ get config(): Configuration | undefined {
+ return this.loadedStore?.config;
+ }
/**
* modify story properties, for example controls values.
* will notify all installed store observers of the changed story.
diff --git a/core/store/src/serialization/load-store.ts b/core/store/src/serialization/load-store.ts
index 553455b0e..83b0d451d 100644
--- a/core/store/src/serialization/load-store.ts
+++ b/core/store/src/serialization/load-store.ts
@@ -25,6 +25,7 @@ export const loadStoryStore = (
stores,
packages: loadedPackages,
components: loadedComponents,
+ config,
} = newStore;
if (stores) {
@@ -33,6 +34,7 @@ export const loadStoryStore = (
stories: {},
components: {},
packages: {},
+ config,
};
stores.forEach(s => {
const storeDocs = s.docs;
diff --git a/core/store/src/types.ts b/core/store/src/types.ts
index 9e3b18622..aea4fc4ae 100644
--- a/core/store/src/types.ts
+++ b/core/store/src/types.ts
@@ -2,6 +2,7 @@ import {
StoriesStore,
Story,
StoryDocs,
+ Configuration,
} from '@component-controls/specification';
/**
@@ -16,6 +17,7 @@ export interface StoryStore {
getStory: (storyId: string) => Story | undefined;
getStoryDoc: (name: string) => StoryDocs | undefined;
getDocs: () => StoryDocs | undefined;
+ config: Configuration | undefined;
updateStoryProp: (
storyId: string,
propName: string,
diff --git a/examples/gatsby/.config/main.js b/examples/gatsby/.config/main.js
index a3885a6db..f3aae1e30 100644
--- a/examples/gatsby/.config/main.js
+++ b/examples/gatsby/.config/main.js
@@ -1,5 +1,26 @@
+const categories = ['Introduction', 'Controls','Blocks', 'Editors', 'Components', 'App components', 'Plugins'];
+storySort: (a, b) => {
+ const aKind = a[1].kind.split('/')[0];
+ const aIndex = categories.findIndex(c => c === aKind);
+ const bKind = b[1].kind.split('/')[0];
+ const bIndex = categories.findIndex(c => c === bKind);
+ return aIndex - bIndex;
+},
+
module.exports = {
stories: [
'../../stories/src/**/*.stories.(js|jsx|tsx|mdx)',
+ '../../../core/specification/src/stories/**/*.stories.(js|jsx|tsx|mdx)',
+ '../../../ui/app-components/src/**/*.stories.(js|jsx|tsx|mdx)',
+ '../../../ui/components/src/**/*.stories.(js|jsx|tsx|mdx)',
],
+ options: {
+ storySort: (a, b) => {
+ const aDoc = a.split('/')[0];
+ const aIndex = categories.findIndex(c => c === aDoc);
+ const bDoc = b.split('/')[0];
+ const bIndex = categories.findIndex(c => c === bDoc);
+ return aIndex - bIndex;
+ },
+ }
};
diff --git a/integrations/gatsby-theme-stories/src/gatsby-node.ts b/integrations/gatsby-theme-stories/src/gatsby-node.ts
index 6145246d7..439fc58e7 100644
--- a/integrations/gatsby-theme-stories/src/gatsby-node.ts
+++ b/integrations/gatsby-theme-stories/src/gatsby-node.ts
@@ -1,4 +1,8 @@
-import { compile } from '@component-controls/webpack-compile';
+import {
+ compile,
+ watch,
+ CompileProps,
+} from '@component-controls/webpack-compile';
import { NodePluginArgs, NodeInput, CreatePagesArgs } from 'gatsby';
import { StoriesStore } from '@component-controls/specification';
import { loadStoryStore } from '@component-controls/store';
@@ -11,12 +15,12 @@ exports.sourceNodes = async function sourceNodes(
options: LoaderOptions,
) {
const { createNode } = actions;
-
- const { store } = await compile({
+ const config: CompileProps = {
webPack: options.webpack,
presets: defaultPresets,
configPath: options.configPath,
- });
+ };
+ const { store } = true ? await watch(config) : await compile(config);
const loadedStore: StoriesStore | undefined = loadStoryStore(store);
if (loadedStore) {
diff --git a/integrations/storybook/src/preset.ts b/integrations/storybook/src/preset.ts
index 164c8ed5b..dd0d28d0a 100644
--- a/integrations/storybook/src/preset.ts
+++ b/integrations/storybook/src/preset.ts
@@ -47,7 +47,6 @@ module.exports = {
return result;
},
webpackFinal: (config: any = {}, options: PresetOptions = {}) => {
- debugger;
const mergedConfig = mergeWebpackConfig(
config,
options?.webpack || defaultRules,
diff --git a/plugins/axe-plugin/src/typings.d.ts b/plugins/axe-plugin/src/typings.d.ts
deleted file mode 100644
index 201a6a9cf..000000000
--- a/plugins/axe-plugin/src/typings.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'recoil';
diff --git a/ui/app/src/Sidebar/Sidebar.tsx b/ui/app/src/Sidebar/Sidebar.tsx
index ca2aa3a02..a9048bf07 100644
--- a/ui/app/src/Sidebar/Sidebar.tsx
+++ b/ui/app/src/Sidebar/Sidebar.tsx
@@ -65,8 +65,12 @@ export const Sidebar: FC = ({ docPath, buttonClass, title }) => {
const { storeProvider } = useContext(BlockContext);
const menuItems = useMemo(() => {
if (storeProvider) {
+ const { options } = storeProvider.config || {};
+
const docs: string[] = Object.keys(storeProvider.getDocs() || []);
- const menuItems = docs.reduce((acc: MenuItems, doc: string) => {
+ const sortedDocs =
+ options && options.storySort ? docs.sort(options.storySort) : docs;
+ const menuItems = sortedDocs.reduce((acc: MenuItems, doc: string) => {
const levels = doc.split('/');
createMenuItem(levels, levels, acc);
return acc;