superdesk-ui-framework 3.0.1-beta.4 → 3.0.1-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import moment from 'moment';
4
4
  import nextId from "react-id-generator";
5
+ import { InputWrapper } from './Form';
5
6
 
6
7
  interface IProps {
7
8
  hours?: number;
@@ -24,60 +25,72 @@ interface IState {
24
25
  hours?: any;
25
26
  minutes?: any;
26
27
  seconds?: any;
27
- invalid?: any;
28
28
  }
29
29
 
30
30
  export class DurationInput extends React.PureComponent<IProps, IState> {
31
31
  hourRef: React.RefObject<HTMLInputElement>;
32
32
  minuteRef: React.RefObject<HTMLInputElement>;
33
33
  secondRef: React.RefObject<HTMLInputElement>;
34
+ private htmlId = nextId();
34
35
  constructor(props: IProps) {
35
36
  super(props);
36
37
  this.state = {
37
- hours: this.props.hours ? this.zerPad(this.props.hours) : this.zerPad(0),
38
- minutes: this.props.minutes ? this.zerPad(this.props.minutes) : this.zerPad(0),
39
- seconds: this.props.seconds ? this.zerPad(this.props.seconds) : this.zerPad(0),
40
- invalid: this.props.invalid ?? false,
38
+ hours: this.stateUpdate('hours', this.props.hours, this.props.minutes, this.props.seconds),
39
+ minutes: this.stateUpdate('minutes', this.props.minutes, this.props.seconds),
40
+ seconds: this.stateUpdate('seconds', this.props.seconds),
41
41
  };
42
42
 
43
43
  this.hourRef = React.createRef();
44
44
  this.minuteRef = React.createRef();
45
45
  this.secondRef = React.createRef();
46
46
  this.handleKeyDown = this.handleKeyDown.bind(this);
47
- this.zerPad = this.zerPad.bind(this);
47
+ this.zeroPad = this.zeroPad.bind(this);
48
48
  this.handleChange = this.handleChange.bind(this);
49
49
  this.handleFocusOnKeyUp = this.handleFocusOnKeyUp.bind(this);
50
50
  this.handleKeyValue = this.handleKeyValue.bind(this);
51
+ this.valueUpdate = this.valueUpdate.bind(this);
52
+ this.stateUpdate = this.stateUpdate.bind(this);
53
+ }
51
54
 
55
+ stateUpdate(state: string, parametar1?: number, parametar2?: number, parametar3?: number) {
56
+ let value;
57
+ if (state === 'hours') {
58
+ value = parametar1
59
+ ? parametar1 + Math.floor((parametar2 || 0) / 60) + Math.floor((parametar3 || 0) / 3600)
60
+ : Math.floor((parametar2 || 0) / 60) + Math.floor((parametar3 || 0) / 3600);
61
+ } else if (state === 'minutes') {
62
+ value = parametar1
63
+ ? (parametar1 % 60) + Math.floor((parametar2 || 0) % 3600 / 60)
64
+ : Math.floor((parametar2 || 0) % 3600 / 60);
65
+ } else {
66
+ value = parametar1 ? parametar1 % 60 : 0;
67
+ }
68
+ return this.zeroPad(value);
52
69
  }
53
70
 
54
71
  componentDidUpdate(_: any, prevState: IState) {
55
- if (this.props.onChange) {
56
- this.props.onChange(moment.duration(`${this.state.hours}:${this.state.minutes}:${this.state.seconds}`)
57
- .asSeconds());
58
- }
59
72
  if (!this.hourRef.current || !this.minuteRef.current || !this.secondRef.current ) {
60
73
  return;
61
74
  }
62
75
  if (this.state.hours !== prevState.hours) {
63
76
  if (Number(this.hourRef.current.value) > 99) {
64
77
  this.setState({
65
- hours: this.zerPad(99),
78
+ hours: this.zeroPad(99),
66
79
  });
67
80
  }
68
81
  }
69
82
  if (this.state.minutes !== prevState.minutes) {
70
83
  if (Number(this.minuteRef.current.value) > 59) {
71
84
  this.setState({
72
- hours: this.zerPad(Number(this.state.hours) + 1),
73
- minutes: this.zerPad(0),
85
+ hours: this.zeroPad(Number(this.state.hours) + 1),
86
+ minutes: this.zeroPad(this.state.minutes % 60),
74
87
  });
75
88
  }
76
89
  if (Number(this.minuteRef.current.value) < 0) {
77
90
  this.setState({
78
- hours: this.zerPad(Number(this.state.hours)) > 0
79
- ? this.zerPad(Number(this.state.hours) - 1)
80
- : this.zerPad(Number(this.state.hours)),
91
+ hours: this.zeroPad(Number(this.state.hours)) > 0
92
+ ? this.zeroPad(Number(this.state.hours) - 1)
93
+ : this.zeroPad(Number(this.state.hours)),
81
94
  minutes: 59,
82
95
  });
83
96
  }
@@ -85,19 +98,26 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
85
98
  if (this.state.seconds !== prevState.seconds) {
86
99
  if (Number(this.secondRef.current.value) > 59) {
87
100
  this.setState({
88
- minutes: this.zerPad(Number(this.state.minutes) + 1),
89
- seconds: this.zerPad(0),
101
+ minutes: this.zeroPad(Number(this.state.minutes) + 1),
102
+ seconds: this.zeroPad(this.state.seconds % 60),
90
103
  });
91
104
  }
92
105
  if (Number(this.secondRef.current.value) < 0) {
93
106
  this.setState({
94
- minutes: this.zerPad(Number(this.state.minutes) - 1),
107
+ minutes: this.zeroPad(Number(this.state.minutes) - 1),
95
108
  seconds: 59,
96
109
  });
97
110
  }
98
111
  }
99
112
  }
100
113
 
114
+ valueUpdate() {
115
+ if (this.props.onChange) {
116
+ this.props.onChange(moment.duration(`${this.state.hours}:${this.state.minutes}:${this.state.seconds}`)
117
+ .asSeconds());
118
+ }
119
+ }
120
+
101
121
  handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
102
122
  if (!(event.target instanceof HTMLInputElement)) {
103
123
  return;
@@ -140,6 +160,12 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
140
160
  }
141
161
  if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
142
162
  this.handleKeyValue(event, event.target.id as 'hours' | 'minutes' | 'seconds');
163
+ setTimeout(this.valueUpdate);
164
+ }
165
+ if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
166
+ if (!this.state.hours || !this.state.minutes || !this.state.seconds) {
167
+ setTimeout(this.valueUpdate);
168
+ }
143
169
  }
144
170
  }
