@jobber/components-native 0.40.0 → 0.41.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 (95) hide show
  1. package/dist/src/FormatFile/FormatFile.js +114 -0
  2. package/dist/src/FormatFile/FormatFile.style.js +16 -0
  3. package/dist/src/FormatFile/components/ErrorIcon/ErrorIcon.js +8 -0
  4. package/dist/src/FormatFile/components/ErrorIcon/ErrorIcon.style.js +10 -0
  5. package/dist/src/FormatFile/components/ErrorIcon/index.js +1 -0
  6. package/dist/src/FormatFile/components/FileView/FileView.js +67 -0
  7. package/dist/src/FormatFile/components/FileView/FileView.style.js +64 -0
  8. package/dist/src/FormatFile/components/FileView/index.js +1 -0
  9. package/dist/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.js +22 -0
  10. package/dist/src/FormatFile/components/FormatFileBottomSheet/index.js +1 -0
  11. package/dist/src/FormatFile/components/FormatFileBottomSheet/messages.js +13 -0
  12. package/dist/src/FormatFile/components/MediaView/MediaView.js +56 -0
  13. package/dist/src/FormatFile/components/MediaView/MediaView.style.js +27 -0
  14. package/dist/src/FormatFile/components/MediaView/index.js +1 -0
  15. package/dist/src/FormatFile/components/ProgressBar/ProgressBar.js +29 -0
  16. package/dist/src/FormatFile/components/ProgressBar/ProgressBar.style.js +15 -0
  17. package/dist/src/FormatFile/components/ProgressBar/index.js +1 -0
  18. package/dist/src/FormatFile/components/_mocks/mockFiles.js +78 -0
  19. package/dist/src/FormatFile/constants.js +14 -0
  20. package/dist/src/FormatFile/context/FormatFileContext.js +8 -0
  21. package/dist/src/FormatFile/context/types.js +1 -0
  22. package/dist/src/FormatFile/index.js +1 -0
  23. package/dist/src/FormatFile/messages.js +23 -0
  24. package/dist/src/FormatFile/types.js +8 -0
  25. package/dist/src/FormatFile/utils/computeA11yLabel.js +12 -0
  26. package/dist/src/FormatFile/utils/createUseCreateThumbnail.js +22 -0
  27. package/dist/src/FormatFile/utils/index.js +1 -0
  28. package/dist/src/InputText/InputText.js +8 -1
  29. package/dist/src/index.js +1 -0
  30. package/dist/src/utils/test/wait.js +1 -1
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/dist/types/src/Form/components/FormMessage/FormMessage.d.ts +1 -0
  33. package/dist/types/src/FormatFile/FormatFile.d.ts +47 -0
  34. package/dist/types/src/FormatFile/FormatFile.style.d.ts +14 -0
  35. package/dist/types/src/FormatFile/components/ErrorIcon/ErrorIcon.d.ts +2 -0
  36. package/dist/types/src/FormatFile/components/ErrorIcon/ErrorIcon.style.d.ts +8 -0
  37. package/dist/types/src/FormatFile/components/ErrorIcon/index.d.ts +1 -0
  38. package/dist/types/src/FormatFile/components/FileView/FileView.d.ts +12 -0
  39. package/dist/types/src/FormatFile/components/FileView/FileView.style.d.ts +62 -0
  40. package/dist/types/src/FormatFile/components/FileView/index.d.ts +1 -0
  41. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.d.ts +11 -0
  42. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/index.d.ts +2 -0
  43. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/messages.d.ts +12 -0
  44. package/dist/types/src/FormatFile/components/MediaView/MediaView.d.ts +12 -0
  45. package/dist/types/src/FormatFile/components/MediaView/MediaView.style.d.ts +25 -0
  46. package/dist/types/src/FormatFile/components/MediaView/index.d.ts +1 -0
  47. package/dist/types/src/FormatFile/components/ProgressBar/ProgressBar.d.ts +19 -0
  48. package/dist/types/src/FormatFile/components/ProgressBar/ProgressBar.style.d.ts +13 -0
  49. package/dist/types/src/FormatFile/components/ProgressBar/index.d.ts +1 -0
  50. package/dist/types/src/FormatFile/components/_mocks/mockFiles.d.ts +18 -0
  51. package/dist/types/src/FormatFile/constants.d.ts +6 -0
  52. package/dist/types/src/FormatFile/context/FormatFileContext.d.ts +10 -0
  53. package/dist/types/src/FormatFile/context/types.d.ts +9 -0
  54. package/dist/types/src/FormatFile/index.d.ts +3 -0
  55. package/dist/types/src/FormatFile/messages.d.ts +22 -0
  56. package/dist/types/src/FormatFile/types.d.ts +105 -0
  57. package/dist/types/src/FormatFile/utils/computeA11yLabel.d.ts +9 -0
  58. package/dist/types/src/FormatFile/utils/createUseCreateThumbnail.d.ts +5 -0
  59. package/dist/types/src/FormatFile/utils/index.d.ts +1 -0
  60. package/dist/types/src/InputCurrency/InputCurrency.d.ts +1 -1
  61. package/dist/types/src/index.d.ts +1 -0
  62. package/package.json +3 -2
  63. package/src/FormatFile/FormatFile.style.ts +17 -0
  64. package/src/FormatFile/FormatFile.test.tsx +333 -0
  65. package/src/FormatFile/FormatFile.tsx +300 -0
  66. package/src/FormatFile/components/ErrorIcon/ErrorIcon.style.ts +11 -0
  67. package/src/FormatFile/components/ErrorIcon/ErrorIcon.tsx +12 -0
  68. package/src/FormatFile/components/ErrorIcon/index.ts +1 -0
  69. package/src/FormatFile/components/FileView/FileView.style.ts +65 -0
  70. package/src/FormatFile/components/FileView/FileView.tsx +134 -0
  71. package/src/FormatFile/components/FileView/index.ts +1 -0
  72. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.tsx +108 -0
  73. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +56 -0
  74. package/src/FormatFile/components/FormatFileBottomSheet/index.ts +2 -0
  75. package/src/FormatFile/components/FormatFileBottomSheet/messages.ts +14 -0
  76. package/src/FormatFile/components/MediaView/MediaView.style.ts +28 -0
  77. package/src/FormatFile/components/MediaView/MediaView.tsx +145 -0
  78. package/src/FormatFile/components/MediaView/index.ts +1 -0
  79. package/src/FormatFile/components/ProgressBar/ProgressBar.style.tsx +16 -0
  80. package/src/FormatFile/components/ProgressBar/ProgressBar.tsx +57 -0
  81. package/src/FormatFile/components/ProgressBar/index.ts +1 -0
  82. package/src/FormatFile/components/_mocks/mockFiles.ts +105 -0
  83. package/src/FormatFile/constants.ts +15 -0
  84. package/src/FormatFile/context/FormatFileContext.ts +13 -0
  85. package/src/FormatFile/context/types.ts +12 -0
  86. package/src/FormatFile/index.ts +13 -0
  87. package/src/FormatFile/messages.ts +24 -0
  88. package/src/FormatFile/types.ts +126 -0
  89. package/src/FormatFile/utils/computeA11yLabel.ts +26 -0
  90. package/src/FormatFile/utils/createUseCreateThumbnail.ts +33 -0
  91. package/src/FormatFile/utils/index.ts +1 -0
  92. package/src/InputCurrency/InputCurrency.tsx +1 -1
  93. package/src/InputText/InputText.tsx +8 -1
  94. package/src/index.ts +1 -0
  95. package/src/utils/test/wait.ts +3 -1
