@wq/material-native 2.0.0-alpha.0 → 2.0.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/babel.config.cjs +1 -1
- package/jest.config.js +1 -5
- package/package.json +16 -17
- package/src/App.js +23 -5
- package/src/components/{ExpansionPanel.js → Accordion.js} +2 -2
- package/src/components/BottomNavigation.js +3 -0
- package/src/components/BottomNavigationAction.js +3 -0
- package/src/components/CheckboxButton.js +25 -2
- package/src/components/Fab.js +0 -1
- package/src/components/IconButton.js +1 -1
- package/src/components/Img.js +102 -0
- package/src/components/ListItem.js +17 -1
- package/src/components/NavMenuFixed.js +3 -0
- package/src/components/NavMenuPopup.js +3 -0
- package/src/components/Popup.js +18 -2
- package/src/components/RadioButton.js +25 -2
- package/src/components/SidePanel.js +93 -2
- package/src/components/Switch.js +17 -2
- package/src/components/TabGroup.js +38 -0
- package/src/components/TabItem.js +16 -0
- package/src/components/TableCell.js +23 -1
- package/src/components/index.js +17 -10
- package/src/icons.js +16 -1
- package/src/inputs/Checkbox.js +22 -13
- package/src/inputs/DateTime.js +8 -5
- package/src/inputs/File.js +175 -2
- package/src/inputs/FileArray.js +12 -0
- package/src/inputs/HelperText.js +28 -2
- package/src/inputs/Hidden.js +5 -4
- package/src/inputs/Image.js +5 -2
- package/src/inputs/Input.js +17 -11
- package/src/inputs/Radio.js +31 -2
- package/src/inputs/Select.js +22 -16
- package/src/inputs/Toggle.js +37 -2
- package/src/inputs/index.js +8 -0
- package/setup-jest.js +0 -5
- package/src/components/FileArray.js +0 -3
- /package/src/{components → inputs}/Fieldset.js +0 -0
- /package/src/{components → inputs}/FieldsetArray.js +0 -0
- /package/src/{components → inputs}/FlatFieldset.js +0 -0
package/src/components/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Container from "./Container.js";
|
|
2
2
|
import Header from "./Header.js";
|
|
3
|
+
import NavMenuPopup from "./NavMenuPopup.js";
|
|
4
|
+
import NavMenuFixed from "./NavMenuFixed.js";
|
|
3
5
|
import Main from "./Main.js";
|
|
4
6
|
import Footer from "./Footer.js";
|
|
5
7
|
import FooterContent from "./FooterContent.js";
|
|
@@ -7,6 +9,7 @@ import View from "./View.js";
|
|
|
7
9
|
import ScrollView from "./ScrollView.js";
|
|
8
10
|
import HorizontalView from "./HorizontalView.js";
|
|
9
11
|
import Text from "./Text.js";
|
|
12
|
+
import Img from "./Img.js";
|
|
10
13
|
import Typography from "./Typography.js";
|
|
11
14
|
import FormatJson from "./FormatJson.js";
|
|
12
15
|
|
|
@@ -16,6 +19,10 @@ import ButtonLink from "./ButtonLink.js";
|
|
|
16
19
|
import HomeLink from "./HomeLink.js";
|
|
17
20
|
import IconButton from "./IconButton.js";
|
|
18
21
|
import Fab from "./Fab.js";
|
|
22
|
+
import TabGroup from "./TabGroup.js";
|
|
23
|
+
import TabItem from "./TabItem.js";
|
|
24
|
+
import BottomNavigation from "./BottomNavigation.js";
|
|
25
|
+
import BottomNavigationAction from "./BottomNavigationAction.js";
|
|
19
26
|
import Chip from "./Chip.js";
|
|
20
27
|
import Switch from "./Switch.js";
|
|
21
28
|
import CheckboxButton from "./CheckboxButton.js";
|
|
@@ -25,7 +32,7 @@ import List from "./List.js";
|
|
|
25
32
|
import ListItem from "./ListItem.js";
|
|
26
33
|
import ListItemLink from "./ListItemLink.js";
|
|
27
34
|
import ListSubheader from "./ListSubheader.js";
|
|
28
|
-
import
|
|
35
|
+
import Accordion from "./Accordion.js";
|
|
29
36
|
import ExpandableListItem from "./ExpandableListItem.js";
|
|
30
37
|
import Divider from "./Divider.js";
|
|
31
38
|
|
|
@@ -40,10 +47,6 @@ import TablePagination from "./TablePagination.js";
|
|
|
40
47
|
|
|
41
48
|
import FormRoot from "./FormRoot.js";
|
|
42
49
|
import FormError from "./FormError.js";
|
|
43
|
-
import Fieldset from "./Fieldset.js";
|
|
44
|
-
import FlatFieldset from "./FlatFieldset.js";
|
|
45
|
-
import FieldsetArray from "./FieldsetArray.js";
|
|
46
|
-
import FileArray from "./FileArray.js";
|
|
47
50
|
import CancelButton from "./CancelButton.js";
|
|
48
51
|
import SubmitButton from "./SubmitButton.js";
|
|
49
52
|
import IconSubmitButton from "./IconSubmitButton.js";
|
|
@@ -58,6 +61,8 @@ import Pagination from "./Pagination.js";
|
|
|
58
61
|
export {
|
|
59
62
|
Container,
|
|
60
63
|
Header,
|
|
64
|
+
NavMenuPopup,
|
|
65
|
+
NavMenuFixed,
|
|
61
66
|
Main,
|
|
62
67
|
Footer,
|
|
63
68
|
FooterContent,
|
|
@@ -65,6 +70,7 @@ export {
|
|
|
65
70
|
ScrollView,
|
|
66
71
|
HorizontalView,
|
|
67
72
|
Text,
|
|
73
|
+
Img,
|
|
68
74
|
Typography,
|
|
69
75
|
FormatJson,
|
|
70
76
|
};
|
|
@@ -76,6 +82,10 @@ export {
|
|
|
76
82
|
HomeLink,
|
|
77
83
|
IconButton,
|
|
78
84
|
Fab,
|
|
85
|
+
TabGroup,
|
|
86
|
+
TabItem,
|
|
87
|
+
BottomNavigation,
|
|
88
|
+
BottomNavigationAction,
|
|
79
89
|
Chip,
|
|
80
90
|
Switch,
|
|
81
91
|
CheckboxButton,
|
|
@@ -87,7 +97,8 @@ export {
|
|
|
87
97
|
ListItem,
|
|
88
98
|
ListItemLink,
|
|
89
99
|
ListSubheader,
|
|
90
|
-
|
|
100
|
+
Accordion,
|
|
101
|
+
Accordion as ExpansionPanel,
|
|
91
102
|
ExpandableListItem,
|
|
92
103
|
Divider,
|
|
93
104
|
};
|
|
@@ -106,10 +117,6 @@ export {
|
|
|
106
117
|
export {
|
|
107
118
|
FormRoot,
|
|
108
119
|
FormError,
|
|
109
|
-
Fieldset,
|
|
110
|
-
FlatFieldset,
|
|
111
|
-
FieldsetArray,
|
|
112
|
-
FileArray,
|
|
113
120
|
CancelButton,
|
|
114
121
|
SubmitButton,
|
|
115
122
|
IconSubmitButton,
|
package/src/icons.js
CHANGED
|
@@ -4,6 +4,21 @@ export const Add = "plus",
|
|
|
4
4
|
Success = "check",
|
|
5
5
|
Error = "alert-circle",
|
|
6
6
|
Pending = "sync",
|
|
7
|
+
Close = "close",
|
|
8
|
+
Expand = "chevron-down",
|
|
9
|
+
Collapse = "chevron-up",
|
|
10
|
+
PanelOpen = "chevron-right",
|
|
11
|
+
PanelClose = "chevron-left",
|
|
7
12
|
GpsStart = "crosshairs-gps",
|
|
8
13
|
GpsStop = "crosshairs-off",
|
|
9
|
-
Search = "magnify"
|
|
14
|
+
Search = "magnify",
|
|
15
|
+
List = "view-list",
|
|
16
|
+
Detail = "information",
|
|
17
|
+
Map = "map",
|
|
18
|
+
Home = "home",
|
|
19
|
+
BreadcrumbSeparator = "chevron-right",
|
|
20
|
+
Menu = "menu",
|
|
21
|
+
Login = "login",
|
|
22
|
+
Logout = "logout",
|
|
23
|
+
Config = "cog",
|
|
24
|
+
External = "open-in-new";
|
package/src/inputs/Checkbox.js
CHANGED
|
@@ -2,9 +2,10 @@ import React from "react";
|
|
|
2
2
|
import { useField } from "formik";
|
|
3
3
|
import { Checkbox as PaperCheckbox, useTheme } from "react-native-paper";
|
|
4
4
|
import { Text, View } from "react-native";
|
|
5
|
+
import HelperText from "./HelperText.js";
|
|
5
6
|
import PropTypes from "prop-types";
|
|
6
7
|
|
|
7
|
-
export default function Checkbox({ name, label }) {
|
|
8
|
+
export default function Checkbox({ name, label, hint }) {
|
|
8
9
|
const theme = useTheme(),
|
|
9
10
|
[, meta, helpers] = useField(name),
|
|
10
11
|
{ value } = meta,
|
|
@@ -15,19 +16,26 @@ export default function Checkbox({ name, label }) {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
|
-
<View
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<Text
|
|
26
|
-
style={{ color: theme.colors.text, fontSize: 16, flex: 1 }}
|
|
27
|
-
onPress={toggleChecked}
|
|
19
|
+
<View>
|
|
20
|
+
<View
|
|
21
|
+
style={{
|
|
22
|
+
flexDirection: "row",
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
padding: 8,
|
|
25
|
+
}}
|
|
28
26
|
>
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
<PaperCheckbox.Android
|
|
28
|
+
status={value ? "checked" : "unchecked"}
|
|
29
|
+
onPress={toggleChecked}
|
|
30
|
+
/>
|
|
31
|
+
<Text
|
|
32
|
+
style={{ color: theme.colors.text, fontSize: 16, flex: 1 }}
|
|
33
|
+
onPress={toggleChecked}
|
|
34
|
+
>
|
|
35
|
+
{label}
|
|
36
|
+
</Text>
|
|
37
|
+
</View>
|
|
38
|
+
<HelperText name={name} hint={hint} />
|
|
31
39
|
</View>
|
|
32
40
|
);
|
|
33
41
|
}
|
|
@@ -35,4 +43,5 @@ export default function Checkbox({ name, label }) {
|
|
|
35
43
|
Checkbox.propTypes = {
|
|
36
44
|
name: PropTypes.string,
|
|
37
45
|
label: PropTypes.string,
|
|
46
|
+
hint: PropTypes.string,
|
|
38
47
|
};
|
package/src/inputs/DateTime.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import DateTimePickerModal from "react-native-modal-datetime-picker";
|
|
3
|
-
import { Text } from "react-native";
|
|
3
|
+
import { Text, View } from "react-native";
|
|
4
4
|
import { TouchableRipple, TextInput } from "react-native-paper";
|
|
5
5
|
import { useField } from "formik";
|
|
6
|
-
import PropTypes from "prop-types";
|
|
7
6
|
import { format, parse } from "./date-utils.js";
|
|
7
|
+
import HelperText from "./HelperText.js";
|
|
8
|
+
import PropTypes from "prop-types";
|
|
8
9
|
|
|
9
10
|
const displayFormat = {
|
|
10
11
|
date: (value) => parse.date(value).toLocaleDateString(),
|
|
@@ -12,7 +13,7 @@ const displayFormat = {
|
|
|
12
13
|
datetime: (value) => parse.datetime(value).toLocaleString(),
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
export default function DateTime({ name, type, label }) {
|
|
16
|
+
export default function DateTime({ name, type, label, hint }) {
|
|
16
17
|
type = type.toLowerCase();
|
|
17
18
|
|
|
18
19
|
const [, meta, helpers] = useField(name),
|
|
@@ -33,7 +34,7 @@ export default function DateTime({ name, type, label }) {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
|
-
|
|
37
|
+
<View>
|
|
37
38
|
<TextInput
|
|
38
39
|
label={label}
|
|
39
40
|
value={value ? displayFormat[type](value) : ""}
|
|
@@ -43,6 +44,7 @@ export default function DateTime({ name, type, label }) {
|
|
|
43
44
|
</TouchableRipple>
|
|
44
45
|
)}
|
|
45
46
|
/>
|
|
47
|
+
<HelperText name={name} hint={hint} />
|
|
46
48
|
<DateTimePickerModal
|
|
47
49
|
isVisible={show}
|
|
48
50
|
mode={type}
|
|
@@ -50,7 +52,7 @@ export default function DateTime({ name, type, label }) {
|
|
|
50
52
|
onConfirm={onConfirm}
|
|
51
53
|
onCancel={hidePicker}
|
|
52
54
|
/>
|
|
53
|
-
|
|
55
|
+
</View>
|
|
54
56
|
);
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -58,4 +60,5 @@ DateTime.propTypes = {
|
|
|
58
60
|
name: PropTypes.string,
|
|
59
61
|
type: PropTypes.string,
|
|
60
62
|
label: PropTypes.string,
|
|
63
|
+
hint: PropTypes.string,
|
|
61
64
|
};
|
package/src/inputs/File.js
CHANGED
|
@@ -1,3 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { useField } from "formik";
|
|
3
|
+
import { useComponents } from "@wq/react";
|
|
4
|
+
import { View, Text } from "react-native";
|
|
5
|
+
import { Button, List, Menu } from "react-native-paper";
|
|
6
|
+
import * as Application from "expo-application";
|
|
7
|
+
import * as DocumentPicker from "expo-document-picker";
|
|
8
|
+
import * as ImagePicker from "expo-image-picker";
|
|
9
|
+
import { format } from "./date-utils.js";
|
|
10
|
+
import HelperText from "./HelperText.js";
|
|
11
|
+
import PropTypes from "prop-types";
|
|
12
|
+
|
|
13
|
+
export default function File({ name, accept, capture, required, label, hint }) {
|
|
14
|
+
const [, { value }, { setValue }] = useField(name),
|
|
15
|
+
[imageOpen, setImageOpen] = useState(false),
|
|
16
|
+
[menuOpen, setMenuOpen] = useState(false),
|
|
17
|
+
{ Img, Popup } = useComponents(),
|
|
18
|
+
acceptImage = accept && accept.startsWith("image/"),
|
|
19
|
+
showImage = () => setImageOpen(true),
|
|
20
|
+
hideImage = () => setImageOpen(false),
|
|
21
|
+
showMenu = () => setMenuOpen(true),
|
|
22
|
+
hideMenu = () => setMenuOpen(false);
|
|
23
|
+
|
|
24
|
+
async function handleFile(mode) {
|
|
25
|
+
const value = await mode(accept, capture);
|
|
26
|
+
if (value || mode === clear) {
|
|
27
|
+
setValue(value);
|
|
28
|
+
}
|
|
29
|
+
hideMenu();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const modes = capture
|
|
33
|
+
? [takePhoto]
|
|
34
|
+
: acceptImage
|
|
35
|
+
? [takePhoto, pickFile]
|
|
36
|
+
: [pickFile];
|
|
37
|
+
|
|
38
|
+
if (value && !required) {
|
|
39
|
+
modes.push(clear);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<View>
|
|
44
|
+
{label && <List.Subheader>{label}</List.Subheader>}
|
|
45
|
+
<View
|
|
46
|
+
style={{
|
|
47
|
+
flexDirection: "row",
|
|
48
|
+
alignItems: "center",
|
|
49
|
+
padding: 8,
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
{isImage(value) && (
|
|
53
|
+
<Img
|
|
54
|
+
onPress={showImage}
|
|
55
|
+
style={{ width: 64, height: 64 }}
|
|
56
|
+
src={typeof value === "string" ? value : value.uri}
|
|
57
|
+
/>
|
|
58
|
+
)}
|
|
59
|
+
{value && !isImage(value) && <List.Icon icon="attachment" />}
|
|
60
|
+
<Text style={{ flex: 1, padding: 8 }}>
|
|
61
|
+
{value ? value.name : "No file selected"}
|
|
62
|
+
</Text>
|
|
63
|
+
<Menu
|
|
64
|
+
visible={menuOpen}
|
|
65
|
+
onDismiss={hideMenu}
|
|
66
|
+
anchor={
|
|
67
|
+
<Button
|
|
68
|
+
onPress={
|
|
69
|
+
modes.length > 1
|
|
70
|
+
? showMenu
|
|
71
|
+
: () => handleFile(modes[0])
|
|
72
|
+
}
|
|
73
|
+
icon={value ? "pencil" : "plus"}
|
|
74
|
+
mode="contained-tonal"
|
|
75
|
+
>
|
|
76
|
+
{value
|
|
77
|
+
? "Change"
|
|
78
|
+
: capture
|
|
79
|
+
? "Add Photo"
|
|
80
|
+
: acceptImage
|
|
81
|
+
? "Add Image"
|
|
82
|
+
: "Add File"}
|
|
83
|
+
</Button>
|
|
84
|
+
}
|
|
85
|
+
>
|
|
86
|
+
{modes.map((mode) => (
|
|
87
|
+
<Menu.Item
|
|
88
|
+
key={mode.icon}
|
|
89
|
+
onPress={() => handleFile(mode)}
|
|
90
|
+
leadingIcon={mode.icon}
|
|
91
|
+
title={mode.label}
|
|
92
|
+
/>
|
|
93
|
+
))}
|
|
94
|
+
</Menu>
|
|
95
|
+
</View>
|
|
96
|
+
<HelperText name={name} hint={hint} />
|
|
97
|
+
<Popup open={value && imageOpen} onClose={hideImage}>
|
|
98
|
+
<Img
|
|
99
|
+
onPress={hideImage}
|
|
100
|
+
resizeMode="contain"
|
|
101
|
+
style={{
|
|
102
|
+
width: "90%",
|
|
103
|
+
height: "90%",
|
|
104
|
+
margin: "5%",
|
|
105
|
+
}}
|
|
106
|
+
src={typeof value === "string" ? value : value && value.uri}
|
|
107
|
+
/>
|
|
108
|
+
</Popup>
|
|
109
|
+
</View>
|
|
110
|
+
);
|
|
3
111
|
}
|
|
112
|
+
File.propTypes = {
|
|
113
|
+
name: PropTypes.string,
|
|
114
|
+
accept: PropTypes.string,
|
|
115
|
+
capture: PropTypes.string,
|
|
116
|
+
required: PropTypes.bool,
|
|
117
|
+
label: PropTypes.string,
|
|
118
|
+
hint: PropTypes.string,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
function isImage(value) {
|
|
122
|
+
if (typeof value === "string") {
|
|
123
|
+
return IMAGE_EXTENSIONS.some((ext) =>
|
|
124
|
+
value.toLowerCase().endsWith(ext)
|
|
125
|
+
);
|
|
126
|
+
} else {
|
|
127
|
+
return (
|
|
128
|
+
value && value.type && value.type.startsWith("image/") && value.uri
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function generateName() {
|
|
134
|
+
const appName = Application.applicationName.replace(/ /, ""),
|
|
135
|
+
timestamp = new Date(),
|
|
136
|
+
date = format.date(timestamp).replace(/-/g, ""),
|
|
137
|
+
time = format.time(timestamp).replace(/:/g, "");
|
|
138
|
+
return `${appName}_${date}_${time}.jpg`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function pickFile(accept) {
|
|
142
|
+
const result = await DocumentPicker.getDocumentAsync({ type: accept });
|
|
143
|
+
if (result.assets && result.assets.length > 0) {
|
|
144
|
+
const { name, mimeType: type, uri } = result.assets[0];
|
|
145
|
+
return { name, type, uri };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
pickFile.icon = "folder";
|
|
149
|
+
pickFile.label = "Pick File";
|
|
150
|
+
|
|
151
|
+
async function takePhoto(accept, capture) {
|
|
152
|
+
const options = {};
|
|
153
|
+
if (capture) {
|
|
154
|
+
options.cameraType =
|
|
155
|
+
capture === "user"
|
|
156
|
+
? ImagePicker.CameraType.front
|
|
157
|
+
: ImagePicker.CameraType.back;
|
|
158
|
+
}
|
|
159
|
+
const result = await ImagePicker.launchCameraAsync(options);
|
|
160
|
+
if (result.assets && result.assets.length > 0) {
|
|
161
|
+
const name = generateName(),
|
|
162
|
+
type = "image/jpeg",
|
|
163
|
+
{ uri } = result.assets[0];
|
|
164
|
+
return { name, type, uri };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
takePhoto.icon = "camera";
|
|
168
|
+
takePhoto.label = "Take Photo";
|
|
169
|
+
|
|
170
|
+
function clear() {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
clear.icon = "delete";
|
|
174
|
+
clear.label = "Remove";
|
|
175
|
+
|
|
176
|
+
const IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif"];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { List } from "react-native-paper";
|
|
3
|
+
import FieldsetArray from "./FieldsetArray.js";
|
|
4
|
+
|
|
5
|
+
export default function FileArray(props) {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
{props.label && <List.Subheader>{props.label}</List.Subheader>}
|
|
9
|
+
<FieldsetArray {...props} />
|
|
10
|
+
</>
|
|
11
|
+
);
|
|
12
|
+
}
|
package/src/inputs/HelperText.js
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useFormikContext, getIn } from "formik";
|
|
3
|
+
import { HelperText as FormHelperText } from "react-native-paper";
|
|
4
|
+
import PropTypes from "prop-types";
|
|
2
5
|
|
|
3
|
-
export default HelperText
|
|
6
|
+
export default function HelperText({ name, hint }) {
|
|
7
|
+
const { errors, touched } = useFormikContext(),
|
|
8
|
+
error = getIn(errors, name),
|
|
9
|
+
showError = !!error && !!getIn(touched, name);
|
|
10
|
+
|
|
11
|
+
if (showError) {
|
|
12
|
+
hint = error;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!hint) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<FormHelperText type={showError ? "error" : "info"}>
|
|
21
|
+
{hint}
|
|
22
|
+
</FormHelperText>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
HelperText.propTypes = {
|
|
27
|
+
name: PropTypes.string,
|
|
28
|
+
hint: PropTypes.string,
|
|
29
|
+
};
|
package/src/inputs/Hidden.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Field
|
|
3
|
-
import
|
|
2
|
+
import { Field } from "formik";
|
|
3
|
+
import HelperText from "./HelperText.js";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
|
|
6
6
|
function Empty() {
|
|
@@ -8,15 +8,16 @@ function Empty() {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export default function Hidden(props) {
|
|
11
|
-
const { name } = props;
|
|
11
|
+
const { name, hint } = props;
|
|
12
12
|
return (
|
|
13
13
|
<>
|
|
14
14
|
<Field {...props} component={Empty} />
|
|
15
|
-
<
|
|
15
|
+
<HelperText name={name} hint={hint} />
|
|
16
16
|
</>
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
Hidden.propTypes = {
|
|
21
21
|
name: PropTypes.string,
|
|
22
|
+
hint: PropTypes.string,
|
|
22
23
|
};
|
package/src/inputs/Image.js
CHANGED
package/src/inputs/Input.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
2
3
|
import { TextInput } from "react-native-paper";
|
|
3
4
|
import { useField } from "formik";
|
|
4
5
|
import { useHtmlInput } from "@wq/react";
|
|
6
|
+
import HelperText from "./HelperText.js";
|
|
5
7
|
import PropTypes from "prop-types";
|
|
6
8
|
|
|
7
9
|
const keyboards = {
|
|
@@ -12,7 +14,7 @@ const keyboards = {
|
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export default function Input(props) {
|
|
15
|
-
const { name, type, label, style, min, max } = props,
|
|
17
|
+
const { name, type, label, hint, style, min, max } = props,
|
|
16
18
|
{ maxLength } = useHtmlInput(props),
|
|
17
19
|
[, meta, helpers] = useField(name),
|
|
18
20
|
{ value } = meta,
|
|
@@ -49,16 +51,19 @@ export default function Input(props) {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
return (
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
<View style={{ flex: (style || {}).flex }}>
|
|
55
|
+
<TextInput
|
|
56
|
+
label={label}
|
|
57
|
+
multiline={type === "text"}
|
|
58
|
+
keyboardType={keyboards[type] || "default"}
|
|
59
|
+
maxLength={maxLength}
|
|
60
|
+
onChangeText={handleChange}
|
|
61
|
+
onBlur={() => setTouched(true)}
|
|
62
|
+
value={formatValue}
|
|
63
|
+
style={style}
|
|
64
|
+
/>
|
|
65
|
+
<HelperText name={name} hint={hint} />
|
|
66
|
+
</View>
|
|
62
67
|
);
|
|
63
68
|
}
|
|
64
69
|
|
|
@@ -66,6 +71,7 @@ Input.propTypes = {
|
|
|
66
71
|
name: PropTypes.string,
|
|
67
72
|
type: PropTypes.string,
|
|
68
73
|
label: PropTypes.string,
|
|
74
|
+
hint: PropTypes.string,
|
|
69
75
|
style: PropTypes.object,
|
|
70
76
|
min: PropTypes.number,
|
|
71
77
|
max: PropTypes.number,
|
package/src/inputs/Radio.js
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { RadioButton, List } from "react-native-paper";
|
|
4
|
+
import HelperText from "./HelperText.js";
|
|
5
|
+
import { useField } from "formik";
|
|
6
|
+
import PropTypes from "prop-types";
|
|
7
|
+
|
|
8
|
+
export default function Radio({ name, choices, label, hint }) {
|
|
9
|
+
const [, { value }, { setValue }] = useField(name);
|
|
10
|
+
return (
|
|
11
|
+
<View>
|
|
12
|
+
<List.Subheader>{label}</List.Subheader>
|
|
13
|
+
<RadioButton.Group onValueChange={setValue} value={value}>
|
|
14
|
+
{choices.map((choice) => (
|
|
15
|
+
<RadioButton.Item
|
|
16
|
+
key={choice.name}
|
|
17
|
+
value={choice.name}
|
|
18
|
+
label={choice.label}
|
|
19
|
+
/>
|
|
20
|
+
))}
|
|
21
|
+
</RadioButton.Group>
|
|
22
|
+
<HelperText name={name} hint={hint} />
|
|
23
|
+
</View>
|
|
24
|
+
);
|
|
3
25
|
}
|
|
26
|
+
|
|
27
|
+
Radio.propTypes = {
|
|
28
|
+
name: PropTypes.string,
|
|
29
|
+
label: PropTypes.string,
|
|
30
|
+
hint: PropTypes.string,
|
|
31
|
+
choices: PropTypes.arrayOf(PropTypes.object),
|
|
32
|
+
};
|
package/src/inputs/Select.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import RNPickerSelect from "react-native-picker-select";
|
|
3
|
+
import { View } from "react-native";
|
|
3
4
|
import { TextInput, useTheme } from "react-native-paper";
|
|
4
5
|
import { useField } from "formik";
|
|
6
|
+
import HelperText from "./HelperText.js";
|
|
5
7
|
import PropTypes from "prop-types";
|
|
6
8
|
|
|
7
|
-
export default function Select({ name, choices, label }) {
|
|
9
|
+
export default function Select({ name, choices, label, hint }) {
|
|
8
10
|
const theme = useTheme(),
|
|
9
11
|
[, meta, helpers] = useField(name),
|
|
10
12
|
{ value } = meta,
|
|
@@ -27,26 +29,30 @@ export default function Select({ name, choices, label }) {
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
return (
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
<View>
|
|
33
|
+
<TextInput
|
|
34
|
+
label={label}
|
|
35
|
+
value={"-"}
|
|
36
|
+
render={() => (
|
|
37
|
+
<RNPickerSelect
|
|
38
|
+
value={value}
|
|
39
|
+
onValueChange={setValue}
|
|
40
|
+
items={choices.map(({ name, label }) => ({
|
|
41
|
+
value: name,
|
|
42
|
+
label,
|
|
43
|
+
}))}
|
|
44
|
+
style={styles}
|
|
45
|
+
/>
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
<HelperText name={name} hint={hint} />
|
|
49
|
+
</View>
|
|
45
50
|
);
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
Select.propTypes = {
|
|
49
54
|
name: PropTypes.string,
|
|
50
55
|
label: PropTypes.string,
|
|
56
|
+
hint: PropTypes.string,
|
|
51
57
|
choices: PropTypes.arrayOf(PropTypes.object),
|
|
52
58
|
};
|
package/src/inputs/Toggle.js
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View, Text } from "react-native";
|
|
3
|
+
import { ToggleButton, List } from "react-native-paper";
|
|
4
|
+
import HelperText from "./HelperText.js";
|
|
5
|
+
import { useField } from "formik";
|
|
6
|
+
import PropTypes from "prop-types";
|
|
7
|
+
|
|
8
|
+
export default function Toggle({ name, choices, label, hint, style }) {
|
|
9
|
+
const [, { value }, { setValue }] = useField(name);
|
|
10
|
+
return (
|
|
11
|
+
<View>
|
|
12
|
+
<List.Subheader>{label}</List.Subheader>
|
|
13
|
+
<ToggleButton.Row
|
|
14
|
+
onValueChange={setValue}
|
|
15
|
+
value={value}
|
|
16
|
+
style={{ paddingLeft: 16, paddingBottom: 8, ...style }}
|
|
17
|
+
>
|
|
18
|
+
{choices.map((choice) => (
|
|
19
|
+
<ToggleButton
|
|
20
|
+
key={choice.name}
|
|
21
|
+
value={choice.name}
|
|
22
|
+
icon={() => <Text>{choice.label}</Text>}
|
|
23
|
+
style={{ width: undefined, padding: 8 }}
|
|
24
|
+
/>
|
|
25
|
+
))}
|
|
26
|
+
</ToggleButton.Row>
|
|
27
|
+
<HelperText name={name} hint={hint} />
|
|
28
|
+
</View>
|
|
29
|
+
);
|
|
3
30
|
}
|
|
31
|
+
|
|
32
|
+
Toggle.propTypes = {
|
|
33
|
+
name: PropTypes.string,
|
|
34
|
+
label: PropTypes.string,
|
|
35
|
+
hint: PropTypes.string,
|
|
36
|
+
choices: PropTypes.arrayOf(PropTypes.object),
|
|
37
|
+
style: PropTypes.object,
|
|
38
|
+
};
|