@jobber/components-native 0.84.4-JOB-134681-8086ad4.25 → 0.84.4-JOB-138679-b1552ab.68

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 (278) hide show
  1. package/dist/package.json +23 -14
  2. package/dist/src/ActionItem/ActionItemGroup.js +1 -1
  3. package/dist/src/AutoLink/components/Link/Link.js +1 -1
  4. package/dist/src/Banner/Banner.js +2 -0
  5. package/dist/src/Banner/components/BannerIcon/BannerIcon.style.js +3 -0
  6. package/dist/src/BottomSheet/BottomSheet.js +2 -2
  7. package/dist/src/Button/components/InternalButtonLoading/InternalButtonLoading.js +0 -1
  8. package/dist/src/ButtonGroup/ButtonGroup.js +1 -1
  9. package/dist/src/ContentOverlay/ContentOverlay.js +5 -7
  10. package/dist/src/ContentOverlay/UNSAFE_WrappedModalize.js +23 -0
  11. package/dist/src/ErrorMessageWrapper/context/ErrorMessageProvider.js +1 -1
  12. package/dist/src/Form/Form.js +5 -2
  13. package/dist/src/Form/components/FormCache/FormCache.js +1 -0
  14. package/dist/src/Form/components/FormMessageBanner/FormMessageBanner.js +1 -1
  15. package/dist/src/Form/context/AtlantisFormContext.js +1 -0
  16. package/dist/src/Form/hooks/useInternalForm.js +6 -3
  17. package/dist/src/FormatFile/components/MediaView/MediaView.js +22 -5
  18. package/dist/src/FormatFile/utils/createUseCreateThumbnail.js +1 -1
  19. package/dist/src/InputCurrency/InputCurrency.js +42 -30
  20. package/dist/src/InputDate/InputDate.js +2 -2
  21. package/dist/src/InputEmail/InputEmail.js +12 -4
  22. package/dist/src/InputFieldWrapper/InputFieldWrapper.js +14 -12
  23. package/dist/src/InputFieldWrapper/InputFieldWrapper.style.js +1 -1
  24. package/dist/src/InputFieldWrapper/components/Prefix/Prefix.js +5 -2
  25. package/dist/src/InputFieldWrapper/components/Suffix/Suffix.js +5 -2
  26. package/dist/src/InputNumber/InputNumber.js +10 -4
  27. package/dist/src/InputPressable/InputPressable.js +20 -8
  28. package/dist/src/InputPressable/InputPressable.style.js +3 -0
  29. package/dist/src/InputSearch/InputSearch.js +1 -1
  30. package/dist/src/InputText/InputText.js +22 -11
  31. package/dist/src/InputText/InputText.style.js +4 -0
  32. package/dist/src/InputTime/InputTime.js +2 -2
  33. package/dist/src/Menu/Menu.js +2 -2
  34. package/dist/src/Select/Select.style.js +1 -0
  35. package/dist/src/Select/components/SelectPressable/SelectPressable.js +1 -1
  36. package/dist/src/Switch/components/BaseSwitch/BaseSwitch.js +7 -1
  37. package/dist/src/Typography/Typography.js +16 -5
  38. package/dist/src/hooks/useAtlantisI18n/locales/en.json +1 -0
  39. package/dist/src/hooks/useAtlantisI18n/locales/es.json +1 -0
  40. package/dist/src/hooks/useFormController.js +5 -14
  41. package/dist/tsconfig.build.json +7 -0
  42. package/dist/tsconfig.build.tsbuildinfo +1 -0
  43. package/dist/tsconfig.json +4 -6
  44. package/dist/types/src/ActionItem/ActionItem.d.ts +2 -1
  45. package/dist/types/src/ActionItem/ActionItemGroup.d.ts +2 -1
  46. package/dist/types/src/ActionItem/components/ActionItemContainer.d.ts +2 -1
  47. package/dist/types/src/ActionLabel/ActionLabel.d.ts +4 -3
  48. package/dist/types/src/ActivityIndicator/ActivityIndicator.d.ts +2 -1
  49. package/dist/types/src/AutoLink/AutoLink.d.ts +2 -1
  50. package/dist/types/src/AutoLink/components/ComposeTextWithLinks/ComposeTextWithLinks.d.ts +2 -1
  51. package/dist/types/src/AutoLink/components/Link/Link.d.ts +2 -1
  52. package/dist/types/src/Banner/Banner.d.ts +2 -1
  53. package/dist/types/src/Banner/components/BannerIcon/BannerIcon.d.ts +2 -1
  54. package/dist/types/src/Banner/components/BannerIcon/BannerIcon.style.d.ts +3 -0
  55. package/dist/types/src/Banner/types.d.ts +1 -1
  56. package/dist/types/src/BottomSheet/BottomSheet.d.ts +1 -1
  57. package/dist/types/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.d.ts +2 -1
  58. package/dist/types/src/Button/Button.d.ts +2 -1
  59. package/dist/types/src/Button/components/InternalButtonLoading/InternalButtonLoading.d.ts +1 -1
  60. package/dist/types/src/ButtonGroup/ButtonGroup.d.ts +2 -1
  61. package/dist/types/src/ButtonGroup/ButtonGroupAction.d.ts +4 -3
  62. package/dist/types/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.d.ts +3 -2
  63. package/dist/types/src/Card/Card.d.ts +2 -1
  64. package/dist/types/src/Card/components/InternalCardHeader.d.ts +2 -1
  65. package/dist/types/src/Checkbox/Checkbox.d.ts +2 -1
  66. package/dist/types/src/Checkbox/CheckboxGroup.d.ts +2 -1
  67. package/dist/types/src/Chip/Chip.d.ts +2 -1
  68. package/dist/types/src/Content/Content.d.ts +2 -1
  69. package/dist/types/src/ContentOverlay/ContentOverlay.d.ts +1 -1
  70. package/dist/types/src/ContentOverlay/UNSAFE_WrappedModalize.d.ts +3 -0
  71. package/dist/types/src/Disclosure/Disclosure.d.ts +1 -1
  72. package/dist/types/src/Divider/Divider.d.ts +2 -1
  73. package/dist/types/src/EmptyState/EmptyState.d.ts +2 -1
  74. package/dist/types/src/ErrorMessageWrapper/ErrorMessageWrapper.d.ts +2 -1
  75. package/dist/types/src/ErrorMessageWrapper/context/ErrorMessageProvider.d.ts +2 -1
  76. package/dist/types/src/ErrorMessageWrapper/context/types.d.ts +1 -1
  77. package/dist/types/src/Flex/Flex.d.ts +2 -1
  78. package/dist/types/src/Form/Form.d.ts +2 -1
  79. package/dist/types/src/Form/components/FormActionBar/FormActionBar.d.ts +3 -2
  80. package/dist/types/src/Form/components/FormBody/FormBody.d.ts +3 -2
  81. package/dist/types/src/Form/components/FormCache/FormCache.d.ts +4 -3
  82. package/dist/types/src/Form/components/FormErrorBanner/FormErrorBanner.d.ts +2 -1
  83. package/dist/types/src/Form/components/FormMask/FormMask.d.ts +2 -1
  84. package/dist/types/src/Form/components/FormMessage/FormMessage.d.ts +2 -1
  85. package/dist/types/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.d.ts +2 -1
  86. package/dist/types/src/Form/components/FormMessageBanner/FormMessageBanner.d.ts +2 -1
  87. package/dist/types/src/Form/components/FormSaveButton/FormSaveButton.d.ts +2 -1
  88. package/dist/types/src/Form/context/AtlantisFormContext.d.ts +2 -1
  89. package/dist/types/src/Form/context/types.d.ts +3 -2
  90. package/dist/types/src/Form/hooks/useFormViewRefs.d.ts +2 -2
  91. package/dist/types/src/Form/hooks/useInternalForm.d.ts +5 -5
  92. package/dist/types/src/Form/types.d.ts +13 -7
  93. package/dist/types/src/FormField/FormField.d.ts +1 -1
  94. package/dist/types/src/FormatFile/FormatFile.d.ts +2 -1
  95. package/dist/types/src/FormatFile/components/ErrorIcon/ErrorIcon.d.ts +2 -1
  96. package/dist/types/src/FormatFile/components/FileView/FileView.d.ts +2 -1
  97. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.d.ts +3 -2
  98. package/dist/types/src/FormatFile/components/MediaView/MediaView.d.ts +2 -1
  99. package/dist/types/src/FormatFile/components/ProgressBar/ProgressBar.d.ts +2 -1
  100. package/dist/types/src/Heading/Heading.d.ts +4 -3
  101. package/dist/types/src/Icon/Icon.d.ts +2 -1
  102. package/dist/types/src/IconButton/IconButton.d.ts +1 -1
  103. package/dist/types/src/InputCurrency/InputCurrency.d.ts +2 -1
  104. package/dist/types/src/InputDate/InputDate.d.ts +4 -2
  105. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.d.ts +9 -2
  106. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.style.d.ts +1 -1
  107. package/dist/types/src/InputFieldWrapper/components/ClearAction/ClearAction.d.ts +2 -1
  108. package/dist/types/src/InputFieldWrapper/components/Prefix/Prefix.d.ts +4 -4
  109. package/dist/types/src/InputFieldWrapper/components/Suffix/Suffix.d.ts +4 -4
  110. package/dist/types/src/InputPressable/InputPressable.d.ts +9 -1
  111. package/dist/types/src/InputPressable/InputPressable.style.d.ts +3 -0
  112. package/dist/types/src/InputSearch/InputSearch.d.ts +1 -1
  113. package/dist/types/src/InputSearch/components/FilterButton.d.ts +2 -1
  114. package/dist/types/src/InputText/InputText.d.ts +10 -2
  115. package/dist/types/src/InputText/InputText.style.d.ts +4 -0
  116. package/dist/types/src/InputText/context/InputAccessoriesProvider.d.ts +2 -1
  117. package/dist/types/src/InputTime/InputTime.d.ts +4 -2
  118. package/dist/types/src/Menu/Menu.d.ts +2 -1
  119. package/dist/types/src/Menu/components/MenuOption/MenuOption.d.ts +2 -1
  120. package/dist/types/src/Menu/components/Overlay/Overlay.d.ts +2 -1
  121. package/dist/types/src/Menu/types.d.ts +6 -1
  122. package/dist/types/src/ProgressBar/ProgressBar.d.ts +2 -1
  123. package/dist/types/src/ProgressBar/ProgressBarInner.d.ts +2 -1
  124. package/dist/types/src/Select/Select.d.ts +3 -2
  125. package/dist/types/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.d.ts +2 -1
  126. package/dist/types/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.d.ts +2 -1
  127. package/dist/types/src/Select/components/SelectInternalPicker/SelectInternalPicker.d.ts +2 -1
  128. package/dist/types/src/Select/components/SelectPressable/SelectPressable.d.ts +2 -1
  129. package/dist/types/src/StatusLabel/StatusLabel.d.ts +2 -1
  130. package/dist/types/src/Switch/Switch.d.ts +2 -1
  131. package/dist/types/src/Switch/components/BaseSwitch/BaseSwitch.d.ts +2 -1
  132. package/dist/types/src/Text/Text.d.ts +4 -3
  133. package/dist/types/src/TextList/TextList.d.ts +2 -1
  134. package/dist/types/src/ThumbnailList/ThumbnailList.d.ts +2 -1
  135. package/dist/types/src/Toast/Toast.d.ts +2 -1
  136. package/dist/types/src/Typography/Typography.d.ts +3 -3
  137. package/dist/types/src/Typography/TypographyGestureDetector.d.ts +2 -1
  138. package/dist/types/src/utils/test/MockSafeAreaProvider.d.ts +1 -1
  139. package/package.json +23 -14
  140. package/src/ActionItem/ActionItem.tsx +1 -1
  141. package/src/ActionItem/ActionItemGroup.tsx +1 -3
  142. package/src/ActionItem/components/ActionItemContainer.tsx +1 -1
  143. package/src/ActionLabel/ActionLabel.test.tsx +12 -0
  144. package/src/ActionLabel/ActionLabel.tsx +3 -3
  145. package/src/ActionLabel/__snapshots__/ActionLabel.test.tsx.snap +66 -0
  146. package/src/ActivityIndicator/ActivityIndicator.tsx +1 -3
  147. package/src/AtlantisContext/AtlantisContext.test.tsx +1 -1
  148. package/src/AtlantisThemeContext/AtlantisThemeContext.test.tsx +5 -5
  149. package/src/AutoLink/AutoLink.test.tsx +2 -4
  150. package/src/AutoLink/AutoLink.tsx +1 -1
  151. package/src/AutoLink/components/ComposeTextWithLinks/ComposeTextWithLinks.tsx +1 -1
  152. package/src/AutoLink/components/Link/Link.tsx +1 -5
  153. package/src/Banner/Banner.test.tsx +12 -0
  154. package/src/Banner/Banner.tsx +4 -2
  155. package/src/Banner/components/BannerIcon/BannerIcon.style.ts +3 -0
  156. package/src/Banner/components/BannerIcon/BannerIcon.tsx +1 -1
  157. package/src/Banner/types.ts +1 -1
  158. package/src/BottomSheet/BottomSheet.test.tsx +17 -17
  159. package/src/BottomSheet/BottomSheet.tsx +4 -3
  160. package/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.tsx +1 -1
  161. package/src/Button/Button.tsx +1 -1
  162. package/src/Button/components/InternalButtonLoading/InternalButtonLoading.tsx +1 -2
  163. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -11
  164. package/src/ButtonGroup/ButtonGroup.tsx +2 -2
  165. package/src/ButtonGroup/ButtonGroupAction.tsx +4 -4
  166. package/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.tsx +2 -2
  167. package/src/Card/Card.tsx +1 -1
  168. package/src/Card/components/InternalCardHeader.tsx +1 -1
  169. package/src/Checkbox/Checkbox.tsx +2 -2
  170. package/src/Checkbox/CheckboxGroup.test.tsx +3 -7
  171. package/src/Checkbox/CheckboxGroup.tsx +2 -2
  172. package/src/Chip/Chip.tsx +1 -1
  173. package/src/Content/Content.tsx +1 -1
  174. package/src/ContentOverlay/ContentOverlay.test.tsx +34 -27
  175. package/src/ContentOverlay/ContentOverlay.tsx +7 -7
  176. package/src/ContentOverlay/UNSAFE_WrappedModalize.tsx +41 -0
  177. package/src/ContentOverlay/hooks/useKeyboardVisibility.test.ts +7 -7
  178. package/src/ContentOverlay/hooks/useViewLayoutHeight.test.ts +1 -1
  179. package/src/Disclosure/Disclosure.tsx +1 -1
  180. package/src/Divider/Divider.tsx +1 -1
  181. package/src/EmptyState/EmptyState.test.tsx +29 -42
  182. package/src/EmptyState/EmptyState.tsx +1 -1
  183. package/src/ErrorMessageWrapper/ErrorMessageWrapper.tsx +1 -1
  184. package/src/ErrorMessageWrapper/context/ErrorMessageProvider.tsx +3 -5
  185. package/src/ErrorMessageWrapper/context/types.ts +1 -1
  186. package/src/Flex/Flex.tsx +2 -2
  187. package/src/Form/Form.test.tsx +145 -2
  188. package/src/Form/Form.tsx +8 -1
  189. package/src/Form/components/FormActionBar/FormActionBar.tsx +3 -3
  190. package/src/Form/components/FormBody/FormBody.tsx +3 -3
  191. package/src/Form/components/FormCache/FormCache.tsx +5 -4
  192. package/src/Form/components/FormErrorBanner/FormErrorBanner.tsx +1 -1
  193. package/src/Form/components/FormMask/FormMask.tsx +1 -1
  194. package/src/Form/components/FormMessage/FormMessage.test.tsx +40 -27
  195. package/src/Form/components/FormMessage/FormMessage.tsx +1 -1
  196. package/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.tsx +1 -1
  197. package/src/Form/components/FormMessageBanner/FormMessageBanner.tsx +1 -3
  198. package/src/Form/components/FormSaveButton/FormSaveButton.test.tsx +2 -2
  199. package/src/Form/components/FormSaveButton/FormSaveButton.tsx +1 -1
  200. package/src/Form/context/AtlantisFormContext.test.tsx +1 -1
  201. package/src/Form/context/AtlantisFormContext.tsx +1 -0
  202. package/src/Form/context/types.ts +3 -2
  203. package/src/Form/hooks/useFormViewRefs.ts +4 -5
  204. package/src/Form/hooks/useInternalForm.ts +12 -4
  205. package/src/Form/hooks/useScrollToError/useScrollToError.test.tsx +2 -1
  206. package/src/Form/types.ts +14 -8
  207. package/src/FormField/FormField.tsx +1 -1
  208. package/src/FormatFile/FormatFile.test.tsx +21 -21
  209. package/src/FormatFile/FormatFile.tsx +3 -3
  210. package/src/FormatFile/components/ErrorIcon/ErrorIcon.tsx +1 -1
  211. package/src/FormatFile/components/FileView/FileView.tsx +1 -1
  212. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.tsx +14 -14
  213. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +2 -2
  214. package/src/FormatFile/components/MediaView/MediaView.test.tsx +283 -0
  215. package/src/FormatFile/components/MediaView/MediaView.tsx +28 -7
  216. package/src/FormatFile/components/ProgressBar/ProgressBar.tsx +1 -1
  217. package/src/FormatFile/utils/createUseCreateThumbnail.ts +1 -1
  218. package/src/Glimmer/Glimmer.test.tsx +2 -2
  219. package/src/Heading/Heading.test.tsx +13 -0
  220. package/src/Heading/Heading.tsx +3 -3
  221. package/src/Heading/__snapshots__/Heading.test.tsx.snap +65 -0
  222. package/src/Icon/Icon.tsx +1 -1
  223. package/src/Icon/__snapshots__/Icon.test.tsx.snap +7 -0
  224. package/src/IconButton/IconButton.tsx +1 -1
  225. package/src/InputCurrency/InputCurrency.tsx +72 -58
  226. package/src/InputDate/InputDate.tsx +7 -3
  227. package/src/InputEmail/InputEmail.tsx +15 -8
  228. package/src/InputFieldWrapper/InputFieldWrapper.style.ts +1 -1
  229. package/src/InputFieldWrapper/InputFieldWrapper.test.tsx +48 -1
  230. package/src/InputFieldWrapper/InputFieldWrapper.tsx +39 -29
  231. package/src/InputFieldWrapper/components/ClearAction/ClearAction.tsx +1 -1
  232. package/src/InputFieldWrapper/components/Prefix/Prefix.test.tsx +8 -16
  233. package/src/InputFieldWrapper/components/Prefix/Prefix.tsx +8 -6
  234. package/src/InputFieldWrapper/components/Suffix/Suffix.test.tsx +2 -4
  235. package/src/InputFieldWrapper/components/Suffix/Suffix.tsx +8 -6
  236. package/src/InputNumber/InputNumber.tsx +11 -7
  237. package/src/InputPassword/InputPassword.tsx +1 -1
  238. package/src/InputPressable/InputPressable.style.ts +4 -0
  239. package/src/InputPressable/InputPressable.test.tsx +75 -1
  240. package/src/InputPressable/InputPressable.tsx +34 -8
  241. package/src/InputSearch/InputSearch.tsx +2 -1
  242. package/src/InputSearch/components/FilterButton.tsx +1 -1
  243. package/src/InputText/InputText.style.ts +5 -0
  244. package/src/InputText/InputText.test.tsx +75 -0
  245. package/src/InputText/InputText.tsx +34 -17
  246. package/src/InputText/context/InputAccessoriesProvider.tsx +1 -1
  247. package/src/InputTime/InputTime.tsx +7 -3
  248. package/src/Menu/Menu.tsx +3 -3
  249. package/src/Menu/components/MenuOption/MenuOption.tsx +1 -1
  250. package/src/Menu/components/Overlay/Overlay.tsx +1 -1
  251. package/src/Menu/types.ts +7 -1
  252. package/src/ProgressBar/ProgressBar.tsx +1 -1
  253. package/src/ProgressBar/ProgressBarInner.tsx +1 -1
  254. package/src/Select/Select.style.ts +1 -0
  255. package/src/Select/Select.tsx +2 -2
  256. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.tsx +1 -1
  257. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.tsx +1 -1
  258. package/src/Select/components/SelectInternalPicker/SelectInternalPicker.tsx +1 -1
  259. package/src/Select/components/SelectPressable/SelectPressable.tsx +1 -4
  260. package/src/StatusLabel/StatusLabel.tsx +1 -1
  261. package/src/Switch/Switch.tsx +1 -1
  262. package/src/Switch/components/BaseSwitch/BaseSwitch.tsx +8 -2
  263. package/src/Text/Text.test.tsx +10 -0
  264. package/src/Text/Text.tsx +3 -3
  265. package/src/Text/__snapshots__/Text.test.tsx.snap +66 -0
  266. package/src/TextList/TextList.tsx +1 -1
  267. package/src/ThumbnailList/ThumbnailList.test.tsx +5 -5
  268. package/src/ThumbnailList/ThumbnailList.tsx +1 -1
  269. package/src/Toast/Toast.tsx +2 -2
  270. package/src/Typography/Typography.test.tsx +61 -0
  271. package/src/Typography/Typography.tsx +25 -9
  272. package/src/Typography/TypographyGestureDetector.tsx +1 -3
  273. package/src/Typography/__snapshots__/Typography.test.tsx.snap +222 -0
  274. package/src/hooks/useAtlantisI18n/locales/en.json +1 -0
  275. package/src/hooks/useAtlantisI18n/locales/es.json +1 -0
  276. package/src/hooks/useFormController.ts +6 -13
  277. package/src/utils/test/MockSafeAreaProvider.tsx +1 -1
  278. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,5 +1,5 @@
