Skip to content

Commit

Permalink
feat: overlay loader
Browse files Browse the repository at this point in the history
  • Loading branch information
Vandish Gandhi committed Apr 7, 2019
1 parent ddd7689 commit be89956
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 1 deletion.
4 changes: 3 additions & 1 deletion docs/components/Layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import InformationBoxExample from '../../examples/InformationBoxExample';
import SplitPaneExample from '../../examples/SplitPaneExample';
import HoverDropdownMenuExample from '../../examples/HoverDropdownMenuExample';
import NavigationExample from '../../examples/NavigationExample';
import OverlayLoaderExample from '../../examples/OverlayLoaderExample';

import './styles.scss';
import '../../examples/styles.scss';
Expand Down Expand Up @@ -93,7 +94,7 @@ const componentsBySection = {
'stats-and-data': ['count-badge', 'statistic', 'totals', 'slicey'],
'icons-and-graphics': ['svg-symbol', 'svg-symbol-circle'],
navigation: ['breadcrumb', 'tab', 'hover-dropdown-menu', 'navigation-tabs'],
'feedback-and-states': ['alert', 'empty', 'spinner', 'pretty-diff', 'status-pill'],
'feedback-and-states': ['alert', 'empty', 'spinner', 'overlay-loader', 'pretty-diff', 'status-pill'],
dialogue: ['popover', 'help-icon-popover', 'avatar'],
modals: ['confirm-modal'],
search: ['search', 'search-bar', 'tag'],
Expand Down Expand Up @@ -213,6 +214,7 @@ class PageLayout extends React.Component {
<AlertExample />
<EmptyExample />
<SpinnerExample />
<OverlayLoaderExample />
<PrettyDiffExample />
<StatusPillExample />

Expand Down
104 changes: 104 additions & 0 deletions docs/examples/OverlayLoaderExample.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from 'react';
import Example from '../components/Example';
import { OverlayLoader, Button } from '../../src';

class OverlayLoaderExample extends React.Component {
constructor(props) {
super(props);
this.state = {
showDisabledLoader: false,
showLoader: false,
};
this.toggleLoader = this.toggleLoader.bind(this);
this.toggleDisabledLoader = this.toggleDisabledLoader.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
}

handleKeyPress(event) {
if (event.keyCode === 27) {
this.toggleDisabledLoader();
}
}

toggleLoader() {
this.setState(prevState => ({ showLoader: !prevState.showLoader }));
}

toggleDisabledLoader() {
this.setState(
prevState => ({ showDisabledLoader: !prevState.showDisabledLoader, showLoader: false }),
() => {
const eventTrigger = this.state.showDisabledLoader ? window.addEventListener : window.removeEventListener;
eventTrigger('keydown', this.handleKeyPress);
}
);
}

render() {
return (
<React.Fragment>
<h4>Static markup</h4>
<div className="static-markup">
<OverlayLoader text="campaigns" />
<OverlayLoader heading="Fetching" text="delivery data" />
</div>
<div className="live-demo">
<h4>Demo</h4>
<Button onClick={this.toggleLoader}>{this.state.showLoader ? 'Hide' : 'Show'} Loader</Button>
{this.state.showLoader && <OverlayLoader heading="Entering" text="galaxy" />}
<Button onClick={this.toggleDisabledLoader}>
{this.state.showDisabledLoader ? 'Hide' : 'Show'} Loader (disabled background)
</Button>
{this.state.showDisabledLoader && <OverlayLoader disableBackground={true} text="Press esc to hide" />}
</div>
</React.Fragment>
);
}
}

const exampleProps = {
componentName: 'Overlay Loader',
notes: `Fixed position loader which provides user experience for page loading or interim loading states`,
exampleCodeSnippet: `
// Static Markup Loaders
<OverlayLoader text="campaigns" />
<OverlayLoader heading="Fetching" text="delivery data" />
// Demo Loaders
<OverlayLoader heading="Entering" text="galaxy" />
<OverlayLoader disableBackground={true} text="Press esc to hide" />
`,
propTypeSectionArray: [
{
propTypes: [
{
defaultValue: 'Loading',
propType: 'heading',
type: 'string',
},
{
propType: 'top',
type: 'number',
note: 'Position from top of DOM',
defaultValue: '320',
},
{
propType: 'text',
type: 'string',
},
{
propType: 'disableBackground',
defaultValue: 'false',
type: 'bool',
note: 'prevents event propogation',
},
],
},
],
};

export default () => (
<Example {...exampleProps}>
<OverlayLoaderExample />
</Example>
);
20 changes: 20 additions & 0 deletions docs/examples/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,26 @@
}
}
}