@@ -0,0 +1,105 @@
1
+ import { v4 } from "react-native-uuid";
2
+ import { File, FileUpload, StatusCode } from "../../types";
3
+
4
+ export const FILE_UPLOAD_MOCK_FILE = ({
5
+ progress,
6
+ status = StatusCode.InProgress,
7
+ }: {
8
+ progress: number;
9
+ status?: StatusCode;
10
+ }): FileUpload => ({
11
+ batchContext: {
12
+ batchCount: 1,
13
+ batchId: "FILES",
14
+ },
15
+ uuid: v4(),
16
+ key: "path/test.txt",
17
+ name: "test.txt",
18
+ size: 1,
19
+ type: "application/txt",
20
+ progress: progress,
21
+ status: status,
22
+ sourcePath: "path/test.txt",
23
+ uploadUrl: "uploadUrl",
24
+ cancel: jest.fn(),
25
+ });
26
+
27
+ export const FILE_UPLOAD_MOCK_IMAGE = ({
28
+ progress,
29
+ size,
30
+ status = StatusCode.InProgress,
31
+ }: {
32
+ progress: number;
33
+ size?: number;
34
+ status?: StatusCode;
35
+ }): FileUpload => ({
36
+ batchContext: {
37
+ batchCount: 1,
38
+ batchId: "IMAGES",
39
+ },
40
+ uuid: v4(),
41
+ key: "path/test.png",
42
+ name: "test.png",
43
+ size: size || 1,
44
+ type: "image/png",
45
+ progress: progress,
46
+ status: status,
47
+ sourcePath: "path/test.png",
48
+ uploadUrl: "uploadUrl",
49
+ cancel: jest.fn(),
50
+ });
51
+
52
+ export const FILE_UPLOAD_MOCK_PDF = ({
53
+ progress,
54
+ status = StatusCode.InProgress,
55
+ }: {
56
+ progress: number;
57
+ status?: StatusCode;
58
+ }): FileUpload => ({
59
+ batchContext: {
60
+ batchCount: 1,
61
+ batchId: "FILES",
62
+ },
63
+ uuid: v4(),
64
+ key: "path/test.pdf",
65
+ name: "test.pdf",
66
+ size: 1,
67
+ type: "file/pdf",
68
+ progress: progress,
69
+ status: status,
70
+ sourcePath: "path/test.pdf",
71
+ uploadUrl: "uploadUrl",
72
+ cancel: jest.fn(),
73
+ });
74
+
75
+ export const FILE_MOCK_PDF: File = {
76
+ fileName: "some_file.pdf",
77
+ fileSize: 1,
78
+ contentType: "pdf",
79
+ url: "https://path/to/file.pdf",
80
+ thumbnailUrl: "https://path/to/fileThumbnail.pdf",
81
+ };
82
+
83
+ export const FILE_MOCK_VIDEO: File = {
84
+ fileName: "some_file.mp4",
85
+ fileSize: 1,
86
+ contentType: "video",
87
+ url: undefined, //undefined to prevent thumbnail errors
88
+ thumbnailUrl: "path/to/fileThumbnail.mp4",
89
+ };
90
+
91
+ export const FILE_MOCK_FILE: File = {
92
+ fileName: "some_file.txt",
93
+ fileSize: 1,
94
+ contentType: "file",
95
+ url: "https://path/to/file",
96
+ thumbnailUrl: "https://path/to/fileThumbnail",
97
+ };
98
+
99
+ export const FILE_MOCK_IMAGE: File = {
100
+ fileName: "some_image.jpg",
101
+ fileSize: 1,
102
+ contentType: "image/jpg",
103
+ url: "https://path/to/image",
104
+ thumbnailUrl: "https://path/to/imageThumbnail",
105
+ };
@@ -0,0 +1,15 @@
1
+ export const acceptedExtensions = [
2
+ { name: "video" },
3
+ { name: "pdf" },
4
+ { name: "mov" },
5
+ { name: "mp4" },
6
+ { name: "docx" },
7
+ { name: "xlsx" },
8
+ ];
9
+
10
+ export const videoExtensions = [
11
+ { type: "mov" },
12
+ { type: "mp4" },
13
+ { type: "3gpp" },
14
+ { type: "hevc" },
15
+ ];
@@ -0,0 +1,13 @@
1
+ import { createContext, useContext } from "react";
2
+ import { AtlantisFormatFileContextProps } from "./types";
3
+
4
+ export const formatFileContextDefaultValues = {
5
+ useCreateThumbnail: () => ({ thumbnail: undefined, error: false }),
6
+ };
7
+
8
+ export const AtlantisFormatFileContext =
9
+ createContext<AtlantisFormatFileContextProps>(formatFileContextDefaultValues);
10
+
11
+ export function useAtlantisFormatFileContext(): AtlantisFormatFileContextProps {
12
+ return useContext(AtlantisFormatFileContext);
13
+ }
@@ -0,0 +1,12 @@
1
+ import { FormattedFile } from "../types";
2
+
3
+ export interface UseCreateThumbnailResponse {
4
+ readonly thumbnail: string | undefined;
5
+ readonly error: boolean;
6
+ }
7
+ export type UseCreateThumbnail = (
8
+ formattedFile: FormattedFile,
9
+ ) => UseCreateThumbnailResponse;
10
+ export interface AtlantisFormatFileContextProps {
11
+ useCreateThumbnail: UseCreateThumbnail;
12
+ }
@@ -0,0 +1,13 @@
1
+ export { FormatFile, FormatFileProps } from "./FormatFile";
2
+ export type {
3
+ FormattedFile,
4
+ File,
5
+ CreateThumbnail,
6
+ CreateThumbnailResponse,
7
+ FileUpload,
8
+ StatusCode,
9
+ } from "./types";
10
+ export type {
11
+ UseCreateThumbnail,
12
+ UseCreateThumbnailResponse,
13
+ } from "./context/types";
@@ -0,0 +1,24 @@
1
+ import { defineMessages } from "react-intl";
2
+
3
+ export const messages = defineMessages({
4
+ defaultAccessibilityLabel: {
5
+ id: "defaultAccessibilityLabel",
6
+ defaultMessage: "Attachment Preview",
7
+ description: "The default accessibility label",
8
+ },
9
+ defaultAccessibilityHint: {
10
+ id: "defaultAccessibilityHint",
11
+ defaultMessage: "Select for more options",
12
+ description: "The default accessibility hint",
13
+ },
14
+ errorAccessibilityLabel: {
15
+ id: "errorAccessibilityLabel",
16
+ defaultMessage: "Failed upload",
17
+ description: "The accessibility label for error states",
18
+ },
19
+ inProgressAccessibilityLabel: {
20
+ id: "inProgress",
21
+ defaultMessage: "Upload in progress",
22
+ description: "The accessibility label for in-progress states",
23
+ },
24
+ });
@@ -0,0 +1,126 @@
1
+ export enum StatusCode {
2
+ Pending,
3
+ Started,
4
+ InProgress,
5
+ Completed,
6
+ Failed,
7
+ }
8
+
9
+ export interface FileUpload {
10
+ /**
11
+ * File Identifier
12
+ */
13
+ key?: string;
14
+
15
+ /**
16
+ * Universally unique identifier
17
+ */
18
+ readonly uuid: string;
19
+
20
+ /**
21
+ * The name of the file.
22
+ */
23
+ readonly name: string;
24
+
25
+ /**
26
+ * The [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) type of the file
27
+ */
28
+ readonly type: string;
29
+
30
+ /**
31
+ * The size of the file in bytes.
32
+ */
33
+ readonly size: number;
34
+
35
+ /**
36
+ * The progress of a file upload between 0 and 1.
37
+ * - `0` represents Upload just started.
38
+ * - `1` represents a complete upload.
39
+ */
40
+ readonly progress: number;
41
+
42
+ /**
43
+ * The upload status of the file
44
+ */
45
+
46
+ status: StatusCode;
47
+
48
+ /**
49
+ * Represents the width and height for images
50
+ */
51
+ readonly dimension?: {
52
+ width: number;
53
+ height: number;
54
+ };
55
+
56
+ /**
57
+ * Provides context about multi-file upload batch
58
+ */
59
+ readonly batchContext: {
60
+ /**
61
+ * Batch id
62
+ */
63
+ readonly batchId: string;
64
+
65
+ /**
66
+ * Number of files in batch
67
+ */
68
+ readonly batchCount: number;
69
+ };
70
+
71
+ /**
72
+ * Url file was uploaded to, used to send in mutation to JO
73
+ */
74
+ uploadUrl?: string;
75
+
76
+ /**
77
+ * The url of the file.
78
+ */
79
+ sourcePath: string;
80
+
81
+ /**
82
+ * Cancel uploading this file
83
+ */
84
+ cancel: () => void;
85
+
86
+ /**
87
+ * Number of retries to upload
88
+ */
89
+ retries?: number;
90
+
91
+ /**
92
+ * Error message when upload fails
93
+ */
94
+ errorMessage?: string;
95
+ }
96
+
97
+ export interface File {
98
+ contentType?: string;
99
+ fileName?: string;
100
+ thumbnailUrl?: string;
101
+ url?: string;
102
+ fileSize: number;
103
+ }
104
+
105
+ export interface FormattedFile {
106
+ showPreview: boolean;
107
+ source?: string;
108
+ thumbnailUrl?: string;
109
+ name?: string;
110
+ size: number;
111
+ external: boolean;
112
+ progress: number;
113
+ status: StatusCode;
114
+ error: boolean;
115
+ type?: string;
116
+ isMedia?: boolean;
117
+ showFileTypeIndicator: boolean;
118
+ }
119
+
120
+ export interface CreateThumbnailResponse {
121
+ readonly thumbnail: string | undefined;
122
+ readonly error: boolean;
123
+ }
124
+ export type CreateThumbnail = (
125
+ formattedFile: FormattedFile,
126
+ ) => Promise<CreateThumbnailResponse>;
@@ -0,0 +1,26 @@
1
+ import { MessageDescriptor } from "react-intl";
2
+ import { messages } from "../messages";
3
+
4
+ interface params {
5
+ accessibilityLabel?: string;
6
+ showOverlay: boolean;
7
+ showError: boolean;
8
+ formatMessage: (message: MessageDescriptor) => string;
9
+ }
10
+
11
+ export function computeA11yLabel({
12
+ accessibilityLabel,
13
+ showOverlay,
14
+ showError,
15
+ formatMessage,
16
+ }: params): string {
17
+ if (!showError && showOverlay) {
18
+ return formatMessage(messages.inProgressAccessibilityLabel);
19
+ } else if (showError) {
20
+ return formatMessage(messages.errorAccessibilityLabel);
21
+ } else {
22
+ return (
23
+ accessibilityLabel || formatMessage(messages.defaultAccessibilityLabel)
24
+ );
25
+ }
26
+ }
@@ -0,0 +1,33 @@
1
+ import { useIsMounted } from "@jobber/hooks/useIsMounted";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { UseCreateThumbnail } from "../context/types";
4
+ import { CreateThumbnail, FormattedFile } from "../types";
5
+
6
+ export function createUseCreateThumbnail(createThumbnail: CreateThumbnail): {
7
+ useCreateThumbnail: UseCreateThumbnail;
8
+ } {
9
+ const useCreateThumbnail = useCallback(
10
+ (file: FormattedFile) => {
11
+ const [thumbnail, setThumbnail] = useState<string | undefined>(undefined);
12
+ const [error, setError] = useState<boolean>(false);
13
+
14
+ const { current } = useIsMounted();
15
+
16
+ useEffect(() => {
17
+ createThumbnail(file)
18
+ .then(({ thumbnail: newThumbnail, error: newError }) => {
19
+ setThumbnail(newThumbnail);
20
+ setError(newError);
21
+ })
22
+ .catch(() => {
23
+ setError(true);
24
+ setThumbnail(undefined);
25
+ });
26
+ }, [current, file]);
27
+
28
+ return { thumbnail, error };
29
+ },
30
+ [createThumbnail],
31
+ );
32
+ return { useCreateThumbnail };
33
+ }
@@ -0,0 +1 @@
1
+ export { computeA11yLabel } from "./computeA11yLabel";
@@ -54,7 +54,7 @@ export const getInternalValue = (
54
54
  props: InputCurrencyProps,
55
55
  field: ControllerRenderProps<FieldValues, string>,
56
56
  formatNumber: (
57
- value: number | bigint,
57
+ value: number,
58
58
  opts?: FormatNumberOptions | undefined,
59
59
  ) => string,
60
60
  ): string => {
@@ -267,6 +267,7 @@ function InputTextInternal(
267
267
  ref: Ref<InputTextRef>,
268
268
  ) {
269
269
  const isAndroid = Platform.OS === "android";
270
+ const isIOS = Platform.OS === "ios";
270
271
 
271
272
  const {
272
273
  input: inputTransform = identity,
@@ -419,7 +420,13 @@ function InputTextInternal(
419
420
  );
420
421
 
421
422
  function handleChangeText(value: string) {
422
- const newValue = outputTransform(value);
423
+ /**
424
+ * Replacing the U+FFFC character because it's duplicating text
425
+ * when dictating on iOS 16.
426
+ * https://github.com/facebook/react-native/issues/36521#issuecomment-1555421134
427
+ */
428
+ const removedIOSCharValue = isIOS ? value.replace(/\uFFFC/g, "") : value;
429
+ const newValue = outputTransform(removedIOSCharValue);
423
430
  setHasMiniLabel(Boolean(newValue));
424
431
  onChangeText?.(newValue);
425
432
  field.onChange(newValue);
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export * from "./Divider";
16
16
  export * from "./EmptyState";
17
17
  export * from "./ErrorMessageWrapper";
18
18
  export * from "./Flex";
19
+ export * from "./FormatFile";
19
20
  export * from "./Form";
20
21
  export * from "./FormField";
21
22
  export * from "./Heading";
@@ -10,7 +10,9 @@ import { act } from "react-test-renderer";
10
10
  * @param milliseconds time to wait in milliseconds
11
11
  */
12
12
  export async function wait(milliseconds = 0): Promise<void> {
13
- await new Promise(resolve => setTimeout(resolve, milliseconds));
13
+ await new Promise((resolve: (value?: unknown) => void) =>
14
+ setTimeout(resolve, milliseconds),
15
+ );
14
16
  }
15
17
 
16
18
  /**