Skip to content

Commit 873bb78

Browse files
committed
#226 - Code changes for consistency
1 parent a1a98e6 commit 873bb78

File tree

9 files changed

+134
-105
lines changed

9 files changed

+134
-105
lines changed

docs/documentation/docs/controls/IFrameDialog.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IFrameDialog control
22

3-
This control renders a Dialog with an iframe as a content.
3+
This control renders a Dialog with an iframe as content.
44

55
Here is an example of the control in action:
66

@@ -58,4 +58,4 @@ The IFrameDialog component can be configured with the following properties:
5858
| scrolling | string | no | Specifies whether or not to display scrollbars in an iframe |
5959
| seamless | string | no | When present, it specifies that the iframe should look like it is a part of the containing document (no borders or scrollbars) |
6060

61-
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/FileTypeIcon)
61+
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/IFrameDialog)

docs/documentation/docs/controls/IFramePanel.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IFramePanel control
22

3-
This control renders a Panel with an iframe as a content.
3+
This control renders a Panel with an iframe as content.
44

55
Here is an example of the control in action:
66

@@ -21,15 +21,13 @@ import { IFramePanel } from "@pnp/spfx-controls-react/lib/IFramePanel";
2121

2222

2323
```TypeScript
24-
<IFramePanel
25-
url={this.state.iFrameUrl}
26-
type={PanelType.medium}
27-
headerText="Panel Title"
28-
closeButtonAriaLabel="Close"
29-
isOpen={this.state.iFramePanelOpened}
30-
onDismiss={this._onDismiss.bind(this)}
31-
iframeOnLoad={this._onIframeLoaded.bind(this)}
32-
/>
24+
<IFramePanel url={this.state.iFrameUrl}
25+
type={PanelType.medium}
26+
headerText="Panel Title"
27+
closeButtonAriaLabel="Close"
28+
isOpen={this.state.iFramePanelOpened}
29+
onDismiss={this._onDismiss.bind(this)}
30+
iframeOnLoad={this._onIframeLoaded.bind(this)} />
3331
```
3432

3533
## Implementation

src/controls/iFramePanel/IFramePanel.tsx

Lines changed: 18 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,21 @@
11
import * as React from 'react';
2-
import { Guid } from "@microsoft/sp-core-library";
3-
import styles from './IFramePanelContent.module.scss';
4-
import { Panel, IPanelProps } from 'office-ui-fabric-react/lib/Panel';
2+
import { Panel } from 'office-ui-fabric-react/lib/Panel';
53
import omit = require('lodash/omit');
64
import { IFramePanelContent } from './IFramePanelContent';
7-
8-
export interface IIFramePanelProps extends IPanelProps {
9-
/**
10-
* iframe Url
11-
*/
12-
url: string;
13-
/**
14-
* iframe height, if null then hight is calculated
15-
*/
16-
height?: string;
17-
/**
18-
* Specifies if iframe content can be displayed in a full screen.
19-
* Usage: <IFrameDialog allowFullScreen />
20-
*/
21-
allowFullScreen?: boolean;
22-
/**
23-
* iframe's onload event handler
24-
*/
25-
iframeOnLoad?: (iframe: any) => void;
26-
/**
27-
* Specifies if transparency is allowed in iframe
28-
*/
29-
allowTransparency?: boolean;
30-
/**
31-
* Specifies the name of an <iframe>
32-
*/
33-
name?: string;
34-
/**
35-
* Enables an extra set of restrictions for the content in an <iframe>
36-
*/
37-
sandbox?: string;
38-
/**
39-
* Specifies whether or not to display scrollbars in an <iframe>
40-
*/
41-
scrolling?: string;
42-
/**
43-
* When present, it specifies that the <iframe> should look like it is a part of the containing document (no borders or scrollbars)
44-
*/
45-
seamless?: boolean;
46-
}
47-
48-
export interface IIFramePanelState {
49-
}
5+
import { IIFramePanelProps, IIFramePanelState } from '.';
506

