Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addon-docs: Fix Preview scaling with transform instead of zoom #12845

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
30d1ea1
use transform instead of zoom to scale component in Preview
Tomastomaslol Oct 21, 2020
9c681dc
Add new zoom component and use it in Preview blocks
Tomastomaslol Oct 24, 2020
704d91e
removed unused imports
Tomastomaslol Oct 25, 2020
7a9575a
add support to be able to zoom on a iframe
Tomastomaslol Oct 25, 2020
6e969b5
add Element to children props for Zoom
Tomastomaslol Oct 25, 2020
f31bf0d
fix Zoom Props
Oct 25, 2020
16e86e7
split zoom element and iframe in seperate Zoom components
Tomastomaslol Oct 27, 2020
69e4e78
do not pass id to Zoom iframe. make initial zommed stories out less z…
Tomastomaslol Oct 27, 2020
d60370b
Merge branch 'next' of https://github.com/storybookjs/storybook into …
Tomastomaslol Oct 27, 2020
c875d45
only wrap element in ZoomElement if css Zoom is not supported. Use sp…
Tomastomaslol Oct 28, 2020
09e5fdd
re-add css zoom to target all child elements for ZoomElement
Tomastomaslol Oct 28, 2020
50e7385
access iframe as a ref in Zoom.Iframe. add innerWrapper for ZoomEleme…
Tomastomaslol Oct 29, 2020
79d755e
Merge branch 'next' of https://github.com/storybookjs/storybook into …
Tomastomaslol Oct 29, 2020
bb9f95d
Merge branch 'next' into pr/12845
shilman Nov 1, 2020
4e65bd6
do not use default exports for Zoom component
Tomastomaslol Nov 9, 2020
57c83c9
Merge branch 'next' of https://github.com/storybookjs/storybook into …
Tomastomaslol Nov 9, 2020
7f79f75
Merge branch '12324_zoom_buttons_in_docs_do_not_work' of github.com:T…
Tomastomaslol Nov 9, 2020
de43e6e
fix zoom iframe story. make udateable using controls
Tomastomaslol Nov 12, 2020
790b371
Merge branch 'next' of https://github.com/storybookjs/storybook into …
Tomastomaslol Nov 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions lib/components/src/Zoom/Zoom.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { CSSProperties, useEffect, useState } from 'react';
import { Zoom } from './Zoom';

export default {
component: Zoom,
title: 'Basics/Zoom',
argTypes: {
scale: {
control: { type: 'range', min: 0.2, max: 30, step: 0.02 },
},
},
};
const EXAMPLE_ELEMENT = (
<div
style={{
width: 2000,
height: 2000,
border: '10px solid orangered',
background: `url('data:image/png;base64,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')`,
}}
/>
);

const TemplateElement = (args) => <Zoom.Element {...args} />;

export const elementActualSize = TemplateElement.bind({});

elementActualSize.args = {
scale: 1,
children: EXAMPLE_ELEMENT,
};

export const elementZoomedIn = TemplateElement.bind({});

elementZoomedIn.args = {
scale: 0.7,
children: EXAMPLE_ELEMENT,
};

export const elementZoomedOut = TemplateElement.bind({});

elementZoomedOut.args = {
scale: 3,
children: EXAMPLE_ELEMENT,
};

const style: CSSProperties = {
width: '500px',
height: '500px',
border: '2px solid hotpink',
position: 'relative',
};

const TemplateIFrame = (args) => {
const iFrameRef = React.useRef<HTMLIFrameElement>(null);
const [scale, setScale] = useState(1);
const [loaded, hasLoaded] = useState(false);

useEffect(() => {
if (loaded) {
setScale(args.scale);
}
}, [args.scale, loaded]);
return (
<Zoom.IFrame iFrameRef={iFrameRef} scale={scale} active={args.active}>
<iframe
id="iframe"
title="UI Panel"
onLoad={() => hasLoaded(true)}
src="/iframe.html?id=ui-panel--default&viewMode=story"
style={style}
ref={iFrameRef}
allowFullScreen
/>
</Zoom.IFrame>
);
};
export const iFrameActualSize = TemplateIFrame.bind({});

iFrameActualSize.args = {
scale: 1,
active: true,
};

export const iFrameZoomedIn = TemplateIFrame.bind({});

iFrameZoomedIn.args = {
scale: 0.7,
active: true,
};

export const iFrameZoomedOut = TemplateIFrame.bind({});

iFrameZoomedOut.args = {
scale: 3,
active: true,
};
11 changes: 11 additions & 0 deletions lib/components/src/Zoom/Zoom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import window from 'global';
import { ZoomElement as Element } from './ZoomElement';
import { ZoomIFrame as IFrame } from './ZoomIFrame';

