diff --git a/examples/official-storybook/stories/core/layout.stories.js b/examples/official-storybook/stories/core/layout.stories.js
new file mode 100644
index 000000000000..b347acb6c8c2
--- /dev/null
+++ b/examples/official-storybook/stories/core/layout.stories.js
@@ -0,0 +1,33 @@
+import React from 'react';
+
+// eslint-disable-next-line react/prop-types
+const Box = ({ children, display = 'block' }) => (
+
{children}
+);
+
+export default {
+ title: 'Core/Layout',
+};
+
+export const Default = () => padded by default;
+
+export const PaddedBlock = () => padded;
+PaddedBlock.story = { parameters: { layout: 'padded' } };
+
+export const PaddedInline = () => padded;
+PaddedInline.story = { parameters: { layout: 'padded' } };
+
+export const FullscreenBlock = () => fullscreen;
+FullscreenBlock.story = { parameters: { layout: 'fullscreen' } };
+
+export const FullscreenInline = () => fullscreen;
+FullscreenInline.story = { parameters: { layout: 'fullscreen' } };
+
+export const CenteredBlock = () => centered;
+CenteredBlock.story = { parameters: { layout: 'centered' } };
+
+export const CenteredInline = () => centered;
+CenteredInline.story = { parameters: { layout: 'centered' } };
+
+export const Invalid = () => invalid layout value;
+CenteredInline.story = { parameters: { layout: '!invalid!' } };
diff --git a/lib/core/src/client/preview/start.js b/lib/core/src/client/preview/start.js
index 2bcb2ab8edc8..8fb75467ebc2 100644
--- a/lib/core/src/client/preview/start.js
+++ b/lib/core/src/client/preview/start.js
@@ -121,6 +121,37 @@ function focusInInput(event) {
);
}
+const applyLayout = (() => {
+ let previousStyles;
+
+ return layout => {
+ const layouts = {
+ centered: `
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ margin: 0;
+ padding: 1rem;
+ box-sizing: border-box;
+ `,
+ fullscreen: `
+ margin: 0;
+ `,
+ padded: `
+ margin: 0;
+ padding: 1rem;
+ `,
+ };
+ const styles = layouts[layout] || layouts.padded;
+
+ if (styles !== previousStyles) {
+ document.body.style = styles;
+ previousStyles = styles;
+ }
+ };
+})();
+
export default function start(render, { decorateStory } = {}) {
const context = getContext(decorateStory);
@@ -140,9 +171,12 @@ export default function start(render, { decorateStory } = {}) {
const data = storyStore.fromId(storyId);
- const { kind, name, getDecorated, id, parameters, error } = data || {};
+ const { kind, name, getDecorated, id, parameters = {}, error } = data || {};
+
+ const { docsOnly, layout } = parameters;
+ applyLayout(layout);
- const viewMode = parameters && parameters.docsOnly ? 'docs' : urlViewMode;
+ const viewMode = docsOnly ? 'docs' : urlViewMode;
const renderContext = {
...context,
@@ -220,7 +254,7 @@ export default function start(render, { decorateStory } = {}) {
// Given a cleaned up state, render the appropriate view mode
switch (viewMode) {
case 'docs': {
- const docs = (parameters && parameters.docs) || {};
+ const docs = parameters.docs || {};
const DocsContainer = docs.container || (({ children }) => <>{children}>);
const Page = docs.page || NoDocs;
ReactDOM.render(