145
171
 
@@ -157,22 +183,24 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
157
183
  if (event.key === 'ArrowUp') {
158
184
  if (event.target.id === 'hours') {
159
185
  stateClone[state] = this.state[state] < 99
160
- ? this.zerPad(Number(this.state[state]) + 1)
161
- : this.zerPad(99);
186
+ ? this.zeroPad(Number(this.state[state]) + 1)
187
+ : this.zeroPad(99);
162
188
  } else {
163
- stateClone[state] = this.zerPad(Number(this.state[state]) + 1);
189
+ stateClone[state] = this.zeroPad(Number(this.state[state]) + 1);
164
190
  }
165
191
  } else if (event.key === 'ArrowDown') {
166
192
  if (event.target.id === 'hours') {
167
- stateClone[state] = this.state[state] > 0 ? this.zerPad(Number(this.state[state]) - 1) : this.zerPad(0);
193
+ stateClone[state] = this.state[state] > 0
194
+ ? this.zeroPad(Number(this.state[state]) - 1)
195
+ : this.zeroPad(0);
168
196
  } else {
169
- stateClone[state] = this.zerPad(Number(this.state[state]) - 1);
197
+ stateClone[state] = this.zeroPad(Number(this.state[state]) - 1);
170
198
  }
171
199
  }
172
200
  this.setState(stateClone);
173
201
  }
174
202
 
175
- zerPad(value: number | string) {
203
+ zeroPad(value: number | string) {
176
204
  if (value.toString().length === 1 || value === 0) {
177
205
  return `0${value}`;
178
206
  } else if (!value) {
@@ -190,6 +218,7 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
190
218
  stateClone[state] = event.target.value;
191
219
  }
192
220
  this.setState(stateClone);
221
+ setTimeout(this.valueUpdate);
193
222
  }
194
223
 
195
224
  handleFocus(ref: HTMLInputElement | null, state: 'hours' | 'minutes' | 'seconds') {
@@ -198,18 +227,20 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
198
227
  ref?.setSelectionRange(0, 2);
199
228
  });
200
229
  let stateClone: IState = {};
201
- stateClone[state] = this.zerPad(this.state[state]);
230
+ stateClone[state] = this.zeroPad(this.state[state]);
202
231
  this.setState(stateClone);
203
232
  }
204
233
 
205
234
  handleFocusOnKeyUp(event: React.KeyboardEvent<HTMLInputElement>, ref: HTMLInputElement | null) {
206
235
  if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft' && event.key !== 'ArrowUp' && event.key !== 'ArrowDown' && event.key !== 'Backspace') {
207
- const target = event.target as HTMLInputElement;
208
- if (target.value.length >= 2) {
209
- ref?.focus();
210
- setTimeout(() => {
211
- ref?.setSelectionRange(0, 2);
212
- });
236
+ if ((event.keyCode > 46 && event.keyCode < 58) || (event.keyCode > 95 && event.keyCode < 106)) {
237
+ const target = event.target as HTMLInputElement;
238
+ if (target.value.length >= 2) {
239
+ ref?.focus();
240
+ setTimeout(() => {
241
+ ref?.setSelectionRange(0, 2);
242
+ });
243
+ }
213
244
  }
214
245
  }
215
246
  }
