@jobber/components-native 0.83.0 → 0.84.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.
@@ -1,4 +1,4 @@
1
- import { TextAlign, TextVariation, TruncateLength, TypographyProps } from "../Typography";
1
+ import { OnTextLayoutEvent, TextAlign, TextVariation, TruncateLength, TypographyProps } from "../Typography";
2
2
  import { TypographyUnsafeStyle } from "../Typography/Typography";
3
3
  export interface TextProps extends Pick<TypographyProps<"base">, "maxFontScaleSize" | "selectable"> {
4
4
  /**
@@ -66,7 +66,11 @@ export interface TextProps extends Pick<TypographyProps<"base">, "maxFontScaleSi
66
66
  * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
67
67
  */
68
68
  readonly UNSAFE_style?: TypographyUnsafeStyle;
69
+ /**
70
+ * Callback that is called when the text is laid out.
71
+ */
72
+ readonly onTextLayout?: OnTextLayoutEvent;
69
73
  }
70
74
  export type TextLevel = "text" | "textSupporting";
71
75
  export declare const TEXT_MAX_SCALED_FONT_SIZES: Record<TextLevel, number>;
72
- export declare function Text({ level, variation, emphasis, allowFontScaling, adjustsFontSizeToFit, maxLines, align, children, reverseTheme, strikeThrough, italic, hideFromScreenReader, maxFontScaleSize, UNSAFE_style, underline, selectable, }: TextProps): JSX.Element;
76
+ export declare function Text({ level, variation, emphasis, allowFontScaling, adjustsFontSizeToFit, maxLines, align, children, reverseTheme, strikeThrough, italic, hideFromScreenReader, maxFontScaleSize, UNSAFE_style, underline, selectable, onTextLayout, }: TextProps): JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { StyleProp, TextProps, TextStyle } from "react-native";
3
- export interface TypographyProps<T extends FontFamily> extends Pick<TextProps, "selectable"> {
3
+ export interface TypographyProps<T extends FontFamily> {
4
4
  /**
5
5
  * Text capitalization
6
6
  */
@@ -13,6 +13,12 @@ export interface TypographyProps<T extends FontFamily> extends Pick<TextProps, "
13
13
  * Alignment of text
14
14
  */
15
15
  readonly align?: TextAlign;
16
+ /**
17
+ * Lets the user select text, to use the native copy and paste functionality.
18
+ * WARNING: if true, this prevents ellipsis from being shown on Android.
19
+ * @default true
20
+ */
21
+ readonly selectable?: boolean;
16
22
  /**
17
23
  * Font size
18
24
  */
@@ -24,6 +30,7 @@ export interface TypographyProps<T extends FontFamily> extends Pick<TextProps, "
24
30
  /**
25
31
  * The maximum amount of lines the text can occupy before being truncated with "...".
26
32
  * Uses predefined string values that correspond to a doubling scale for the amount of lines.
33
+ * WARNING: if `selectable` is true, Android will not show an ellipsis.
27
34
  */
28
35
  readonly maxLines?: TruncateLength;
29
36
  /**
@@ -86,12 +93,19 @@ export interface TypographyProps<T extends FontFamily> extends Pick<TextProps, "
86
93
  */
87
94
  readonly strikeThrough?: boolean;
88
95
  readonly UNSAFE_style?: TypographyUnsafeStyle;
96
+ /**
97
+ * Callback behaves differently on iOS and Android.
98
+ * On iOS, it is called when the text is laid out.
99
+ * On Android, it is called before the text is laid out.
100
+ * @see https://reactnative.dev/docs/text#ontextlayout
101
+ */
102
+ readonly onTextLayout?: OnTextLayoutEvent;
89
103
  }
90
104
  export interface TypographyUnsafeStyle {
91
105
  textStyle?: StyleProp<TextStyle>;
92
106
  }
93
107
  export declare const Typography: React.MemoExoticComponent<typeof InternalTypography>;
94
- declare function InternalTypography<T extends FontFamily = "base">({ fontFamily, fontStyle, fontWeight, transform, color, align, size, children, maxLines, allowFontScaling, maxFontScaleSize, adjustsFontSizeToFit, lineHeight, letterSpacing, reverseTheme, hideFromScreenReader, accessibilityRole, strikeThrough, underline, UNSAFE_style, selectable, }: TypographyProps<T>): JSX.Element;
108
+ declare function InternalTypography<T extends FontFamily = "base">({ fontFamily, fontStyle, fontWeight, transform, color, align, size, children, maxLines, allowFontScaling, maxFontScaleSize, adjustsFontSizeToFit, lineHeight, letterSpacing, reverseTheme, hideFromScreenReader, accessibilityRole, strikeThrough, underline, UNSAFE_style, selectable, onTextLayout, }: TypographyProps<T>): JSX.Element;
95
109
  export type FontFamily = "base" | "display";
96
110
  export type FontStyle = "regular" | "italic";
97
111
  export type FontWeight = "regular" | "medium" | "bold" | "semiBold" | "extraBold" | "black";
@@ -108,4 +122,5 @@ export type LineHeight = "extravagant" | "jumbo" | "largest" | "larger" | "large
108
122
  export type LetterSpacing = "base" | "loose";
109
123
  export type TextAccessibilityRole = "text" | "header";
110
124
  export type TruncateLength = "single" | "small" | "base" | "large" | "extraLarge" | "unlimited";
125
+ export type OnTextLayoutEvent = Exclude<TextProps["onTextLayout"], undefined>;
111
126
  export {};
@@ -1,5 +1,5 @@
1
1
  export { Typography } from "./Typography";
2
- export type { FontFamily, FontStyle, FontWeight, BaseWeight, DisplayWeight, BaseStyle, DisplayStyle, TextColor, TextTransform, TextSize, TextAlign, LineHeight, LetterSpacing, TextAccessibilityRole, TextVariation, TypographyProps, TruncateLength, } from "./Typography";
2
+ export type { FontFamily, FontStyle, FontWeight, BaseWeight, DisplayWeight, BaseStyle, DisplayStyle, TextColor, TextTransform, TextSize, TextAlign, LineHeight, LetterSpacing, TextAccessibilityRole, TextVariation, TypographyProps, TruncateLength, OnTextLayoutEvent, } from "./Typography";
3
3
  export { getTypographyStyles, useTypographyStyles } from "./Typography.style";
4
4
  export { typographyStyles } from "./Typography.style";
5
5
  export { TypographyGestureDetector } from "./TypographyGestureDetector";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components-native",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "license": "MIT",
5
5
  "description": "React Native implementation of Atlantis",
6
6
  "repository": {
@@ -79,5 +79,5 @@
79
79
  "react-native-safe-area-context": "^5.4.0",
80
80
  "react-native-svg": ">=12.0.0"
81
81
  },
82
- "gitHead": "5b2a570f0d657e82d04a8d60964242f67da3fab0"
82
+ "gitHead": "5fcbf313b34c60eb45e8985527acb880421690e3"
83
83
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { render } from "@testing-library/react-native";
2
+ import { fireEvent, render, screen } from "@testing-library/react-native";
3
3
  import { Text } from ".";
4
4
  import { tokens } from "../utils/design";
5
5
 
@@ -135,6 +135,7 @@ it("renders with italic styling", () => {
135
135
 
136
136
  it("renders text that is inaccessible", () => {
137
137
  const text = render(<Text hideFromScreenReader={true}>Test Text</Text>);
138
+
138
139
  expect(text.root.props).toEqual(
139
140
  expect.objectContaining({
140
141
  accessibilityRole: "none",
@@ -145,7 +146,7 @@ it("renders text that is inaccessible", () => {
145
146
  });
146
147
 
147
148
  it("renders text with underline styling", () => {
148
- const text = render(<Text underline="dashed">Test Text</Text>);
149
+ const text = render(<Text underline="dotted">Test Text</Text>);
149
150
 
150
151
  expect(text.toJSON()).toMatchSnapshot();
151
152
  });
@@ -159,12 +160,39 @@ describe("UNSAFE_style", () => {
159
160
  },
160
161
  };
161
162
 
162
- const { getByRole } = render(
163
- <Text UNSAFE_style={customStyle}>Test Text</Text>,
164
- );
165
- const textElement = getByRole("text");
163
+ render(<Text UNSAFE_style={customStyle}>Test Text</Text>);
164
+ const textElement = screen.getByRole("text");
166
165
  expect(textElement.props.style).toContainEqual(
167
166
  expect.objectContaining(customStyle.textStyle),
168
167
  );
169
168
  });
170
169
  });
170
+
171
+ describe("onTextLayout", () => {
172
+ it("calls onTextLayout callback when text layout event occurs", () => {
173
+ const onTextLayoutMock = jest.fn();
174
+ render(<Text onTextLayout={onTextLayoutMock}>Test Text</Text>);
175
+
176
+ const textElement = screen.getByRole("text");
177
+ const mockEvent = {
178
+ nativeEvent: {
179
+ lines: [
180
+ {
181
+ text: "Test Text",
182
+ x: 0,
183
+ y: 0,
184
+ width: 100,
185
+ height: 20,
186
+ ascender: 15,
187
+ descender: -5,
188
+ capHeight: 14,
189
+ xHeight: 10,
190
+ },
191
+ ],
192
+ },
193
+ };
194
+ fireEvent(textElement, "onTextLayout", mockEvent);
195
+ expect(onTextLayoutMock).toHaveBeenCalledTimes(1);
196
+ expect(onTextLayoutMock).toHaveBeenCalledWith(mockEvent);
197
+ });
198
+ });
package/src/Text/Text.tsx CHANGED
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import {
3
3
  BaseWeight,
4
4
  LineHeight,
5
+ OnTextLayoutEvent,
5
6
  TextAccessibilityRole,
6
7
  TextAlign,
7
8
  TextSize,
@@ -93,6 +94,11 @@ export interface TextProps
93
94
  * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
94
95
  */
95
96
  readonly UNSAFE_style?: TypographyUnsafeStyle;
97
+
98
+ /**
99
+ * Callback that is called when the text is laid out.
100
+ */
101
+ readonly onTextLayout?: OnTextLayoutEvent;
96
102
  }
97
103
 
98
104
  export type TextLevel = "text" | "textSupporting";
@@ -136,6 +142,7 @@ export function Text({
136
142
  UNSAFE_style,
137
143
  underline,
138
144
  selectable,
145
+ onTextLayout,
139
146
  }: TextProps): JSX.Element {
140
147
  const accessibilityRole: TextAccessibilityRole = "text";
141
148
 
@@ -149,6 +156,7 @@ export function Text({
149
156
  maxFontScaleSize={maxFontScaleSize || TEXT_MAX_SCALED_FONT_SIZES[level]}
150
157
  selectable={selectable}
151
158
  underline={underline}
159
+ onTextLayout={onTextLayout}
152
160
  {...{
153
161
  ...levelStyles[level],
154
162
  allowFontScaling,
@@ -574,7 +574,7 @@ exports[`renders text with underline styling 1`] = `
574
574
  "letterSpacing": 0,
575
575
  },
576
576
  {
577
- "textDecorationStyle": "dashed",
577
+ "textDecorationStyle": "dotted",
578
578
  },
579
579
  {
580
580
  "textDecorationColor": "hsl(197, 15%, 43%)",
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { render } from "@testing-library/react-native";
2
+ import { fireEvent, render } from "@testing-library/react-native";
3
3
  import { I18nManager } from "react-native";
4
4
  import { Typography } from "./Typography";
5
5
 
@@ -251,3 +251,34 @@ describe("underline", () => {
251
251
  },
252
252
  );
253
253
  });
254
+
255
+ describe("onTextLayout", () => {
256
+ it("calls onTextLayout callback when text layout event occurs", () => {
257
+ const onTextLayoutMock = jest.fn();
258
+ const { getByRole } = render(
259
+ <Typography onTextLayout={onTextLayoutMock}>Test Text</Typography>,
260
+ );
261
+
262
+ const textElement = getByRole("text");
263
+ const mockEvent = {
264
+ nativeEvent: {
265
+ lines: [
266
+ {
267
+ text: "Test Text",
268
+ x: 0,
269
+ y: 0,
270
+ width: 100,
271
+ height: 20,
272
+ ascender: 15,
273
+ descender: -5,
274
+ capHeight: 14,
275
+ xHeight: 10,
276
+ },
277
+ ],
278
+ },
279
+ };
280
+ fireEvent(textElement, "onTextLayout", mockEvent);
281
+ expect(onTextLayoutMock).toHaveBeenCalledTimes(1);
282
+ expect(onTextLayoutMock).toHaveBeenCalledWith(mockEvent);
283
+ });
284
+ });
@@ -14,8 +14,7 @@ import { useTypographyStyles } from "./Typography.style";
14
14
  import { capitalize } from "../utils/intl";
15
15
  import { useAtlantisTheme } from "../AtlantisThemeContext";
16
16
 
17
- export interface TypographyProps<T extends FontFamily>
18
- extends Pick<TextProps, "selectable"> {
17
+ export interface TypographyProps<T extends FontFamily> {
19
18
  /**
20
19
  * Text capitalization
21
20
  */
@@ -31,6 +30,13 @@ export interface TypographyProps<T extends FontFamily>
31
30
  */
32
31
  readonly align?: TextAlign;
33
32
 
33
+ /**
34
+ * Lets the user select text, to use the native copy and paste functionality.
35
+ * WARNING: if true, this prevents ellipsis from being shown on Android.
36
+ * @default true
37
+ */
38
+ readonly selectable?: boolean;
39
+
34
40
  /**
35
41
  * Font size
36
42
  */
@@ -44,6 +50,7 @@ export interface TypographyProps<T extends FontFamily>
44
50
  /**
45
51
  * The maximum amount of lines the text can occupy before being truncated with "...".
46
52
  * Uses predefined string values that correspond to a doubling scale for the amount of lines.
53
+ * WARNING: if `selectable` is true, Android will not show an ellipsis.
47
54
  */
48
55
  readonly maxLines?: TruncateLength;
49
56
 
@@ -120,6 +127,14 @@ export interface TypographyProps<T extends FontFamily>
120
127
  readonly strikeThrough?: boolean;
121
128
 
122
129
  readonly UNSAFE_style?: TypographyUnsafeStyle;
130
+
131
+ /**
132
+ * Callback behaves differently on iOS and Android.
133
+ * On iOS, it is called when the text is laid out.
134
+ * On Android, it is called before the text is laid out.
135
+ * @see https://reactnative.dev/docs/text#ontextlayout
136
+ */
137
+ readonly onTextLayout?: OnTextLayoutEvent;
123
138
  }
124
139
 
125
140
  const maxNumberOfLines = {
@@ -160,6 +175,7 @@ function InternalTypography<T extends FontFamily = "base">({
160
175
  underline,
161
176
  UNSAFE_style,
162
177
  selectable = true,
178
+ onTextLayout,
163
179
  }: TypographyProps<T>): JSX.Element {
164
180
  const styles = useTypographyStyles();
165
181
  const sizeAndHeight = getSizeAndHeightStyle(size, styles, lineHeight);
@@ -217,6 +233,7 @@ function InternalTypography<T extends FontFamily = "base">({
217
233
  )}
218
234
  selectable={selectable}
219
235
  selectionColor={tokens["color-brand--highlight"]}
236
+ onTextLayout={onTextLayout}
220
237
  >
221
238
  {text}
222
239
  </Text>
@@ -477,3 +494,5 @@ export type TruncateLength =
477
494
  | "large"
478
495
  | "extraLarge"
479
496
  | "unlimited";
497
+
498
+ export type OnTextLayoutEvent = Exclude<TextProps["onTextLayout"], undefined>;
@@ -17,6 +17,7 @@ export type {
17
17
  TextVariation,
18
18
  TypographyProps,
19
19
  TruncateLength,
20
+ OnTextLayoutEvent,
20
21
  } from "./Typography";
21
22
  export { getTypographyStyles, useTypographyStyles } from "./Typography.style";
22
23
  export { typographyStyles } from "./Typography.style";