aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/ui/input/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ui/input/index.tsx')
-rw-r--r--src/components/ui/input/index.tsx187
1 files changed, 104 insertions, 83 deletions
diff --git a/src/components/ui/input/index.tsx b/src/components/ui/input/index.tsx
index 2a36d7aa9..cb26c0ea4 100644
--- a/src/components/ui/input/index.tsx
+++ b/src/components/ui/input/index.tsx
@@ -1,5 +1,4 @@
1import { mdiEye, mdiEyeOff } from '@mdi/js'; 1import { mdiEye, mdiEyeOff } from '@mdi/js';
2import Icon from '@mdi/react';
3import classnames from 'classnames'; 2import classnames from 'classnames';
4import { 3import {
5 Component, 4 Component,
@@ -7,9 +6,13 @@ import {
7 InputHTMLAttributes, 6 InputHTMLAttributes,
8 ReactElement, 7 ReactElement,
9 RefObject, 8 RefObject,
9 KeyboardEvent,
10} from 'react'; 10} from 'react';
11import injectSheet, { WithStylesProps } from 'react-jss'; 11import withStyles, { WithStylesProps } from 'react-jss';
12import { noop } from 'lodash'; 12import { noop } from 'lodash';
13import { observer } from 'mobx-react';
14import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
15import Icon from '../icon';
13import { IFormField } from '../typings/generic'; 16import { IFormField } from '../typings/generic';
14import Error from '../error'; 17import Error from '../error';
15import Label from '../label'; 18import Label from '../label';
@@ -17,6 +20,12 @@ import Wrapper from '../wrapper';
17import { scorePasswordFunc } from './scorePassword'; 20import { scorePasswordFunc } from './scorePassword';
18import styles from './styles'; 21import styles from './styles';
19 22
23const messages = defineMessages({
24 passwordToggle: {
25 id: 'settings.app.form.passwordToggle',
26 defaultMessage: 'Password toggle',
27 },
28});
20interface IData { 29interface IData {
21 [index: string]: string; 30 [index: string]: string;
22} 31}
@@ -24,7 +33,8 @@ interface IData {
24interface IProps 33interface IProps
25 extends InputHTMLAttributes<HTMLInputElement>, 34 extends InputHTMLAttributes<HTMLInputElement>,
26 IFormField, 35 IFormField,
27 WithStylesProps<typeof styles> { 36 WithStylesProps<typeof styles>,
37 WrappedComponentProps {
28 focus?: boolean; 38 focus?: boolean;
29 prefix?: string; 39 prefix?: string;
30 suffix?: string; 40 suffix?: string;
@@ -40,8 +50,10 @@ interface IState {
40 passwordScore: number; 50 passwordScore: number;
41} 51}
42 52
43class InputComponent extends Component<IProps, IState> { 53@observer
44 private inputRef: RefObject<HTMLInputElement> = createRef<HTMLInputElement>(); 54class Input extends Component<IProps, IState> {
55 private inputElement: RefObject<HTMLInputElement> =
56 createRef<HTMLInputElement>();
45 57
46 constructor(props: IProps) { 58 constructor(props: IProps) {
47 super(props); 59 super(props);
@@ -53,36 +65,40 @@ class InputComponent extends Component<IProps, IState> {
53 } 65 }
54 66
55 componentDidMount(): void { 67 componentDidMount(): void {
56 const { focus, data = {} } = this.props; 68 const { focus = false, data = {} } = this.props;
57 69
58 if (this.inputRef && this.inputRef.current) { 70 if (this.inputElement && this.inputElement.current) {
59 if (focus) { 71 if (focus) {
60 this.inputRef.current.focus(); 72 this.inputElement.current.focus();
61 } 73 }
62 74
63 for (const key of Object.keys(data)) 75 for (const key of Object.keys(data)) {
64 this.inputRef.current!.dataset[key] = data[key]; 76 this.inputElement.current.dataset[key] = data[key];
77 }
65 } 78 }
66 } 79 }
67 80
68 onChange(e: React.ChangeEvent<HTMLInputElement>): void { 81 onChange(e: React.ChangeEvent<HTMLInputElement>): void {
69 const { scorePassword, onChange } = this.props; 82 const { scorePassword, onChange = noop } = this.props;
70 83
71 if (onChange) { 84 onChange(e);
72 onChange(e);
73 }
74 85
75 if (this.inputRef && this.inputRef.current && scorePassword) { 86 if (scorePassword) {
87 console.log(
88 '--->',
89 e.target.value,
90 scorePasswordFunc(e.target.value as string),
91 );
76 this.setState({ 92 this.setState({
77 passwordScore: scorePasswordFunc(this.inputRef.current.value), 93 passwordScore: scorePasswordFunc(e.target.value),
78 }); 94 });
79 } 95 }
80 } 96 }
81 97
82 onInputKeyPress(e: React.KeyboardEvent): void { 98 onInputKeyPress(e: KeyboardEvent<HTMLInputElement>): void {
83 if (e.key === 'Enter') { 99 if (e.key === 'Enter') {
84 const { onEnterKey } = this.props; 100 const { onEnterKey = noop } = this.props;
85 onEnterKey && onEnterKey(); 101 onEnterKey();
86 } 102 }
87 } 103 }
88 104
@@ -113,10 +129,9 @@ class InputComponent extends Component<IProps, IState> {
113 type = 'text', 129 type = 'text',
114 disabled = false, 130 disabled = false,
115 readOnly, 131 readOnly,
132 intl,
116 } = this.props; 133 } = this.props;
117
118 const { showPassword, passwordScore } = this.state; 134 const { showPassword, passwordScore } = this.state;
119
120 const inputType = type === 'password' && showPassword ? 'text' : type; 135 const inputType = type === 'password' && showPassword ? 'text' : type;
121 136
122 return ( 137 return (
@@ -125,79 +140,85 @@ class InputComponent extends Component<IProps, IState> {
125 identifier="franz-input" 140 identifier="franz-input"
126 noMargin={noMargin} 141 noMargin={noMargin}
127 > 142 >
128 <Label 143 {label && showLabel && (
129 title={label} 144 <Label
130 showLabel={showLabel} 145 title={label}
131 htmlFor={id} 146 showLabel={showLabel}
132 className={classes.label} 147 htmlFor={id}
133 isRequired={required} 148 className={classes.label}
149 isRequired={required}
150 />
151 )}
152 <div
153 className={classnames({
154 [`${inputClassName}`]: inputClassName,
155 // [`${classes.hasPasswordScore}`]: scorePassword,
156 [`${classes.wrapper}`]: true,
157 [`${classes.disabled}`]: disabled,
158 [`${classes.hasError}`]: error,
159 })}
134 > 160 >
161 {prefix && <span className={classes.prefix}>{prefix}</span>}
162 <input
163 id={id}
164 type={inputType}
165 name={name}
166 value={value as string}
167 placeholder={placeholder}
168 spellCheck={spellCheck}
169 className={classes.input}
170 ref={this.inputElement}
171 onChange={this.onChange.bind(this)}
172 onFocus={onFocus}
173 onBlur={onBlur}
174 disabled={disabled}
175 onKeyPress={this.onInputKeyPress.bind(this)}
176 min={min}
177 max={max}
178 step={step}
179 readOnly={readOnly}
180 />
181
182 {suffix && <span className={classes.suffix}>{suffix}</span>}
183
184 {showPasswordToggle && (
185 <button
186 type="button"
187 className={classnames({
188 'franz-form__input-modifier': true,
189 })}
190 onClick={() =>
191 this.setState(prevState => ({
192 showPassword: !prevState.showPassword,
193 }))
194 }
195 tabIndex={-1}
196 aria-label={intl.formatMessage(messages.passwordToggle)}
197 >
198 <Icon icon={this.state.showPassword ? mdiEye : mdiEyeOff} />
199 </button>
200 )}
201 </div>
202 {scorePassword && (
135 <div 203 <div
136 className={classnames({ 204 className={classnames({
137 [`${inputClassName}`]: inputClassName, 205 [`${classes.passwordScore}`]: true,
138 [`${classes.hasPasswordScore}`]: scorePassword,
139 [`${classes.wrapper}`]: true,
140 [`${classes.disabled}`]: disabled,
141 [`${classes.hasError}`]: error, 206 [`${classes.hasError}`]: error,
142 })} 207 })}
143 > 208 >
144 {prefix && <span className={classes.prefix}>{prefix}</span>} 209 <meter
145 <input 210 value={passwordScore < 5 ? 5 : passwordScore}
146 id={id} 211 low={30}
147 type={inputType} 212 high={75}
148 name={name} 213 optimum={100}
149 value={value as string} 214 max={100}
150 placeholder={placeholder}
151 spellCheck={spellCheck}
152 className={classes.input}
153 ref={this.inputRef}
154 onChange={this.onChange.bind(this)}
155 onFocus={onFocus}
156 onBlur={onBlur}
157 disabled={disabled}
158 onKeyPress={this.onInputKeyPress.bind(this)}
159 min={min}
160 max={max}
161 step={step}
162 readOnly={readOnly}
163 /> 215 />
164 {suffix && <span className={classes.suffix}>{suffix}</span>}
165 {showPasswordToggle && (
166 <button
167 type="button"
168 className={classes.formModifier}
169 onClick={() =>
170 this.setState(prevState => ({
171 showPassword: !prevState.showPassword,
172 }))
173 }
174 tabIndex={-1}
175 >
176 <Icon path={!showPassword ? mdiEye : mdiEyeOff} />
177 </button>
178 )}
179 </div> 216 </div>
180 {scorePassword && ( 217 )}
181 <div
182 className={classnames({
183 [`${classes.passwordScore}`]: true,
184 [`${classes.hasError}`]: error,
185 })}
186 >
187 <meter
188 value={passwordScore < 5 ? 5 : passwordScore}
189 low={30}
190 high={75}
191 optimum={100}
192 max={100}
193 />
194 </div>
195 )}
196 </Label>
197 {error && <Error message={error} />} 218 {error && <Error message={error} />}
198 </Wrapper> 219 </Wrapper>
199 ); 220 );
200 } 221 }
201} 222}
202 223
203export default injectSheet(styles, { injectTheme: true })(InputComponent); 224export default injectIntl(withStyles(styles, { injectTheme: true })(Input));