Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ coverage
examples/bundle.js
examples/style.css
npm-debug.log
yarn.lock
28 changes: 28 additions & 0 deletions src/Dropdown/DialogWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { Component, PropTypes } from 'react';
/*
* We must make another component so that this.closePortal
* gets passed down and handed to children
*/
export default class DialogWrapper extends Component {
static propTypes = {
closePortal: PropTypes.func,
children: PropTypes.any,
target: PropTypes.any.isRequired
}

componentDidMount() {
this.dialogDom.showModal(this.props.target)
}

render() {
const { closePortal, children } = this.props
return(
<dialog className="portal__dialog" ref={(c) => this.dialogDom = c}>
{ React.cloneElement(
children,
{closePortal: closePortal}
)}
</dialog>
);
}
}
10 changes: 10 additions & 0 deletions src/Dropdown/Dropdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,13 @@
.mdl-dropdown *, .mdl-dropdown *:before, .mdl-dropdown *:after {
box-sizing: inherit;
}

.portal__dialog {
border: 0 none;
margin: 0;
padding: 0;
}

.portal__dialog::backdrop {
background: transparent;
}
18 changes: 12 additions & 6 deletions src/Dropdown/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Portal from 'react-portal'
import Tether from 'tether'

import './Dropdown.css'
import DialogWrapper from './DialogWrapper';

const POS = {
t: 'top',
Expand Down Expand Up @@ -63,9 +64,10 @@ export default class Dropdown extends Component {
useTargetMinHeight,
viewportPadding: pad,
} = this.props
const mdlParent = findDOMNode(this.dialogDom);

// append class name
portalNode.classList.add('mdl-dropdown')
mdlParent.classList.add('mdl-dropdown')

// window is our boundary
const { innerWidth, innerHeight } = window
Expand All @@ -74,7 +76,7 @@ export default class Dropdown extends Component {
const targetNode = this.props.targetNode || findDOMNode(this)

// get bounding rects
const portal = portalNode.getBoundingClientRect()
const portal = portalNode.getBoundingClientRect() // TOOD: Test
const target = targetNode.getBoundingClientRect()

// parse position
Expand Down Expand Up @@ -167,7 +169,7 @@ export default class Dropdown extends Component {

// tether
this.tether = new Tether({
element: portalNode,
element: mdlParent,
target: targetNode,
attachment: `${ay} ${ax}`,
targetAttachment: `${ty} ${tx}`,
Expand All @@ -179,7 +181,7 @@ export default class Dropdown extends Component {
})

// fade in
this.applyStyles(portalNode, { opacity: 1 })
this.applyStyles(mdlParent, { opacity: 1 })

// force reposition
if (portal.height > maxHeight) {
Expand Down Expand Up @@ -213,9 +215,13 @@ export default class Dropdown extends Component {
onOpen={this.onOpen}
beforeClose={this.beforeClose}
>
{children}
<DialogWrapper
target={target}
ref={(c) => this.dialogDom = c}
>
{children}
</DialogWrapper>
</Portal>
)
}

}
28 changes: 28 additions & 0 deletions stories/Menu.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import faker from 'faker'
import { Card, Button, IconButton } from 'react-mdl'

import { Menu, MenuItem } from '../src'
import DialogHelper from './helpers/DialogHelper'
import StatefulMenu from './helpers/StatefulMenu'

const bigMenuItems = [...Array(35).keys()].map(i =>
<MenuItem key={i}>Menu Item {i}</MenuItem>
Expand All @@ -22,6 +24,16 @@ storiesOf('Menu', module)
<MenuItem onClick={() => console.log('select three')}>Three</MenuItem>
</Menu>
))
.add('default with icon', () => (
<div>
<h4>Menu with Icon</h4>
<p>Useful for a button-style dropdown.</p>
<StatefulMenu
options={['One', 'Two', 'Three']}
value="Select Value"
/>
</div>
))
.add('position', () => {
const styles = {
center: {
Expand Down Expand Up @@ -231,3 +243,19 @@ storiesOf('Menu', module)
</Card>
)
})
.add('opens within dialog', () => {
return (
<div>
<DialogHelper>
<Menu target={<IconButton name={'more_vert'}/>} align={'tr br'}>
<MenuItem onClick={() => console.log('select one')}>One</MenuItem>
<MenuItem onClick={() => console.log('select two')}>Two</MenuItem>
<MenuItem onClick={() => console.log('select three')}>Three</MenuItem>
<MenuItem>I</MenuItem>
<MenuItem>Am</MenuItem>
<MenuItem>Free</MenuItem>
</Menu>
</DialogHelper>
</div>
)
})
55 changes: 55 additions & 0 deletions stories/helpers/DialogHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { Component, PropTypes } from 'react'
import { Button, Dialog, DialogTitle, DialogActions, DialogContent } from 'react-mdl'


export default class DialogHelper extends Component {

constructor(props) {
super(props);
this.state = {
dialogOpen: props.dialogOpen
}
}

static propTypes = {
dialogOpen: PropTypes.bool,
children: PropTypes.object
}

static defaultProps = {
dialogOpen: false,
children: []
}

handelCloseDialog = () => {
this.setState({
dialogOpen: false
});
}

handleOpenDialog = () => {
this.setState({
dialogOpen: true
});
}

render() {
const { children } = this.props;
const { dialogOpen } = this.state;
return(
<div>
<Button raised type="button" onClick={this.handleOpenDialog}>Open Dialog</Button>
<Dialog open={dialogOpen} style={{minWidth: 400}}>
<DialogTitle>How does it render within a Dialog?</DialogTitle>
<DialogContent>
{ children }
</DialogContent>
<DialogActions>
<Button type="button" onClick={this.handelCloseDialog}>Close</Button>
</DialogActions>
</Dialog>
</div>
);
}

}
40 changes: 40 additions & 0 deletions stories/helpers/StatefulMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { Component, PropTypes } from 'react';
import { Button, Icon } from 'react-mdl'
import { Menu, MenuItem } from '../../src'

export default class StatefulMenu extends Component {

constructor(props) {
super(props);
this.state = { value: null }
}

static propTypes = {
options: PropTypes.arrayOf(React.PropTypes.string).isRequired,
value: PropTypes.string
}

static defaultProps = {
value: null
}

onChange = (value) => {
this.setState({ value })
console.log(`select ${value}`)
}

render() {
const { value, options } = this.props;
const val = this.state.value ? this.state.value : value ? value : options[0];
return (
<Menu
target={<Button raised>{val} <Icon name="arrow_drop_down" /></Button>}
align={'tl bl'}
>
{ options.map((option) => (
<MenuItem key={option} onClick={() => this.onChange(option) }>{option}</MenuItem>
))}
</Menu>
)
}
}