ferns-ui 0.17.0 → 0.18.1
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/dist/CustomSelect.d.ts +14 -0
- package/dist/CustomSelect.js +36 -0
- package/dist/CustomSelect.js.map +1 -0
- package/dist/Field.d.ts +3 -11
- package/dist/Field.js +43 -116
- package/dist/Field.js.map +1 -1
- package/dist/SelectList.js +6 -1
- package/dist/SelectList.js.map +1 -1
- package/dist/TapToEdit.d.ts +3 -2
- package/dist/TapToEdit.js +8 -8
- package/dist/TapToEdit.js.map +1 -1
- package/package.json +1 -1
- package/src/CustomSelect.tsx +77 -0
- package/src/Field.tsx +79 -165
- package/src/SelectList.tsx +7 -1
- package/src/TapToEdit.tsx +18 -13
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
export interface CustomSelectProps {
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
options: Array<{
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}>;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
label?: string;
|
|
12
|
+
labelColor?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const CustomSelect: ({ value, onChange, placeholder, disabled, options, }: CustomSelectProps) => ReactElement | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Box } from "./Box";
|
|
3
|
+
import { SelectList } from "./SelectList";
|
|
4
|
+
import { TextField } from "./TextField";
|
|
5
|
+
export const CustomSelect = ({ value, onChange, placeholder, disabled, options, }) => {
|
|
6
|
+
const [customValue, setCustomValue] = useState("");
|
|
7
|
+
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!showCustomInput) {
|
|
10
|
+
setCustomValue(value);
|
|
11
|
+
}
|
|
12
|
+
}, [showCustomInput, value]);
|
|
13
|
+
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
14
|
+
const handleCustomSelectListChange = (newValue) => {
|
|
15
|
+
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
16
|
+
if (newValue === "custom") {
|
|
17
|
+
setShowCustomInput(true);
|
|
18
|
+
setCustomValue("custom");
|
|
19
|
+
onChange("");
|
|
20
|
+
}
|
|
21
|
+
// If any non-custom value is selected
|
|
22
|
+
else {
|
|
23
|
+
// Close the custom input if open and clear the value
|
|
24
|
+
if (showCustomInput) {
|
|
25
|
+
setShowCustomInput(false);
|
|
26
|
+
}
|
|
27
|
+
// Update the field value and select value
|
|
28
|
+
onChange(newValue);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return (React.createElement(React.Fragment, null,
|
|
32
|
+
React.createElement(SelectList, { id: "providedOptions", options: [...options, { label: "Custom", value: "custom" }], placeholder: "Select an option", value: customValue, onChange: handleCustomSelectListChange }),
|
|
33
|
+
Boolean(showCustomInput) && (React.createElement(Box, { paddingY: 2 },
|
|
34
|
+
React.createElement(TextField, { disabled: disabled, id: "customOptions", placeholder: placeholder, type: "text", value: value, onChange: (result) => onChange(result.value) })))));
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=CustomSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomSelect.js","sourceRoot":"","sources":["../src/CustomSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAe,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAYtC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,OAAO,GACW,EAAuB,EAAE;IAC3C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE;YACpB,cAAc,CAAC,KAAK,CAAC,CAAC;SACvB;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7B,wHAAwH;IACxH,MAAM,4BAA4B,GAAG,CAAC,QAAgB,EAAE,EAAE;QACxD,uGAAuG;QACvG,IAAI,QAAQ,KAAK,QAAQ,EAAE;YACzB,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,cAAc,CAAC,QAAQ,CAAC,CAAC;YACzB,QAAQ,CAAC,EAAE,CAAC,CAAC;SACd;QAED,sCAAsC;aACjC;YACH,qDAAqD;YACrD,IAAI,eAAe,EAAE;gBACnB,kBAAkB,CAAC,KAAK,CAAC,CAAC;aAC3B;YAED,0CAA0C;YAC1C,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACpB;IACH,CAAC,CAAC;IAEF,OAAO,CACL;QACE,oBAAC,UAAU,IACT,EAAE,EAAC,iBAAiB,EACpB,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC,CAAC,EACzD,WAAW,EAAC,kBAAkB,EAC9B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,4BAA4B,GACtC;QACD,OAAO,CAAC,eAAe,CAAC,IAAI,CAC3B,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC;YACd,oBAAC,SAAS,IACR,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAC,eAAe,EAClB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAC5C,CACE,CACP,CACA,CACJ,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/Field.d.ts
CHANGED
|
@@ -4,26 +4,18 @@ import { SelectListOptions } from "./SelectList";
|
|
|
4
4
|
export interface FieldProps extends FieldWithLabelsProps {
|
|
5
5
|
name: string;
|
|
6
6
|
label?: string;
|
|
7
|
-
subLabel?: string;
|
|
8
|
-
initialValue?: any;
|
|
9
|
-
handleChange: any;
|
|
10
7
|
height?: number;
|
|
11
|
-
validate?: (value: any) => boolean;
|
|
12
|
-
validateErrorMessage?: string;
|
|
13
8
|
type?: "boolean" | "email" | "text" | "textarea" | "number" | "currency" | "percent" | "select" | "password" | "url" | "date" | "multiselect" | "address" | "customSelect";
|
|
14
9
|
rows?: number;
|
|
10
|
+
value?: any;
|
|
11
|
+
onChange?: any;
|
|
15
12
|
options?: SelectListOptions;
|
|
16
13
|
placeholder?: string;
|
|
17
14
|
disabled?: boolean;
|
|
18
15
|
}
|
|
19
16
|
/**
|
|
20
|
-
* Field is a fully uncontrolled component for creating various inputs. Fully uncontrolled means Field manages its own
|
|
21
|
-
* state for the TextFields/Switches/etc, not the parent component. When values are updated, Field will pass the data to
|
|
22
|
-
* the parent through the handleChange prop. You can set an initialValue, but you should not update initialValue
|
|
23
|
-
* this prop with the result of handleChange.
|
|
24
|
-
*
|
|
25
17
|
* Note: You MUST set a key={} prop for this component, otherwise you may wind up with stale data. Just changing
|
|
26
18
|
* initialValue will not work.
|
|
27
19
|
*
|
|
28
20
|
*/
|
|
29
|
-
export declare
|
|
21
|
+
export declare const Field: ({ name, label, labelColor, height, type, rows, value, onChange, options, placeholder, disabled, errorMessage, errorMessageColor, helperText, helperTextColor, }: FieldProps) => JSX.Element;
|
package/dist/Field.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { Box } from "./Box";
|
|
3
3
|
import { USSTATESLIST } from "./Constants";
|
|
4
|
+
import { CustomSelect } from "./CustomSelect";
|
|
4
5
|
import { FieldWithLabels } from "./FieldWithLabels";
|
|
5
6
|
import { SelectList } from "./SelectList";
|
|
6
7
|
import { Switch } from "./Switch";
|
|
@@ -8,131 +9,61 @@ import { Text } from "./Text";
|
|
|
8
9
|
import { TextArea } from "./TextArea";
|
|
9
10
|
import { TextField } from "./TextField";
|
|
10
11
|
/**
|
|
11
|
-
* Field is a fully uncontrolled component for creating various inputs. Fully uncontrolled means Field manages its own
|
|
12
|
-
* state for the TextFields/Switches/etc, not the parent component. When values are updated, Field will pass the data to
|
|
13
|
-
* the parent through the handleChange prop. You can set an initialValue, but you should not update initialValue
|
|
14
|
-
* this prop with the result of handleChange.
|
|
15
|
-
*
|
|
16
12
|
* Note: You MUST set a key={} prop for this component, otherwise you may wind up with stale data. Just changing
|
|
17
13
|
* initialValue will not work.
|
|
18
14
|
*
|
|
19
15
|
*/
|
|
20
|
-
export
|
|
21
|
-
var _a;
|
|
22
|
-
const [value, setValue] = useState(props.initialValue || "");
|
|
23
|
-
const [multiselectValue, setMultiselectValue] = useState((_a = props.initialValue) !== null && _a !== void 0 ? _a : []);
|
|
24
|
-
// showCustomInput, customValue, and selectValue are all for type="customSelect"
|
|
25
|
-
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
26
|
-
const [customValue, setCustomValue] = useState("");
|
|
27
|
-
const [selectValue, setSelectValue] = useState(props.initialValue || "");
|
|
28
|
-
const handleChange = (newValue) => {
|
|
29
|
-
if (props.type === "currency") {
|
|
30
|
-
newValue = newValue.replace("$", "");
|
|
31
|
-
}
|
|
32
|
-
else if (props.type === "percent") {
|
|
33
|
-
newValue = newValue.replace("%", "");
|
|
34
|
-
}
|
|
35
|
-
setValue(newValue);
|
|
36
|
-
if (props.handleChange) {
|
|
37
|
-
props.handleChange(props.name, newValue);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
// upon initialization, set the value within the parent to the initial value
|
|
42
|
-
handleChange(props.initialValue || (props.options && props.options[0] ? props.options[0].value : ""));
|
|
43
|
-
// only want to run this once so setting empty dependency array
|
|
44
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
|
-
}, []);
|
|
46
|
-
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
47
|
-
const handleCustomSelectListChange = (newValue) => {
|
|
48
|
-
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
49
|
-
if (newValue === "custom") {
|
|
50
|
-
setShowCustomInput(true);
|
|
51
|
-
setValue("");
|
|
52
|
-
setSelectValue(newValue);
|
|
53
|
-
}
|
|
54
|
-
// If any non-custom value is selected
|
|
55
|
-
else {
|
|
56
|
-
// Close the custom input if open and clear the value
|
|
57
|
-
if (showCustomInput) {
|
|
58
|
-
setShowCustomInput(false);
|
|
59
|
-
setCustomValue("");
|
|
60
|
-
}
|
|
61
|
-
// Update the field value and select value
|
|
62
|
-
setValue(newValue);
|
|
63
|
-
setSelectValue(newValue);
|
|
64
|
-
if (props.handleChange) {
|
|
65
|
-
props.handleChange(props.name, newValue);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
const handleCustomSelectTextInputChange = (newValue) => {
|
|
70
|
-
setValue(newValue);
|
|
71
|
-
setCustomValue(newValue);
|
|
72
|
-
if (props.handleChange) {
|
|
73
|
-
props.handleChange(props.name, newValue);
|
|
74
|
-
}
|
|
75
|
-
};
|
|
16
|
+
export const Field = ({ name, label, labelColor, height, type, rows, value, onChange, options, placeholder, disabled, errorMessage, errorMessageColor, helperText, helperTextColor, }) => {
|
|
76
17
|
const handleAddressChange = (field, newValue) => {
|
|
77
|
-
|
|
78
|
-
if (props.handleChange) {
|
|
79
|
-
props.handleChange(props.name, Object.assign(Object.assign({}, value), { [field]: newValue }));
|
|
80
|
-
}
|
|
18
|
+
onChange(Object.assign(Object.assign({}, value), { [field]: newValue }));
|
|
81
19
|
};
|
|
82
20
|
const handleSwitchChange = (switchValue) => {
|
|
83
|
-
|
|
84
|
-
if (props.handleChange) {
|
|
85
|
-
props.handleChange(props.name, switchValue);
|
|
86
|
-
}
|
|
21
|
+
onChange(switchValue);
|
|
87
22
|
};
|
|
88
23
|
const renderField = () => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!props.options) {
|
|
24
|
+
if (type === "select") {
|
|
25
|
+
if (!options) {
|
|
92
26
|
console.error("Field with type=select require options");
|
|
93
27
|
return null;
|
|
94
28
|
}
|
|
95
|
-
return (React.createElement(SelectList, { disabled:
|
|
29
|
+
return (React.createElement(SelectList, { disabled: disabled, id: name, options: options, value: value, onChange: onChange }));
|
|
96
30
|
}
|
|
97
|
-
else if (
|
|
98
|
-
if (!
|
|
31
|
+
else if (type === "multiselect") {
|
|
32
|
+
if (!options) {
|
|
99
33
|
console.error("Field with type=multiselect require options");
|
|
100
34
|
return null;
|
|
101
35
|
}
|
|
102
|
-
return (React.createElement(Box, { width: "100%" },
|
|
36
|
+
return (React.createElement(Box, { width: "100%" }, options.map((o) => (React.createElement(Box, { key: o.label + o.value, direction: "row", justifyContent: "between", width: "100%" },
|
|
103
37
|
React.createElement(Box, { flex: "shrink", marginRight: 2 },
|
|
104
38
|
React.createElement(Text, { weight: "bold" }, o.label)),
|
|
105
39
|
React.createElement(Box, null,
|
|
106
|
-
React.createElement(Switch, { key: o.label + o.value, disabled:
|
|
40
|
+
React.createElement(Switch, { key: o.label + o.value, disabled: disabled, id: name, name: name, switched: (value !== null && value !== void 0 ? value : []).includes(o.value), onChange: (result) => {
|
|
107
41
|
let newValue;
|
|
108
42
|
if (result) {
|
|
109
|
-
if (
|
|
43
|
+
if (value.includes(o.value)) {
|
|
110
44
|
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
111
45
|
return;
|
|
112
46
|
}
|
|
113
|
-
newValue = [...
|
|
47
|
+
newValue = [...value, o.value];
|
|
114
48
|
}
|
|
115
49
|
else {
|
|
116
|
-
newValue =
|
|
117
|
-
}
|
|
118
|
-
setMultiselectValue(newValue);
|
|
119
|
-
if (props.handleChange) {
|
|
120
|
-
props.handleChange(props.name, newValue);
|
|
50
|
+
newValue = value.filter((v) => v !== o.value);
|
|
121
51
|
}
|
|
52
|
+
onChange(newValue);
|
|
122
53
|
} })))))));
|
|
123
54
|
}
|
|
124
|
-
else if (
|
|
125
|
-
return (React.createElement(TextArea, { disabled:
|
|
55
|
+
else if (type === "textarea") {
|
|
56
|
+
return (React.createElement(TextArea, { disabled: disabled, height: height !== null && height !== void 0 ? height : 100, id: name, placeholder: Boolean(value) ? "" : placeholder, rows: rows, value: String(value), onChange: (result) => onChange(result.value) }));
|
|
126
57
|
}
|
|
127
|
-
else if (
|
|
128
|
-
return (React.createElement(Switch, { disabled:
|
|
58
|
+
else if (type === "boolean") {
|
|
59
|
+
return (React.createElement(Switch, { disabled: disabled, id: name, name: name, switched: Boolean(value), onChange: (result) => handleSwitchChange(result) }));
|
|
129
60
|
}
|
|
130
|
-
else if (
|
|
131
|
-
return (React.createElement(TextField, { disabled: true, id:
|
|
61
|
+
else if (type === "date") {
|
|
62
|
+
return (React.createElement(TextField, { disabled: true, id: name, placeholder: placeholder, type: "date",
|
|
132
63
|
// TODO: allow editing with a date picker
|
|
133
|
-
value: value, onChange: (result) =>
|
|
64
|
+
value: value, onChange: (result) => onChange(result.value) }));
|
|
134
65
|
}
|
|
135
|
-
else if (
|
|
66
|
+
else if (type === "address") {
|
|
136
67
|
const { address1 = "", address2 = "", city = "", state = "", zipcode = "", } = value;
|
|
137
68
|
return (React.createElement(React.Fragment, null,
|
|
138
69
|
React.createElement(TextField, { id: "address1", label: "Street Address", type: "text", value: address1, onChange: (result) => handleAddressChange("address1", result.value) }),
|
|
@@ -141,45 +72,41 @@ export function Field(props) {
|
|
|
141
72
|
React.createElement(SelectList, { id: "state", label: "State", options: USSTATESLIST, placeholder: "Select state", style: { borderRadius: 16 }, value: state, onChange: (result) => handleAddressChange("state", result) }),
|
|
142
73
|
React.createElement(TextField, { id: "zipcode", label: "Zipcode", type: "text", value: zipcode, onChange: (result) => handleAddressChange("zipcode", result.value) })));
|
|
143
74
|
}
|
|
144
|
-
else if (
|
|
145
|
-
if (!
|
|
75
|
+
else if (type === "customSelect") {
|
|
76
|
+
if (!options) {
|
|
146
77
|
console.error("Field with type=customSelect require options");
|
|
147
78
|
return null;
|
|
148
79
|
}
|
|
149
|
-
return (React.createElement(
|
|
150
|
-
React.createElement(SelectList, { id: "providedOptions", options: [...props.options, { label: "Custom", value: "custom" }], placeholder: "Select an option", value: selectValue, onChange: handleCustomSelectListChange }),
|
|
151
|
-
Boolean(showCustomInput) && (React.createElement(Box, { paddingY: 2 },
|
|
152
|
-
React.createElement(TextField, { disabled: props.disabled, id: "customOptions", placeholder: props.placeholder, type: "text", value: customValue, onChange: (result) => handleCustomSelectTextInputChange(result.value) })))));
|
|
80
|
+
return (React.createElement(CustomSelect, { disabled: disabled, options: options, value: value, onChange: onChange }));
|
|
153
81
|
}
|
|
154
82
|
else {
|
|
155
|
-
let
|
|
83
|
+
let tfType = "text";
|
|
84
|
+
let tfValue = value;
|
|
156
85
|
// Number is supported differently because we need fractional numbers and they don't work
|
|
157
86
|
// well on iOS.
|
|
158
|
-
if (
|
|
159
|
-
|
|
87
|
+
if (type && ["date", "email", "password", "url"].indexOf(type) > -1) {
|
|
88
|
+
tfType = type;
|
|
160
89
|
}
|
|
161
|
-
else if (
|
|
162
|
-
|
|
90
|
+
else if (type === "percent" || type === "currency") {
|
|
91
|
+
tfType = "text";
|
|
163
92
|
}
|
|
164
93
|
let autoComplete = "on";
|
|
165
|
-
if (
|
|
94
|
+
if (tfType === "password") {
|
|
166
95
|
autoComplete = "current-password";
|
|
167
96
|
}
|
|
168
|
-
else if (
|
|
97
|
+
else if (tfType === "email") {
|
|
169
98
|
autoComplete = "username";
|
|
170
99
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return (React.createElement(TextField, { autoComplete: autoComplete, disabled: props.disabled, id: props.name, placeholder: props.placeholder, type: type, value: stringValue, onChange: (result) => handleChange(result.value) }));
|
|
100
|
+
if (type === "percent") {
|
|
101
|
+
tfValue = `${Number(value).toFixed(0)}%`;
|
|
102
|
+
}
|
|
103
|
+
else if (type === "currency") {
|
|
104
|
+
tfValue = `$${Number(value).toFixed(2)}`;
|
|
105
|
+
}
|
|
106
|
+
return (React.createElement(TextField, { autoComplete: autoComplete, disabled: disabled, id: name, placeholder: placeholder, type: tfType, value: tfValue, onChange: (result) => onChange(result.value) }));
|
|
179
107
|
}
|
|
180
108
|
};
|
|
181
109
|
const children = renderField();
|
|
182
|
-
const { errorMessage, errorMessageColor, helperText, helperTextColor, label, labelColor } = props;
|
|
183
110
|
return (React.createElement(Box, { marginBottom: 5 },
|
|
184
111
|
React.createElement(FieldWithLabels, Object.assign({}, {
|
|
185
112
|
errorMessage,
|
|
@@ -189,5 +116,5 @@ export function Field(props) {
|
|
|
189
116
|
label,
|
|
190
117
|
labelColor,
|
|
191
118
|
}), children)));
|
|
192
|
-
}
|
|
119
|
+
};
|
|
193
120
|
//# sourceMappingURL=Field.js.map
|
package/dist/Field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"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"}
|
package/dist/SelectList.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
2
|
import RNPickerSelect from "./PickerSelect";
|
|
3
3
|
import { Unifier } from "./Unifier";
|
|
4
4
|
import { WithLabel } from "./WithLabel";
|
|
5
5
|
export function SelectList({ options, value, onChange, label, labelColor, style }) {
|
|
6
6
|
const withLabelProps = { label, labelColor };
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (!value && options && options.length > 0) {
|
|
9
|
+
onChange(options[0].value);
|
|
10
|
+
}
|
|
11
|
+
}, [onChange, options, value]);
|
|
7
12
|
return (React.createElement(WithLabel, Object.assign({}, withLabelProps),
|
|
8
13
|
React.createElement(RNPickerSelect, { items: options, placeholder: {}, style: {
|
|
9
14
|
viewContainer: {
|
package/dist/SelectList.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../src/SelectList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../src/SelectList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGvC,OAAO,cAAc,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAgBtC,MAAM,UAAU,UAAU,CAAC,EAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAkB;IAC9F,MAAM,cAAc,GAAG,EAAC,KAAK,EAAE,UAAU,EAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3C,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;SAC5B;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/B,OAAO,CACL,oBAAC,SAAS,oBAAK,cAAc;QAC3B,oBAAC,cAAc,IACb,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,EAAE,EACf,KAAK,EAAE;gBACL,aAAa,EAAE;oBACb,aAAa,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,aAAa,KAAI,KAAK;oBAC5C,cAAc,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,KAAI,QAAQ;oBACjD,UAAU,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,UAAU,KAAI,QAAQ;oBACzC,SAAS,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,EAAE;oBACjC,KAAK,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,KAAI,MAAM;oBAC7B,oDAAoD;oBACpD,iBAAiB,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,iBAAiB,KAAI,CAAC;oBAChD,eAAe,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,eAAe,KAAI,CAAC;oBAC5C,WAAW,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,KAAI,OAAO,CAAC,KAAK,CAAC,IAAI;oBACrD,WAAW,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,KAAI,CAAC;oBACpC,YAAY,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,YAAY,KAAI,CAAC;oBACtC,eAAe,EAAE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,eAAe,KAAI,OAAO,CAAC,KAAK,CAAC,KAAK;iBAC/D;aACF,EACD,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,QAAQ,GACvB,CACQ,CACb,CAAC;AACJ,CAAC"}
|
package/dist/TapToEdit.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
2
|
import { BoxProps } from "./Common";
|
|
3
3
|
import { FieldProps } from "./Field";
|
|
4
|
-
export interface TapToEditProps extends Omit<FieldProps, "
|
|
4
|
+
export interface TapToEditProps extends Omit<FieldProps, "onChange" | "value"> {
|
|
5
5
|
title: string;
|
|
6
|
+
initialValue: any;
|
|
6
7
|
onSave?: (value: any) => void | Promise<void>;
|
|
7
8
|
editable?: boolean;
|
|
8
9
|
rowBoxProps?: Partial<BoxProps>;
|
|
9
10
|
transform?: (value: any) => string;
|
|
10
11
|
fieldComponent?: (setValue: () => void) => ReactElement;
|
|
11
12
|
}
|
|
12
|
-
export declare const TapToEdit: (
|
|
13
|
+
export declare const TapToEdit: ({ initialValue, title, onSave, editable, rowBoxProps, transform, fieldComponent, ...fieldProps }: TapToEditProps) => ReactElement;
|
package/dist/TapToEdit.js
CHANGED
|
@@ -15,20 +15,20 @@ import { Button } from "./Button";
|
|
|
15
15
|
import { Field } from "./Field";
|
|
16
16
|
import { Icon } from "./Icon";
|
|
17
17
|
import { Text } from "./Text";
|
|
18
|
-
export const TapToEdit = (
|
|
18
|
+
export const TapToEdit = (_a) => {
|
|
19
|
+
var { initialValue, title, onSave, editable = true, rowBoxProps, transform, fieldComponent } = _a, fieldProps = __rest(_a, ["initialValue", "title", "onSave", "editable", "rowBoxProps", "transform", "fieldComponent"]);
|
|
19
20
|
const [editing, setEditing] = useState(false);
|
|
20
|
-
const [value, setValue] = useState(
|
|
21
|
-
const { title, editable = true, rowBoxProps, transform, fieldComponent } = props, fieldProps = __rest(props, ["title", "editable", "rowBoxProps", "transform", "fieldComponent"]);
|
|
21
|
+
const [value, setValue] = useState(initialValue);
|
|
22
22
|
if (editing) {
|
|
23
23
|
return (React.createElement(Box, { direction: "column" },
|
|
24
|
-
fieldComponent ? (fieldComponent(setValue)) : (React.createElement(Field, Object.assign({
|
|
24
|
+
fieldComponent ? (fieldComponent(setValue)) : (React.createElement(Field, Object.assign({ label: title, value: value, onChange: setValue }, fieldProps))),
|
|
25
25
|
React.createElement(Box, { direction: "row" },
|
|
26
26
|
React.createElement(Button, { color: "blue", inline: true, text: "Save", onClick: async () => {
|
|
27
|
-
if (!
|
|
27
|
+
if (!onSave) {
|
|
28
28
|
console.error("No onSave provided for editable TapToEdit");
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
await
|
|
31
|
+
await onSave(value);
|
|
32
32
|
}
|
|
33
33
|
setEditing(false);
|
|
34
34
|
} }),
|
|
@@ -38,10 +38,10 @@ export const TapToEdit = (props) => {
|
|
|
38
38
|
} })))));
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
let displayValue =
|
|
41
|
+
let displayValue = initialValue;
|
|
42
42
|
// If a transform props is present, that takes priority
|
|
43
43
|
if (transform) {
|
|
44
|
-
displayValue = transform(
|
|
44
|
+
displayValue = transform(initialValue);
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
47
|
// If no transform, try and display the value reasonably.
|
package/dist/TapToEdit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TapToEdit.js","sourceRoot":"","sources":["../src/TapToEdit.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAe,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAC,KAAK,EAAa,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"TapToEdit.js","sourceRoot":"","sources":["../src/TapToEdit.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React, {ReactElement, useEffect, useState} from "react";
|
|
2
|
+
|
|
3
|
+
import {Box} from "./Box";
|
|
4
|
+
import {SelectList} from "./SelectList";
|
|
5
|
+
import {TextField} from "./TextField";
|
|
6
|
+
|
|
7
|
+
export interface CustomSelectProps {
|
|
8
|
+
value: string;
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
options: Array<{label: string; value: string}>;
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
label?: string;
|
|
14
|
+
labelColor?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const CustomSelect = ({
|
|
18
|
+
value,
|
|
19
|
+
onChange,
|
|
20
|
+
placeholder,
|
|
21
|
+
disabled,
|
|
22
|
+
options,
|
|
23
|
+
}: CustomSelectProps): ReactElement | null => {
|
|
24
|
+
const [customValue, setCustomValue] = useState("");
|
|
25
|
+
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!showCustomInput) {
|
|
29
|
+
setCustomValue(value);
|
|
30
|
+
}
|
|
31
|
+
}, [showCustomInput, value]);
|
|
32
|
+
|
|
33
|
+
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
34
|
+
const handleCustomSelectListChange = (newValue: string) => {
|
|
35
|
+
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
36
|
+
if (newValue === "custom") {
|
|
37
|
+
setShowCustomInput(true);
|
|
38
|
+
setCustomValue("custom");
|
|
39
|
+
onChange("");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// If any non-custom value is selected
|
|
43
|
+
else {
|
|
44
|
+
// Close the custom input if open and clear the value
|
|
45
|
+
if (showCustomInput) {
|
|
46
|
+
setShowCustomInput(false);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Update the field value and select value
|
|
50
|
+
onChange(newValue);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<SelectList
|
|
57
|
+
id="providedOptions"
|
|
58
|
+
options={[...options, {label: "Custom", value: "custom"}]}
|
|
59
|
+
placeholder="Select an option"
|
|
60
|
+
value={customValue}
|
|
61
|
+
onChange={handleCustomSelectListChange}
|
|
62
|
+
/>
|
|
63
|
+
{Boolean(showCustomInput) && (
|
|
64
|
+
<Box paddingY={2}>
|
|
65
|
+
<TextField
|
|
66
|
+
disabled={disabled}
|
|
67
|
+
id="customOptions"
|
|
68
|
+
placeholder={placeholder}
|
|
69
|
+
type="text"
|
|
70
|
+
value={value}
|
|
71
|
+
onChange={(result) => onChange(result.value)}
|
|
72
|
+
/>
|
|
73
|
+
</Box>
|
|
74
|
+
)}
|
|
75
|
+
</>
|
|
76
|
+
);
|
|
77
|
+
};
|
package/src/Field.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
|
|
3
3
|
import {Box} from "./Box";
|
|
4
4
|
import {AddressInterface, FieldWithLabelsProps, TextFieldType} from "./Common";
|
|
5
5
|
import {USSTATESLIST} from "./Constants";
|
|
6
|
+
import {CustomSelect} from "./CustomSelect";
|
|
6
7
|
import {FieldWithLabels} from "./FieldWithLabels";
|
|
7
8
|
import {SelectList, SelectListOptions} from "./SelectList";
|
|
8
9
|
import {Switch} from "./Switch";
|
|
@@ -13,13 +14,7 @@ import {TextField} from "./TextField";
|
|
|
13
14
|
export interface FieldProps extends FieldWithLabelsProps {
|
|
14
15
|
name: string;
|
|
15
16
|
label?: string;
|
|
16
|
-
subLabel?: string;
|
|
17
|
-
initialValue?: any;
|
|
18
|
-
handleChange: any;
|
|
19
17
|
height?: number;
|
|
20
|
-
// Additional validation
|
|
21
|
-
validate?: (value: any) => boolean;
|
|
22
|
-
validateErrorMessage?: string;
|
|
23
18
|
type?:
|
|
24
19
|
| "boolean"
|
|
25
20
|
| "email"
|
|
@@ -36,122 +31,66 @@ export interface FieldProps extends FieldWithLabelsProps {
|
|
|
36
31
|
| "address"
|
|
37
32
|
| "customSelect";
|
|
38
33
|
rows?: number;
|
|
34
|
+
value?: any;
|
|
35
|
+
onChange?: any;
|
|
39
36
|
options?: SelectListOptions;
|
|
40
37
|
placeholder?: string;
|
|
41
38
|
disabled?: boolean;
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
/**
|
|
45
|
-
* Field is a fully uncontrolled component for creating various inputs. Fully uncontrolled means Field manages its own
|
|
46
|
-
* state for the TextFields/Switches/etc, not the parent component. When values are updated, Field will pass the data to
|
|
47
|
-
* the parent through the handleChange prop. You can set an initialValue, but you should not update initialValue
|
|
48
|
-
* this prop with the result of handleChange.
|
|
49
|
-
*
|
|
50
42
|
* Note: You MUST set a key={} prop for this component, otherwise you may wind up with stale data. Just changing
|
|
51
43
|
* initialValue will not work.
|
|
52
44
|
*
|
|
53
45
|
*/
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
props.handleChange(props.name, newValue);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
// upon initialization, set the value within the parent to the initial value
|
|
77
|
-
handleChange(
|
|
78
|
-
props.initialValue || (props.options && props.options[0] ? props.options[0].value : "")
|
|
79
|
-
);
|
|
80
|
-
// only want to run this once so setting empty dependency array
|
|
81
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
82
|
-
}, []);
|
|
83
|
-
|
|
84
|
-
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
85
|
-
const handleCustomSelectListChange = (newValue: string) => {
|
|
86
|
-
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
87
|
-
if (newValue === "custom") {
|
|
88
|
-
setShowCustomInput(true);
|
|
89
|
-
setValue("");
|
|
90
|
-
setSelectValue(newValue);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// If any non-custom value is selected
|
|
94
|
-
else {
|
|
95
|
-
// Close the custom input if open and clear the value
|
|
96
|
-
if (showCustomInput) {
|
|
97
|
-
setShowCustomInput(false);
|
|
98
|
-
setCustomValue("");
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Update the field value and select value
|
|
102
|
-
setValue(newValue);
|
|
103
|
-
setSelectValue(newValue);
|
|
104
|
-
if (props.handleChange) {
|
|
105
|
-
props.handleChange(props.name, newValue);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const handleCustomSelectTextInputChange = (newValue: string) => {
|
|
111
|
-
setValue(newValue);
|
|
112
|
-
setCustomValue(newValue);
|
|
113
|
-
if (props.handleChange) {
|
|
114
|
-
props.handleChange(props.name, newValue);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
46
|
+
export const Field = ({
|
|
47
|
+
name,
|
|
48
|
+
label,
|
|
49
|
+
labelColor,
|
|
50
|
+
height,
|
|
51
|
+
type,
|
|
52
|
+
rows,
|
|
53
|
+
value,
|
|
54
|
+
onChange,
|
|
55
|
+
options,
|
|
56
|
+
placeholder,
|
|
57
|
+
disabled,
|
|
58
|
+
errorMessage,
|
|
59
|
+
errorMessageColor,
|
|
60
|
+
helperText,
|
|
61
|
+
helperTextColor,
|
|
62
|
+
}: FieldProps) => {
|
|
118
63
|
const handleAddressChange = (field: string, newValue: string) => {
|
|
119
|
-
|
|
120
|
-
if (props.handleChange) {
|
|
121
|
-
props.handleChange(props.name, {...value, [field]: newValue});
|
|
122
|
-
}
|
|
64
|
+
onChange({...value, [field]: newValue});
|
|
123
65
|
};
|
|
124
66
|
|
|
125
67
|
const handleSwitchChange = (switchValue: boolean) => {
|
|
126
|
-
|
|
127
|
-
if (props.handleChange) {
|
|
128
|
-
props.handleChange(props.name, switchValue);
|
|
129
|
-
}
|
|
68
|
+
onChange(switchValue);
|
|
130
69
|
};
|
|
131
70
|
|
|
132
71
|
const renderField = () => {
|
|
133
|
-
if (
|
|
134
|
-
if (!
|
|
72
|
+
if (type === "select") {
|
|
73
|
+
if (!options) {
|
|
135
74
|
console.error("Field with type=select require options");
|
|
136
75
|
return null;
|
|
137
76
|
}
|
|
138
77
|
return (
|
|
139
78
|
<SelectList
|
|
140
|
-
disabled={
|
|
141
|
-
id={
|
|
142
|
-
options={
|
|
79
|
+
disabled={disabled}
|
|
80
|
+
id={name}
|
|
81
|
+
options={options}
|
|
143
82
|
value={value}
|
|
144
|
-
onChange={
|
|
83
|
+
onChange={onChange}
|
|
145
84
|
/>
|
|
146
85
|
);
|
|
147
|
-
} else if (
|
|
148
|
-
if (!
|
|
86
|
+
} else if (type === "multiselect") {
|
|
87
|
+
if (!options) {
|
|
149
88
|
console.error("Field with type=multiselect require options");
|
|
150
89
|
return null;
|
|
151
90
|
}
|
|
152
91
|
return (
|
|
153
92
|
<Box width="100%">
|
|
154
|
-
{
|
|
93
|
+
{options.map((o) => (
|
|
155
94
|
<Box key={o.label + o.value} direction="row" justifyContent="between" width="100%">
|
|
156
95
|
<Box flex="shrink" marginRight={2}>
|
|
157
96
|
<Text weight="bold">{o.label}</Text>
|
|
@@ -159,25 +98,22 @@ export function Field(props: FieldProps) {
|
|
|
159
98
|
<Box>
|
|
160
99
|
<Switch
|
|
161
100
|
key={o.label + o.value}
|
|
162
|
-
disabled={
|
|
163
|
-
id={
|
|
164
|
-
name={
|
|
165
|
-
switched={(
|
|
101
|
+
disabled={disabled}
|
|
102
|
+
id={name}
|
|
103
|
+
name={name}
|
|
104
|
+
switched={(value ?? []).includes(o.value)}
|
|
166
105
|
onChange={(result) => {
|
|
167
106
|
let newValue;
|
|
168
107
|
if (result) {
|
|
169
|
-
if (
|
|
108
|
+
if (value.includes(o.value)) {
|
|
170
109
|
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
171
110
|
return;
|
|
172
111
|
}
|
|
173
|
-
newValue = [...
|
|
112
|
+
newValue = [...value, o.value];
|
|
174
113
|
} else {
|
|
175
|
-
newValue =
|
|
176
|
-
}
|
|
177
|
-
setMultiselectValue(newValue);
|
|
178
|
-
if (props.handleChange) {
|
|
179
|
-
props.handleChange(props.name, newValue);
|
|
114
|
+
newValue = value.filter((v: string) => v !== o.value);
|
|
180
115
|
}
|
|
116
|
+
onChange(newValue);
|
|
181
117
|
}}
|
|
182
118
|
/>
|
|
183
119
|
</Box>
|
|
@@ -185,41 +121,41 @@ export function Field(props: FieldProps) {
|
|
|
185
121
|
))}
|
|
186
122
|
</Box>
|
|
187
123
|
);
|
|
188
|
-
} else if (
|
|
124
|
+
} else if (type === "textarea") {
|
|
189
125
|
return (
|
|
190
126
|
<TextArea
|
|
191
|
-
disabled={
|
|
192
|
-
height={
|
|
193
|
-
id={
|
|
194
|
-
placeholder={Boolean(value) ? "" :
|
|
195
|
-
rows={
|
|
127
|
+
disabled={disabled}
|
|
128
|
+
height={height ?? 100}
|
|
129
|
+
id={name}
|
|
130
|
+
placeholder={Boolean(value) ? "" : placeholder}
|
|
131
|
+
rows={rows}
|
|
196
132
|
value={String(value)}
|
|
197
|
-
onChange={(result) =>
|
|
133
|
+
onChange={(result) => onChange(result.value)}
|
|
198
134
|
/>
|
|
199
135
|
);
|
|
200
|
-
} else if (
|
|
136
|
+
} else if (type === "boolean") {
|
|
201
137
|
return (
|
|
202
138
|
<Switch
|
|
203
|
-
disabled={
|
|
204
|
-
id={
|
|
205
|
-
name={
|
|
139
|
+
disabled={disabled}
|
|
140
|
+
id={name}
|
|
141
|
+
name={name}
|
|
206
142
|
switched={Boolean(value)}
|
|
207
143
|
onChange={(result) => handleSwitchChange(result)}
|
|
208
144
|
/>
|
|
209
145
|
);
|
|
210
|
-
} else if (
|
|
146
|
+
} else if (type === "date") {
|
|
211
147
|
return (
|
|
212
148
|
<TextField
|
|
213
149
|
disabled
|
|
214
|
-
id={
|
|
215
|
-
placeholder={
|
|
150
|
+
id={name}
|
|
151
|
+
placeholder={placeholder}
|
|
216
152
|
type="date"
|
|
217
153
|
// TODO: allow editing with a date picker
|
|
218
154
|
value={value}
|
|
219
|
-
onChange={(result) =>
|
|
155
|
+
onChange={(result) => onChange(result.value)}
|
|
220
156
|
/>
|
|
221
157
|
);
|
|
222
|
-
} else if (
|
|
158
|
+
} else if (type === "address") {
|
|
223
159
|
const {
|
|
224
160
|
address1 = "",
|
|
225
161
|
address2 = "",
|
|
@@ -268,72 +204,50 @@ export function Field(props: FieldProps) {
|
|
|
268
204
|
/>
|
|
269
205
|
</>
|
|
270
206
|
);
|
|
271
|
-
} else if (
|
|
272
|
-
if (!
|
|
207
|
+
} else if (type === "customSelect") {
|
|
208
|
+
if (!options) {
|
|
273
209
|
console.error("Field with type=customSelect require options");
|
|
274
210
|
return null;
|
|
275
211
|
}
|
|
276
212
|
return (
|
|
277
|
-
|
|
278
|
-
<SelectList
|
|
279
|
-
id="providedOptions"
|
|
280
|
-
options={[...props.options, {label: "Custom", value: "custom"}]}
|
|
281
|
-
placeholder="Select an option"
|
|
282
|
-
value={selectValue}
|
|
283
|
-
onChange={handleCustomSelectListChange}
|
|
284
|
-
/>
|
|
285
|
-
{Boolean(showCustomInput) && (
|
|
286
|
-
<Box paddingY={2}>
|
|
287
|
-
<TextField
|
|
288
|
-
disabled={props.disabled}
|
|
289
|
-
id="customOptions"
|
|
290
|
-
placeholder={props.placeholder}
|
|
291
|
-
type="text"
|
|
292
|
-
value={customValue}
|
|
293
|
-
onChange={(result) => handleCustomSelectTextInputChange(result.value)}
|
|
294
|
-
/>
|
|
295
|
-
</Box>
|
|
296
|
-
)}
|
|
297
|
-
</>
|
|
213
|
+
<CustomSelect disabled={disabled} options={options} value={value} onChange={onChange} />
|
|
298
214
|
);
|
|
299
215
|
} else {
|
|
300
|
-
let
|
|
216
|
+
let tfType: TextFieldType = "text";
|
|
217
|
+
let tfValue: string = value;
|
|
301
218
|
// Number is supported differently because we need fractional numbers and they don't work
|
|
302
219
|
// well on iOS.
|
|
303
|
-
if (
|
|
304
|
-
|
|
305
|
-
} else if (
|
|
306
|
-
|
|
220
|
+
if (type && ["date", "email", "password", "url"].indexOf(type) > -1) {
|
|
221
|
+
tfType = type as TextFieldType;
|
|
222
|
+
} else if (type === "percent" || type === "currency") {
|
|
223
|
+
tfType = "text";
|
|
307
224
|
}
|
|
308
225
|
let autoComplete: "on" | "current-password" | "username" = "on";
|
|
309
|
-
if (
|
|
226
|
+
if (tfType === "password") {
|
|
310
227
|
autoComplete = "current-password";
|
|
311
|
-
} else if (
|
|
228
|
+
} else if (tfType === "email") {
|
|
312
229
|
autoComplete = "username";
|
|
313
230
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
// }
|
|
320
|
-
// console.log("VAL", value);
|
|
231
|
+
if (type === "percent") {
|
|
232
|
+
tfValue = `${Number(value).toFixed(0)}%`;
|
|
233
|
+
} else if (type === "currency") {
|
|
234
|
+
tfValue = `$${Number(value).toFixed(2)}`;
|
|
235
|
+
}
|
|
321
236
|
return (
|
|
322
237
|
<TextField
|
|
323
238
|
autoComplete={autoComplete}
|
|
324
|
-
disabled={
|
|
325
|
-
id={
|
|
326
|
-
placeholder={
|
|
327
|
-
type={
|
|
328
|
-
value={
|
|
329
|
-
onChange={(result) =>
|
|
239
|
+
disabled={disabled}
|
|
240
|
+
id={name}
|
|
241
|
+
placeholder={placeholder}
|
|
242
|
+
type={tfType as "date" | "email" | "number" | "password" | "text" | "url"}
|
|
243
|
+
value={tfValue}
|
|
244
|
+
onChange={(result) => onChange(result.value)}
|
|
330
245
|
/>
|
|
331
246
|
);
|
|
332
247
|
}
|
|
333
248
|
};
|
|
334
249
|
|
|
335
250
|
const children = renderField();
|
|
336
|
-
const {errorMessage, errorMessageColor, helperText, helperTextColor, label, labelColor} = props;
|
|
337
251
|
return (
|
|
338
252
|
<Box marginBottom={5}>
|
|
339
253
|
<FieldWithLabels
|
|
@@ -350,4 +264,4 @@ export function Field(props: FieldProps) {
|
|
|
350
264
|
</FieldWithLabels>
|
|
351
265
|
</Box>
|
|
352
266
|
);
|
|
353
|
-
}
|
|
267
|
+
};
|
package/src/SelectList.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, {useEffect} from "react";
|
|
2
2
|
|
|
3
3
|
import {FieldWithLabelsProps, StyleProp} from "./Common";
|
|
4
4
|
import RNPickerSelect from "./PickerSelect";
|
|
@@ -21,6 +21,12 @@ export interface SelectListProps extends FieldWithLabelsProps {
|
|
|
21
21
|
|
|
22
22
|
export function SelectList({options, value, onChange, label, labelColor, style}: SelectListProps) {
|
|
23
23
|
const withLabelProps = {label, labelColor};
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!value && options && options.length > 0) {
|
|
27
|
+
onChange(options[0].value);
|
|
28
|
+
}
|
|
29
|
+
}, [onChange, options, value]);
|
|
24
30
|
return (
|
|
25
31
|
<WithLabel {...withLabelProps}>
|
|
26
32
|
<RNPickerSelect
|
package/src/TapToEdit.tsx
CHANGED
|
@@ -7,8 +7,9 @@ import {Field, FieldProps} from "./Field";
|
|
|
7
7
|
import {Icon} from "./Icon";
|
|
8
8
|
import {Text} from "./Text";
|
|
9
9
|
|
|
10
|
-
export interface TapToEditProps extends Omit<FieldProps, "
|
|
10
|
+
export interface TapToEditProps extends Omit<FieldProps, "onChange" | "value"> {
|
|
11
11
|
title: string;
|
|
12
|
+
initialValue: any;
|
|
12
13
|
// Not required if not editable.
|
|
13
14
|
onSave?: (value: any) => void | Promise<void>;
|
|
14
15
|
// Defaults to true
|
|
@@ -19,22 +20,26 @@ export interface TapToEditProps extends Omit<FieldProps, "handleChange"> {
|
|
|
19
20
|
fieldComponent?: (setValue: () => void) => ReactElement;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export const TapToEdit = (
|
|
23
|
+
export const TapToEdit = ({
|
|
24
|
+
initialValue,
|
|
25
|
+
title,
|
|
26
|
+
onSave,
|
|
27
|
+
editable = true,
|
|
28
|
+
rowBoxProps,
|
|
29
|
+
transform,
|
|
30
|
+
fieldComponent,
|
|
31
|
+
...fieldProps
|
|
32
|
+
}: TapToEditProps): ReactElement => {
|
|
23
33
|
const [editing, setEditing] = useState(false);
|
|
24
|
-
const [value, setValue] = useState(
|
|
34
|
+
const [value, setValue] = useState(initialValue);
|
|
25
35
|
|
|
26
|
-
const {title, editable = true, rowBoxProps, transform, fieldComponent, ...fieldProps} = props;
|
|
27
36
|
if (editing) {
|
|
28
37
|
return (
|
|
29
38
|
<Box direction="column">
|
|
30
39
|
{fieldComponent ? (
|
|
31
40
|
fieldComponent(setValue as any)
|
|
32
41
|
) : (
|
|
33
|
-
<Field
|
|
34
|
-
handleChange={(_: string, val: any): void => setValue(val)}
|
|
35
|
-
label={props.title}
|
|
36
|
-
{...fieldProps}
|
|
37
|
-
/>
|
|
42
|
+
<Field label={title} value={value} onChange={setValue} {...fieldProps} />
|
|
38
43
|
)}
|
|
39
44
|
<Box direction="row">
|
|
40
45
|
<Button
|
|
@@ -42,10 +47,10 @@ export const TapToEdit = (props: TapToEditProps): ReactElement => {
|
|
|
42
47
|
inline
|
|
43
48
|
text="Save"
|
|
44
49
|
onClick={async (): Promise<void> => {
|
|
45
|
-
if (!
|
|
50
|
+
if (!onSave) {
|
|
46
51
|
console.error("No onSave provided for editable TapToEdit");
|
|
47
52
|
} else {
|
|
48
|
-
await
|
|
53
|
+
await onSave(value);
|
|
49
54
|
}
|
|
50
55
|
setEditing(false);
|
|
51
56
|
}}
|
|
@@ -64,10 +69,10 @@ export const TapToEdit = (props: TapToEditProps): ReactElement => {
|
|
|
64
69
|
</Box>
|
|
65
70
|
);
|
|
66
71
|
} else {
|
|
67
|
-
let displayValue =
|
|
72
|
+
let displayValue = initialValue;
|
|
68
73
|
// If a transform props is present, that takes priority
|
|
69
74
|
if (transform) {
|
|
70
|
-
displayValue = transform(
|
|
75
|
+
displayValue = transform(initialValue);
|
|
71
76
|
} else {
|
|
72
77
|
// If no transform, try and display the value reasonably.
|
|
73
78
|
if (fieldProps?.type === "boolean") {
|