1
1
  import type { Ref } from "react";
2
- import React, { forwardRef, useEffect, useState } from "react";
2
+ import React, { forwardRef } from "react";
3
3
  import type { IconNames } from "@jobber/design";
4
4
  import type { FieldError } from "react-hook-form";
5
5
  import { Text as NativeText, Pressable } from "react-native";
@@ -7,6 +7,7 @@ import type { Clearable } from "@jobber/hooks";
7
7
  import { useShowClear } from "@jobber/hooks";
8
8
  import type { XOR } from "ts-xor";
9
9
  import { useStyles } from "./InputPressable.style";
10
+ import type { InputFieldWrapperProps } from "../InputFieldWrapper";
10
11
  import { InputFieldWrapper, useCommonInputStyles } from "../InputFieldWrapper";
11
12
 
12
13
  interface BasicSuffix {
@@ -51,6 +52,15 @@ export interface InputPressableProps {
51
52
  */
52
53
  readonly invalid?: boolean | string;
53
54
 
55
+ /**
56
+ * Controls the visibility of the mini label that appears inside the input
57
+ * when a value is entered. By default, the placeholder text moves up to
58
+ * become a mini label. Set to false to disable this behavior.
59
+ *
60
+ * @default true
61
+ */
62
+ readonly showMiniLabel?: boolean;
63
+
54
64
  /**
55
65
  * Callback that is called when the text input is focused
56
66
  * @param event
@@ -105,6 +115,7 @@ export function InputPressableInternal(
105
115
  disabled,
106
116
  invalid,
107
117
  error,
118
+ showMiniLabel = true,
108
119
  onPress,
109
120
  accessibilityLabel,
110
121
  accessibilityHint,
@@ -115,13 +126,10 @@ export function InputPressableInternal(
115
126
  focused,
116
127
  }: InputPressableProps,
117
128
  ref: Ref<InputPressableRef>,
118
- ): JSX.Element {
129
+ ) {
119
130
  const hasValue = !!value;
120
- const [hasMiniLabel, setHasMiniLabel] = useState(Boolean(value));
121
131
 
122
- useEffect(() => {
123
- setHasMiniLabel(Boolean(value));
124
- }, [value]);
132
+ const placeholderMode = getPlaceholderMode(showMiniLabel, value);
125
133
 
126
134
  const showClear = useShowClear({
127
135
  clearable,
@@ -139,7 +147,7 @@ export function InputPressableInternal(
139
147
  prefix={prefix}
140
148
  suffix={suffix}
141
149
  hasValue={hasValue}
142
- hasMiniLabel={hasMiniLabel}
150
+ placeholderMode={placeholderMode}
143
151
  focused={focused}
144
152
  error={error}
145
153
  invalid={invalid}
@@ -160,7 +168,8 @@ export function InputPressableInternal(
160
168
  style={[
161
169
  commonInputStyles.input,
162
170
  styles.inputPressableStyles,
163
- !hasMiniLabel && commonInputStyles.inputEmpty,
171
+ placeholderMode === "normal" && commonInputStyles.inputEmpty,
172
+ placeholderMode === "hidden" && styles.withoutMiniLabel,
164
173
  disabled && commonInputStyles.inputDisabled,
165
174
  (Boolean(invalid) || error) && styles.inputInvalid,
166
175
  ]}
@@ -176,3 +185,20 @@ export function InputPressableInternal(
176
185
  </InputFieldWrapper>
177
186
  );
178
187
  }
188
+
189
+ function getPlaceholderMode(
190
+ isMiniLabelAllowed: boolean,
191
+ internalValue: string | undefined,
192
+ ): InputFieldWrapperProps["placeholderMode"] {
193
+ const hasValue = Boolean(internalValue);
194
+
195
+ if (hasValue) {
196
+ if (isMiniLabelAllowed) {
197
+ return "mini";
198
+ } else {
199
+ return "hidden";
200
+ }
201
+ } else {
202
+ return "normal";
203
+ }
204
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Ref } from "react";
2
2
  import React, { forwardRef, useEffect } from "react";
3
3
  import { View } from "react-native";
4
- import { useDebounce } from "@jobber/hooks/useDebounce";
4
+ import { useDebounce } from "@jobber/hooks";
5
5
  import { styles } from "./InputSearch.style";
6
6
  import type { InputTextProps, InputTextRef } from "../InputText";
7
7
  import { InputText } from "../InputText";
@@ -16,6 +16,7 @@ export interface InputSearchProps
16
16
  | "autoFocus"
17
17
  | "placeholder"
18
18
  | "prefix"
19
+ | "showMiniLabel"
19
20
  > {
20
21
  /**
21
22
  * A callback function that handles the update of the new value of the property value.
@@ -10,7 +10,7 @@ interface FilterButtonProps {
10
10
  export function FilterButton({
11
11
  accessibilityLabel,
12
12
  onClick,
13
- }: FilterButtonProps): JSX.Element {
13
+ }: FilterButtonProps) {
14
14
  return (
15
15
  <IconButton
16
16
  onPress={() => {
@@ -27,5 +27,10 @@ export const useStyles = buildThemedStyles(tokens => {
27
27
  paddingTop:
28
28
  (typographyStyles.defaultSize.fontSize || 0) + tokens["space-smallest"],
29
29
  },
30
+
31
+ multilineWithoutMiniLabel: {
32
+ paddingTop: tokens["space-base"] + tokens["space-smallest"],
33
+ paddingBottom: tokens["space-base"] + tokens["space-smallest"],
34
+ },
30
35
  };
31
36
  });
@@ -4,6 +4,7 @@ import {
4
4
  fireEvent,
5
5
  render,
6
6
  renderHook,
7
+ screen,
7
8
  waitFor,
8
9
  } from "@testing-library/react-native";
9
10
  import type { TextStyle } from "react-native";
@@ -548,6 +549,80 @@ describe("InputText", () => {
548
549
  expect(styleOverride.inputText.color).toEqual(flattenedStyle.color);
549
550
  });
550
551
  });
552
+
553
+ describe("showMiniLabel", () => {
554
+ it("defaults to true", () => {
555
+ const props = { placeholder: "placeholder", value: "value" };
556
+ renderInputText(props);
557
+ expect(
558
+ screen.getByText("placeholder", { includeHiddenElements: true }),
559
+ ).toBeDefined();
560
+ expect(MockInputFieldWrapper).toHaveBeenCalledWith(
561
+ expect.objectContaining({
562
+ placeholderMode: "mini",
563
+ }),
564
+ );
565
+ });
566
+
567
+ describe("when true", () => {
568
+ it("renders the placeholder in its normal position when the input has no value", () => {
569
+ const props = { showMiniLabel: true, placeholder: "placeholder" };
570
+ renderInputText(props);
571
+ expect(
572
+ screen.getByText("placeholder", { includeHiddenElements: true }),
573
+ ).toBeDefined();
574
+ expect(MockInputFieldWrapper).toHaveBeenCalledWith(
575
+ expect.objectContaining({
576
+ placeholderMode: "normal",
577
+ }),
578
+ );
579
+ });
580
+
581
+ it("renders the placeholder as a mini label when the input has a value", () => {
582
+ const props = {
583
+ showMiniLabel: true,
584
+ placeholder: "placeholder",
585
+ value: "value",
586
+ };
587
+ renderInputText(props);
588
+ expect(
589
+ screen.getByText("placeholder", { includeHiddenElements: true }),
590
+ ).toBeDefined();
591
+ expect(MockInputFieldWrapper).toHaveBeenCalledWith(
592
+ expect.objectContaining({
593
+ placeholderMode: "mini",
594
+ }),
595
+ );
596
+ });
597
+ });
598
+
599
+ describe("when false", () => {
600
+ it("renders the placeholder in its normal position when the input has no value", () => {
601
+ const props = { showMiniLabel: false, placeholder: "placeholder" };
602
+ renderInputText(props);
603
+ expect(
604
+ screen.getByText("placeholder", { includeHiddenElements: true }),
605
+ ).toBeDefined();
606
+ expect(MockInputFieldWrapper).toHaveBeenCalledWith(
607
+ expect.objectContaining({
608
+ placeholderMode: "normal",
609
+ }),
610
+ );
611
+ });
612
+
613
+ it("does not render the placeholder when the input has a value", () => {
614
+ const props = {
615
+ showMiniLabel: false,
616
+ placeholder: "placeholder",
617
+ value: "value",
618
+ };
619
+ renderInputText(props);
620
+ expect(
621
+ screen.queryByText("placeholder", { includeHiddenElements: true }),
622
+ ).toBeNull();
623
+ });
624
+ });
625
+ });
551
626
  });
552
627
 
553
628
  describe("Transform", () => {
@@ -8,10 +8,9 @@ import React, {
8
8
  useState,
9
9
  } from "react";
10
10
  import type {
11
- NativeSyntheticEvent,
11
+ FocusEvent,
12
12
  ReturnKeyTypeOptions,
13
13
  StyleProp,
14
- TextInputFocusEventData,
15
14
  TextInputProps,
16
15
  TextStyle,
17
16
  } from "react-native";
@@ -66,6 +65,15 @@ export interface InputTextProps
66
65
  */
67
66
  readonly assistiveText?: string;
68
67
 
68
+ /**
69
+ * Controls the visibility of the mini label that appears inside the input
70
+ * when a value is entered. By default, the placeholder text moves up to
71
+ * become a mini label. Set to false to disable this behavior.
72
+ *
73
+ * @default true
74
+ */
75
+ readonly showMiniLabel?: boolean;
76
+
69
77
  /**
70
78
  * Determines what keyboard is shown
71
79
  */
@@ -113,9 +121,7 @@ export interface InputTextProps
113
121
  * Callback that is called when the text input is focused
114
122
  * @param event
115
123
  */
116
- readonly onFocus?: (
117
- event?: NativeSyntheticEvent<TextInputFocusEventData>,
118
- ) => void;
124
+ readonly onFocus?: (event?: FocusEvent) => void;
119
125
 
120
126
  /**
121
127
  * Callback that is called when the text input is blurred
@@ -248,6 +254,7 @@ function InputTextInternal(
248
254
  name,
249
255
  placeholder,
250
256
  assistiveText,
257
+ showMiniLabel = true,
251
258
  keyboard,
252
259
  value: controlledValue,
253
260
  defaultValue,
@@ -295,7 +302,8 @@ function InputTextInternal(
295
302
 
296
303
  const hasValue = internalValue !== "" && internalValue !== undefined;
297
304
  const [focused, setFocused] = useState(false);
298
- const { hasMiniLabel } = useMiniLabel(internalValue);
305
+ const placeholderMode = getPlaceholderMode(showMiniLabel, internalValue);
306
+ const miniLabelActive = placeholderMode === "mini";
299
307
 
300
308
  const textInputRef = useTextInputRef({ ref, onClear: handleClear });
301
309
 
@@ -370,7 +378,7 @@ function InputTextInternal(
370
378
  prefix={prefix}
371
379
  suffix={suffix}
372
380
  hasValue={hasValue}
373
- hasMiniLabel={hasMiniLabel}
381
+ placeholderMode={placeholderMode}
374
382
  assistiveText={assistiveText}
375
383
  focused={focused}
376
384
  error={error}
@@ -394,11 +402,14 @@ function InputTextInternal(
394
402
  style={[
395
403
  commonInputStyles.input,
396
404
  styles.inputPaddingTop,
397
- !hasMiniLabel && commonInputStyles.inputEmpty,
405
+ !miniLabelActive && commonInputStyles.inputEmpty,
398
406
  disabled && commonInputStyles.inputDisabled,
399
407
  multiline && styles.multiLineInput,
400
408
  multiline && Platform.OS === "ios" && styles.multilineInputiOS,
401
- multiline && hasMiniLabel && styles.multiLineInputWithMini,
409
+ multiline && miniLabelActive && styles.multiLineInputWithMini,
410
+ multiline &&
411
+ placeholderMode === "hidden" &&
412
+ styles.multilineWithoutMiniLabel,
402
413
  styleOverride?.inputText,
403
414
  loading && loadingType === "glimmer" && { color: "transparent" },
404
415
  ]}
@@ -513,13 +524,19 @@ function useTextInputRef({ ref, onClear }: UseTextInputRefProps) {
513
524
  return textInputRef;
514
525
  }
515
526
 
516
- function useMiniLabel(internalValue: string): {
517
- hasMiniLabel: boolean;
518
- } {
519
- const [hasMiniLabel, setHasMiniLabel] = useState(Boolean(internalValue));
520
- useEffect(() => {
521
- setHasMiniLabel(Boolean(internalValue));
522
- }, [internalValue]);
527
+ function getPlaceholderMode(
528
+ isMiniLabelAllowed: boolean,
529
+ internalValue: string,
530
+ ): InputFieldWrapperProps["placeholderMode"] {
531
+ const hasValue = Boolean(internalValue);
523
532
 
524
- return { hasMiniLabel };
533
+ if (hasValue) {
534
+ if (isMiniLabelAllowed) {
535
+ return "mini";
536
+ } else {
537
+ return "hidden";
538
+ }
539
+ } else {
540
+ return "normal";
541
+ }
525
542
  }
@@ -16,7 +16,7 @@ export function InputAccessoriesProvider({
16
16
  children,
17
17
  }: {
18
18
  readonly children: ReactNode;
19
- }): JSX.Element {
19
+ }) {
20
20
  const inputAccessoryID = useRef(v4()).current;
21
21
  const {
22
22
  focusedInput,
@@ -11,9 +11,11 @@ import { InputPressable } from "../InputPressable";
11
11
  import { FormField } from "../FormField";
12
12
  import type { InputFieldWrapperProps } from "../InputFieldWrapper";
13
13
  import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
14
+ import type { InputPressableProps } from "../InputPressable/InputPressable";
14
15
 
15
16
  interface InputTimeBaseProps
16
- extends Pick<InputFieldWrapperProps, "invalid" | "disabled" | "placeholder"> {
17
+ extends Pick<InputFieldWrapperProps, "invalid" | "disabled" | "placeholder">,
18
+ Pick<InputPressableProps, "showMiniLabel"> {
17
19
  /**
18
20
  * Defaulted to "always" so user can clear the time whenever there's a value.
19
21
  */
@@ -97,7 +99,7 @@ function formatInvalidState(
97
99
  return Boolean(error);
98
100
  }
99
101
 
100
- export function InputTime(props: InputTimeProps): JSX.Element {
102
+ export function InputTime(props: InputTimeProps) {
101
103
  if (props.name) {
102
104
  return (
103
105
  <FormField name={props.name} validations={props.validations}>
@@ -129,9 +131,10 @@ function InternalInputTime({
129
131
  value,
130
132
  name,
131
133
  type = "scheduling",
134
+ showMiniLabel = true,
132
135
  onChange,
133
136
  showIcon = true,
134
- }: InputTimeProps): JSX.Element {
137
+ }: InputTimeProps) {
135
138
  const [showPicker, setShowPicker] = useState(false);
136
139
  const { t, formatTime } = useAtlantisI18n();
137
140
  const { timeZone, timeFormat } = useAtlantisContext();
@@ -156,6 +159,7 @@ function InternalInputTime({
156
159
  return (
157
160
  <View style={styles.container}>
158
161
  <InputPressable
162
+ showMiniLabel={showMiniLabel}
159
163
  clearable={canClearTime}
160
164
  disabled={disabled}
161
165
  invalid={invalid}
package/src/Menu/Menu.tsx CHANGED
@@ -20,11 +20,11 @@ import { useAtlantisContext } from "../AtlantisContext";
20
20
  import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
21
21
  import { useAtlantisTheme } from "../AtlantisThemeContext";
22
22
 
23
- export function Menu({ menuOptions, customActivator }: MenuProps): JSX.Element {
23
+ export function Menu({ menuOptions, customActivator }: MenuProps) {
24
24
  const [open, setOpen] = useState<boolean>(false);
25
25
  const [menuPosition, setMenuPosition] = useState<object>();
26
- const activatorLayout = useRef<LayoutRectangle>();
27
- const menuButtonRef = useRef<View | null>();
26
+ const activatorLayout = useRef<LayoutRectangle>(null);
27
+ const menuButtonRef = useRef<View>(null);
28
28
  const screenInfo = useScreenInformation();
29
29
 
30
30
  const { t } = useAtlantisI18n();
@@ -17,7 +17,7 @@ export function MenuOption({
17
17
  textTransform = "capitalize",
18
18
  onPress,
19
19
  setOpen,
20
- }: MenuOptionInternalProps): JSX.Element {
20
+ }: MenuOptionInternalProps) {
21
21
  const destructiveColor = "destructive";
22
22
  const textVariation = destructive ? destructiveColor : "heading";
23
23
  const styles = useStyles();
@@ -3,7 +3,7 @@ import { Pressable, View } from "react-native";
3
3
  import { useStyles } from "./Overlay.style";
4
4
  import type { OverlayProp } from "../../types";
5
5
 
6
- export function Overlay({ setOpen }: OverlayProp): JSX.Element {
6
+ export function Overlay({ setOpen }: OverlayProp) {
7
7
  const styles = useStyles();
8
8
 
9
9
  return (
package/src/Menu/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { IconColorNames, IconNames } from "@jobber/design";
2
+ import type { ReactElement } from "react";
2
3
  import type { TextAlign } from "../Typography";
3
4
 
4
5
  export interface MenuOptionProps {
@@ -15,9 +16,14 @@ export interface MenuOptionInternalProps extends MenuOptionProps {
15
16
  setOpen: (bool: boolean) => void;
16
17
  }
17
18
 
19
+ export interface CustomActivatorProps {
20
+ readonly onPress?: () => void;
21
+ readonly onLongPress?: () => void;
22
+ }
23
+
18
24
  export interface MenuProps {
19
25
  readonly menuOptions?: MenuOptionProps[];
20
- readonly customActivator?: JSX.Element;
26
+ readonly customActivator?: ReactElement<CustomActivatorProps>;
21
27
  }
22
28
 
23
29
  export interface OverlayProp {
@@ -17,7 +17,7 @@ export function ProgressBar({
17
17
  header,
18
18
  variation = "progress",
19
19
  size = "base",
20
- }: ProgressBarProps): JSX.Element {
20
+ }: ProgressBarProps) {
21
21
  const { t } = useAtlantisI18n();
22
22
  const styles = useStyles();
23
23
  const { tokens } = useAtlantisTheme();
@@ -14,7 +14,7 @@ export function ProgressBarInner({
14
14
  width,
15
15
  // animationDuration = 0,
16
16
  color,
17
- }: ProgressBarInnerProps): JSX.Element {
17
+ }: ProgressBarInnerProps) {
18
18
  // Animation breaking on Android
19
19
  // const [animatedOpacity] = useTiming({
20
20
  // duration: animationDuration,
@@ -14,6 +14,7 @@ export const useStyles = buildThemedStyles(tokens => {
14
14
  minHeight: tokens["space-largest"] + tokens["space-small"],
15
15
  marginVertical: 0,
16
16
  borderWidth: 0,
17
+ backgroundColor: "transparent",
17
18
  },
18
19
  ]),
19
20
 
@@ -110,7 +110,7 @@ export function Select({
110
110
  accessibilityLabel,
111
111
  name,
112
112
  testID,
113
- }: SelectProps): JSX.Element {
113
+ }: SelectProps) {
114
114
  const { field, error } = useFormController({
115
115
  name,
116
116
  validations,
@@ -243,6 +243,6 @@ function getTestID(testID?: string): string {
243
243
  return "ATL-Select";
244
244
  }
245
245
 
246
- export function Option({ children }: SelectOption): JSX.Element {
246
+ export function Option({ children }: SelectOption) {
247
247
  return <>{children}</>;
248
248
  }
@@ -19,7 +19,7 @@ export function SelectDefaultPicker({
19
19
  children,
20
20
  options,
21
21
  onChange,
22
- }: SelectDefaultPickerProps): JSX.Element {
22
+ }: SelectDefaultPickerProps) {
23
23
  const [show, setShow] = useState(false);
24
24
  const { t } = useAtlantisI18n();
25
25
  const selectedLanguage = options.find(option => option.isActive);
@@ -12,7 +12,7 @@ export function SelectDefaultPicker({
12
12
  options,
13
13
  disabled,
14
14
  onChange,
15
- }: SelectDefaultPickerProps): JSX.Element {
15
+ }: SelectDefaultPickerProps) {
16
16
  const selectedItem = options.find(option => option.isActive);
17
17
  const pickerRef = useRef<Picker<string>>(null);
18
18
  const { tokens } = useAtlantisTheme();
@@ -10,7 +10,7 @@ export function SelectInternalPicker({
10
10
  options,
11
11
  disabled,
12
12
  onChange,
13
- }: SelectInternalPickerProps): JSX.Element {
13
+ }: SelectInternalPickerProps) {
14
14
  if (disabled) return <>{children}</>;
15
15
 
16
16
  if (isIOS14AndUp()) {
@@ -13,10 +13,7 @@ type SelectPressableProps = Pick<SelectInternalPickerProps, "children"> &
13
13
  * screen-reader is being used to avoid screen-readers from ignoring the press
14
14
  * on the MenuView
15
15
  */
16
- export function SelectPressable({
17
- children,
18
- onPress,
19
- }: SelectPressableProps): JSX.Element {
16
+ export function SelectPressable({ children, onPress }: SelectPressableProps) {
20
17
  const isScreenReaderEnabled = useIsScreenReaderEnabled();
21
18
  const styles = useStyles();
22
19
  if (isScreenReaderEnabled) return <>{children}</>;
@@ -37,7 +37,7 @@ export function StatusLabel({
37
37
  text,
38
38
  alignment = "end",
39
39
  status = "success",
40
- }: StatusLabelProps): JSX.Element {
40
+ }: StatusLabelProps) {
41
41
  const styles = useStyles();
42
42
 
43
43
  return (
@@ -20,7 +20,7 @@ interface WithLabelProps extends BaseSwitchProps {
20
20
 
21
21
  export type SwitchProps = XOR<BaseSwitchProps, WithLabelProps>;
22
22
 
23
- export function Switch(props: SwitchProps): JSX.Element {
23
+ export function Switch(props: SwitchProps) {
24
24
  const switchProps: SwitchProps = {
25
25
  ...props,
26
26
  accessibilityLabel: props.accessibilityLabel || props.label,
@@ -43,7 +43,7 @@ export function BaseSwitch({
43
43
  disabled = false,
44
44
  accessibilityLabel,
45
45
  name,
46
- }: BaseSwitchProps): JSX.Element {
46
+ }: BaseSwitchProps) {
47
47
  const { field } = useFormController({
48
48
  name,
49
49
  value: value ?? defaultValue,
@@ -85,6 +85,12 @@ export function BaseSwitch({
85
85
  };
86
86
  }
87
87
  }
88
+ // Temporary fix for iOS 26. Remove when we upgrade to RN 0.81.
89
+ // https://github.com/facebook/react-native/pull/53389
90
+ const iOSBackgroundColor =
91
+ Platform.OS === "ios" && Platform.Version?.startsWith("26.")
92
+ ? undefined
93
+ : tokens["color-interactive--background"];
88
94
 
89
95
  return (
90
96
  <Switch
@@ -98,7 +104,7 @@ export function BaseSwitch({
98
104
  disabled={disabled}
99
105
  thumbColor={getThumbColor()}
100
106
  trackColor={getTrackColors()}
101
- ios_backgroundColor={tokens["color-interactive--background"]}
107
+ ios_backgroundColor={iOSBackgroundColor}
102
108
  accessibilityLabel={accessibilityLabel}
103
109
  accessibilityRole={"switch"}
104
110
  accessibilityState={{
@@ -151,6 +151,16 @@ it("renders text with underline styling", () => {
151
151
  expect(text.toJSON()).toMatchSnapshot();
152
152
  });
153
153
 
154
+ it("supports nested Text children with mixed styles", () => {
155
+ const { getByText, toJSON } = render(
156
+ <Text>
157
+ Hello <Text emphasis="strong">World</Text>!
158
+ </Text>,
159
+ );
160
+ expect(getByText("World")).toBeDefined();
161
+ expect(toJSON()).toMatchSnapshot();
162
+ });
163
+
154
164
  describe("UNSAFE_style", () => {
155
165
  it("applies custom styles via UNSAFE_style prop", () => {
156
166
  const customStyle = {
package/src/Text/Text.tsx CHANGED
@@ -53,9 +53,9 @@ export interface TextProps
53
53
  readonly align?: TextAlign;
54
54
 
55
55
  /**
56
- * Text to display
56
+ * Text to display. Supports nesting text elements.
57
57
  */
58
- readonly children?: string;
58
+ readonly children?: React.ReactNode;
59
59
 
60
60
  /**
61
61
  * Reverse theme for better display on dark background
@@ -143,7 +143,7 @@ export function Text({
143
143
  underline,
144
144
  selectable,
145
145
  onTextLayout,
146
- }: TextProps): JSX.Element {
146
+ }: TextProps) {
147
147
  const accessibilityRole: TextAccessibilityRole = "text";
148
148
 
149
149
  return (