react-native-molecules 0.5.0-beta.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 (355) hide show
  1. package/components/Accordion/Accordion.tsx +89 -0
  2. package/components/Accordion/AccordionItem.tsx +94 -0
  3. package/components/Accordion/AccordionItemContent.tsx +17 -0
  4. package/components/Accordion/AccordionItemHeader.tsx +122 -0
  5. package/components/Accordion/index.tsx +36 -0
  6. package/components/Accordion/utils.ts +62 -0
  7. package/components/ActivityIndicator/ActivityIndicator.ios.tsx +1 -0
  8. package/components/ActivityIndicator/ActivityIndicator.tsx +200 -0
  9. package/components/ActivityIndicator/AnimatedSpinner.tsx +121 -0
  10. package/components/ActivityIndicator/index.tsx +17 -0
  11. package/components/Appbar/AppbarActions.tsx +13 -0
  12. package/components/Appbar/AppbarBase.tsx +60 -0
  13. package/components/Appbar/AppbarCenterAligned.tsx +13 -0
  14. package/components/Appbar/AppbarLarge.tsx +13 -0
  15. package/components/Appbar/AppbarLeft.tsx +26 -0
  16. package/components/Appbar/AppbarMedium.tsx +13 -0
  17. package/components/Appbar/AppbarRight.tsx +40 -0
  18. package/components/Appbar/AppbarSmall.tsx +13 -0
  19. package/components/Appbar/AppbarTitle.tsx +49 -0
  20. package/components/Appbar/index.tsx +46 -0
  21. package/components/Appbar/types.ts +19 -0
  22. package/components/Appbar/utils.ts +127 -0
  23. package/components/Avatar/Avatar.tsx +189 -0
  24. package/components/Avatar/index.tsx +11 -0
  25. package/components/Avatar/utils.ts +35 -0
  26. package/components/Backdrop/Backdrop.tsx +18 -0
  27. package/components/Backdrop/index.tsx +11 -0
  28. package/components/Backdrop/types.ts +3 -0
  29. package/components/Backdrop/utils.ts +21 -0
  30. package/components/Badge/Badge.tsx +29 -0
  31. package/components/Badge/index.tsx +11 -0
  32. package/components/Badge/utils.ts +38 -0
  33. package/components/Button/Button.tsx +349 -0
  34. package/components/Button/index.tsx +11 -0
  35. package/components/Button/types.ts +5 -0
  36. package/components/Button/utils.ts +416 -0
  37. package/components/Card/Card.tsx +160 -0
  38. package/components/Card/CardActions.tsx +18 -0
  39. package/components/Card/CardContent.tsx +29 -0
  40. package/components/Card/CardHeader.tsx +31 -0
  41. package/components/Card/CardHeadline.tsx +15 -0
  42. package/components/Card/CardMedia.tsx +36 -0
  43. package/components/Card/CardSubhead.tsx +15 -0
  44. package/components/Card/CardText.tsx +13 -0
  45. package/components/Card/CardTypography.tsx +113 -0
  46. package/components/Card/index.tsx +38 -0
  47. package/components/Card/types.ts +1 -0
  48. package/components/Card/utils.ts +23 -0
  49. package/components/Checkbox/Checkbox.tsx +123 -0
  50. package/components/Checkbox/CheckboxBase.ios.tsx +86 -0
  51. package/components/Checkbox/CheckboxBase.tsx +216 -0
  52. package/components/Checkbox/index.tsx +11 -0
  53. package/components/Checkbox/types.ts +72 -0
  54. package/components/Checkbox/utils.ts +210 -0
  55. package/components/Chip/Chip.tsx +416 -0
  56. package/components/Chip/index.tsx +51 -0
  57. package/components/Chip/utils.ts +100 -0
  58. package/components/DatePickerDocked/DatePickerDocked.tsx +30 -0
  59. package/components/DatePickerDocked/DatePickerDockedHeader.tsx +129 -0
  60. package/components/DatePickerDocked/index.tsx +21 -0
  61. package/components/DatePickerDocked/types.ts +11 -0
  62. package/components/DatePickerDocked/utils.ts +155 -0
  63. package/components/DatePickerInline/AutoSizer.tsx +46 -0
  64. package/components/DatePickerInline/DatePickerContext.tsx +21 -0
  65. package/components/DatePickerInline/DatePickerInline.tsx +82 -0
  66. package/components/DatePickerInline/DatePickerInlineBase.tsx +181 -0
  67. package/components/DatePickerInline/DatePickerInlineHeader.tsx +108 -0
  68. package/components/DatePickerInline/Day.tsx +88 -0
  69. package/components/DatePickerInline/DayName.tsx +17 -0
  70. package/components/DatePickerInline/DayNames.tsx +32 -0
  71. package/components/DatePickerInline/DayRange.tsx +48 -0
  72. package/components/DatePickerInline/HeaderItem.tsx +111 -0
  73. package/components/DatePickerInline/Month.tsx +233 -0
  74. package/components/DatePickerInline/MonthPicker.tsx +174 -0
  75. package/components/DatePickerInline/Swiper.native.tsx +172 -0
  76. package/components/DatePickerInline/Swiper.tsx +172 -0
  77. package/components/DatePickerInline/SwiperUtils.ts +40 -0
  78. package/components/DatePickerInline/Week.tsx +67 -0
  79. package/components/DatePickerInline/YearPicker.tsx +139 -0
  80. package/components/DatePickerInline/dateUtils.tsx +334 -0
  81. package/components/DatePickerInline/index.tsx +41 -0
  82. package/components/DatePickerInline/types.ts +104 -0
  83. package/components/DatePickerInline/utils.ts +367 -0
  84. package/components/DatePickerInput/DatePickerInput.tsx +139 -0
  85. package/components/DatePickerInput/DatePickerInputModal.tsx +48 -0
  86. package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +77 -0
  87. package/components/DatePickerInput/DateRangeInput.tsx +88 -0
  88. package/components/DatePickerInput/index.tsx +14 -0
  89. package/components/DatePickerInput/inputUtils.ts +138 -0
  90. package/components/DatePickerInput/types.ts +28 -0
  91. package/components/DatePickerInput/utils.ts +16 -0
  92. package/components/DatePickerModal/AnimatedCrossView.tsx +94 -0
  93. package/components/DatePickerModal/CalendarEdit.tsx +139 -0
  94. package/components/DatePickerModal/DatePickerModal.tsx +85 -0
  95. package/components/DatePickerModal/DatePickerModalContent.tsx +155 -0
  96. package/components/DatePickerModal/DatePickerModalContentHeader.tsx +213 -0
  97. package/components/DatePickerModal/DatePickerModalHeader.tsx +74 -0
  98. package/components/DatePickerModal/DatePickerModalHeaderBackground.tsx +13 -0
  99. package/components/DatePickerModal/index.tsx +20 -0
  100. package/components/DatePickerModal/types.ts +92 -0
  101. package/components/DatePickerModal/utils.ts +121 -0
  102. package/components/DateTimePicker/DateTimePicker.tsx +172 -0
  103. package/components/DateTimePicker/index.tsx +14 -0
  104. package/components/DateTimePicker/utils.ts +13 -0
  105. package/components/Dialog/Dialog.tsx +66 -0
  106. package/components/Dialog/DialogActions.tsx +89 -0
  107. package/components/Dialog/DialogContent.tsx +37 -0
  108. package/components/Dialog/DialogIcon.tsx +69 -0
  109. package/components/Dialog/DialogTitle.tsx +68 -0
  110. package/components/Dialog/index.tsx +37 -0
  111. package/components/Dialog/utils.ts +80 -0
  112. package/components/Drawer/Collapsible/DrawerCollapsible.tsx +22 -0
  113. package/components/Drawer/Collapsible/DrawerCollapsibleItem.tsx +38 -0
  114. package/components/Drawer/Collapsible/DrawerCollapsibleItemContent.tsx +16 -0
  115. package/components/Drawer/Collapsible/DrawerCollapsibleItemHeader.tsx +48 -0
  116. package/components/Drawer/Collapsible/index.tsx +23 -0
  117. package/components/Drawer/Collapsible/utils.ts +49 -0
  118. package/components/Drawer/Drawer.tsx +43 -0
  119. package/components/Drawer/DrawerContent.tsx +35 -0
  120. package/components/Drawer/DrawerFooter.tsx +27 -0
  121. package/components/Drawer/DrawerHeader.tsx +27 -0
  122. package/components/Drawer/DrawerItem.tsx +206 -0
  123. package/components/Drawer/DrawerItemGroup.tsx +82 -0
  124. package/components/Drawer/index.tsx +47 -0
  125. package/components/Drawer/types.ts +3 -0
  126. package/components/Drawer/utils.ts +8 -0
  127. package/components/ElementGroup/ElementGroup.tsx +139 -0
  128. package/components/ElementGroup/index.tsx +11 -0
  129. package/components/ElementGroup/utils.ts +25 -0
  130. package/components/FAB/FAB.tsx +176 -0
  131. package/components/FAB/index.tsx +12 -0
  132. package/components/FAB/types.ts +1 -0
  133. package/components/FAB/utils.ts +221 -0
  134. package/components/FilePicker/FilePicker.tsx +133 -0
  135. package/components/FilePicker/index.tsx +11 -0
  136. package/components/FilePicker/utils.ts +13 -0
  137. package/components/HelperText/HelperText.tsx +139 -0
  138. package/components/HelperText/index.tsx +11 -0
  139. package/components/HelperText/utils.ts +29 -0
  140. package/components/HorizontalDivider/HorizontalDivider.tsx +101 -0
  141. package/components/HorizontalDivider/index.tsx +13 -0
  142. package/components/Icon/CrossFadeIcon.tsx +116 -0
  143. package/components/Icon/Icon.tsx +41 -0
  144. package/components/Icon/iconFactory.tsx +23 -0
  145. package/components/Icon/index.tsx +11 -0
  146. package/components/Icon/types.ts +35 -0
  147. package/components/IconButton/IconButton.tsx +218 -0
  148. package/components/IconButton/index.tsx +11 -0
  149. package/components/IconButton/types.ts +1 -0
  150. package/components/IconButton/utils.ts +325 -0
  151. package/components/If/index.tsx +13 -0
  152. package/components/InputAddon/InputAddon.tsx +27 -0
  153. package/components/InputAddon/index.tsx +11 -0
  154. package/components/InputAddon/utils.ts +33 -0
  155. package/components/Link/Link.tsx +48 -0
  156. package/components/Link/index.tsx +11 -0
  157. package/components/Link/utils.ts +37 -0
  158. package/components/ListItem/ListItem.tsx +136 -0
  159. package/components/ListItem/ListItemDescription.tsx +25 -0
  160. package/components/ListItem/ListItemTitle.tsx +25 -0
  161. package/components/ListItem/index.tsx +18 -0
  162. package/components/ListItem/utils.ts +113 -0
  163. package/components/Menu/Menu.tsx +69 -0
  164. package/components/Menu/MenuDivider.tsx +13 -0
  165. package/components/Menu/MenuItem.tsx +128 -0
  166. package/components/Menu/index.tsx +19 -0
  167. package/components/Menu/utils.ts +92 -0
  168. package/components/Modal/Modal.tsx +261 -0
  169. package/components/Modal/index.tsx +11 -0
  170. package/components/Modal/utils.ts +45 -0
  171. package/components/NavigationRail/NavigationRail.tsx +32 -0
  172. package/components/NavigationRail/NavigationRailContent.tsx +25 -0
  173. package/components/NavigationRail/NavigationRailFooter.tsx +18 -0
  174. package/components/NavigationRail/NavigationRailHeader.tsx +18 -0
  175. package/components/NavigationRail/NavigationRailItem.tsx +226 -0
  176. package/components/NavigationRail/index.tsx +35 -0
  177. package/components/NavigationRail/utils.ts +170 -0
  178. package/components/NavigationStack/NavigationStack.tsx +85 -0
  179. package/components/NavigationStack/NavigationStackItem.tsx +60 -0
  180. package/components/NavigationStack/index.tsx +20 -0
  181. package/components/NavigationStack/utils.tsx +16 -0
  182. package/components/Popover/Popover.native.tsx +185 -0
  183. package/components/Popover/Popover.tsx +198 -0
  184. package/components/Popover/common.ts +459 -0
  185. package/components/Popover/index.ts +2 -0
  186. package/components/Portal/Portal.tsx +13 -0
  187. package/components/Portal/index.tsx +12 -0
  188. package/components/RadioButton/RadioButton.tsx +138 -0
  189. package/components/RadioButton/RadioButtonAndroid.tsx +188 -0
  190. package/components/RadioButton/RadioButtonGroup.tsx +98 -0
  191. package/components/RadioButton/RadioButtonIOS.tsx +106 -0
  192. package/components/RadioButton/RadioButtonItem.tsx +232 -0
  193. package/components/RadioButton/index.ts +27 -0
  194. package/components/RadioButton/utils.ts +164 -0
  195. package/components/Rating/Rating.tsx +149 -0
  196. package/components/Rating/RatingItem.tsx +125 -0
  197. package/components/Rating/index.tsx +13 -0
  198. package/components/Rating/utils.ts +38 -0
  199. package/components/Select/Select.tsx +1038 -0
  200. package/components/Select/index.ts +14 -0
  201. package/components/Select/types.ts +115 -0
  202. package/components/StateLayer/StateLayer.tsx +12 -0
  203. package/components/StateLayer/index.tsx +11 -0
  204. package/components/StateLayer/utils.ts +17 -0
  205. package/components/Surface/BackgroundContextWrapper.tsx +27 -0
  206. package/components/Surface/Surface.android.tsx +62 -0
  207. package/components/Surface/Surface.ios.tsx +123 -0
  208. package/components/Surface/Surface.tsx +48 -0
  209. package/components/Surface/index.tsx +12 -0
  210. package/components/Surface/utils.ts +106 -0
  211. package/components/Switch/Switch.ios.tsx +67 -0
  212. package/components/Switch/Switch.tsx +278 -0
  213. package/components/Switch/index.tsx +11 -0
  214. package/components/Switch/utils.ts +283 -0
  215. package/components/Tabs/TabItem.tsx +150 -0
  216. package/components/Tabs/TabLabel.tsx +84 -0
  217. package/components/Tabs/Tabs.tsx +398 -0
  218. package/components/Tabs/index.tsx +21 -0
  219. package/components/Tabs/utils.ts +126 -0
  220. package/components/Text/Text.tsx +23 -0
  221. package/components/Text/index.tsx +2 -0
  222. package/components/Text/textFactory.tsx +33 -0
  223. package/components/TextInput/InputLabel.tsx +181 -0
  224. package/components/TextInput/TextInput.tsx +693 -0
  225. package/components/TextInput/index.tsx +16 -0
  226. package/components/TextInput/types.ts +96 -0
  227. package/components/TextInput/utils.ts +544 -0
  228. package/components/TextInputWithMask/TextInputMask.tsx +57 -0
  229. package/components/TextInputWithMask/index.tsx +11 -0
  230. package/components/TextInputWithMask/utils.ts +56 -0
  231. package/components/TimePicker/AmPmSwitcher.tsx +99 -0
  232. package/components/TimePicker/AnalogClock.tsx +165 -0
  233. package/components/TimePicker/AnalogClockHours.tsx +163 -0
  234. package/components/TimePicker/AnalogClockMinutes.tsx +68 -0
  235. package/components/TimePicker/AnimatedClockSwitcher.tsx +72 -0
  236. package/components/TimePicker/DisplayModeContext.tsx +6 -0
  237. package/components/TimePicker/TimeInput.tsx +112 -0
  238. package/components/TimePicker/TimeInputs.tsx +148 -0
  239. package/components/TimePicker/TimePicker.tsx +130 -0
  240. package/components/TimePicker/index.tsx +19 -0
  241. package/components/TimePicker/timeUtils.ts +159 -0
  242. package/components/TimePicker/utils.ts +285 -0
  243. package/components/TimePickerField/TimePickerField.tsx +152 -0
  244. package/components/TimePickerField/index.tsx +14 -0
  245. package/components/TimePickerField/sanitizeTime.ts +85 -0
  246. package/components/TimePickerField/utils.ts +95 -0
  247. package/components/TimePickerModal/TimePickerModal.tsx +115 -0
  248. package/components/TimePickerModal/index.tsx +14 -0
  249. package/components/TimePickerModal/utils.ts +48 -0
  250. package/components/Tooltip/Tooltip.tsx +137 -0
  251. package/components/Tooltip/TooltipContent.tsx +12 -0
  252. package/components/Tooltip/TooltipTrigger.tsx +94 -0
  253. package/components/Tooltip/index.tsx +20 -0
  254. package/components/Tooltip/utils.ts +21 -0
  255. package/components/TouchableRipple/TouchableRipple.native.tsx +105 -0
  256. package/components/TouchableRipple/TouchableRipple.tsx +286 -0
  257. package/components/TouchableRipple/index.tsx +14 -0
  258. package/components/TouchableRipple/utils.ts +15 -0
  259. package/components/VerticalDivider/VerticalDivider.tsx +99 -0
  260. package/components/VerticalDivider/index.tsx +13 -0
  261. package/context-bridge/index.tsx +87 -0
  262. package/core/componentsRegistry.ts +164 -0
  263. package/core/index.tsx +2 -0
  264. package/fast-context/index.tsx +190 -0
  265. package/hocs/index.tsx +5 -0
  266. package/hocs/typedMemo.tsx +5 -0
  267. package/hocs/withKeyboardAccessibility.tsx +231 -0
  268. package/hocs/withPortal.tsx +16 -0
  269. package/hooks/createPsuedoHook.tsx +50 -0
  270. package/hooks/index.tsx +29 -0
  271. package/hooks/useActionState.native.tsx +22 -0
  272. package/hooks/useActionState.tsx +34 -0
  273. package/hooks/useActive.tsx +5 -0
  274. package/hooks/useBreakpoints.tsx +7 -0
  275. package/hooks/useColorMode.tsx +17 -0
  276. package/hooks/useContrastColor.ts +15 -0
  277. package/hooks/useControlledValue.tsx +68 -0
  278. package/hooks/useFilePicker.tsx +48 -0
  279. package/hooks/useFocus.tsx +5 -0
  280. package/hooks/useHandleNumberFormat.tsx +106 -0
  281. package/hooks/useHover.tsx +5 -0
  282. package/hooks/useKeyboardDismissable.ts +66 -0
  283. package/hooks/useLatest.tsx +9 -0
  284. package/hooks/useMediaQuery.tsx +64 -0
  285. package/hooks/useMergedRefs.ts +14 -0
  286. package/hooks/usePrevious.ts +13 -0
  287. package/hooks/useQueryFilter.tsx +35 -0
  288. package/hooks/useSearchable.tsx +74 -0
  289. package/hooks/useSubcomponents.tsx +59 -0
  290. package/hooks/useTheme.ts +3 -0
  291. package/hooks/useToggle.tsx +24 -0
  292. package/package.json +114 -0
  293. package/shortcuts-manager/EventsManager.tsx +121 -0
  294. package/shortcuts-manager/ShortcutsManager/ShortcutsManager.native.tsx +9 -0
  295. package/shortcuts-manager/ShortcutsManager/ShortcutsManager.tsx +58 -0
  296. package/shortcuts-manager/ShortcutsManager/index.tsx +2 -0
  297. package/shortcuts-manager/ShortcutsManager/utils.tsx +30 -0
  298. package/shortcuts-manager/index.tsx +6 -0
  299. package/shortcuts-manager/types.ts +24 -0
  300. package/shortcuts-manager/useIsKeyPressed/index.tsx +1 -0
  301. package/shortcuts-manager/useIsKeyPressed/useIsKeyPress.tsx +9 -0
  302. package/shortcuts-manager/useSetScopes/index.tsx +1 -0
  303. package/shortcuts-manager/useSetScopes/useSetScopes.native.tsx +9 -0
  304. package/shortcuts-manager/useSetScopes/useSetScopes.tsx +25 -0
  305. package/shortcuts-manager/useShortcut/index.tsx +2 -0
  306. package/shortcuts-manager/useShortcut/types.ts +3 -0
  307. package/shortcuts-manager/useShortcut/useShortcut.native.tsx +9 -0
  308. package/shortcuts-manager/useShortcut/useShortcut.tsx +61 -0
  309. package/shortcuts-manager/utils.ts +105 -0
  310. package/styles/index.ts +4 -0
  311. package/styles/overlay.ts +69 -0
  312. package/styles/shadow.ts +21 -0
  313. package/styles/themes/DarkTheme.tsx +98 -0
  314. package/styles/themes/LightTheme.tsx +212 -0
  315. package/styles/themes/tokens.ts +248 -0
  316. package/styles/utils.ts +11 -0
  317. package/types/index.ts +129 -0
  318. package/types/theme.ts +159 -0
  319. package/utils/DocumentPicker/documentPicker.native.ts +10 -0
  320. package/utils/DocumentPicker/documentPicker.ts +76 -0
  321. package/utils/DocumentPicker/index.ts +2 -0
  322. package/utils/DocumentPicker/types.ts +28 -0
  323. package/utils/addEventListener.tsx +51 -0
  324. package/utils/backgroundContext.ts +9 -0
  325. package/utils/color.ts +22 -0
  326. package/utils/compare/index.ts +54 -0
  327. package/utils/composeEventHandlers.ts +9 -0
  328. package/utils/createNumberMask/createNumberMask.ts +98 -0
  329. package/utils/createNumberMask/index.ts +5 -0
  330. package/utils/createSyntheticEvent.ts +31 -0
  331. package/utils/date-fns.ts +7 -0
  332. package/utils/dateTimePicker.ts +5 -0
  333. package/utils/escapeRegex.ts +9 -0
  334. package/utils/extractTextStyles.ts +52 -0
  335. package/utils/formatNumberWithMask/formatNumberWithMask.ts +26 -0
  336. package/utils/formatNumberWithMask/formatWithMask.ts +119 -0
  337. package/utils/formatNumberWithMask/index.ts +6 -0
  338. package/utils/getCursorStyle/getCursorStyle.native.ts +1 -0
  339. package/utils/getCursorStyle/getCursorStyle.ts +1 -0
  340. package/utils/getCursorStyle/index.ts +1 -0
  341. package/utils/getOS/getOS.native.ts +7 -0
  342. package/utils/getOS/getOS.ts +24 -0
  343. package/utils/getOS/index.ts +1 -0
  344. package/utils/getyearRange.ts +5 -0
  345. package/utils/index.ts +20 -0
  346. package/utils/lodash.ts +50 -0
  347. package/utils/mergeRefs.ts +13 -0
  348. package/utils/normalizeBorderRadiuses.ts +24 -0
  349. package/utils/normalizeSpacings.ts +110 -0
  350. package/utils/normalizeToNumberString/index.ts +4 -0
  351. package/utils/normalizeToNumberString/normalizeToNumberString.ts +48 -0
  352. package/utils/repository.ts +103 -0
  353. package/utils/resolveColorMode.ts +9 -0
  354. package/utils/resolveStateVariant.ts +26 -0
  355. package/utils/tokenStylesParser.ts +7 -0
