Skip to content

Commit

Permalink
Fix layout of Preview container (#8628)
Browse files Browse the repository at this point in the history
Fix layout of Preview container
  • Loading branch information
shilman committed Dec 2, 2019
1 parent d67633d commit 1b533fb
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 48 deletions.
Expand Up @@ -45,3 +45,5 @@ jsxOverride.story = {
docs: { page: () => <div>Hello docs</div> },
},
};

export const largerThanPreview = () => <div style={{ width: 1000, background: 'pink' }}>HUGE</div>;
39 changes: 33 additions & 6 deletions examples/official-storybook/stories/core/scroll.stories.js
@@ -1,29 +1,56 @@
import React from 'react';
import { styled } from '@storybook/theming';

import { Spaced } from '@storybook/components';

export default {
title: 'Core|Scroll',
};

const Horizontal = styled(props => <Spaced col={1} {...props} />)({
display: 'grid',
gridTemplateColumns: '100px calc(100vw + 100px) 100px',
});
const Vertical = styled(props => <Spaced row={1} {...props} />)({});

export const story1 = () => (
<div>
<Vertical>
<pre>START, when switching stories, you should be able to read this at the top of the page</pre>
<div style={{ height: '100vh' }} />
<pre style={{ height: '100vh' }}>middle</pre>
<pre>
END, this text should be below the scroll "fold" and therefore only be readable after
scrolling
</pre>
</div>
</Vertical>
);
story1.story = { name: 'story with 100vh padding 1' };

export const story2 = () => (
<div>
<Vertical>
<pre>START, when switching stories, you should be able to read this at the top of the page</pre>
<div style={{ height: '100vh' }} />
<pre style={{ height: '100vh' }}>middle</pre>
<pre>
END, this text should be below the scroll "fold" and therefore only be readable after
scrolling
</pre>
</div>
</Vertical>
);
story2.story = { name: 'story with 100vh padding 2' };

export const story3 = () => (
<Horizontal>
<pre>START</pre>
<pre>middle</pre>
<pre>END</pre>
</Horizontal>
);
story3.story = { name: 'story with 100vw+' };

export const story4 = () => (
<Horizontal>
<pre>START</pre>
<pre>middle</pre>
<pre>END</pre>
</Horizontal>
);
story4.story = { name: 'story with 100vw+ 2' };
18 changes: 17 additions & 1 deletion lib/components/src/blocks/Preview.stories.tsx
@@ -1,7 +1,8 @@
import React from 'react';
import { styled } from '@storybook/theming';

import { Spaced } from '../spaced/Spaced';
import { Preview } from './Preview';

import { Story } from './Story';
import { Button } from '../Button/Button';
import * as sourceStories from './Source.stories';
Expand Down Expand Up @@ -88,6 +89,21 @@ export const withToolbar = () => (
</Preview>
);

const Horizontal = styled(props => <Spaced col={1} {...props} />)({
display: 'grid',
gridTemplateColumns: '100px calc(100vw + 100px) 100px',
});

export const wide = () => (
<Preview withToolbar>
<Horizontal>
<div>START</div>
<div>middle</div>
<div>END</div>
</Horizontal>
</Preview>
);