@@ -217,25 +248,19 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
217
248
  render() {
218
249
  let InputClasses = classNames('sd-input__duration-input');
219
250
 
220
- const classes = classNames('sd-input', {
221
- 'sd-input--inline-label': this.props.inlineLabel,
222
- 'sd-input--required': this.props.required,
223
- 'sd-input--disabled': this.props.disabled,
224
- 'sd-input--full-width': this.props.fullWidth,
225
- 'sd-input--invalid': this.props.invalid || this.state.invalid,
226
- });
227
- const labelClasses = classNames('sd-input__label', {
228
- 'a11y-only': this.props.labelHidden,
229
- });
230
-
231
- let htmlId = nextId();
232
-
233
251
  return (
234
- <div className={classes}>
235
- <label className={labelClasses} htmlFor={htmlId} id={htmlId + 'label'}
236
- tabIndex={this.props.tabindex === undefined ? undefined : -1}>
237
- {this.props.label}
238
- </label>
252
+ <InputWrapper
253
+ label={this.props.label}
254
+ error={this.props.error}
255
+ required={this.props.required}
256
+ disabled={this.props.disabled}
257
+ invalid={this.props.invalid}
258
+ info={this.props.info}
259
+ inlineLabel={this.props.inlineLabel}
260
+ labelHidden={this.props.labelHidden}
261
+ fullWidth={this.props.fullWidth}
262
+ htmlId={this.htmlId}
263
+ tabindex={this.props.tabindex}>
239
264
  <div className={InputClasses}>
240
265
  <input
241
266
  className='duration-input'
@@ -249,7 +274,7 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
249
274
  onKeyDown={(event) => this.handleKeyDown(event)}
250
275
  onKeyUp={(event) => this.handleFocusOnKeyUp(event, this.minuteRef.current)}
251
276
  onChange={(event) => { this.handleChange(event, 'hours'); }}
252
- onBlur={(event) => this.setState({hours: this.zerPad(event.target.value)})}
277
+ onBlur={(event) => this.setState({hours: this.zeroPad(event.target.value)})}
253
278
  onKeyPress={(event) => {
254
279
  if (!/[0-9]/.test(event.key)) {
255
280
  event.preventDefault();
@@ -267,7 +292,7 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
267
292
  onKeyDown={(event) => this.handleKeyDown(event)}
268
293
  onKeyUp={(event) => this.handleFocusOnKeyUp(event, this.secondRef.current)}
269
294
  onChange={(event) => { this.handleChange(event, 'minutes'); }}
270
- onBlur={(event) => this.setState({minutes: this.zerPad(event.target.value)})}
295
+ onBlur={(event) => this.setState({minutes: this.zeroPad(event.target.value)})}
271
296
  onKeyPress={(event) => {
272
297
  if (!/[0-9]/.test(event.key)) {
273
298
  event.preventDefault();
@@ -285,7 +310,7 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
285
310
  onKeyDown={(event) => this.handleKeyDown(event)}
286
311
  onKeyUp={(event) => this.handleFocusOnKeyUp(event, this.hourRef.current)}
287
312
  onChange={(event) => { this.handleChange(event, 'seconds'); }}
288
- onBlur={(event) => this.setState({seconds: this.zerPad(event.target.value)})}
313
+ onBlur={(event) => this.setState({seconds: this.zeroPad(event.target.value)})}
289
314
  onKeyPress={(event) => {
290
315
  if (!/[0-9]/.test(event.key)) {
291
316
  event.preventDefault();
@@ -293,14 +318,11 @@ export class DurationInput extends React.PureComponent<IProps, IState> {
293
318
  }} />
294
319
  <span className='sd-input__suffix'>s</span>
295
320
  </div>
296
- <div className='sd-input__message-box'>
297
- {this.props.info && !this.props.invalid && !this.state.invalid ?
298
- <div className='sd-input__hint'>{this.props.info}</div> : null}
299
- {this.props.invalid || this.state.invalid ?
300
- <div className='sd-input__message'>{this.props.error}</div>
301
- : null}
302
- </div>
303
- </div>
321
+ </InputWrapper>
304
322
  );
305
323
  }
306
324
  }
325
+
326
+ export function getDurationString(seconds: number) {
327
+ return moment.utc(seconds * 1000).format("HH:mm:ss");
328
+ }
@@ -90,7 +90,9 @@ export class InputNew extends React.PureComponent<IProps, IState> {
90
90
  type="text"
91
91
  onChange={(value: string) => {
92
92
  this.setState({ value: value });
93
- this.setState({ invalid: this.props.maxLength ? (value as string).length > this.props.maxLength : false });
93
+ this.setState({ invalid: this.props.maxLength
94
+ ? (value as string).length > this.props.maxLength
95
+ : false });
94
96
  this.props.onChange(value as string);
95
97
  }}
96
98
  disabled={this.props.disabled}