ferns-ui 0.16.0 → 0.18.0
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/Common.d.ts +3 -0
- package/dist/Common.js.map +1 -1
- package/dist/Field.d.ts +3 -11
- package/dist/Field.js +46 -92
- package/dist/Field.js.map +1 -1
- package/dist/IconButton.d.ts +2 -4
- package/dist/IconButton.js +43 -26
- package/dist/IconButton.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/Common.ts +3 -0
- package/src/Field.tsx +84 -121
- package/src/IconButton.tsx +66 -29
- package/src/SelectList.tsx +7 -1
- package/src/TapToEdit.tsx +18 -13
package/dist/Common.d.ts
CHANGED
|
@@ -328,6 +328,9 @@ export interface IconButtonProps {
|
|
|
328
328
|
bgColor?: "transparent" | "transparentDarkGray" | "gray" | "lightGray" | "white";
|
|
329
329
|
disabled?: boolean;
|
|
330
330
|
selected?: boolean;
|
|
331
|
+
withConfirmation?: boolean;
|
|
332
|
+
confirmationText?: string;
|
|
333
|
+
confirmationHeading?: string;
|
|
331
334
|
}
|
|
332
335
|
export interface NavigatorProps {
|
|
333
336
|
config?: any;
|
package/dist/Common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Common.js","sourceRoot":"","sources":["../src/Common.ts"],"names":[],"mappings":"AAkVA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAkBzB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAe,EAAE,EAAE;IAClD,OAAO;QACL,EAAE,EAAE,CAAC;QACL,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;KACP,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAI,GAAG,EAAE,EAAY,EAAE;IACtD,IAAI,QAAkB,CAAC;IACvB,IAAI,IAAI,GAAG,CAAC,EAAE;QACZ,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM;QACL,QAAQ,GAAG,IAAI,CAAC;KACjB;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,OAAgE;IAC9F,OAAO,CAAC;QACN,SAAS,EAAE,QAAQ;QACnB,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,KAAK;QACZ,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;KACjB,CAAC,OAAO,CAAC,IAAI,MAAM,CAAU,CAAC;AACjC,CAAC;
|
|
1
|
+
{"version":3,"file":"Common.js","sourceRoot":"","sources":["../src/Common.ts"],"names":[],"mappings":"AAkVA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAkBzB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAe,EAAE,EAAE;IAClD,OAAO;QACL,EAAE,EAAE,CAAC;QACL,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;KACP,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAI,GAAG,EAAE,EAAY,EAAE;IACtD,IAAI,QAAkB,CAAC;IACvB,IAAI,IAAI,GAAG,CAAC,EAAE;QACZ,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM,IAAI,IAAI,GAAG,EAAE,EAAE;QACpB,QAAQ,GAAG,IAAI,CAAC;KACjB;SAAM;QACL,QAAQ,GAAG,IAAI,CAAC;KACjB;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,OAAgE;IAC9F,OAAO,CAAC;QACN,SAAS,EAAE,QAAQ;QACnB,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,KAAK;QACZ,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;KACjB,CAAC,OAAO,CAAC,IAAI,MAAM,CAAU,CAAC;AACjC,CAAC;AAg5BD,MAAM,UAAU,UAAU,CAAC,OAAqB;IAC9C,OAAO,CACL,OAAO;QACP,OAAO,CAAC,KAAK;QACb,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CACrF,CAAC;AACJ,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,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
import { Box } from "./Box";
|
|
3
3
|
import { USSTATESLIST } from "./Constants";
|
|
4
4
|
import { FieldWithLabels } from "./FieldWithLabels";
|
|
@@ -8,48 +8,20 @@ import { Text } from "./Text";
|
|
|
8
8
|
import { TextArea } from "./TextArea";
|
|
9
9
|
import { TextField } from "./TextField";
|
|
10
10
|
/**
|
|
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
11
|
* Note: You MUST set a key={} prop for this component, otherwise you may wind up with stale data. Just changing
|
|
17
12
|
* initialValue will not work.
|
|
18
13
|
*
|
|
19
14
|
*/
|
|
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 : []);
|
|
15
|
+
export const Field = ({ name, label, labelColor, height, type, rows, value, onChange, options, placeholder, disabled, errorMessage, errorMessageColor, helperText, helperTextColor, }) => {
|
|
24
16
|
// showCustomInput, customValue, and selectValue are all for type="customSelect"
|
|
25
17
|
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
26
18
|
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
19
|
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
47
20
|
const handleCustomSelectListChange = (newValue) => {
|
|
48
21
|
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
49
22
|
if (newValue === "custom") {
|
|
50
23
|
setShowCustomInput(true);
|
|
51
|
-
|
|
52
|
-
setSelectValue(newValue);
|
|
24
|
+
onChange("");
|
|
53
25
|
}
|
|
54
26
|
// If any non-custom value is selected
|
|
55
27
|
else {
|
|
@@ -59,80 +31,63 @@ export function Field(props) {
|
|
|
59
31
|
setCustomValue("");
|
|
60
32
|
}
|
|
61
33
|
// Update the field value and select value
|
|
62
|
-
|
|
63
|
-
setSelectValue(newValue);
|
|
64
|
-
if (props.handleChange) {
|
|
65
|
-
props.handleChange(props.name, newValue);
|
|
66
|
-
}
|
|
34
|
+
onChange(newValue);
|
|
67
35
|
}
|
|
68
36
|
};
|
|
69
37
|
const handleCustomSelectTextInputChange = (newValue) => {
|
|
70
|
-
|
|
38
|
+
onChange(newValue);
|
|
71
39
|
setCustomValue(newValue);
|
|
72
|
-
if (props.handleChange) {
|
|
73
|
-
props.handleChange(props.name, newValue);
|
|
74
|
-
}
|
|
75
40
|
};
|
|
76
41
|
const handleAddressChange = (field, newValue) => {
|
|
77
|
-
|
|
78
|
-
if (props.handleChange) {
|
|
79
|
-
props.handleChange(props.name, Object.assign(Object.assign({}, value), { [field]: newValue }));
|
|
80
|
-
}
|
|
42
|
+
onChange(Object.assign(Object.assign({}, value), { [field]: newValue }));
|
|
81
43
|
};
|
|
82
44
|
const handleSwitchChange = (switchValue) => {
|
|
83
|
-
|
|
84
|
-
if (props.handleChange) {
|
|
85
|
-
props.handleChange(props.name, switchValue);
|
|
86
|
-
}
|
|
45
|
+
onChange(switchValue);
|
|
87
46
|
};
|
|
88
47
|
const renderField = () => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!props.options) {
|
|
48
|
+
if (type === "select") {
|
|
49
|
+
if (!options) {
|
|
92
50
|
console.error("Field with type=select require options");
|
|
93
51
|
return null;
|
|
94
52
|
}
|
|
95
|
-
return (React.createElement(SelectList, { disabled:
|
|
53
|
+
return (React.createElement(SelectList, { disabled: disabled, id: name, options: options, value: value, onChange: onChange }));
|
|
96
54
|
}
|
|
97
|
-
else if (
|
|
98
|
-
if (!
|
|
55
|
+
else if (type === "multiselect") {
|
|
56
|
+
if (!options) {
|
|
99
57
|
console.error("Field with type=multiselect require options");
|
|
100
58
|
return null;
|
|
101
59
|
}
|
|
102
|
-
return (React.createElement(Box, { width: "100%" },
|
|
60
|
+
return (React.createElement(Box, { width: "100%" }, options.map((o) => (React.createElement(Box, { key: o.label + o.value, direction: "row", justifyContent: "between", width: "100%" },
|
|
103
61
|
React.createElement(Box, { flex: "shrink", marginRight: 2 },
|
|
104
62
|
React.createElement(Text, { weight: "bold" }, o.label)),
|
|
105
63
|
React.createElement(Box, null,
|
|
106
|
-
React.createElement(Switch, { key: o.label + o.value, disabled:
|
|
64
|
+
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
65
|
let newValue;
|
|
108
66
|
if (result) {
|
|
109
|
-
if (
|
|
67
|
+
if (value.includes(o.value)) {
|
|
110
68
|
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
111
69
|
return;
|
|
112
70
|
}
|
|
113
|
-
newValue = [...
|
|
71
|
+
newValue = [...value, o.value];
|
|
114
72
|
}
|
|
115
73
|
else {
|
|
116
|
-
newValue =
|
|
117
|
-
}
|
|
118
|
-
setMultiselectValue(newValue);
|
|
119
|
-
if (props.handleChange) {
|
|
120
|
-
props.handleChange(props.name, newValue);
|
|
74
|
+
newValue = value.filter((v) => v !== o.value);
|
|
121
75
|
}
|
|
76
|
+
onChange(newValue);
|
|
122
77
|
} })))))));
|
|
123
78
|
}
|
|
124
|
-
else if (
|
|
125
|
-
return (React.createElement(TextArea, { disabled:
|
|
79
|
+
else if (type === "textarea") {
|
|
80
|
+
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
81
|
}
|
|
127
|
-
else if (
|
|
128
|
-
return (React.createElement(Switch, { disabled:
|
|
82
|
+
else if (type === "boolean") {
|
|
83
|
+
return (React.createElement(Switch, { disabled: disabled, id: name, name: name, switched: Boolean(value), onChange: (result) => handleSwitchChange(result) }));
|
|
129
84
|
}
|
|
130
|
-
else if (
|
|
131
|
-
return (React.createElement(TextField, { disabled: true, id:
|
|
85
|
+
else if (type === "date") {
|
|
86
|
+
return (React.createElement(TextField, { disabled: true, id: name, placeholder: placeholder, type: "date",
|
|
132
87
|
// TODO: allow editing with a date picker
|
|
133
|
-
value: value, onChange: (result) =>
|
|
88
|
+
value: value, onChange: (result) => onChange(result.value) }));
|
|
134
89
|
}
|
|
135
|
-
else if (
|
|
90
|
+
else if (type === "address") {
|
|
136
91
|
const { address1 = "", address2 = "", city = "", state = "", zipcode = "", } = value;
|
|
137
92
|
return (React.createElement(React.Fragment, null,
|
|
138
93
|
React.createElement(TextField, { id: "address1", label: "Street Address", type: "text", value: address1, onChange: (result) => handleAddressChange("address1", result.value) }),
|
|
@@ -141,45 +96,44 @@ export function Field(props) {
|
|
|
141
96
|
React.createElement(SelectList, { id: "state", label: "State", options: USSTATESLIST, placeholder: "Select state", style: { borderRadius: 16 }, value: state, onChange: (result) => handleAddressChange("state", result) }),
|
|
142
97
|
React.createElement(TextField, { id: "zipcode", label: "Zipcode", type: "text", value: zipcode, onChange: (result) => handleAddressChange("zipcode", result.value) })));
|
|
143
98
|
}
|
|
144
|
-
else if (
|
|
145
|
-
if (!
|
|
99
|
+
else if (type === "customSelect") {
|
|
100
|
+
if (!options) {
|
|
146
101
|
console.error("Field with type=customSelect require options");
|
|
147
102
|
return null;
|
|
148
103
|
}
|
|
149
104
|
return (React.createElement(React.Fragment, null,
|
|
150
|
-
React.createElement(SelectList, { id: "providedOptions", options: [...
|
|
105
|
+
React.createElement(SelectList, { id: "providedOptions", options: [...options, { label: "Custom", value: "custom" }], placeholder: "Select an option", value: value, onChange: handleCustomSelectListChange }),
|
|
151
106
|
Boolean(showCustomInput) && (React.createElement(Box, { paddingY: 2 },
|
|
152
|
-
React.createElement(TextField, { disabled:
|
|
107
|
+
React.createElement(TextField, { disabled: disabled, id: "customOptions", placeholder: placeholder, type: "text", value: customValue, onChange: (result) => handleCustomSelectTextInputChange(result.value) })))));
|
|
153
108
|
}
|
|
154
109
|
else {
|
|
155
|
-
let
|
|
110
|
+
let tfType = "text";
|
|
111
|
+
let tfValue = value;
|
|
156
112
|
// Number is supported differently because we need fractional numbers and they don't work
|
|
157
113
|
// well on iOS.
|
|
158
|
-
if (
|
|
159
|
-
|
|
114
|
+
if (type && ["date", "email", "password", "url"].indexOf(type) > -1) {
|
|
115
|
+
tfType = type;
|
|
160
116
|
}
|
|
161
|
-
else if (
|
|
162
|
-
|
|
117
|
+
else if (type === "percent" || type === "currency") {
|
|
118
|
+
tfType = "text";
|
|
163
119
|
}
|
|
164
120
|
let autoComplete = "on";
|
|
165
|
-
if (
|
|
121
|
+
if (tfType === "password") {
|
|
166
122
|
autoComplete = "current-password";
|
|
167
123
|
}
|
|
168
|
-
else if (
|
|
124
|
+
else if (tfType === "email") {
|
|
169
125
|
autoComplete = "username";
|
|
170
126
|
}
|
|
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) }));
|
|
127
|
+
if (type === "percent") {
|
|
128
|
+
tfValue = `${Number(value).toFixed(0)}%`;
|
|
129
|
+
}
|
|
130
|
+
else if (type === "currency") {
|
|
131
|
+
tfValue = `$${Number(value).toFixed(2)}`;
|
|
132
|
+
}
|
|
133
|
+
return (React.createElement(TextField, { autoComplete: autoComplete, disabled: disabled, id: name, placeholder: placeholder, type: tfType, value: tfValue, onChange: (result) => onChange(result.value) }));
|
|
179
134
|
}
|
|
180
135
|
};
|
|
181
136
|
const children = renderField();
|
|
182
|
-
const { errorMessage, errorMessageColor, helperText, helperTextColor, label, labelColor } = props;
|
|
183
137
|
return (React.createElement(Box, { marginBottom: 5 },
|
|
184
138
|
React.createElement(FieldWithLabels, Object.assign({}, {
|
|
185
139
|
errorMessage,
|
|
@@ -189,5 +143,5 @@ export function Field(props) {
|
|
|
189
143
|
label,
|
|
190
144
|
labelColor,
|
|
191
145
|
}), children)));
|
|
192
|
-
}
|
|
146
|
+
};
|
|
193
147
|
//# 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,EAAE,EAAC,
|
|
1
|
+
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"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"}
|
package/dist/IconButton.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import { IconButtonProps } from "./Common";
|
|
3
|
-
export declare
|
|
4
|
-
render(): JSX.Element;
|
|
5
|
-
}
|
|
3
|
+
export declare function IconButton({ prefix, icon, iconColor, onClick, size, bgColor, withConfirmation, confirmationText, confirmationHeading, }: IconButtonProps): JSX.Element;
|
package/dist/IconButton.js
CHANGED
|
@@ -1,41 +1,58 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
import { TouchableOpacity } from "react-native";
|
|
3
3
|
import { iconSizeToNumber } from "./Common";
|
|
4
4
|
import { Icon } from "./Icon";
|
|
5
|
+
import { Modal } from "./Modal";
|
|
6
|
+
import { Text } from "./Text";
|
|
5
7
|
import { Unifier } from "./Unifier";
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
export function IconButton({ prefix, icon, iconColor, onClick, size, bgColor = "transparent", withConfirmation = false, confirmationText = "Are you sure you want to continue?", confirmationHeading = "Confirm", }) {
|
|
9
|
+
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
10
|
+
let opacity = 1;
|
|
11
|
+
let color;
|
|
12
|
+
if (bgColor === "transparentDarkGray") {
|
|
13
|
+
opacity = 0.8;
|
|
14
|
+
color = Unifier.theme.darkGray;
|
|
15
|
+
}
|
|
16
|
+
else if (bgColor === "transparent" || !bgColor) {
|
|
17
|
+
opacity = 0.0;
|
|
18
|
+
color = Unifier.theme.white;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
color = Unifier.theme[bgColor];
|
|
22
|
+
}
|
|
23
|
+
const renderConfirmation = () => {
|
|
24
|
+
return (React.createElement(Modal, { heading: confirmationHeading, primaryButtonOnClick: () => {
|
|
25
|
+
onClick();
|
|
26
|
+
setShowConfirmation(false);
|
|
27
|
+
}, primaryButtonText: "Confirm", secondaryButtonOnClick: () => setShowConfirmation(false), secondaryButtonText: "Cancel", size: "sm", visible: showConfirmation, onDismiss: () => {
|
|
28
|
+
setShowConfirmation(false);
|
|
29
|
+
} },
|
|
30
|
+
React.createElement(Text, null, confirmationText)));
|
|
31
|
+
};
|
|
32
|
+
return (React.createElement(React.Fragment, null,
|
|
33
|
+
React.createElement(TouchableOpacity, { hitSlop: { top: 10, left: 10, bottom: 10, right: 10 }, style: {
|
|
22
34
|
opacity,
|
|
23
35
|
backgroundColor: color,
|
|
24
36
|
borderRadius: 100,
|
|
25
|
-
// paddingBottom: iconSizeToNumber(
|
|
26
|
-
// paddingTop: iconSizeToNumber(
|
|
27
|
-
// paddingLeft: iconSizeToNumber(
|
|
28
|
-
// paddingRight: iconSizeToNumber(
|
|
29
|
-
width: iconSizeToNumber(
|
|
30
|
-
height: iconSizeToNumber(
|
|
37
|
+
// paddingBottom: iconSizeToNumber(size) / 4,
|
|
38
|
+
// paddingTop: iconSizeToNumber(size) / 4,
|
|
39
|
+
// paddingLeft: iconSizeToNumber(size) / 2,
|
|
40
|
+
// paddingRight: iconSizeToNumber(size) / 2,
|
|
41
|
+
width: iconSizeToNumber(size) * 2.5,
|
|
42
|
+
height: iconSizeToNumber(size) * 2.5,
|
|
31
43
|
display: "flex",
|
|
32
44
|
justifyContent: "center",
|
|
33
45
|
alignItems: "center",
|
|
34
46
|
}, onPress: () => {
|
|
35
47
|
Unifier.utils.haptic();
|
|
36
|
-
|
|
48
|
+
if (withConfirmation && !showConfirmation) {
|
|
49
|
+
setShowConfirmation(true);
|
|
50
|
+
}
|
|
51
|
+
else if (onClick) {
|
|
52
|
+
onClick();
|
|
53
|
+
}
|
|
37
54
|
} },
|
|
38
|
-
React.createElement(Icon, { color:
|
|
39
|
-
|
|
55
|
+
React.createElement(Icon, { color: iconColor, name: icon, prefix: prefix || "fas", size: size })),
|
|
56
|
+
Boolean(withConfirmation) && renderConfirmation()));
|
|
40
57
|
}
|
|
41
58
|
//# sourceMappingURL=IconButton.js.map
|
package/dist/IconButton.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.js","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"IconButton.js","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAC;AACtC,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAkB,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,IAAI,EACJ,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAO,GAAG,aAAa,EACvB,gBAAgB,GAAG,KAAK,EACxB,gBAAgB,GAAG,oCAAoC,EACvD,mBAAmB,GAAG,SAAS,GACf;IAChB,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEhE,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,CAAC;IACV,IAAI,OAAO,KAAK,qBAAqB,EAAE;QACrC,OAAO,GAAG,GAAG,CAAC;QACd,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;KAChC;SAAM,IAAI,OAAO,KAAK,aAAa,IAAI,CAAC,OAAO,EAAE;QAChD,OAAO,GAAG,GAAG,CAAC;QACd,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;KAC7B;SAAM;QACL,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAChC;IAED,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,OAAO,CACL,oBAAC,KAAK,IACJ,OAAO,EAAE,mBAAmB,EAC5B,oBAAoB,EAAE,GAAG,EAAE;gBACzB,OAAO,EAAE,CAAC;gBACV,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC,EACD,iBAAiB,EAAC,SAAS,EAC3B,sBAAsB,EAAE,GAAS,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAC9D,mBAAmB,EAAC,QAAQ,EAC5B,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,GAAS,EAAE;gBACpB,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;YAED,oBAAC,IAAI,QAAE,gBAAgB,CAAQ,CACzB,CACT,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL;QACE,oBAAC,gBAAgB,IACf,OAAO,EAAE,EAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAC,EACnD,KAAK,EAAE;gBACL,OAAO;gBACP,eAAe,EAAE,KAAK;gBACtB,YAAY,EAAE,GAAG;gBACjB,6CAA6C;gBAC7C,0CAA0C;gBAC1C,2CAA2C;gBAC3C,4CAA4C;gBAC5C,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,GAAG;gBACnC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,GAAG;gBACpC,OAAO,EAAE,MAAM;gBACf,cAAc,EAAE,QAAQ;gBACxB,UAAU,EAAE,QAAQ;aACrB,EACD,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,EAAE;oBACzC,mBAAmB,CAAC,IAAI,CAAC,CAAC;iBAC3B;qBAAM,IAAI,OAAO,EAAE;oBAClB,OAAO,EAAE,CAAC;iBACX;YACH,CAAC;YAED,oBAAC,IAAI,IAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,KAAK,EAAE,IAAI,EAAE,IAAI,GAAI,CAC1D;QAClB,OAAO,CAAC,gBAAgB,CAAC,IAAI,kBAAkB,EAAE,CACjD,CACJ,CAAC;AACJ,CAAC"}
|
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, "handleChange"> {
|
|
4
|
+
export interface TapToEditProps extends Omit<FieldProps, "handleChange" | "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, 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, 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
package/src/Common.ts
CHANGED
|
@@ -630,6 +630,9 @@ export interface IconButtonProps {
|
|
|
630
630
|
bgColor?: "transparent" | "transparentDarkGray" | "gray" | "lightGray" | "white"; // default transparent
|
|
631
631
|
disabled?: boolean;
|
|
632
632
|
selected?: boolean;
|
|
633
|
+
withConfirmation?: boolean;
|
|
634
|
+
confirmationText?: string;
|
|
635
|
+
confirmationHeading?: string;
|
|
633
636
|
}
|
|
634
637
|
|
|
635
638
|
export interface NavigatorProps {
|
package/src/Field.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {useState} from "react";
|
|
2
2
|
|
|
3
3
|
import {Box} from "./Box";
|
|
4
4
|
import {AddressInterface, FieldWithLabelsProps, TextFieldType} from "./Common";
|
|
@@ -13,13 +13,7 @@ import {TextField} from "./TextField";
|
|
|
13
13
|
export interface FieldProps extends FieldWithLabelsProps {
|
|
14
14
|
name: string;
|
|
15
15
|
label?: string;
|
|
16
|
-
subLabel?: string;
|
|
17
|
-
initialValue?: any;
|
|
18
|
-
handleChange: any;
|
|
19
16
|
height?: number;
|
|
20
|
-
// Additional validation
|
|
21
|
-
validate?: (value: any) => boolean;
|
|
22
|
-
validateErrorMessage?: string;
|
|
23
17
|
type?:
|
|
24
18
|
| "boolean"
|
|
25
19
|
| "email"
|
|
@@ -36,58 +30,45 @@ export interface FieldProps extends FieldWithLabelsProps {
|
|
|
36
30
|
| "address"
|
|
37
31
|
| "customSelect";
|
|
38
32
|
rows?: number;
|
|
33
|
+
value?: any;
|
|
34
|
+
onChange?: any;
|
|
39
35
|
options?: SelectListOptions;
|
|
40
36
|
placeholder?: string;
|
|
41
37
|
disabled?: boolean;
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
/**
|
|
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
41
|
* Note: You MUST set a key={} prop for this component, otherwise you may wind up with stale data. Just changing
|
|
51
42
|
* initialValue will not work.
|
|
52
43
|
*
|
|
53
44
|
*/
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
export const Field = ({
|
|
46
|
+
name,
|
|
47
|
+
label,
|
|
48
|
+
labelColor,
|
|
49
|
+
height,
|
|
50
|
+
type,
|
|
51
|
+
rows,
|
|
52
|
+
value,
|
|
53
|
+
onChange,
|
|
54
|
+
options,
|
|
55
|
+
placeholder,
|
|
56
|
+
disabled,
|
|
57
|
+
errorMessage,
|
|
58
|
+
errorMessageColor,
|
|
59
|
+
helperText,
|
|
60
|
+
helperTextColor,
|
|
61
|
+
}: FieldProps) => {
|
|
58
62
|
// showCustomInput, customValue, and selectValue are all for type="customSelect"
|
|
59
63
|
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
60
64
|
const [customValue, setCustomValue] = useState("");
|
|
61
|
-
const [selectValue, setSelectValue] = useState(props.initialValue || "");
|
|
62
|
-
|
|
63
|
-
const handleChange = (newValue: string) => {
|
|
64
|
-
if (props.type === "currency") {
|
|
65
|
-
newValue = newValue.replace("$", "");
|
|
66
|
-
} else if (props.type === "percent") {
|
|
67
|
-
newValue = newValue.replace("%", "");
|
|
68
|
-
}
|
|
69
|
-
setValue(newValue);
|
|
70
|
-
if (props.handleChange) {
|
|
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
65
|
|
|
84
66
|
// Custom select has 3 values - the overall field value, the value of the select menu, and the value of the custom input
|
|
85
67
|
const handleCustomSelectListChange = (newValue: string) => {
|
|
86
68
|
// If "custom" is selected from the dropdown, toggle the custom input open and clear the previous value
|
|
87
69
|
if (newValue === "custom") {
|
|
88
70
|
setShowCustomInput(true);
|
|
89
|
-
|
|
90
|
-
setSelectValue(newValue);
|
|
71
|
+
onChange("");
|
|
91
72
|
}
|
|
92
73
|
|
|
93
74
|
// If any non-custom value is selected
|
|
@@ -99,59 +80,46 @@ export function Field(props: FieldProps) {
|
|
|
99
80
|
}
|
|
100
81
|
|
|
101
82
|
// Update the field value and select value
|
|
102
|
-
|
|
103
|
-
setSelectValue(newValue);
|
|
104
|
-
if (props.handleChange) {
|
|
105
|
-
props.handleChange(props.name, newValue);
|
|
106
|
-
}
|
|
83
|
+
onChange(newValue);
|
|
107
84
|
}
|
|
108
85
|
};
|
|
109
86
|
|
|
110
87
|
const handleCustomSelectTextInputChange = (newValue: string) => {
|
|
111
|
-
|
|
88
|
+
onChange(newValue);
|
|
112
89
|
setCustomValue(newValue);
|
|
113
|
-
if (props.handleChange) {
|
|
114
|
-
props.handleChange(props.name, newValue);
|
|
115
|
-
}
|
|
116
90
|
};
|
|
117
91
|
|
|
118
92
|
const handleAddressChange = (field: string, newValue: string) => {
|
|
119
|
-
|
|
120
|
-
if (props.handleChange) {
|
|
121
|
-
props.handleChange(props.name, {...value, [field]: newValue});
|
|
122
|
-
}
|
|
93
|
+
onChange({...value, [field]: newValue});
|
|
123
94
|
};
|
|
124
95
|
|
|
125
96
|
const handleSwitchChange = (switchValue: boolean) => {
|
|
126
|
-
|
|
127
|
-
if (props.handleChange) {
|
|
128
|
-
props.handleChange(props.name, switchValue);
|
|
129
|
-
}
|
|
97
|
+
onChange(switchValue);
|
|
130
98
|
};
|
|
131
99
|
|
|
132
100
|
const renderField = () => {
|
|
133
|
-
if (
|
|
134
|
-
if (!
|
|
101
|
+
if (type === "select") {
|
|
102
|
+
if (!options) {
|
|
135
103
|
console.error("Field with type=select require options");
|
|
136
104
|
return null;
|
|
137
105
|
}
|
|
138
106
|
return (
|
|
139
107
|
<SelectList
|
|
140
|
-
disabled={
|
|
141
|
-
id={
|
|
142
|
-
options={
|
|
108
|
+
disabled={disabled}
|
|
109
|
+
id={name}
|
|
110
|
+
options={options}
|
|
143
111
|
value={value}
|
|
144
|
-
onChange={
|
|
112
|
+
onChange={onChange}
|
|
145
113
|
/>
|
|
146
114
|
);
|
|
147
|
-
} else if (
|
|
148
|
-
if (!
|
|
115
|
+
} else if (type === "multiselect") {
|
|
116
|
+
if (!options) {
|
|
149
117
|
console.error("Field with type=multiselect require options");
|
|
150
118
|
return null;
|
|
151
119
|
}
|
|
152
120
|
return (
|
|
153
121
|
<Box width="100%">
|
|
154
|
-
{
|
|
122
|
+
{options.map((o) => (
|
|
155
123
|
<Box key={o.label + o.value} direction="row" justifyContent="between" width="100%">
|
|
156
124
|
<Box flex="shrink" marginRight={2}>
|
|
157
125
|
<Text weight="bold">{o.label}</Text>
|
|
@@ -159,25 +127,22 @@ export function Field(props: FieldProps) {
|
|
|
159
127
|
<Box>
|
|
160
128
|
<Switch
|
|
161
129
|
key={o.label + o.value}
|
|
162
|
-
disabled={
|
|
163
|
-
id={
|
|
164
|
-
name={
|
|
165
|
-
switched={(
|
|
130
|
+
disabled={disabled}
|
|
131
|
+
id={name}
|
|
132
|
+
name={name}
|
|
133
|
+
switched={(value ?? []).includes(o.value)}
|
|
166
134
|
onChange={(result) => {
|
|
167
135
|
let newValue;
|
|
168
136
|
if (result) {
|
|
169
|
-
if (
|
|
137
|
+
if (value.includes(o.value)) {
|
|
170
138
|
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
171
139
|
return;
|
|
172
140
|
}
|
|
173
|
-
newValue = [...
|
|
141
|
+
newValue = [...value, o.value];
|
|
174
142
|
} else {
|
|
175
|
-
newValue =
|
|
176
|
-
}
|
|
177
|
-
setMultiselectValue(newValue);
|
|
178
|
-
if (props.handleChange) {
|
|
179
|
-
props.handleChange(props.name, newValue);
|
|
143
|
+
newValue = value.filter((v: string) => v !== o.value);
|
|
180
144
|
}
|
|
145
|
+
onChange(newValue);
|
|
181
146
|
}}
|
|
182
147
|
/>
|
|
183
148
|
</Box>
|
|
@@ -185,41 +150,41 @@ export function Field(props: FieldProps) {
|
|
|
185
150
|
))}
|
|
186
151
|
</Box>
|
|
187
152
|
);
|
|
188
|
-
} else if (
|
|
153
|
+
} else if (type === "textarea") {
|
|
189
154
|
return (
|
|
190
155
|
<TextArea
|
|
191
|
-
disabled={
|
|
192
|
-
height={
|
|
193
|
-
id={
|
|
194
|
-
placeholder={Boolean(value) ? "" :
|
|
195
|
-
rows={
|
|
156
|
+
disabled={disabled}
|
|
157
|
+
height={height ?? 100}
|
|
158
|
+
id={name}
|
|
159
|
+
placeholder={Boolean(value) ? "" : placeholder}
|
|
160
|
+
rows={rows}
|
|
196
161
|
value={String(value)}
|
|
197
|
-
onChange={(result) =>
|
|
162
|
+
onChange={(result) => onChange(result.value)}
|
|
198
163
|
/>
|
|
199
164
|
);
|
|
200
|
-
} else if (
|
|
165
|
+
} else if (type === "boolean") {
|
|
201
166
|
return (
|
|
202
167
|
<Switch
|
|
203
|
-
disabled={
|
|
204
|
-
id={
|
|
205
|
-
name={
|
|
168
|
+
disabled={disabled}
|
|
169
|
+
id={name}
|
|
170
|
+
name={name}
|
|
206
171
|
switched={Boolean(value)}
|
|
207
172
|
onChange={(result) => handleSwitchChange(result)}
|
|
208
173
|
/>
|
|
209
174
|
);
|
|
210
|
-
} else if (
|
|
175
|
+
} else if (type === "date") {
|
|
211
176
|
return (
|
|
212
177
|
<TextField
|
|
213
178
|
disabled
|
|
214
|
-
id={
|
|
215
|
-
placeholder={
|
|
179
|
+
id={name}
|
|
180
|
+
placeholder={placeholder}
|
|
216
181
|
type="date"
|
|
217
182
|
// TODO: allow editing with a date picker
|
|
218
183
|
value={value}
|
|
219
|
-
onChange={(result) =>
|
|
184
|
+
onChange={(result) => onChange(result.value)}
|
|
220
185
|
/>
|
|
221
186
|
);
|
|
222
|
-
} else if (
|
|
187
|
+
} else if (type === "address") {
|
|
223
188
|
const {
|
|
224
189
|
address1 = "",
|
|
225
190
|
address2 = "",
|
|
@@ -268,8 +233,8 @@ export function Field(props: FieldProps) {
|
|
|
268
233
|
/>
|
|
269
234
|
</>
|
|
270
235
|
);
|
|
271
|
-
} else if (
|
|
272
|
-
if (!
|
|
236
|
+
} else if (type === "customSelect") {
|
|
237
|
+
if (!options) {
|
|
273
238
|
console.error("Field with type=customSelect require options");
|
|
274
239
|
return null;
|
|
275
240
|
}
|
|
@@ -277,17 +242,17 @@ export function Field(props: FieldProps) {
|
|
|
277
242
|
<>
|
|
278
243
|
<SelectList
|
|
279
244
|
id="providedOptions"
|
|
280
|
-
options={[...
|
|
245
|
+
options={[...options, {label: "Custom", value: "custom"}]}
|
|
281
246
|
placeholder="Select an option"
|
|
282
|
-
value={
|
|
247
|
+
value={value}
|
|
283
248
|
onChange={handleCustomSelectListChange}
|
|
284
249
|
/>
|
|
285
250
|
{Boolean(showCustomInput) && (
|
|
286
251
|
<Box paddingY={2}>
|
|
287
252
|
<TextField
|
|
288
|
-
disabled={
|
|
253
|
+
disabled={disabled}
|
|
289
254
|
id="customOptions"
|
|
290
|
-
placeholder={
|
|
255
|
+
placeholder={placeholder}
|
|
291
256
|
type="text"
|
|
292
257
|
value={customValue}
|
|
293
258
|
onChange={(result) => handleCustomSelectTextInputChange(result.value)}
|
|
@@ -297,43 +262,41 @@ export function Field(props: FieldProps) {
|
|
|
297
262
|
</>
|
|
298
263
|
);
|
|
299
264
|
} else {
|
|
300
|
-
let
|
|
265
|
+
let tfType: TextFieldType = "text";
|
|
266
|
+
let tfValue: string = value;
|
|
301
267
|
// Number is supported differently because we need fractional numbers and they don't work
|
|
302
268
|
// well on iOS.
|
|
303
|
-
if (
|
|
304
|
-
|
|
305
|
-
} else if (
|
|
306
|
-
|
|
269
|
+
if (type && ["date", "email", "password", "url"].indexOf(type) > -1) {
|
|
270
|
+
tfType = type as TextFieldType;
|
|
271
|
+
} else if (type === "percent" || type === "currency") {
|
|
272
|
+
tfType = "text";
|
|
307
273
|
}
|
|
308
274
|
let autoComplete: "on" | "current-password" | "username" = "on";
|
|
309
|
-
if (
|
|
275
|
+
if (tfType === "password") {
|
|
310
276
|
autoComplete = "current-password";
|
|
311
|
-
} else if (
|
|
277
|
+
} else if (tfType === "email") {
|
|
312
278
|
autoComplete = "username";
|
|
313
279
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
// }
|
|
320
|
-
// console.log("VAL", value);
|
|
280
|
+
if (type === "percent") {
|
|
281
|
+
tfValue = `${Number(value).toFixed(0)}%`;
|
|
282
|
+
} else if (type === "currency") {
|
|
283
|
+
tfValue = `$${Number(value).toFixed(2)}`;
|
|
284
|
+
}
|
|
321
285
|
return (
|
|
322
286
|
<TextField
|
|
323
287
|
autoComplete={autoComplete}
|
|
324
|
-
disabled={
|
|
325
|
-
id={
|
|
326
|
-
placeholder={
|
|
327
|
-
type={
|
|
328
|
-
value={
|
|
329
|
-
onChange={(result) =>
|
|
288
|
+
disabled={disabled}
|
|
289
|
+
id={name}
|
|
290
|
+
placeholder={placeholder}
|
|
291
|
+
type={tfType as "date" | "email" | "number" | "password" | "text" | "url"}
|
|
292
|
+
value={tfValue}
|
|
293
|
+
onChange={(result) => onChange(result.value)}
|
|
330
294
|
/>
|
|
331
295
|
);
|
|
332
296
|
}
|
|
333
297
|
};
|
|
334
298
|
|
|
335
299
|
const children = renderField();
|
|
336
|
-
const {errorMessage, errorMessageColor, helperText, helperTextColor, label, labelColor} = props;
|
|
337
300
|
return (
|
|
338
301
|
<Box marginBottom={5}>
|
|
339
302
|
<FieldWithLabels
|
|
@@ -350,4 +313,4 @@ export function Field(props: FieldProps) {
|
|
|
350
313
|
</FieldWithLabels>
|
|
351
314
|
</Box>
|
|
352
315
|
);
|
|
353
|
-
}
|
|
316
|
+
};
|
package/src/IconButton.tsx
CHANGED
|
@@ -1,52 +1,89 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, {useState} from "react";
|
|
2
2
|
import {TouchableOpacity} from "react-native";
|
|
3
3
|
|
|
4
4
|
import {IconButtonProps, iconSizeToNumber} from "./Common";
|
|
5
5
|
import {Icon} from "./Icon";
|
|
6
|
+
import {Modal} from "./Modal";
|
|
7
|
+
import {Text} from "./Text";
|
|
6
8
|
import {Unifier} from "./Unifier";
|
|
7
9
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
export function IconButton({
|
|
11
|
+
prefix,
|
|
12
|
+
icon,
|
|
13
|
+
iconColor,
|
|
14
|
+
onClick,
|
|
15
|
+
size,
|
|
16
|
+
bgColor = "transparent",
|
|
17
|
+
withConfirmation = false,
|
|
18
|
+
confirmationText = "Are you sure you want to continue?",
|
|
19
|
+
confirmationHeading = "Confirm",
|
|
20
|
+
}: IconButtonProps) {
|
|
21
|
+
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
22
|
+
|
|
23
|
+
let opacity = 1;
|
|
24
|
+
let color;
|
|
25
|
+
if (bgColor === "transparentDarkGray") {
|
|
26
|
+
opacity = 0.8;
|
|
27
|
+
color = Unifier.theme.darkGray;
|
|
28
|
+
} else if (bgColor === "transparent" || !bgColor) {
|
|
29
|
+
opacity = 0.0;
|
|
30
|
+
color = Unifier.theme.white;
|
|
31
|
+
} else {
|
|
32
|
+
color = Unifier.theme[bgColor];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const renderConfirmation = () => {
|
|
21
36
|
return (
|
|
37
|
+
<Modal
|
|
38
|
+
heading={confirmationHeading}
|
|
39
|
+
primaryButtonOnClick={() => {
|
|
40
|
+
onClick();
|
|
41
|
+
setShowConfirmation(false);
|
|
42
|
+
}}
|
|
43
|
+
primaryButtonText="Confirm"
|
|
44
|
+
secondaryButtonOnClick={(): void => setShowConfirmation(false)}
|
|
45
|
+
secondaryButtonText="Cancel"
|
|
46
|
+
size="sm"
|
|
47
|
+
visible={showConfirmation}
|
|
48
|
+
onDismiss={(): void => {
|
|
49
|
+
setShowConfirmation(false);
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<Text>{confirmationText}</Text>
|
|
53
|
+
</Modal>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
22
59
|
<TouchableOpacity
|
|
23
60
|
hitSlop={{top: 10, left: 10, bottom: 10, right: 10}}
|
|
24
61
|
style={{
|
|
25
62
|
opacity,
|
|
26
63
|
backgroundColor: color,
|
|
27
64
|
borderRadius: 100,
|
|
28
|
-
// paddingBottom: iconSizeToNumber(
|
|
29
|
-
// paddingTop: iconSizeToNumber(
|
|
30
|
-
// paddingLeft: iconSizeToNumber(
|
|
31
|
-
// paddingRight: iconSizeToNumber(
|
|
32
|
-
width: iconSizeToNumber(
|
|
33
|
-
height: iconSizeToNumber(
|
|
65
|
+
// paddingBottom: iconSizeToNumber(size) / 4,
|
|
66
|
+
// paddingTop: iconSizeToNumber(size) / 4,
|
|
67
|
+
// paddingLeft: iconSizeToNumber(size) / 2,
|
|
68
|
+
// paddingRight: iconSizeToNumber(size) / 2,
|
|
69
|
+
width: iconSizeToNumber(size) * 2.5,
|
|
70
|
+
height: iconSizeToNumber(size) * 2.5,
|
|
34
71
|
display: "flex",
|
|
35
72
|
justifyContent: "center",
|
|
36
73
|
alignItems: "center",
|
|
37
74
|
}}
|
|
38
75
|
onPress={() => {
|
|
39
76
|
Unifier.utils.haptic();
|
|
40
|
-
|
|
77
|
+
if (withConfirmation && !showConfirmation) {
|
|
78
|
+
setShowConfirmation(true);
|
|
79
|
+
} else if (onClick) {
|
|
80
|
+
onClick();
|
|
81
|
+
}
|
|
41
82
|
}}
|
|
42
83
|
>
|
|
43
|
-
<Icon
|
|
44
|
-
color={this.props.iconColor}
|
|
45
|
-
name={this.props.icon}
|
|
46
|
-
prefix={this.props.prefix || "fas"}
|
|
47
|
-
size={this.props.size}
|
|
48
|
-
/>
|
|
84
|
+
<Icon color={iconColor} name={icon} prefix={prefix || "fas"} size={size} />
|
|
49
85
|
</TouchableOpacity>
|
|
50
|
-
|
|
51
|
-
|
|
86
|
+
{Boolean(withConfirmation) && renderConfirmation()}
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
52
89
|
}
|
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, "handleChange"> {
|
|
10
|
+
export interface TapToEditProps extends Omit<FieldProps, "handleChange" | "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,
|
|
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} 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") {
|