export const browserSupportsCssZoom = (): boolean =>
window.document.implementation.createHTMLDocument().body.style.zoom !== undefined;

export const Zoom = {
Element,
IFrame,
};
40 changes: 40 additions & 0 deletions lib/components/src/Zoom/ZoomElement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { ReactElement, useEffect, useState } from 'react';
import { styled } from '@storybook/theming';
import { browserSupportsCssZoom } from './Zoom';

const ZoomElementWrapper = styled.div<{ scale: number; height: number }>(({ scale = 1, height }) =>
browserSupportsCssZoom()
? {
'> *': {
zoom: 1 / scale,
},
}
: {
height: height + 50,
transformOrigin: 'top left',
transform: `scale(${1 / scale})`,
}
);
type ZoomProps = {
scale: number;
children: ReactElement | ReactElement[];
};

export function ZoomElement({ scale, children }: ZoomProps) {
const componentWrapperRef = React.useRef<HTMLDivElement>(null);
const [height, setHeight] = useState(0);

useEffect(() => {
if (componentWrapperRef.current) {
setHeight(componentWrapperRef.current.getBoundingClientRect().height);
}
}, [scale, componentWrapperRef.current]);

return (
<ZoomElementWrapper scale={scale} height={height}>
<div ref={componentWrapperRef} className="innerZoomElementWrapper">
{children}
</div>
</ZoomElementWrapper>
);
}
67 changes: 67 additions & 0 deletions lib/components/src/Zoom/ZoomIFrame.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Component, ReactElement } from 'react';
import { browserSupportsCssZoom } from './Zoom';

export type IZoomIFrameProps = {
scale: number;
children: ReactElement<HTMLIFrameElement>;
iFrameRef: React.MutableRefObject<HTMLIFrameElement>;
active?: boolean;
};

export class ZoomIFrame extends Component<IZoomIFrameProps> {
iframe: HTMLIFrameElement = null;

componentDidMount() {
const { iFrameRef } = this.props;
this.iframe = iFrameRef.current;
}

shouldComponentUpdate(nextProps: IZoomIFrameProps) {
const { scale, active } = this.props;

if (scale !== nextProps.scale) {
this.setIframeInnerZoom(nextProps.scale);
}

if (active !== nextProps.active) {
this.iframe.setAttribute('data-is-storybook', nextProps.active ? 'true' : 'false');
}

// this component renders an iframe, which gets updates via post-messages
// never update this component, it will cause the iframe to refresh
return false;
}

setIframeInnerZoom(scale: number) {
try {
if (browserSupportsCssZoom()) {
Object.assign(this.iframe.contentDocument.body.style, {
Copy link
Member

Choose a reason for hiding this comment

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

iframe.contentDocument can't work cross origin.. but I'm guessing addressing that is out of scope.

can we use useRef() to get the current element instead though?

zoom: 1 / scale,
});
} else {
Object.assign(this.iframe.contentDocument.body.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
transformOrigin: 'top left',
});
}
} catch (e) {
this.setIframeZoom(scale);
}
}

setIframeZoom(scale: number) {
Object.assign(this.iframe.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
transformOrigin: 'top left',
});
}

render() {
const { children } = this.props;
return children;
}
}
31 changes: 15 additions & 16 deletions lib/components/src/blocks/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Source, SourceProps } from './Source';
import { ActionBar, ActionItem } from '../ActionBar/ActionBar';
import { Toolbar } from './Toolbar';
import { ZoomContext } from './ZoomContext';
import { Zoom } from '../Zoom/Zoom';

