From 678c1fb3d8e2082a3dc8aea32689d453e68ad3d9 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Wed, 23 Nov 2022 22:34:32 -0600 Subject: [PATCH] create combobox --- client/components/combobox.jsx | 145 ++++++++++-------- client/components/combobox.less | 14 +- .../editor/metadataEditor/metadataEditor.jsx | 36 ++--- .../editor/metadataEditor/metadataEditor.less | 3 + 4 files changed, 118 insertions(+), 80 deletions(-) diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index e4d5e77e5..a50ceeb5d 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -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 ( -
- {dropdownChildren} -
- ); - }, - render : function () { - const dropdownChildren = React.Children.map(this.props.children, (child, i)=>{ - // Ignore the first child - if(i < 1) return; - return child; - }); - return ( -
{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)} -
- ); +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 ( +
{this.handleDropdown(true);} : undefined} + onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}> + this.handleInput(e)} value={this.state.value || ''} /> +
+ ); + }, + renderDropdown : function(dropdownChildren){ + if(!this.state.showDropdown) return null; + return ( +
+ {dropdownChildren} +
+ ); + }, + render : function () { + const dropdownChildren = this.state.options.map((child, i)=>{ + const clone = React.cloneElement(child, { onClick: (e)=>this.handleOption(e) }); + return clone; + }); + return ( +
{this.handleDropdown(false);} : undefined}> + {this.renderTextInput()} + {this.renderDropdown(dropdownChildren)} +
+ ); + } +}); -module.exports = Dropdown; \ No newline at end of file +module.exports = Combobox; \ No newline at end of file diff --git a/client/components/combobox.less b/client/components/combobox.less index 2d0109c8e..5091a198c 100644 --- a/client/components/combobox.less +++ b/client/components/combobox.less @@ -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; } } diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index abb00fbb5..5a8c4cfb0 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -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 = - +
{`Themes are not supported in the Legacy Renderer`}
-
; + ; } else { dropdown = - +
{`${_.upperFirst(currentTheme.renderer)} : ${currentTheme.name}`}
{/*listThemes('Legacy')*/} {listThemes('V3')} -
; + ; } return
@@ -257,22 +257,22 @@ const MetadataEditor = createClass({ const listLanguages = ()=>{ return _.map(langCodes.sort(), (code, index)=>{ const languageNames = new Intl.DisplayNames([code], { type: 'language' }); - return
this.handleLanguage(code)}>{`${code}`}
; + return
+ {`${code}`} +
{`${languageNames.of(code)}`}
+
; }); }; + return
- -
- this.handleFieldChange('lang', e)} - placeholder='en' - /> -
- {listLanguages()} -
+ this.handleLanguage(value)} + onEntry={(e)=>{this.handleFieldChange('lang', e);}} + options={listLanguages()}> +
; }, diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 31dd9c721..a8c54a13d 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -52,6 +52,9 @@ } input[type='text'], textarea { border : 1px solid gray; + &:focus { + outline: 1px solid #444; + } } &.thumbnail{ height : 1.4em;