@wq/material-native 2.0.0-alpha.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.
Files changed (73) hide show
  1. package/README.md +29 -0
  2. package/babel.config.cjs +10 -0
  3. package/jest.config.js +9 -0
  4. package/package.json +58 -0
  5. package/setup-jest.js +5 -0
  6. package/src/App.js +48 -0
  7. package/src/components/Breadcrumbs.js +3 -0
  8. package/src/components/Button.js +46 -0
  9. package/src/components/ButtonLink.js +14 -0
  10. package/src/components/CancelButton.js +3 -0
  11. package/src/components/CheckboxButton.js +3 -0
  12. package/src/components/Chip.js +67 -0
  13. package/src/components/Container.js +3 -0
  14. package/src/components/DeleteForm.js +64 -0
  15. package/src/components/Divider.js +3 -0
  16. package/src/components/ExpandableListItem.js +46 -0
  17. package/src/components/ExpansionPanel.js +22 -0
  18. package/src/components/Fab.js +29 -0
  19. package/src/components/Fieldset.js +3 -0
  20. package/src/components/FieldsetArray.js +21 -0
  21. package/src/components/FileArray.js +3 -0
  22. package/src/components/FlatFieldset.js +3 -0
  23. package/src/components/Footer.js +3 -0
  24. package/src/components/FooterContent.js +3 -0
  25. package/src/components/FormError.js +15 -0
  26. package/src/components/FormRoot.js +3 -0
  27. package/src/components/FormatJson.js +15 -0
  28. package/src/components/Header.js +22 -0
  29. package/src/components/HomeLink.js +3 -0
  30. package/src/components/HorizontalView.js +22 -0
  31. package/src/components/IconButton.js +32 -0
  32. package/src/components/IconSubmitButton.js +12 -0
  33. package/src/components/Link.js +15 -0
  34. package/src/components/List.js +3 -0
  35. package/src/components/ListItem.js +22 -0
  36. package/src/components/ListItemLink.js +13 -0
  37. package/src/components/ListSubheader.js +3 -0
  38. package/src/components/Main.js +3 -0
  39. package/src/components/Pagination.js +3 -0
  40. package/src/components/Popup.js +3 -0
  41. package/src/components/RadioButton.js +3 -0
  42. package/src/components/ScrollView.js +22 -0
  43. package/src/components/SidePanel.js +3 -0
  44. package/src/components/Spinner.js +16 -0
  45. package/src/components/SubmitButton.js +17 -0
  46. package/src/components/Switch.js +3 -0
  47. package/src/components/Table.js +3 -0
  48. package/src/components/TableBody.js +3 -0
  49. package/src/components/TableCell.js +3 -0
  50. package/src/components/TableContainer.js +2 -0
  51. package/src/components/TableHead.js +3 -0
  52. package/src/components/TablePagination.js +3 -0
  53. package/src/components/TableRow.js +3 -0
  54. package/src/components/TableTitle.js +3 -0
  55. package/src/components/Text.js +3 -0
  56. package/src/components/Typography.js +39 -0
  57. package/src/components/View.js +3 -0
  58. package/src/components/index.js +119 -0
  59. package/src/hooks.js +6 -0
  60. package/src/icons.js +9 -0
  61. package/src/index.js +45 -0
  62. package/src/inputs/Checkbox.js +38 -0
  63. package/src/inputs/DateTime.js +61 -0
  64. package/src/inputs/File.js +3 -0
  65. package/src/inputs/HelperText.js +3 -0
  66. package/src/inputs/Hidden.js +22 -0
  67. package/src/inputs/Image.js +3 -0
  68. package/src/inputs/Input.js +72 -0
  69. package/src/inputs/Radio.js +3 -0
  70. package/src/inputs/Select.js +52 -0
  71. package/src/inputs/Toggle.js +3 -0
  72. package/src/inputs/date-utils.js +21 -0
  73. package/src/inputs/index.js +30 -0
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ [![@wq/material][logo]][docs]
2
+
3
+ **@wq/material-native** provides [React Native] and [Expo] bindings for [@wq/material], via the [React Native Paper] library.
4
+
5
+ ### [Documentation][docs]
6
+
7
+ [**Installation**][installation]
8
+ •
9
+ [**API**][api]
10
+ •
11
+ [**Components**][components]
12
+ •
13
+ [Icons][icons]
14
+ •
15
+ [Inputs][inputs]
16
+
17
+ [logo]: https://wq.io/images/@wq/material.svg
18
+ [docs]: https://wq.io/@wq/material
19
+ [installation]: https://wq.io/@wq/material#installation
20
+ [api]: https://wq.io/@wq/material#api
21
+ [components]: https://wq.io/components/
22
+ [icons]: https://wq.io/icons
23
+ [inputs]: https://wq.io/inputs/
24
+
25
+ [@wq/material]: https://wq.io/@wq/material
26
+ [React]: https://reactjs.org/
27
+ [React Native]: https://reactnative.dev/
28
+ [Expo]: https://expo.io/
29
+ [React Native Paper]: https://callstack.github.io/react-native-paper/
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ env: {
3
+ test: {
4
+ plugins: [
5
+ ["@babel/plugin-proposal-private-methods", { loose: true }],
6
+ ],
7
+ presets: ["module:metro-react-native-babel-preset"],
8
+ },
9
+ },
10
+ };
package/jest.config.js ADDED
@@ -0,0 +1,9 @@
1
+ export default {
2
+ preset: "react-native",
3
+ setupFiles: [
4
+ "./node_modules/react-native-gesture-handler/jestSetup.js",
5
+ "./setup-jest.js",
6
+ ],
7
+ testMatch: ["**/__tests__/**/*.js?(x)"],
8
+ transformIgnorePatterns: [],
9
+ };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@wq/material-native",
3
+ "version": "2.0.0-alpha.0",
4
+ "description": "React Native and Expo bindings for @wq/material",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "scripts": {
8
+ "test": "cd ../../ && npm run jest packages/material-native -- --config packages/material-native/jest.config.js --moduleDirectories node_modules/ packages/material-native/node_modules/",
9
+ "build": "npm run prettier",
10
+ "prettier": "cd ../../ && npm run prettier -- --write packages/material-native/",
11
+ "lint": "cd ../../ && npm run eslint packages/material-native/{,src/,src/*/,src/*/*/}*.js"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/wq/wq.app.git",
16
+ "directory": "packages/material-native"
17
+ },
18
+ "keywords": [
19
+ "wq",
20
+ "react",
21
+ "material",
22
+ "material-ui"
23
+ ],
24
+ "author": "S. Andrew Sheppard",
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "https://github.com/wq/wq.app/issues"
28
+ },
29
+ "homepage": "https://wq.io/@wq/material",
30
+ "dependencies": {
31
+ "@wq/react": "^2.0.0-alpha.0",
32
+ "date-fns": "^2.29.3"
33
+ },
34
+ "peerDependencies": {
35
+ "@react-native-async-storage/async-storage": "*",
36
+ "@react-native-community/datetimepicker": "*",
37
+ "@react-native-community/masked-view": "*",
38
+ "@react-native-community/netinfo": "*",
39
+ "@react-navigation/native": "*",
40
+ "@react-navigation/stack": "*",
41
+ "react-native-modal-datetime-picker": "*",
42
+ "react-native-paper": "*",
43
+ "react-native-picker-select": "*"
44
+ },
45
+ "devDependencies": {
46
+ "@react-native-async-storage/async-storage": "^1.17.11",
47
+ "@react-native-community/datetimepicker": "^6.7.1",
48
+ "@react-native-community/masked-view": "^0.1.11",
49
+ "@react-native-community/netinfo": "^9.3.7",
50
+ "@react-navigation/native": "^6.1.2",
51
+ "@react-navigation/stack": "^6.3.11",
52
+ "@wq/model": "^2.0.0-alpha.0",
53
+ "@wq/store": "^2.0.0-alpha.0",
54
+ "react-native-modal-datetime-picker": "^14.0.1",
55
+ "react-native-paper": "^5.1.3",
56
+ "react-native-picker-select": "^8.0.4"
57
+ }
58
+ }
package/setup-jest.js ADDED
@@ -0,0 +1,5 @@
1
+ import { NativeModules } from "react-native";
2
+
3
+ if (!NativeModules.PlatformLocalStorage) {
4
+ NativeModules.PlatformLocalStorage = {};
5
+ }
package/src/App.js ADDED
@@ -0,0 +1,48 @@
1
+ import React, { useMemo } from "react";
2
+ import { App as DefaultApp, usePlugin } from "@wq/react";
3
+ import {
4
+ DefaultTheme,
5
+ DarkTheme,
6
+ Provider as PaperProvider,
7
+ } from "react-native-paper";
8
+
9
+ export default function App() {
10
+ const { theme: configTheme } = usePlugin("material").config,
11
+ theme = useMemo(() => createTheme(configTheme), [configTheme]),
12
+ options = useMemo(
13
+ () => ({
14
+ navigator: { theme },
15
+ screen: {
16
+ cardStyle: { backgroundColor: theme.colors.background },
17
+ },
18
+ }),
19
+ [theme]
20
+ );
21
+
22
+ return (
23
+ <PaperProvider theme={theme}>
24
+ <DefaultApp options={options} />
25
+ </PaperProvider>
26
+ );
27
+ }
28
+
29
+ function createTheme({ type, primary, secondary, background }) {
30
+ const colors = {},
31
+ base = type === "dark" ? DarkTheme : DefaultTheme;
32
+ if (primary) {
33
+ colors.primary = primary;
34
+ }
35
+ if (secondary) {
36
+ colors.accent = secondary;
37
+ }
38
+ if (background) {
39
+ colors.background = background;
40
+ }
41
+ return {
42
+ ...base,
43
+ colors: {
44
+ ...base.colors,
45
+ ...colors,
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,3 @@
1
+ export default function NotImplemented() {
2
+ return null; // FIXME
3
+ }
@@ -0,0 +1,46 @@
1
+ import React from "react";
2
+ import { useIcon } from "@wq/react";
3
+ import { Button as PaperButton, useTheme } from "react-native-paper";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function Button({
7
+ onClick,
8
+ onPress,
9
+ variant,
10
+ mode,
11
+ icon,
12
+ color,
13
+ ...rest
14
+ }) {
15
+ const Icon = useIcon(icon),
16
+ theme = useTheme();
17
+ if (!onPress) {
18
+ onPress = onClick;
19
+ }
20
+ if (!mode) {
21
+ mode = variant;
22
+ }
23
+ if (color === "primary") {
24
+ color = theme.colors.primary;
25
+ } else if (color === "secondary") {
26
+ color = theme.colors.accent;
27
+ }
28
+ return (
29
+ <PaperButton
30
+ onPress={onPress}
31
+ mode={mode}
32
+ icon={Icon}
33
+ color={color}
34
+ {...rest}
35
+ />
36
+ );
37
+ }
38
+
39
+ Button.propTypes = {
40
+ onClick: PropTypes.func,
41
+ onPress: PropTypes.func,
42
+ variant: PropTypes.string,
43
+ mode: PropTypes.string,
44
+ icon: PropTypes.string,
45
+ color: PropTypes.string,
46
+ };
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import { Button } from "react-native-paper";
3
+ import { useNav } from "@wq/react";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function ButtonLink({ to, children }) {
7
+ const onPress = useNav(to);
8
+ return <Button onPress={onPress}>{children}</Button>;
9
+ }
10
+
11
+ ButtonLink.propTypes = {
12
+ to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
13
+ children: PropTypes.node,
14
+ };
@@ -0,0 +1,3 @@
1
+ import ButtonLink from "./ButtonLink.js";
2
+
3
+ export default ButtonLink;
@@ -0,0 +1,3 @@
1
+ export default function NotImplemented() {
2
+ return null; // FIXME
3
+ }
@@ -0,0 +1,67 @@
1
+ import React from "react";
2
+ import { useIcon } from "@wq/react";
3
+ import { Chip as PaperChip, useTheme } from "react-native-paper";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function Chip({
7
+ label,
8
+ icon,
9
+ color,
10
+ onClick,
11
+ onPress,
12
+ onDelete,
13
+ onClose,
14
+ ...rest
15
+ }) {
16
+ const theme = useTheme(),
17
+ Icon = useIcon(icon);
18
+
19
+ if (color === "primary") {
20
+ color = theme.colors.primary;
21
+ } else if (color === "secondary") {
22
+ color = theme.colors.accent;
23
+ }
24
+
25
+ let style, chipTheme;
26
+ if (color) {
27
+ style = {
28
+ backgroundColor: color,
29
+ };
30
+ chipTheme = {
31
+ colors: {
32
+ text: "#ffffff",
33
+ },
34
+ };
35
+ }
36
+
37
+ if (!onPress) {
38
+ onPress = onClick;
39
+ }
40
+
41
+ if (!onClose) {
42
+ onClose = onDelete;
43
+ }
44
+
45
+ return (
46
+ <PaperChip
47
+ icon={Icon}
48
+ style={style}
49
+ theme={chipTheme}
50
+ onPress={onPress}
51
+ onClose={onClose}
52
+ {...rest}
53
+ >
54
+ {label}
55
+ </PaperChip>
56
+ );
57
+ }
58
+
59
+ Chip.propTypes = {
60
+ label: PropTypes.node,
61
+ icon: PropTypes.string,
62
+ color: PropTypes.string,
63
+ onClick: PropTypes.func,
64
+ onPress: PropTypes.func,
65
+ onDelete: PropTypes.func,
66
+ onClose: PropTypes.func,
67
+ };
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,64 @@
1
+ import React from "react";
2
+ import Alert from "react-native";
3
+ import { useComponents, useMessages } from "@wq/react";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function DeleteForm({ action }) {
7
+ const { Form, SubmitButton, View, HorizontalView } = useComponents(),
8
+ {
9
+ CONFIRM_DELETE,
10
+ CONFIRM_DELETE_TITLE,
11
+ CONFIRM_DELETE_OK,
12
+ CONFIRM_DELETE_CANCEL,
13
+ } = useMessages();
14
+
15
+ async function confirmSubmit() {
16
+ return new Promise((resolve) => {
17
+ Alert.alert(
18
+ CONFIRM_DELETE_TITLE,
19
+ CONFIRM_DELETE,
20
+ [
21
+ {
22
+ text: CONFIRM_DELETE_CANCEL,
23
+ onPress() {
24
+ resolve(false);
25
+ },
26
+ style: "cancel",
27
+ },
28
+ {
29
+ text: CONFIRM_DELETE_OK,
30
+ onPress() {
31
+ resolve(true);
32
+ },
33
+ style: "destructive",
34
+ },
35
+ ],
36
+ {
37
+ onDismiss() {
38
+ resolve(false);
39
+ },
40
+ }
41
+ );
42
+ });
43
+ }
44
+
45
+ return (
46
+ <Form
47
+ action={action}
48
+ method="DELETE"
49
+ backgroundSync={false}
50
+ onSubmit={confirmSubmit}
51
+ >
52
+ <HorizontalView>
53
+ <View />
54
+ <SubmitButton icon="delete" variant="text" color="secondary">
55
+ Delete
56
+ </SubmitButton>
57
+ </HorizontalView>
58
+ </Form>
59
+ );
60
+ }
61
+
62
+ DeleteForm.propTypes = {
63
+ action: PropTypes.string,
64
+ };
@@ -0,0 +1,3 @@
1
+ import { Divider } from "react-native-paper";
2
+
3
+ export default Divider;
@@ -0,0 +1,46 @@
1
+ import React, { useState } from "react";
2
+ import { useIcon } from "@wq/react";
3
+ import { List } from "react-native-paper";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function ExpandableListItem({
7
+ children,
8
+ description,
9
+ icon,
10
+ open,
11
+ onToggle,
12
+ ...rest
13
+ }) {
14
+ const Icon = useIcon(icon),
15
+ [summary, ...details] = React.Children.toArray(children),
16
+ [internalOpen, setOpen] = useState(false);
17
+
18
+ let toggleOpen;
19
+ if (open === false || open || onToggle) {
20
+ toggleOpen = () => onToggle(!open);
21
+ } else {
22
+ open = internalOpen;
23
+ toggleOpen = () => setOpen(!open);
24
+ }
25
+
26
+ return (
27
+ <List.Accordion
28
+ title={summary}
29
+ description={description}
30
+ left={Icon ? (props) => <List.Icon icon={Icon} {...props} /> : null}
31
+ expanded={open}
32
+ onPress={toggleOpen}
33
+ {...rest}
34
+ >
35
+ {details}
36
+ </List.Accordion>
37
+ );
38
+ }
39
+
40
+ ExpandableListItem.propTypes = {
41
+ children: PropTypes.node,
42
+ description: PropTypes.node,
43
+ icon: PropTypes.string,
44
+ open: PropTypes.bool,
45
+ onToggle: PropTypes.func,
46
+ };
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { List } from "react-native-paper";
3
+ import PropTypes from "prop-types";
4
+
5
+ export default function ExpansionPanel({ summary, children, open, onToggle }) {
6
+ let handleToggle;
7
+ if (onToggle) {
8
+ handleToggle = () => onToggle(!open);
9
+ }
10
+ return (
11
+ <List.Accordion title={summary} expanded={open} onPress={handleToggle}>
12
+ {children}
13
+ </List.Accordion>
14
+ );
15
+ }
16
+
17
+ ExpansionPanel.propTypes = {
18
+ summary: PropTypes.node,
19
+ children: PropTypes.node,
20
+ open: PropTypes.bool,
21
+ onToggle: PropTypes.func,
22
+ };
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import { FAB } from "react-native-paper";
3
+ import { useNav, useIcon } from "@wq/react";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function Fab({ icon, to, ...rest }) {
7
+ const onPress = useNav(to),
8
+ Icon = useIcon(icon);
9
+
10
+ return (
11
+ <FAB
12
+ onPress={onPress}
13
+ icon={Icon}
14
+ color="white"
15
+ style={{
16
+ position: "absolute",
17
+ margin: 16,
18
+ right: 0,
19
+ bottom: 0,
20
+ }}
21
+ {...rest}
22
+ />
23
+ );
24
+ }
25
+
26
+ Fab.propTypes = {
27
+ icon: PropTypes.string,
28
+ to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
29
+ };
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { useComponents } from "@wq/react";
3
+ import PropTypes from "prop-types";
4
+
5
+ export default function FieldsetArray({ label, children, addRow }) {
6
+ const { View, Button } = useComponents();
7
+ return (
8
+ <View>
9
+ {children}
10
+ {addRow && (
11
+ <Button onClick={() => addRow()}>{`Add ${label}`}</Button>
12
+ )}
13
+ </View>
14
+ );
15
+ }
16
+
17
+ FieldsetArray.propTypes = {
18
+ label: PropTypes.string,
19
+ children: PropTypes.node,
20
+ addRow: PropTypes.func,
21
+ };
@@ -0,0 +1,3 @@
1
+ export default function NotImplemented() {
2
+ return null; // FIXME
3
+ }
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { useField } from "formik";
3
+ import { HelperText } from "react-native-paper";
4
+
5
+ export default function FormError(props) {
6
+ const [, { error }] = useField("__other__");
7
+ if (!error) {
8
+ return null;
9
+ }
10
+ return (
11
+ <HelperText type="error" {...props}>
12
+ {error}
13
+ </HelperText>
14
+ );
15
+ }
@@ -0,0 +1,3 @@
1
+ import { Fragment } from "react";
2
+
3
+ export default Fragment;
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { Text, ScrollView } from "react-native";
3
+ import PropTypes from "prop-types";
4
+
5
+ export default function FormatJson({ json }) {
6
+ return (
7
+ <ScrollView style={{ height: 128 }}>
8
+ <Text>{JSON.stringify(json, null, 4)}</Text>
9
+ </ScrollView>
10
+ );
11
+ }
12
+
13
+ FormatJson.propTypes = {
14
+ json: PropTypes.object,
15
+ };
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { Appbar } from "react-native-paper";
3
+ import { useBreadcrumbs, useNav } from "@wq/react";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function Header({ options, route }) {
7
+ const title = options.title || route.name,
8
+ breadcrumbs = useBreadcrumbs() || [],
9
+ previous = breadcrumbs[breadcrumbs.length - 2],
10
+ nav = useNav(previous?.url);
11
+ return (
12
+ <Appbar.Header>
13
+ {previous && <Appbar.BackAction onPress={nav} />}
14
+ <Appbar.Content title={title} />
15
+ </Appbar.Header>
16
+ );
17
+ }
18
+
19
+ Header.propTypes = {
20
+ options: PropTypes.object,
21
+ route: PropTypes.object,
22
+ };
@@ -0,0 +1,3 @@
1
+ export default function NotImplemented() {
2
+ return null; // FIXME
3
+ }
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import PropTypes from "prop-types";
4
+
5
+ export default function HorizontalView({ style, ...rest }) {
6
+ return (
7
+ <View
8
+ style={{
9
+ flexDirection: "row",
10
+ justifyContent: "space-between",
11
+ alignItems: "center",
12
+ padding: 8,
13
+ ...style,
14
+ }}
15
+ {...rest}
16
+ />
17
+ );
18
+ }
19
+
20
+ HorizontalView.propTypes = {
21
+ style: PropTypes.object,
22
+ };
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import { useIcon } from "@wq/react";
3
+ import { IconButton as PaperIconButton, useTheme } from "react-native-paper";
4
+ import PropTypes from "prop-types";
5
+
6
+ export default function IconButton({ icon, onClick, onPress, color, ...rest }) {
7
+ const Icon = useIcon(icon),
8
+ theme = useTheme();
9
+ if (!onPress) {
10
+ onPress = onClick;
11
+ }
12
+ if (color === "primary") {
13
+ color = theme.colors.primary;
14
+ } else if (color === "secondary") {
15
+ color = theme.colors.accent;
16
+ }
17
+ return (
18
+ <PaperIconButton
19
+ icon={Icon}
20
+ onPress={onPress}
21
+ color={color}
22
+ {...rest}
23
+ />
24
+ );
25
+ }
26
+
27
+ IconButton.propTypes = {
28
+ icon: PropTypes.string,
29
+ onClick: PropTypes.func,
30
+ onPress: PropTypes.func,
31
+ color: PropTypes.string,
32
+ };
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { useComponents } from "@wq/react";
3
+ import { useFormikContext } from "formik";
4
+
5
+ export default function IconSubmitButton(props) {
6
+ const { IconButton } = useComponents(),
7
+ { isSubmitting, submitForm } = useFormikContext();
8
+
9
+ return (
10
+ <IconButton disabled={isSubmitting} onPress={submitForm} {...props} />
11
+ );
12
+ }