@jobber/components-native 0.44.2 → 0.45.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/package.json +88 -0
- package/dist/src/AtlantisContext/AtlantisContext.js +1 -0
- package/dist/src/BottomSheet/BottomSheet.js +3 -4
- package/dist/src/ButtonGroup/ButtonGroup.js +3 -4
- package/dist/src/ButtonGroup/utils.js +4 -5
- package/dist/src/ContentOverlay/ContentOverlay.js +3 -4
- package/dist/src/Form/components/FormErrorBanner/FormErrorBanner.js +5 -13
- package/dist/src/Form/components/FormMask/FormMask.js +3 -4
- package/dist/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.js +4 -5
- package/dist/src/Form/components/FormSaveButton/FormSaveButton.js +4 -5
- package/dist/src/Form/hooks/useOfflineHandler.js +6 -7
- package/dist/src/FormatFile/FormatFile.js +3 -4
- package/dist/src/FormatFile/components/FileView/FileView.js +3 -3
- package/dist/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.js +6 -7
- package/dist/src/FormatFile/components/MediaView/MediaView.js +3 -3
- package/dist/src/FormatFile/utils/computeA11yLabel.js +4 -5
- package/dist/src/InputCurrency/InputCurrency.js +3 -3
- package/dist/src/InputDate/InputDate.js +4 -5
- package/dist/src/InputFieldWrapper/components/ClearAction/ClearAction.js +3 -4
- package/dist/src/InputFieldWrapper/components/ClearAction/index.js +0 -1
- package/dist/src/InputNumber/InputNumber.js +3 -4
- package/dist/src/InputPassword/InputPassword.js +3 -4
- package/dist/src/InputTime/InputTime.js +3 -4
- package/dist/src/Menu/Menu.js +3 -4
- package/dist/src/ProgressBar/ProgressBar.js +14 -8
- package/dist/src/Select/Select.js +5 -6
- package/dist/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.js +3 -4
- package/dist/src/Toast/Toast.js +4 -5
- package/dist/src/hooks/useAtlantisI18n/index.js +1 -0
- package/dist/src/hooks/useAtlantisI18n/locales/en.json +31 -0
- package/dist/src/hooks/useAtlantisI18n/locales/es.json +31 -0
- package/dist/src/hooks/useAtlantisI18n/useAtlantisI18n.js +22 -0
- package/dist/tsconfig.json +38 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/src/AtlantisContext/AtlantisContext.d.ts +8 -0
- package/dist/types/src/FormatFile/utils/computeA11yLabel.d.ts +6 -6
- package/dist/types/src/InputFieldWrapper/components/ClearAction/index.d.ts +0 -1
- package/dist/types/src/hooks/useAtlantisI18n/index.d.ts +1 -0
- package/dist/types/src/hooks/useAtlantisI18n/useAtlantisI18n.d.ts +6 -0
- package/package.json +2 -2
- package/src/AtlantisContext/AtlantisContext.tsx +10 -0
- package/src/BottomSheet/BottomSheet.test.tsx +3 -4
- package/src/BottomSheet/BottomSheet.tsx +3 -4
- package/src/ButtonGroup/ButtonGroup.test.tsx +8 -9
- package/src/ButtonGroup/ButtonGroup.tsx +3 -4
- package/src/ButtonGroup/utils.ts +5 -6
- package/src/ContentOverlay/ContentOverlay.test.tsx +1 -11
- package/src/ContentOverlay/ContentOverlay.tsx +5 -9
- package/src/Form/Form.test.tsx +9 -40
- package/src/Form/components/FormErrorBanner/FormErrorBanner.test.tsx +9 -72
- package/src/Form/components/FormErrorBanner/FormErrorBanner.tsx +6 -15
- package/src/Form/components/FormMask/FormMask.tsx +3 -7
- package/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.tsx +4 -5
- package/src/Form/components/FormSaveButton/FormSaveButton.test.tsx +3 -7
- package/src/Form/components/FormSaveButton/FormSaveButton.tsx +4 -5
- package/src/Form/hooks/useOfflineHandler.ts +7 -8
- package/src/FormatFile/FormatFile.test.tsx +7 -31
- package/src/FormatFile/FormatFile.tsx +3 -7
- package/src/FormatFile/components/FileView/FileView.tsx +3 -3
- package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.tsx +2 -9
- package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +6 -7
- package/src/FormatFile/components/MediaView/MediaView.tsx +3 -3
- package/src/FormatFile/utils/computeA11yLabel.ts +9 -12
- package/src/InputCurrency/InputCurrency.test.tsx +6 -1
- package/src/InputCurrency/InputCurrency.tsx +3 -3
- package/src/InputDate/InputDate.tsx +6 -5
- package/src/InputFieldWrapper/InputFieldWrapper.test.tsx +4 -15
- package/src/InputFieldWrapper/components/ClearAction/ClearAction.test.tsx +1 -5
- package/src/InputFieldWrapper/components/ClearAction/ClearAction.tsx +3 -4
- package/src/InputFieldWrapper/components/ClearAction/index.ts +0 -1
- package/src/InputNumber/InputNumber.test.tsx +10 -18
- package/src/InputNumber/InputNumber.tsx +3 -4
- package/src/InputPassword/InputPassword.test.tsx +1 -2
- package/src/InputPassword/InputPassword.tsx +3 -4
- package/src/InputSearch/InputSearch.test.tsx +1 -6
- package/src/InputText/InputText.test.tsx +10 -38
- package/src/InputTime/InputTime.tsx +3 -4
- package/src/Menu/Menu.test.tsx +10 -9
- package/src/Menu/Menu.tsx +3 -4
- package/src/ProgressBar/ProgressBar.tsx +17 -8
- package/src/Select/Select.test.tsx +4 -5
- package/src/Select/Select.tsx +5 -8
- package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.tsx +3 -4
- package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.test.tsx +1 -2
- package/src/Toast/Toast.tsx +4 -9
- package/src/hooks/useAtlantisI18n/index.ts +1 -0
- package/src/hooks/useAtlantisI18n/locales/en.json +31 -0
- package/src/hooks/useAtlantisI18n/locales/es.json +31 -0
- package/src/hooks/useAtlantisI18n/useAtlantisI18n.test.ts +53 -0
- package/src/hooks/useAtlantisI18n/useAtlantisI18n.ts +43 -0
- package/dist/src/BottomSheet/messages.js +0 -8
- package/dist/src/ButtonGroup/messages.js +0 -18
- package/dist/src/ContentOverlay/messages.js +0 -8
- package/dist/src/Form/components/FormErrorBanner/messages.js +0 -13
- package/dist/src/Form/components/FormMessage/components/InternalFormMessage/messages.js +0 -8
- package/dist/src/Form/components/FormSaveButton/messages.js +0 -8
- package/dist/src/Form/messages.js +0 -28
- package/dist/src/FormatFile/components/FormatFileBottomSheet/messages.js +0 -13
- package/dist/src/FormatFile/messages.js +0 -23
- package/dist/src/InputCurrency/messages.js +0 -8
- package/dist/src/InputDate/messages.js +0 -8
- package/dist/src/InputFieldWrapper/components/ClearAction/messages.js +0 -8
- package/dist/src/InputNumber/messages.js +0 -8
- package/dist/src/InputPassword/messages.js +0 -8
- package/dist/src/InputTime/messages.js +0 -8
- package/dist/src/Menu/messages.js +0 -8
- package/dist/src/ProgressBar/messages.js +0 -13
- package/dist/src/Select/components/SelectDefaultPicker/messages.js +0 -8
- package/dist/src/Select/messages.js +0 -13
- package/dist/src/Toast/messages.js +0 -13
- package/dist/types/src/BottomSheet/messages.d.ts +0 -7
- package/dist/types/src/ButtonGroup/messages.d.ts +0 -17
- package/dist/types/src/ContentOverlay/messages.d.ts +0 -7
- package/dist/types/src/Form/components/FormErrorBanner/messages.d.ts +0 -12
- package/dist/types/src/Form/components/FormMessage/components/InternalFormMessage/messages.d.ts +0 -7
- package/dist/types/src/Form/components/FormSaveButton/messages.d.ts +0 -7
- package/dist/types/src/Form/messages.d.ts +0 -27
- package/dist/types/src/FormatFile/components/FormatFileBottomSheet/messages.d.ts +0 -12
- package/dist/types/src/FormatFile/messages.d.ts +0 -22
- package/dist/types/src/InputCurrency/messages.d.ts +0 -7
- package/dist/types/src/InputDate/messages.d.ts +0 -7
- package/dist/types/src/InputFieldWrapper/components/ClearAction/messages.d.ts +0 -7
- package/dist/types/src/InputNumber/messages.d.ts +0 -7
- package/dist/types/src/InputPassword/messages.d.ts +0 -7
- package/dist/types/src/InputTime/messages.d.ts +0 -7
- package/dist/types/src/Menu/messages.d.ts +0 -7
- package/dist/types/src/ProgressBar/messages.d.ts +0 -12
- package/dist/types/src/Select/components/SelectDefaultPicker/messages.d.ts +0 -7
- package/dist/types/src/Select/messages.d.ts +0 -12
- package/dist/types/src/Toast/messages.d.ts +0 -12
- package/src/BottomSheet/messages.ts +0 -9
- package/src/ButtonGroup/messages.ts +0 -19
- package/src/ContentOverlay/messages.ts +0 -9
- package/src/Form/components/FormErrorBanner/messages.ts +0 -14
- package/src/Form/components/FormMessage/components/InternalFormMessage/messages.ts +0 -10
- package/src/Form/components/FormSaveButton/messages.ts +0 -9
- package/src/Form/messages.ts +0 -33
- package/src/FormatFile/components/FormatFileBottomSheet/messages.ts +0 -14
- package/src/FormatFile/messages.ts +0 -24
- package/src/InputCurrency/messages.ts +0 -10
- package/src/InputDate/messages.ts +0 -9
- package/src/InputFieldWrapper/components/ClearAction/messages.ts +0 -9
- package/src/InputNumber/messages.ts +0 -10
- package/src/InputPassword/messages.ts +0 -9
- package/src/InputTime/messages.ts +0 -9
- package/src/Menu/messages.ts +0 -9
- package/src/ProgressBar/messages.ts +0 -14
- package/src/Select/components/SelectDefaultPicker/messages.ts +0 -9
- package/src/Select/messages.ts +0 -14
- package/src/Toast/messages.ts +0 -14
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
3
|
import { styles } from "./FormMask.style";
|
|
5
4
|
import { ActivityIndicator } from "../../../ActivityIndicator";
|
|
6
|
-
import {
|
|
5
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
7
6
|
|
|
8
7
|
export function FormMask(): JSX.Element {
|
|
9
|
-
const {
|
|
8
|
+
const { t } = useAtlantisI18n();
|
|
10
9
|
|
|
11
10
|
return (
|
|
12
|
-
<View
|
|
13
|
-
style={styles.mask}
|
|
14
|
-
accessibilityLabel={formatMessage(messages.loadingA11YLabel)}
|
|
15
|
-
>
|
|
11
|
+
<View style={styles.mask} accessibilityLabel={t("loading")}>
|
|
16
12
|
<ActivityIndicator />
|
|
17
13
|
</View>
|
|
18
14
|
);
|
package/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.tsx
CHANGED
|
@@ -2,10 +2,9 @@ import React, { useMemo } from "react";
|
|
|
2
2
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
3
3
|
import { Modal, StatusBar, View } from "react-native";
|
|
4
4
|
import { ScrollView } from "react-native-gesture-handler";
|
|
5
|
-
import { useIntl } from "react-intl";
|
|
6
5
|
import { styles } from "./InternalFormMessage.style";
|
|
7
|
-
import { messages } from "./messages";
|
|
8
6
|
import { EmptyState, EmptyStateProps } from "../../../../../EmptyState";
|
|
7
|
+
import { useAtlantisI18n } from "../../../../../hooks/useAtlantisI18n";
|
|
9
8
|
|
|
10
9
|
interface FormMessageProps {
|
|
11
10
|
readonly data: EmptyStateProps;
|
|
@@ -16,7 +15,7 @@ export function InternalFormMessage({
|
|
|
16
15
|
data,
|
|
17
16
|
onRequestClose,
|
|
18
17
|
}: FormMessageProps): JSX.Element {
|
|
19
|
-
const {
|
|
18
|
+
const { t } = useAtlantisI18n();
|
|
20
19
|
const emptyStateData: EmptyStateProps = useMemo(() => {
|
|
21
20
|
if (data.secondaryAction) {
|
|
22
21
|
return data;
|
|
@@ -24,12 +23,12 @@ export function InternalFormMessage({
|
|
|
24
23
|
return {
|
|
25
24
|
...data,
|
|
26
25
|
secondaryAction: {
|
|
27
|
-
label:
|
|
26
|
+
label: t("goBack"),
|
|
28
27
|
onPress: onRequestClose,
|
|
29
28
|
},
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
|
-
}, [data,
|
|
31
|
+
}, [data, t, onRequestClose]);
|
|
33
32
|
|
|
34
33
|
return (
|
|
35
34
|
<Modal
|
|
@@ -3,8 +3,6 @@ import { fireEvent, render, waitFor } from "@testing-library/react-native";
|
|
|
3
3
|
import { Host } from "react-native-portalize";
|
|
4
4
|
import { IconNames } from "@jobber/design";
|
|
5
5
|
import { FormSaveButton } from "./FormSaveButton";
|
|
6
|
-
import { messages } from "./messages";
|
|
7
|
-
import { messages as buttonGroupMessage } from "../../../ButtonGroup/messages";
|
|
8
6
|
|
|
9
7
|
interface TestSecondaryActionProp {
|
|
10
8
|
label: string;
|
|
@@ -62,7 +60,7 @@ describe("the form save button is enabled", () => {
|
|
|
62
60
|
|
|
63
61
|
it("renders a save button and calls the onPress handler when pressed", () => {
|
|
64
62
|
const pressHandler = jest.fn();
|
|
65
|
-
const saveButtonText =
|
|
63
|
+
const saveButtonText = "Save";
|
|
66
64
|
const { getByLabelText } = render(
|
|
67
65
|
<ButtonGroupForTest
|
|
68
66
|
primaryAction={pressHandler}
|
|
@@ -121,9 +119,7 @@ describe("when a secondaryActions is passed in", () => {
|
|
|
121
119
|
/>,
|
|
122
120
|
);
|
|
123
121
|
|
|
124
|
-
expect(
|
|
125
|
-
getByLabelText(buttonGroupMessage.more.defaultMessage),
|
|
126
|
-
).toBeDefined();
|
|
122
|
+
expect(getByLabelText("More")).toBeDefined();
|
|
127
123
|
});
|
|
128
124
|
|
|
129
125
|
it("renders a secondaryAction element with and fires the onSubmit and beforeSubmit if available", async () => {
|
|
@@ -148,7 +144,7 @@ describe("when a secondaryActions is passed in", () => {
|
|
|
148
144
|
]}
|
|
149
145
|
/>,
|
|
150
146
|
);
|
|
151
|
-
fireEvent.press(getByLabelText(
|
|
147
|
+
fireEvent.press(getByLabelText("More"));
|
|
152
148
|
expect(getByLabelText("hi")).toBeDefined();
|
|
153
149
|
fireEvent.press(getByLabelText("hi"));
|
|
154
150
|
expect(beforeSubmitMock).toHaveBeenCalled();
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { useIntl } from "react-intl";
|
|
3
2
|
import { useFormContext } from "react-hook-form";
|
|
4
|
-
import { messages } from "./messages";
|
|
5
3
|
import { FormSaveButtonProps, SecondaryActionProp } from "../../types";
|
|
6
4
|
import {
|
|
7
5
|
ButtonGroup,
|
|
8
6
|
ButtonGroupSecondaryActionProps,
|
|
9
7
|
} from "../../../ButtonGroup";
|
|
8
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
10
9
|
|
|
11
10
|
export function FormSaveButton({
|
|
12
11
|
primaryAction,
|
|
@@ -17,7 +16,7 @@ export function FormSaveButton({
|
|
|
17
16
|
onOpenBottomSheet,
|
|
18
17
|
onCloseBottomSheet,
|
|
19
18
|
}: FormSaveButtonProps): JSX.Element {
|
|
20
|
-
const {
|
|
19
|
+
const { t } = useAtlantisI18n();
|
|
21
20
|
const formContext = useFormContext();
|
|
22
21
|
const buttonActions = useButtonGroupAction(secondaryActions);
|
|
23
22
|
|
|
@@ -34,7 +33,7 @@ export function FormSaveButton({
|
|
|
34
33
|
<ButtonGroup.PrimaryAction
|
|
35
34
|
key={index}
|
|
36
35
|
onPress={primaryAction}
|
|
37
|
-
label={label ??
|
|
36
|
+
label={label ?? t("save")}
|
|
38
37
|
loading={loading}
|
|
39
38
|
/>
|
|
40
39
|
);
|
|
@@ -69,7 +68,7 @@ export function FormSaveButton({
|
|
|
69
68
|
: [];
|
|
70
69
|
|
|
71
70
|
buttonGroupActionProps.unshift({
|
|
72
|
-
label: label ??
|
|
71
|
+
label: label ?? t("save"),
|
|
73
72
|
onPress: primaryAction,
|
|
74
73
|
loading: loading,
|
|
75
74
|
icon: undefined,
|
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
|
-
import { useIntl } from "react-intl";
|
|
3
2
|
import { Alert } from "react-native";
|
|
4
|
-
import {
|
|
3
|
+
import { useAtlantisI18n } from "../../hooks/useAtlantisI18n";
|
|
5
4
|
|
|
6
5
|
export function useOfflineHandler(): (
|
|
7
6
|
callback: () => void,
|
|
8
7
|
dismiss: () => void,
|
|
9
8
|
) => () => void {
|
|
10
|
-
const {
|
|
9
|
+
const { t } = useAtlantisI18n();
|
|
11
10
|
|
|
12
11
|
const handleOfflineSubmit = useCallback(
|
|
13
12
|
(callback: () => void, dismiss: () => void) => {
|
|
14
13
|
return () => {
|
|
15
14
|
Alert.alert(
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
t("networkUnavailableTitle"),
|
|
16
|
+
t("networkUnavailableDescription"),
|
|
18
17
|
[
|
|
19
18
|
{
|
|
20
|
-
text:
|
|
19
|
+
text: t("dismiss"),
|
|
21
20
|
style: "cancel",
|
|
22
21
|
onPress: dismiss,
|
|
23
22
|
},
|
|
24
23
|
{
|
|
25
|
-
text:
|
|
24
|
+
text: t("tryAgain"),
|
|
26
25
|
style: "default",
|
|
27
26
|
onPress: callback,
|
|
28
27
|
},
|
|
@@ -30,7 +29,7 @@ export function useOfflineHandler(): (
|
|
|
30
29
|
);
|
|
31
30
|
};
|
|
32
31
|
},
|
|
33
|
-
[
|
|
32
|
+
[t],
|
|
34
33
|
);
|
|
35
34
|
return handleOfflineSubmit;
|
|
36
35
|
}
|
|
@@ -2,7 +2,6 @@ import React from "react";
|
|
|
2
2
|
import { RenderAPI, fireEvent, render } from "@testing-library/react-native";
|
|
3
3
|
import { Host } from "react-native-portalize";
|
|
4
4
|
import { Alert } from "react-native";
|
|
5
|
-
import { useIntl } from "react-intl";
|
|
6
5
|
import { File, FormatFile } from ".";
|
|
7
6
|
import {
|
|
8
7
|
FILE_MOCK_FILE,
|
|
@@ -13,8 +12,6 @@ import {
|
|
|
13
12
|
FILE_UPLOAD_MOCK_IMAGE,
|
|
14
13
|
FILE_UPLOAD_MOCK_PDF,
|
|
15
14
|
} from "./components/_mocks/mockFiles";
|
|
16
|
-
import { messages } from "./components/FormatFileBottomSheet/messages";
|
|
17
|
-
import { messages as formatFileMessages } from "./messages";
|
|
18
15
|
import { BottomSheetOptionsSuffix } from "./components/FormatFileBottomSheet";
|
|
19
16
|
import { FileUpload, StatusCode } from "./types";
|
|
20
17
|
import { tokens } from "../utils/design";
|
|
@@ -94,11 +91,7 @@ function basicRenderTestWithValue() {
|
|
|
94
91
|
|
|
95
92
|
it("renders a helpful accessibility label", () => {
|
|
96
93
|
const tree = renderFormatFile(file);
|
|
97
|
-
expect(
|
|
98
|
-
tree.getByLabelText(
|
|
99
|
-
formatFileMessages.inProgressAccessibilityLabel.defaultMessage,
|
|
100
|
-
),
|
|
101
|
-
).toBeDefined();
|
|
94
|
+
expect(tree.getByLabelText("Upload in progress.")).toBeDefined();
|
|
102
95
|
});
|
|
103
96
|
|
|
104
97
|
it("renders an overlay on the image when upload status is not completed", () => {
|
|
@@ -166,11 +159,7 @@ function basicRenderTestWithValue() {
|
|
|
166
159
|
|
|
167
160
|
it("renders a helpful accessibility label", () => {
|
|
168
161
|
const tree = renderFormatFile(file);
|
|
169
|
-
expect(
|
|
170
|
-
tree.getByLabelText(
|
|
171
|
-
formatFileMessages.errorAccessibilityLabel.defaultMessage,
|
|
172
|
-
),
|
|
173
|
-
).toBeDefined();
|
|
162
|
+
expect(tree.getByLabelText("Failed to upload.")).toBeDefined();
|
|
174
163
|
});
|
|
175
164
|
|
|
176
165
|
it("does not render an overlay", () => {
|
|
@@ -206,10 +195,7 @@ function basicRenderTestWithValue() {
|
|
|
206
195
|
"when a uploaded %s is being used",
|
|
207
196
|
(bottomSheetOptionsSuffix, testId, file) => {
|
|
208
197
|
let tree: RenderAPI;
|
|
209
|
-
const
|
|
210
|
-
const removeLabel = formatMessage(messages.removeButton, {
|
|
211
|
-
bottomSheetOptionsSuffix: bottomSheetOptionsSuffix,
|
|
212
|
-
});
|
|
198
|
+
const removeLabel = `Remove ${bottomSheetOptionsSuffix}`;
|
|
213
199
|
|
|
214
200
|
beforeEach(() => {
|
|
215
201
|
jest.clearAllMocks();
|
|
@@ -244,12 +230,8 @@ function basicRenderTestWithValue() {
|
|
|
244
230
|
);
|
|
245
231
|
|
|
246
232
|
describe("when the preview option is tapped", () => {
|
|
247
|
-
const { formatMessage } = useIntl();
|
|
248
|
-
|
|
249
233
|
it("calls onPreview with a valid image", () => {
|
|
250
|
-
const previewLabel =
|
|
251
|
-
bottomSheetOptionsSuffix: "image",
|
|
252
|
-
});
|
|
234
|
+
const previewLabel = "Preview image";
|
|
253
235
|
const { getByTestId, getByLabelText } = renderFormatFile(
|
|
254
236
|
FILE_UPLOAD_MOCK_IMAGE({ progress: 1, status: StatusCode.Completed }),
|
|
255
237
|
"image",
|
|
@@ -260,9 +242,7 @@ function basicRenderTestWithValue() {
|
|
|
260
242
|
});
|
|
261
243
|
|
|
262
244
|
it("calls onPreview with a valid pdf file", () => {
|
|
263
|
-
const previewLabel =
|
|
264
|
-
bottomSheetOptionsSuffix: "file",
|
|
265
|
-
});
|
|
245
|
+
const previewLabel = "Preview file";
|
|
266
246
|
const { getByTestId, getByLabelText } = renderFormatFile(
|
|
267
247
|
FILE_UPLOAD_MOCK_PDF({ progress: 1, status: StatusCode.Completed }),
|
|
268
248
|
"file",
|
|
@@ -273,9 +253,7 @@ function basicRenderTestWithValue() {
|
|
|
273
253
|
});
|
|
274
254
|
|
|
275
255
|
it("calls onPreview with a valid external PDF file", () => {
|
|
276
|
-
const previewLabel =
|
|
277
|
-
bottomSheetOptionsSuffix: "file",
|
|
278
|
-
});
|
|
256
|
+
const previewLabel = "Preview file";
|
|
279
257
|
const { getByTestId, getByLabelText } = renderFormatFile(
|
|
280
258
|
FILE_MOCK_PDF,
|
|
281
259
|
"file",
|
|
@@ -286,9 +264,7 @@ function basicRenderTestWithValue() {
|
|
|
286
264
|
});
|
|
287
265
|
|
|
288
266
|
it("does not show the preview option with an unaccepted file", () => {
|
|
289
|
-
const previewLabel =
|
|
290
|
-
bottomSheetOptionsSuffix: "file",
|
|
291
|
-
});
|
|
267
|
+
const previewLabel = "Preview file";
|
|
292
268
|
const { getByTestId, queryByLabelText } = renderFormatFile(
|
|
293
269
|
FILE_UPLOAD_MOCK_FILE({ progress: 1, status: StatusCode.Completed }),
|
|
294
270
|
"file",
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React, { createRef, useCallback, useState } from "react";
|
|
2
2
|
import { TouchableOpacity, View } from "react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
|
-
import { messages } from "./messages";
|
|
5
3
|
import { styles } from "./FormatFile.style";
|
|
6
4
|
import { MediaView } from "./components/MediaView";
|
|
7
5
|
import {
|
|
@@ -20,6 +18,7 @@ import {
|
|
|
20
18
|
import { AtlantisFormatFileContext } from "./context/FormatFileContext";
|
|
21
19
|
import { createUseCreateThumbnail } from "./utils/createUseCreateThumbnail";
|
|
22
20
|
import { BottomSheetRef } from "../BottomSheet/BottomSheet";
|
|
21
|
+
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
23
22
|
|
|
24
23
|
export interface FormatFileProps<T> {
|
|
25
24
|
/**
|
|
@@ -247,7 +246,7 @@ function FormatFileInternal({
|
|
|
247
246
|
file.status !== StatusCode.Completed,
|
|
248
247
|
);
|
|
249
248
|
|
|
250
|
-
const {
|
|
249
|
+
const { t } = useAtlantisI18n();
|
|
251
250
|
const bottomSheetRef = createRef<BottomSheetRef>();
|
|
252
251
|
|
|
253
252
|
const handlePreviewPress = useCallback(() => {
|
|
@@ -263,10 +262,7 @@ function FormatFileInternal({
|
|
|
263
262
|
<View>
|
|
264
263
|
<TouchableOpacity
|
|
265
264
|
accessibilityRole="imagebutton"
|
|
266
|
-
accessibilityHint={
|
|
267
|
-
accessibilityHint ??
|
|
268
|
-
formatMessage(messages.defaultAccessibilityHint)
|
|
269
|
-
}
|
|
265
|
+
accessibilityHint={accessibilityHint ?? t("FormatFile.hint")}
|
|
270
266
|
onPress={handleOnPress}
|
|
271
267
|
testID={testID}
|
|
272
268
|
>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
3
|
import { IconNames } from "@jobber/design";
|
|
5
4
|
import { styles } from "./FileView.style";
|
|
6
5
|
import { Icon } from "../../../Icon";
|
|
@@ -9,6 +8,7 @@ import { FormattedFile, StatusCode } from "../../types";
|
|
|
9
8
|
import { computeA11yLabel } from "../../utils";
|
|
10
9
|
import { ProgressBar } from "../ProgressBar";
|
|
11
10
|
import { ErrorIcon } from "../ErrorIcon";
|
|
11
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
12
12
|
|
|
13
13
|
interface FileViewProps {
|
|
14
14
|
accessibilityLabel?: string;
|
|
@@ -27,12 +27,12 @@ export function FileView({
|
|
|
27
27
|
showError,
|
|
28
28
|
onUploadComplete,
|
|
29
29
|
}: FileViewProps): JSX.Element {
|
|
30
|
-
const {
|
|
30
|
+
const { t } = useAtlantisI18n();
|
|
31
31
|
const a11yLabel = computeA11yLabel({
|
|
32
32
|
accessibilityLabel,
|
|
33
33
|
showOverlay,
|
|
34
34
|
showError,
|
|
35
|
-
|
|
35
|
+
t,
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const freezeProgressBar =
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import React, { createRef } from "react";
|
|
2
2
|
import { RenderAPI, fireEvent, render } from "@testing-library/react-native";
|
|
3
3
|
import { Host } from "react-native-portalize";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
4
|
import { act } from "react-test-renderer";
|
|
6
5
|
import {
|
|
7
6
|
BottomSheetOptionsSuffix,
|
|
8
7
|
FormatFileBottomSheet,
|
|
9
8
|
} from "./FormatFileBottomSheet";
|
|
10
|
-
import { messages } from "./messages";
|
|
11
9
|
import { BottomSheetRef } from "../../../BottomSheet/BottomSheet";
|
|
12
10
|
|
|
13
11
|
let Platform: { OS: "ios" | "android" };
|
|
@@ -38,13 +36,8 @@ const basicRenderTestWithValue = () => {
|
|
|
38
36
|
describe.each([["image"], ["receipt"], ["file"], ["video"]])(
|
|
39
37
|
"when FormatFileBottomSheet for %s is opened",
|
|
40
38
|
bottomSheetOptionsSuffix => {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
bottomSheetOptionsSuffix,
|
|
44
|
-
});
|
|
45
|
-
const removeLabel = formatMessage(messages.removeButton, {
|
|
46
|
-
bottomSheetOptionsSuffix,
|
|
47
|
-
});
|
|
39
|
+
const previewLabel = `Preview ${bottomSheetOptionsSuffix}`;
|
|
40
|
+
const removeLabel = `Remove ${bottomSheetOptionsSuffix}`;
|
|
48
41
|
let tree: RenderAPI;
|
|
49
42
|
|
|
50
43
|
beforeEach(() => {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React, { RefObject } from "react";
|
|
2
2
|
import { Portal } from "react-native-portalize";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
|
-
import { messages } from "./messages";
|
|
5
3
|
import { BottomSheet, BottomSheetRef } from "../../../BottomSheet/BottomSheet";
|
|
6
4
|
import { BottomSheetOption } from "../../../BottomSheet/components/BottomSheetOption";
|
|
5
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
7
6
|
|
|
8
7
|
export type BottomSheetOptionsSuffix = "receipt" | "image" | "file" | "video";
|
|
9
8
|
|
|
@@ -20,7 +19,7 @@ export const FormatFileBottomSheet = ({
|
|
|
20
19
|
onRemovePress,
|
|
21
20
|
bottomSheetOptionsSuffix,
|
|
22
21
|
}: FormatFileBottomSheetProps): JSX.Element => {
|
|
23
|
-
const {
|
|
22
|
+
const { t } = useAtlantisI18n();
|
|
24
23
|
|
|
25
24
|
const handlePress = (onPressAction: () => void) => {
|
|
26
25
|
onPressAction();
|
|
@@ -34,8 +33,8 @@ export const FormatFileBottomSheet = ({
|
|
|
34
33
|
{onPreviewPress ? (
|
|
35
34
|
<BottomSheetOption
|
|
36
35
|
icon={"eye"}
|
|
37
|
-
text={
|
|
38
|
-
bottomSheetOptionsSuffix,
|
|
36
|
+
text={t("FormatFile.preview", {
|
|
37
|
+
item: bottomSheetOptionsSuffix || "",
|
|
39
38
|
})}
|
|
40
39
|
onPress={() => handlePress(onPreviewPress)}
|
|
41
40
|
/>
|
|
@@ -44,8 +43,8 @@ export const FormatFileBottomSheet = ({
|
|
|
44
43
|
<BottomSheetOption
|
|
45
44
|
icon={"trash"}
|
|
46
45
|
destructive={true}
|
|
47
|
-
text={
|
|
48
|
-
bottomSheetOptionsSuffix,
|
|
46
|
+
text={t("FormatFile.remove", {
|
|
47
|
+
item: bottomSheetOptionsSuffix || "",
|
|
49
48
|
})}
|
|
50
49
|
onPress={() => handlePress(onRemovePress)}
|
|
51
50
|
/>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { ImageBackground, View } from "react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
3
|
import { styles } from "./MediaView.style";
|
|
5
4
|
import { FormattedFile, StatusCode } from "../../types";
|
|
6
5
|
import { computeA11yLabel } from "../../utils";
|
|
@@ -9,6 +8,7 @@ import { Icon } from "../../../Icon";
|
|
|
9
8
|
import { ProgressBar } from "../ProgressBar";
|
|
10
9
|
import { ErrorIcon } from "../ErrorIcon";
|
|
11
10
|
import { useAtlantisFormatFileContext } from "../../context/FormatFileContext";
|
|
11
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
12
12
|
|
|
13
13
|
interface MediaViewProps {
|
|
14
14
|
accessibilityLabel?: string;
|
|
@@ -27,7 +27,7 @@ export function MediaView({
|
|
|
27
27
|
styleInGrid,
|
|
28
28
|
onUploadComplete,
|
|
29
29
|
}: MediaViewProps): JSX.Element {
|
|
30
|
-
const {
|
|
30
|
+
const { t } = useAtlantisI18n();
|
|
31
31
|
const { useCreateThumbnail } = useAtlantisFormatFileContext();
|
|
32
32
|
const { thumbnail, error } = useCreateThumbnail(file);
|
|
33
33
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -36,7 +36,7 @@ export function MediaView({
|
|
|
36
36
|
accessibilityLabel,
|
|
37
37
|
showOverlay,
|
|
38
38
|
showError,
|
|
39
|
-
|
|
39
|
+
t,
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
const hasError = showError || error;
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { messages } from "../messages";
|
|
1
|
+
import { useAtlantisI18nValue } from "../../hooks/useAtlantisI18n";
|
|
3
2
|
|
|
4
3
|
interface params {
|
|
5
|
-
accessibilityLabel?: string;
|
|
6
|
-
showOverlay: boolean;
|
|
7
|
-
showError: boolean;
|
|
8
|
-
|
|
4
|
+
readonly accessibilityLabel?: string;
|
|
5
|
+
readonly showOverlay: boolean;
|
|
6
|
+
readonly showError: boolean;
|
|
7
|
+
readonly t: useAtlantisI18nValue["t"];
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
export function computeA11yLabel({
|
|
12
11
|
accessibilityLabel,
|
|
13
12
|
showOverlay,
|
|
14
13
|
showError,
|
|
15
|
-
|
|
14
|
+
t,
|
|
16
15
|
}: params): string {
|
|
17
16
|
if (!showError && showOverlay) {
|
|
18
|
-
return
|
|
17
|
+
return t("upload.inProgress");
|
|
19
18
|
} else if (showError) {
|
|
20
|
-
return
|
|
19
|
+
return t("upload.failed");
|
|
21
20
|
} else {
|
|
22
|
-
return (
|
|
23
|
-
accessibilityLabel || formatMessage(messages.defaultAccessibilityLabel)
|
|
24
|
-
);
|
|
21
|
+
return accessibilityLabel || t("FormatFile.label");
|
|
25
22
|
}
|
|
26
23
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { fireEvent, render, waitFor } from "@testing-library/react-native";
|
|
3
3
|
import { InputCurrency } from "./InputCurrency";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AtlantisContext,
|
|
6
|
+
AtlantisContextProps,
|
|
7
|
+
defaultValues,
|
|
8
|
+
} from "../AtlantisContext";
|
|
5
9
|
|
|
6
10
|
const mockCurrencySymbol = "£";
|
|
7
11
|
const atlantisContext: AtlantisContextProps = {
|
|
12
|
+
...defaultValues,
|
|
8
13
|
currencySymbol: mockCurrencySymbol,
|
|
9
14
|
timeFormat: "p",
|
|
10
15
|
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
limitInputWholeDigits,
|
|
12
12
|
parseGivenInput,
|
|
13
13
|
} from "./utils";
|
|
14
|
-
import { messages } from "./messages";
|
|
15
14
|
import { useAtlantisContext } from "../AtlantisContext";
|
|
16
15
|
import { InputText, InputTextProps } from "../InputText";
|
|
17
16
|
import { useFormController } from "../hooks/useFormController";
|
|
17
|
+
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
18
18
|
|
|
19
19
|
export interface InputCurrencyProps
|
|
20
20
|
extends Omit<
|
|
@@ -164,7 +164,7 @@ export function InputCurrency(props: InputCurrencyProps): JSX.Element {
|
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
-
const {
|
|
167
|
+
const { t } = useAtlantisI18n();
|
|
168
168
|
|
|
169
169
|
return (
|
|
170
170
|
<>
|
|
@@ -186,7 +186,7 @@ export function InputCurrency(props: InputCurrencyProps): JSX.Element {
|
|
|
186
186
|
validations={{
|
|
187
187
|
pattern: {
|
|
188
188
|
value: NUMBER_VALIDATION_REGEX,
|
|
189
|
-
message:
|
|
189
|
+
message: t("errors.notANumber"),
|
|
190
190
|
},
|
|
191
191
|
...props.validations,
|
|
192
192
|
}}
|
|
@@ -3,14 +3,13 @@ import DateTimePicker from "react-native-modal-datetime-picker";
|
|
|
3
3
|
import { Platform } from "react-native";
|
|
4
4
|
import { FieldError, UseControllerProps } from "react-hook-form";
|
|
5
5
|
import { XOR } from "ts-xor";
|
|
6
|
-
import { useIntl } from "react-intl";
|
|
7
6
|
import { utcToZonedTime } from "date-fns-tz";
|
|
8
7
|
import { format as formatDate } from "date-fns";
|
|
9
|
-
import { messages } from "./messages";
|
|
10
8
|
import { Clearable, InputFieldWrapperProps } from "../InputFieldWrapper";
|
|
11
9
|
import { FormField } from "../FormField";
|
|
12
10
|
import { InputPressable } from "../InputPressable";
|
|
13
11
|
import { useAtlantisContext } from "../AtlantisContext";
|
|
12
|
+
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
14
13
|
|
|
15
14
|
interface BaseInputDateProps
|
|
16
15
|
extends Pick<InputFieldWrapperProps, "invalid" | "disabled" | "placeholder"> {
|
|
@@ -154,7 +153,7 @@ function InternalInputDate({
|
|
|
154
153
|
accessibilityHint,
|
|
155
154
|
}: InputDateProps): JSX.Element {
|
|
156
155
|
const [showPicker, setShowPicker] = useState(false);
|
|
157
|
-
const {
|
|
156
|
+
const { t, locale } = useAtlantisI18n();
|
|
158
157
|
const { timeZone, dateFormat } = useAtlantisContext();
|
|
159
158
|
|
|
160
159
|
const date = useMemo(() => {
|
|
@@ -173,8 +172,7 @@ function InternalInputDate({
|
|
|
173
172
|
|
|
174
173
|
const canClearDate = formattedDate === emptyValueLabel ? "never" : clearable;
|
|
175
174
|
|
|
176
|
-
const placeholderLabel =
|
|
177
|
-
placeholder ?? formatMessage(messages.datePlaceholder);
|
|
175
|
+
const placeholderLabel = placeholder ?? t("date");
|
|
178
176
|
|
|
179
177
|
return (
|
|
180
178
|
<>
|
|
@@ -198,6 +196,9 @@ function InternalInputDate({
|
|
|
198
196
|
maximumDate={maxDate}
|
|
199
197
|
minimumDate={minDate}
|
|
200
198
|
mode="date"
|
|
199
|
+
confirmTextIOS={t("confirm")}
|
|
200
|
+
cancelTextIOS={t("cancel")}
|
|
201
|
+
locale={locale}
|
|
201
202
|
onCancel={handleCancel}
|
|
202
203
|
onConfirm={handleConfirm}
|
|
203
204
|
/>
|
|
@@ -2,13 +2,11 @@ import React from "react";
|
|
|
2
2
|
import { RenderAPI, fireEvent, render } from "@testing-library/react-native";
|
|
3
3
|
// eslint-disable-next-line no-restricted-imports
|
|
4
4
|
import { Text, ViewStyle } from "react-native";
|
|
5
|
-
import { useIntl } from "react-intl";
|
|
6
5
|
import {
|
|
7
6
|
InputFieldWrapper,
|
|
8
7
|
InputFieldWrapperProps,
|
|
9
8
|
commonInputStyles,
|
|
10
9
|
} from ".";
|
|
11
|
-
import { messages as clearMessages } from "./components/ClearAction";
|
|
12
10
|
import { styles } from "./InputFieldWrapper.style";
|
|
13
11
|
import { typographyStyles } from "../Typography";
|
|
14
12
|
|
|
@@ -32,6 +30,7 @@ function renderWithSuffixLabel(hasValue: boolean): RenderAPI {
|
|
|
32
30
|
return renderInputFieldWrapper({ suffix: mockLabel, hasValue });
|
|
33
31
|
}
|
|
34
32
|
|
|
33
|
+
const clearInput = "Clear input";
|
|
35
34
|
describe("InputFieldWrapper", () => {
|
|
36
35
|
it("renders an invalid InputFieldWrapper", () => {
|
|
37
36
|
const { getByTestId } = renderInputFieldWrapper({ invalid: true });
|
|
@@ -120,36 +119,26 @@ describe("InputFieldWrapper", () => {
|
|
|
120
119
|
|
|
121
120
|
describe("ClearAction", () => {
|
|
122
121
|
it("renders the Clear Action Button when showClearAction is true", () => {
|
|
123
|
-
const { formatMessage } = useIntl();
|
|
124
122
|
const { getByLabelText } = renderInputFieldWrapper({
|
|
125
123
|
showClearAction: true,
|
|
126
124
|
});
|
|
127
|
-
expect(
|
|
128
|
-
getByLabelText(formatMessage(clearMessages.clearTextLabel)),
|
|
129
|
-
).toBeDefined();
|
|
125
|
+
expect(getByLabelText(clearInput)).toBeDefined();
|
|
130
126
|
});
|
|
131
127
|
|
|
132
128
|
it("does not render the Clear Action Button when showClearAction is false", () => {
|
|
133
|
-
const { formatMessage } = useIntl();
|
|
134
129
|
const { queryByLabelText } = renderInputFieldWrapper({
|
|
135
130
|
showClearAction: false,
|
|
136
131
|
});
|
|
137
|
-
expect(
|
|
138
|
-
queryByLabelText(formatMessage(clearMessages.clearTextLabel)),
|
|
139
|
-
).toBeNull();
|
|
132
|
+
expect(queryByLabelText(clearInput)).toBeNull();
|
|
140
133
|
});
|
|
141
134
|
|
|
142
135
|
it("calls onClear when the Clear Action button is pressed", () => {
|
|
143
|
-
const { formatMessage } = useIntl();
|
|
144
136
|
const onClear = jest.fn();
|
|
145
137
|
const { getByLabelText } = renderInputFieldWrapper({
|
|
146
138
|
showClearAction: true,
|
|
147
139
|
onClear: onClear,
|
|
148
140
|
});
|
|
149
|
-
fireEvent(
|
|
150
|
-
getByLabelText(formatMessage(clearMessages.clearTextLabel)),
|
|
151
|
-
"press",
|
|
152
|
-
);
|
|
141
|
+
fireEvent(getByLabelText(clearInput), "press");
|
|
153
142
|
expect(onClear).toHaveBeenCalled();
|
|
154
143
|
});
|
|
155
144
|
});
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { fireEvent, render } from "@testing-library/react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
3
|
import { ClearAction } from "./ClearAction";
|
|
5
|
-
import { messages } from "./messages";
|
|
6
4
|
|
|
7
5
|
it("should call the handler", () => {
|
|
8
6
|
const pressHandler = jest.fn();
|
|
9
|
-
const { formatMessage } = useIntl();
|
|
10
|
-
|
|
11
7
|
const { getByLabelText } = render(<ClearAction onPress={pressHandler} />);
|
|
12
8
|
|
|
13
|
-
fireEvent.press(getByLabelText(
|
|
9
|
+
fireEvent.press(getByLabelText("Clear input"));
|
|
14
10
|
expect(pressHandler).toHaveBeenCalled();
|
|
15
11
|
});
|