@@ -0,0 +1,286 @@
1
+ import { Children, forwardRef, memo, type ReactNode, useCallback, useMemo } from 'react';
2
+ import {
3
+ type GestureResponderEvent,
4
+ Pressable,
5
+ type PressableProps,
6
+ type StyleProp,
7
+ View,
8
+ type ViewStyle,
9
+ } from 'react-native';
10
+ import { StyleSheet } from 'react-native-unistyles';
11
+
12
+ import { touchableRippleStyles } from './utils';
13
+
14
+ export type Props = PressableProps & {
15
+ /**
16
+ * Whether to render the ripple outside the view bounds.
17
+ */
18
+ borderless?: boolean;
19
+ /**
20
+ * Type of background drawabale to display the feedback (Android).
21
+ * https://reactnative.dev/docs/touchablenativefeedback#background
22
+ */
23
+ background?: Object;
24
+ /**
25
+ * Whether to start the ripple at the center (Web).
26
+ */
27
+ centered?: boolean;
28
+ /**
29
+ * Whether to prevent interaction with the touchable.
30
+ */
31
+ disabled?: boolean;
32
+ /**
33
+ * Function to execute on press. If not set, will cause the touchable to be disabled.
34
+ */
35
+ onPress?: (e: GestureResponderEvent) => void;
36
+ /**
37
+ * Function to execute on long press.
38
+ */
39
+ onLongPress?: (e: GestureResponderEvent) => void;
40
+ /**
41
+ * Color of the ripple effect (Android >= 5.0 and Web).
42
+ */
43
+ rippleColor?: string;
44
+ /**
45
+ * Color of the underlay for the highlight effect (Android < 5.0 and iOS).
46
+ */
47
+ underlayColor?: string;
48
+ /**
49
+ * Content of the `TouchableRipple`.
50
+ */
51
+ children: ReactNode;
52
+ style?: StyleProp<ViewStyle>;
53
+ };
54
+
55
+ /**
56
+ * A wrapper for views that should respond to touches.
57
+ * Provides a material "ink ripple" interaction effect for supported platforms (>= Android Lollipop).
58
+ * On unsupported platforms, it falls back to a highlight effect.
59
+ *
60
+ * <div class="screenshots">
61
+ * <figure>
62
+ * <img class="small" src="screenshots/touchable-ripple.gif" />
63
+ * </figure>
64
+ * </div>
65
+ *
66
+ * ## Usage
67
+ * ```js
68
+ * import * as React from 'react';
69
+ * import { View } from 'react-native';
70
+ * import { Text, TouchableRipple } from 'react-native-paper';
71
+ *
72
+ * const MyComponent = () => (
73
+ * <TouchableRipple
74
+ * onPress={() => console.log('Pressed')}
75
+ * rippleColor="rgba(0, 0, 0, .32)"
76
+ * >
77
+ * <Text>Press anywhere</Text>
78
+ * </TouchableRipple>
79
+ * );
80
+ *
81
+ * export default MyComponent;
82
+ * ```
83
+ *
84
+ * @extends TouchableWithoutFeedback props https://reactnative.dev/docs/touchablewithoutfeedback#props
85
+ */
86
+ const TouchableRipple = (
87
+ {
88
+ style,
89
+ background: _background,
90
+ borderless = false,
91
+ disabled: disabledProp,
92
+ rippleColor: rippleColorProp,
93
+ underlayColor: _underlayColor,
94
+ onPress,
95
+ children,
96
+ onPressIn: onPressInProp,
97
+ onPressOut: onPressOutProp,
98
+ centered,
99
+ ...rest
100
+ }: Props,
101
+ ref: any,
102
+ ) => {
103
+ // TODO - enable ripple onLongPress, need to check for mobile as well
104
+ const disabled = disabledProp || !onPress;
105
+
106
+ const componentStyles = touchableRippleStyles;
107
+
108
+ const { rippleColor, containerStyle } = useMemo(() => {
109
+ const { rippleColor: defaultRippleColor } = componentStyles.root;
110
+
111
+ return {
112
+ rippleColor: rippleColorProp || defaultRippleColor,
113
+ containerStyle: [
114
+ styles.touchable,
115
+ { borderRadius: 'inherit' },
116
+ borderless && styles.borderless,
117
+ // ...(Platform.OS === 'web' && !disabled ? ({ cursor: 'pointer' } as any) : {}),
118
+ componentStyles.root,
119
+ style,
120
+ ],
121
+ };
122
+ }, [borderless, componentStyles.root, rippleColorProp, style]);
123
+
124
+ const handlePressIn = useCallback(
125
+ (e: any) => {
126
+ onPressInProp?.(e);
127
+
128
+ if (disabled) return;
129
+
130
+ const button = e.currentTarget;
131
+ const computedStyle = window.getComputedStyle(button);
132
+ const dimensions = button.getBoundingClientRect();
133
+
134
+ let touchX;
135
+ let touchY;
136
+
137
+ const { changedTouches, touches } = e.nativeEvent;
138
+ const touch = touches?.[0] ?? changedTouches?.[0];
139
+
140
+ // If centered or it was pressed using keyboard - enter or space
141
+ if (centered || !touch) {
142
+ touchX = dimensions.width / 2;
143
+ touchY = dimensions.height / 2;
144
+ } else {
145
+ touchX = touch.locationX ?? e.pageX;
146
+ touchY = touch.locationY ?? e.pageY;
147
+ }
148
+
149
+ // Get the size of the button to determine how big the ripple should be
150
+ const size = centered
151
+ ? // If ripple is always centered, we don't need to make it too big
152
+ Math.min(dimensions.width, dimensions.height) * 1.25
153
+ : // Otherwise make it twice as big so clicking on one end spreads ripple to other
154
+ Math.max(dimensions.width, dimensions.height) * 2;
155
+
156
+ // Create a container for our ripple effect so we don't need to change the parent's style
157
+ const container = document.createElement('span');
158
+
159
+ container.setAttribute('data-paper-ripple', '');
160
+
161
+ Object.assign(container.style, {
162
+ position: 'absolute',
163
+ pointerEvents: 'none',
164
+ top: '0',
165
+ left: '0',
166
+ right: '0',
167
+ bottom: '0',
168
+ borderTopLeftRadius: computedStyle.borderTopLeftRadius,
169
+ borderTopRightRadius: computedStyle.borderTopRightRadius,
170
+ borderBottomRightRadius: computedStyle.borderBottomRightRadius,
171
+ borderBottomLeftRadius: computedStyle.borderBottomLeftRadius,
172
+ overflow: centered ? 'visible' : 'hidden',
173
+ });
174
+
175
+ // Create span to show the ripple effect
176
+ const ripple = document.createElement('span');
177
+
178
+ Object.assign(ripple.style, {
179
+ position: 'absolute',
180
+ pointerEvents: 'none',
181
+ backgroundColor: rippleColor,
182
+ borderRadius: '50%',
183
+
184
+ /* Transition configuration */
185
+ transitionProperty: 'transform opacity',
186
+ transitionDuration: `${Math.min(size * 1.5, 350)}ms`,
187
+ transitionTimingFunction: 'linear',
188
+ transformOrigin: 'center',
189
+
190
+ /* We'll animate these properties */
191
+ transform: 'translate3d(-50%, -50%, 0) scale3d(0.1, 0.1, 0.1)',
192
+ opacity: '0.5',
193
+
194
+ // Position the ripple where cursor was
195
+ left: `${touchX}px`,
196
+ top: `${touchY}px`,
197
+ width: `${size}px`,
198
+ height: `${size}px`,
199
+ });
200
+
201
+ // Finally, append it to DOM
202
+ container.appendChild(ripple);
203
+ button.appendChild(container);
204
+
205
+ // rAF runs in the same frame as the event handler
206
+ // Use double rAF to ensure the transition class is added in next frame
207
+ // This will make sure that the transition animation is triggered
208
+ requestAnimationFrame(() => {
209
+ requestAnimationFrame(() => {
210
+ Object.assign(ripple.style, {
211
+ transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)',
212
+ opacity: '1',
213
+ });
214
+ });
215
+ });
216
+ },
217
+ [onPressInProp, disabled, centered, rippleColor],
218
+ );
219
+
220
+ const handlePressOut = useCallback(
221
+ (e: any) => {
222
+ onPressOutProp?.(e);
223
+
224
+ if (disabled) return;
225
+
226
+ const containers = e.currentTarget.querySelectorAll(
227
+ '[data-paper-ripple]',
228
+ ) as HTMLElement[];
229
+
230
+ requestAnimationFrame(() => {
231
+ requestAnimationFrame(() => {
232
+ containers.forEach(container => {
233
+ const ripple = container.firstChild as HTMLSpanElement;
234
+
235
+ Object.assign(ripple.style, {
236
+ transitionDuration: '250ms',
237
+ opacity: 0,
238
+ });
239
+
240
+ // Finally remove the span after the transition
241
+ setTimeout(() => {
242
+ const { parentNode } = container;
243
+
244
+ if (parentNode) {
245
+ parentNode.removeChild(container);
246
+ }
247
+ }, 500);
248
+ });
249
+ });
250
+ });
251
+ },
252
+ [onPressOutProp, disabled],
253
+ );
254
+
255
+ const Component = onPress ? Pressable : View;
256
+
257
+ return (
258
+ <Component
259
+ {...(onPress ? { role: 'button' } : {})}
260
+ {...rest}
261
+ style={containerStyle}
262
+ ref={ref}
263
+ onPress={onPress}
264
+ onPressIn={handlePressIn}
265
+ onPressOut={handlePressOut}
266
+ disabled={disabled}>
267
+ {Children.only(children)}
268
+ </Component>
269
+ );
270
+ };
271
+
272
+ /**
273
+ * Whether ripple effect is supported.
274
+ */
275
+ TouchableRipple.supported = true;
276
+
277
+ const styles = StyleSheet.create({
278
+ touchable: {
279
+ position: 'relative',
280
+ },
281
+ borderless: {
282
+ overflow: 'hidden',
283
+ },
284
+ });
285
+
286
+ export default memo(forwardRef(TouchableRipple));
@@ -0,0 +1,14 @@
1
+ import { getRegisteredComponentWithFallback, registerMoleculesComponents } from '../../core';
2
+ import TouchableRippleDefault from './TouchableRipple';
3
+
4
+ registerMoleculesComponents({
5
+ TouchableRipple: TouchableRippleDefault,
6
+ });
7
+
8
+ export const TouchableRipple = getRegisteredComponentWithFallback(
9
+ 'TouchableRipple',
10
+ TouchableRippleDefault,
11
+ );
12
+
13
+ export type { Props as TouchableRippleProps } from './TouchableRipple';
14
+ export { touchableRippleStyles } from './utils';
@@ -0,0 +1,15 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+
3
+ import { getRegisteredMoleculesComponentStyles, registerComponentsStyles } from '../../core';
4
+
5
+ const touchableRippleStylesDefault = StyleSheet.create(theme => ({
6
+ root: {
7
+ rippleColor: theme.colors.onSurfaceRipple,
8
+ } as any,
9
+ }));
10
+
11
+ registerComponentsStyles({
12
+ TouchableRipple: touchableRippleStylesDefault,
13
+ });
14
+
15
+ export const touchableRippleStyles = getRegisteredMoleculesComponentStyles('TouchableRipple');
@@ -0,0 +1,99 @@
1
+ import { memo } from 'react';
2
+ import { type StyleProp, View, type ViewProps, type ViewStyle } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+
5
+ import { getRegisteredMoleculesComponentStyles, registerComponentStyles } from '../../core';
6
+
7
+ export type Props = Omit<ViewProps, 'children'> & {
8
+ /**
9
+ * Top Inset of the Divider.
10
+ */
11
+ topInset?: number;
12
+ /**
13
+ * Bottom Inset of the Divider.
14
+ */
15
+ bottomInset?: number;
16
+ /**
17
+ * Whether divider should be bolded.
18
+ */
19
+ bold?: boolean;
20
+ /**
21
+ * Horizontal spacing of the Divider
22
+ */
23
+ spacing?: number;
24
+ style?: StyleProp<ViewStyle>;
25
+ };
26
+
27
+ /**
28
+ * A divider is a thin, lightweight separator that groups content in lists and page layouts.
29
+ *
30
+ * <div class="screenshots">
31
+ * <figure>
32
+ * <img class="medium" src="screenshots/divider.png" />
33
+ * </figure>
34
+ * </div>
35
+ *
36
+ * ## Usage
37
+ * ```js
38
+ * import * as React from 'react';
39
+ * import { View } from 'react-native';
40
+ * import { Divider, Text } from 'react-native-paper';
41
+ *
42
+ * const MyComponent = () => (
43
+ * <View>
44
+ * <Text>Lemon</Text>
45
+ * <Divider />
46
+ * <Text>Mango</Text>
47
+ * <Divider />
48
+ * </View>
49
+ * );
50
+ *
51
+ * export default MyComponent;
52
+ * ```
53
+ */
54
+
55
+ const VerticalDivider = ({
56
+ topInset = 0,
57
+ bottomInset = 0,
58
+ spacing = 0,
59
+ style,
60
+ bold = false,
61
+ ...rest
62
+ }: Props) => {
63
+ verticalDividerStyles.useVariants({
64
+ isBold: bold,
65
+ });
66
+
67
+ return (
68
+ <View
69
+ {...rest}
70
+ style={[
71
+ verticalDividerStyles.root,
72
+ style,
73
+ topInset && { marginTop: topInset },
74
+ bottomInset && { marginBottom: bottomInset },
75
+ spacing && { marginHorizontal: spacing },
76
+ ]}
77
+ />
78
+ );
79
+ };
80
+
81
+ export const verticalDividerStylesDefault = StyleSheet.create(theme => ({
82
+ root: {
83
+ width: StyleSheet.hairlineWidth,
84
+ background: theme.colors.outlineVariant,
85
+
86
+ variants: {
87
+ isBold: {
88
+ true: {
89
+ width: 1,
90
+ },
91
+ },
92
+ },
93
+ },
94
+ }));
95
+
96
+ registerComponentStyles('VerticalDivider', verticalDividerStylesDefault);
97
+ export const verticalDividerStyles = getRegisteredMoleculesComponentStyles('HorizontalDivider');
98
+
99
+ export default memo(VerticalDivider);
@@ -0,0 +1,13 @@
1
+ import { getRegisteredComponentWithFallback, registerMoleculesComponents } from '../../core';
2
+ import VerticalDividerDefault from './VerticalDivider';
3
+
4
+ registerMoleculesComponents({
5
+ VerticalDivider: VerticalDividerDefault,
6
+ });
7
+
8
+ export const VerticalDivider = getRegisteredComponentWithFallback(
9
+ 'VerticalDivider',
10
+ VerticalDividerDefault,
11
+ );
12
+
13
+ export { type Props as VerticalDividerProps, verticalDividerStyles } from './VerticalDivider';
@@ -0,0 +1,87 @@
1
+ import type { ComponentType, Context as ContextType, PropsWithChildren } from 'react';
2
+ import { Fragment, useContext, useId, useMemo, useRef, useState } from 'react';
3
+
4
+ import typedMemo from '../hocs/typedMemo';
5
+ import { Repository } from '../utils/repository';
6
+
7
+ // https://github.com/pmndrs/its-fine/blob/main/src/index.tsx
8
+ // In development, React will warn about using contexts between renderers.
9
+ // Hide the warning because its-fine fixes this issue
10
+ // https://github.com/facebook/react/pull/12779
11
+ function wrapContext<T>(context: React.Context<T>): React.Context<T> {
12
+ try {
13
+ return Object.defineProperties(context, {
14
+ _currentRenderer: {
15
+ get() {
16
+ return null;
17
+ },
18
+ set() {},
19
+ },
20
+ _currentRenderer2: {
21
+ get() {
22
+ return null;
23
+ },
24
+ set() {},
25
+ },
26
+ });
27
+ } catch (_) {
28
+ return context;
29
+ }
30
+ }
31
+
32
+ export const createContextBridge = <T extends object>(
33
+ bridgeName: string,
34
+ Wrapper: ComponentType<T>,
35
+ contexts: ContextType<any>[] = [],
36
+ ) => {
37
+ const respository = new Repository<ContextType<any>[]>({
38
+ name: bridgeName,
39
+ onRegister: (arg, name, registry) => {
40
+ return [registry[name] ?? [], arg].flat();
41
+ },
42
+ });
43
+
44
+ return {
45
+ registerContextToBridge: (updatedContexts: ContextType<any> | ContextType<any>[]) => {
46
+ respository.register(
47
+ 'contexts',
48
+ ([] as ContextType<any>[])
49
+ .concat(updatedContexts)
50
+ .map(context => wrapContext(context)),
51
+ );
52
+ },
53
+ BridgedComponent: typedMemo((props: PropsWithChildren<T> & { name?: string }) => {
54
+ const { name, ...rest } = props;
55
+ const contextValuesRef = useRef<any[]>([]);
56
+
57
+ const id = useId();
58
+
59
+ const [allContexts] = useState(() =>
60
+ Array.from(new Set([...contexts, ...Object.values(respository.getAll()).flat()])),
61
+ );
62
+
63
+ for (const i in allContexts) {
64
+ // eslint-disable-next-line react-hooks/rules-of-hooks
65
+ contextValuesRef.current[i] = useContext(allContexts[i]);
66
+ }
67
+
68
+ const content = useMemo(() => {
69
+ return allContexts.reduce((acc, Context, currentIndex) => {
70
+ return (
71
+ <Context.Provider value={contextValuesRef.current[currentIndex]}>
72
+ {acc}
73
+ </Context.Provider>
74
+ );
75
+ }, <>{props.children}</>);
76
+ // eslint-disable-next-line react-hooks/exhaustive-deps
77
+ }, [...contextValuesRef.current, allContexts, props.children]);
78
+
79
+ const _key = name ? name + id : id;
80
+ return (
81
+ <Wrapper name={name} {...(rest as T)}>
82
+ <Fragment key={_key}>{content}</Fragment>
83
+ </Wrapper>
84
+ );
85
+ }),
86
+ };
87
+ };
@@ -0,0 +1,164 @@
1
+ import EventEmitter, {
2
+ type ConstructorOptions,
3
+ type event as Event,
4
+ type eventNS,
5
+ } from 'eventemitter2';
6
+ import type { ComponentType } from 'react';
7
+
8
+ interface RepositoryConstructor<T> extends ConstructorOptions {
9
+ onRegister?: (arg: T, name: string, registery: Record<string, T>) => T;
10
+ name?: string;
11
+ }
12
+
13
+ let id = Date.now();
14
+
15
+ export class Repository<T> extends EventEmitter {
16
+ private registry: Record<string, T> = {};
17
+ readonly #name!: string;
18
+
19
+ readonly #onRegister!: (arg: T, name: string, registery: Record<string, T>) => T;
20
+
21
+ get name() {
22
+ return this.#name;
23
+ }
24
+
25
+ static get uniqueId() {
26
+ return (id++).toString(36).substring(0, 15);
27
+ }
28
+
29
+ constructor({
30
+ onRegister = arg => arg,
31
+ name = Repository.uniqueId,
32
+ ...options
33
+ }: RepositoryConstructor<T> = {}) {
34
+ super(options);
35
+ this.#onRegister = onRegister;
36
+ this.#name = name;
37
+ }
38
+
39
+ has = (itemName: string): boolean => {
40
+ return !!this.registry[itemName];
41
+ };
42
+
43
+ emit(event: eventNS | Event, ...values: any[]) {
44
+ event = typeof event === 'string' ? `${this.#name}::event` : event;
45
+ return super.emit(event, ...values);
46
+ }
47
+
48
+ /**
49
+ * Register a item with the src.
50
+ */
51
+ registerOne = <X extends T = T, ItemName extends string = ''>(itemName: ItemName, item: X) => {
52
+ let updatedItem = this.#onRegister?.(item, itemName, { ...this.registry });
53
+ if (!updatedItem) updatedItem = item;
54
+
55
+ if (this.registry[itemName]) return;
56
+
57
+ this.registry = {
58
+ ...this.registry,
59
+ [itemName]: updatedItem,
60
+ };
61
+
62
+ this.emit('item_registered', itemName);
63
+ };
64
+
65
+ /**
66
+ * Register a item with the src.
67
+ */
68
+ register = (items: Record<string, any>) => {
69
+ // let updatedItem = this.#onRegister?.(item, itemName, { ...this.registry });
70
+ // if (!updatedItem) updatedItem = item;
71
+
72
+ Object.keys(items).forEach(itemName => {
73
+ if (this.registry[itemName]) return;
74
+ this.registry = {
75
+ ...this.registry,
76
+ [itemName]: items[itemName],
77
+ };
78
+ });
79
+ };
80
+
81
+ /**
82
+ * Get all registered module from the registry.
83
+ */
84
+ getAll = () => {
85
+ return this.registry;
86
+ };
87
+
88
+ get = (name: string) => {
89
+ return this.registry[name];
90
+ };
91
+ }
92
+
93
+ export const componentsRepository = new Repository<Record<string, any>>({
94
+ name: 'Components_Repository',
95
+ maxListeners: 0,
96
+ });
97
+
98
+ export const componentsStylesRepository = new Repository<Record<string, any>>({
99
+ name: 'Components_Styles_Repository',
100
+ maxListeners: 0,
101
+ });
102
+
103
+ export const componentsUtilsRepository = new Repository<Record<string, any>>({
104
+ name: 'Components_Utils_Repository',
105
+ maxListeners: 0,
106
+ });
107
+
108
+ export const registerMoleculesComponent = componentsRepository.registerOne;
109
+ export const registerMoleculesComponents = componentsRepository.register;
110
+ export const registerComponentStyles = componentsStylesRepository.registerOne;
111
+ export const registerComponentsStyles = componentsStylesRepository.register;
112
+ export const registerComponentUtils = componentsUtilsRepository.registerOne;
113
+ export const registerComponentsUtils = componentsUtilsRepository.register;
114
+
115
+ type RegisterMoleculesConfig = {
116
+ component: ComponentType<any>;
117
+ styles?: Record<string, any>;
118
+ utils?: Record<string, any>;
119
+ };
120
+
121
+ export const registerMolecules = (molecules: Record<string, RegisterMoleculesConfig>) => {
122
+ const components: Record<string, ComponentType<any>> = {};
123
+ const styles: Record<string, Record<string, any>> = {};
124
+ const utils: Record<string, Record<string, any>> = {};
125
+
126
+ Object.entries(molecules).forEach(([name, config]) => {
127
+ if (config.component) {
128
+ components[name] = config.component;
129
+ }
130
+ if (config.styles) {
131
+ styles[name] = config.styles;
132
+ }
133
+ if (config.utils) {
134
+ utils[name] = config.utils;
135
+ }
136
+ });
137
+
138
+ if (Object.keys(components).length) {
139
+ registerMoleculesComponents(components);
140
+ }
141
+ if (Object.keys(styles).length) {
142
+ registerComponentsStyles(styles);
143
+ }
144
+ if (Object.keys(utils).length) {
145
+ registerComponentsUtils(utils);
146
+ }
147
+ };
148
+
149
+ export const getRegisteredMoleculesComponent = componentsRepository.get;
150
+ export const getRegisteredMoleculesComponentStyles = componentsStylesRepository.get;
151
+ export const getRegisteredComponentUtils = componentsUtilsRepository.get;
152
+
153
+ /**
154
+ * Gets a registered component with a fallback to the default component
155
+ * @param name The name of the component to retrieve
156
+ * @param defaultComponent The default component to use as fallback
157
+ * @returns The registered component or the default component
158
+ */
159
+ export function getRegisteredComponentWithFallback<T extends ComponentType<any>>(
160
+ name: string,
161
+ defaultComponent: T,
162
+ ): T {
163
+ return (getRegisteredMoleculesComponent(name) ?? defaultComponent) as T;
164
+ }
package/core/index.tsx ADDED
@@ -0,0 +1,2 @@
1
+ export * from './componentsRegistry';
2
+ export { PortalProvider } from '@gorhom/portal';