Skip to content
This repository has been archived by the owner on Mar 30, 2018. It is now read-only.

Commit

Permalink
update the component
Browse files Browse the repository at this point in the history
  • Loading branch information
sureshHARDIYA committed Mar 21, 2017
1 parent cd11cc7 commit 191a419
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 132 deletions.
66 changes: 34 additions & 32 deletions src/Dropdown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cx from 'classnames'
import { Component, PropTypes, createElement } from 'react'
import { Component, PropTypes, cloneElement } from 'react'

const links = {}

Expand Down Expand Up @@ -37,19 +37,18 @@ export default class Dropdown extends Component {
delay: PropTypes.number.isRequired,
mode: PropTypes.oneOf(['hover', 'click']).isRequired,
remainTime: PropTypes.number.isRequired,
className: PropTypes.string,
component: PropTypes.node,
dropdownLabel: PropTypes.string,
link: PropTypes.string,
}

static defaultProps = {
dropdownIcon: '',
dropdownLabel: 'Open',
mode: 'hover',
remainTime: 800,
delay: 0,
component: 'div',
link: '',
className: 'uk-inline',
}

state = {
Expand Down Expand Up @@ -120,46 +119,49 @@ export default class Dropdown extends Component {

render() {
const { handleMouseEnter, handleMouseLeave, handleClick } = this
const { mode, children, component, link } = this.props
const { mode, component, children, className } = this.props
const { isOpen } = this.state
const className = cx('uk-button uk-button-default', {
'uk-open': isOpen,
})

const dropdownClassName = cx('uk-dropdown uk-dropdown-bottom-left', {
'uk-open': isOpen,
})

const labelProps = {
'aria-expanded': isOpen,
'aria-haspopup': true,
className: link !== 'navbar' ? className : '',
const eventHandlers = {
onClick: handleClick,
onMouseEnter: mode === 'hover' && handleMouseEnter,
onMouseLeave: mode === 'hover' && handleMouseLeave,
children: this.props.dropdownLabel || mode,
}

const childrenProps = {
'aria-expanded': isOpen,
'aria-haspopup': true,
className: dropdownClassName,
onClick: handleClick,
onMouseEnter: mode === 'hover' && handleMouseEnter,
onMouseLeave: mode === 'hover' && handleMouseLeave,
children,
if (typeof this.props.children === 'function') {
return this.props.children({ isOpen, ...eventHandlers })
}

const parentProps = {
className: link !== 'navbar' ? 'uk-inline' : '',
children: [
createElement(link === 'navbar' ? 'a' : 'button', labelProps),
createElement('div', childrenProps),
],
if (!Array.isArray(children) || !children.length === 2) {
return new Error('Children must be passed as array and must have two components.')
}
const [target, body] = this.props.children

// construct target Element
const targetElement = cloneElement(target, {
...target.props,
...eventHandlers,
className: cx(target.props.className, {
'uk-open': isOpen,
}),
})

// construct body Element
const bodyElement = cloneElement(body, {
...body.props,
...eventHandlers,
className: cx(body.props.className, {
'uk-open': isOpen,
}),
})

const WrapperComponent = component

return (
createElement(component, parentProps)
<WrapperComponent className={className}>
{targetElement}
{bodyElement}
</WrapperComponent>
)
}
}
54 changes: 0 additions & 54 deletions src/__tests__/__snapshots__/Dropdown-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -458,57 +458,3 @@ exports[`Dropdown renders correctly 2`] = `
</div>
</li>
`;

exports[`should be closed 1`] = `
<div
className="uk-inline"
>
<button
aria-expanded={false}
aria-haspopup={true}
className="uk-button uk-button-default"
onClick={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Hover
</button>
<div
aria-expanded={false}
aria-haspopup={true}
className="uk-dropdown uk-dropdown-bottom-left"
onClick={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
First Instance
</div>
</div>
`;

exports[`should be open 1`] = `
<div
className="uk-inline"
>
<button
aria-expanded={true}
aria-haspopup={true}
className="uk-button uk-button-default uk-open"
onClick={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Hover
</button>
<div
aria-expanded={true}
aria-haspopup={true}
className="uk-dropdown uk-dropdown-bottom-left uk-open"
onClick={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Second Instance
</div>
</div>
`;
122 changes: 76 additions & 46 deletions src/stories/Dropdown.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,82 @@
import { storiesOf } from '@kadira/storybook'

import cx from 'classnames'
import { PropTypes, Component } from 'react'
import Dropdown from '../Dropdown'
import Button from '../Button'

// This is to work around: https://github.com/kadirahq/react-storybook-addon-info/issues/26#issuecomment-229029177
Dropdown.displayName = 'Dropdown'

const Nav = () => <ul className="uk-nav uk-nav-dropdown">
<li><a className="uk-warning" href="#">Item</a></li>
<li><a href="#">Another item</a></li>
<li className="uk-nav-header">Header</li>
<li><a href="#">Item</a></li>
<li><a href="#">Another item</a></li>
<li className="uk-nav-divider" />
<li><a href="#">Separated item</a></li>
</ul>
const Nav = () => (
<ul className="uk-nav uk-nav-dropdown">
<li><a className="uk-warning" href="#">Item</a></li>
<li><a href="#">Another item</a></li>
<li className="uk-nav-header">Header</li>
<li><a href="#">Item</a></li>
<li><a href="#">Another item</a></li>
<li className="uk-nav-divider" />
<li><a href="#">Separated item</a></li>
</ul>
)

const Menu = () => <Nav />
Menu.displayName = 'Menu'

const DropdownMenu = () => <Nav />
DropdownMenu.displayName = 'Menu'

const LoremIpsum = `Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`

class MyDropdown extends Component {
static propTypes = {
className: PropTypes.string,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
}

handleMouseLeave = () => {
this.props.onMouseLeave()
}

handleMouseEnter = () => {
this.props.onMouseEnter()
}

render() {
const { ...props } = this.props
const { handleMouseEnter, handleMouseLeave } = this
return (
<div
{...props}
className={cx('uk-dropdown uk-dropdown-bottom-left', props.className)}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{LoremIpsum}
</div>)
}
}

storiesOf('Dropdown', module)
.addWithInfo('Basic Usage', '', () => (
<div className="uk-margin-bottom">
<Dropdown dropdownLabel="Hover" >
{LoremIpsum}
</Dropdown>
&nbsp;
<Dropdown dropdownLabel="Click" mode="click">
{LoremIpsum}
</Dropdown>
</div>
.addWithInfo('Basic Usage', '', () => (
<div className="uk-margin-bottom">
<Dropdown mode="hover">
<Button>Hover</Button>
<MyDropdown />
</Dropdown>
&nbsp;
<Dropdown mode="click">
<Button primary>Click</Button>
<MyDropdown />
</Dropdown>
</div>
), { header: false, inline: true, propTables: [Dropdown] })

.addWithInfo('Nav in dropdown', '', () => (
<div className="uk-margin-bottom">
<Dropdown dropdownLabel="Hover">
<Menu />
</Dropdown>
&nbsp;
<Dropdown dropdownLabel="Click" mode="click">
<Menu />
<Dropdown>
<Button>Hover</Button>
<div className="uk-dropdown uk-dropdown-bottom-left">
<Nav />
</div>
</Dropdown>
</div>
), { header: false, inline: true, propTables: [Dropdown] })
Expand All @@ -55,24 +87,22 @@ storiesOf('Dropdown', module)
<ul className="uk-navbar-nav">
<li className="uk-active"><a>Active</a></li>
<li><a href="">Item</a></li>
<Dropdown
className="uk-parent"
component="li"
dropdownLabel="Parent"
link="navbar"
>
<DropdownMenu />
</Dropdown>
<Dropdown
className="uk-parent"
component="li"
dropdownLabel="Parent"
link="navbar"
>
<DropdownMenu />
<Dropdown className="" component="li" >
<a href="#">Parent</a>
<div className="uk-navbar-dropdown">
<ul className="uk-nav uk-navbar-dropdown-nav">
<li className="uk-active"><a href="#">Active</a></li>
<li><a href="#">Item</a></li>
<li className="uk-nav-header">Header</li>
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
<li className="uk-nav-divider" />
<li><a href="#">Item</a></li>
</ul>
</div>
</Dropdown>
<li><a href="">Item</a></li>
</ul>

</nav>
</div>
), { header: false, inline: true })

0 comments on commit 191a419

Please sign in to comment.