mirror of
https://github.com/Alamantus/Lexiconga.git
synced 2025-06-26 10:54:17 +02:00
Create maximizeable LargeTextArea for WordForm Details
Other places need to utilize this as well (Dictionary Details)
This commit is contained in:
parent
c142f302d3
commit
0a9259ec56
3 changed files with 165 additions and 17 deletions
136
src/components/management/LargeTextArea/index.jsx
Normal file
136
src/components/management/LargeTextArea/index.jsx
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
import Inferno from 'inferno';
|
||||||
|
import Component from 'inferno-component';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import './styles.scss';
|
||||||
|
|
||||||
|
export class LargeTextArea extends Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
PropTypes.checkPropTypes({
|
||||||
|
label: PropTypes.string.isRequired,
|
||||||
|
value: PropTypes.string.isRequired,
|
||||||
|
placeholder: PropTypes.string,
|
||||||
|
isValid: PropTypes.bool,
|
||||||
|
invalidText: PropTypes.string,
|
||||||
|
onInput: PropTypes.func,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
}, props, 'prop', 'LargeTextArea');
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isMaximized: false,
|
||||||
|
value: props.value || '',
|
||||||
|
};
|
||||||
|
|
||||||
|
this.textarea = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
this.setState({
|
||||||
|
value: nextProps.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
maximize () {
|
||||||
|
this.setState({ isMaximized: true }, () => {
|
||||||
|
this.textarea.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
minimize () {
|
||||||
|
this.setState({ isMaximized: false }, () => {
|
||||||
|
this.textarea.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput (event) {
|
||||||
|
const val = event.currentTarget.value;
|
||||||
|
|
||||||
|
if (val !== this.state.value) {
|
||||||
|
this.setState({ value: val }, () => {
|
||||||
|
if (this.props.onInput) {
|
||||||
|
this.props.onInput(this.state.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTextarea () {
|
||||||
|
const { placeholder, isValid, onChange } = this.props;
|
||||||
|
return (
|
||||||
|
<textarea className={ `textarea ${(!isValid) ? 'is-danger' : ''}` }
|
||||||
|
placeholder={ placeholder || '' }
|
||||||
|
value={ this.state.value || '' }
|
||||||
|
onInput={ event => this.onInput(event) }
|
||||||
|
onKeyDown={ event => this.onInput(event) }
|
||||||
|
onChange={ onChange }
|
||||||
|
ref={ textarea => this.textarea = textarea }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { label, isValid, invalidText } = this.props;
|
||||||
|
|
||||||
|
// if (this.state.isMaximized) {
|
||||||
|
// return (
|
||||||
|
// <div className='large-modal is-active'>
|
||||||
|
// <div className='modal-background' onClick={ this.minimize.bind(this) } />
|
||||||
|
// <div className='large-modal-card'>
|
||||||
|
// <header className='modal-card-head'>
|
||||||
|
// <span className='modal-card-title'>
|
||||||
|
// { label }
|
||||||
|
// </span>
|
||||||
|
// <button className='delete'
|
||||||
|
// aria-label='close'
|
||||||
|
// onClick={ this.minimize.bind(this) }
|
||||||
|
// />
|
||||||
|
// </header>
|
||||||
|
// { this.renderTextarea() }
|
||||||
|
// <footer className='modal-card-foot is-small' />
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='field'>
|
||||||
|
<label className='label'>
|
||||||
|
{ label }
|
||||||
|
<a className='button is-small is-pulled-right is-inline' onClick={ this.maximize.bind(this) }>
|
||||||
|
<span className='icon'><i className='fa fa-expand' /></span>
|
||||||
|
</a>
|
||||||
|
</label>
|
||||||
|
<div className='control'>
|
||||||
|
{ this.renderTextarea() }
|
||||||
|
{(!isValid)
|
||||||
|
? (
|
||||||
|
<span className='help is-danger'>
|
||||||
|
{ invalidText }
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
{this.state.isMaximized
|
||||||
|
&& (
|
||||||
|
<div className='large-modal is-active'>
|
||||||
|
<div className='modal-background' onClick={ this.minimize.bind(this) } />
|
||||||
|
<div className='large-modal-card'>
|
||||||
|
<header className='modal-card-head'>
|
||||||
|
<span className='modal-card-title'>
|
||||||
|
{ label }
|
||||||
|
</span>
|
||||||
|
<button className='delete'
|
||||||
|
aria-label='close'
|
||||||
|
onClick={ this.minimize.bind(this) }
|
||||||
|
/>
|
||||||
|
</header>
|
||||||
|
{ this.renderTextarea() }
|
||||||
|
<footer className='modal-card-foot is-small' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
19
src/components/management/LargeTextArea/styles.scss
Normal file
19
src/components/management/LargeTextArea/styles.scss
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
@import '../../node_modules/bulma/sass/utilities/initial-variables';
|
||||||
|
@import '../../node_modules/bulma/sass/utilities/derived-variables';
|
||||||
|
@import '../../node_modules/bulma/sass/utilities/mixins';
|
||||||
|
@import '../../node_modules/bulma/sass/components/modal';
|
||||||
|
|
||||||
|
.large-modal {
|
||||||
|
@extend .modal;
|
||||||
|
|
||||||
|
.large-modal-card {
|
||||||
|
@extend .modal-card;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
@extend .modal-card-body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import dictionaryData from '../../managers/DictionaryData';
|
import dictionaryData from '../../managers/DictionaryData';
|
||||||
import { IPAField } from './IPAField';
|
import { IPAField } from './IPAField';
|
||||||
|
import { LargeTextArea } from './LargeTextArea';
|
||||||
import { Word } from '../../managers/Word';
|
import { Word } from '../../managers/Word';
|
||||||
|
|
||||||
export class WordForm extends Component {
|
export class WordForm extends Component {
|
||||||
|
@ -160,23 +161,15 @@ export class WordForm extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<LargeTextArea
|
||||||
<label className='label'>Details</label>
|
label='Details'
|
||||||
<div className='control'>
|
value={ this.state.wordDetails }
|
||||||
<textarea className={ `textarea${(!this.state.detailsIsValid) ? ' is-danger' : ''}` }
|
placeholder='Explanation of word (Markdown enabled)'
|
||||||
placeholder='Explanation of word (Markdown enabled)'
|
isValid={ this.state.detailsIsValid }
|
||||||
value={ this.state.wordDetails }
|
invalidText='You must at least enter Details if excluding a Definition.'
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
this.setState({ wordDetails: event.target.value });
|
this.setState({ wordDetails: event.target.value });
|
||||||
}} />
|
}} />
|
||||||
{(!this.state.detailsIsValid)
|
|
||||||
? (
|
|
||||||
<span className='help is-danger'>
|
|
||||||
You must at least enter Details if excluding a Definition.
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{this.props.word
|
{this.props.word
|
||||||
? (
|
? (
|
||||||
|
|
Loading…
Add table
Reference in a new issue