&.overlay-loader-example {
.static-markup {
display: flex;
margin-bottom: 50px;
width: 300px;

.aui--overlay-loader {
position: inherit;

.loader {
position: inherit;
}

+ .aui--overlay-loader {
margin-right: 10px;
}
}
}
}
}

.full-width {
Expand Down
33 changes: 33 additions & 0 deletions src/components/adslot-ui/OverlayLoader/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
// import ReactDOM from 'react-dom';
import { Spinner } from 'alexandria';
import './styles.scss';

const OverlayLoader = ({ text, top, heading, disableBackground }) => (
<div
className={`aui--overlay-loader ${disableBackground ? 'aui--overlay-loader-disabled' : ''}`}
{...(disableBackground ? { onClick: event => event.stopPropagation() } : {})}
>
<div className="loader" style={{ top }}>
<Spinner size="medium" />
<span className="loader-heading">{heading}</span>
{text && <span className="loader-text">{text}</span>}
</div>
</div>
);

OverlayLoader.defaultProps = {
heading: 'Loading',
top: 320,
disableBackground: false,
};

OverlayLoader.propTypes = {
heading: PropTypes.string,
text: PropTypes.string,
top: PropTypes.number,
disableBackground: PropTypes.bool,
};

export default OverlayLoader;
26 changes: 26 additions & 0 deletions src/components/adslot-ui/OverlayLoader/index.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import sinon from 'sinon';
import { mount, shallow } from 'enzyme';
import OverlayLoader from 'adslot-ui/OverlayLoader';

describe('Overlay Loader Component', () => {
it('should render Overlay Loader', () => {
const wrapper = shallow(<OverlayLoader text="foo" />);
expect(wrapper.find('.aui--overlay-loader')).to.have.length(1);
expect(wrapper.find('.loader-heading').text()).to.equal('Loading');
});

it('should stop event propogation when disabled background', () => {
const eventStub = sinon.stub();
const wrapper = mount(
<div onClick={() => eventStub} className="my-div">
<OverlayLoader text="foo" disableBackground />
</div>
);
expect(wrapper.find(OverlayLoader)).to.have.length(1);
expect(wrapper.find('.loader-heading').text()).to.equal('Loading');
wrapper.find('.my-div').simulate('click');
wrapper.find(OverlayLoader).simulate('click');
expect(eventStub.called).to.equal(false);
});
});
54 changes: 54 additions & 0 deletions src/components/adslot-ui/OverlayLoader/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@import '~styles/variable';

.aui--overlay-loader {
width: 100%;
height: 100%;
position: absolute;
top: 10px;
z-index: $zindex-popover;

&-disabled {
position: fixed;
}

.loader {
position: fixed;
left: 50%;
width: 96px;
min-height: 132px;
background-color: $color-gray-white;
display: flex;
align-items: center;
flex-direction: column;
padding: 20px;
border-radius: 5px;
border: 1px solid $color-gray-light;
font-weight: $font-weight-bold;
opacity: .9;
line-height: 14px;

.loader-heading {
color: $color-gray-darker;
}

.loader-text {
margin-top: 5px;
color: $color-gray;
width: 65px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
}

.spinner-medium {
height: 40px;
width: 40px;
margin-bottom: 20px;
border-bottom-color: $color-gray-darker;
border-left-color: $color-gray-darker;
border-right-color: $color-gray-darker;
border-width: 5px;
}
}
}
2 changes: 2 additions & 0 deletions src/components/adslot-ui/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import HoverDropdownMenu from 'adslot-ui/HoverDropdownMenu';
import fastStatelessWrapper from 'adslot-ui/fastStatelessWrapper';
import InformationBox from 'adslot-ui/InformationBox';
import Nav from 'adslot-ui/Navigation';
import OverlayLoader from 'adslot-ui/OverlayLoader';

export {
Accordion,
Expand Down Expand Up @@ -68,4 +69,5 @@ export {
UserListPicker,
InformationBox,
HoverDropdownMenu,
OverlayLoader,
};
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ import {
UserListPicker,
InformationBox,
HoverDropdownMenu,
OverlayLoader,
} from 'adslot-ui';

export {
Expand Down Expand Up @@ -145,4 +146,5 @@ export {
UserListPicker,
InformationBox,
HoverDropdownMenu,
OverlayLoader,
};
2 changes: 2 additions & 0 deletions src/styles/variable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ $popover-border-color: $color-border-lighter;
$popover-arrow-width: 5px;
$popover-arrow-outer-color: $popover-border-color;
$popover-title-bg: $color-background;
$zindex-popover: 1060;


// == TreePicker
$treepicker-height: 500px;
Expand Down

0 comments on commit be89956

Please sign in to comment.