Skip to content

Commit

Permalink
Fixed #453 - Maximizable Dialogs
Browse files Browse the repository at this point in the history
  • Loading branch information
Çağatay Çivici authored and Çağatay Çivici committed Jun 26, 2018
1 parent 6b9d70e commit 32e74ad
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 29 deletions.
15 changes: 11 additions & 4 deletions src/components/dialog/Dialog.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@
.ui-draggable .ui-dialog-titlebar {
cursor: move;
}

.ui-dialog .ui-dialog-titlebar-icon {
text-decoration: none
}
.ui-dialog .ui-dialog-titlebar-close {
text-decoration: none;
float: right;
float: right;
padding: .125em;
cursor: pointer;
border: 1px solid transparent;
}
.ui-dialog .ui-dialog-titlebar-close span {

.ui-dialog .ui-dialog-titlebar-icon span {
display: block;
margin: 0;
font-size: 1.25em;
}

.ui-dialog-footer {
Expand All @@ -59,6 +61,11 @@
height: 100%;
}

.ui-dialog-maximized {
-webkit-transition: left .3s, top .3s, width .3s,height .3s;
transition: left .3s, top .3s, width .3s,height .3s;
}

/* ConfirmDialog */
.ui-confirmdialog {
width: 30em;
Expand Down
4 changes: 2 additions & 2 deletions src/components/dialog/Dialog.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface DialogProps {
width?: string;
height?: string;
modal?: boolean;
onHide(): void
onHide(): void;
onShow?(): void;
draggable?: boolean;
resizable?: boolean;
Expand All @@ -30,7 +30,7 @@ interface DialogProps {
baseZIndex?: number;
minX?: number;
minY?: number;
autoAlign?: boolean;
maximizable?: boolean;
}

export class Dialog extends React.Component<DialogProps,any> {}
92 changes: 84 additions & 8 deletions src/components/dialog/Dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export class Dialog extends Component {
appendTo: null,
baseZIndex: 0,
minX: 0,
minY: 0
minY: 0,
maximizable: false
}

static propTypes = {
Expand Down Expand Up @@ -68,26 +69,30 @@ export class Dialog extends Component {
appendTo: PropTypes.object,
baseZIndex: PropTypes.number,
minX: PropTypes.number,
minY: PropTypes.number
minY: PropTypes.number,
maximizable: PropTypes.bool
};

constructor(props) {
super(props);
this.state = {};
this.state = {
maximized: false
};
this.onClose = this.onClose.bind(this);
this.initDrag = this.initDrag.bind(this);
this.endDrag = this.endDrag.bind(this);
this.moveOnTop = this.moveOnTop.bind(this);
this.onCloseMouseDown = this.onCloseMouseDown.bind(this);
this.initResize = this.initResize.bind(this);
this.toggleMaximize = this.toggleMaximize.bind(this);

this.id = this.props.id || UniqueComponentId();
}

positionOverlay() {
let viewport = DomHandler.getViewport();
if(DomHandler.getOuterHeight(this.container) > viewport.height) {
this.content.style.height = (viewport.height * .75) + 'px';
this.contentElement.style.height = (viewport.height * .75) + 'px';
}

if(this.props.positionLeft >= 0 && this.props.positionTop >= 0) {
Expand Down Expand Up @@ -115,6 +120,10 @@ export class Dialog extends Component {
if(this.props.modal) {
this.disableModality();
}

if(this.state.maximized) {
DomHandler.removeClass(document.body, 'ui-overflow-hidden');
}
}

show() {
Expand All @@ -131,8 +140,49 @@ export class Dialog extends Component {
this.container.style.zIndex = String(this.props.baseZIndex + DomHandler.generateZIndex());
this.positionOverlay();
DomHandler.fadeIn(this.container, 250);

if(this.state.maximized) {
DomHandler.removeClass(document.body, 'ui-overflow-hidden');
}
}

toggleMaximize(event) {
this.setState({
maximized: !this.state.maximized
});
event.preventDefault();
}

maximize() {
DomHandler.addClass(this.container, 'ui-dialog-maximized');
this.preMaximizePageX = parseFloat(this.container.style.top);
this.preMaximizePageY = parseFloat(this.container.style.left);
this.preMaximizeContainerWidth = DomHandler.getOuterWidth(this.container);
this.preMaximizeContainerHeight = DomHandler.getOuterHeight(this.container);
this.preMaximizeContentHeight = DomHandler.getOuterHeight(this.contentElement);

this.container.style.top = '0px';
this.container.style.left = '0px';
this.container.style.width = '100vw';
this.container.style.height = '100vh';
const diffHeight = DomHandler.getOuterHeight(this.headerElement) + DomHandler.getOuterHeight(this.footerElement) + parseFloat(this.container.style.top);
this.contentElement.style.height = 'calc(100vh - ' + diffHeight +'px)';

DomHandler.addClass(document.body, 'ui-overflow-hidden');
}

restoreMaximize() {
this.container.style.top = this.preMaximizePageX + 'px';
this.container.style.left = this.preMaximizePageY + 'px';
this.container.style.width = this.preMaximizeContainerWidth + 'px';
this.container.style.height = this.preMaximizeContainerHeight + 'px';
this.contentElement.style.height = this.preMaximizeContentHeight + 'px';

DomHandler.removeClass(document.body, 'ui-overflow-hidden');

setTimeout(() => DomHandler.removeClass(this.container, 'ui-dialog-maximized'), 300);
}

center() {
var elementWidth = DomHandler.getOuterWidth(this.container);
var elementHeight = DomHandler.getOuterHeight(this.container);
Expand Down Expand Up @@ -278,7 +328,7 @@ export class Dialog extends Component {

if(newHeight > this.props.minHeight) {
this.container.style.height = newHeight + 'px';
this.content.style.height = contentHeight + deltaY + 'px';
this.contentElement.style.height = contentHeight + deltaY + 'px';
}

this.lastPageX = event.pageX;
Expand Down Expand Up @@ -426,6 +476,15 @@ export class Dialog extends Component {
this.hide();
}
}

if(prevState.maximized !== this.state.maximized) {
if(this.state.maximized) {
this.maximize();
}
else {
this.restoreMaximize();
}
}
}

componentWillUnmount() {
Expand All @@ -447,14 +506,31 @@ export class Dialog extends Component {
}
}

renderMaximizeIcon() {
const iconClassName = classNames('pi', {'pi-window-maximize': !this.state.maximized, 'pi-window-minimize': this.state.maximized});

if(this.props.maximizable) {
return (
<a role="button" className="ui-dialog-titlebar-icon ui-dialog-titlebar-maximize ui-corner-all" onClick={this.toggleMaximize}>
<span className={iconClassName}></span>
</a>
);
}
else {
return null;
}
}

renderHeader() {
if(this.props.showHeader) {
let closeIcon = this.renderCloseIcon();
let maximizeIcon = this.renderMaximizeIcon();

return (
<div className="ui-dialog-titlebar ui-widget-header ui-helper-clearfix ui-corner-top" onMouseDown={this.initDrag}>
<div ref={(el) => { this.headerElement = el; }} className="ui-dialog-titlebar ui-widget-header ui-helper-clearfix ui-corner-top" onMouseDown={this.initDrag}>
<span id={this.id + '_label'} className="ui-dialog-title">{this.props.header}</span>
{closeIcon}
{maximizeIcon}
</div>
);
}
Expand All @@ -465,7 +541,7 @@ export class Dialog extends Component {

renderContent() {
return (
<div ref={(el) => this.content = el} className="ui-dialog-content ui-widget-content" style={this.props.contentStyle}>
<div ref={(el) => this.contentElement = el} className="ui-dialog-content ui-widget-content" style={this.props.contentStyle}>
{this.props.children}
</div>
);
Expand All @@ -474,7 +550,7 @@ export class Dialog extends Component {
renderFooter() {
if(this.props.footer) {
return (
<div className="ui-dialog-footer ui-widget-content">{this.props.footer}</div>
<div ref={(el) => { this.footerElement = el; }} className="ui-dialog-footer ui-widget-content">{this.props.footer}</div>
);
}
else {
Expand Down
34 changes: 22 additions & 12 deletions src/components/utils/DomHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,35 @@ export default class DomHandler {
}

static getOuterWidth(el, margin) {
let width = el.offsetWidth;
if (el) {
let width = el.offsetWidth;

if (margin) {
let style = getComputedStyle(el);
width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
}
if (margin) {
let style = getComputedStyle(el);
width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
}

return width;
return width;
}
else {
return 0;
}
}

static getOuterHeight(el, margin) {
let height = el.offsetHeight;
if (el) {
let height = el.offsetHeight;

if (margin) {
let style = getComputedStyle(el);
height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
if (margin) {
let style = getComputedStyle(el);
height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
}

return height;
}
else {
return 0;
}

return height;
}

static getViewport() {
Expand Down
12 changes: 9 additions & 3 deletions src/showcase/dialog/DialogDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class DialogDemo extends Component {
</div>

<div className="content-section implementation">
<Dialog header="Godfather I" visible={this.state.visible} width="350px" modal={true} footer={footer} minY={70} onHide={this.onHide} appendTo={document.body}>
<Dialog header="Godfather I" visible={this.state.visible} width="350px" modal={true} footer={footer} minY={70} onHide={this.onHide} maximizable={true}>
The story begins as Don Vito Corleone, the head of a New York Mafia family, oversees his daughter's wedding.
His beloved son Michael has just come home from the war, but does not intend to become part of his father's business.
Through Michael's life the nature of the family business becomes clear. The business of the family is just like the head of the family,
Expand Down Expand Up @@ -76,7 +76,7 @@ import {Dialog} from 'primereact/components/dialog/Dialog';
</CodeHighlight>

<h3>Getting Started</h3>
<p>Dialog is used as a container and visibility is controlled with visible property. "onHide" event is required to update user's state.</p>
<p>Dialog is used as a container and visibility is controlled with visible property. "onHide" event is required to update the visibility state.</p>
<CodeHighlight className="html">
{`
<Dialog header="Godfather I" visible={this.state.visible} width="350px" modal={true} onHide={this.onHide}>
Expand Down Expand Up @@ -304,6 +304,12 @@ const footer = (
<td>0</td>
<td>Minimum value for the top coordinate of dialog in dragging.</td>
</tr>
<tr>
<td>maximizable</td>
<td>boolean</td>
<td>false</td>
<td>Whether the dialog can be displayed full screen.</td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -426,7 +432,7 @@ export class DialogDemo extends Component {
</div>
<div className="content-section implementation">
<Dialog header="Godfather I" visible={this.state.visible} width="350px" modal={true} minY={70} footer={footer} onHide={this.onHide}>
<Dialog header="Godfather I" visible={this.state.visible} width="350px" modal={true} footer={footer} minY={70} onHide={this.onHide} maximizable={true}>
The story begins as Don Vito Corleone, the head of a New York Mafia family, oversees his daughter's wedding.
His beloved son Michael has just come home from the war, but does not intend to become part of his father's business.
Through Michael's life the nature of the family business becomes clear. The business of the family is just like the head of the family,
Expand Down

0 comments on commit 32e74ad

Please sign in to comment.