mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 18:32:41 +00:00
create combobox
This commit is contained in:
@@ -4,65 +4,90 @@ 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>
|
||||
);
|
||||
const Combobox = createClass({
|
||||
displayName : 'Combobox',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
trigger : 'hover',
|
||||
default : ''
|
||||
};
|
||||
},
|
||||
getInitialState : function() {
|
||||
return {
|
||||
showDropdown : false,
|
||||
value : '',
|
||||
options : [...this.props.options]
|
||||
};
|
||||
},
|
||||
componentDidMount : function() {
|
||||
if(this.props.trigger == 'click')
|
||||
document.addEventListener('click', this.handleClickOutside);
|
||||
this.setState({
|
||||
value : this.props.default
|
||||
});
|
||||
},
|
||||
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
|
||||
});
|
||||
},
|
||||
handleInput : function(e){
|
||||
e.persist();
|
||||
this.setState({
|
||||
value : e.target.value
|
||||
}, ()=>{
|
||||
// const event = new Event('entry');
|
||||
// console.log(eevent);
|
||||
this.props.onEntry(e);
|
||||
});
|
||||
},
|
||||
handleOption : function(e){
|
||||
this.setState({
|
||||
value : e.currentTarget.getAttribute('data-value')
|
||||
}, ()=>{this.props.onSelect(this.state.value);});
|
||||
;
|
||||
},
|
||||
renderTextInput : function(){
|
||||
return (
|
||||
<div className='dropdown-input item'
|
||||
onMouseEnter={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(true);} : undefined}
|
||||
onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}>
|
||||
<input type='text' onChange={(e)=>this.handleInput(e)} value={this.state.value || ''} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
renderDropdown : function(dropdownChildren){
|
||||
if(!this.state.showDropdown) return null;
|
||||
return (
|
||||
<div className='dropdown-options'>
|
||||
{dropdownChildren}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
render : function () {
|
||||
const dropdownChildren = this.state.options.map((child, i)=>{
|
||||
const clone = React.cloneElement(child, { onClick: (e)=>this.handleOption(e) });
|
||||
return clone;
|
||||
});
|
||||
return (
|
||||
<div className={`dropdown-container ${this.props.className}`}
|
||||
ref='dropdown'
|
||||
onMouseLeave={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(false);} : undefined}>
|
||||
{this.renderTextInput()}
|
||||
{this.renderDropdown(dropdownChildren)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Dropdown;
|
||||
module.exports = Combobox;
|
||||
@@ -5,13 +5,23 @@
|
||||
background-color: rgb(227, 227, 227);
|
||||
z-index: 100;
|
||||
width: 100%;
|
||||
border: 1px solid #444;
|
||||
border: 1px solid gray;
|
||||
.item {
|
||||
font-size: 12px;
|
||||
position:relative;
|
||||
font-size: 14px;
|
||||
font-family: OpenSans;
|
||||
padding: 5px;
|
||||
cursor: default;
|
||||
&:hover {
|
||||
filter: brightness(120%);
|
||||
background-color: rgb(163, 163, 163);
|
||||
}
|
||||
.detail {
|
||||
width:100%;
|
||||
text-align: right;
|
||||
color: rgb(124, 124, 124);
|
||||
font-style:italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
const request = require('superagent');
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
const Dropdown = require('client/components/combobox.jsx');
|
||||
const Combobox = require('client/components/combobox.jsx');
|
||||
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
|
||||
|
||||
const Themes = require('themes/themes.json');
|
||||
@@ -109,8 +109,8 @@ const MetadataEditor = createClass({
|
||||
this.props.onChange(this.props.metadata);
|
||||
},
|
||||
|
||||
handleLanguage : function(language){
|
||||
this.props.metadata.lang = language;
|
||||
handleLanguage : function(languageCode){
|
||||
this.props.metadata.lang = languageCode;
|
||||
this.props.onChange(this.props.metadata);
|
||||
},
|
||||
|
||||
@@ -197,20 +197,20 @@ const MetadataEditor = createClass({
|
||||
|
||||
if(this.props.metadata.renderer == 'legacy') {
|
||||
dropdown =
|
||||
<Dropdown.combo className='disabled' trigger='disabled'>
|
||||
<Combobox className='disabled' trigger='disabled'>
|
||||
<div>
|
||||
{`Themes are not supported in the Legacy Renderer`} <i className='fas fa-caret-down'></i>
|
||||
</div>
|
||||
</Dropdown.combo>;
|
||||
</Combobox>;
|
||||
} else {
|
||||
dropdown =
|
||||
<Dropdown.combo trigger='click'>
|
||||
<Combobox trigger='click'>
|
||||
<div>
|
||||
{`${_.upperFirst(currentTheme.renderer)} : ${currentTheme.name}`} <i className='fas fa-caret-down'></i>
|
||||
</div>
|
||||
{/*listThemes('Legacy')*/}
|
||||
{listThemes('V3')}
|
||||
</Dropdown.combo>;
|
||||
</Combobox>;
|
||||
}
|
||||
|
||||
return <div className='field themes'>
|
||||
@@ -257,22 +257,22 @@ const MetadataEditor = createClass({
|
||||
const listLanguages = ()=>{
|
||||
return _.map(langCodes.sort(), (code, index)=>{
|
||||
const languageNames = new Intl.DisplayNames([code], { type: 'language' });
|
||||
return <div className='item' title={''} key={index} onClick={()=>this.handleLanguage(code)}>{`${code}`}</div>;
|
||||
return <div className='item' title={''} key={`${index}`} data-value={`${code}`}>
|
||||
{`${code}`}
|
||||
<div className='detail'>{`${languageNames.of(code)}`}</div>
|
||||
</div>;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return <div className='field language'>
|
||||
<label>language</label>
|
||||
<Dropdown.combo trigger='hover'>
|
||||
<div className='item'>
|
||||
<input type='text'
|
||||
defaultValue={this.props.metadata.lang || ''}
|
||||
onChange={(e)=>this.handleFieldChange('lang', e)}
|
||||
placeholder='en'
|
||||
/>
|
||||
</div>
|
||||
{listLanguages()}
|
||||
</Dropdown.combo>
|
||||
<Combobox trigger='click'
|
||||
default={this.props.metadata.lang || ''}
|
||||
onSelect={(value)=>this.handleLanguage(value)}
|
||||
onEntry={(e)=>{this.handleFieldChange('lang', e);}}
|
||||
options={listLanguages()}>
|
||||
</Combobox>
|
||||
</div>;
|
||||
},
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
}
|
||||
input[type='text'], textarea {
|
||||
border : 1px solid gray;
|
||||
&:focus {
|
||||
outline: 1px solid #444;
|
||||
}
|
||||
}
|
||||
&.thumbnail{
|
||||
height : 1.4em;
|
||||
|
||||
Reference in New Issue
Block a user