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

JENKINS-39371 Dialog Component #113

Merged
merged 1 commit into from Nov 13, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -7,4 +7,4 @@
@import "components/table";
@import "components/toast";
@import "components/progressBar";
@import "components/popover";
@import "components/popups";
@@ -1,5 +1,3 @@
// TODO: Rename this file because it's for assorted modal popups not just popover

//--------------------------------------------------------------------------
//
// Popups, popovers, and dialogs
@@ -69,12 +67,54 @@
align-items: center;
width: 100%;
height: 80px;
min-height: 80px;
flex-shrink: 0;

This comment has been minimized.

Copy link
@kzantow

kzantow Nov 10, 2016

Collaborator

can we use flex for this? I thought we had to change away from flex to get IE working properly

This comment has been minimized.

Copy link
@sophistifunk

sophistifunk Nov 10, 2016

Author Collaborator

This is news to me. If we see bugs on whatever is the minimum version of IE we support I guess we can address it there, but I'd go with an ie-specific stylesheet rather than dropping flex-box, as it's miles better and it's everywhere in the editor.

This comment has been minimized.

Copy link
@cliffmeyers

cliffmeyers Nov 10, 2016

Collaborator

I think the problems with flexbox were limited to how the top-level page template in blueocean-web was laid out, causing IE issues. Perhaps @tfennelly can clarify since I think he was the one who fixed them.

This comment has been minimized.

Copy link
@cliffmeyers

cliffmeyers Nov 11, 2016

Collaborator

I tested the stories on Win 8.1 + IE11 and Win 10 + Edge and saw no issues. Think this use of flexbox will be 👍

background: @brand-primary;
color: white;
border-top-left-radius: @popup-border-radius;
border-top-right-radius: @popup-border-radius;
padding: 0 32px;

.Dialog--input & {
background: @brand-input-required;
}

.Dialog--error & {
background: @brand-danger;
}

.Dialog--success & {
background: @brand-success;
}

.Dialog--warning & {
background: @brand-warning;
}
}

.Dialog-content-scroll {
overflow: auto;
flex-shrink: 1;
}

.Dialog-content-margin {
margin:32px 32px 16px 32px;
}

.Dialog-button-bar {
padding: 0 32px;
margin: 16px 0 32px;
display: flex;
width:100%;
justify-content: flex-end;
flex-shrink: 0;

//.Dialog-content-scroll+& {
// padding-top: 0;
//}

&>Button+Button {
margin-left:0.5em;
}
}

