Cleanup for linting issues, and added last bit of focus handling for … (#304)

* Cleanup for linting issues, and added last bit of focus handling for selected modifications and specials

* added correct value for selectedRefId for utility slot section menu when Empty All selected
This commit is contained in:
Pat Nellesen
2018-06-10 17:23:03 -05:00
committed by William
parent 9b81f6efd2
commit 3d5a9ef220
7 changed files with 51 additions and 36 deletions

View File

@@ -43,13 +43,13 @@ export default class ModificationsMenu extends TranslatedComponent {
this._rollBest = this._rollBest.bind(this); this._rollBest = this._rollBest.bind(this);
this._rollWorst = this._rollWorst.bind(this); this._rollWorst = this._rollWorst.bind(this);
this._reset = this._reset.bind(this); this._reset = this._reset.bind(this);
this._keyDown = this._keyDown.bind(this); this._keyDown = this._keyDown.bind(this);
this.modItems = [];// Array to hold various element refs (<li>, <div>, <ul>, etc.) this.modItems = [];// Array to hold various element refs (<li>, <div>, <ul>, etc.)
this.firstModId = null; this.firstModId = null;
this.firstBPLabel = null;// First item in mod menu this.firstBPLabel = null;// First item in mod menu
this.lastModId = null; this.lastModId = null;
this.selectedModId = null;
this.selectedSpecialId = null;
this.lastNeId = null;// Last number editor id. Used to set focus to last number editor when shift-tab pressed on first element in mod menu. this.lastNeId = null;// Last number editor id. Used to set focus to last number editor when shift-tab pressed on first element in mod menu.
this.modValDidChange = false; // used to determine if component update was caused by change in modification value. this.modValDidChange = false; // used to determine if component update was caused by change in modification value.
this._handleModChange = this._handleModChange.bind(this); this._handleModChange = this._handleModChange.bind(this);
@@ -83,8 +83,7 @@ export default class ModificationsMenu extends TranslatedComponent {
const close = this._blueprintSelected.bind(this, blueprintName, grade); const close = this._blueprintSelected.bind(this, blueprintName, grade);
const key = blueprintName + ':' + grade; const key = blueprintName + ':' + grade;
const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade], Modifications.modules[m.grp].blueprints[blueprintName].grades[grade].engineers, m.grp); const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade], Modifications.modules[m.grp].blueprints[blueprintName].grades[grade].engineers, m.grp);
if (classes.indexOf('active') >= 0) this.selectedModId = key;
blueprintGrades.unshift(<li key={key} tabIndex="0" data-id={key} className={classes} style={{ width: '2em' }} onMouseOver={termtip.bind(null, tooltipContent)} onMouseOut={tooltip.bind(null, null)} onClick={close} onKeyDown={this._keyDown} ref={modItem => this.modItems[key] = modItem}>{grade}</li>); blueprintGrades.unshift(<li key={key} tabIndex="0" data-id={key} className={classes} style={{ width: '2em' }} onMouseOver={termtip.bind(null, tooltipContent)} onMouseOut={tooltip.bind(null, null)} onClick={close} onKeyDown={this._keyDown} ref={modItem => this.modItems[key] = modItem}>{grade}</li>);
} }
if (blueprintGrades) { if (blueprintGrades) {
@@ -178,6 +177,7 @@ export default class ModificationsMenu extends TranslatedComponent {
const classes = cn('button-inline-menu', { const classes = cn('button-inline-menu', {
active: m.blueprint && m.blueprint.special && m.blueprint.special.edname == specialName active: m.blueprint && m.blueprint.special && m.blueprint.special.edname == specialName
}); });
if (classes.indexOf('active') >= 0) this.selectedSpecialId = specialName;
const close = this._specialSelected.bind(this, specialName); const close = this._specialSelected.bind(this, specialName);
if (m.blueprint && m.blueprint.name) { if (m.blueprint && m.blueprint.name) {
let tmp = {}; let tmp = {};
@@ -324,6 +324,8 @@ export default class ModificationsMenu extends TranslatedComponent {
const { m, ship } = this.props; const { m, ship } = this.props;
ship.clearModifications(m); ship.clearModifications(m);
ship.clearModuleBlueprint(m); ship.clearModuleBlueprint(m);
this.selectedModId = null;
this.selectedSpecialId = null;
this.props.onChange(); this.props.onChange();
} }
@@ -356,6 +358,13 @@ export default class ModificationsMenu extends TranslatedComponent {
componentDidUpdate() { componentDidUpdate() {
if (!this.modValDidChange) { if (!this.modValDidChange) {
if (this.modItems['modMainDiv'].children.length > 0) { if (this.modItems['modMainDiv'].children.length > 0) {
if (this.modItems[this.selectedModId]) {
this.modItems[this.selectedModId].focus();
return;
} else if (this.modItems[this.selectedSpecialId]) {
this.modItems[this.selectedSpecialId].focus();
return;
}
let firstEleCn = this.modItems['modMainDiv'].children[0].className; let firstEleCn = this.modItems['modMainDiv'].children[0].className;
if (firstEleCn.indexOf('button-inline-menu') >= 0) { if (firstEleCn.indexOf('button-inline-menu') >= 0) {
this.modItems['modMainDiv'].firstElementChild.focus(); this.modItems['modMainDiv'].firstElementChild.focus();
@@ -455,7 +464,7 @@ export default class ModificationsMenu extends TranslatedComponent {
<tbody> <tbody>
{ showRolls ? { showRolls ?
<tr> <tr>
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: false}) }> { translate('roll') }: </td> <td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: false }) }> { translate('roll') }: </td>
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 0 }) } style={{ cursor: 'pointer' }} onClick={_rollWorst} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('0%') } </td> <td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 0 }) } style={{ cursor: 'pointer' }} onClick={_rollWorst} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('0%') } </td>
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 50 })} style={{ cursor: 'pointer' }} onClick={_rollFifty} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_FIFTY')} onMouseOut={tooltip.bind(null, null)}> { translate('50%') } </td> <td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 50 })} style={{ cursor: 'pointer' }} onClick={_rollFifty} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_FIFTY')} onMouseOut={tooltip.bind(null, null)}> { translate('50%') } </td>
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 100 })} style={{ cursor: 'pointer' }} onClick={_rollFull} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('100%') } </td> <td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 100 })} style={{ cursor: 'pointer' }} onClick={_rollFull} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('100%') } </td>

