@jobber/components-native 0.7.0 → 0.9.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 (42) hide show
  1. package/dist/src/Card/Card.js +38 -0
  2. package/dist/src/Card/Card.style.js +31 -0
  3. package/dist/src/Card/components/InternalCardHeader.js +14 -0
  4. package/dist/src/Card/components/InternalCardHeader.style.js +16 -0
  5. package/dist/src/Card/components/index.js +1 -0
  6. package/dist/src/Card/index.js +1 -0
  7. package/dist/src/StatusLabel/StatusLabel.js +21 -0
  8. package/dist/src/StatusLabel/StatusLabel.style.js +27 -0
  9. package/dist/src/StatusLabel/index.js +1 -0
  10. package/dist/src/Typography/Typography.style.js +101 -164
  11. package/dist/src/Typography/webFonts.js +34 -0
  12. package/dist/src/index.js +2 -0
  13. package/dist/tsconfig.tsbuildinfo +1 -1
  14. package/dist/types/src/Card/Card.d.ts +40 -0
  15. package/dist/types/src/Card/Card.style.d.ts +56 -0
  16. package/dist/types/src/Card/components/InternalCardHeader.d.ts +9 -0
  17. package/dist/types/src/Card/components/InternalCardHeader.style.d.ts +14 -0
  18. package/dist/types/src/Card/components/index.d.ts +1 -0
  19. package/dist/types/src/Card/index.d.ts +2 -0
  20. package/dist/types/src/StatusLabel/StatusLabel.d.ts +22 -0
  21. package/dist/types/src/StatusLabel/StatusLabel.style.d.ts +23 -0
  22. package/dist/types/src/StatusLabel/index.d.ts +2 -0
  23. package/dist/types/src/Typography/Typography.style.d.ts +6 -6
  24. package/dist/types/src/Typography/webFonts.d.ts +4 -0
  25. package/dist/types/src/index.d.ts +2 -0
  26. package/package.json +2 -2
  27. package/src/Card/Card.style.ts +46 -0
  28. package/src/Card/Card.test.tsx +128 -0
  29. package/src/Card/Card.tsx +145 -0
  30. package/src/Card/components/InternalCardHeader.style.ts +19 -0
  31. package/src/Card/components/InternalCardHeader.test.tsx +31 -0
  32. package/src/Card/components/InternalCardHeader.tsx +41 -0
  33. package/src/Card/components/index.ts +1 -0
  34. package/src/Card/index.ts +2 -0
  35. package/src/StatusLabel/StatusLabel.style.ts +30 -0
  36. package/src/StatusLabel/StatusLabel.test.tsx +68 -0
  37. package/src/StatusLabel/StatusLabel.tsx +73 -0
  38. package/src/StatusLabel/__snapshots__/StatusLabel.test.tsx.snap +554 -0
  39. package/src/StatusLabel/index.ts +2 -0
  40. package/src/Typography/Typography.style.ts +33 -18
  41. package/src/Typography/webFonts.ts +43 -0
  42. package/src/index.ts +2 -0
