mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-14 06:22:40 +00:00
dropdown changes
This commit is contained in:
68
client/components/combobox.jsx
Normal file
68
client/components/combobox.jsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
const React = require('react');
|
||||||
|
const createClass = require('create-react-class');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const cx = require('classnames');
|
||||||
|
require('./combobox.less');
|
||||||
|
|
||||||
|
const Dropdown = {
|
||||||
|
combo : createClass({
|
||||||
|
displayName : 'Dropdown.combo',
|
||||||
|
getDefaultProps : function() {
|
||||||
|
return {
|
||||||
|
trigger : 'hover'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getInitialState : function() {
|
||||||
|
return {
|
||||||
|
showDropdown : false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
componentDidMount : function() {
|
||||||
|
if(this.props.trigger == 'click')
|
||||||
|
document.addEventListener('click', this.handleClickOutside);
|
||||||
|
},
|
||||||
|
componentWillUnmount : function() {
|
||||||
|
if(this.props.trigger == 'click')
|
||||||
|
document.removeEventListener('click', this.handleClickOutside);
|
||||||
|
},
|
||||||
|
handleClickOutside : function(e){
|
||||||
|
// Close dropdown when clicked outside
|
||||||
|
if(this.refs.dropdown && !this.refs.dropdown.contains(e.target)) {
|
||||||
|
this.handleDropdown(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleDropdown : function(show){
|
||||||
|
this.setState({
|
||||||
|
showDropdown : show
|
||||||
|
});
|
||||||
|
},
|
||||||
|
renderDropdown : function(dropdownChildren){
|
||||||
|
if(!this.state.showDropdown) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='dropdown-options'>
|
||||||
|
{dropdownChildren}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
render : function () {
|
||||||
|
const dropdownChildren = React.Children.map(this.props.children, (child, i)=>{
|
||||||
|
// Ignore the first child
|
||||||
|
if(i < 1) return;
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div className={`dropdown-container ${this.props.className}`}
|
||||||
|
ref='dropdown'
|
||||||
|
onMouseEnter={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(true);} : undefined}
|
||||||
|
onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}
|
||||||
|
onMouseLeave={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(false);} : undefined}>
|
||||||
|
{this.props.children[0] || this.props.children /*children is not an array when only one child*/}
|
||||||
|
{this.renderDropdown(dropdownChildren)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Dropdown;
|
||||||
20
client/components/combobox.less
Normal file
20
client/components/combobox.less
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.dropdown-container {
|
||||||
|
position:relative;
|
||||||
|
.dropdown-options {
|
||||||
|
position:absolute;
|
||||||
|
background-color: rgb(227, 227, 227);
|
||||||
|
z-index: 100;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #444;
|
||||||
|
.item {
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: OpenSans;
|
||||||
|
padding: 5px;
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(120%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ const _ = require('lodash');
|
|||||||
const cx = require('classnames');
|
const cx = require('classnames');
|
||||||
const request = require('superagent');
|
const request = require('superagent');
|
||||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||||
|
const Dropdown = require('client/components/combobox.jsx');
|
||||||
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
|
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
|
||||||
|
|
||||||
const Themes = require('themes/themes.json');
|
const Themes = require('themes/themes.json');
|
||||||
@@ -108,6 +109,11 @@ const MetadataEditor = createClass({
|
|||||||
this.props.onChange(this.props.metadata);
|
this.props.onChange(this.props.metadata);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleLanguage : function(language){
|
||||||
|
this.props.metadata.lang = language;
|
||||||
|
this.props.onChange(this.props.metadata);
|
||||||
|
},
|
||||||
|
|
||||||
handleDelete : function(){
|
handleDelete : function(){
|
||||||
if(this.props.metadata.authors && this.props.metadata.authors.length <= 1){
|
if(this.props.metadata.authors && this.props.metadata.authors.length <= 1){
|
||||||
if(!confirm('Are you sure you want to delete this brew? Because you are the only owner of this brew, the document will be deleted permanently.')) return;
|
if(!confirm('Are you sure you want to delete this brew? Because you are the only owner of this brew, the document will be deleted permanently.')) return;
|
||||||
@@ -191,20 +197,20 @@ const MetadataEditor = createClass({
|
|||||||
|
|
||||||
if(this.props.metadata.renderer == 'legacy') {
|
if(this.props.metadata.renderer == 'legacy') {
|
||||||
dropdown =
|
dropdown =
|
||||||
<Nav.dropdown className='disabled' trigger='disabled'>
|
<Dropdown.combo className='disabled' trigger='disabled'>
|
||||||
<div>
|
<div>
|
||||||
{`Themes are not supported in the Legacy Renderer`} <i className='fas fa-caret-down'></i>
|
{`Themes are not supported in the Legacy Renderer`} <i className='fas fa-caret-down'></i>
|
||||||
</div>
|
</div>
|
||||||
</Nav.dropdown>;
|
</Dropdown.combo>;
|
||||||
} else {
|
} else {
|
||||||
dropdown =
|
dropdown =
|
||||||
<Nav.dropdown trigger='click'>
|
<Dropdown.combo trigger='click'>
|
||||||
<div>
|
<div>
|
||||||
{`${_.upperFirst(currentTheme.renderer)} : ${currentTheme.name}`} <i className='fas fa-caret-down'></i>
|
{`${_.upperFirst(currentTheme.renderer)} : ${currentTheme.name}`} <i className='fas fa-caret-down'></i>
|
||||||
</div>
|
</div>
|
||||||
{/*listThemes('Legacy')*/}
|
{/*listThemes('Legacy')*/}
|
||||||
{listThemes('V3')}
|
{listThemes('V3')}
|
||||||
</Nav.dropdown>;
|
</Dropdown.combo>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className='field themes'>
|
return <div className='field themes'>
|
||||||
@@ -251,22 +257,22 @@ const MetadataEditor = createClass({
|
|||||||
const listLanguages = ()=>{
|
const listLanguages = ()=>{
|
||||||
return _.map(langCodes.sort(), (code, index)=>{
|
return _.map(langCodes.sort(), (code, index)=>{
|
||||||
const languageNames = new Intl.DisplayNames([code], { type: 'language' });
|
const languageNames = new Intl.DisplayNames([code], { type: 'language' });
|
||||||
return <option key={index} value={`${code}`}>{`${languageNames.of(code)}`}</option>;
|
return <div className='item' title={''} key={index} onClick={()=>this.handleLanguage(code)}>{`${code}`}</div>;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return <div className='field language'>
|
return <div className='field language'>
|
||||||
<label>language</label>
|
<label>language</label>
|
||||||
<input type='text' className='value'
|
<Dropdown.combo trigger='hover'>
|
||||||
defaultValue={this.props.metadata.lang || 'en'}
|
<div className='item'>
|
||||||
onChange={(e)=>this.handleFieldChange('lang', e)}
|
<input type='text'
|
||||||
list='languageList'
|
defaultValue={this.props.metadata.lang || ''}
|
||||||
placeholder={`'en', 'es', 'de' for example`}
|
onChange={(e)=>this.handleFieldChange('lang', e)}
|
||||||
name='brewLanguage'
|
placeholder='en'
|
||||||
/>
|
/>
|
||||||
<datalist id='languageList'>
|
</div>
|
||||||
{listLanguages()}
|
{listLanguages()}
|
||||||
</datalist>
|
</Dropdown.combo>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -275,10 +281,8 @@ const MetadataEditor = createClass({
|
|||||||
<div className='field title'>
|
<div className='field title'>
|
||||||
<label>title</label>
|
<label>title</label>
|
||||||
<input type='text' className='value'
|
<input type='text' className='value'
|
||||||
value={this.props.metadata.title}
|
defaultValue={this.props.metadata.title}
|
||||||
onChange={(e)=>this.handleFieldChange('title', e)}
|
onChange={(e)=>this.handleFieldChange('title', e)} />
|
||||||
name='brewTitle'
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='field-group'>
|
<div className='field-group'>
|
||||||
<div className='field-column'>
|
<div className='field-column'>
|
||||||
|
|||||||
Reference in New Issue
Block a user