@jobber/components-native 0.13.0 → 0.14.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/src/ProgressBar/ProgressBar.js +21 -0
- package/dist/src/ProgressBar/ProgressBar.style.js +24 -0
- package/dist/src/ProgressBar/ProgressBarInner.js +29 -0
- package/dist/src/ProgressBar/index.js +1 -0
- package/dist/src/ProgressBar/messages.js +13 -0
- package/dist/src/ProgressBar/types.js +1 -0
- package/dist/src/index.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/src/ProgressBar/ProgressBar.d.ts +3 -0
- package/dist/types/src/ProgressBar/ProgressBar.style.d.ts +22 -0
- package/dist/types/src/ProgressBar/ProgressBarInner.d.ts +9 -0
- package/dist/types/src/ProgressBar/index.d.ts +2 -0
- package/dist/types/src/ProgressBar/messages.d.ts +12 -0
- package/dist/types/src/ProgressBar/types.d.ts +28 -0
- package/dist/types/src/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/ProgressBar/ProgressBar.style.ts +25 -0
- package/src/ProgressBar/ProgressBar.test.tsx +41 -0
- package/src/ProgressBar/ProgressBar.tsx +58 -0
- package/src/ProgressBar/ProgressBarInner.tsx +47 -0
- package/src/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap +138 -0
- package/src/ProgressBar/index.tsx +2 -0
- package/src/ProgressBar/messages.ts +14 -0
- package/src/ProgressBar/types.ts +34 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const styles: {
|
|
2
|
+
progressBarContainer: {
|
|
3
|
+
marginTop: number;
|
|
4
|
+
marginBottom: number;
|
|
5
|
+
height: number;
|
|
6
|
+
position: "relative";
|
|
7
|
+
flexDirection: "row";
|
|
8
|
+
};
|
|
9
|
+
progressBarInner: {
|
|
10
|
+
backgroundColor: string;
|
|
11
|
+
width: string;
|
|
12
|
+
height: string;
|
|
13
|
+
position: "absolute";
|
|
14
|
+
left: number;
|
|
15
|
+
top: number;
|
|
16
|
+
borderRadius: number;
|
|
17
|
+
};
|
|
18
|
+
progressInner: {
|
|
19
|
+
height: string;
|
|
20
|
+
borderRadius: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface ProgressBarInnerProps {
|
|
3
|
+
readonly width: number;
|
|
4
|
+
readonly animationDuration?: number;
|
|
5
|
+
readonly color?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ProgressBarInner({ width, color, }: ProgressBarInnerProps): JSX.Element;
|
|
8
|
+
export declare function calculateWidth(total: number, current: number): number;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export interface ProgressBarProps {
|
|
3
|
+
/**
|
|
4
|
+
* The total number of items to be completed
|
|
5
|
+
*/
|
|
6
|
+
readonly total: number;
|
|
7
|
+
/**
|
|
8
|
+
* The number of items that are currently completed
|
|
9
|
+
*/
|
|
10
|
+
readonly current: number;
|
|
11
|
+
/**
|
|
12
|
+
* The number of items in progress (not completed, but to be less than the total)
|
|
13
|
+
*/
|
|
14
|
+
readonly inProgress?: number;
|
|
15
|
+
/**
|
|
16
|
+
* If the progress bar is loading, the progress indicators aren't rendered on the screen
|
|
17
|
+
*/
|
|
18
|
+
readonly loading?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* If the amountFormatted and totalAmountFormatted text needs to appear more visibile because of the
|
|
21
|
+
* background, for example
|
|
22
|
+
*/
|
|
23
|
+
readonly reverseTheme?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Component to render above the progress bar.
|
|
26
|
+
*/
|
|
27
|
+
readonly header?: ReactNode;
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"module": "dist/src/index.js",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"react": "^18",
|
|
48
48
|
"react-native": ">=0.69.2"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "7237667e48edeb962f88a75bacaaca79e510f415"
|
|
51
51
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { tokens } from "../utils/design";
|
|
3
|
+
|
|
4
|
+
export const styles = StyleSheet.create({
|
|
5
|
+
progressBarContainer: {
|
|
6
|
+
marginTop: tokens["space-small"],
|
|
7
|
+
marginBottom: tokens["space-small"],
|
|
8
|
+
height: 20,
|
|
9
|
+
position: "relative",
|
|
10
|
+
flexDirection: "row",
|
|
11
|
+
},
|
|
12
|
+
progressBarInner: {
|
|
13
|
+
backgroundColor: "rgba(255,255,255,0.3)",
|
|
14
|
+
width: "100%",
|
|
15
|
+
height: "100%",
|
|
16
|
+
position: "absolute",
|
|
17
|
+
left: 0,
|
|
18
|
+
top: 0,
|
|
19
|
+
borderRadius: 100,
|
|
20
|
+
},
|
|
21
|
+
progressInner: {
|
|
22
|
+
height: "100%",
|
|
23
|
+
borderRadius: 100,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
|
+
import { ProgressBar, ProgressBarProps } from ".";
|
|
4
|
+
|
|
5
|
+
const defaultSetupProps = {
|
|
6
|
+
total: 0,
|
|
7
|
+
current: 0,
|
|
8
|
+
inProgress: 0,
|
|
9
|
+
loading: false,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ProgressBarCombinedProps = ProgressBarProps;
|
|
13
|
+
|
|
14
|
+
function renderProgressBarComponent({
|
|
15
|
+
total,
|
|
16
|
+
current,
|
|
17
|
+
inProgress,
|
|
18
|
+
}: ProgressBarCombinedProps) {
|
|
19
|
+
return render(
|
|
20
|
+
<ProgressBar total={total} current={current} inProgress={inProgress} />,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
it("renders blue inProgress bar when 1 or more jobs is in progress", () => {
|
|
25
|
+
const bar = renderProgressBarComponent({
|
|
26
|
+
...defaultSetupProps,
|
|
27
|
+
inProgress: 1,
|
|
28
|
+
}).toJSON();
|
|
29
|
+
expect(bar).toMatchSnapshot();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("renders green CompletedProgress bar when 1 or more jobs is completed", () => {
|
|
33
|
+
const current = 1;
|
|
34
|
+
const bar = renderProgressBarComponent({
|
|
35
|
+
...defaultSetupProps,
|
|
36
|
+
current: current,
|
|
37
|
+
total: 2,
|
|
38
|
+
});
|
|
39
|
+
expect(bar).toMatchSnapshot();
|
|
40
|
+
expect(bar.getByLabelText("1 of 2 complete")).toBeDefined();
|
|
41
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { useIntl } from "react-intl";
|
|
4
|
+
import { ProgressBarProps } from "./types";
|
|
5
|
+
import { styles } from "./ProgressBar.style";
|
|
6
|
+
import { ProgressBarInner, calculateWidth } from "./ProgressBarInner";
|
|
7
|
+
import { messages } from "./messages";
|
|
8
|
+
import { tokens } from "../utils/design";
|
|
9
|
+
|
|
10
|
+
export function ProgressBar({
|
|
11
|
+
loading,
|
|
12
|
+
total,
|
|
13
|
+
current,
|
|
14
|
+
inProgress = 0,
|
|
15
|
+
reverseTheme = false,
|
|
16
|
+
header,
|
|
17
|
+
}: ProgressBarProps): JSX.Element {
|
|
18
|
+
const { formatMessage } = useIntl();
|
|
19
|
+
const accessibilityLabel = [];
|
|
20
|
+
accessibilityLabel.push(formatMessage(messages.complete, { current, total }));
|
|
21
|
+
inProgress &&
|
|
22
|
+
accessibilityLabel.push(formatMessage(messages.inProgress, { inProgress }));
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<View
|
|
26
|
+
accessible
|
|
27
|
+
accessibilityRole="progressbar"
|
|
28
|
+
accessibilityLabel={accessibilityLabel.join(", ")}
|
|
29
|
+
>
|
|
30
|
+
{header}
|
|
31
|
+
<View style={styles.progressBarContainer}>
|
|
32
|
+
<ProgressBarInner
|
|
33
|
+
width={100}
|
|
34
|
+
animationDuration={0}
|
|
35
|
+
color={reverseTheme ? undefined : tokens["color-surface--background"]}
|
|
36
|
+
/>
|
|
37
|
+
{!loading && (
|
|
38
|
+
<>
|
|
39
|
+
{inProgress && inProgress > 0 ? (
|
|
40
|
+
<ProgressBarInner
|
|
41
|
+
width={calculateWidth(total, current + inProgress)}
|
|
42
|
+
color={tokens["color-informative"]}
|
|
43
|
+
animationDuration={800}
|
|
44
|
+
/>
|
|
45
|
+
) : (
|
|
46
|
+
<></>
|
|
47
|
+
)}
|
|
48
|
+
<ProgressBarInner
|
|
49
|
+
width={calculateWidth(total, current)}
|
|
50
|
+
color={tokens["color-interactive"]}
|
|
51
|
+
animationDuration={600}
|
|
52
|
+
/>
|
|
53
|
+
</>
|
|
54
|
+
)}
|
|
55
|
+
</View>
|
|
56
|
+
</View>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
// import Reanimated from "react-native-reanimated";
|
|
4
|
+
// import { useTiming } from "utils/reanimated";
|
|
5
|
+
import { styles } from "./ProgressBar.style";
|
|
6
|
+
|
|
7
|
+
interface ProgressBarInnerProps {
|
|
8
|
+
readonly width: number;
|
|
9
|
+
readonly animationDuration?: number;
|
|
10
|
+
readonly color?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ProgressBarInner({
|
|
14
|
+
width,
|
|
15
|
+
// animationDuration = 0,
|
|
16
|
+
color,
|
|
17
|
+
}: ProgressBarInnerProps): JSX.Element {
|
|
18
|
+
// Animation breaking on Android
|
|
19
|
+
// const [animatedOpacity] = useTiming({
|
|
20
|
+
// duration: animationDuration,
|
|
21
|
+
// fromValue: 0,
|
|
22
|
+
// toValue: 1,
|
|
23
|
+
// });
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<View
|
|
27
|
+
style={[
|
|
28
|
+
styles.progressBarInner,
|
|
29
|
+
{
|
|
30
|
+
width: `${width}%`,
|
|
31
|
+
// opacity: animatedOpacity,
|
|
32
|
+
...(color && { backgroundColor: color }),
|
|
33
|
+
},
|
|
34
|
+
]}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function calculateWidth(total: number, current: number): number {
|
|
40
|
+
if (total <= 0) return 0;
|
|
41
|
+
if (current >= total) return 100;
|
|
42
|
+
|
|
43
|
+
const curr = Math.max(0, current);
|
|
44
|
+
|
|
45
|
+
if (curr >= total) return 100;
|
|
46
|
+
return (curr / total) * 100;
|
|
47
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`renders blue inProgress bar when 1 or more jobs is in progress 1`] = `
|
|
4
|
+
<View
|
|
5
|
+
accessibilityLabel="0 of 0 complete, 1 in progress"
|
|
6
|
+
accessibilityRole="progressbar"
|
|
7
|
+
accessible={true}
|
|
8
|
+
>
|
|
9
|
+
<View
|
|
10
|
+
style={
|
|
11
|
+
{
|
|
12
|
+
"flexDirection": "row",
|
|
13
|
+
"height": 20,
|
|
14
|
+
"marginBottom": 8,
|
|
15
|
+
"marginTop": 8,
|
|
16
|
+
"position": "relative",
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
>
|
|
20
|
+
<View
|
|
21
|
+
style={
|
|
22
|
+
[
|
|
23
|
+
{
|
|
24
|
+
"backgroundColor": "rgba(255,255,255,0.3)",
|
|
25
|
+
"borderRadius": 100,
|
|
26
|
+
"height": "100%",
|
|
27
|
+
"left": 0,
|
|
28
|
+
"position": "absolute",
|
|
29
|
+
"top": 0,
|
|
30
|
+
"width": "100%",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"backgroundColor": "rgb(244, 244, 244)",
|
|
34
|
+
"width": "100%",
|
|
35
|
+
},
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
/>
|
|
39
|
+
<View
|
|
40
|
+
style={
|
|
41
|
+
[
|
|
42
|
+
{
|
|
43
|
+
"backgroundColor": "rgba(255,255,255,0.3)",
|
|
44
|
+
"borderRadius": 100,
|
|
45
|
+
"height": "100%",
|
|
46
|
+
"left": 0,
|
|
47
|
+
"position": "absolute",
|
|
48
|
+
"top": 0,
|
|
49
|
+
"width": "100%",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"backgroundColor": "rgb(60, 162, 224)",
|
|
53
|
+
"width": "0%",
|
|
54
|
+
},
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
/>
|
|
58
|
+
<View
|
|
59
|
+
style={
|
|
60
|
+
[
|
|
61
|
+
{
|
|
62
|
+
"backgroundColor": "rgba(255,255,255,0.3)",
|
|
63
|
+
"borderRadius": 100,
|
|
64
|
+
"height": "100%",
|
|
65
|
+
"left": 0,
|
|
66
|
+
"position": "absolute",
|
|
67
|
+
"top": 0,
|
|
68
|
+
"width": "100%",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"backgroundColor": "rgb(125, 176, 14)",
|
|
72
|
+
"width": "0%",
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
</View>
|
|
78
|
+
</View>
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
exports[`renders green CompletedProgress bar when 1 or more jobs is completed 1`] = `
|
|
82
|
+
<View
|
|
83
|
+
accessibilityLabel="1 of 2 complete"
|
|
84
|
+
accessibilityRole="progressbar"
|
|
85
|
+
accessible={true}
|
|
86
|
+
>
|
|
87
|
+
<View
|
|
88
|
+
style={
|
|
89
|
+
{
|
|
90
|
+
"flexDirection": "row",
|
|
91
|
+
"height": 20,
|
|
92
|
+
"marginBottom": 8,
|
|
93
|
+
"marginTop": 8,
|
|
94
|
+
"position": "relative",
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
>
|
|
98
|
+
<View
|
|
99
|
+
style={
|
|
100
|
+
[
|
|
101
|
+
{
|
|
102
|
+
"backgroundColor": "rgba(255,255,255,0.3)",
|
|
103
|
+
"borderRadius": 100,
|
|
104
|
+
"height": "100%",
|
|
105
|
+
"left": 0,
|
|
106
|
+
"position": "absolute",
|
|
107
|
+
"top": 0,
|
|
108
|
+
"width": "100%",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"backgroundColor": "rgb(244, 244, 244)",
|
|
112
|
+
"width": "100%",
|
|
113
|
+
},
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
/>
|
|
117
|
+
<View
|
|
118
|
+
style={
|
|
119
|
+
[
|
|
120
|
+
{
|
|
121
|
+
"backgroundColor": "rgba(255,255,255,0.3)",
|
|
122
|
+
"borderRadius": 100,
|
|
123
|
+
"height": "100%",
|
|
124
|
+
"left": 0,
|
|
125
|
+
"position": "absolute",
|
|
126
|
+
"top": 0,
|
|
127
|
+
"width": "100%",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"backgroundColor": "rgb(125, 176, 14)",
|
|
131
|
+
"width": "50%",
|
|
132
|
+
},
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
/>
|
|
136
|
+
</View>
|
|
137
|
+
</View>
|
|
138
|
+
`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineMessages } from "react-intl";
|
|
2
|
+
|
|
3
|
+
export const messages = defineMessages({
|
|
4
|
+
complete: {
|
|
5
|
+
id: "complete",
|
|
6
|
+
defaultMessage: "{current} of {total} complete",
|
|
7
|
+
description: "Progress bar accessibilityLabel for current/total",
|
|
8
|
+
},
|
|
9
|
+
inProgress: {
|
|
10
|
+
id: "inProgress",
|
|
11
|
+
defaultMessage: "{inProgress} in progress",
|
|
12
|
+
description: "Progress bar accessibilityLabel for inProgress/total",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export interface ProgressBarProps {
|
|
4
|
+
/**
|
|
5
|
+
* The total number of items to be completed
|
|
6
|
+
*/
|
|
7
|
+
readonly total: number;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The number of items that are currently completed
|
|
11
|
+
*/
|
|
12
|
+
readonly current: number;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The number of items in progress (not completed, but to be less than the total)
|
|
16
|
+
*/
|
|
17
|
+
readonly inProgress?: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* If the progress bar is loading, the progress indicators aren't rendered on the screen
|
|
21
|
+
*/
|
|
22
|
+
readonly loading?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* If the amountFormatted and totalAmountFormatted text needs to appear more visibile because of the
|
|
26
|
+
* background, for example
|
|
27
|
+
*/
|
|
28
|
+
readonly reverseTheme?: boolean;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Component to render above the progress bar.
|
|
32
|
+
*/
|
|
33
|
+
readonly header?: ReactNode;
|
|
34
|
+
}
|