@xeplr/ui-utils 1.0.1 → 1.0.2
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.
- package/package.json +4 -1
- package/src/confirm/confirm.js +116 -47
- package/src/dataImport/validateDesign.js +27 -8
- package/src/dateRange/dateRange.js +273 -0
- package/src/dateRange/designs/DateRangeSample.jsx +138 -0
- package/src/dateRange/designs/dateRange.css +69 -0
- package/src/dateRange/designs/index.js +1 -0
- package/src/dateRange/pages.jsx +10 -0
- package/src/dateRange/useDateRangeController.js +118 -0
- package/src/dateRange/validateDesign.js +20 -0
- package/src/fileUpload/validateDesign.js +27 -8
- package/src/index.js +64 -2
- package/src/progress/ProgressNotifier.jsx +118 -0
- package/src/progress/designs/progressNotifier.css +73 -0
- package/src/progress/progressSource.js +168 -0
- package/src/rangeField/designs/RangeFieldSample.jsx +25 -0
- package/src/rangeField/designs/index.js +1 -0
- package/src/rangeField/designs/rangeField.css +26 -0
- package/src/rangeField/pages.jsx +10 -0
- package/src/rangeField/rangeField.js +29 -0
- package/src/rangeField/useRangeFieldController.js +52 -0
- package/src/rangeField/validateDesign.js +3 -0
- package/src/textField/designs/TextFieldSample.jsx +75 -0
- package/src/textField/designs/index.js +1 -0
- package/src/textField/designs/textField.css +92 -0
- package/src/textField/pages.jsx +10 -0
- package/src/textField/textField.js +65 -0
- package/src/textField/useTextFieldController.js +101 -0
- package/src/textField/validateDesign.js +3 -0
- package/src/theme/default.theme.json +839 -83
- package/src/theme/index.js +80 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { useState, useMemo, useCallback } from 'react';
|
|
2
|
+
import { toValue, normalise, validate, remaining, TEXT_TYPES } from './textField.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {object} props
|
|
6
|
+
* @param {'text'|'multiline'|'search'} [props.type='text']
|
|
7
|
+
* @param {string} [props.value] — controlled
|
|
8
|
+
* @param {string} [props.defaultValue] — uncontrolled initial
|
|
9
|
+
* @param {(value) => void} [props.onChange]
|
|
10
|
+
* @param {(value) => void} [props.onCommit] — on blur/Enter, after normalising
|
|
11
|
+
* @param {boolean} [props.required]
|
|
12
|
+
* @param {number} [props.minLength]
|
|
13
|
+
* @param {number} [props.maxLength]
|
|
14
|
+
* @param {RegExp|string} [props.pattern]
|
|
15
|
+
* @param {boolean} [props.trim] — normalise away surrounding space
|
|
16
|
+
* @param {string} [props.placeholder]
|
|
17
|
+
* @param {boolean} [props.disabled]
|
|
18
|
+
* @param {number} [props.rows] — multiline only
|
|
19
|
+
*/
|
|
20
|
+
export function useTextFieldController(props) {
|
|
21
|
+
props = props || {};
|
|
22
|
+
var type = props.type || 'text';
|
|
23
|
+
if (TEXT_TYPES.indexOf(type) === -1) {
|
|
24
|
+
throw new Error('[xeplr-ui-utils:TextField] Unknown type: ' + type + '. Expected one of ' + TEXT_TYPES.join(', '));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var controlled = props.value !== undefined;
|
|
28
|
+
var [inner, setInner] = useState(toValue(props.defaultValue));
|
|
29
|
+
var raw = controlled ? toValue(props.value) : inner;
|
|
30
|
+
|
|
31
|
+
// Errors appear on COMMIT, not on every keystroke. A required field that
|
|
32
|
+
// says "This is required" while you are still typing the first letter is
|
|
33
|
+
// shouting at somebody for not having finished.
|
|
34
|
+
var [touched, setTouched] = useState(false);
|
|
35
|
+
|
|
36
|
+
var options = useMemo(function() {
|
|
37
|
+
return {
|
|
38
|
+
required: props.required,
|
|
39
|
+
requiredMessage: props.requiredMessage,
|
|
40
|
+
minLength: props.minLength,
|
|
41
|
+
maxLength: props.maxLength,
|
|
42
|
+
pattern: props.pattern,
|
|
43
|
+
patternMessage: props.patternMessage,
|
|
44
|
+
trim: props.trim
|
|
45
|
+
};
|
|
46
|
+
}, [props.required, props.requiredMessage, props.minLength, props.maxLength,
|
|
47
|
+
props.pattern, props.patternMessage, props.trim]);
|
|
48
|
+
|
|
49
|
+
var handleChange = useCallback(function(e) {
|
|
50
|
+
var next = e && e.target ? e.target.value : e;
|
|
51
|
+
// Capped as you type, because a maxLength you can exceed and are told off
|
|
52
|
+
// for afterwards is a maxLength that does nothing.
|
|
53
|
+
if (props.maxLength != null) next = String(next).slice(0, props.maxLength);
|
|
54
|
+
if (!controlled) setInner(next);
|
|
55
|
+
if (props.onChange) props.onChange(next);
|
|
56
|
+
}, [controlled, props.maxLength, props.onChange]);
|
|
57
|
+
|
|
58
|
+
var commit = useCallback(function(value) {
|
|
59
|
+
var next = normalise(value, options);
|
|
60
|
+
setTouched(true);
|
|
61
|
+
if (!controlled && next !== value) setInner(next);
|
|
62
|
+
if (props.onCommit) props.onCommit(next);
|
|
63
|
+
else if (next !== value && props.onChange) props.onChange(next);
|
|
64
|
+
}, [controlled, options, props.onChange, props.onCommit]);
|
|
65
|
+
|
|
66
|
+
var handleBlur = useCallback(function(e) {
|
|
67
|
+
commit(e && e.target ? e.target.value : raw);
|
|
68
|
+
}, [commit, raw]);
|
|
69
|
+
|
|
70
|
+
var handleKeyDown = useCallback(function(e) {
|
|
71
|
+
// Enter commits a single-line field; in a multiline one it is a newline.
|
|
72
|
+
if (e.key === 'Enter' && type !== 'multiline') commit(e.target.value);
|
|
73
|
+
if (e.key === 'Escape' && props.onCancel) props.onCancel();
|
|
74
|
+
}, [commit, type, props.onCancel]);
|
|
75
|
+
|
|
76
|
+
var handleClear = useCallback(function() {
|
|
77
|
+
if (!controlled) setInner('');
|
|
78
|
+
if (props.onChange) props.onChange('');
|
|
79
|
+
if (props.onCommit) props.onCommit('');
|
|
80
|
+
}, [controlled, props.onChange, props.onCommit]);
|
|
81
|
+
|
|
82
|
+
var error = touched ? validate(raw, options) : null;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
type: type,
|
|
86
|
+
raw: raw,
|
|
87
|
+
error: error,
|
|
88
|
+
remaining: remaining(raw, props.maxLength),
|
|
89
|
+
placeholder: props.placeholder,
|
|
90
|
+
disabled: props.disabled,
|
|
91
|
+
required: props.required,
|
|
92
|
+
maxLength: props.maxLength,
|
|
93
|
+
rows: props.rows,
|
|
94
|
+
label: props.label,
|
|
95
|
+
help: props.help,
|
|
96
|
+
handleChange: handleChange,
|
|
97
|
+
handleBlur: handleBlur,
|
|
98
|
+
handleKeyDown: handleKeyDown,
|
|
99
|
+
handleClear: handleClear
|
|
100
|
+
};
|
|
101
|
+
}
|