export interface PreviewProps {
isColumn?: boolean;
Expand All @@ -20,15 +21,15 @@ export interface PreviewProps {

type layout = 'padded' | 'fullscreen' | 'centered';

const ChildrenContainer = styled.div<PreviewProps & { zoom: number; layout: layout }>(
const ChildrenContainer = styled.div<PreviewProps & { layout: layout }>(
({ isColumn, columns, layout }) => ({
display: isColumn || !columns ? 'block' : 'flex',
position: 'relative',
flexWrap: 'wrap',
overflow: 'auto',
flexDirection: isColumn ? 'column' : 'row',

'& > *': isColumn
'& .innerZoomElementWrapper > *': isColumn
? {
width: layout !== 'fullscreen' ? 'calc(100% - 20px)' : '100%',
display: 'block',
Expand All @@ -43,7 +44,7 @@ const ChildrenContainer = styled.div<PreviewProps & { zoom: number; layout: layo
? {
padding: '30px 20px',
margin: -10,
'& > *': {
'& .innerZoomElementWrapper > *': {
width: 'auto',
border: '10px solid transparent!important',
},
Expand All @@ -59,13 +60,10 @@ const ChildrenContainer = styled.div<PreviewProps & { zoom: number; layout: layo
alignItems: 'center',
}
: {},
({ zoom = 1 }) => ({
'> *': {
zoom: 1 / zoom,
},
}),
({ columns }) =>
columns && columns > 1 ? { '> *': { minWidth: `calc(100% / ${columns} - 20px)` } } : {}
columns && columns > 1
? { '.innerZoomElementWrapper > *': { minWidth: `calc(100% / ${columns} - 20px)` } }
: {}
);

const StyledSource = styled(Source)<{}>(({ theme }) => ({
Expand Down Expand Up @@ -217,15 +215,16 @@ const Preview: FunctionComponent<PreviewProps> = ({
<ChildrenContainer
isColumn={isColumn || !Array.isArray(children)}
columns={columns}
zoom={scale}
layout={layout}
>
{Array.isArray(children) ? (
// eslint-disable-next-line react/no-array-index-key
children.map((child, i) => <div key={i}>{child}</div>)
) : (
<div>{children}</div>
)}
<Zoom.Element scale={scale}>
{Array.isArray(children) ? (
// eslint-disable-next-line react/no-array-index-key
children.map((child, i) => <div key={i}>{child}</div>)
) : (
<div>{children}</div>
)}
</Zoom.Element>
</ChildrenContainer>
<ActionBar actionItems={actionItems} />
</Relative>
Expand Down
1 change: 1 addition & 0 deletions lib/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { ActionBar } from './ActionBar/ActionBar';
export { Spaced } from './spaced/Spaced';
export { Placeholder } from './placeholder/placeholder';
export { ScrollArea } from './ScrollArea/ScrollArea';
export { Zoom } from './Zoom/Zoom';

// Forms
export { Button } from './Button/Button';
Expand Down
74 changes: 11 additions & 63 deletions lib/ui/src/components/preview/iframe.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import window from 'global';
import React, { Component, IframeHTMLAttributes } from 'react';

import React, { IframeHTMLAttributes } from 'react';
import { styled } from '@storybook/theming';

const FIREFOX_BROWSER = 'Firefox';
import { Zoom } from '@storybook/components';

const StyledIframe = styled.iframe({
position: 'absolute',
Expand All @@ -25,70 +22,21 @@ export interface IFrameProps {
active: boolean;
}

export class IFrame extends Component<IFrameProps & IframeHTMLAttributes<HTMLIFrameElement>> {
iframe: HTMLIFrameElement = null;

componentDidMount() {
const { id } = this.props;
this.iframe = window.document.getElementById(id);
}

shouldComponentUpdate(nextProps: IFrameProps) {
const { scale, active } = this.props;

if (scale !== nextProps.scale) {
this.setIframeInnerZoom(nextProps.scale);
}

if (active !== nextProps.active) {
this.iframe.setAttribute('data-is-storybook', nextProps.active ? 'true' : 'false');
}

// this component renders an iframe, which gets updates via post-messages
// never update this component, it will cause the iframe to refresh
return false;
}

setIframeInnerZoom(scale: number) {
try {
if (window.navigator.userAgent.indexOf(FIREFOX_BROWSER) !== -1) {
Object.assign(this.iframe.contentDocument.body.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
transformOrigin: 'top left',
});
} else {
Object.assign(this.iframe.contentDocument.body.style, {
zoom: 1 / scale,
});
}
} catch (e) {
this.setIframeZoom(scale);
}
}

setIframeZoom(scale: number) {
Object.assign(this.iframe.style, {
width: `${scale * 100}%`,
height: `${scale * 100}%`,
transform: `scale(${1 / scale})`,
transformOrigin: 'top left',
});
}

render() {
const { id, title, src, allowFullScreen, scale, active, ...rest } = this.props;
return (
export function IFrame(props: IFrameProps & IframeHTMLAttributes<HTMLIFrameElement>) {
const { active, id, title, src, allowFullScreen, scale, ...rest } = props;
const iFrameRef = React.useRef<HTMLIFrameElement>(null);
return (
<Zoom.IFrame scale={scale} active={active} iFrameRef={iFrameRef}>
<StyledIframe
onLoad={() => this.iframe.setAttribute('data-is-loaded', 'true')}
data-is-storybook={active ? 'true' : 'false'}
onLoad={(e) => e.currentTarget.setAttribute('data-is-loaded', 'true')}
id={id}
title={title}
src={src}
allowFullScreen={allowFullScreen}
ref={iFrameRef}
{...rest}
/>
);
}
</Zoom.IFrame>
);
}