@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
package/src/Select/Select.tsx
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React, { ReactElement } from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { useIntl } from "react-intl";
|
|
4
3
|
import { RegisterOptions } from "react-hook-form";
|
|
5
4
|
import { styles } from "./Select.style";
|
|
6
5
|
import { SelectInternalPicker } from "./components/SelectInternalPicker";
|
|
7
|
-
import { messages } from "./messages";
|
|
8
6
|
import { InputFieldWrapper } from "../InputFieldWrapper";
|
|
9
7
|
import { Icon } from "../Icon";
|
|
10
8
|
import { TextVariation } from "../Typography";
|
|
11
9
|
import { Text } from "../Text";
|
|
12
10
|
import { useFormController } from "../hooks";
|
|
11
|
+
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
13
12
|
|
|
14
13
|
export interface SelectOption {
|
|
15
14
|
/**
|
|
@@ -111,7 +110,7 @@ export function Select({
|
|
|
111
110
|
value: value ?? defaultValue,
|
|
112
111
|
});
|
|
113
112
|
|
|
114
|
-
const {
|
|
113
|
+
const { t } = useAtlantisI18n();
|
|
115
114
|
const internalValue = value ?? field.value;
|
|
116
115
|
const textVariation = getTextVariation({
|
|
117
116
|
disabled,
|
|
@@ -134,7 +133,7 @@ export function Select({
|
|
|
134
133
|
accessible={true}
|
|
135
134
|
accessibilityLabel={getA11yLabel()}
|
|
136
135
|
accessibilityValue={{ text: getValue() }}
|
|
137
|
-
accessibilityHint={
|
|
136
|
+
accessibilityHint={t("Select.a11yHint")}
|
|
138
137
|
accessibilityRole="button"
|
|
139
138
|
accessibilityState={{ disabled: disabled }}
|
|
140
139
|
>
|
|
@@ -207,7 +206,7 @@ export function Select({
|
|
|
207
206
|
|
|
208
207
|
if (!internalValue || placeholder) {
|
|
209
208
|
options.unshift({
|
|
210
|
-
label: placeholder ||
|
|
209
|
+
label: placeholder || t("Select.emptyValue"),
|
|
211
210
|
value: "",
|
|
212
211
|
isActive: !internalValue,
|
|
213
212
|
});
|
|
@@ -220,9 +219,7 @@ export function Select({
|
|
|
220
219
|
const options = getOptions();
|
|
221
220
|
|
|
222
221
|
const activeValue = options.find(option => option.isActive);
|
|
223
|
-
return (
|
|
224
|
-
activeValue?.label || placeholder || formatMessage(messages.emptyValue)
|
|
225
|
-
);
|
|
222
|
+
return activeValue?.label || placeholder || t("Select.emptyValue");
|
|
226
223
|
}
|
|
227
224
|
}
|
|
228
225
|
|
|
@@ -8,11 +8,10 @@ import {
|
|
|
8
8
|
} from "react-native";
|
|
9
9
|
import { Picker } from "@react-native-picker/picker";
|
|
10
10
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
11
|
-
import { useIntl } from "react-intl";
|
|
12
11
|
import { styles } from "./SelectDefaultPicker.style";
|
|
13
|
-
import { messages } from "./messages";
|
|
14
12
|
import { SelectInternalPickerProps } from "../../types";
|
|
15
13
|
import { SelectPressable } from "../SelectPressable/SelectPressable";
|
|
14
|
+
import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
|
|
16
15
|
|
|
17
16
|
type SelectDefaultPickerProps = SelectInternalPickerProps;
|
|
18
17
|
|
|
@@ -22,7 +21,7 @@ export function SelectDefaultPicker({
|
|
|
22
21
|
onChange,
|
|
23
22
|
}: SelectDefaultPickerProps): JSX.Element {
|
|
24
23
|
const [show, setShow] = useState(false);
|
|
25
|
-
const {
|
|
24
|
+
const { t } = useAtlantisI18n();
|
|
26
25
|
const selectedLanguage = options.find(option => option.isActive);
|
|
27
26
|
|
|
28
27
|
return (
|
|
@@ -36,7 +35,7 @@ export function SelectDefaultPicker({
|
|
|
36
35
|
>
|
|
37
36
|
<TouchableOpacity style={styles.overlay} onPress={hidePicker} />
|
|
38
37
|
<View style={styles.actionBar}>
|
|
39
|
-
<Button title={
|
|
38
|
+
<Button title={t("done")} onPress={hidePicker} />
|
|
40
39
|
</View>
|
|
41
40
|
<View style={styles.pickerContainer} testID="select-wheel-picker">
|
|
42
41
|
<SafeAreaView edges={["bottom"]}>
|
|
@@ -2,7 +2,6 @@ import React from "react";
|
|
|
2
2
|
import { cleanup, fireEvent, render } from "@testing-library/react-native";
|
|
3
3
|
import { AccessibilityInfo, View } from "react-native";
|
|
4
4
|
import { SelectDefaultPicker } from "./SelectDefaultPicker";
|
|
5
|
-
import { messages } from "./messages";
|
|
6
5
|
import { Text } from "../../../Text";
|
|
7
6
|
|
|
8
7
|
const A11yInfoSpy = jest.spyOn(AccessibilityInfo, "isScreenReaderEnabled");
|
|
@@ -55,7 +54,7 @@ describe("SelectDefaultPicker", () => {
|
|
|
55
54
|
const screen = setup();
|
|
56
55
|
|
|
57
56
|
fireEvent.press(screen.getByText(childText));
|
|
58
|
-
fireEvent.press(screen.getByText(
|
|
57
|
+
fireEvent.press(screen.getByText("Done"));
|
|
59
58
|
expect(
|
|
60
59
|
screen.getByTestId("SelectDefaultPicker").findAllByType(MockPicker),
|
|
61
60
|
).toEqual([]);
|
package/src/Toast/Toast.tsx
CHANGED
|
@@ -6,28 +6,23 @@ import Toast, {
|
|
|
6
6
|
} from "react-native-toast-message";
|
|
7
7
|
import { AccessibilityInfo, TouchableOpacity, View } from "react-native";
|
|
8
8
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
9
|
-
import { useIntl } from "react-intl";
|
|
10
9
|
import { styles } from "./Toast.styles";
|
|
11
|
-
import { messages } from "./messages";
|
|
12
10
|
import { tokens } from "../utils/design";
|
|
13
11
|
import { Text } from "../Text";
|
|
14
12
|
import { IconButton } from "../IconButton";
|
|
13
|
+
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
15
14
|
|
|
16
15
|
const MAX_TOAST_MESSAGE_LENGTH = 60;
|
|
17
16
|
const ANNOUNCEMENT_DELAY = 100;
|
|
18
17
|
|
|
19
18
|
function DefaultToast({ text1 }: ToastConfigParams<string>): JSX.Element {
|
|
20
19
|
const { bottom } = useSafeAreaInsets();
|
|
21
|
-
const {
|
|
20
|
+
const { t } = useAtlantisI18n();
|
|
22
21
|
const toastContainerStyles = [styles.container, { paddingBottom: bottom }];
|
|
23
22
|
return (
|
|
24
23
|
<View style={toastContainerStyles}>
|
|
25
24
|
<View style={styles.toast}>
|
|
26
|
-
<TouchableOpacity
|
|
27
|
-
style={styles.toastMessage}
|
|
28
|
-
accessibilityRole="alert"
|
|
29
|
-
accessibilityLabel={formatMessage(messages.toastNotificationLabel)}
|
|
30
|
-
>
|
|
25
|
+
<TouchableOpacity style={styles.toastMessage} accessibilityRole="alert">
|
|
31
26
|
<Text reverseTheme>{text1}</Text>
|
|
32
27
|
</TouchableOpacity>
|
|
33
28
|
<View style={styles.toastIcon}>
|
|
@@ -35,7 +30,7 @@ function DefaultToast({ text1 }: ToastConfigParams<string>): JSX.Element {
|
|
|
35
30
|
onPress={Toast.hide}
|
|
36
31
|
name="remove"
|
|
37
32
|
customColor={tokens["color-greyBlue--light"]}
|
|
38
|
-
accessibilityLabel={
|
|
33
|
+
accessibilityLabel={t("dismiss")}
|
|
39
34
|
/>
|
|
40
35
|
</View>
|
|
41
36
|
</View>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useAtlantisI18n";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cancel": "Cancel",
|
|
3
|
+
"confirm": "Confirm",
|
|
4
|
+
"date": "Date",
|
|
5
|
+
"dismiss": "Dismiss",
|
|
6
|
+
"done": "Done",
|
|
7
|
+
"ContentOverlay.close": "Close {title} modal",
|
|
8
|
+
"errors.couldNotSave": "Could not save changes",
|
|
9
|
+
"errors.notANumber": "Enter a number",
|
|
10
|
+
"FormatFile.label": "Attachment Preview",
|
|
11
|
+
"FormatFile.hint": "Select for more options",
|
|
12
|
+
"FormatFile.preview": "Preview {item}",
|
|
13
|
+
"FormatFile.remove": "Remove {item}",
|
|
14
|
+
"goBack": "Go back",
|
|
15
|
+
"InputFieldWrapper.clear": "Clear input",
|
|
16
|
+
"InputPassword.enterPassword": "Enter a password",
|
|
17
|
+
"loading": "Loading",
|
|
18
|
+
"menu": "Menu",
|
|
19
|
+
"more": "More",
|
|
20
|
+
"networkUnavailableTitle": "Network Unavailable",
|
|
21
|
+
"networkUnavailableDescription": "Check your internet connection and try again later.",
|
|
22
|
+
"ProgressBar.complete": "{current} of {total} complete",
|
|
23
|
+
"ProgressBar.inProgress": "{current} of {total} complete, {inProgress} in progress",
|
|
24
|
+
"save": "Save",
|
|
25
|
+
"Select.a11yHint": "Select to open the picker",
|
|
26
|
+
"Select.emptyValue": "Select an option",
|
|
27
|
+
"time": "Time",
|
|
28
|
+
"tryAgain": "Try again",
|
|
29
|
+
"upload.failed": "Failed to upload.",
|
|
30
|
+
"upload.inProgress": "Upload in progress."
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cancel": "Cancelar",
|
|
3
|
+
"confirm": "Confirmar",
|
|
4
|
+
"date": "Fecha",
|
|
5
|
+
"dismiss": "Descartar",
|
|
6
|
+
"done": "Listo",
|
|
7
|
+
"ContentOverlay.close": "Close {title} modal",
|
|
8
|
+
"errors.couldNotSave": "No se pudieron guardar los cambios",
|
|
9
|
+
"errors.notANumber": "Escriba un número",
|
|
10
|
+
"FormatFile.label": "Attachment Preview",
|
|
11
|
+
"FormatFile.hint": "Select for more options",
|
|
12
|
+
"FormatFile.preview": "Vista previa de {item}",
|
|
13
|
+
"FormatFile.remove": "Eliminar {item}",
|
|
14
|
+
"goBack": "Volver",
|
|
15
|
+
"InputFieldWrapper.clear": "Borrar",
|
|
16
|
+
"InputPassword.enterPassword": "Escriba una contraseña",
|
|
17
|
+
"loading": "Cargando",
|
|
18
|
+
"menu": "Menú",
|
|
19
|
+
"more": "Más",
|
|
20
|
+
"networkUnavailableTitle": "Red no disponible",
|
|
21
|
+
"networkUnavailableDescription": "Compruebe su conexión a Internet e inténtelo de nuevo más adelante.",
|
|
22
|
+
"ProgressBar.complete": "{current} de {total} completo",
|
|
23
|
+
"ProgressBar.inProgress": "{current} de {total} completo, {inProgress} en progreso",
|
|
24
|
+
"save": "Guardar",
|
|
25
|
+
"Select.a11yHint": "Seleccionar para abrir el selector",
|
|
26
|
+
"Select.emptyValue": "Seleccione una opción",
|
|
27
|
+
"time": "Hora",
|
|
28
|
+
"tryAgain": "Intentar de nuevo",
|
|
29
|
+
"upload.failed": "No se pudo adjuntar el archivo.",
|
|
30
|
+
"upload.inProgress": "Carga de archivo en curso."
|
|
31
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { renderHook } from "@testing-library/react-native";
|
|
2
|
+
import { useAtlantisI18n } from ".";
|
|
3
|
+
import en from "./locales/en.json";
|
|
4
|
+
import es from "./locales/es.json";
|
|
5
|
+
import * as context from "../../AtlantisContext";
|
|
6
|
+
|
|
7
|
+
jest.mock("../../AtlantisContext", () => ({
|
|
8
|
+
// need to mark this as a module so that we can spy on it
|
|
9
|
+
__esModule: true,
|
|
10
|
+
...jest.requireActual("../../AtlantisContext"),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe("useAtlantisI18n", () => {
|
|
14
|
+
it("should return english by default", () => {
|
|
15
|
+
const { result } = renderHook(useAtlantisI18n);
|
|
16
|
+
|
|
17
|
+
expect(result.current.t("cancel")).toBe("Cancel");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should interpolate the strings wrapped in {}", () => {
|
|
21
|
+
const { result } = renderHook(useAtlantisI18n);
|
|
22
|
+
|
|
23
|
+
expect(result.current.t("FormatFile.preview", { item: "🔱" })).toBe(
|
|
24
|
+
"Preview 🔱",
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("Español", () => {
|
|
29
|
+
it("should return español", () => {
|
|
30
|
+
const spy = jest.spyOn(context, "useAtlantisContext");
|
|
31
|
+
spy.mockReturnValueOnce({ ...context.defaultValues, locale: "es" });
|
|
32
|
+
const { result } = renderHook(useAtlantisI18n);
|
|
33
|
+
|
|
34
|
+
expect(result.current.t("cancel")).toBe("Cancelar");
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("Unsupported language", () => {
|
|
39
|
+
it("should return the english translation", () => {
|
|
40
|
+
const spy = jest.spyOn(context, "useAtlantisContext");
|
|
41
|
+
spy.mockReturnValueOnce({ ...context.defaultValues, locale: "fr" });
|
|
42
|
+
const { result } = renderHook(useAtlantisI18n);
|
|
43
|
+
|
|
44
|
+
expect(result.current.t("cancel")).toBe("Cancel");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("Translation files", () => {
|
|
49
|
+
it("should have the same keys for en and es", () => {
|
|
50
|
+
expect(Object.keys(en)).toEqual(Object.keys(es));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import en from "./locales/en.json";
|
|
2
|
+
import es from "./locales/es.json";
|
|
3
|
+
import { useAtlantisContext } from "../../AtlantisContext";
|
|
4
|
+
|
|
5
|
+
export interface useAtlantisI18nValue {
|
|
6
|
+
readonly locale: string;
|
|
7
|
+
readonly t: (
|
|
8
|
+
message: keyof typeof en,
|
|
9
|
+
values?: Record<string, string>,
|
|
10
|
+
) => string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function useAtlantisI18n(): useAtlantisI18nValue {
|
|
14
|
+
const { locale } = useAtlantisContext();
|
|
15
|
+
const t = (messageKey: keyof typeof en, values?: Record<string, string>) =>
|
|
16
|
+
formatMessage(messageKey, values, locale);
|
|
17
|
+
|
|
18
|
+
return { locale, t };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getLocalizedStrings(locale: string): typeof en {
|
|
22
|
+
switch (locale) {
|
|
23
|
+
case "es":
|
|
24
|
+
return es;
|
|
25
|
+
default:
|
|
26
|
+
return en;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function formatMessage(
|
|
31
|
+
messageKey: keyof typeof en,
|
|
32
|
+
values?: Record<string, string>,
|
|
33
|
+
locale = "en",
|
|
34
|
+
) {
|
|
35
|
+
const message = getLocalizedStrings(locale)[messageKey];
|
|
36
|
+
|
|
37
|
+
if (!values) return message;
|
|
38
|
+
|
|
39
|
+
return Object.entries(values).reduce(
|
|
40
|
+
(acc, [key, value]) => acc.replace(`{${key}}`, value),
|
|
41
|
+
message,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
more: {
|
|
4
|
-
id: "more",
|
|
5
|
-
defaultMessage: "More",
|
|
6
|
-
description: "Accessibility label for the More button",
|
|
7
|
-
},
|
|
8
|
-
unavailableNetworkTitle: {
|
|
9
|
-
id: "unavailableNetworkTitle",
|
|
10
|
-
defaultMessage: "Network unavailable",
|
|
11
|
-
description: "The title for alert about network unavailable",
|
|
12
|
-
},
|
|
13
|
-
unavailableNetworkMessage: {
|
|
14
|
-
id: "unavailableNetworkMessage",
|
|
15
|
-
defaultMessage: "Check your internet connection and try again later.",
|
|
16
|
-
description: "The message for alert about network unavailable",
|
|
17
|
-
},
|
|
18
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
closeOverlayA11YLabel: {
|
|
4
|
-
id: "closeOverlayA11yLabel",
|
|
5
|
-
defaultMessage: "Close {title} modal",
|
|
6
|
-
description: "Accessibility label for button to close the overlay modal",
|
|
7
|
-
},
|
|
8
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
networkError: {
|
|
4
|
-
id: "networkError",
|
|
5
|
-
defaultMessage: "Could not save changes",
|
|
6
|
-
description: "Displayed when a general server error occurs during save",
|
|
7
|
-
},
|
|
8
|
-
offlineError: {
|
|
9
|
-
id: "offlineError",
|
|
10
|
-
defaultMessage: "Currently offline. Check your internet connection.",
|
|
11
|
-
description: "Error message to be shown when the app is offline",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
loadingA11YLabel: {
|
|
4
|
-
id: "loadingA11yLabel",
|
|
5
|
-
defaultMessage: "Loading",
|
|
6
|
-
description: "Accessibility label for the loading indicator",
|
|
7
|
-
},
|
|
8
|
-
dismissAlertButton: {
|
|
9
|
-
id: "dismiss",
|
|
10
|
-
defaultMessage: "Dismiss",
|
|
11
|
-
description: "The label for the button to dismiss the alert ",
|
|
12
|
-
},
|
|
13
|
-
retryAlertButton: {
|
|
14
|
-
id: "retry",
|
|
15
|
-
defaultMessage: "Try Again",
|
|
16
|
-
description: "The label for the alert button to try action again",
|
|
17
|
-
},
|
|
18
|
-
unavailableNetworkTitle: {
|
|
19
|
-
id: "unavailableNetworkTitle",
|
|
20
|
-
defaultMessage: "Network unavailable",
|
|
21
|
-
description: "The title for alert about network unavailable",
|
|
22
|
-
},
|
|
23
|
-
unavailableNetworkMessage: {
|
|
24
|
-
id: "unavailableNetworkMessage",
|
|
25
|
-
defaultMessage: "Check your internet connection and try again later.",
|
|
26
|
-
description: "The message for alert about network unavailable",
|
|
27
|
-
},
|
|
28
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
lightBoxPreviewButton: {
|
|
4
|
-
id: "lightBoxPreviewButton",
|
|
5
|
-
defaultMessage: "Preview {bottomSheetOptionsSuffix}",
|
|
6
|
-
description: "Label for button when preview the file",
|
|
7
|
-
},
|
|
8
|
-
removeButton: {
|
|
9
|
-
id: "removeButton",
|
|
10
|
-
defaultMessage: "Remove {bottomSheetOptionsSuffix}",
|
|
11
|
-
description: "Label for button when remove the file",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
defaultAccessibilityLabel: {
|
|
4
|
-
id: "defaultAccessibilityLabel",
|
|
5
|
-
defaultMessage: "Attachment Preview",
|
|
6
|
-
description: "The default accessibility label",
|
|
7
|
-
},
|
|
8
|
-
defaultAccessibilityHint: {
|
|
9
|
-
id: "defaultAccessibilityHint",
|
|
10
|
-
defaultMessage: "Select for more options",
|
|
11
|
-
description: "The default accessibility hint",
|
|
12
|
-
},
|
|
13
|
-
errorAccessibilityLabel: {
|
|
14
|
-
id: "errorAccessibilityLabel",
|
|
15
|
-
defaultMessage: "Failed upload",
|
|
16
|
-
description: "The accessibility label for error states",
|
|
17
|
-
},
|
|
18
|
-
inProgressAccessibilityLabel: {
|
|
19
|
-
id: "inProgress",
|
|
20
|
-
defaultMessage: "Upload in progress",
|
|
21
|
-
description: "The accessibility label for in-progress states",
|
|
22
|
-
},
|
|
23
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
notANumberError: {
|
|
4
|
-
id: "notANumberError",
|
|
5
|
-
defaultMessage: "Enter a number",
|
|
6
|
-
description: "Error message shown when a non-numeric value is typed in number input",
|
|
7
|
-
},
|
|
8
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
notANumberError: {
|
|
4
|
-
id: "notANumberError",
|
|
5
|
-
defaultMessage: "Enter a number",
|
|
6
|
-
description: "Error message shown when a non-numeric value is typed in number input",
|
|
7
|
-
},
|
|
8
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
complete: {
|
|
4
|
-
id: "complete",
|
|
5
|
-
defaultMessage: "{current} of {total} complete",
|
|
6
|
-
description: "Progress bar accessibilityLabel for current/total",
|
|
7
|
-
},
|
|
8
|
-
inProgress: {
|
|
9
|
-
id: "inProgress",
|
|
10
|
-
defaultMessage: "{inProgress} in progress",
|
|
11
|
-
description: "Progress bar accessibilityLabel for inProgress/total",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
a11yHint: {
|
|
4
|
-
id: "a11yHint",
|
|
5
|
-
defaultMessage: "Select to open the picker",
|
|
6
|
-
description: "Accessibility hint on how to interact with the select",
|
|
7
|
-
},
|
|
8
|
-
emptyValue: {
|
|
9
|
-
id: "emptyValue",
|
|
10
|
-
defaultMessage: "Select an option",
|
|
11
|
-
description: "Accessibility hint on how to interact with the select",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from "react-intl";
|
|
2
|
-
export const messages = defineMessages({
|
|
3
|
-
toastNotificationLabel: {
|
|
4
|
-
id: "toastNotificationLabel",
|
|
5
|
-
defaultMessage: "Toast Notification",
|
|
6
|
-
description: "Accessibility label for the Toast",
|
|
7
|
-
},
|
|
8
|
-
dismissA11yLabel: {
|
|
9
|
-
id: "dismissA11yLabel",
|
|
10
|
-
defaultMessage: "Dismiss toast notification",
|
|
11
|
-
description: "Accessibility label to dismiss the toast when pressing X",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const messages: {
|
|
2
|
-
more: {
|
|
3
|
-
id: string;
|
|
4
|
-
defaultMessage: string;
|
|
5
|
-
description: string;
|
|
6
|
-
};
|
|
7
|
-
unavailableNetworkTitle: {
|
|
8
|
-
id: string;
|
|
9
|
-
defaultMessage: string;
|
|
10
|
-
description: string;
|
|
11
|
-
};
|
|
12
|
-
unavailableNetworkMessage: {
|
|
13
|
-
id: string;
|
|
14
|
-
defaultMessage: string;
|
|
15
|
-
description: string;
|
|
16
|
-
};
|
|
17
|
-
};
|