@@ -0,0 +1,40 @@
1
+ import { ReactNode } from "react";
2
+ import { IconNames } from "@jobber/design";
3
+ import { XOR } from "ts-xor";
4
+ interface CardProps {
5
+ /**
6
+ * @deprecated Use <ActionItem /> with the title and onPress properties instead
7
+ */
8
+ readonly header?: HeaderProps;
9
+ readonly footer?: FooterProps;
10
+ readonly children?: ReactNode;
11
+ readonly reportCardHeight?: (height: number) => void;
12
+ readonly testID?: string;
13
+ readonly error?: string;
14
+ readonly elevation?: elevationProp;
15
+ }
16
+ type elevationProp = "none" | "low" | "base" | "high";
17
+ export type HeaderProps = HeaderCommonProps & HeaderActionProps;
18
+ interface FooterProps {
19
+ readonly onPress: () => void;
20
+ readonly title: string;
21
+ }
22
+ interface HeaderCommonProps {
23
+ readonly title: string;
24
+ }
25
+ type HeaderActionProps = {
26
+ readonly onPress?: never;
27
+ readonly actionItem?: never;
28
+ } | {
29
+ readonly onPress: () => void;
30
+ readonly actionItem: ActionItem;
31
+ };
32
+ interface IconAction {
33
+ readonly iconName: IconNames;
34
+ }
35
+ interface ButtonAction {
36
+ readonly label: string;
37
+ }
38
+ export type ActionItem = XOR<IconAction, ButtonAction>;
39
+ export declare function Card({ header, footer, children, reportCardHeight: onCardHeightChange, testID, error, elevation, }: CardProps): JSX.Element;
40
+ export {};
@@ -0,0 +1,56 @@
1
+ export declare const styles: {
2
+ container: {
3
+ width: string;
4
+ backgroundColor: string;
5
+ };
6
+ lowElevation: {
7
+ shadowColor: string;
8
+ shadowOffset: {
9
+ width: number;
10
+ height: number;
11
+ };
12
+ shadowOpacity: number;
13
+ shadowRadius: number;
14
+ elevation: number;
15
+ };
16
+ baseElevation: {
17
+ shadowColor: string;
18
+ shadowOffset: {
19
+ width: number;
20
+ height: number;
21
+ };
22
+ shadowOpacity: number;
23
+ shadowRadius: number;
24
+ elevation: number;
25
+ };
26
+ highElevation: {
27
+ shadowColor: string;
28
+ shadowOffset: {
29
+ width: number;
30
+ height: number;
31
+ };
32
+ shadowOpacity: number;
33
+ shadowRadius: number;
34
+ elevation: number;
35
+ };
36
+ headerTitle: {
37
+ flexGrow: number;
38
+ flex: number;
39
+ };
40
+ footer: {
41
+ height: number;
42
+ flex: number;
43
+ justifyContent: "center";
44
+ alignItems: "center";
45
+ };
46
+ pressed: {
47
+ opacity: number;
48
+ };
49
+ actionItem: {
50
+ height: number;
51
+ justifyContent: "center";
52
+ };
53
+ actionLabel: {
54
+ paddingTop: number;
55
+ };
56
+ };
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from "react";
2
+ interface InternalCardHeaderProps {
3
+ readonly children: ReactNode[] | ReactNode;
4
+ readonly onPress?: () => void;
5
+ readonly testID?: string;
6
+ readonly collapsable: boolean;
7
+ }
8
+ export declare function InternalCardHeader({ onPress, children, testID, collapsable, }: InternalCardHeaderProps): JSX.Element;
9
+ export {};
@@ -0,0 +1,14 @@
1
+ export declare const styles: {
2
+ header: {
3
+ flexDirection: "row";
4
+ alignItems: "flex-start";
5
+ paddingTop: number;
6
+ paddingHorizontal: number;
7
+ };
8
+ pressed: {
9
+ opacity: number;
10
+ };
11
+ noChildren: {
12
+ paddingBottom: number;
13
+ };
14
+ };
@@ -0,0 +1 @@
1
+ export { InternalCardHeader } from "./InternalCardHeader";
@@ -0,0 +1,2 @@
1
+ export { Card } from "./Card";
2
+ export type { ActionItem, HeaderProps } from "./Card";
@@ -0,0 +1,22 @@
1
+ /// <reference types="react" />
2
+ export type StatusType = "success" | "warning" | "critical" | "inactive" | "informative";
3
+ export interface StatusLabelType {
4
+ readonly statusLabel: string;
5
+ readonly statusType?: StatusType;
6
+ }
7
+ interface StatusLabelProps {
8
+ /**
9
+ * Text to display.
10
+ */
11
+ readonly text: string;
12
+ /**
13
+ * Alignment of text
14
+ */
15
+ readonly alignment?: "start" | "end";
16
+ /**
17
+ * Status color of the square beside text
18
+ */
19
+ readonly status?: StatusType;
20
+ }
21
+ export declare function StatusLabel({ text, alignment, status, }: StatusLabelProps): JSX.Element;
22
+ export {};
@@ -0,0 +1,23 @@
1
+ export declare const styles: {
2
+ statusLabelRow: {
3
+ flexDirection: "row";
4
+ justifyContent: "flex-end";
5
+ flexWrap: "nowrap";
6
+ };
7
+ statusLabelText: {
8
+ flexShrink: number;
9
+ };
10
+ statusLabelIcon: {
11
+ borderRadius: number;
12
+ backgroundColor: string;
13
+ width: number;
14
+ height: number;
15
+ marginTop: number;
16
+ };
17
+ labelTextStartAligned: {
18
+ flexDirection: "row-reverse";
19
+ };
20
+ innerPad: {
21
+ width: number;
22
+ };
23
+ };
@@ -0,0 +1,2 @@
1
+ export { StatusLabel } from "./StatusLabel";
2
+ export type { StatusType, StatusLabelType } from "./StatusLabel";
@@ -1,4 +1,10 @@
1
1
  import { TextStyle } from "react-native";