export const withToolbarMulti = () => (
<Preview withToolbar>
<Story inline storyFn={buttonFn} title="story1" />
Expand Down
84 changes: 52 additions & 32 deletions lib/components/src/blocks/Preview.tsx
Expand Up @@ -7,7 +7,6 @@ import { getBlockBackgroundStyle } from './BlockBackgroundStyles';
import { Source, SourceProps } from './Source';
import { ActionBar, ActionItem } from '../ActionBar/ActionBar';
import { Toolbar } from './Toolbar';
import { ZoomContext } from './ZoomContext';

export interface PreviewProps {
isColumn?: boolean;
Expand All @@ -19,14 +18,16 @@ export interface PreviewProps {

const ChildrenContainer = styled.div<PreviewProps>(({ isColumn, columns }) => ({
display: 'flex',
position: 'relative',
flexWrap: 'wrap',
padding: '10px 20px 30px 20px',
overflow: 'auto',
flexDirection: isColumn ? 'column' : 'row',
marginTop: -20,

'> *': {
flex: columns ? `1 1 calc(100%/${columns} - 20px)` : `1 1 0%`,
marginRight: 20,
marginTop: 20,
maxWidth: '100%',
},
}));

Expand All @@ -47,23 +48,19 @@ const StyledSource = styled(Source)<{}>(({ theme }) => ({
},
}));

const PreviewWrapper = styled.div<PreviewProps>(
const PreviewContainer = styled.div<PreviewProps>(
({ theme, withSource, isExpanded }) => ({
...getBlockBackgroundStyle(theme),
padding: '30px 20px',
position: 'relative',
overflow: 'hidden',
margin: '25px 0 40px',
...getBlockBackgroundStyle(theme),
borderBottomLeftRadius: withSource && isExpanded && 0,
borderBottomRightRadius: withSource && isExpanded && 0,
borderBottomWidth: isExpanded && 0,
}),
({ withToolbar }) => withToolbar && { paddingTop: 64 }
({ withToolbar }) => withToolbar && { paddingTop: 40 }
);

const PreviewContainer = styled.div({
margin: '25px 0 40px',
});

interface SourceItem {
source?: React.ReactElement;
actionItem: ActionItem;
Expand Down Expand Up @@ -109,6 +106,31 @@ function getStoryId(children: React.ReactNode) {
return null;
}

const Relative = styled.div({
position: 'relative',
});

const Scale = styled.div<{ scale: number }>(
{
position: 'relative',
},
({ scale }) =>
scale
? {
transform: `scale(${1 / scale})`,
transformOrigin: 'top left',
}
: {}
);

const PositionedToolbar = styled(Toolbar)({
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: 40,
});

/**
* A preview component for showing one or more component `Story`
* items. The preview also shows the source for the component
Expand All @@ -132,28 +154,26 @@ const Preview: React.FunctionComponent<PreviewProps> = ({
}
const showToolbar = withToolbar && !Array.isArray(children);
return (
<PreviewContainer {...props}>
<PreviewWrapper {...{ withSource, withToolbar: showToolbar }}>
{showToolbar && (
<Toolbar
border
zoom={z => setScale(scale * z)}
resetZoom={() => setScale(1)}
storyId={getStoryId(children)}
baseUrl="./iframe.html"
/>
)}
<ZoomContext.Provider value={{ scale }}>
<ChildrenContainer isColumn={isColumn} columns={columns}>
{Array.isArray(children) ? (
children.map((child, i) => <div key={i.toString()}>{child}</div>)
) : (
<div>{children}</div>
)}
</ChildrenContainer>
</ZoomContext.Provider>
<PreviewContainer {...{ withSource, withToolbar: showToolbar }} {...props}>
{showToolbar && (
<PositionedToolbar
border
zoom={z => setScale(scale * z)}
resetZoom={() => setScale(1)}
storyId={getStoryId(children)}
baseUrl="./iframe.html"
/>
)}
<Relative>
<ChildrenContainer isColumn={isColumn} columns={columns}>
{Array.isArray(children) ? (
children.map((child, i) => <div key={i.toString()}>{child}</div>)
) : (
<Scale scale={scale}>{children}</Scale>
)}
</ChildrenContainer>
{withSource && <ActionBar actionItems={[actionItem]} />}
</PreviewWrapper>
</Relative>
{withSource && source}
</PreviewContainer>
);
Expand Down
15 changes: 8 additions & 7 deletions lib/components/src/blocks/Source.stories.tsx
Expand Up @@ -10,10 +10,9 @@ const jsxCode = `
<MyComponent boolProp scalarProp={1} complexProp={{ foo: 1, bar: '2' }}>
<SomeOtherComponent funcProp={(a) => a.id} />
</MyComponent>
`.trim();
`;

const jsxProps = {};
export const jsx = () => <Source code={jsxCode} language="jsx" />;
export const jsx = () => <Source code={jsxCode} language="jsx" format={false} />;

const cssCode = `
@-webkit-keyframes blinker {
Expand All @@ -27,10 +26,12 @@ const cssCode = `
-webkit-animation-timing-function: cubic-bezier(.5, 0, 1, 1);
-webkit-animation-duration: 1.7s;
}
`.trim();
`;

export const css = () => <Source code={cssCode} language="css" />;
export const css = () => <Source code={cssCode} language="css" format={false} />;

export const noStory = () => <Source error={SourceError.NO_STORY} />;
export const noStory = () => <Source error={SourceError.NO_STORY} format={false} />;

export const sourceUnavailable = () => <Source error={SourceError.SOURCE_UNAVAILABLE} />;
export const sourceUnavailable = () => (
<Source error={SourceError.SOURCE_UNAVAILABLE} format={false} />
);
4 changes: 2 additions & 2 deletions lib/components/src/spaced/Spaced.tsx
Expand Up @@ -58,11 +58,11 @@ export interface SpacedProps {
outer?: number | boolean;
}

export const Spaced: FunctionComponent<SpacedProps> = ({ col, row, outer, children }) => {
export const Spaced: FunctionComponent<SpacedProps> = ({ col, row, outer, children, ...rest }) => {
const outerAmount = toNumber(typeof outer === 'number' || !outer ? outer : col || row);

return (
<Container col={col} row={row} outer={outerAmount}>
<Container col={col} row={row} outer={outerAmount} {...rest}>
{children}
</Container>
);
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/client/preview/start.js
Expand Up @@ -274,6 +274,7 @@ export default function start(render, { decorateStory } = {}) {

if (!forceRender && viewMode !== 'docs') {
document.documentElement.scrollTop = 0;
document.documentElement.scrollLeft = 0;
}
};

Expand Down

1 comment on commit 1b533fb

@vercel
Copy link

@vercel vercel bot commented on 1b533fb Dec 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deployment failed with the following error:

ENOENT: no such file or directory, stat '/tmp/RXKkoikHLzjgU9qXbq1tJKuJ/repo/examples/official-storybook/built-storybooks/angular-cli'

Please sign in to comment.