@jobber/components-native 0.54.4-JOB-88641.7 → 0.54.4-fix-inline.3

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 (148) hide show
  1. package/dist/package.json +7 -7
  2. package/dist/src/ActionItem/ActionItem.js +1 -1
  3. package/dist/src/Banner/Banner.js +2 -3
  4. package/dist/src/Banner/Banner.style.js +4 -2
  5. package/dist/src/Button/Button.js +2 -2
  6. package/dist/src/Button/Button.style.js +2 -2
  7. package/dist/src/Button/components/InternalButtonLoading/InternalButtonLoading.js +3 -0
  8. package/dist/src/ButtonGroup/ButtonGroup.js +1 -1
  9. package/dist/src/ButtonGroup/ButtonGroup.style.js +1 -1
  10. package/dist/src/Card/Card.js +7 -8
  11. package/dist/src/Disclosure/Disclosure.js +3 -3
  12. package/dist/src/Glimmer/Glimmer.js +42 -0
  13. package/dist/src/Glimmer/Glimmer.shape.style.js +16 -0
  14. package/dist/src/Glimmer/Glimmer.size.style.js +9 -0
  15. package/dist/src/Glimmer/Glimmer.style.js +20 -0
  16. package/dist/src/Glimmer/index.js +1 -0
  17. package/dist/src/InputCurrency/InputCurrency.js +16 -17
  18. package/dist/src/InputFieldWrapper/InputFieldWrapper.js +39 -18
  19. package/dist/src/InputFieldWrapper/InputFieldWrapper.style.js +38 -1
  20. package/dist/src/InputText/InputText.js +6 -3
  21. package/dist/src/Menu/Menu.js +20 -3
  22. package/dist/src/Menu/Menu.style.js +1 -1
  23. package/dist/src/Menu/utils.js +2 -7
  24. package/dist/src/index.js +6 -5
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/dist/types/src/Banner/Banner.style.d.ts +4 -2
  27. package/dist/types/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.d.ts +1 -1
  28. package/dist/types/src/ButtonGroup/ButtonGroup.style.d.ts +1 -1
  29. package/dist/types/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.d.ts +6 -6
  30. package/dist/types/src/Checkbox/CheckboxGroup.d.ts +2 -2
  31. package/dist/types/src/Form/components/FormBody/FormBody.d.ts +3 -3
  32. package/dist/types/src/Form/components/FormCache/FormCache.d.ts +4 -4
  33. package/dist/types/src/Form/components/FormMessageBanner/FormMessageBanner.d.ts +1 -1
  34. package/dist/types/src/FormField/FormField.d.ts +2 -2
  35. package/dist/types/src/FormatFile/FormatFile.d.ts +6 -6
  36. package/dist/types/src/FormatFile/components/FileView/FileView.d.ts +6 -6
  37. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.d.ts +4 -4
  38. package/dist/types/src/FormatFile/components/MediaView/MediaView.d.ts +6 -6
  39. package/dist/types/src/FormatFile/components/ProgressBar/ProgressBar.d.ts +3 -3
  40. package/dist/types/src/Glimmer/Glimmer.d.ts +31 -0
  41. package/dist/types/src/Glimmer/Glimmer.shape.style.d.ts +14 -0
  42. package/dist/types/src/Glimmer/Glimmer.size.style.d.ts +17 -0
  43. package/dist/types/src/Glimmer/Glimmer.style.d.ts +18 -0
  44. package/dist/types/src/Glimmer/index.d.ts +1 -0
  45. package/dist/types/src/InputCurrency/InputCurrency.d.ts +3 -3
  46. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.d.ts +19 -1
  47. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.style.d.ts +34 -0
  48. package/dist/types/src/InputFieldWrapper/components/Prefix/Prefix.d.ts +12 -12
  49. package/dist/types/src/InputFieldWrapper/components/Suffix/Suffix.d.ts +14 -14
  50. package/dist/types/src/InputPassword/InputPassword.d.ts +1 -1
  51. package/dist/types/src/InputText/InputText.d.ts +6 -2
  52. package/dist/types/src/InputText/context/InputAccessoriesProvider.d.ts +1 -1
  53. package/dist/types/src/Toast/Toast.d.ts +1 -1
  54. package/dist/types/src/index.d.ts +6 -5
  55. package/dist/types/src/utils/test/MockSafeAreaProvider.d.ts +3 -3
  56. package/jestSetup.js +2 -0
  57. package/package.json +7 -7
  58. package/src/ActionItem/ActionItem.test.tsx +2 -2
  59. package/src/ActionItem/ActionItem.tsx +3 -1
  60. package/src/ActionItem/ActionItemGroup.tsx +1 -0
  61. package/src/AutoLink/hooks/useCreateLinkedText.ts +1 -0
  62. package/src/AutoLink/hooks/useTokenGenerator.ts +1 -0
  63. package/src/Banner/Banner.style.ts +4 -2
  64. package/src/Banner/Banner.tsx +3 -3
  65. package/src/BottomSheet/BottomSheet.tsx +3 -3
  66. package/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.tsx +3 -1
  67. package/src/Button/Button.style.ts +2 -2
  68. package/src/Button/Button.test.tsx +2 -2
  69. package/src/Button/Button.tsx +2 -2
  70. package/src/Button/components/InternalButtonLoading/InternalButtonLoading.tsx +4 -0
  71. package/src/ButtonGroup/ButtonGroup.style.ts +1 -1
  72. package/src/ButtonGroup/ButtonGroup.tsx +1 -0
  73. package/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.tsx +7 -6
  74. package/src/Card/Card.tsx +31 -32
  75. package/src/Card/components/InternalCardHeader.tsx +1 -0
  76. package/src/Checkbox/CheckboxGroup.tsx +12 -2
  77. package/src/Chip/Chip.tsx +2 -0
  78. package/src/Content/Content.test.tsx +1 -0
  79. package/src/Content/Content.tsx +1 -0
  80. package/src/ContentOverlay/ContentOverlay.test.tsx +1 -0
  81. package/src/Disclosure/Disclosure.tsx +3 -8
  82. package/src/Disclosure/__snapshots__/Disclosure.test.tsx.snap +18 -24
  83. package/src/Divider/Divider.tsx +1 -0
  84. package/src/EmptyState/EmptyState.tsx +2 -2
  85. package/src/Flex/Flex.styles.tsx +1 -0
  86. package/src/Flex/Flex.test.tsx +2 -0
  87. package/src/Form/Form.test.tsx +19 -14
  88. package/src/Form/components/FormBody/FormBody.tsx +4 -3
  89. package/src/Form/components/FormCache/FormCache.tsx +5 -4
  90. package/src/Form/components/FormMessage/FormMessage.tsx +1 -0
  91. package/src/Form/components/FormMessageBanner/FormMessageBanner.tsx +1 -1
  92. package/src/Form/components/FormSaveButton/FormSaveButton.test.tsx +5 -5
  93. package/src/Form/context/AtlantisFormContext.tsx +1 -0
  94. package/src/Form/hooks/useFormViewRefs.ts +1 -0
  95. package/src/Form/hooks/useOfflineHandler.ts +1 -0
  96. package/src/Form/hooks/useScrollToError/useScrollToError.ts +2 -0
  97. package/src/FormField/FormField.test.tsx +6 -8
  98. package/src/FormField/FormField.tsx +2 -2
  99. package/src/FormatFile/FormatFile.tsx +15 -14
  100. package/src/FormatFile/components/FileView/FileView.tsx +9 -6
  101. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +4 -4
  102. package/src/FormatFile/components/MediaView/MediaView.tsx +15 -14
  103. package/src/FormatFile/components/ProgressBar/ProgressBar.tsx +3 -3
  104. package/src/FormatFile/utils/createUseCreateThumbnail.ts +1 -0
  105. package/src/Glimmer/Glimmer.shape.style.ts +17 -0
  106. package/src/Glimmer/Glimmer.size.style.ts +10 -0
  107. package/src/Glimmer/Glimmer.style.ts +23 -0
  108. package/src/Glimmer/Glimmer.test.tsx +73 -0
  109. package/src/Glimmer/Glimmer.tsx +106 -0
  110. package/src/Glimmer/index.ts +1 -0
  111. package/src/Icon/Icon.tsx +1 -0
  112. package/src/Icon/__snapshots__/Icon.test.tsx.snap +89 -24
  113. package/src/InputCurrency/InputCurrency.tsx +40 -38
  114. package/src/InputCurrency/utils.ts +9 -0
  115. package/src/InputDate/InputDate.test.tsx +1 -0
  116. package/src/InputFieldWrapper/InputFieldWrapper.style.ts +46 -1
  117. package/src/InputFieldWrapper/InputFieldWrapper.test.tsx +74 -0
  118. package/src/InputFieldWrapper/InputFieldWrapper.tsx +131 -64
  119. package/src/InputFieldWrapper/components/ClearAction/ClearAction.tsx +1 -0
  120. package/src/InputFieldWrapper/components/Prefix/Prefix.tsx +12 -12
  121. package/src/InputFieldWrapper/components/Suffix/Suffix.tsx +14 -14
  122. package/src/InputNumber/InputNumber.tsx +8 -0
  123. package/src/InputPassword/InputPassword.test.tsx +1 -0
  124. package/src/InputPassword/InputPassword.tsx +2 -1
  125. package/src/InputPressable/InputPressable.test.tsx +1 -0
  126. package/src/InputSearch/InputSearch.tsx +1 -0
  127. package/src/InputText/InputText.test.tsx +11 -0
  128. package/src/InputText/InputText.tsx +27 -2
  129. package/src/InputText/context/InputAccessoriesProvider.test.tsx +6 -1
  130. package/src/InputText/context/InputAccessoriesProvider.tsx +1 -1
  131. package/src/InputTime/utils/index.ts +1 -0
  132. package/src/Menu/Menu.style.ts +1 -1
  133. package/src/Menu/Menu.tsx +23 -2
  134. package/src/Menu/components/MenuOption/MenuOption.tsx +1 -0
  135. package/src/Menu/utils.ts +3 -7
  136. package/src/ProgressBar/ProgressBarInner.tsx +1 -0
  137. package/src/Select/components/SelectInternalPicker/SelectInternalPicker.tsx +1 -0
  138. package/src/Select/components/SelectInternalPicker/utils.ts +1 -0
  139. package/src/StatusLabel/StatusLabel.tsx +1 -1
  140. package/src/Switch/components/BaseSwitch/BaseSwitch.tsx +1 -0
  141. package/src/Text/Text.tsx +1 -0
  142. package/src/Toast/Toast.tsx +2 -1
  143. package/src/Typography/Typography.tsx +5 -0
  144. package/src/hooks/useAtlantisI18n/utils/dateFormatter.ts +1 -0
  145. package/src/hooks/useFormController.ts +2 -0
  146. package/src/index.ts +6 -5
  147. package/src/utils/intl/capitalize.ts +1 -0
  148. package/src/utils/test/MockSafeAreaProvider.tsx +3 -3