View File

@@ -251,11 +251,11 @@ class TextInputBox extends React.Component {
*/ */
constructor(props) { constructor(props) {
super(props); super(props);
this._handleFocus = this._handleFocus.bind(this); this._handleFocus = this._handleFocus.bind(this);
this._handleBlur = this._handleBlur.bind(this); this._handleBlur = this._handleBlur.bind(this);
this._handleChange = this._handleChange.bind(this); this._handleChange = this._handleChange.bind(this);
this._keyup = this._keyup.bind(this); this._keyup = this._keyup.bind(this);
this.state = this._getInitialState(); this.state = this._getInitialState();
} }
/** /**
* Update input value if slider changes will change props/state * Update input value if slider changes will change props/state
@@ -263,10 +263,10 @@ class TextInputBox extends React.Component {
* @param {Object} nextState React Component state values * @param {Object} nextState React Component state values
*/ */
componentWillReceiveProps(nextProps, nextState) { componentWillReceiveProps(nextProps, nextState) {
let nextValue = nextProps.percent * nextProps.max; let nextValue = nextProps.percent * nextProps.max;
// See https://stackoverflow.com/questions/32414308/updating-state-on-props-change-in-react-form // See https://stackoverflow.com/questions/32414308/updating-state-on-props-change-in-react-form
if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) { if (nextValue !== this.state.inputValue && nextValue <= nextProps.max) {
this.setState({ inputValue: nextValue }); this.setState({ inputValue: nextValue });
} }
} }
/** /**
@@ -276,14 +276,14 @@ class TextInputBox extends React.Component {
*/ */
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') { if (prevState.divStyle.display == 'none' && this.state.divStyle.display == 'block') {
this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10); this.enterTimer = setTimeout(() => this.sliderVal.focus(), 10);
} }
if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) { if (prevProps.max !== this.props.max && this.state.inputValue > this.props.max) {
// they chose a different module // they chose a different module
this.setState({ inputValue: this.props.max }); this.setState({ inputValue: this.props.max });
} }
if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) { if (this.state.inputValue != prevState.inputValue && prevProps.max == this.props.max) {
this.props.onChange(this.state.inputValue/this.props.max); this.props.onChange(this.state.inputValue / this.props.max);
} }
} }
/** /**
@@ -294,9 +294,9 @@ class TextInputBox extends React.Component {
*/ */
_getInitialState() { _getInitialState() {
return { return {
divStyle: {display:'none'}, divStyle: { display:'none' },
inputStyle: {width:'4em'}, inputStyle: { width:'4em' },
labelStyle: {marginLeft: '.1em'}, labelStyle: { marginLeft: '.1em' },
maxLength:5, maxLength:5,
size:5, size:5,
min:0, min:0,
@@ -304,7 +304,7 @@ class TextInputBox extends React.Component {
type:'number', type:'number',
readOnly: true, readOnly: true,
inputValue: this.props.percent * this.props.max inputValue: this.props.percent * this.props.max
} };
} }
/** /**
* *
@@ -312,7 +312,7 @@ class TextInputBox extends React.Component {
*/ */
_setDisplay(val) { _setDisplay(val) {
this.setState({ this.setState({
divStyle: {display:val} divStyle: { display:val }
}); });
} }
/** /**
@@ -330,7 +330,7 @@ class TextInputBox extends React.Component {
_handleBlur() { _handleBlur() {
this._setDisplay('none'); this._setDisplay('none');
if (this.state.inputValue !== '') { if (this.state.inputValue !== '') {
this.props.onChange(this.state.inputValue/this.props.max); this.props.onChange(this.state.inputValue / this.props.max);
} else { } else {
this.setState({ this.setState({
inputValue: this.props.percent * this.props.max inputValue: this.props.percent * this.props.max
@@ -339,6 +339,7 @@ class TextInputBox extends React.Component {
} }
/** /**
* Get the value in the text box * Get the value in the text box
* @returns {number} inputValue Value of the input box
*/ */
_getValue() { _getValue() {
return this.state.inputValue; return this.state.inputValue;
@@ -348,15 +349,15 @@ class TextInputBox extends React.Component {
* values depending on what user * values depending on what user
* has selected * has selected
* *
* @param {SyntheticEvent} event * @param {SyntheticEvent} event ReactJs onChange event
*/ */
_handleChange(event) { _handleChange(event) {
if (event.target.value < 0) { if (event.target.value < 0) {
this.setState({inputValue: 0}); this.setState({ inputValue: 0 });
} else if (event.target.value <= this.props.max) { } else if (event.target.value <= this.props.max) {
this.setState({inputValue: event.target.value}); this.setState({ inputValue: event.target.value });
} else { } else {
this.setState({inputValue: this.props.max}); this.setState({ inputValue: this.props.max });
} }
} }
/** /**
@@ -373,9 +374,13 @@ class TextInputBox extends React.Component {
return; return;
} }
} }
/**
* Get the value in the text box
* @return {React.Component} Text Input component for Slider
*/
render() { render() {
let { axisUnit, onChange, percent, scale } = this.props; let { axisUnit, onChange, percent, scale } = this.props;
return <div style={this.state.divStyle}><input style={this.state.inputStyle} value={this._getValue()} min={this.state.min} max={this.props.max} onChange={this._handleChange} onKeyUp={this._keyup} tabIndex={this.state.tabIndex} maxLength={this.state.maxLength} size={this.state.size} onBlur={() => {this._handleBlur()}} onFocus={() => {this._handleFocus()}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/><text className="primary upp" style={this.state.labelStyle}>{this.props.axisUnit}</text></div>; return <div style={this.state.divStyle}><input style={this.state.inputStyle} value={this._getValue()} min={this.state.min} max={this.props.max} onChange={this._handleChange} onKeyUp={this._keyup} tabIndex={this.state.tabIndex} maxLength={this.state.maxLength} size={this.state.size} onBlur={() => {this._handleBlur();}} onFocus={() => {this._handleFocus();}} type={this.state.type} ref={(ip) => this.sliderVal = ip}/><text className="primary upp" style={this.state.labelStyle}>{this.props.axisUnit}</text></div>;
} }
} }

View File

@@ -85,10 +85,10 @@ export default class Slot extends TranslatedComponent {
*/ */
_keyDown(event) { _keyDown(event) {
if (event.key == 'Enter') { if (event.key == 'Enter') {
if(event.target.className == 'r') { if(event.target.className == 'r') {
this._toggleModifications(); this._toggleModifications();
} }
this.props.onOpen(event); this.props.onOpen(event);
} }
} }
/** /**

View File

@@ -74,7 +74,7 @@ export default class SlotSection extends TranslatedComponent {
} }
if (event.key == 'Tab') { if (event.key == 'Tab') {
if (event.shiftKey) { if (event.shiftKey) {
if ((event.currentTarget === this.sectionRefArr[this.firstRefId]) && this.sectionRefArr[this.lastRefId]) { if ((event.currentTarget === this.sectionRefArr[this.firstRefId]) && this.sectionRefArr[this.lastRefId]) {
event.preventDefault(); event.preventDefault();
this.sectionRefArr[this.lastRefId].focus(); this.sectionRefArr[this.lastRefId].focus();
} }

View File

@@ -43,7 +43,7 @@ export default class StandardSlot extends TranslatedComponent {
* Handle Enter key * Handle Enter key
* @param {SyntheticEvent} event KeyDown event * @param {SyntheticEvent} event KeyDown event
*/ */
_keyDown(event) { _keyDown(event) {
if (event.key == 'Enter') { if (event.key == 'Enter') {
if(event.target.className == 'r') { if(event.target.className == 'r') {
this._toggleModifications(); this._toggleModifications();

View File

@@ -33,6 +33,7 @@ export default class UtilitySlotSection extends SlotSection {
* Empty all utility slots and close the menu * Empty all utility slots and close the menu
*/ */
_empty() { _empty() {
this.selectedRefId = this.firstRefId;
this.props.ship.emptyUtility(); this.props.ship.emptyUtility();
this.props.onChange(); this.props.onChange();
this._close(); this._close();

View File

@@ -608,7 +608,7 @@ export default class OutfittingPage extends Page {
</div> </div>
{/* Main tables */} {/* Main tables */}
<ShipSummaryTable ship={ship} fuel={fuel} cargo={cargo} marker={shipSummaryMarker} pips={{sys: this.state.sys, wep: this.state.wep, eng: this.state.eng}} /> <ShipSummaryTable ship={ship} fuel={fuel} cargo={cargo} marker={shipSummaryMarker} pips={{ sys: this.state.sys, wep: this.state.wep, eng: this.state.eng }} />
<StandardSlotSection ship={ship} fuel={fuel} cargo={cargo} code={standardSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/> <StandardSlotSection ship={ship} fuel={fuel} cargo={cargo} code={standardSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/>
<InternalSlotSection ship={ship} code={internalSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/> <InternalSlotSection ship={ship} code={internalSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/>
<HardpointSlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/> <HardpointSlotSection ship={ship} code={hardpointsSlotMarker} onChange={shipUpdated} onCargoChange={this._cargoUpdated} onFuelChange={this._fuelUpdated} currentMenu={menu} sectionMenuRefs={this._sectionMenuRefs}/>