Skip to content

Commit

Permalink
Merge pull request #5785 from prathamVaidya/refactor-text_input
Browse files Browse the repository at this point in the history
refactor: text_input.jsx to functional component
  • Loading branch information
ragesoss committed May 13, 2024
2 parents 0c294bc + 4623150 commit 1b9500c
Showing 1 changed file with 110 additions and 100 deletions.
210 changes: 110 additions & 100 deletions app/assets/javascripts/components/common/text_input.jsx
Original file line number Diff line number Diff line change
@@ -1,116 +1,126 @@
import React from 'react';
import createReactClass from 'create-react-class';
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import InputHOC from '../high_order/input_hoc.jsx';
import Conditional from '../high_order/conditional.jsx';

const TextInput = createReactClass({
displayName: 'TextInput',
const TextInput = ({
value,
value_key,
editable,
label,
placeholder,
spacer,
valueClass,
p_tag_classname,
inline,
type,
max,
maxLength,
focus,
onBlur,
onClick,
append,
onKeyDown,
_value,
invalid,
onChange,
onFocus,
id,
children
}) => {
const inputRef = useRef(null);

propTypes: {
value: PropTypes.any,
value_key: PropTypes.string,
editable: PropTypes.bool,
label: PropTypes.string,
placeholder: PropTypes.string,
spacer: PropTypes.string,
valueClass: PropTypes.string,
p_tag_classname: PropTypes.string,
inline: PropTypes.bool,
type: PropTypes.string,
max: PropTypes.string,
maxLength: PropTypes.string,
focus: PropTypes.func,
onBlur: PropTypes.func,
onClick: PropTypes.func,
append: PropTypes.node,
onKeyDown: PropTypes.func,
_value: PropTypes.any,
// validation: Regex used by Conditional
// required: bool used by Conditional
},
const onKeyDownHandler = (e) => {
if (!onKeyDown) return;
onKeyDown(e.keyCode, inputRef.current);
};

onKeyDown(e) {
if (!this.props.onKeyDown) { return; }
this.props.onKeyDown(e.keyCode, this.refs.inputbox);
},
const labelContent = label ? `${label}${spacer || ': '}` : undefined;

dateChange(date) {
const value = date ? date.format('YYYY-MM-DD') : '';
return this.props.onChange({ target: { value } });
},
const usedValueClass = `text-input-component__value ${valueClass ?? ''}`;

render() {
let label;
const spacer = this.props.spacer || ': ';
if (editable) {
const labelClass = invalid ? 'red' : '';
const inputClass = `${inline ? 'inline' : ''} ${invalid ? 'invalid' : ''}`;

if (this.props.label) {
label = this.props.label + spacer;
let title;
if (type === 'number') {
title = I18n.t('accessibility.number_field');
}

const value = this.props.value;
const className = `${inputClass} ${value_key}`;

let valueClass = 'text-input-component__value ';
if (this.props.valueClass) { valueClass += this.props.valueClass; }
// The default maximum length of 75 ensures that the slug field
// of a course, which combines three TextInput values, will not exceed
// the maximum string size of 255.
const usedMaxLength = maxLength || '75';
const inputElement = (
<input
id={id}
className={className}
value={_value ?? (value || '')}
onChange={onChange}
autoFocus={focus}
onFocus={onFocus}
onBlur={onBlur}
onKeyDown={onKeyDownHandler}
type={type || 'text'}
max={max}
maxLength={usedMaxLength}
placeholder={placeholder}
title={title}
min={0}
ref={inputRef}
aria-labelledby={`${id}-label`}
/>
);

if (this.props.editable) {
let labelClass = '';
let inputClass = this.props.inline ? 'inline' : '';
if (this.props.invalid) {
labelClass += 'red';
inputClass += ' invalid';
}

let title;
if (this.props.type === 'number') {
title = I18n.t('accessibility.number_field');
}

const className = `${inputClass} ${this.props.value_key}`;
// The default maximum length of 75 ensures that the slug field
// of a course, which combines three TextInput values, will not exceed
// the maximum string size of 255.
const maxLength = this.props.maxLength || '75';
const input = (
<input
className={className}
id={this.props.id}
value={this.props._value !== undefined ? this.props._value : this.props.value || ''}
onChange={this.props.onChange}
autoFocus={this.props.focus}
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
onKeyDown={this.onKeyDown}
type={this.props.type || 'text'}
max={this.props.max}
maxLength={maxLength}
placeholder={this.props.placeholder}
title={title}
min={0}
ref="inputbox"
aria-labelledby={`${this.props.id}-label`}
/>
);

return (
<div className="form-group">
<label id={`${this.props.id}-label`} htmlFor={this.props.id} className={labelClass}>{label}</label>
{input}
{this.props.children}
</div>
);
} else if (this.props.label) {
return (
<p className={this.props.p_tag_classname}>
<span className="text-input-component__label"><strong>{label}</strong></span>
<span onBlur={this.props.onBlur} onClick={this.props.onClick} className={valueClass}>{value}</span>
{this.props.append}
</p>
);
}
return <span>{value}</span>;
return (
<div className="form-group">
<label id={`${id}-label`} htmlFor={id} className={labelClass}>
{labelContent}
</label>
{inputElement}
{children}
</div>
);
} else if (label) {
return (
<p className={p_tag_classname}>
<span className="text-input-component__label">
<strong>{labelContent}</strong>
</span>
<span onBlur={onBlur} onClick={onClick} className={usedValueClass}>
{value}
</span>
{append}
</p>
);
}
}
);
return <span>{value}</span>;
};

TextInput.propTypes = {
value: PropTypes.any,
value_key: PropTypes.string,
editable: PropTypes.bool,
label: PropTypes.string,
placeholder: PropTypes.string,
spacer: PropTypes.string,
valueClass: PropTypes.string,
p_tag_classname: PropTypes.string,
inline: PropTypes.bool,
type: PropTypes.string,
max: PropTypes.string,
maxLength: PropTypes.string,
focus: PropTypes.func,
onBlur: PropTypes.func,
onClick: PropTypes.func,
append: PropTypes.node,
onKeyDown: PropTypes.func,
_value: PropTypes.any,
// validation: Regex used by Conditional
// required: bool used by Conditional
};

export default Conditional(InputHOC(TextInput));

0 comments on commit 1b9500c

Please sign in to comment.