@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.
Files changed (150) hide show
  1. package/dist/package.json +88 -0
  2. package/dist/src/AtlantisContext/AtlantisContext.js +1 -0
  3. package/dist/src/BottomSheet/BottomSheet.js +3 -4
  4. package/dist/src/ButtonGroup/ButtonGroup.js +3 -4
  5. package/dist/src/ButtonGroup/utils.js +4 -5
  6. package/dist/src/ContentOverlay/ContentOverlay.js +3 -4
  7. package/dist/src/Form/components/FormErrorBanner/FormErrorBanner.js +5 -13
  8. package/dist/src/Form/components/FormMask/FormMask.js +3 -4
  9. package/dist/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.js +4 -5
  10. package/dist/src/Form/components/FormSaveButton/FormSaveButton.js +4 -5
  11. package/dist/src/Form/hooks/useOfflineHandler.js +6 -7
  12. package/dist/src/FormatFile/FormatFile.js +3 -4
  13. package/dist/src/FormatFile/components/FileView/FileView.js +3 -3
  14. package/dist/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.js +6 -7
  15. package/dist/src/FormatFile/components/MediaView/MediaView.js +3 -3
  16. package/dist/src/FormatFile/utils/computeA11yLabel.js +4 -5
  17. package/dist/src/InputCurrency/InputCurrency.js +3 -3
  18. package/dist/src/InputDate/InputDate.js +4 -5
  19. package/dist/src/InputFieldWrapper/components/ClearAction/ClearAction.js +3 -4
  20. package/dist/src/InputFieldWrapper/components/ClearAction/index.js +0 -1
  21. package/dist/src/InputNumber/InputNumber.js +3 -4
  22. package/dist/src/InputPassword/InputPassword.js +3 -4
  23. package/dist/src/InputTime/InputTime.js +3 -4
  24. package/dist/src/Menu/Menu.js +3 -4
  25. package/dist/src/ProgressBar/ProgressBar.js +14 -8
  26. package/dist/src/Select/Select.js +5 -6
  27. package/dist/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.js +3 -4
  28. package/dist/src/Toast/Toast.js +4 -5
  29. package/dist/src/hooks/useAtlantisI18n/index.js +1 -0
  30. package/dist/src/hooks/useAtlantisI18n/locales/en.json +31 -0
  31. package/dist/src/hooks/useAtlantisI18n/locales/es.json +31 -0
  32. package/dist/src/hooks/useAtlantisI18n/useAtlantisI18n.js +22 -0
  33. package/dist/tsconfig.json +38 -0
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/dist/types/src/AtlantisContext/AtlantisContext.d.ts +8 -0
  36. package/dist/types/src/FormatFile/utils/computeA11yLabel.d.ts +6 -6
  37. package/dist/types/src/InputFieldWrapper/components/ClearAction/index.d.ts +0 -1
  38. package/dist/types/src/hooks/useAtlantisI18n/index.d.ts +1 -0
  39. package/dist/types/src/hooks/useAtlantisI18n/useAtlantisI18n.d.ts +6 -0
  40. package/package.json +2 -2
  41. package/src/AtlantisContext/AtlantisContext.tsx +10 -0
  42. package/src/BottomSheet/BottomSheet.test.tsx +3 -4
  43. package/src/BottomSheet/BottomSheet.tsx +3 -4
  44. package/src/ButtonGroup/ButtonGroup.test.tsx +8 -9
  45. package/src/ButtonGroup/ButtonGroup.tsx +3 -4
  46. package/src/ButtonGroup/utils.ts +5 -6
  47. package/src/ContentOverlay/ContentOverlay.test.tsx +1 -11
  48. package/src/ContentOverlay/ContentOverlay.tsx +5 -9
  49. package/src/Form/Form.test.tsx +9 -40
  50. package/src/Form/components/FormErrorBanner/FormErrorBanner.test.tsx +9 -72
  51. package/src/Form/components/FormErrorBanner/FormErrorBanner.tsx +6 -15
  52. package/src/Form/components/FormMask/FormMask.tsx +3 -7
  53. package/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.tsx +4 -5
  54. package/src/Form/components/FormSaveButton/FormSaveButton.test.tsx +3 -7
  55. package/src/Form/components/FormSaveButton/FormSaveButton.tsx +4 -5
  56. package/src/Form/hooks/useOfflineHandler.ts +7 -8
  57. package/src/FormatFile/FormatFile.test.tsx +7 -31
  58. package/src/FormatFile/FormatFile.tsx +3 -7
  59. package/src/FormatFile/components/FileView/FileView.tsx +3 -3
  60. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.tsx +2 -9
  61. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +6 -7
  62. package/src/FormatFile/components/MediaView/MediaView.tsx +3 -3
  63. package/src/FormatFile/utils/computeA11yLabel.ts +9 -12
  64. package/src/InputCurrency/InputCurrency.test.tsx +6 -1
  65. package/src/InputCurrency/InputCurrency.tsx +3 -3
  66. package/src/InputDate/InputDate.tsx +6 -5
  67. package/src/InputFieldWrapper/InputFieldWrapper.test.tsx +4 -15
  68. package/src/InputFieldWrapper/components/ClearAction/ClearAction.test.tsx +1 -5
  69. package/src/InputFieldWrapper/components/ClearAction/ClearAction.tsx +3 -4
  70. package/src/InputFieldWrapper/components/ClearAction/index.ts +0 -1
  71. package/src/InputNumber/InputNumber.test.tsx +10 -18
  72. package/src/InputNumber/InputNumber.tsx +3 -4
  73. package/src/InputPassword/InputPassword.test.tsx +1 -2
  74. package/src/InputPassword/InputPassword.tsx +3 -4
  75. package/src/InputSearch/InputSearch.test.tsx +1 -6
  76. package/src/InputText/InputText.test.tsx +10 -38
  77. package/src/InputTime/InputTime.tsx +3 -4
  78. package/src/Menu/Menu.test.tsx +10 -9
  79. package/src/Menu/Menu.tsx +3 -4
  80. package/src/ProgressBar/ProgressBar.tsx +17 -8
  81. package/src/Select/Select.test.tsx +4 -5
  82. package/src/Select/Select.tsx +5 -8
  83. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.tsx +3 -4
  84. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.test.tsx +1 -2
  85. package/src/Toast/Toast.tsx +4 -9
  86. package/src/hooks/useAtlantisI18n/index.ts +1 -0
  87. package/src/hooks/useAtlantisI18n/locales/en.json +31 -0
  88. package/src/hooks/useAtlantisI18n/locales/es.json +31 -0
  89. package/src/hooks/useAtlantisI18n/useAtlantisI18n.test.ts +53 -0
  90. package/src/hooks/useAtlantisI18n/useAtlantisI18n.ts +43 -0
  91. package/dist/src/BottomSheet/messages.js +0 -8
  92. package/dist/src/ButtonGroup/messages.js +0 -18
  93. package/dist/src/ContentOverlay/messages.js +0 -8
  94. package/dist/src/Form/components/FormErrorBanner/messages.js +0 -13
  95. package/dist/src/Form/components/FormMessage/components/InternalFormMessage/messages.js +0 -8
  96. package/dist/src/Form/components/FormSaveButton/messages.js +0 -8
  97. package/dist/src/Form/messages.js +0 -28
  98. package/dist/src/FormatFile/components/FormatFileBottomSheet/messages.js +0 -13
  99. package/dist/src/FormatFile/messages.js +0 -23
  100. package/dist/src/InputCurrency/messages.js +0 -8
  101. package/dist/src/InputDate/messages.js +0 -8
  102. package/dist/src/InputFieldWrapper/components/ClearAction/messages.js +0 -8
  103. package/dist/src/InputNumber/messages.js +0 -8
  104. package/dist/src/InputPassword/messages.js +0 -8
  105. package/dist/src/InputTime/messages.js +0 -8
  106. package/dist/src/Menu/messages.js +0 -8
  107. package/dist/src/ProgressBar/messages.js +0 -13
  108. package/dist/src/Select/components/SelectDefaultPicker/messages.js +0 -8
  109. package/dist/src/Select/messages.js +0 -13
  110. package/dist/src/Toast/messages.js +0 -13
  111. package/dist/types/src/BottomSheet/messages.d.ts +0 -7
  112. package/dist/types/src/ButtonGroup/messages.d.ts +0 -17
  113. package/dist/types/src/ContentOverlay/messages.d.ts +0 -7
  114. package/dist/types/src/Form/components/FormErrorBanner/messages.d.ts +0 -12
  115. package/dist/types/src/Form/components/FormMessage/components/InternalFormMessage/messages.d.ts +0 -7
  116. package/dist/types/src/Form/components/FormSaveButton/messages.d.ts +0 -7
  117. package/dist/types/src/Form/messages.d.ts +0 -27
  118. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/messages.d.ts +0 -12
  119. package/dist/types/src/FormatFile/messages.d.ts +0 -22
  120. package/dist/types/src/InputCurrency/messages.d.ts +0 -7
  121. package/dist/types/src/InputDate/messages.d.ts +0 -7
  122. package/dist/types/src/InputFieldWrapper/components/ClearAction/messages.d.ts +0 -7
  123. package/dist/types/src/InputNumber/messages.d.ts +0 -7
  124. package/dist/types/src/InputPassword/messages.d.ts +0 -7
  125. package/dist/types/src/InputTime/messages.d.ts +0 -7
  126. package/dist/types/src/Menu/messages.d.ts +0 -7
  127. package/dist/types/src/ProgressBar/messages.d.ts +0 -12
  128. package/dist/types/src/Select/components/SelectDefaultPicker/messages.d.ts +0 -7
  129. package/dist/types/src/Select/messages.d.ts +0 -12
  130. package/dist/types/src/Toast/messages.d.ts +0 -12
  131. package/src/BottomSheet/messages.ts +0 -9
  132. package/src/ButtonGroup/messages.ts +0 -19
  133. package/src/ContentOverlay/messages.ts +0 -9
  134. package/src/Form/components/FormErrorBanner/messages.ts +0 -14
  135. package/src/Form/components/FormMessage/components/InternalFormMessage/messages.ts +0 -10
  136. package/src/Form/components/FormSaveButton/messages.ts +0 -9
  137. package/src/Form/messages.ts +0 -33
  138. package/src/FormatFile/components/FormatFileBottomSheet/messages.ts +0 -14
  139. package/src/FormatFile/messages.ts +0 -24
  140. package/src/InputCurrency/messages.ts +0 -10
  141. package/src/InputDate/messages.ts +0 -9
  142. package/src/InputFieldWrapper/components/ClearAction/messages.ts +0 -9
  143. package/src/InputNumber/messages.ts +0 -10
  144. package/src/InputPassword/messages.ts +0 -9
  145. package/src/InputTime/messages.ts +0 -9
  146. package/src/Menu/messages.ts +0 -9
  147. package/src/ProgressBar/messages.ts +0 -14
  148. package/src/Select/components/SelectDefaultPicker/messages.ts +0 -9
  149. package/src/Select/messages.ts +0 -14
  150. 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 { messages } from "../../messages";
