-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from b2wads/develop
Release 6.1.0
- Loading branch information
Showing
26 changed files
with
1,031 additions
and
1,851 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Node CI | ||
|
||
on: [push] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
node-version: [8.x] | ||
|
||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- name: test build | ||
run: | | ||
yarn | ||
yarn test | ||
env: | ||
CI: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
source/components/editable-value/editable-value-component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import React, { PureComponent, Fragment } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import CSSModules from 'react-css-modules'; | ||
import cx from 'classnames'; | ||
|
||
import Icon from '../icon'; | ||
import Button from '../button'; | ||
import Loader from '../loader'; | ||
import { FormControlLabel, FormGroup, FormHelpText } from '../form'; | ||
|
||
import styles from './editable-value.styl'; | ||
|
||
class EditableValue extends PureComponent { | ||
constructor(props) { | ||
super(); | ||
this.state = { | ||
isEditing: null, | ||
editValue: null, | ||
innerValue: props.initialValue, | ||
validationStatus: null, | ||
}; | ||
|
||
this.toggleEdit = this.toggleEdit.bind(this); | ||
this.onSubmit = this.onSubmit.bind(this); | ||
this.changeFieldValue = this.changeFieldValue.bind(this); | ||
} | ||
|
||
static propTypes = { | ||
value: PropTypes.string, | ||
initialValue: PropTypes.string, | ||
validation: PropTypes.func, | ||
errorMessage: PropTypes.string, | ||
loading: PropTypes.bool, | ||
onSubmit: PropTypes.func, | ||
label: PropTypes.string, | ||
outline: PropTypes.bool, | ||
inputClassName: PropTypes.string, | ||
buttonClassName: PropTypes.string, | ||
iconClassName: PropTypes.string, | ||
}; | ||
|
||
static defaultProps = { | ||
outline: false, | ||
loading: false, | ||
}; | ||
|
||
validation() { | ||
const { editValue } = this.state; | ||
const isValid = this.props.validation ? this.props.validation(editValue) : true; | ||
|
||
if (!isValid) { | ||
return { validationStatus: 'error' }; | ||
} | ||
|
||
return { validationStatus: null }; | ||
} | ||
|
||
toggleEdit() { | ||
this.setState({ isEditing: !this.state.isEditing, validationStatus: null, editValue: null }); | ||
} | ||
|
||
onSubmit() { | ||
const { editValue } = this.state; | ||
const { validationStatus } = this.validation(editValue); | ||
|
||
if (!this.isValid(editValue)) { | ||
this.toggleEdit(); | ||
} else if (validationStatus !== 'error') { | ||
this.setState({ innerValue: editValue }); | ||
this.props.onSubmit(editValue, this.toggleEdit); | ||
} else { | ||
this.setState({ validationStatus }); | ||
} | ||
} | ||
|
||
changeFieldValue(evt) { | ||
this.setState({ editValue: evt.target.value }); | ||
} | ||
|
||
isValid(value) { | ||
return value !== null && value !== undefined; | ||
} | ||
|
||
renderEdition() { | ||
const { label, value, outline, loading, inputClassName, buttonClassName, errorMessage } = this.props; | ||
const { editValue, innerValue, validationStatus } = this.state; | ||
const finalValue = value || innerValue; | ||
return ( | ||
<Fragment> | ||
<FormGroup key={validationStatus} validationState={validationStatus} className={styles.formGroup}> | ||
<FormControlLabel | ||
onChange={this.changeFieldValue} | ||
disabled={loading} | ||
outline={outline} | ||
label={label} | ||
type="text" | ||
value={this.isValid(editValue) ? editValue : finalValue} | ||
inputClassName={cx(styles.input, inputClassName)} | ||
/> | ||
{validationStatus === 'error' && errorMessage && <FormHelpText>{errorMessage}</FormHelpText>} | ||
</FormGroup> | ||
<Button className={cx(styles.submit, buttonClassName)} size="none" onClick={this.onSubmit}> | ||
{!loading ? <Icon name="check" size={16} /> : <Loader size="20px" color="secondary" />} | ||
</Button> | ||
</Fragment> | ||
); | ||
} | ||
|
||
renderValue() { | ||
const { value, iconClassName } = this.props; | ||
return ( | ||
<Fragment> | ||
{value || this.state.innerValue} | ||
<Button className={cx(styles.edit, iconClassName)} size="none" color="transparent" onClick={this.toggleEdit}> | ||
<Icon name="edit" size={16} /> | ||
</Button> | ||
</Fragment> | ||
); | ||
} | ||
|
||
render() { | ||
const { isEditing } = this.state; | ||
return ( | ||
<div className={cx(styles.wrap, { [styles.isEditing]: isEditing }, this.props.className)}> | ||
{isEditing ? this.renderEdition() : this.renderValue()} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default CSSModules(EditableValue, styles); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import '../../../internals/test/helper'; | ||
|
||
import EditableValue from './editable-value-component'; | ||
|
||
/** @test {EditableValue} */ | ||
describe('EditableValue component', () => { | ||
/** @test {EditableValue#render} */ | ||
describe('#render', () => { | ||
it('render correctly', () => { | ||
const wrapper = shallow( | ||
<EditableValue /> | ||
); | ||
expect(wrapper.length).toEqual(1); | ||
}); | ||
}); | ||
}); |
109 changes: 109 additions & 0 deletions
109
source/components/editable-value/editable-value.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
import { withKnobs } from '@storybook/addon-knobs'; | ||
import { withState } from '@dump247/storybook-state'; | ||
|
||
import EditableValue from './editable-value-component'; | ||
import Button from '../button'; | ||
|
||
const stories = storiesOf('EditableValue', module); | ||
|
||
stories.addDecorator(withKnobs); | ||
|
||
stories.add('Default', () => ( | ||
<EditableValue | ||
initialValue="Default" | ||
onSubmit={(value, toggleFn) => { | ||
console.log('onSubmit', value); | ||
toggleFn(); | ||
}} | ||
/> | ||
)); | ||
|
||
stories.add('Outline', () => ( | ||
<EditableValue | ||
outline | ||
initialValue="Outline" | ||
onSubmit={(value, toggleFn) => { | ||
console.log('onSubmit', value); | ||
toggleFn(); | ||
}} | ||
validation={value => `${value}`.length === 4} | ||
errorMessage="Favor inserir 4 caracteres" | ||
/> | ||
)); | ||
|
||
stories.add('Label', () => ( | ||
<div> | ||
<EditableValue | ||
outline | ||
label="Teste" | ||
initialValue="Outline" | ||
onSubmit={(value, toggleFn) => { | ||
console.log('onSubmit', value); | ||
toggleFn(); | ||
}} | ||
validation={value => `${value}`.length === 4} | ||
errorMessage="Favor inserir 4 caracteres" | ||
/> | ||
<br/> | ||
<br/> | ||
<br/> | ||
<br/> | ||
<EditableValue | ||
label="Teste" | ||
initialValue="No Outline" | ||
onSubmit={(value, toggleFn) => { | ||
console.log('onSubmit', value); | ||
toggleFn(); | ||
}} | ||
validation={value => `${value}`.length === 4} | ||
errorMessage="Favor inserir 4 caracteres" | ||
/> | ||
</div> | ||
)); | ||
|
||
stories.add('Uncontrolled', () => ( | ||
<EditableValue | ||
label="Uncontrolled" | ||
initialValue="Valor interno" | ||
onSubmit={(value, toggleFn) => { | ||
console.log('onSubmit', value); | ||
toggleFn(); | ||
}} | ||
validation={value => `${value}`.length === 4} | ||
errorMessage="Favor inserir 4 caracteres" | ||
/> | ||
)); | ||
|
||
stories.add( | ||
'Controlled', | ||
withState({ loading: false, value: 'Valor no estado (externo)' })(({ store }) => { | ||
const setVal = (value, toggle) => { | ||
store.set({ loading: true }); | ||
setTimeout(() => { | ||
store.set({ value, loading: false }); | ||
toggle(); | ||
}, 1000); | ||
}; | ||
|
||
const changeVal = () => { | ||
store.set({ value: 'Novo Valor do Estado' }); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<EditableValue | ||
loading={store.state.loading} | ||
value={store.state.value} | ||
onSubmit={setVal} | ||
validation={value => `${value}`.length > 4} | ||
errorMessage="Favor inserir mais que 4 caracteres" | ||
/> | ||
<br/> | ||
<br/> | ||
<Button onClick={changeVal}>Change State Value</Button> | ||
</div> | ||
); | ||
}) | ||
); |
Oops, something went wrong.