@@ -0,0 +1,106 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+ import { Animated, Easing, LayoutChangeEvent, View } from "react-native";
3
+ import Svg, { Defs, LinearGradient, Rect, Stop } from "react-native-svg";
4
+ import { shineWidth, styles } from "./Glimmer.style";
5
+ import { sizeStyles } from "./Glimmer.size.style";
6
+ import { shapeStyles } from "./Glimmer.shape.style";
7
+ import { tokens } from "../utils/design";
8
+
9
+ export type GlimmerShapes = keyof typeof shapeStyles;
10
+ export type GlimmerSizes = keyof typeof sizeStyles;
11
+ export type GlimmerTimings = "base" | "fast";
12
+
13
+ interface GlimmerProps {
14
+ /**
15
+ * Sets the size of the glimmer.
16
+ */
17
+ readonly shape?: GlimmerShapes;
18
+
19
+ /**
20
+ * Sets the shape of the glimmer.
21
+ *
22
+ * If you need a specific width, use the `width` prop.
23
+ */
24
+ readonly size?: GlimmerSizes;
25
+
26
+ /**
27
+ * Control how fast the shine moves from left to right. This is useful when
28
+ * the glimmer is used on smaller spaces.
29
+ */
30
+ readonly timing?: GlimmerTimings;
31
+
32
+ /**
33
+ * Adjust the width of the glimmer in px or % values.
34
+ */
35
+ readonly width?: number | `${number}%`;
36
+ }
37
+
38
+ export const GLIMMER_TEST_ID = "ATL-Glimmer";
39
+ export const GLIMMER_SHINE_TEST_ID = "ATL-Glimmer-Shine";
40
+
41
+ export function Glimmer({
42
+ width,
43
+ shape = "rectangle",
44
+ size = "base",
45
+ timing = "base",
46
+ }: GlimmerProps) {
47
+ const leftPosition = useRef(new Animated.Value(-shineWidth)).current;
48
+ const [parentWidth, setParentWidth] = useState(0);
49
+
50
+ useEffect(() => {
51
+ const shine = Animated.loop(
52
+ Animated.timing(leftPosition, {
53
+ toValue: parentWidth + shineWidth,
54
+ duration:
55
+ timing === "base"
56
+ ? tokens["timing-loading--extended"]
57
+ : tokens["timing-loading"],
58
+ easing: Easing.ease,
59
+ useNativeDriver: true,
60
+ }),
61
+ );
62
+
63
+ shine.start();
64
+
65
+ return shine.stop;
66
+ }, [parentWidth]);
67
+
68
+ return (
69
+ <View
70
+ style={[
71
+ styles.container,
72
+ sizeStyles[size],
73
+ shapeStyles[shape],
74
+ { width },
75
+ ]}
76
+ onLayout={getWidth}
77
+ testID={GLIMMER_TEST_ID}
78
+ >
79
+ <Animated.View
80
+ style={[styles.shine, { transform: [{ translateX: leftPosition }] }]}
81
+ testID={GLIMMER_SHINE_TEST_ID}
82
+ >
83
+ <Svg>
84
+ <Defs>
85
+ <LinearGradient id="gradientShine" x1={0} y1={0.5} x2={1} y2={0.5}>
86
+ <Stop
87
+ offset="0%"
88
+ stopColor={tokens["color-surface--background"]}
89
+ />
90
+ <Stop offset="50%" stopColor={tokens["color-surface"]} />
91
+ <Stop
92
+ offset="100%"
93
+ stopColor={tokens["color-surface--background"]}
94
+ />
95
+ </LinearGradient>
96
+ </Defs>
97
+ <Rect fill="url(#gradientShine)" height="100%" width="100%" />
98
+ </Svg>
99
+ </Animated.View>
100
+ </View>
101
+ );
102
+
103
+ function getWidth(event: LayoutChangeEvent) {
104
+ setParentWidth(event.nativeEvent.layout.width);
105
+ }
106
+ }
@@ -0,0 +1 @@
1
+ export * from "./Glimmer";
package/src/Icon/Icon.tsx CHANGED
@@ -93,6 +93,7 @@ function getSvgStyle(classNames = ""): SvgProps["style"] & FillProps {
93
93
  ...colorsClassMap,
94
94
  };