2
+ /**
3
+ * Reusable typography tokens to ensure consistency for any client facing texts.
4
+ */
5
+ export declare const typographyTokens: {
6
+ [index: string]: TextStyle;
7
+ };
2
8
  /**
3
9
  * `StyleSheet` for Typography.tsx.
4
10
  *
@@ -9,12 +15,6 @@ import { TextStyle } from "react-native";
9
15
  * import { typographyStyles } from "@jobber/components-native"
10
16
  * ```
11
17
  */
12
- /**
13
- * Reusable typography tokens to ensure consistency for any client facing texts.
14
- */
15
- export declare const typographyTokens: {
16
- [index: string]: TextStyle;
17
- };
18
18
  export declare const typographyStyles: {
19
19
  [index: string]: TextStyle;
20
20
  };
@@ -0,0 +1,4 @@
1
+ import { TextStyle } from "react-native";
2
+ export declare const webFonts: {
3
+ [index: string]: TextStyle;
4
+ };
@@ -6,4 +6,6 @@ export * from "./ErrorMessageWrapper";
6
6
  export * from "./ActionLabel";
7
7
  export * from "./Content";
8
8
  export * from "./ActivityIndicator";
9
+ export * from "./Card";
10
+ export * from "./StatusLabel";
9
11
  export * from "./AtlantisContext";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components-native",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/src/index.js",
6
6
  "module": "dist/src/index.js",
@@ -44,5 +44,5 @@
44
44
  "react": "^18",
45
45
  "react-native": ">=0.69.2"
46
46
  },
47
- "gitHead": "d4d0fe8b51c3f1a1bbbc5f221bd64fc90dc6a3cd"
47
+ "gitHead": "f884bf403f42a1c85f7bf840a6317ae1642653e1"
48
48
  }