5
+ import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
7
6
 
8
7
  export function FormMask(): JSX.Element {
9
- const { formatMessage } = useIntl();
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
  );
@@ -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 { formatMessage } = useIntl();
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: formatMessage(messages.goBackButton),
26
+ label: t("goBack"),
28
27
  onPress: onRequestClose,
29
28
  },
30
29
  };
31
30
  }
32
- }, [data, formatMessage, onRequestClose]);
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 = messages.saveButton.defaultMessage;
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(buttonGroupMessage.more.defaultMessage));
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 { formatMessage } = useIntl();
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 ?? formatMessage(messages.saveButton)}
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 ?? formatMessage(messages.saveButton),
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 { messages } from "../messages";
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 { formatMessage } = useIntl();
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
- formatMessage(messages.unavailableNetworkTitle),
17
- formatMessage(messages.unavailableNetworkMessage),
15
+ t("networkUnavailableTitle"),
16
+ t("networkUnavailableDescription"),
18
17
  [
19
18
  {
20
- text: formatMessage(messages.dismissAlertButton),
19
+ text: t("dismiss"),
21
20
  style: "cancel",
22
21
  onPress: dismiss,
23
22
  },
24
23
  {
25
- text: formatMessage(messages.retryAlertButton),
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
- [formatMessage],
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 { formatMessage } = useIntl();
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 = formatMessage(messages.lightBoxPreviewButton, {
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 = formatMessage(messages.lightBoxPreviewButton, {
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 = formatMessage(messages.lightBoxPreviewButton, {
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 = formatMessage(messages.lightBoxPreviewButton, {
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 { formatMessage } = useIntl();
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 { formatMessage } = useIntl();
30
+ const { t } = useAtlantisI18n();
31
31
  const a11yLabel = computeA11yLabel({
32
32
  accessibilityLabel,
33
33
  showOverlay,
34
34
  showError,
35
- formatMessage,
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 { formatMessage } = useIntl();
42
- const previewLabel = formatMessage(messages.lightBoxPreviewButton, {
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 { formatMessage } = useIntl();
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={formatMessage(messages.lightBoxPreviewButton, {
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={formatMessage(messages.removeButton, {
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 { formatMessage } = useIntl();
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
- formatMessage,
39
+ t,
40
40
  });
41
41
 
42
42
  const hasError = showError || error;
@@ -1,26 +1,23 @@
1
- import { MessageDescriptor } from "react-intl";
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
- formatMessage: (message: MessageDescriptor) => string;
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
- formatMessage,
14
+ t,
16
15
  }: params): string {
17
16
  if (!showError && showOverlay) {
18
- return formatMessage(messages.inProgressAccessibilityLabel);
17
+ return t("upload.inProgress");
19
18
  } else if (showError) {
20
- return formatMessage(messages.errorAccessibilityLabel);
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 { AtlantisContext, AtlantisContextProps } from "../AtlantisContext";
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 { formatMessage } = useIntl();
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: formatMessage(messages.notANumberError),
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 { formatMessage } = useIntl();
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(formatMessage(messages.clearTextLabel)));
9
+ fireEvent.press(getByLabelText("Clear input"));
14
10
  expect(pressHandler).toHaveBeenCalled();
15
11
  });