Make dropdowns fancy

pull/10616/head
Alex P 2017-05-09 18:17:35 -07:00
parent 1eed46b462
commit c7809f82f9
4 changed files with 133 additions and 73 deletions

View File

@ -2,6 +2,8 @@ import React, {Component, PropTypes} from 'react'
import {Link} from 'react-router'
import classnames from 'classnames'
import OnClickOutside from 'shared/components/OnClickOutside'
import FancyScrollbox from 'shared/components/FancyScrollbar'
import {DROPDOWN_MENU_MAX_HEIGHT, DROPDOWN_MENU_ITEM_THRESHOLD} from 'shared/constants/index'
class Dropdown extends Component {
constructor(props) {
@ -52,17 +54,116 @@ class Dropdown extends Component {
action.handler(item)
}
renderShortMenu() {
const {actions, addNew, items, menuWidth, menuLabel} = this.props
return (
<ul className="dropdown-menu" style={{width: menuWidth}}>
{menuLabel
? <li className="dropdown-header">{menuLabel}</li>
: null
}
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li>
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</ul>
)
}
renderLongMenu() {
const {actions, addNew, items, menuWidth, menuLabel} = this.props
return (
<ul className="dropdown-menu" style={{width: menuWidth, height: DROPDOWN_MENU_MAX_HEIGHT}}>
<FancyScrollbox autoHide={false}>
{menuLabel
? <li className="dropdown-header">{menuLabel}</li>
: null
}
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li>
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</FancyScrollbox>
</ul>
)
}
render() {
const {
items,
selected,
className,
iconName,
actions,
addNew,
buttonSize,
buttonColor,
menuWidth,
} = this.props
const {isOpen} = this.state
@ -78,47 +179,11 @@ class Dropdown extends Component {
<span className="dropdown-selected">{selected}</span>
<span className="caret" />
</div>
{isOpen
? <ul className="dropdown-menu" style={{width: menuWidth}}>
{items.map((item, i) => {
if (item.text === 'SEPARATOR') {
return <li key={i} role="separator" className="divider" />
}
return (
<li className="dropdown-item" key={i}>
<a href="#" onClick={() => this.handleSelection(item)}>
{item.text}
</a>
{actions.length > 0
? <div className="dropdown-item__actions">
{actions.map(action => {
return (
<button
key={action.text}
className="dropdown-item__action"
onClick={e =>
this.handleAction(e, action, item)}
>
<span
title={action.text}
className={`icon ${action.icon}`}
/>
</button>
)
})}
</div>
: null}
</li>
)
})}
{addNew
? <li>
<Link to={addNew.url}>
{addNew.text}
</Link>
</li>
: null}
</ul>
{(isOpen && items.length < DROPDOWN_MENU_ITEM_THRESHOLD)
? this.renderShortMenu()
: null}
{(isOpen && items.length >= DROPDOWN_MENU_ITEM_THRESHOLD)
? this.renderLongMenu()
: null}
</div>
)
@ -152,6 +217,7 @@ Dropdown.propTypes = {
buttonSize: string,
buttonColor: string,
menuWidth: string,
menuLabel: string,
}
export default OnClickOutside(Dropdown)

View File

@ -379,6 +379,9 @@ export const STROKE_WIDTH = {
light: 1.5,
}
export const DROPDOWN_MENU_MAX_HEIGHT = '270px'
export const DROPDOWN_MENU_ITEM_THRESHOLD = 10
export const HEARTBEAT_INTERVAL = 10000 // ms
export const PRESENTATION_MODE_ANIMATION_DELAY = 0 // In milliseconds.

View File

@ -6,7 +6,7 @@
*/
$dropdown-menu-default-width: 100%;
$dropdown-menu-max-height: 290px;
$dropdown-menu-max-height: 270px;
/*
Generic width modifiers
@ -73,27 +73,26 @@ $dropdown-menu-max-height: 290px;
----------------------------------------------
*/
.dropdown-menu {
float: none !important;
width: $dropdown-menu-default-width;
min-width: $dropdown-menu-default-width;
max-width: $dropdown-menu-default-width;
margin: 0 !important;
padding: 0 !important;
min-width: initial;
margin: 0;
padding: 0;
overflow: hidden;
max-height: $dropdown-menu-max-height;
overflow: auto;
@include custom-scrollbar-round($c-pool, $c-laser);
@include gradient-h($c-ocean, $c-pool);
box-shadow: 0 2px 5px 0.6px fade-out($g0-obsidian, 0.8);
> li {
li.dropdown-item {
position: relative;
width: 100%;
font-size: 0px;
&:hover {
@include gradient-h($c-laser, $c-pool);
}
}
> li > a {
li.dropdown-item > a {
position: relative;
@include no-user-select();
width: 100%;
border-radius: 0 !important;
display: inline-block;
@ -119,12 +118,6 @@ $dropdown-menu-max-height: 290px;
@include gradient-h($c-ocean, $c-pool);
}
}
> li:last-child a {
border-radius: 0 0 3px 3px;
}
> li:first-child a {
border-radius: 3px 3px 0 0;
}
}
.dropdown.dropdown-kapacitor .dropdown-toggle {
color: $c-rainforest !important;
@ -135,10 +128,10 @@ $dropdown-menu-max-height: 290px;
@include custom-scrollbar($c-rainforest, $c-honeydew);
@include gradient-h($c-pool, $c-rainforest);
> li:hover {
li.dropdown-item:hover {
@include gradient-h($c-laser, $c-rainforest);
}
> li > a {
li.dropdown-item > a {
color: $c-mint !important;
&:hover {
color: $g20-white !important;
@ -149,10 +142,10 @@ $dropdown-menu-max-height: 290px;
@include custom-scrollbar($c-comet, $c-potassium);
@include gradient-h($c-ocean, $c-comet);
> li:hover {
li.dropdown-item:hover {
@include gradient-h($c-laser, $c-comet);
}
> li > a {
li.dropdown-item > a {
color: $c-twilight !important;
&:hover {
color: $g20-white !important;
@ -187,14 +180,6 @@ $dropdown-menu-max-height: 290px;
Dropdown Actions
----------------------------------------------
*/
.dropdown-item {
position: relative;
> a {
position: relative;
z-index: 1;
}
}
.dropdown-item__actions {
z-index: 2;
position: absolute;

View File

@ -47,4 +47,10 @@ $scrollbar-color-kap-b: $c-pool;
.fancy-scroll--kapacitor {
.fancy-scroll--thumb-h { @include gradient-h($scrollbar-color-kap-a,$scrollbar-color-kap-b); }
.fancy-scroll--thumb-v { @include gradient-v($scrollbar-color-kap-a,$scrollbar-color-kap-b); }
}
/* Dropdown Theme Scrollbars */
ul.dropdown-menu {
.fancy-scroll--thumb-h { @include gradient-h($c-neutrino,$c-laser); }
.fancy-scroll--thumb-v { @include gradient-v($c-neutrino,$c-laser); }
}