@jobber/components-native 0.13.0 → 0.15.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 (53) hide show
  1. package/dist/src/ActionItem/ActionItem.js +37 -0
  2. package/dist/src/ActionItem/ActionItem.style.js +23 -0
  3. package/dist/src/ActionItem/ActionItemGroup.js +19 -0
  4. package/dist/src/ActionItem/components/ActionItemContainer.js +14 -0
  5. package/dist/src/ActionItem/components/ActionItemContainer.style.js +12 -0
  6. package/dist/src/ActionItem/index.js +2 -0
  7. package/dist/src/Button/Button.js +0 -1
  8. package/dist/src/Card/Card.js +0 -1
  9. package/dist/src/ProgressBar/ProgressBar.js +21 -0
  10. package/dist/src/ProgressBar/ProgressBar.style.js +24 -0
  11. package/dist/src/ProgressBar/ProgressBarInner.js +29 -0
  12. package/dist/src/ProgressBar/index.js +1 -0
  13. package/dist/src/ProgressBar/messages.js +13 -0
  14. package/dist/src/ProgressBar/types.js +1 -0
  15. package/dist/src/index.js +2 -0
  16. package/dist/tsconfig.tsbuildinfo +1 -1
  17. package/dist/types/src/ActionItem/ActionItem.d.ts +41 -0
  18. package/dist/types/src/ActionItem/ActionItem.style.d.ts +21 -0
  19. package/dist/types/src/ActionItem/ActionItemGroup.d.ts +11 -0
  20. package/dist/types/src/ActionItem/components/ActionItemContainer.d.ts +9 -0
  21. package/dist/types/src/ActionItem/components/ActionItemContainer.style.d.ts +10 -0
  22. package/dist/types/src/ActionItem/index.d.ts +2 -0
  23. package/dist/types/src/Card/Card.d.ts +2 -2
  24. package/dist/types/src/Card/index.d.ts +1 -1
  25. package/dist/types/src/ProgressBar/ProgressBar.d.ts +3 -0
  26. package/dist/types/src/ProgressBar/ProgressBar.style.d.ts +22 -0
  27. package/dist/types/src/ProgressBar/ProgressBarInner.d.ts +9 -0
  28. package/dist/types/src/ProgressBar/index.d.ts +2 -0
  29. package/dist/types/src/ProgressBar/messages.d.ts +12 -0
  30. package/dist/types/src/ProgressBar/types.d.ts +28 -0
  31. package/dist/types/src/index.d.ts +2 -0
  32. package/package.json +2 -2
  33. package/src/ActionItem/ActionItem.style.ts +29 -0
  34. package/src/ActionItem/ActionItem.test.tsx +121 -0
  35. package/src/ActionItem/ActionItem.tsx +131 -0
  36. package/src/ActionItem/ActionItemGroup.test.tsx +34 -0
  37. package/src/ActionItem/ActionItemGroup.tsx +43 -0
  38. package/src/ActionItem/components/ActionItemContainer.style.ts +14 -0
  39. package/src/ActionItem/components/ActionItemContainer.test.tsx +37 -0
  40. package/src/ActionItem/components/ActionItemContainer.tsx +45 -0
  41. package/src/ActionItem/index.ts +2 -0
  42. package/src/Button/Button.tsx +0 -1
  43. package/src/Card/Card.tsx +2 -3
  44. package/src/Card/index.ts +1 -1
  45. package/src/ProgressBar/ProgressBar.style.ts +25 -0
  46. package/src/ProgressBar/ProgressBar.test.tsx +41 -0
  47. package/src/ProgressBar/ProgressBar.tsx +58 -0
  48. package/src/ProgressBar/ProgressBarInner.tsx +47 -0
  49. package/src/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap +138 -0
  50. package/src/ProgressBar/index.tsx +2 -0
  51. package/src/ProgressBar/messages.ts +14 -0
  52. package/src/ProgressBar/types.ts +34 -0
  53. package/src/index.ts +2 -0