@@ -0,0 +1,46 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { tokens } from "../utils/design";
3
+
4
+ export const styles = StyleSheet.create({
5
+ container: {
6
+ width: "100%",
7
+ backgroundColor: tokens["color-surface"],
8
+ },
9
+
10
+ lowElevation: {
11
+ ...tokens["shadow-low"],
12
+ },
13
+
14
+ baseElevation: {
15
+ ...tokens["shadow-base"],
16
+ },
17
+
18
+ highElevation: {
19
+ ...tokens["shadow-high"],
20
+ },
21
+
22
+ headerTitle: {
23
+ flexGrow: 1,
24
+ flex: 1,
25
+ },
26
+
27
+ footer: {
28
+ height: tokens["space-largest"],
29
+ flex: 1,
30
+ justifyContent: "center",
31
+ alignItems: "center",
32
+ },
33
+
34
+ pressed: {
35
+ opacity: tokens["opacity-pressed"],
36
+ },
37
+
38
+ actionItem: {
39
+ height: tokens["typography--lineHeight-base"],
40
+ justifyContent: "center",
41
+ },
42
+
43
+ actionLabel: {
44
+ paddingTop: tokens["space-smallest"],
45
+ },
46
+ });
@@ -0,0 +1,128 @@
1
+ import React from "react";
2
+ import { fireEvent, render } from "@testing-library/react-native";
3
+ import { Card } from "./Card";
4
+ import { Text } from "../Text";
5
+
6
+ const cardHeaderTestID = "cardHeader";
7
+ const cardFooterTestID = "cardFooter";
8
+
9
+ it("renders with only a header title", () => {
10
+ const title = "Foobar";
11
+ const { getByTestId, getByText, queryAllByRole } = render(
12
+ <Card header={{ title }} />,
13
+ );
14
+
15
+ expect(getByText(title)).toBeDefined();
16
+ expect(getByTestId(cardHeaderTestID)).toBeDefined();
17
+ expect(queryAllByRole("button")).toEqual([]);
18
+ });
19
+
20
+ it("renders with an icon action", () => {
21
+ const iconName = "plus2";
22
+ const { getByTestId } = render(
23
+ <Card
24
+ header={{
25
+ title: "Foobar",
26
+ actionItem: { iconName },
27
+ onPress: jest.fn(),
28
+ }}
29
+ />,
30
+ );
31
+
32
+ expect(getByTestId(iconName)).toBeDefined();
33
+ });
34
+
35
+ it("renders with a button action", () => {
36
+ const label = "Edit";
37
+ const { getByText } = render(
38
+ <Card
39
+ header={{
40
+ title: "Foobar",
41
+ actionItem: { label },
42
+ onPress: jest.fn(),
43
+ }}
44
+ />,
45
+ );
46
+
47
+ expect(getByText(label)).toBeDefined();
48
+ });
49
+
50
+ it("renders without a header and footer", () => {
51
+ const content = "I am the content";
52
+ const { getByText, queryByTestId } = render(
53
+ <Card>
54
+ <Text>{content}</Text>
55
+ </Card>,
56
+ );
57
+
58
+ expect(getByText(content)).toBeDefined();
59
+ expect(queryByTestId(cardHeaderTestID)).toBeNull();
60
+ expect(queryByTestId(cardFooterTestID)).toBeNull();
61
+ });
62
+
63
+ it("should call the onPress when pressing the header", () => {
64
+ const pressHandler = jest.fn();
65
+
66
+ const { getByText } = render(
67
+ <Card
68
+ header={{
69
+ title: "Header",
70
+ actionItem: { iconName: "plus2" },
71
+ onPress: pressHandler,
72
+ }}
73
+ />,
74
+ );
75
+
76
+ fireEvent.press(getByText("Header"));
77
+ expect(pressHandler).toHaveBeenCalled();
78
+ });
79
+
80
+ it("should call the onPress when pressing the action button", () => {
81
+ const pressHandler = jest.fn();
82
+
83
+ const { getByText } = render(
84
+ <Card
85
+ header={{
86
+ title: "Header",
87
+ actionItem: { label: "Edit" },
88
+ onPress: pressHandler,
89
+ }}
90
+ />,
91
+ );
92
+
93
+ fireEvent.press(getByText("Edit"));
94
+ expect(pressHandler).toHaveBeenCalled();
95
+ });
96
+
97
+ it("renders with a footer", () => {
98
+ const title = "View All";
99
+ const { getByText, getByTestId, queryByTestId } = render(
100
+ <Card footer={{ title: title, onPress: jest.fn() }} />,
101
+ );
102
+
103
+ expect(getByText(title)).toBeDefined();
104
+ expect(getByTestId(cardFooterTestID)).toBeDefined();
105
+ expect(queryByTestId(cardHeaderTestID)).toBeNull();
106
+ });
107
+
108
+ it("should call the onPress when pressing the footer", () => {
109
+ const headerPressHandler = jest.fn();
110
+ const footerPressHandler = jest.fn();
111
+
112
+ const { getByText } = render(
113
+ <Card
114
+ header={{
115
+ title: "Header",
116
+ actionItem: { iconName: "plus2" },
117
+ onPress: headerPressHandler,
118
+ }}
119
+ footer={{
120
+ title: "View All",
121
+ onPress: footerPressHandler,
122
+ }}
123
+ />,
124
+ );
125
+
126
+ fireEvent.press(getByText("View All"));
127
+ expect(footerPressHandler).toHaveBeenCalled();
128
+ });
@@ -0,0 +1,145 @@
1
+ import React, { ReactNode } from "react";
2
+ import {
3
+ LayoutChangeEvent,
4
+ Pressable,
5
+ PressableStateCallbackType,
6
+ View,
7
+ } from "react-native";
8
+ import { IconNames } from "@jobber/design";
9
+ import { XOR } from "ts-xor";
10
+ import { styles } from "./Card.style";
11
+ // eslint-disable-next-line import/no-internal-modules
12
+ import { InternalCardHeader } from "./components/InternalCardHeader";
13
+ import { ErrorMessageWrapper } from "../ErrorMessageWrapper";
14
+ import { ActionLabel } from "../ActionLabel";
15
+ import { Typography } from "../Typography";
16
+ import { Icon } from "../Icon";
17
+
18
+ interface CardProps {
19
+ /**
20
+ * @deprecated Use <ActionItem /> with the title and onPress properties instead
21
+ */
22
+ readonly header?: HeaderProps;
23
+
24
+ readonly footer?: FooterProps;
25
+ readonly children?: ReactNode;
26
+ readonly reportCardHeight?: (height: number) => void;
27
+ readonly testID?: string;
28
+ readonly error?: string;
29
+ readonly elevation?: elevationProp;
30
+ }
31
+
32
+ type elevationProp = "none" | "low" | "base" | "high";
33
+
34
+ export type HeaderProps = HeaderCommonProps & HeaderActionProps;
35
+
36
+ interface FooterProps {
37
+ readonly onPress: () => void;
38
+ readonly title: string;
39
+ }
40
+
41
+ interface HeaderCommonProps {
42
+ readonly title: string;
43
+ }
44
+
45
+ type HeaderActionProps =
46
+ | {
47
+ readonly onPress?: never;
48
+ readonly actionItem?: never;
49
+ }
50
+ | {
51
+ readonly onPress: () => void;
52
+ readonly actionItem: ActionItem;
53
+ };
54
+
55
+ interface IconAction {
56
+ readonly iconName: IconNames;
57
+ }
58
+
59
+ interface ButtonAction {
60
+ readonly label: string;
61
+ }
62
+
63
+ export type ActionItem = XOR<IconAction, ButtonAction>;
64
+
65
+ function getElevationStyle(elevation: elevationProp) {
66
+ if (elevation === "none") {
67
+ return undefined;
68
+ }
69
+ return styles[`${elevation}Elevation`];
70
+ }
71
+
72
+ export function Card({
73
+ header,
74
+ footer,
75
+ children,
76
+ reportCardHeight: onCardHeightChange,
77
+ testID = "card",
78
+ error,
79
+ elevation = "none",
80
+ }: CardProps): JSX.Element {
81
+ return (
82
+ <ErrorMessageWrapper message={error} wrapFor="card">
83
+ <View
84
+ onLayout={handleLayoutChange}
85
+ style={[styles.container, getElevationStyle(elevation)]}
86
+ testID={testID}
87
+ >
88
+ {header && (
89
+ <>
90
+ <InternalCardHeader
91
+ onPress={header.onPress}
92
+ testID={`${testID}Header`}
93
+ collapsable={!!children}
94
+ >
95
+ <View style={styles.headerTitle}>
96
+ <Typography
97
+ color="heading"
98
+ fontFamily="base"
99
+ fontWeight="bold"
100
+ size="default"
101
+ lineHeight="base"
102
+ accessibilityRole="header"
103
+ >
104
+ {header.title}
105
+ </Typography>
106
+ </View>
107
+ <View style={styles.actionItem}>
108
+ {!!header.actionItem?.label && (
109
+ <View style={styles.actionLabel}>
110
+ <ActionLabel type="cardTitle">
111
+ {header.actionItem.label}
112
+ </ActionLabel>
113
+ </View>
114
+ )}
115
+
116
+ {header.actionItem?.iconName && (
117
+ <Icon name={header.actionItem.iconName} color="interactive" />
118
+ )}
119
+ </View>
120
+ </InternalCardHeader>
121
+ </>
122
+ )}
123
+ {children}
124
+ {footer && (
125
+ <Pressable
126
+ testID={`${testID}Footer`}
127
+ onPress={footer.onPress}
128
+ style={({ pressed }: PressableStateCallbackType) => [
129
+ styles.footer,
130
+ pressed && styles.pressed,
131
+ ]}
132
+ accessibilityRole={"button"}
133
+ >
134
+ <ActionLabel>{footer.title}</ActionLabel>
135
+ </Pressable>
136
+ )}
137
+ </View>
138
+ </ErrorMessageWrapper>
139
+ );
140
+
141
+ function handleLayoutChange(event: LayoutChangeEvent) {
142
+ const { height } = event.nativeEvent.layout;
143
+ onCardHeightChange?.(height);
144
+ }
145
+ }
@@ -0,0 +1,19 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { tokens } from "../../utils/design";
3
+
4
+ export const styles = StyleSheet.create({
5
+ header: {
6
+ flexDirection: "row",
7
+ alignItems: "flex-start",
8
+ paddingTop: tokens["space-small"] + tokens["space-smaller"],
9
+ paddingHorizontal: tokens["space-base"],
10
+ },
11
+
12
+ pressed: {
13
+ opacity: tokens["opacity-pressed"],
14
+ },
15
+
16
+ noChildren: {
17
+ paddingBottom: tokens["space-small"] + tokens["space-smaller"],
18
+ },
19
+ });
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { fireEvent, render } from "@testing-library/react-native";
3
+ import { InternalCardHeader } from "./InternalCardHeader";
4
+
5
+ it("should render a pressable header", () => {
6
+ const handlePress = jest.fn();
7
+ const screen = render(
8
+ <InternalCardHeader collapsable onPress={handlePress} testID="cardHeader">
9
+ 🍩
10
+ </InternalCardHeader>,
11
+ );
12
+
13
+ const header = screen.getByTestId("cardHeader");
14
+ expect(header).toBeDefined();
15
+ expect(header.props.accessibilityRole).toBe("button");
16
+
17
+ fireEvent.press(header);
18
+ expect(handlePress).toHaveBeenCalled();
19
+ });
20
+
21
+ it("should render an un-pressable header", () => {
22
+ const screen = render(
23
+ <InternalCardHeader collapsable testID="cardHeader">
24
+ 🌞
25
+ </InternalCardHeader>,
26
+ );
27
+
28
+ const header = screen.getByTestId("cardHeader");
29
+ expect(header).toBeDefined();
30
+ expect(header.props.onPress).toBeUndefined();
31
+ });
@@ -0,0 +1,41 @@
1
+ import React, { ReactNode } from "react";
2
+ import { Pressable, View } from "react-native";
3
+ import { styles } from "./InternalCardHeader.style";
4
+
5
+ interface InternalCardHeaderProps {
6
+ readonly children: ReactNode[] | ReactNode;
7
+ readonly onPress?: () => void;
8
+ readonly testID?: string;
9
+ readonly collapsable: boolean;
10
+ }
11
+
12
+ export function InternalCardHeader({
13
+ onPress,
14
+ children,
15
+ testID,
16
+ collapsable,
17
+ }: InternalCardHeaderProps): JSX.Element {
18
+ const conditionalChildStyling = collapsable ? undefined : styles.noChildren;
19
+ if (onPress) {
20
+ return (
21
+ <Pressable
22
+ testID={testID}
23
+ onPress={onPress}
24
+ style={({ pressed }) => [
25
+ styles.header,
26
+ pressed && styles.pressed,
27
+ conditionalChildStyling,
28
+ ]}
29
+ accessibilityRole={"button"}
30
+ >
31
+ {children}
32
+ </Pressable>
33
+ );
34
+ }
35
+
36
+ return (
37
+ <View testID={testID} style={[styles.header, conditionalChildStyling]}>
38
+ {children}
39
+ </View>
40
+ );
41
+ }
@@ -0,0 +1 @@
1
+ export { InternalCardHeader } from "./InternalCardHeader";
@@ -0,0 +1,2 @@
1
+ export { Card } from "./Card";
2
+ export type { ActionItem, HeaderProps } from "./Card";
@@ -0,0 +1,30 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { tokens } from "../utils/design";
3
+
4
+ const statusLabelIconDiameter = tokens["space-base"] - tokens["space-smaller"]; //12px
5
+
6
+ const indicatorOffset = tokens["space-smallest"] + tokens["space-minuscule"];
7
+
8
+ export const styles = StyleSheet.create({
9
+ statusLabelRow: {
10
+ flexDirection: "row",
11
+ justifyContent: "flex-end",
12
+ flexWrap: "nowrap",
13
+ },
14
+ statusLabelText: {
15
+ flexShrink: 1,
16
+ },
17
+ statusLabelIcon: {
18
+ borderRadius: tokens["radius-base"],
19
+ backgroundColor: tokens["color-success"],
20
+ width: statusLabelIconDiameter,
21
+ height: statusLabelIconDiameter,
22
+ marginTop: indicatorOffset,
23
+ },
24
+ labelTextStartAligned: {
25
+ flexDirection: "row-reverse",
26
+ },
27
+ innerPad: {
28
+ width: tokens["space-small"],
29
+ },
30
+ });