95
95
  const svgStyle = getStylesForClassNames(classNames.split(" "), classMap);
96
+
96
97
  return { ...svgStyle, display: "flex" };
97
98
  }
98
99
 
@@ -34,7 +34,12 @@ exports[`renders apple icon 1`] = `
34
34
  vbWidth={24}
35
35
  >
36
36
  <RNSVGGroup
37
- fill={4284840068}
37
+ fill={
38
+ {
39
+ "payload": 4284840068,
40
+ "type": 0,
41
+ }
42
+ }
38
43
  propList={
39
44
  [
40
45
  "fill",
@@ -43,7 +48,12 @@ exports[`renders apple icon 1`] = `
43
48
  >
44
49
  <RNSVGPath
45
50
  d="M18.467 12.754c-.027-2.996 2.453-4.453 2.566-4.52-1.404-2.048-3.581-2.328-4.346-2.35-1.828-.193-3.601 1.094-4.533 1.094-.95 0-2.384-1.076-3.93-1.044-1.988.03-3.849 1.182-4.87 2.97C1.25 12.55 2.82 17.91 4.838 20.856c1.01 1.443 2.189 3.055 3.733 2.998 1.51-.062 2.074-.963 3.897-.963 1.806 0 2.335.963 3.91.927 1.62-.026 2.641-1.45 3.615-2.907 1.166-1.654 1.635-3.283 1.653-3.367-.038-.013-3.147-1.2-3.178-4.79Zm-2.974-8.81c.812-1.015 1.368-2.397 1.213-3.8-1.175.053-2.646.814-3.492 1.807-.75.876-1.418 2.31-1.246 3.66 1.321.099 2.677-.666 3.525-1.666Z"