517
export class IFramePanel extends React.Component<IIFramePanelProps, IIFramePanelState> {
8+
529
constructor(props: IIFramePanelProps) {
5310
super(props);
5411

55-
this.state = {
56-
};
12+
this.state = {};
5713
}
5814

15+
/**
16+
* Default React render
17+
*/
5918
public render(): React.ReactElement<IIFramePanelProps> {
60-
6119
const {
6220
height,
6321
allowFullScreen,
@@ -68,21 +26,19 @@ export class IFramePanel extends React.Component<IIFramePanelProps, IIFramePanel
6826
scrolling,
6927
seamless
7028
} = this.props;
29+
7130
return (
72-
<Panel
73-
{...omit(this.props, 'className')}
74-
>
31+
<Panel {...omit(this.props, 'className')} >
7532
<IFramePanelContent src={this.props.url}
76-
iframeOnLoad={iframeOnLoad}
77-
close={this.props.onDismiss}
78-
height={height}
79-
allowFullScreen={allowFullScreen}
80-
allowTransparency={allowTransparency}
81-
name={name}
82-
sandbox={sandbox}
83-
scrolling={scrolling}
84-
seamless={seamless}
85-
/>
33+
iframeOnLoad={iframeOnLoad}
34+
close={this.props.onDismiss}
35+
height={height}
36+
allowFullScreen={allowFullScreen}
37+
allowTransparency={allowTransparency}
38+
name={name}
39+
sandbox={sandbox}
40+
scrolling={scrolling}
41+
seamless={seamless} />
8642
</Panel>
8743
);
8844
}

src/controls/iFramePanel/IFramePanelContent.tsx

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,7 @@ import * as React from "react";
22
import styles from './IFramePanelContent.module.scss';
33
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
44
import omit = require('lodash/omit');
5-
6-
export interface IIFramePanelContentProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {
7-
close: () => void;
8-
iframeOnLoad?: (iframe: any) => void;
9-
}
10-
11-
export interface IIFramePanelContentState {
12-
isContentVisible?: boolean;
13-
}
5+
import { IIFramePanelContentProps, IIFramePanelContentState } from ".";
146

157
/**
168
* IFrame Panel content
@@ -27,29 +19,47 @@ export class IFramePanelContent extends React.Component<IIFramePanelContentProps
2719
window.onresize = this.resizeIframe;
2820
}
2921

22+
/**
23+
* Resize the iframe element
24+
*/
3025
private resizeIframe = () => {
3126
if (!this.props.height) {
3227
if (this._iframe) {
33-
let mainDiv = this._iframe.parentElement.parentElement.parentElement.parentElement as HTMLDivElement;
34-
let commandsDiv = mainDiv.getElementsByClassName("ms-Panel-commands")[0] as HTMLDivElement;
35-
let headerDiv = mainDiv.getElementsByClassName("ms-Panel-header")[0] as HTMLDivElement;
36-
let footerDiv = mainDiv.getElementsByClassName("ms-Panel-footer")[0] as HTMLDivElement;
28+
const mainDiv = this.findParent(this._iframe, "ms-Panel-main");
29+
const commandsDiv = mainDiv.querySelector(".ms-Panel-commands") as HTMLDivElement;
30+
const headerDiv = mainDiv.querySelector("ms-Panel-header") as HTMLDivElement;
31+
const footerDiv = mainDiv.querySelector("ms-Panel-footer") as HTMLDivElement;
3732

3833
let height = this.getTrueHeight(mainDiv);
3934
height = height - this.getTrueHeight(commandsDiv);
4035
height = height - this.getTrueHeight(headerDiv);
4136
height = height - this.getTrueHeight(footerDiv);
4237
height = height - 20; // padding on content div
4338

44-
4539
this._iframe.height = height.toString() + 'px';
4640
}
4741
}
4842
}
4943

50-
private getTrueHeight(element): number {
51-
if (element) {
52-
let style = element.currentStyle || window.getComputedStyle(element);
44+
/**
45+
* Find the parent element
46+
*
47+
* @param elm
48+
* @param className
49+
*/
50+
private findParent(elm: HTMLElement, className: string) {
51+
while ((elm = elm.parentElement) && !elm.classList.contains(className));
52+
return elm;
53+
}
54+
55+
/**
56+
* Get the element its height
57+
*
58+
* @param elm
59+
*/
60+
private getTrueHeight(elm: HTMLElement): number {
61+
if (elm) {
62+
const style = elm.style || window.getComputedStyle(elm);
5363
let marginTop = parseInt((style.marginTop as string).replace("px", ""));
5464
let marginBottom = parseInt((style.marginTop as string).replace("px", ""));
5565
if (isNaN(marginTop)) {
@@ -58,24 +68,16 @@ export class IFramePanelContent extends React.Component<IIFramePanelContentProps
5868
if (isNaN(marginBottom)) {
5969
marginBottom = 0;
6070
}
61-
return element.offsetHeight + marginTop + marginBottom;
62-
}
63-
else {
71+
return elm.offsetHeight + marginTop + marginBottom;
72+
} else {
6473
return 0;
6574
}
6675
}
6776

68-
public render(): JSX.Element {
69-
return (<div className={styles.iFrameDialog}>
70-
<iframe ref={(iframe) => { this._iframe = iframe; }} frameBorder={0} onLoad={this._iframeOnLoad} style={{ width: '100%', height: this.props.height, visibility: this.state.isContentVisible ? 'visible' : 'hidden' }} {...omit(this.props, 'height')} />
71-
{!this.state.isContentVisible &&
72-
<div className={styles.spinnerContainer}>
73-
<Spinner size={SpinnerSize.large} />
74-
</div>}
75-
</div>);
76-
}
77-
78-
private _iframeOnLoad = () => {
77+
/**
78+
* On iframe load event
79+
*/
80+
private iframeOnLoad = () => {
7981
try { // for cross origin requests we can have issues with accessing frameElement
8082
this._iframe.contentWindow.frameElement.cancelPopUp = this.props.close;
8183
}
@@ -95,4 +97,23 @@ export class IFramePanelContent extends React.Component<IIFramePanelContentProps
9597
isContentVisible: true
9698
});
9799
}
100+
101+
/**
102+
* Default React render
103+
*/
104+
public render(): JSX.Element {
105+
return (
106+
<div className={styles.iFrameDialog}>
107+
<iframe ref={(iframe) => { this._iframe = iframe; }} frameBorder={0} onLoad={this.iframeOnLoad} style={{ width: '100%', height: this.props.height, visibility: this.state.isContentVisible ? 'visible' : 'hidden' }} {...omit(this.props, 'height')} />
108+
109+
{
110+
!this.state.isContentVisible && (
111+
<div className={styles.spinnerContainer}>
112+
<Spinner size={SpinnerSize.large} />
113+
</div>
114+
)
115+
}
116+
</div>
117+
);
118+
}
98119
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface IIFramePanelContentProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {
2+
close: () => void;
3+
iframeOnLoad?: (iframe: any) => void;
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface IIFramePanelContentState {
2+
isContentVisible?: boolean;
3+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { IPanelProps } from "office-ui-fabric-react/lib/Panel";
2+
3+
export interface IIFramePanelProps extends IPanelProps {
4+
/**
5+
* iframe Url
6+
*/
7+
url: string;
8+
/**
9+
* iframe height, if null then hight is calculated
10+
*/
11+
height?: string;
12+
/**
13+
* Specifies if iframe content can be displayed in a full screen.
14+
* Usage: <IFrameDialog allowFullScreen />
15+
*/
16+
allowFullScreen?: boolean;
17+
/**
18+
* iframe's onload event handler
19+
*/
20+
iframeOnLoad?: (iframe: any) => void;
21+
/**
22+
* Specifies if transparency is allowed in iframe
23+
*/
24+
allowTransparency?: boolean;
25+
/**
26+
* Specifies the name of an <iframe>
27+
*/
28+
name?: string;
29+
/**
30+
* Enables an extra set of restrictions for the content in an <iframe>
31+
*/
32+
sandbox?: string;
33+
/**
34+
* Specifies whether or not to display scrollbars in an <iframe>
35+
*/
36+
scrolling?: string;
37+
/**
38+
* When present, it specifies that the <iframe> should look like it is a part of the containing document (no borders or scrollbars)
39+
*/
40+
seamless?: boolean;
41+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export interface IIFramePanelState {
2+
}

src/controls/iFramePanel/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
export * from './IFramePanelContent.module.scss';
22
export * from './IFramePanelContent';
3+
export * from './IFramePanelContentProps';
4+
export * from './IFramePanelContentState';
35
export * from './IFramePanel';
6+
export * from './IFramePanelProps';
7+
export * from './IFramePanelState';

0 commit comments

Comments
 (0)