summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Ambas <jon@jonambas.com>2017-08-14 09:41:22 -0400
committerGitHub <noreply@github.com>2017-08-14 09:41:22 -0400
commit2b07705e0fa64561a1e93e16ada2392da7c54e9d (patch)
treea7bab8482c2c05886345e77396abe1930af61807
parent9b9887a45c8b2d3ace1853bd4b097268525bf5d4 (diff)
parent08534fc31305993a01731255bbdabeaa3044e84b (diff)
downloadmatchbox-2b07705e0fa64561a1e93e16ada2392da7c54e9d.zip
matchbox-2b07705e0fa64561a1e93e16ada2392da7c54e9d.tar.gz
matchbox-2b07705e0fa64561a1e93e16ada2392da7c54e9d.tar.bz2
Merge pull request #31 from SparkPost/FAD-5354
ActionList FAD-5354
-rw-r--r--src/components/ActionList/ActionList.js59
-rw-r--r--src/components/ActionList/ActionList.module.scss31
-rw-r--r--src/components/ActionList/index.js1
-rw-r--r--src/components/Popover/Popover.js12
-rw-r--r--src/components/Popover/Popover.module.scss10
-rw-r--r--src/components/index.js1
-rw-r--r--stories/ActionList.js88
-rw-r--r--stories/index.js1
8 files changed, 198 insertions, 5 deletions
diff --git a/src/components/ActionList/ActionList.js b/src/components/ActionList/ActionList.js
new file mode 100644
index 0000000..b007824
--- /dev/null
+++ b/src/components/ActionList/ActionList.js
@@ -0,0 +1,59 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import ReactDOM from 'react-dom';
+import classnames from 'classnames';
+
+import UnstyledLink, { linkFrom } from '../UnstyledLink';
+import styles from './ActionList.module.scss';
+
+const Section = ({ section }) => {
+ const actions = section.actions.map((action, index) => {
+ return linkFrom({ ...action, className: styles.Action }, index);
+ });
+ return (
+ <div className={styles.Section}>
+ { actions }
+ </div>
+ )
+}
+
+class ActionList extends Component {
+ static propTypes = {
+ /**
+ * Actions
+ * e.g. [{ content: 'action label', onClick: callback() }]
+ */
+ actions: PropTypes.arrayOf(PropTypes.shape({
+ content: PropTypes.string.isRequired
+ })),
+ /**
+ * Creates sections
+ * e.g. [{ actions:[{ content: 'action label', onClick: callback() }]}]
+ */
+ sections: PropTypes.arrayOf(PropTypes.shape({
+ actions: PropTypes.array
+ })),
+ };
+ render() {
+ const {
+ actions,
+ sections,
+ ...rest
+ } = this.props;
+
+ let list = actions ? [{ actions }] : [];
+ if (sections) {
+ list = list.concat(sections);
+ }
+
+ const listMarkup = list.map((section, index) => <Section section={section} key={index} />)
+
+ return (
+ <div className={styles.ActionList} {...rest}>
+ { listMarkup }
+ </div>
+ );
+ }
+}
+
+export default ActionList;
diff --git a/src/components/ActionList/ActionList.module.scss b/src/components/ActionList/ActionList.module.scss
new file mode 100644
index 0000000..f9fc6f2
--- /dev/null
+++ b/src/components/ActionList/ActionList.module.scss
@@ -0,0 +1,31 @@
+@import '../../styles/config';
+
+.ActionList {
+ padding-top: spacing(small);
+ overflow: scroll;
+ z-index: 1;
+ max-height: rem(160);
+}
+
+.Section {
+ border-bottom: 1px solid color(gray, 8);
+
+ &:last-child {
+ border: none;
+ }
+
+ &:first-child {
+ margin-top: 3px;
+ }
+}
+
+.Action, a.Action {
+ display: block;
+ padding: rem(9) spacing();
+ color: color(gray, 3);
+
+ &:hover {
+ background: color(blue);
+ color: color(gray, 10);
+ }
+}
diff --git a/src/components/ActionList/index.js b/src/components/ActionList/index.js
new file mode 100644
index 0000000..aba0fa8
--- /dev/null
+++ b/src/components/ActionList/index.js
@@ -0,0 +1 @@
+export { default as ActionList } from './ActionList';
diff --git a/src/components/Popover/Popover.js b/src/components/Popover/Popover.js
index 9764ce4..7447451 100644
--- a/src/components/Popover/Popover.js
+++ b/src/components/Popover/Popover.js
@@ -17,6 +17,10 @@ class Popover extends Component {
*/
sectioned: PropTypes.bool,
/**
+ * Optional, opens the popover
+ */
+ open: PropTypes.bool,
+ /**
* Popover Content
*/
children: PropTypes.oneOfType([
@@ -28,7 +32,7 @@ class Popover extends Component {
constructor(props) {
super(props);
this.state = {
- open: false
+ open: props.open
}
this.handleClickOutside = this.handleClickOutside.bind(this);
@@ -88,9 +92,11 @@ class Popover extends Component {
<div className={wrapperClasses}>
{ triggerMarkup }
<div className={popoverClasses} {...rest}>
- { children }
+ <span className={styles.Tip} />
+ <div className={styles.Content} >
+ { children }
+ </div>
</div>
- <span className={styles.Tip} />
</div>
);
}
diff --git a/src/components/Popover/Popover.module.scss b/src/components/Popover/Popover.module.scss
index 2e26787..81f1652 100644
--- a/src/components/Popover/Popover.module.scss
+++ b/src/components/Popover/Popover.module.scss
@@ -22,7 +22,6 @@
z-index: 1;
}
-
.sectioned {
padding: spacing();
}
@@ -30,7 +29,7 @@
.Tip {
display: block;
position: absolute;
- top: 100%;
+ top: rem(-14);
left: rem(21);
width: rem(14);
height: rem(14);
@@ -49,6 +48,13 @@
z-index: 1;
}
+.Content {
+ position: relative;
+ z-index: 1;
+ border-radius: border-radius(large);
+ overflow: hidden;
+}
+
.Wrapper {
position: relative;
}
diff --git a/src/components/index.js b/src/components/index.js
index 0932dee..5900e98 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,4 @@
+export * from './ActionList';
export * from './Banner';
export * from './Button';
export * from './Checkbox';
diff --git a/stories/ActionList.js b/stories/ActionList.js
new file mode 100644
index 0000000..748db4e
--- /dev/null
+++ b/stories/ActionList.js
@@ -0,0 +1,88 @@
+import React, { Component } from 'react';
+import { storiesOf } from '@storybook/react';
+import { action } from '@storybook/addon-actions';
+import { StoryContainer } from './helpers';
+
+import { ActionList, Popover, Button, TextField, Panel } from '../src';
+
+class DemoTypeahead extends Component {
+ state = {
+ open: false
+ }
+
+ render() {
+ return (
+ <div style={{ maxWidth: '500px', position: 'relative' }}>
+ <TextField
+ placeholder='Search Subbaccount'
+ onClick={action('Trigger Click')}
+ onChange={() => this.setState({ open: true }) }
+ onBlur={() => this.setState({ open: false })}/>
+ { this.state.open
+ ? <div
+ style={{
+ position: 'absolute',
+ marginTop: '1px',
+ top: '100%',
+ left: '0',
+ right: '0',
+ background: '#fff',
+ border: '1px solid #e5e5e5'
+ }}>
+ <ActionList
+ actions={[
+ { content: 'Sub 1' },
+ { content: 'Sub 2' },
+ { content: 'Sub 3' },
+ { content: 'Sub 4' },
+ { content: 'Sub 5' },
+ ]}/>
+ </div>
+ : null }
+
+ </div>
+ );
+ }
+}
+
+storiesOf('ActionList', module)
+ .addDecorator((getStory) => (
+ <StoryContainer>{ getStory() }</StoryContainer>
+ ))
+ .addWithInfo('within a Popover',
+ () => (
+ <Popover
+ open={true}
+ trigger={<Button>More Actions</Button>}
+ style={{ width: '200px' }}>
+ <ActionList
+ actions={[
+ {
+ content: 'Edit'
+ },
+ {
+ content: 'Delete'
+ },
+ {
+ content: 'Test'
+ }
+ ]}
+ sections={[
+ {
+ actions: [
+ {
+ content: 'Sectioned1'
+ },
+ {
+ content: 'Sectioned2'
+ }
+ ]
+ }
+ ]}
+ />
+ </Popover>
+ ))
+ .add('within a custom component',
+ () => (
+ <DemoTypeahead />
+ ));
diff --git a/stories/index.js b/stories/index.js
index 6aa9ea2..9f36314 100644
--- a/stories/index.js
+++ b/stories/index.js
@@ -14,6 +14,7 @@ import './ProgressBar';
import './Datepicker';
import './Tooltip';
import './Popover';
+import './ActionList';
import './Table';
import './Modal';
import './Icons';