//--------------------------------------
@@ -26,12 +26,13 @@ html {

body {
color: @text-color;
text-rendering: optimizeSpeed;
font-feature-settings: "kern" on, "liga" off;
-moz-font-feature-settings: "kern" on, "liga" off;
// Want to change this? Pick a fight with i386
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeSpeed;
font-feature-settings: "kern" on, "liga" off;
-moz-font-feature-settings: "kern" on, "liga" off;
// Want to change this? Pick a fight with i386
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 1.2;
}

//
@@ -42,6 +43,10 @@ body {
box-sizing: border-box;
}

p {
margin: 1em 0;
}

// Default All headings to basically "bold and display:block"
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
@@ -29,6 +29,7 @@
@brand-grey: #4A4A4A;
@brand-grey-lite: #949393;
@brand-selection: lighten(@brand-primary, 20%);
@brand-input-required: #24B0D5;

//Misc colors
@brand-active: darken(@brand-primary, 20%);
@@ -0,0 +1,212 @@
// @flow
import React, {Component, PropTypes} from 'react';

import {ModalContainer} from './ModalContainer';

//--------------------------------------------------------------------------
//
// Basic Dialog
//
//--------------------------------------------------------------------------

/**
Basic, bare-bones Dialog component:
- Show the user a styled dialog, with any child content to be set by owner.
- Listen for and re-dispatch user dismiss requests.
*/
export class BasicDialog extends Component {

props: {
className?: string,
onDismiss?: Function,
ignoreEscapeKey?: bool,
children?: ReactChildren
};

//--------------------------------------
// User Interaction
//--------------------------------------

modalScreenClicked = () => {
const { onDismiss } = this.props;

if (onDismiss) {
onDismiss();
}
};

keyPressed = (event:KeyboardEvent) => {
// TODO: Move this into ModalContainer, and remove from Popover as well!
const { onDismiss, ignoreEscapeKey } = this.props;

if (!ignoreEscapeKey && onDismiss && event.keyCode === 27) {
onDismiss();
}
};

//--------------------------------------
// React Lifecycle
//--------------------------------------

render() {

const {className, children} = this.props;
const newClassName = (className ? className + " " : "") + ' Dialog';

return (
<ModalContainer onScreenClick={this.modalScreenClicked}>
<div className={newClassName}>{children}</div>
</ModalContainer>
);
}

componentDidMount() {
document.addEventListener("keyup", this.keyPressed, false);
// TODO: Remove from here and Popover
}

componentWillUnmount() {
document.removeEventListener("keyup", this.keyPressed, false);
// TODO: Remove from here and Popover
}
}

BasicDialog.propTypes = {
onDismiss: PropTypes.func,
ignoreEscapeKey: PropTypes.bool,
children: PropTypes.node
};

//--------------------------------------------------------------------------
//
// Dialog Header / Title Bar
//
//--------------------------------------------------------------------------

/** Basic header for dialogs */
export class DialogHeader extends Component {
props: {
children?: ReactChildren
};

render() {
return (
<div className="Dialog-header">
<h3>{this.props.children}</h3>

This comment has been minimized.

Copy link
@cliffmeyers

cliffmeyers Nov 11, 2016

Collaborator

In the event someone wanted to use Dialog but provide custom header content (icons, a button, etc), should we do anything a bit fancier here? Perhaps check if children is a string and wrap in h3, if a ReactElement omit the h3?

I know they can always use BasicDialog and built up their own, just wasn't sure it was a use-case we wanted to bother supporting.

</div>
);
}
}

DialogHeader.propTypes = {
children: PropTypes.node
};

//--------------------------------------------------------------------------
//
// Scrolling Content Pane
//
//--------------------------------------------------------------------------

/** Wraps the content of a dialog to provide a scrollbar if there's too much to fit */
export class DialogContent extends Component {
props: {
children?: ReactChildren
};

render() {
return (
<div className="Dialog-content-scroll">
<div className="Dialog-content-margin">
{this.props.children}
</div>
</div>
);
}
}

DialogContent.propTypes = {
children: PropTypes.node
};

//--------------------------------------------------------------------------
//
// Button bar
//
//--------------------------------------------------------------------------

/** A container for dialog action buttons */
export class DialogButtonBar extends Component {

props: {
children?: ReactChildren
};

render() {
const {children} = this.props;

return (
<div className="Dialog-button-bar">
{children}
</div>
);
}
}

DialogButtonBar.propTypes = {
children: PropTypes.node
};

//--------------------------------------------------------------------------
//
// Easy-to-use Dialog
//
//--------------------------------------------------------------------------

/** An easy-to-use Dialog component with a title and button bar, and scroll pane for children */
export class Dialog extends Component {

userDismissed = () => {
const {onDismiss} = this.props;
if (onDismiss) {
onDismiss(this);
}
};

render() {
const {
className,
title,
buttons,
children,
ignoreEscapeKey
} = this.props;

const defaultButton = <button onClick={this.userDismissed}>Close</button>;
const buttonArray = [].concat(buttons || defaultButton);

// Doing this will avoid getting annoying messages from React about array keys
const buttonBar = React.createElement(DialogButtonBar, {}, ...buttonArray);

return (
<BasicDialog className={className}
ignoreEscapeKey={ignoreEscapeKey}
onDismiss={this.userDismissed}>
<DialogHeader>{ title }</DialogHeader>
<DialogContent>{ children }</DialogContent>
{ buttonBar }
</BasicDialog>
);
}
}

Dialog.propTypes = {
className: PropTypes.string,
title: PropTypes.node,
buttons: PropTypes.node,
children: PropTypes.node,
onDismiss: PropTypes.func,
ignoreEscapeKey: PropTypes.bool
};
@@ -1,3 +1,10 @@
//@flow

export { ModalContainer } from './ModalContainer';
export {
BasicDialog,
DialogHeader,
DialogContent,
DialogButtonBar,
Dialog
} from './Dialog';
@@ -34,6 +34,13 @@ export {TimeDuration} from './TimeDuration';
export { Progress } from './Progress';
export { Popover } from './Popover';
export {ExpandablePath} from './ExpandablePath';
export {ModalContainer} from './dialog';
export {
BasicDialog,
ModalContainer,
DialogHeader,
DialogContent,
DialogButtonBar,
Dialog
} from './dialog';
import FloatingElement from './FloatingElement';
export {FloatingElement};
@@ -4,3 +4,6 @@ declare var performance: {
now: () => number
};

// Helpful react stuff

type ReactChildren = string | Array<React$Element<any>>;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.