`;
-exports[`Storyshots Story|How to create a story the opts value is not necessary 1`] = `
+exports[`Storyshots Story|How to create a story theOptsValueIsNotNecessary 1`] = `
`;
-exports[`Storyshots Story|Nest tags Three tags 1`] = `
+exports[`Storyshots Story|Nest tags threeTags 1`] = `
@@ -19,7 +19,7 @@ exports[`Storyshots Addon|Actions Action on component method 1`] = `
`;
-exports[`Storyshots Addon|Actions Action on view method 1`] = `
+exports[`Storyshots Addon|Actions actionOnViewMethod 1`] = `
@@ -61,7 +61,7 @@ exports[`Storyshots Addon|Actions Action on view method 1`] = `
`;
-exports[`Storyshots Addon|Backgrounds story 1 1`] = `
+exports[`Storyshots Addon|Backgrounds story1 1`] = `
@@ -122,7 +122,7 @@ exports[`Storyshots Addon|Centered rounded 1`] = `
`;
-exports[`Storyshots Addon|Centered with action 1`] = `
+exports[`Storyshots Addon|Centered withAction 1`] = `
@@ -155,7 +155,7 @@ exports[`Storyshots Addon|Knobs Simple 1`] = `
`;
-exports[`Storyshots Addon|Links Go to welcome view 1`] = `
+exports[`Storyshots Addon|Links goToWelcomeView 1`] = `
@@ -183,7 +183,7 @@ exports[`Storyshots Addon|Links Go to welcome view 1`] = `
`;
-exports[`Storyshots Addon|Notes Note with HTML 1`] = `
+exports[`Storyshots Addon|Notes noteWithHtml 1`] = `
@@ -225,7 +225,7 @@ exports[`Storyshots Addon|Notes Note with HTML 1`] = `
`;
-exports[`Storyshots Addon|Notes Simple note 1`] = `
+exports[`Storyshots Addon|Notes simpleNote 1`] = `
diff --git a/examples/vue-kitchen-sink/__snapshots__/vueshots.test.js.snap b/examples/vue-kitchen-sink/__snapshots__/vueshots.test.js.snap
index 611131f30459..8038ccef3dbe 100644
--- a/examples/vue-kitchen-sink/__snapshots__/vueshots.test.js.snap
+++ b/examples/vue-kitchen-sink/__snapshots__/vueshots.test.js.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Storyshots Addon|Actions Action and method 1`] = `
+exports[`Storyshots Addon|Actions actionAndMethod 1`] = `
`;
-exports[`Storyshots Addon|Contexts Simple CSS Theming 1`] = `
+exports[`Storyshots Addon|Contexts simpleCssTheming 1`] = `
@@ -87,7 +87,13 @@ exports[`Storyshots Addon|Contexts Simple CSS Theming 1`] = `
`;
-exports[`Storyshots Addon|Knobs All knobs 1`] = `
+exports[`Storyshots Addon|Knobs Simple 1`] = `
+
+ I am John Doe and I'm 40 years old.
+
+`;
+
+exports[`Storyshots Addon|Knobs allKnobs 1`] = `
@@ -125,19 +131,13 @@ exports[`Storyshots Addon|Knobs All knobs 1`] = `
`;
-exports[`Storyshots Addon|Knobs Simple 1`] = `
-
- I am John Doe and I'm 40 years old.
-
-`;
-
-exports[`Storyshots Addon|Knobs XSS safety 1`] = `
+exports[`Storyshots Addon|Knobs xssSafety 1`] = `
<img src=x onerror="alert('XSS Attack')" >
`;
-exports[`Storyshots Addon|Links Go to welcome 1`] = `
+exports[`Storyshots Addon|Links goToWelcome 1`] = `
`;
-exports[`Storyshots Addon|Notes Note with HTML 1`] = `
+exports[`Storyshots Addon|Notes noteWithHtml 1`] = `
🤔😳😯😮
@@ -156,7 +156,7 @@ exports[`Storyshots Addon|Notes Note with HTML 1`] = `
`;
-exports[`Storyshots Addon|Notes Simple note 1`] = `
+exports[`Storyshots Addon|Notes simpleNote 1`] = `
Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.
@@ -164,7 +164,7 @@ exports[`Storyshots Addon|Notes Simple note 1`] = `
`;
-exports[`Storyshots App App 1`] = `
+exports[`Storyshots App app 1`] = `
@@ -278,13 +278,13 @@ exports[`Storyshots Button square 1`] = `
`;
-exports[`Storyshots Core|Parameters passed to story 1`] = `
+exports[`Storyshots Core|Parameters passedToStory 1`] = `
- Parameters are {"options":{"hierarchyRootSeparator":{},"hierarchySeparator":{}},"docs":{"iframeHeight":"60px"},"globalParameter":"globalParameter","framework":"vue","chapterParameter":"chapterParameter","storyParameter":"storyParameter"}
+ Parameters are {"options":{"hierarchyRootSeparator":{},"hierarchySeparator":{}},"docs":{"iframeHeight":"60px"},"globalParameter":"globalParameter","framework":"vue","chapterParameter":"chapterParameter","storyParameter":"storyParameter","displayName":"passed to story"}
`;
-exports[`Storyshots Core|Template string only 1`] = `
+exports[`Storyshots Core|Template stringOnly 1`] = `
`;
-exports[`Storyshots Custom|Method for rendering Vue pre-registered component 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue preRegisteredComponent 1`] = `
This component was pre-registered in .storybook/config.js
@@ -384,7 +385,13 @@ exports[`Storyshots Custom|Method for rendering Vue pre-registered component 1`]
`;
-exports[`Storyshots Custom|Method for rendering Vue render + component 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue render 1`] = `
+
+ renders a div with some text in it..
+
+`;
+
+exports[`Storyshots Custom|Method for rendering Vue renderComponent 1`] = `
`;
-exports[`Storyshots Custom|Method for rendering Vue render 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue template 1`] = `
- renders a div with some text in it..
+
+ A template
+
+
+
+ rendered in vue in storybook
+
`;
-exports[`Storyshots Custom|Method for rendering Vue template + component 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue templateComponent 1`] = `
`;
-exports[`Storyshots Custom|Method for rendering Vue template + methods 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue templateMethods 1`] = `
Clicking the button will navigate to another story using the 'addon-links'
@@ -424,19 +437,7 @@ exports[`Storyshots Custom|Method for rendering Vue template + methods 1`] = `
`;
-exports[`Storyshots Custom|Method for rendering Vue template 1`] = `
-
-
- A template
-
-
-
- rendered in vue in storybook
-
-
-`;
-
-exports[`Storyshots Custom|Method for rendering Vue vuex + actions 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue vuexActions 1`] = `
`;
-exports[`Storyshots Custom|Method for rendering Vue whatever you want 1`] = `
+exports[`Storyshots Custom|Method for rendering Vue whateverYouWant 1`] = `
({
}));
describe('preview.client_api', () => {
+ describe('defaultMakeDisplayName', () => {
+ it('should format CSF exports with sensible defaults', () => {
+ const testCases = {
+ name: 'Name',
+ someName: 'Some Name',
+ someNAME: 'Some NAME',
+ some_custom_NAME: 'Some Custom NAME',
+ };
+ Object.entries(testCases).forEach(([key, val]) =>
+ expect(defaultMakeDisplayName(key)).toBe(val)
+ );
+ });
+ });
+
describe('setAddon', () => {
it('should register addons', () => {
const { clientApi } = getContext(undefined);
diff --git a/lib/client-api/src/client_api.ts b/lib/client-api/src/client_api.ts
index 0050ead84775..754f8a48f803 100644
--- a/lib/client-api/src/client_api.ts
+++ b/lib/client-api/src/client_api.ts
@@ -1,6 +1,7 @@
/* eslint no-underscore-dangle: 0 */
import deprecate from 'util-deprecate';
import isPlainObject from 'is-plain-object';
+import startCase from 'lodash/startCase';
import { logger } from '@storybook/client-logger';
import addons, { StoryContext, StoryFn, Parameters, OptionsParameter } from '@storybook/addons';
import Events from '@storybook/core-events';
@@ -82,6 +83,8 @@ const withSubscriptionTracking = (storyFn: StoryFn) => {
return result;
};
+export const defaultMakeDisplayName = (key: string) => startCase(key);
+
export default class ClientApi {
private _storyStore: StoryStore;
@@ -123,6 +126,10 @@ export default class ClientApi {
this._globalParameters.options
);
+ getMakeDisplayName = () =>
+ (this._globalParameters.options && this._globalParameters.options.makeDisplayName) ||
+ defaultMakeDisplayName;
+
addDecorator = (decorator: DecoratorFunction) => {
this._globalDecorators.push(decorator);
};
diff --git a/lib/components/src/blocks/Source.stories.tsx b/lib/components/src/blocks/Source.stories.tsx
index 7024c3b21e7e..bad3ea4acaeb 100644
--- a/lib/components/src/blocks/Source.stories.tsx
+++ b/lib/components/src/blocks/Source.stories.tsx
@@ -32,7 +32,5 @@ const cssCode = `
export const css = () => ;
export const noStory = () => ;
-noStory.story = { name: 'no story' };
export const sourceUnavailable = () => ;
-sourceUnavailable.story = { name: 'source unavailable' };
diff --git a/lib/core/src/client/preview/start.js b/lib/core/src/client/preview/start.js
index 10ea0f858bec..5f26f9c2798c 100644
--- a/lib/core/src/client/preview/start.js
+++ b/lib/core/src/client/preview/start.js
@@ -398,6 +398,9 @@ export default function start(render, { decorateStory } = {}) {
// We pass true here to avoid the warning about HMR. It's cool clientApi, we got this
const kind = clientApi.storiesOf(kindName, true);
+ // Transform the CSF named export if the user hasn't specified a name
+ const makeDisplayName = clientApi.getMakeDisplayName();
+
// we should always have a framework, rest optional
kind.addParameters({ framework, component, ...params });
@@ -414,7 +417,10 @@ export default function start(render, { decorateStory } = {}) {
`${kindName} => ${name || key}: story.parameters.decorators is deprecated; use story.decorators instead.`)();
}
const decoratorParams = decorators ? { decorators } : null;
- kind.add(name || key, storyFn, { ...parameters, ...decoratorParams });
+ const displayNameParams = {
+ displayName: name || makeDisplayName(key),
+ };
+ kind.add(key, storyFn, { ...parameters, ...decoratorParams, ...displayNameParams });
}
});
});
diff --git a/lib/ui/src/components/sidebar/SidebarItem.tsx b/lib/ui/src/components/sidebar/SidebarItem.tsx
index 7673a82f0076..36767a030628 100644
--- a/lib/ui/src/components/sidebar/SidebarItem.tsx
+++ b/lib/ui/src/components/sidebar/SidebarItem.tsx
@@ -135,6 +135,9 @@ const SidebarItem = ({
iconName = 'folder';
}
+ // eslint-disable-next-line react/destructuring-assignment
+ const displayName = (props.parameters && props.parameters.displayName) || name;
+
return (
-
- {name}
+ {displayName}
);
};