Make dropdowns fancy
parent
1eed46b462
commit
c7809f82f9
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
}
|
Loading…
Reference in New Issue