parent
e19f89f162
commit
86df54067f
4 changed files with 168 additions and 0 deletions
@ -0,0 +1,60 @@ |
||||
import './properties-form.scss'; |
||||
import { h, Component } from 'preact'; |
||||
|
||||
class PropertiesForm extends Component { |
||||
|
||||
render() { |
||||
let types = this.props.types; |
||||
let value = this.props.value; |
||||
if (!value) { |
||||
value = {}; |
||||
} |
||||
|
||||
return <div className='form-properties-form'> |
||||
{ |
||||
Object.keys(types).map((name) => { |
||||
let type = types[name]; |
||||
let inputType = null; |
||||
if (type === 'string') { |
||||
inputType = 'text'; |
||||
} else if (type === 'number') { |
||||
inputType = 'number'; |
||||
} else if (type === 'boolean') { |
||||
inputType = 'checkbox'; |
||||
} |
||||
return <div key={name} className='form-properties-form-row'> |
||||
<label> |
||||
<span className='column-name'>{name}</span> |
||||
<input type={inputType} name={name} |
||||
className='column-input' |
||||
value={value[name] ? value[name] : ''} |
||||
onChange={this.bindValue.bind(this)} |
||||
checked={value[name]} |
||||
/> |
||||
</label> |
||||
</div>; |
||||
}) |
||||
} |
||||
</div>; |
||||
} |
||||
|
||||
bindValue(e) { |
||||
if (!this.props.onChange) { |
||||
return; |
||||
} |
||||
|
||||
let name = e.target.name; |
||||
let next = Object.assign({}, this.props.value); |
||||
if (e.target.type.toLowerCase() === 'checkbox') { |
||||
next[name] = e.target.checked; |
||||
} else if (e.target.type.toLowerCase() === 'number') { |
||||
next[name] = Number(e.target.value); |
||||
} else { |
||||
next[name] = e.target.value; |
||||
} |
||||
|
||||
this.props.onChange(next); |
||||
} |
||||
} |
||||
|
||||
export default PropertiesForm; |
@ -0,0 +1,12 @@ |
||||
.form-properties-form { |
||||
&-row { |
||||
.column-name { |
||||
display: inline-block; |
||||
min-width: 5rem; |
||||
font-weight: bold; |
||||
} |
||||
.column-input { |
||||
line-height: 2.2rem; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@ |
||||
import { expect } from 'chai'; |
||||
import { h, render } from 'preact'; |
||||
import PropertiesForm from 'settings/components/form/properties-form' |
||||
|
||||
describe("settings/form/PropertiesForm", () => { |
||||
beforeEach(() => { |
||||
document.body.innerHTML = ''; |
||||
}); |
||||
|
||||
describe('render', () => { |
||||
it('renders PropertiesForm', () => { |
||||
let types = { |
||||
mystr: 'string', |
||||
mynum: 'number', |
||||
mybool: 'boolean', |
||||
empty: 'string', |
||||
} |
||||
let value = { |
||||
mystr: 'abc', |
||||
mynum: 123, |
||||
mybool: true, |
||||
}; |
||||
render(<PropertiesForm types={types} value={value} />, document.body); |
||||
|
||||
let strInput = document.querySelector('input[name=mystr]'); |
||||
let numInput = document.querySelector('input[name=mynum]'); |
||||
let boolInput = document.querySelector('input[name=mybool]'); |
||||
let emptyInput = document.querySelector('input[name=empty]'); |
||||
|
||||
expect(strInput.type).to.equals('text'); |
||||
expect(strInput.value).to.equal('abc'); |
||||
expect(numInput.type).to.equals('number'); |
||||
expect(numInput.value).to.equal('123'); |
||||
expect(boolInput.type).to.equals('checkbox'); |
||||
expect(boolInput.checked).to.be.true; |
||||
expect(emptyInput.type).to.equals('text'); |
||||
expect(emptyInput.value).to.be.empty; |
||||
}); |
||||
}); |
||||
|
||||
describe('onChange', () => { |
||||
it('invokes onChange event on text changed', (done) => { |
||||
render(<PropertiesForm |
||||
types={{ 'myvalue': 'string' }} |
||||
value={{ 'myvalue': 'abc' }} |
||||
onChange={value => { |
||||
expect(value).to.have.property('myvalue', 'abcd'); |
||||
done(); |
||||
}} |
||||
/>, document.body); |
||||
|
||||
let input = document.querySelector('input[name=myvalue]'); |
||||
input.value = 'abcd' |
||||
input.dispatchEvent(new Event('change')) |
||||
}); |
||||
|
||||
it('invokes onChange event on number changeed', (done) => { |
||||
render(<PropertiesForm |
||||
types={{ 'myvalue': 'number' }} |
||||
value={{ '': 123 }} |
||||
onChange={value => { |
||||
expect(value).to.have.property('myvalue', 1234); |
||||
done(); |
||||
}} |
||||
/>, document.body); |
||||
|
||||
let input = document.querySelector('input[name=myvalue]'); |
||||
input.value = '1234' |
||||
input.dispatchEvent(new Event('change')) |
||||
}); |
||||
|
||||
it('invokes onChange event on checkbox changed', (done) => { |
||||
render(<PropertiesForm |
||||
types={{ 'myvalue': 'boolean' }} |
||||
value={{ 'myvalue': false }} |
||||
onChange={value => { |
||||
expect(value).to.have.property('myvalue', true); |
||||
done(); |
||||
}} |
||||
/>, document.body); |
||||
|
||||
let input = document.querySelector('input[name=myvalue]'); |
||||
input.click(); |
||||
}); |
||||
}); |
||||
}); |
Reference in new issue