diff options
author | Jon Ambas <jon@jonambas.com> | 2017-08-14 09:41:22 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-14 09:41:22 -0400 |
commit | 2b07705e0fa64561a1e93e16ada2392da7c54e9d (patch) | |
tree | a7bab8482c2c05886345e77396abe1930af61807 | |
parent | 9b9887a45c8b2d3ace1853bd4b097268525bf5d4 (diff) | |
parent | 08534fc31305993a01731255bbdabeaa3044e84b (diff) | |
download | matchbox-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.js | 59 | ||||
-rw-r--r-- | src/components/ActionList/ActionList.module.scss | 31 | ||||
-rw-r--r-- | src/components/ActionList/index.js | 1 | ||||
-rw-r--r-- | src/components/Popover/Popover.js | 12 | ||||
-rw-r--r-- | src/components/Popover/Popover.module.scss | 10 | ||||
-rw-r--r-- | src/components/index.js | 1 | ||||
-rw-r--r-- | stories/ActionList.js | 88 | ||||
-rw-r--r-- | stories/index.js | 1 |
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'; |