@@ -0,0 +1,45 @@
1
+ import React, { ReactNode } from "react";
2
+ import { Pressable, View } from "react-native";
3
+ import { styles } from "./ActionItemContainer.style";
4
+ import { styles as actionItemStyles } from "../ActionItem.style";
5
+
6
+ interface ActionItemContainerProps {
7
+ readonly children: ReactNode;
8
+ readonly title?: string;
9
+ readonly onPress?: () => void;
10
+ readonly testID?: string;
11
+ }
12
+
13
+ export function ActionItemContainer({
14
+ onPress,
15
+ title,
16
+ children,
17
+ testID,
18
+ }: ActionItemContainerProps): JSX.Element {
19
+ if (onPress) {
20
+ return (
21
+ <Pressable
22
+ onPress={onPress}
23
+ style={({ pressed }) => [
24
+ styles.container,
25
+ actionItemStyles.actionItemHorizontalOffset,
26
+ pressed && styles.pressed,
27
+ ]}
28
+ accessibilityRole="button"
29
+ accessibilityLabel={title}
30
+ testID={testID}
31
+ >
32
+ {children}
33
+ </Pressable>
34
+ );
35
+ }
36
+
37
+ return (
38
+ <View
39
+ style={[styles.container, actionItemStyles.actionItemHorizontalOffset]}
40
+ testID={testID}
41
+ >
42
+ {children}
43
+ </View>
44
+ );
45
+ }
@@ -0,0 +1,2 @@
1
+ export { ActionItem, ActionItemProps } from "./ActionItem";
2
+ export { ActionItemGroup } from "./ActionItemGroup";
@@ -3,7 +3,6 @@ import { TouchableHighlight, View } from "react-native";
3
3
  import { IconColorNames, IconNames } from "@jobber/design";
4
4
  import { XOR } from "ts-xor";
5
5
  import { styles } from "./Button.style";
6
- // eslint-disable-next-line import/no-internal-modules
7
6
  import { InternalButtonLoading } from "./components/InternalButtonLoading";
8
7
  import { ButtonSize, ButtonType, ButtonVariation } from "./types";
9
8
  import { ActionLabel, ActionLabelVariation } from "../ActionLabel";
package/src/Card/Card.tsx CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  import { IconNames } from "@jobber/design";
9
9
  import { XOR } from "ts-xor";
10
10
  import { styles } from "./Card.style";
11
- // eslint-disable-next-line import/no-internal-modules
12
11
  import { InternalCardHeader } from "./components/InternalCardHeader";
13
12
  import { ErrorMessageWrapper } from "../ErrorMessageWrapper";
14
13
  import { ActionLabel } from "../ActionLabel";
@@ -49,7 +48,7 @@ type HeaderActionProps =
49
48
  }
50
49
  | {
51
50
  readonly onPress: () => void;
52
- readonly actionItem: ActionItem;
51
+ readonly actionItem: CardAction;
53
52
  };
54
53
 
55
54
  interface IconAction {
@@ -60,7 +59,7 @@ interface ButtonAction {
60
59
  readonly label: string;
61
60
  }
62
61
 
63
- export type ActionItem = XOR<IconAction, ButtonAction>;
62
+ export type CardAction = XOR<IconAction, ButtonAction>;
64
63
 
65
64
  function getElevationStyle(elevation: elevationProp) {
66
65
  if (elevation === "none") {
package/src/Card/index.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Card } from "./Card";
2
- export type { ActionItem, HeaderProps } from "./Card";
2
+ export type { CardAction, HeaderProps } from "./Card";
@@ -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,2 @@
1
+ export { ProgressBar } from "./ProgressBar";
2
+ export type { ProgressBarProps } from "./types";
@@ -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
+ }
package/src/index.ts CHANGED
@@ -11,5 +11,7 @@ export * from "./StatusLabel";
11
11
  export * from "./AtlantisContext";
12
12
  export * from "./Button";
13
13
  export * from "./InputFieldWrapper";
14
+ export * from "./ProgressBar";
14
15
  export * from "./Heading";
15
16
  export * from "./Chip";
17
+ export * from "./ActionItem";