ferns-ui 0.4.3 → 0.4.4
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 +0 -15
- package/dist/Common.js.map +1 -1
- package/dist/Field.d.ts +16 -1
- package/dist/Field.js +30 -1
- package/dist/Field.js.map +1 -1
- package/dist/TapToEdit.d.ts +11 -11
- package/dist/TapToEdit.js +72 -22
- package/dist/TapToEdit.js.map +1 -1
- package/package.json +1 -1
- package/src/Common.ts +0 -27
- package/src/Field.tsx +71 -5
- package/src/TapToEdit.tsx +101 -31
package/dist/Common.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { SyntheticEvent } from "react";
|
|
2
|
-
import { SelectListOptions } from "./SelectList";
|
|
3
2
|
export interface BaseProfile {
|
|
4
3
|
email: string;
|
|
5
4
|
id: string;
|
|
@@ -368,20 +367,6 @@ export interface FieldWithLabelsProps {
|
|
|
368
367
|
helperTextColor?: AllColors;
|
|
369
368
|
children?: React.ReactNode;
|
|
370
369
|
}
|
|
371
|
-
export interface FieldProps extends FieldWithLabelsProps {
|
|
372
|
-
name: string;
|
|
373
|
-
label?: string;
|
|
374
|
-
subLabel?: string;
|
|
375
|
-
initialValue?: any;
|
|
376
|
-
handleChange: any;
|
|
377
|
-
validate?: (value: any) => boolean;
|
|
378
|
-
validateErrorMessage?: string;
|
|
379
|
-
type?: "boolean" | "email" | "text" | "textarea" | "number" | "currency" | "percent" | "select" | "password" | "url" | "date";
|
|
380
|
-
rows?: number;
|
|
381
|
-
options?: SelectListOptions;
|
|
382
|
-
placeholder?: string;
|
|
383
|
-
disabled?: boolean;
|
|
384
|
-
}
|
|
385
370
|
export interface TextFieldProps extends FieldWithLabelsProps {
|
|
386
371
|
id?: string;
|
|
387
372
|
onChange: OnChangeCallback;
|
package/dist/Common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Common.js","sourceRoot":"","sources":["../src/Common.ts"],"names":[],"mappings":"AAmVA,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":"AAmVA,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;AAu5BD,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
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
2
|
+
import { FieldWithLabelsProps } from "./Common";
|
|
3
|
+
import { SelectListOptions } from "./SelectList";
|
|
4
|
+
export interface FieldProps extends FieldWithLabelsProps {
|
|
5
|
+
name: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
subLabel?: string;
|
|
8
|
+
initialValue?: any;
|
|
9
|
+
handleChange: any;
|
|
10
|
+
validate?: (value: any) => boolean;
|
|
11
|
+
validateErrorMessage?: string;
|
|
12
|
+
type?: "boolean" | "email" | "text" | "textarea" | "number" | "currency" | "percent" | "select" | "password" | "url" | "date" | "multiselect";
|
|
13
|
+
rows?: number;
|
|
14
|
+
options?: SelectListOptions;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|
|
3
18
|
/**
|
|
4
19
|
* Field is a fully uncontrolled component for creating various inputs. Fully uncontrolled means Field manages its own
|
|
5
20
|
* state for the TextFields/Switches/etc, not the parent component. When values are updated, Field will pass the data to
|
package/dist/Field.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Box } from "./Box";
|
|
|
6
6
|
import { FieldWithLabels } from "./FieldWithLabels";
|
|
7
7
|
import { SelectList } from "./SelectList";
|
|
8
8
|
import { Switch } from "./Switch";
|
|
9
|
+
import { Text } from "./Text";
|
|
9
10
|
import { TextArea } from "./TextArea";
|
|
10
11
|
import { TextField } from "./TextField";
|
|
11
12
|
/**
|
|
@@ -19,7 +20,9 @@ import { TextField } from "./TextField";
|
|
|
19
20
|
*
|
|
20
21
|
*/
|
|
21
22
|
export function Field(props) {
|
|
23
|
+
var _a;
|
|
22
24
|
const [value, setValue] = useState(props.initialValue || "");
|
|
25
|
+
const [multiselectValue, setMultiselectValue] = useState((_a = props.initialValue) !== null && _a !== void 0 ? _a : []);
|
|
23
26
|
const handleChange = (newValue) => {
|
|
24
27
|
if (props.type === "currency") {
|
|
25
28
|
newValue = newValue.replace("$", "");
|
|
@@ -39,7 +42,6 @@ export function Field(props) {
|
|
|
39
42
|
}
|
|
40
43
|
};
|
|
41
44
|
const validate = () => {
|
|
42
|
-
// console.log("VALIDATE", props.validate && props.validate(value));
|
|
43
45
|
if (props.validate && !props.validate(value)) {
|
|
44
46
|
return false;
|
|
45
47
|
}
|
|
@@ -79,6 +81,33 @@ export function Field(props) {
|
|
|
79
81
|
}
|
|
80
82
|
return (React.createElement(SelectList, { disabled: props.disabled, id: props.name, options: props.options, value: value, onChange: handleChange }));
|
|
81
83
|
}
|
|
84
|
+
else if (props.type === "multiselect") {
|
|
85
|
+
if (!props.options) {
|
|
86
|
+
console.error("Field with type=multiselect require options");
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return (React.createElement(Box, { width: "100%" }, props.options.map((o) => (React.createElement(Box, { key: o.label + o.value, direction: "row", justifyContent: "between", width: "100%" },
|
|
90
|
+
React.createElement(Box, { flex: "shrink", marginRight: 2 },
|
|
91
|
+
React.createElement(Text, { weight: "bold" }, o.label)),
|
|
92
|
+
React.createElement(Box, null,
|
|
93
|
+
React.createElement(Switch, { key: o.label + o.value, disabled: props.disabled, id: props.name, name: props.name, switched: (multiselectValue !== null && multiselectValue !== void 0 ? multiselectValue : []).includes(o.value), onChange: (result) => {
|
|
94
|
+
let newValue;
|
|
95
|
+
if (result) {
|
|
96
|
+
if (multiselectValue.includes(o.value)) {
|
|
97
|
+
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
newValue = [...multiselectValue, o.value];
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
newValue = multiselectValue.filter((v) => v !== o.value);
|
|
104
|
+
}
|
|
105
|
+
setMultiselectValue(newValue);
|
|
106
|
+
if (props.handleChange) {
|
|
107
|
+
props.handleChange(props.name, newValue);
|
|
108
|
+
}
|
|
109
|
+
} })))))));
|
|
110
|
+
}
|
|
82
111
|
else if (props.type === "textarea") {
|
|
83
112
|
return (React.createElement(TextArea, { disabled: props.disabled, id: props.name, placeholder: props.placeholder, rows: props.rows, value: String(value), onChange: (result) => handleChange(result.value) }));
|
|
84
113
|
}
|
package/dist/Field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"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"}
|
package/dist/TapToEdit.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { BoxProps } from "./Common";
|
|
3
|
+
import { FieldProps } from "./Field";
|
|
4
|
+
export interface TapToEditProps extends Omit<FieldProps, "handleChange"> {
|
|
5
|
+
title: string;
|
|
6
|
+
onSave?: (value: any) => void | Promise<void>;
|
|
7
|
+
editable?: boolean;
|
|
8
|
+
rowBoxProps?: Partial<BoxProps>;
|
|
9
|
+
transform?: (value: any) => string;
|
|
10
|
+
fieldComponent?: (setValue: () => void) => ReactElement;
|
|
5
11
|
}
|
|
6
|
-
export declare
|
|
7
|
-
state: {
|
|
8
|
-
showEdit: boolean;
|
|
9
|
-
};
|
|
10
|
-
render(): JSX.Element;
|
|
11
|
-
}
|
|
12
|
-
export {};
|
|
12
|
+
export declare const TapToEdit: (props: TapToEditProps) => ReactElement;
|
package/dist/TapToEdit.js
CHANGED
|
@@ -1,32 +1,82 @@
|
|
|
1
|
-
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import React, { useState } from "react";
|
|
2
13
|
import { Box } from "./Box";
|
|
3
14
|
import { Button } from "./Button";
|
|
15
|
+
import { Field } from "./Field";
|
|
4
16
|
import { Icon } from "./Icon";
|
|
5
17
|
import { Text } from "./Text";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
export const TapToEdit = (props) => {
|
|
19
|
+
const [editing, setEditing] = useState(false);
|
|
20
|
+
const [value, setValue] = useState(props.initialValue);
|
|
21
|
+
const { title, editable = true, rowBoxProps, transform, fieldComponent } = props, fieldProps = __rest(props, ["title", "editable", "rowBoxProps", "transform", "fieldComponent"]);
|
|
22
|
+
if (editing) {
|
|
23
|
+
return (React.createElement(Box, { direction: "column", maxWidth: "100%", paddingX: 3, paddingY: 2, width: "100%" },
|
|
24
|
+
fieldComponent ? (fieldComponent(setValue)) : (React.createElement(Field, Object.assign({ handleChange: (_, val) => setValue(val), label: props.title }, fieldProps))),
|
|
25
|
+
React.createElement(Box, { direction: "row" },
|
|
26
|
+
React.createElement(Button, { color: "blue", inline: true, text: "Save", onClick: async () => {
|
|
27
|
+
if (!props.onSave) {
|
|
28
|
+
console.error("No onSave provided for editable TapToEdit");
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
await props.onSave(value);
|
|
32
|
+
}
|
|
33
|
+
setEditing(false);
|
|
34
|
+
} }),
|
|
35
|
+
React.createElement(Box, { marginLeft: 2 },
|
|
36
|
+
React.createElement(Button, { color: "red", inline: true, text: "Cancel", onClick: () => {
|
|
37
|
+
setEditing(false);
|
|
38
|
+
} })))));
|
|
11
39
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
React.createElement(Text, null, this.props.children)));
|
|
40
|
+
else {
|
|
41
|
+
let displayValue = value;
|
|
42
|
+
// If transform is present, that takes priority
|
|
43
|
+
if (transform) {
|
|
44
|
+
displayValue = transform(value);
|
|
18
45
|
}
|
|
19
46
|
else {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
// If no transform, try and display the value reasonably.
|
|
48
|
+
if ((fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.type) === "boolean") {
|
|
49
|
+
displayValue = value ? "Yes" : "No";
|
|
50
|
+
}
|
|
51
|
+
else if ((fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.type) === "percent") {
|
|
52
|
+
// Prevent floating point errors from showing up by using parseFloat and precision. Pass through parseFloat again
|
|
53
|
+
// to trim off insignificant zeroes.
|
|
54
|
+
displayValue = `${parseFloat(parseFloat(String(value * 100)).toPrecision(7))}%`;
|
|
55
|
+
}
|
|
56
|
+
else if ((fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.type) === "currency") {
|
|
57
|
+
// TODO: support currencies other than USD in Field and related components.
|
|
58
|
+
const formatter = new Intl.NumberFormat("en-US", {
|
|
59
|
+
style: "currency",
|
|
60
|
+
currency: "USD",
|
|
61
|
+
minimumFractionDigits: 2,
|
|
62
|
+
});
|
|
63
|
+
displayValue = formatter.format(value);
|
|
64
|
+
}
|
|
65
|
+
else if ((fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.type) === "multiselect") {
|
|
66
|
+
// ???
|
|
67
|
+
displayValue = value.join(", ");
|
|
68
|
+
}
|
|
29
69
|
}
|
|
70
|
+
return (React.createElement(Box, Object.assign({ direction: "row", justifyContent: "between", maxWidth: "100%", paddingX: 3, paddingY: 2, width: "100%" }, rowBoxProps),
|
|
71
|
+
React.createElement(Box, null,
|
|
72
|
+
React.createElement(Text, { weight: "bold" },
|
|
73
|
+
title,
|
|
74
|
+
":")),
|
|
75
|
+
React.createElement(Box, { direction: "row", flex: "shrink", marginLeft: 2 },
|
|
76
|
+
React.createElement(Box, { flex: "shrink" },
|
|
77
|
+
React.createElement(Text, { overflow: "breakWord" }, displayValue)),
|
|
78
|
+
editable && (React.createElement(Box, { marginLeft: 2, onClick: () => setEditing(true) },
|
|
79
|
+
React.createElement(Icon, { color: "darkGray", name: "edit", size: "lg" }))))));
|
|
30
80
|
}
|
|
31
|
-
}
|
|
81
|
+
};
|
|
32
82
|
//# sourceMappingURL=TapToEdit.js.map
|
package/dist/TapToEdit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TapToEdit.js","sourceRoot":"","sources":["../src/TapToEdit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,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
|
@@ -680,33 +680,6 @@ export interface FieldWithLabelsProps {
|
|
|
680
680
|
children?: React.ReactNode;
|
|
681
681
|
}
|
|
682
682
|
|
|
683
|
-
export interface FieldProps extends FieldWithLabelsProps {
|
|
684
|
-
name: string;
|
|
685
|
-
label?: string;
|
|
686
|
-
subLabel?: string;
|
|
687
|
-
initialValue?: any;
|
|
688
|
-
handleChange: any;
|
|
689
|
-
// Additional validation
|
|
690
|
-
validate?: (value: any) => boolean;
|
|
691
|
-
validateErrorMessage?: string;
|
|
692
|
-
type?:
|
|
693
|
-
| "boolean"
|
|
694
|
-
| "email"
|
|
695
|
-
| "text"
|
|
696
|
-
| "textarea"
|
|
697
|
-
| "number"
|
|
698
|
-
| "currency"
|
|
699
|
-
| "percent"
|
|
700
|
-
| "select"
|
|
701
|
-
| "password"
|
|
702
|
-
| "url"
|
|
703
|
-
| "date";
|
|
704
|
-
rows?: number;
|
|
705
|
-
options?: SelectListOptions;
|
|
706
|
-
placeholder?: string;
|
|
707
|
-
disabled?: boolean;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
683
|
export interface TextFieldProps extends FieldWithLabelsProps {
|
|
711
684
|
id?: string;
|
|
712
685
|
onChange: OnChangeCallback;
|
package/src/Field.tsx
CHANGED
|
@@ -4,15 +4,40 @@ import moment from "moment-timezone";
|
|
|
4
4
|
import React, {useState} from "react";
|
|
5
5
|
|
|
6
6
|
import {Box} from "./Box";
|
|
7
|
-
import {
|
|
7
|
+
import {FieldWithLabelsProps, TextFieldType} from "./Common";
|
|
8
8
|
import {FieldWithLabels} from "./FieldWithLabels";
|
|
9
|
-
import {SelectList} from "./SelectList";
|
|
9
|
+
import {SelectList, SelectListOptions} from "./SelectList";
|
|
10
10
|
import {Switch} from "./Switch";
|
|
11
|
+
import {Text} from "./Text";
|
|
11
12
|
import {TextArea} from "./TextArea";
|
|
12
13
|
import {TextField} from "./TextField";
|
|
13
14
|
|
|
14
|
-
interface
|
|
15
|
-
|
|
15
|
+
export interface FieldProps extends FieldWithLabelsProps {
|
|
16
|
+
name: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
subLabel?: string;
|
|
19
|
+
initialValue?: any;
|
|
20
|
+
handleChange: any;
|
|
21
|
+
// Additional validation
|
|
22
|
+
validate?: (value: any) => boolean;
|
|
23
|
+
validateErrorMessage?: string;
|
|
24
|
+
type?:
|
|
25
|
+
| "boolean"
|
|
26
|
+
| "email"
|
|
27
|
+
| "text"
|
|
28
|
+
| "textarea"
|
|
29
|
+
| "number"
|
|
30
|
+
| "currency"
|
|
31
|
+
| "percent"
|
|
32
|
+
| "select"
|
|
33
|
+
| "password"
|
|
34
|
+
| "url"
|
|
35
|
+
| "date"
|
|
36
|
+
| "multiselect";
|
|
37
|
+
rows?: number;
|
|
38
|
+
options?: SelectListOptions;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
disabled?: boolean;
|
|
16
41
|
}
|
|
17
42
|
|
|
18
43
|
/**
|
|
@@ -27,6 +52,7 @@ interface State {
|
|
|
27
52
|
*/
|
|
28
53
|
export function Field(props: FieldProps) {
|
|
29
54
|
const [value, setValue] = useState(props.initialValue || "");
|
|
55
|
+
const [multiselectValue, setMultiselectValue] = useState(props.initialValue ?? []);
|
|
30
56
|
|
|
31
57
|
const handleChange = (newValue: string) => {
|
|
32
58
|
if (props.type === "currency") {
|
|
@@ -48,7 +74,6 @@ export function Field(props: FieldProps) {
|
|
|
48
74
|
};
|
|
49
75
|
|
|
50
76
|
const validate = () => {
|
|
51
|
-
// console.log("VALIDATE", props.validate && props.validate(value));
|
|
52
77
|
if (props.validate && !props.validate(value)) {
|
|
53
78
|
return false;
|
|
54
79
|
}
|
|
@@ -96,6 +121,47 @@ export function Field(props: FieldProps) {
|
|
|
96
121
|
onChange={handleChange}
|
|
97
122
|
/>
|
|
98
123
|
);
|
|
124
|
+
} else if (props.type === "multiselect") {
|
|
125
|
+
if (!props.options) {
|
|
126
|
+
console.error("Field with type=multiselect require options");
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return (
|
|
130
|
+
<Box width="100%">
|
|
131
|
+
{props.options.map((o) => (
|
|
132
|
+
<Box key={o.label + o.value} direction="row" justifyContent="between" width="100%">
|
|
133
|
+
<Box flex="shrink" marginRight={2}>
|
|
134
|
+
<Text weight="bold">{o.label}</Text>
|
|
135
|
+
</Box>
|
|
136
|
+
<Box>
|
|
137
|
+
<Switch
|
|
138
|
+
key={o.label + o.value}
|
|
139
|
+
disabled={props.disabled}
|
|
140
|
+
id={props.name}
|
|
141
|
+
name={props.name}
|
|
142
|
+
switched={(multiselectValue ?? []).includes(o.value)}
|
|
143
|
+
onChange={(result) => {
|
|
144
|
+
let newValue;
|
|
145
|
+
if (result) {
|
|
146
|
+
if (multiselectValue.includes(o.value)) {
|
|
147
|
+
console.warn(`Tried to add value that already exists: ${o.value}`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
newValue = [...multiselectValue, o.value];
|
|
151
|
+
} else {
|
|
152
|
+
newValue = multiselectValue.filter((v: string) => v !== o.value);
|
|
153
|
+
}
|
|
154
|
+
setMultiselectValue(newValue);
|
|
155
|
+
if (props.handleChange) {
|
|
156
|
+
props.handleChange(props.name, newValue);
|
|
157
|
+
}
|
|
158
|
+
}}
|
|
159
|
+
/>
|
|
160
|
+
</Box>
|
|
161
|
+
</Box>
|
|
162
|
+
))}
|
|
163
|
+
</Box>
|
|
164
|
+
);
|
|
99
165
|
} else if (props.type === "textarea") {
|
|
100
166
|
return (
|
|
101
167
|
<TextArea
|
package/src/TapToEdit.tsx
CHANGED
|
@@ -1,48 +1,118 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, {ReactElement, useState} from "react";
|
|
2
2
|
|
|
3
3
|
import {Box} from "./Box";
|
|
4
4
|
import {Button} from "./Button";
|
|
5
|
-
import {
|
|
5
|
+
import {BoxProps} from "./Common";
|
|
6
|
+
import {Field, FieldProps} from "./Field";
|
|
6
7
|
import {Icon} from "./Icon";
|
|
7
8
|
import {Text} from "./Text";
|
|
8
|
-
import {TextField} from "./TextField";
|
|
9
9
|
|
|
10
|
-
interface
|
|
11
|
-
|
|
10
|
+
export interface TapToEditProps extends Omit<FieldProps, "handleChange"> {
|
|
11
|
+
title: string;
|
|
12
|
+
// Not required if not editable.
|
|
13
|
+
onSave?: (value: any) => void | Promise<void>;
|
|
14
|
+
// Defaults to true
|
|
15
|
+
editable?: boolean;
|
|
16
|
+
// For changing how the non-editing row renders
|
|
17
|
+
rowBoxProps?: Partial<BoxProps>;
|
|
18
|
+
transform?: (value: any) => string;
|
|
19
|
+
fieldComponent?: (setValue: () => void) => ReactElement;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
export
|
|
15
|
-
|
|
22
|
+
export const TapToEdit = (props: TapToEditProps): ReactElement => {
|
|
23
|
+
const [editing, setEditing] = useState(false);
|
|
24
|
+
const [value, setValue] = useState(props.initialValue);
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
26
|
+
const {title, editable = true, rowBoxProps, transform, fieldComponent, ...fieldProps} = props;
|
|
27
|
+
if (editing) {
|
|
28
|
+
return (
|
|
29
|
+
<Box direction="column" maxWidth="100%" paddingX={3} paddingY={2} width="100%">
|
|
30
|
+
{fieldComponent ? (
|
|
31
|
+
fieldComponent(setValue as any)
|
|
32
|
+
) : (
|
|
33
|
+
<Field
|
|
34
|
+
handleChange={(_: string, val: any): void => setValue(val)}
|
|
35
|
+
label={props.title}
|
|
36
|
+
{...fieldProps}
|
|
37
|
+
/>
|
|
38
|
+
)}
|
|
39
|
+
<Box direction="row">
|
|
40
|
+
<Button
|
|
41
|
+
color="blue"
|
|
42
|
+
inline
|
|
43
|
+
text="Save"
|
|
44
|
+
onClick={async (): Promise<void> => {
|
|
45
|
+
if (!props.onSave) {
|
|
46
|
+
console.error("No onSave provided for editable TapToEdit");
|
|
47
|
+
} else {
|
|
48
|
+
await props.onSave(value);
|
|
49
|
+
}
|
|
50
|
+
setEditing(false);
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
<Box marginLeft={2}>
|
|
32
54
|
<Button
|
|
33
|
-
color="
|
|
55
|
+
color="red"
|
|
34
56
|
inline
|
|
35
|
-
text="
|
|
36
|
-
onClick={() => {
|
|
37
|
-
|
|
38
|
-
if (this.props.onSubmitEditing) {
|
|
39
|
-
this.props.onSubmitEditing();
|
|
40
|
-
}
|
|
57
|
+
text="Cancel"
|
|
58
|
+
onClick={(): void => {
|
|
59
|
+
setEditing(false);
|
|
41
60
|
}}
|
|
42
61
|
/>
|
|
43
62
|
</Box>
|
|
44
63
|
</Box>
|
|
45
|
-
|
|
64
|
+
</Box>
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
let displayValue = value;
|
|
68
|
+
// If transform is present, that takes priority
|
|
69
|
+
if (transform) {
|
|
70
|
+
displayValue = transform(value);
|
|
71
|
+
} else {
|
|
72
|
+
// If no transform, try and display the value reasonably.
|
|
73
|
+
if (fieldProps?.type === "boolean") {
|
|
74
|
+
displayValue = value ? "Yes" : "No";
|
|
75
|
+
} else if (fieldProps?.type === "percent") {
|
|
76
|
+
// Prevent floating point errors from showing up by using parseFloat and precision. Pass through parseFloat again
|
|
77
|
+
// to trim off insignificant zeroes.
|
|
78
|
+
displayValue = `${parseFloat(parseFloat(String(value * 100)).toPrecision(7))}%`;
|
|
79
|
+
} else if (fieldProps?.type === "currency") {
|
|
80
|
+
// TODO: support currencies other than USD in Field and related components.
|
|
81
|
+
const formatter = new Intl.NumberFormat("en-US", {
|
|
82
|
+
style: "currency",
|
|
83
|
+
currency: "USD",
|
|
84
|
+
minimumFractionDigits: 2, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
|
|
85
|
+
});
|
|
86
|
+
displayValue = formatter.format(value);
|
|
87
|
+
} else if (fieldProps?.type === "multiselect") {
|
|
88
|
+
// ???
|
|
89
|
+
displayValue = value.join(", ");
|
|
90
|
+
}
|
|
46
91
|
}
|
|
92
|
+
return (
|
|
93
|
+
<Box
|
|
94
|
+
direction="row"
|
|
95
|
+
justifyContent="between"
|
|
96
|
+
maxWidth="100%"
|
|
97
|
+
paddingX={3}
|
|
98
|
+
paddingY={2}
|
|
99
|
+
width="100%"
|
|
100
|
+
{...rowBoxProps}
|
|
101
|
+
>
|
|
102
|
+
<Box>
|
|
103
|
+
<Text weight="bold">{title}:</Text>
|
|
104
|
+
</Box>
|
|
105
|
+
<Box direction="row" flex="shrink" marginLeft={2}>
|
|
106
|
+
<Box flex="shrink">
|
|
107
|
+
<Text overflow="breakWord">{displayValue}</Text>
|
|
108
|
+
</Box>
|
|
109
|
+
{editable && (
|
|
110
|
+
<Box marginLeft={2} onClick={(): void => setEditing(true)}>
|
|
111
|
+
<Icon color="darkGray" name="edit" size="lg" />
|
|
112
|
+
</Box>
|
|
113
|
+
)}
|
|
114
|
+
</Box>
|
|
115
|
+
</Box>
|
|
116
|
+
);
|
|
47
117
|
}
|
|
48
|
-
}
|
|
118
|
+
};
|