46
- fill={4284840068}
51
+ fill={
52
+ {
53
+ "payload": 4284840068,
54
+ "type": 0,
55
+ }
56
+ }
47
57
  propList={
48
58
  [
49
59
  "fill",
@@ -88,7 +98,12 @@ exports[`renders home icon 1`] = `
88
98
  vbWidth={24}
89
99
  >
90
100
  <RNSVGGroup
91
- fill={4284840068}
101
+ fill={
102
+ {
103
+ "payload": 4284840068,
104
+ "type": 0,
105
+ }
106
+ }
92
107
  propList={
93
108
  [
94
109
  "fill",
@@ -97,7 +112,12 @@ exports[`renders home icon 1`] = `
97
112
  >
98
113
  <RNSVGPath
99
114
  d="M13.147 3.582a2 2 0 0 0-2.294 0l-9.426 6.599a1 1 0 1 0 1.147 1.638L5 10.121V18a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3v-7.88l2.427 1.7a1 1 0 0 0 1.146-1.64l-9.426-6.598ZM17 8.721V18a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V8.72l5-3.5 5 3.5Z"
100
- fill={4284840068}
115
+ fill={
116
+ {
117
+ "payload": 4284840068,
118
+ "type": 0,
119
+ }
120
+ }
101
121
  propList={
102
122
  [
103
123
  "fill",
@@ -142,7 +162,12 @@ exports[`renders large arrowDown icon 1`] = `
142
162
  vbWidth={24}
143
163
  >
144
164
  <RNSVGGroup
145
- fill={4284840068}
165
+ fill={
166
+ {
167
+ "payload": 4284840068,
168
+ "type": 0,
169
+ }
170
+ }
146
171
  propList={
147
172
  [
148
173
  "fill",
@@ -151,7 +176,12 @@ exports[`renders large arrowDown icon 1`] = `
151
176
  >
152
177
  <RNSVGPath
153
178
  d="M7.703 8.291a.996.996 0 0 0-1.41.001.994.994 0 0 0 0 1.41l5 5.005a.998.998 0 0 0 1.415 0l5-5a.994.994 0 0 0 0-1.41.995.995 0 0 0-1.411-.001L12 12.584 7.703 8.291Z"
154
- fill={4284840068}
179
+ fill={
180
+ {
181
+ "payload": 4284840068,
182
+ "type": 0,
183
+ }
184
+ }
155
185
  propList={
156
186
  [
157
187
  "fill",
@@ -196,7 +226,12 @@ exports[`renders quote icon with themed color 1`] = `
196
226
  vbWidth={24}
197
227
  >
198
228
  <RNSVGGroup
199
- fill={4286427150}
229
+ fill={
230
+ {
231
+ "payload": 4286427150,
232
+ "type": 0,
233
+ }
234
+ }
200
235
  propList={
201
236
  [
202
237
  "fill",
@@ -205,7 +240,12 @@ exports[`renders quote icon with themed color 1`] = `
205
240
  >
206
241
  <RNSVGPath
207
242
  d="M14 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm-2 0a1 1 0 1 0-2 0 1 1 0 0 0 2 0Z"
208
- fill={4286427150}
243
+ fill={
244
+ {
245
+ "payload": 4286427150,
246
+ "type": 0,
247
+ }
248
+ }
209
249
  propList={
210
250
  [
211
251
  "fill",
@@ -214,7 +254,12 @@ exports[`renders quote icon with themed color 1`] = `
214
254
  />
215
255
  <RNSVGPath
216
256
  d="M3.586 6C3.196 6.39 3 6.902 3 7.414c0 .512.195 1.024.586 1.414l.99.991C4.315 10.554 4 11.175 4 12a7 7 0 0 0 7 7h9v1a1 1 0 1 0 2 0v-2a1 1 0 0 0-1-1h-3v-5a7 7 0 0 0-7-7c-.825 0-1.446.314-2.18.577l-.992-.991A1.994 1.994 0 0 0 6.414 4c-.512 0-1.023.195-1.414.586L3.586 6Zm3.393.565A7.041 7.041 0 0 0 5.565 7.98L5 7.414 6.414 6l.565.565ZM11 7a5 5 0 0 1 5 5v5h-5a5 5 0 0 1 0-10Z"
217
- fill={4286427150}
257
+ fill={
258
+ {
259
+ "payload": 4286427150,
260
+ "type": 0,
261
+ }
262
+ }
218
263
  propList={
219
264
  [
220
265
  "fill",
@@ -259,7 +304,12 @@ exports[`renders small more icon 1`] = `
259
304
  vbWidth={24}
260
305
  >
261
306
  <RNSVGGroup
262
- fill={4284840068}
307
+ fill={
308
+ {
309
+ "payload": 4284840068,
310
+ "type": 0,
311
+ }
312
+ }
263
313
  propList={
264
314
  [
265
315
  "fill",
@@ -268,7 +318,12 @@ exports[`renders small more icon 1`] = `
268
318
  >
269
319
  <RNSVGPath
270
320
  d="M4 12a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm6 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm8-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z"
271
- fill={4284840068}
321
+ fill={
322
+ {
323
+ "payload": 4284840068,
324
+ "type": 0,
325
+ }
326
+ }
272
327
  propList={
273
328
  [
274
329
  "fill",
@@ -313,7 +368,12 @@ exports[`renders star icon with custom color 1`] = `
313
368
  vbWidth={24}
314
369
  >
315
370
  <RNSVGGroup
316
- fill={4284840068}
371
+ fill={
372
+ {
373
+ "payload": 4284840068,
374
+ "type": 0,
375
+ }
376
+ }
317
377
  propList={
318
378
  [
319
379
  "fill",
@@ -322,7 +382,12 @@ exports[`renders star icon with custom color 1`] = `
322
382
  >
323
383
  <RNSVGPath
324
384
  d="m15.673 13.337 3.673-3.58-5.076-.738-2.27-4.6-2.27 4.6-5.076.738 3.673 3.58-.867 5.176L12 16.006l4.54 2.386-.867-5.055ZM12 18.335l-4.505 2.49a1.546 1.546 0 0 1-2.244-1.63l.86-5.137-3.644-3.553a1.546 1.546 0 0 1 .857-2.637l5.037-.732 2.252-4.273a1.547 1.547 0 0 1 2.774 0l2.252 4.273 5.037.732a1.546 1.546 0 0 1 .857 2.637l-3.645 3.553.86 5.139a1.547 1.547 0 0 1-2.243 1.63L12 18.334Z"
325
- fill={4294128419}
385
+ fill={
386
+ {
387
+ "payload": 4294128419,
388
+ "type": 0,
389
+ }
390
+ }
326
391
  propList={
327
392
  [
328
393
  "fill",
@@ -372,16 +437,11 @@ exports[`renders thumbsDown icon 1`] = `
372
437
  vbWidth={24}
373
438
  >
374
439
  <RNSVGGroup
375
- fill={4284840068}
376
- matrix={
377
- [
378
- 1,
379
- 0,
380
- 0,
381
- 1,
382
- 0,
383
- 0,
384
- ]
440
+ fill={
441
+ {
442
+ "payload": 4284840068,
443
+ "type": 0,
444
+ }
385
445
  }
386
446
  propList={
387
447
  [
@@ -391,7 +451,12 @@ exports[`renders thumbsDown icon 1`] = `
391
451
  >
392
452
  <RNSVGPath
393
453
  d="M8 11.78V19h8l3-5.76v-1.29h-7.639l1.036-7.944L8 11.78ZM6.134 11l4.555-8.034c1.124-1.846 3.971-.844 3.691 1.299l-.74 5.685h6.86a.5.5 0 0 1 .5.5v3a1 1 0 0 1-.084.4l-3.276 6.648a.95.95 0 0 1-.44.453c-.132.065-.276.049-.423.049H4c-1.105 0-2-1.045-2-2.15V13a2 2 0 0 1 2-2h2.134ZM6 13H4v6h2v-6Z"
394
- fill={4284840068}
454
+ fill={
455
+ {
456
+ "payload": 4284840068,
457
+ "type": 0,
458
+ }
459
+ }
395
460
  propList={
396
461
  [
397
462
  "fill",
@@ -46,10 +46,11 @@ export interface InputCurrencyProps
46
46
  readonly maxLength?: number;
47
47
 
48
48
  onChange?(newValue?: number | string | undefined): void;
49
- value?: number;
50
- defaultValue?: number;
51
- keyboard?: "decimal-pad" | "numbers-and-punctuation";
49
+ readonly value?: number;
50
+ readonly defaultValue?: number;
51
+ readonly keyboard?: "decimal-pad" | "numbers-and-punctuation";
52
52
  }
53
+
53
54
  export const getInternalValue = (
54
55
  props: InputCurrencyProps,
55
56
  field: ControllerRenderProps<FieldValues, string>,
@@ -59,6 +60,7 @@ export const getInternalValue = (
59
60
  ) => string,
60
61
  ): string => {
61
62
  if (!props.value && !field.value) return "";
63
+
62
64
  return (
63
65
  props.value?.toString() ??
64
66
  formatNumber(field.value, {
@@ -113,6 +115,7 @@ export function InputCurrency(props: InputCurrencyProps): JSX.Element {
113
115
  decimalNumbers !== ""
114
116
  ? transformedValue.toString() + "." + decimalNumbers.slice(1)
115
117
  : transformedValue.toString();
118
+
116
119
  if (checkLastChar(stringValue)) {
117
120
  const roundedDecimal = configureDecimal(
118
121
  decimalCount,
@@ -167,40 +170,39 @@ export function InputCurrency(props: InputCurrencyProps): JSX.Element {
167
170
  const { t } = useAtlantisI18n();
168
171
 
169
172
  return (
170
- <>
171
- <InputText
172
- {...props}
173
- prefix={showCurrencySymbol ? { label: currencySymbol } : undefined}
174
- keyboard={getKeyboard(props)}
175
- value={props.value?.toString() || displayValue}
176
- defaultValue={props.defaultValue?.toString()}
177
- onChangeText={handleChange}
178
- transform={{
179
- output: val => {
180
- return val
181
- ?.split(floatSeparators.group)
182
- .join("")
183
- .replace(floatSeparators.decimal, ".");
184
- },
185
- }}
186
- validations={{
187
- pattern: {
188
- value: NUMBER_VALIDATION_REGEX,
189
- message: t("errors.notANumber"),
190
- },
191
- ...props.validations,
192
- }}
193
- onBlur={() => {
194
- props.onBlur?.();
195
- if (
196
- field.value === 0 ||
197
- field.value === "" ||
198
- field.value === undefined
199
- ) {
200
- setDisplayValue("0");
201
- }
202
- }}
203
- />
204
- </>
173
+ <InputText
174
+ {...props}
175
+ prefix={showCurrencySymbol ? { label: currencySymbol } : undefined}
176
+ keyboard={getKeyboard(props)}
177
+ value={props.value?.toString() || displayValue}
178
+ defaultValue={props.defaultValue?.toString()}
179
+ onChangeText={handleChange}
180
+ transform={{
181
+ output: val => {
182
+ return val
183
+ ?.split(floatSeparators.group)
184
+ .join("")
185
+ .replace(floatSeparators.decimal, ".");
186
+ },
187
+ }}
188
+ validations={{
189
+ pattern: {
190
+ value: NUMBER_VALIDATION_REGEX,
191
+ message: t("errors.notANumber"),
192
+ },
193
+ ...props.validations,
194
+ }}
195
+ onBlur={() => {
196
+ props.onBlur?.();
197
+
198
+ if (
199
+ field.value === 0 ||
200
+ field.value === "" ||
201
+ field.value === undefined
202
+ ) {
203
+ setDisplayValue("0");
204
+ }
205
+ }}
206
+ />
205
207
  );
206
208
  }
@@ -1,5 +1,6 @@
1
1
  export function countDecimal(value: number): number {
2
2
  const convertedValue = value.toString();
3
+
3
4
  if (convertedValue.includes(".")) {
4
5
  return convertedValue.split(".")[1].length;
5
6
  }
@@ -12,10 +13,13 @@ export function limitInputWholeDigits(
12
13
  maxInputLength: number,
13
14
  ): number {
14
15
  let convertedValue = value.toString();
16
+
15
17
  if (convertedValue.length > maxInputLength) {
16
18
  convertedValue = convertedValue.slice(0, maxInputLength);
19
+
17
20
  return parseFloat(convertedValue);
18
21
  }
22
+
19
23
  return value;
20
24
  }
21
25
 
@@ -32,19 +36,23 @@ export function configureDecimal(
32
36
  const precision = 10 ** targetDecimalPlaces;
33
37
  const convertedValue =
34
38
  Math.round(parseFloat(transformedValue) * precision) / precision;
39
+
35
40
  return convertedValue;
36
41
  }
37
42
 
38
43
  export function convertToNumber(value: string): string | number {
39
44
  const regexValidation = /^[0-9]*$/;
45
+
40
46
  if (value?.match?.(regexValidation)) {
41
47
  return parseFloat(value);
42
48
  }
49
+
43
50
  return value;
44
51
  }
45
52
 
46
53
  export const checkLastChar = (stringValue: string): boolean => {
47
54
  const lastChar = stringValue[stringValue.length - 1];
55
+
48
56
  return Boolean(Number(stringValue)) && lastChar !== "0" && lastChar !== ".";
49
57
  };
50
58
 
@@ -85,6 +93,7 @@ export const parseGivenInput = (
85
93
  wholeIntegerValue = splittedValue[0];
86
94
  decimalNumbers = getDecimalNumbers(value, decimalSeparator);
87
95
  }
96
+
88
97
  return [decimalCount, wholeIntegerValue, decimalNumbers];
89
98
  };
90
99
 
@@ -139,6 +139,7 @@ describe("InputDate", () => {
139
139
  const saveButtonText = "Submit";
140
140
 
141
141
  const requiredError = "This is required";
142
+
142
143
  function SimpleFormWithProvider({ children, defaultValues }) {
143
144
  const formMethods = useForm({
144
145
  reValidateMode: "onChange",
@@ -4,7 +4,17 @@ import { tokens } from "../utils/design";
4
4
  import { typographyStyles } from "../Typography";
5
5
 
6
6
  export const styles = StyleSheet.create({
7
- container: StyleSheet.flatten([commonInputStyles.container]),
7
+ container: StyleSheet.flatten([
8
+ commonInputStyles.container,
9
+ {
10
+ flexDirection: "column",
11
+ },
12
+ ]),
13
+
14
+ field: {
15
+ flexDirection: "row",
16
+ alignItems: "center",
17
+ },
8
18
 
9
19
  inputContainer: {
10
20
  flexDirection: "row",
@@ -35,6 +45,7 @@ export const styles = StyleSheet.create({
35
45
  top: 0,
36
46
  paddingTop: tokens["space-small"] - tokens["space-smallest"],
37
47
  backgroundColor: tokens["color-surface"],
48
+ marginRight: tokens["space-small"],
38
49
  maxHeight:
39
50
  (typographyStyles.defaultSize.lineHeight || 0) + tokens["space-smaller"],
40
51
  zIndex: 1,
@@ -82,14 +93,48 @@ export const styles = StyleSheet.create({
82
93
  paddingTop: tokens["space-minuscule"],
83
94
  paddingRight: tokens["space-small"],
84
95
  },
96
+
85
97
  suffixIconMargin: {
86
98
  marginLeft: tokens["space-small"] + tokens["space-smaller"],
87
99
  },
100
+
88
101
  suffixLabelMargin: {
89
102
  marginLeft: tokens["space-smallest"],
90
103
  },
104
+
91
105
  inputEndContainer: {
92
106
  flexDirection: "row",
93
107
  zIndex: 1,
94
108
  },
109
+
110
+ toolbar: {
111
+ flexBasis: "100%",
112
+ flexDirection: "row",
113
+ gap: tokens["space-small"],
114
+ paddingBottom: tokens["space-small"],
115
+ },
116
+
117
+ loadingSpinner: {
118
+ justifyContent: "center",
119
+ paddingRight: tokens["space-small"],
120
+ },
121
+
122
+ loadingGlimmers: {
123
+ position: "absolute",
124
+ top: tokens["space-base"],
125
+ bottom: tokens["space-base"],
126
+ left: 0,
127
+ right: 0,
128
+ gap: tokens["space-small"],
129
+ paddingTop: tokens["space-small"],
130
+ paddingRight: tokens["space-large"],
131
+ backgroundColor: tokens["color-surface"],
132
+ overflow: "hidden",
133
+ },
134
+
135
+ loadingGlimmersHasValue: {
136
+ top: tokens["space-large"],
137
+ paddingTop: tokens["space-base"] - tokens["space-smaller"],
138
+ bottom: tokens["space-smaller"],
139
+ },
95
140
  });
@@ -8,6 +8,10 @@ import {
8
8
  commonInputStyles,
9
9
  } from ".";
10
10
  import { styles } from "./InputFieldWrapper.style";
11
+ import {
12
+ INPUT_FIELD_WRAPPER_GLIMMERS_TEST_ID,
13
+ INPUT_FIELD_WRAPPER_SPINNER_TEST_ID,
14
+ } from "./InputFieldWrapper";
11
15
  import { typographyStyles } from "../Typography";
12
16
 
13
17
  const mockLabel = { label: "$" };
@@ -31,6 +35,7 @@ function renderWithSuffixLabel(hasValue: boolean): RenderAPI {
31
35
  }
32
36
 
33
37
  const clearInput = "Clear input";
38
+ // eslint-disable-next-line max-statements
34
39
  describe("InputFieldWrapper", () => {
35
40
  it("renders an invalid InputFieldWrapper", () => {
36
41
  const { getByTestId } = renderInputFieldWrapper({ invalid: true });
@@ -147,6 +152,7 @@ describe("InputFieldWrapper", () => {
147
152
  const container = getByTestId("ATL-InputFieldWrapper");
148
153
  expect(container.props.style).toContainEqual({
149
154
  ...commonInputStyles.container,
155
+ flexDirection: "column",
150
156
  });
151
157
  });
152
158
 
@@ -225,4 +231,72 @@ describe("InputFieldWrapper", () => {
225
231
  );
226
232
  });
227
233
  });
234
+
235
+ describe("Toolbar", () => {
236
+ it("renders a toolbar on focused", () => {
237
+ const { getByText } = renderInputFieldWrapper({
238
+ focused: true,
239
+ toolbar: <Text>I am a tool</Text>,
240
+ });
241
+ expect(getByText("I am a tool")).toBeDefined();
242
+ });
243
+
244
+ it("does not render a toolbar when not focused", () => {
245
+ const { queryByText } = renderInputFieldWrapper({
246
+ focused: false,
247
+ toolbar: <Text>I am a tool</Text>,
248
+ });
249
+ expect(queryByText("I am a tool")).toBeNull();
250
+ });
251
+
252
+ it("does not render a toolbar when focused and toolbar is not provided", () => {
253
+ const { getByText, queryByText, rerender } = renderInputFieldWrapper({
254
+ focused: true,
255
+ toolbar: <Text>I am a tool</Text>,
256
+ });
257
+ expect(getByText("I am a tool")).toBeDefined();
258
+
259
+ rerender(
260
+ <InputFieldWrapper focused={true}>
261
+ <Text>Test</Text>
262
+ </InputFieldWrapper>,
263
+ );
264
+
265
+ expect(queryByText("I am a tool")).toBeNull();
266
+ });
267
+
268
+ it("renders a toolbar when toolbarVisibility is always", () => {
269
+ const { getByText } = renderInputFieldWrapper({
270
+ focused: false,
271
+ toolbar: <Text>I am a tool</Text>,
272
+ toolbarVisibility: "always",
273
+ });
274
+ expect(getByText("I am a tool")).toBeDefined();
275
+ });
276
+ });
277
+
278
+ describe("Loading state", () => {
279
+ it("does not render any loading indicators", () => {
280
+ const { queryByTestId } = renderInputFieldWrapper({});
281
+ expect(queryByTestId(INPUT_FIELD_WRAPPER_SPINNER_TEST_ID)).toBeNull();
282
+ expect(queryByTestId(INPUT_FIELD_WRAPPER_GLIMMERS_TEST_ID)).toBeNull();
283
+ });
284
+
285
+ it("renders a loading spinner by default when loading is true and loadingType is not set", () => {
286
+ const { getByTestId, queryByTestId } = renderInputFieldWrapper({
287
+ loading: true,
288
+ });
289
+ expect(getByTestId(INPUT_FIELD_WRAPPER_SPINNER_TEST_ID)).toBeDefined();
290
+ expect(queryByTestId(INPUT_FIELD_WRAPPER_GLIMMERS_TEST_ID)).toBeNull();
291
+ });
292
+
293
+ it("renders a glimmer when loading is true and loadingType is glimmer", () => {
294
+ const { getByTestId, queryByTestId } = renderInputFieldWrapper({
295
+ loading: true,
296
+ loadingType: "glimmer",
297
+ });
298
+ expect(getByTestId(INPUT_FIELD_WRAPPER_GLIMMERS_TEST_ID)).toBeDefined();
299
+ expect(queryByTestId(INPUT_FIELD_WRAPPER_SPINNER_TEST_ID)).toBeNull();
300
+ });
301
+ });
228
302
  });