bootstrap-rn 0.4.6 → 0.4.7

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 (287) hide show
  1. package/lib/module/Context.js.map +1 -1
  2. package/lib/module/Provider.js +3 -7
  3. package/lib/module/Provider.js.map +1 -1
  4. package/lib/module/components/Body.js +8 -1
  5. package/lib/module/components/Body.js.map +1 -1
  6. package/lib/module/components/buttons/Button.js +10 -8
  7. package/lib/module/components/buttons/Button.js.map +1 -1
  8. package/lib/module/components/close/CloseButton.js +7 -3
  9. package/lib/module/components/close/CloseButton.js.map +1 -1
  10. package/lib/module/components/collapse/useCollapse.js +2 -3
  11. package/lib/module/components/collapse/useCollapse.js.map +1 -1
  12. package/lib/module/components/dropdown/Dropdown.js +1 -2
  13. package/lib/module/components/dropdown/Dropdown.js.map +1 -1
  14. package/lib/module/components/dropdown/DropdownContext.js.map +1 -1
  15. package/lib/module/components/dropdown/DropdownMenu.js +33 -59
  16. package/lib/module/components/dropdown/DropdownMenu.js.map +1 -1
  17. package/lib/module/components/dropdown/useDismissDropdown.js +5 -4
  18. package/lib/module/components/dropdown/useDismissDropdown.js.map +1 -1
  19. package/lib/module/components/dropdown/useDropdown.js +35 -11
  20. package/lib/module/components/dropdown/useDropdown.js.map +1 -1
  21. package/lib/module/components/dropdown/useToggleDropdown.js +4 -6
  22. package/lib/module/components/dropdown/useToggleDropdown.js.map +1 -1
  23. package/lib/module/components/forms/FormCheckInput.js +1 -1
  24. package/lib/module/components/forms/Input.js +1 -1
  25. package/lib/module/components/forms/internals/PickerNative.js +1 -1
  26. package/lib/module/components/forms/internals/PickerNative.js.map +1 -1
  27. package/lib/module/components/helpers/BackdropHandler.js +6 -92
  28. package/lib/module/components/helpers/BackdropHandler.js.map +1 -1
  29. package/lib/module/components/helpers/BackdropHandler.web.js +8 -0
  30. package/lib/module/components/helpers/BackdropHandler.web.js.map +1 -0
  31. package/lib/module/components/helpers/Dialog.js +29 -0
  32. package/lib/module/components/helpers/Dialog.js.map +1 -0
  33. package/lib/module/components/helpers/Dialog.web.js +117 -0
  34. package/lib/module/components/helpers/Dialog.web.js.map +1 -0
  35. package/lib/module/components/helpers/Portal.js +5 -0
  36. package/lib/module/components/helpers/Portal.js.map +1 -0
  37. package/lib/module/components/helpers/Portal.web.js +16 -0
  38. package/lib/module/components/helpers/Portal.web.js.map +1 -0
  39. package/lib/module/components/helpers/PortalHost.js +5 -0
  40. package/lib/module/components/helpers/PortalHost.js.map +1 -0
  41. package/lib/module/components/helpers/PortalHost.web.js +15 -0
  42. package/lib/module/components/helpers/PortalHost.web.js.map +1 -0
  43. package/lib/module/components/modal/Modal.js +58 -48
  44. package/lib/module/components/modal/Modal.js.map +1 -1
  45. package/lib/module/components/modal/ModalContext.js.map +1 -1
  46. package/lib/module/components/modal/ModalTitle.js +6 -0
  47. package/lib/module/components/modal/ModalTitle.js.map +1 -1
  48. package/lib/module/components/modal/useModal.js +4 -13
  49. package/lib/module/components/modal/useModal.js.map +1 -1
  50. package/lib/module/components/nav/useTabbable.js +2 -3
  51. package/lib/module/components/nav/useTabbable.js.map +1 -1
  52. package/lib/module/components/navbar/NavbarToggler.js +1 -1
  53. package/lib/module/components/navbar/useNavbar.js +2 -3
  54. package/lib/module/components/navbar/useNavbar.js.map +1 -1
  55. package/lib/module/components/offcanvas/Offcanvas.js +84 -82
  56. package/lib/module/components/offcanvas/Offcanvas.js.map +1 -1
  57. package/lib/module/components/offcanvas/OffcanvasContext.js.map +1 -1
  58. package/lib/module/components/offcanvas/OffcanvasTitle.js +6 -0
  59. package/lib/module/components/offcanvas/OffcanvasTitle.js.map +1 -1
  60. package/lib/module/components/offcanvas/useOffcanvas.js +6 -14
  61. package/lib/module/components/offcanvas/useOffcanvas.js.map +1 -1
  62. package/lib/module/components/pagination/PaginationItem.js +39 -39
  63. package/lib/module/components/popover/Popover.js +6 -8
  64. package/lib/module/components/popover/Popover.js.map +1 -1
  65. package/lib/module/components/popover/PopoverArrow.js +18 -9
  66. package/lib/module/components/popover/PopoverArrow.js.map +1 -1
  67. package/lib/module/components/popover/PopoverContext.js.map +1 -1
  68. package/lib/module/components/popover/injectPopover.js +48 -45
  69. package/lib/module/components/popover/injectPopover.js.map +1 -1
  70. package/lib/module/components/tooltip/Tooltip.js +7 -23
  71. package/lib/module/components/tooltip/Tooltip.js.map +1 -1
  72. package/lib/module/components/tooltip/TooltipArrow.js +22 -12
  73. package/lib/module/components/tooltip/TooltipArrow.js.map +1 -1
  74. package/lib/module/components/tooltip/TooltipContext.js.map +1 -1
  75. package/lib/module/components/tooltip/injectTooltip.js +46 -42
  76. package/lib/module/components/tooltip/injectTooltip.js.map +1 -1
  77. package/lib/module/hooks/useBackgroundNative.js.map +1 -1
  78. package/lib/module/hooks/useFocusRing.js +13 -0
  79. package/lib/module/hooks/useFocusRing.js.map +1 -0
  80. package/lib/module/hooks/useFocusRing.web.js +5 -0
  81. package/lib/module/hooks/useFocusRing.web.js.map +1 -0
  82. package/lib/module/hooks/useInteractionState.js +11 -11
  83. package/lib/module/hooks/useInteractionState.js.map +1 -1
  84. package/lib/module/hooks/useOverlay.js +121 -0
  85. package/lib/module/hooks/useOverlay.js.map +1 -0
  86. package/lib/module/hooks/useOverlay.web.js +113 -0
  87. package/lib/module/hooks/useOverlay.web.js.map +1 -0
  88. package/lib/module/hooks/useScrollbarEffects.js +7 -60
  89. package/lib/module/hooks/useScrollbarEffects.js.map +1 -1
  90. package/lib/module/hooks/useScrollbarEffects.web.js +59 -0
  91. package/lib/module/hooks/useScrollbarEffects.web.js.map +1 -0
  92. package/lib/module/index.js +3 -3
  93. package/lib/module/index.js.map +1 -1
  94. package/lib/module/style/StyleSheet.js +1 -3
  95. package/lib/module/style/StyleSheet.js.map +1 -1
  96. package/lib/module/theme/variables.js +9 -9
  97. package/lib/module/utils.js +0 -11
  98. package/lib/module/utils.js.map +1 -1
  99. package/lib/typescript/Context.d.ts +0 -1
  100. package/lib/typescript/Context.d.ts.map +1 -1
  101. package/lib/typescript/Provider.d.ts.map +1 -1
  102. package/lib/typescript/components/Body.d.ts.map +1 -1
  103. package/lib/typescript/components/Link.d.ts +1 -1
  104. package/lib/typescript/components/Link.d.ts.map +1 -1
  105. package/lib/typescript/components/Pressable.d.ts +1 -1
  106. package/lib/typescript/components/Pressable.d.ts.map +1 -1
  107. package/lib/typescript/components/TextInput.d.ts +3 -3
  108. package/lib/typescript/components/TextInput.d.ts.map +1 -1
  109. package/lib/typescript/components/buttons/Button.d.ts +1 -1
  110. package/lib/typescript/components/buttons/Button.d.ts.map +1 -1
  111. package/lib/typescript/components/close/CloseButton.d.ts +1 -1
  112. package/lib/typescript/components/close/CloseButton.d.ts.map +1 -1
  113. package/lib/typescript/components/collapse/useCollapse.d.ts.map +1 -1
  114. package/lib/typescript/components/dropdown/Dropdown.d.ts +0 -1
  115. package/lib/typescript/components/dropdown/Dropdown.d.ts.map +1 -1
  116. package/lib/typescript/components/dropdown/DropdownContext.d.ts +14 -3
  117. package/lib/typescript/components/dropdown/DropdownContext.d.ts.map +1 -1
  118. package/lib/typescript/components/dropdown/DropdownMenu.d.ts +0 -1
  119. package/lib/typescript/components/dropdown/DropdownMenu.d.ts.map +1 -1
  120. package/lib/typescript/components/dropdown/useDismissDropdown.d.ts +1 -1
  121. package/lib/typescript/components/dropdown/useDismissDropdown.d.ts.map +1 -1
  122. package/lib/typescript/components/dropdown/useDropdown.d.ts +38 -4
  123. package/lib/typescript/components/dropdown/useDropdown.d.ts.map +1 -1
  124. package/lib/typescript/components/dropdown/useToggleDropdown.d.ts +4 -3
  125. package/lib/typescript/components/dropdown/useToggleDropdown.d.ts.map +1 -1
  126. package/lib/typescript/components/forms/Picker.d.ts +1 -1
  127. package/lib/typescript/components/forms/internals/PickerNative.d.ts +1 -1
  128. package/lib/typescript/components/forms/internals/PickerNative.d.ts.map +1 -1
  129. package/lib/typescript/components/forms/internals/PickerWeb.d.ts +1 -1
  130. package/lib/typescript/components/forms/internals/PickerWeb.d.ts.map +1 -1
  131. package/lib/typescript/components/helpers/BackdropHandler.d.ts +2 -11
  132. package/lib/typescript/components/helpers/BackdropHandler.d.ts.map +1 -1
  133. package/lib/typescript/components/helpers/BackdropHandler.web.d.ts +3 -0
  134. package/lib/typescript/components/helpers/BackdropHandler.web.d.ts.map +1 -0
  135. package/lib/typescript/components/helpers/Dialog.d.ts +15 -0
  136. package/lib/typescript/components/helpers/Dialog.d.ts.map +1 -0
  137. package/lib/typescript/components/helpers/Dialog.web.d.ts +15 -0
  138. package/lib/typescript/components/helpers/Dialog.web.d.ts.map +1 -0
  139. package/lib/typescript/components/helpers/Portal.d.ts +8 -0
  140. package/lib/typescript/components/helpers/Portal.d.ts.map +1 -0
  141. package/lib/typescript/components/helpers/Portal.web.d.ts +8 -0
  142. package/lib/typescript/components/helpers/Portal.web.d.ts.map +1 -0
  143. package/lib/typescript/components/helpers/PortalHost.d.ts +6 -0
  144. package/lib/typescript/components/helpers/PortalHost.d.ts.map +1 -0
  145. package/lib/typescript/components/helpers/PortalHost.web.d.ts +7 -0
  146. package/lib/typescript/components/helpers/PortalHost.web.d.ts.map +1 -0
  147. package/lib/typescript/components/list-group/ListGroup.d.ts +1 -1
  148. package/lib/typescript/components/list-group/ListGroupItemAction.d.ts +1 -1
  149. package/lib/typescript/components/list-group/ListGroupItemAction.d.ts.map +1 -1
  150. package/lib/typescript/components/modal/Modal.d.ts +1 -1
  151. package/lib/typescript/components/modal/Modal.d.ts.map +1 -1
  152. package/lib/typescript/components/modal/ModalContext.d.ts +1 -0
  153. package/lib/typescript/components/modal/ModalContext.d.ts.map +1 -1
  154. package/lib/typescript/components/modal/ModalTitle.d.ts.map +1 -1
  155. package/lib/typescript/components/modal/useModal.d.ts +2 -1
  156. package/lib/typescript/components/modal/useModal.d.ts.map +1 -1
  157. package/lib/typescript/components/nav/Nav.d.ts +1 -1
  158. package/lib/typescript/components/nav/NavLink.d.ts +1 -1
  159. package/lib/typescript/components/nav/NavLink.d.ts.map +1 -1
  160. package/lib/typescript/components/nav/useTabbable.d.ts.map +1 -1
  161. package/lib/typescript/components/navbar/Navbar.d.ts +2 -2
  162. package/lib/typescript/components/navbar/NavbarBrand.d.ts +1 -1
  163. package/lib/typescript/components/navbar/NavbarBrand.d.ts.map +1 -1
  164. package/lib/typescript/components/navbar/NavbarToggler.d.ts +1 -1
  165. package/lib/typescript/components/navbar/NavbarToggler.d.ts.map +1 -1
  166. package/lib/typescript/components/navbar/useNavbar.d.ts.map +1 -1
  167. package/lib/typescript/components/offcanvas/Offcanvas.d.ts +1 -4
  168. package/lib/typescript/components/offcanvas/Offcanvas.d.ts.map +1 -1
  169. package/lib/typescript/components/offcanvas/OffcanvasContext.d.ts +3 -1
  170. package/lib/typescript/components/offcanvas/OffcanvasContext.d.ts.map +1 -1
  171. package/lib/typescript/components/offcanvas/OffcanvasTitle.d.ts.map +1 -1
  172. package/lib/typescript/components/offcanvas/useOffcanvas.d.ts +3 -1
  173. package/lib/typescript/components/offcanvas/useOffcanvas.d.ts.map +1 -1
  174. package/lib/typescript/components/popover/Popover.d.ts +3 -4
  175. package/lib/typescript/components/popover/Popover.d.ts.map +1 -1
  176. package/lib/typescript/components/popover/PopoverArrow.d.ts.map +1 -1
  177. package/lib/typescript/components/popover/PopoverContext.d.ts +3 -4
  178. package/lib/typescript/components/popover/PopoverContext.d.ts.map +1 -1
  179. package/lib/typescript/components/popover/injectPopover.d.ts +5 -7
  180. package/lib/typescript/components/popover/injectPopover.d.ts.map +1 -1
  181. package/lib/typescript/components/tooltip/Tooltip.d.ts +3 -4
  182. package/lib/typescript/components/tooltip/Tooltip.d.ts.map +1 -1
  183. package/lib/typescript/components/tooltip/TooltipArrow.d.ts.map +1 -1
  184. package/lib/typescript/components/tooltip/TooltipContext.d.ts +3 -4
  185. package/lib/typescript/components/tooltip/TooltipContext.d.ts.map +1 -1
  186. package/lib/typescript/components/tooltip/injectTooltip.d.ts +5 -7
  187. package/lib/typescript/components/tooltip/injectTooltip.d.ts.map +1 -1
  188. package/lib/typescript/hooks/useBackgroundNative.d.ts.map +1 -1
  189. package/lib/typescript/hooks/useFocusRing.d.ts +3 -0
  190. package/lib/typescript/hooks/useFocusRing.d.ts.map +1 -0
  191. package/lib/typescript/hooks/useFocusRing.web.d.ts +3 -0
  192. package/lib/typescript/hooks/useFocusRing.web.d.ts.map +1 -0
  193. package/lib/typescript/hooks/useInteractionState.d.ts +7 -7
  194. package/lib/typescript/hooks/useInteractionState.d.ts.map +1 -1
  195. package/lib/typescript/hooks/useOverlay.d.ts +64 -0
  196. package/lib/typescript/hooks/useOverlay.d.ts.map +1 -0
  197. package/lib/typescript/hooks/useOverlay.web.d.ts +37 -0
  198. package/lib/typescript/hooks/useOverlay.web.d.ts.map +1 -0
  199. package/lib/typescript/hooks/useScrollbarEffects.d.ts.map +1 -1
  200. package/lib/typescript/hooks/useScrollbarEffects.web.d.ts +7 -0
  201. package/lib/typescript/hooks/useScrollbarEffects.web.d.ts.map +1 -0
  202. package/lib/typescript/index.d.ts +5 -4
  203. package/lib/typescript/index.d.ts.map +1 -1
  204. package/lib/typescript/style/StyleSheet.d.ts.map +1 -1
  205. package/lib/typescript/types.d.ts +12 -6
  206. package/lib/typescript/types.d.ts.map +1 -1
  207. package/lib/typescript/utils.d.ts +2 -3
  208. package/lib/typescript/utils.d.ts.map +1 -1
  209. package/package.json +92 -85
  210. package/src/Context.ts +37 -38
  211. package/src/Provider.tsx +61 -66
  212. package/src/components/Body.tsx +16 -1
  213. package/src/components/TextInput.tsx +66 -66
  214. package/src/components/buttons/Button.tsx +381 -379
  215. package/src/components/close/CloseButton.tsx +142 -138
  216. package/src/components/collapse/useCollapse.ts +25 -26
  217. package/src/components/dropdown/Dropdown.tsx +77 -80
  218. package/src/components/dropdown/DropdownContext.ts +14 -3
  219. package/src/components/dropdown/DropdownMenu.tsx +243 -284
  220. package/src/components/dropdown/useDismissDropdown.ts +30 -29
  221. package/src/components/dropdown/useDropdown.ts +55 -38
  222. package/src/components/dropdown/useToggleDropdown.ts +31 -32
  223. package/src/components/forms/FormCheckInput.tsx +268 -268
  224. package/src/components/forms/Input.tsx +220 -220
  225. package/src/components/forms/internals/PickerNative.tsx +9 -10
  226. package/src/components/helpers/BackdropHandler.tsx +5 -119
  227. package/src/components/helpers/BackdropHandler.web.tsx +6 -0
  228. package/src/components/helpers/Dialog.tsx +49 -0
  229. package/src/components/helpers/Dialog.web.tsx +145 -0
  230. package/src/components/helpers/Portal.tsx +10 -0
  231. package/src/components/helpers/Portal.web.tsx +22 -0
  232. package/src/components/helpers/PortalHost.tsx +7 -0
  233. package/src/components/helpers/PortalHost.web.tsx +14 -0
  234. package/src/components/modal/Modal.tsx +60 -48
  235. package/src/components/modal/ModalContext.ts +12 -11
  236. package/src/components/modal/ModalTitle.tsx +41 -31
  237. package/src/components/modal/useModal.ts +13 -25
  238. package/src/components/nav/useTabbable.ts +31 -32
  239. package/src/components/navbar/NavbarToggler.tsx +130 -130
  240. package/src/components/navbar/useNavbar.ts +30 -31
  241. package/src/components/offcanvas/Offcanvas.tsx +91 -92
  242. package/src/components/offcanvas/OffcanvasContext.ts +13 -11
  243. package/src/components/offcanvas/OffcanvasTitle.tsx +43 -33
  244. package/src/components/offcanvas/useOffcanvas.ts +12 -20
  245. package/src/components/pagination/PaginationItem.tsx +139 -139
  246. package/src/components/popover/Popover.tsx +87 -90
  247. package/src/components/popover/PopoverArrow.tsx +22 -6
  248. package/src/components/popover/PopoverContext.ts +13 -18
  249. package/src/components/popover/injectPopover.tsx +63 -55
  250. package/src/components/tooltip/Tooltip.tsx +79 -98
  251. package/src/components/tooltip/TooltipArrow.tsx +26 -8
  252. package/src/components/tooltip/TooltipContext.ts +13 -18
  253. package/src/components/tooltip/injectTooltip.tsx +62 -53
  254. package/src/hooks/useAction.ts +78 -78
  255. package/src/hooks/useBackgroundNative.tsx +6 -4
  256. package/src/hooks/useFocusRing.ts +13 -0
  257. package/src/hooks/useFocusRing.web.ts +3 -0
  258. package/src/hooks/useInteractionState.ts +75 -81
  259. package/src/hooks/useOverlay.ts +197 -0
  260. package/src/hooks/useOverlay.web.ts +190 -0
  261. package/src/hooks/useScrollbarEffects.ts +5 -83
  262. package/src/hooks/useScrollbarEffects.web.ts +83 -0
  263. package/src/index.ts +5 -5
  264. package/src/style/StyleSheet.ts +2 -5
  265. package/src/theme/variables.ts +1420 -1420
  266. package/src/types.ts +14 -14
  267. package/src/utils.ts +4 -22
  268. package/lib/module/components/SafeAreaView.js +0 -42
  269. package/lib/module/components/SafeAreaView.js.map +0 -1
  270. package/lib/module/components/helpers/Overlay.js +0 -50
  271. package/lib/module/components/helpers/Overlay.js.map +0 -1
  272. package/lib/module/hooks/useIdentifier.js +0 -14
  273. package/lib/module/hooks/useIdentifier.js.map +0 -1
  274. package/lib/module/hooks/useTrigger.js +0 -97
  275. package/lib/module/hooks/useTrigger.js.map +0 -1
  276. package/lib/typescript/components/SafeAreaView.d.ts +0 -12
  277. package/lib/typescript/components/SafeAreaView.d.ts.map +0 -1
  278. package/lib/typescript/components/helpers/Overlay.d.ts +0 -28
  279. package/lib/typescript/components/helpers/Overlay.d.ts.map +0 -1
  280. package/lib/typescript/hooks/useIdentifier.d.ts +0 -2
  281. package/lib/typescript/hooks/useIdentifier.d.ts.map +0 -1
  282. package/lib/typescript/hooks/useTrigger.d.ts +0 -33
  283. package/lib/typescript/hooks/useTrigger.d.ts.map +0 -1
  284. package/src/components/SafeAreaView.tsx +0 -64
  285. package/src/components/helpers/Overlay.tsx +0 -81
  286. package/src/hooks/useIdentifier.ts +0 -15
  287. package/src/hooks/useTrigger.ts +0 -141
@@ -0,0 +1,49 @@
1
+ import React, { useEffect } from 'react';
2
+ import { BackHandler } from 'react-native';
3
+ import { Portal } from '@rn-primitives/portal';
4
+ import type { ViewRef } from '../View';
5
+
6
+ type DialogProps = {
7
+ children: React.ReactNode;
8
+ id: string;
9
+ // eslint-disable-next-line react/no-unused-prop-types
10
+ dialogRef: React.RefObject<ViewRef | null>;
11
+ // eslint-disable-next-line react/no-unused-prop-types
12
+ backgroundRef: React.RefObject<ViewRef | null>;
13
+ onClose?: () => void;
14
+ backdrop: boolean | 'static';
15
+ backdropElement: React.ReactNode;
16
+ // eslint-disable-next-line react/no-unused-prop-types
17
+ scroll?: boolean;
18
+ };
19
+
20
+ function Dialog({
21
+ children,
22
+ id,
23
+ backdrop,
24
+ backdropElement,
25
+ onClose: handleClose,
26
+ }: DialogProps) {
27
+ useEffect(() => {
28
+ const backHandler = BackHandler.addEventListener(
29
+ 'hardwareBackPress',
30
+ () => {
31
+ handleClose?.();
32
+ return true;
33
+ },
34
+ );
35
+
36
+ return () => {
37
+ backHandler.remove();
38
+ };
39
+ }, []);
40
+
41
+ return (
42
+ <Portal name={id}>
43
+ {backdrop && backdropElement}
44
+ {children}
45
+ </Portal>
46
+ );
47
+ }
48
+
49
+ export default Dialog;
@@ -0,0 +1,145 @@
1
+ import React, { useContext, useEffect, useRef } from 'react';
2
+ import { FocusScope } from '@react-aria/focus';
3
+ import Portal from './Portal';
4
+ import type { ViewRef } from '../View';
5
+ import Context from '../../Context';
6
+
7
+ type DialogProps = {
8
+ children: React.ReactNode;
9
+ id: string;
10
+ dialogRef: React.RefObject<ViewRef | null>;
11
+ backgroundRef: React.RefObject<ViewRef | null>;
12
+ onClose?: () => void;
13
+ backdrop: boolean | 'static';
14
+ backdropElement: React.ReactNode;
15
+ scroll?: boolean;
16
+ };
17
+
18
+ function Dialog({
19
+ children,
20
+ id,
21
+ dialogRef,
22
+ backgroundRef,
23
+ onClose: handleClose,
24
+ backdrop,
25
+ backdropElement,
26
+ scroll = false,
27
+ }: DialogProps) {
28
+ const context = useContext(Context);
29
+
30
+ // Handle scrollbars
31
+ useEffect(() => {
32
+ if (!context || scroll) {
33
+ return undefined;
34
+ }
35
+
36
+ context.scrollbars.hide();
37
+
38
+ return () => {
39
+ context.scrollbars.show();
40
+ };
41
+ }, [context, scroll]);
42
+
43
+ // Handle ESC key press
44
+ useEffect(() => {
45
+ const dialog = dialogRef.current as HTMLDivElement | null;
46
+
47
+ if (!dialog) {
48
+ return undefined;
49
+ }
50
+
51
+ // Auto-focus dialog element
52
+ dialog.focus();
53
+
54
+ const handleKeyDown = (event: KeyboardEvent) => {
55
+ if (event.key === 'Escape') {
56
+ handleClose?.();
57
+ }
58
+ };
59
+
60
+ dialog.addEventListener('keydown', handleKeyDown);
61
+
62
+ return () => {
63
+ dialog.removeEventListener('keydown', handleKeyDown);
64
+ };
65
+ }, [handleClose]);
66
+
67
+ // Handle outside click
68
+ const state = useRef<{
69
+ waitingForMouseUp: boolean;
70
+ handleClick: ((event: MouseEvent) => void) | null;
71
+ }>({
72
+ waitingForMouseUp: false,
73
+ handleClick: null,
74
+ });
75
+
76
+ useEffect(() => {
77
+ const ref = backgroundRef.current as HTMLDivElement | null;
78
+
79
+ // @ts-expect-error getScrollableNode exists on web only
80
+ const isScrollView = typeof ref?.getScrollableNode === 'function';
81
+
82
+ // If the ref refers to a scroll view, we need the first child, otherwise the ref itself.
83
+ const background = isScrollView ? ref?.firstElementChild : ref;
84
+
85
+ if (!background) {
86
+ return undefined;
87
+ }
88
+
89
+ const handleMouseDown = (event: MouseEvent) => {
90
+ // It might be that a click starts inside the window and ends outside the window, so that
91
+ // only the on mouse down event is dispatched and we need to remove the click listener
92
+ // before the next click event is dispatched.
93
+ if (state.current.waitingForMouseUp && state.current.handleClick) {
94
+ background.removeEventListener('click', state.current.handleClick);
95
+ }
96
+
97
+ // A bad trick to segregate clicks that may start inside dialog but end outside, and avoid
98
+ // listen to scrollbar clicks.
99
+ const handleClick = (event2: MouseEvent) => {
100
+ if (background !== event.target || background !== event2.target) {
101
+ return;
102
+ }
103
+
104
+ if (backdrop === 'static') {
105
+ // TODO: triggerBackdropTransition()
106
+ return;
107
+ }
108
+
109
+ if (backdrop) {
110
+ handleClose?.();
111
+ }
112
+ };
113
+
114
+ state.current = {
115
+ waitingForMouseUp: true,
116
+ handleClick,
117
+ };
118
+
119
+ background.addEventListener('click', handleClick, { once: true });
120
+ };
121
+
122
+ const handleMouseUp = () => {
123
+ state.current.waitingForMouseUp = false;
124
+ };
125
+
126
+ background.addEventListener('mousedown', handleMouseDown);
127
+ background.addEventListener('mouseup', handleMouseUp);
128
+
129
+ return () => {
130
+ background.removeEventListener('mousedown', handleMouseDown);
131
+ background.removeEventListener('mouseup', handleMouseUp);
132
+ };
133
+ }, [backdrop, handleClose]);
134
+
135
+ return (
136
+ <Portal name={id}>
137
+ {backdrop && backdropElement}
138
+ <FocusScope contain restoreFocus>
139
+ {children}
140
+ </FocusScope>
141
+ </Portal>
142
+ );
143
+ }
144
+
145
+ export default Dialog;
@@ -0,0 +1,10 @@
1
+ import { Portal } from '@rn-primitives/portal';
2
+
3
+ export interface PortalProps {
4
+ // eslint-disable-next-line react/no-unused-prop-types
5
+ name: string;
6
+ hostName?: string;
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export default Portal;
@@ -0,0 +1,22 @@
1
+ import { createPortal } from 'react-dom';
2
+
3
+ export interface PortalProps {
4
+ // eslint-disable-next-line react/no-unused-prop-types
5
+ name: string;
6
+ hostName?: string;
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ const DEFAULT_PORTAL_HOST = 'INTERNAL_PRIMITIVE_DEFAULT_HOST_NAME';
11
+
12
+ function Portal({ hostName = DEFAULT_PORTAL_HOST, children }: PortalProps) {
13
+ const element = document.getElementById(hostName);
14
+
15
+ if (!element) {
16
+ return null;
17
+ }
18
+
19
+ return createPortal(children, element);
20
+ }
21
+
22
+ export default Portal;
@@ -0,0 +1,7 @@
1
+ import { PortalHost } from '@rn-primitives/portal';
2
+
3
+ export interface PortalHostProps {
4
+ name?: string;
5
+ }
6
+
7
+ export default PortalHost;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+
4
+ export interface PortalHostProps {
5
+ name?: string;
6
+ }
7
+
8
+ const DEFAULT_PORTAL_HOST = 'INTERNAL_PRIMITIVE_DEFAULT_HOST_NAME';
9
+
10
+ function PortalHost({ name = DEFAULT_PORTAL_HOST }: PortalHostProps) {
11
+ return <View id={name} />;
12
+ }
13
+
14
+ export default PortalHost;
@@ -1,13 +1,12 @@
1
1
  import React, { useRef } from 'react';
2
- import { Modal as BaseModal, Platform } from 'react-native';
3
- import { OverlayProvider } from '@react-native-aria/overlays';
2
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
3
  import StyleSheet from '../../style/StyleSheet';
5
- import { getStyles } from '../../utils';
4
+ import { concatRefs, getStyles } from '../../utils';
6
5
  import css from '../../style/css';
7
6
  import ScrollView, { ScrollViewRef, ScrollViewProps } from '../ScrollView';
8
7
  import View, { ViewRef } from '../View';
8
+ import Dialog from '../helpers/Dialog';
9
9
  import BackdropHandler from '../helpers/BackdropHandler';
10
- import SafeAreaView from '../SafeAreaView';
11
10
  import useModal from './useModal';
12
11
  import ModalContext from './ModalContext';
13
12
  import ModalHeader from './ModalHeader';
@@ -22,7 +21,7 @@ export interface ModalProps extends ScrollViewProps {
22
21
  backdrop?: boolean | 'static';
23
22
  scrollable?: boolean;
24
23
  centered?: boolean;
25
- onToggle: () => void;
24
+ onClose: () => void;
26
25
  dialogStyle?: StyleProp<ExtendedViewStyle>;
27
26
  contentStyle?: StyleProp<ExtendedViewStyle>;
28
27
  dialogTextStyle?: StyleProp<ExtendedTextStyle>;
@@ -39,19 +38,24 @@ type JustifyContentValue =
39
38
 
40
39
  const styles = StyleSheet.create({
41
40
  '.modal': css`
42
- position: absolute; // fixed;
41
+ position: absolute; // added for bootstrap-rn
42
+ @include platform(web) {
43
+ position: fixed;
44
+ }
43
45
  top: 0;
44
46
  left: 0;
45
- z-index: $zindex-modal;
47
+ bottom: 0; // added for bootstrap-rn
48
+ right: 0; // added for bootstrap-rn
49
+ // z-index: $zindex-modal;
46
50
  // display: none;
47
- width: 100%;
48
- height: 100%;
51
+ // width: 100%;
52
+ // height: 100%;
49
53
  // overflow-x: hidden;
50
54
  // overflow-y: auto;
51
55
  // Prevent Chrome on Windows from adding a focus outline. For details, see
52
56
  // https://github.com/twbs/bootstrap/pull/10951.
53
57
  @include platform(web) {
54
- outline-width: 0; // outline: 0;
58
+ outline-style: none; // outline: 0;
55
59
  }
56
60
  // We deliberately don't use "-webkit-overflow-scrolling: touch;" due to a
57
61
  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
@@ -96,7 +100,9 @@ const styles = StyleSheet.create({
96
100
  border-radius: $modal-content-border-radius;
97
101
  // @include box-shadow($modal-content-box-shadow-xs);
98
102
  // Remove focus outline from opened modal
99
- // outline: 0;
103
+ @include platform(web) {
104
+ outline-style: none; // outline: 0;
105
+ }
100
106
 
101
107
  @include media-breakpoint-up(sm) {
102
108
  // @include box-shadow($modal-content-box-shadow-sm-up);
@@ -106,12 +112,17 @@ const styles = StyleSheet.create({
106
112
  color: $modal-content-color;
107
113
  `,
108
114
  '.modal-backdrop': css`
109
- position: absolute;
115
+ position: absolute; // added for bootstrap-rn
116
+ @include platform(web) {
117
+ position: fixed;
118
+ }
110
119
  top: 0;
111
120
  left: 0;
112
- z-index: $zindex-modal-backdrop;
113
- width: 100%;
114
- height: 100%;
121
+ bottom: 0; // added for bootstrap-rn
122
+ right: 0; // added for bootstrap-rn
123
+ // z-index: $zindex-modal-backdrop;
124
+ // width: 100vw;
125
+ // height: 100vh;
115
126
  background-color: $modal-backdrop-bg;
116
127
  opacity: $modal-backdrop-opacity;
117
128
  `,
@@ -144,7 +155,7 @@ const Modal = React.forwardRef<ViewRef | ScrollViewRef, ModalProps>(
144
155
  backdrop = true,
145
156
  scrollable = false,
146
157
  centered = false,
147
- onToggle: handleToggle,
158
+ onClose: handleClose,
148
159
  style,
149
160
  contentContainerStyle,
150
161
  dialogStyle,
@@ -155,9 +166,11 @@ const Modal = React.forwardRef<ViewRef | ScrollViewRef, ModalProps>(
155
166
  ...elementProps
156
167
  } = props;
157
168
 
158
- const dialogRef = useRef(null);
169
+ const modalRef = useRef<ViewRef>(null);
170
+
171
+ const insets = useSafeAreaInsets();
159
172
 
160
- const modal = useModal(visible, scrollable);
173
+ const modal = useModal(scrollable);
161
174
 
162
175
  const backdropClasses = getStyles(styles, ['.modal-backdrop']);
163
176
  const classes = getStyles(styles, ['.modal']);
@@ -182,22 +195,28 @@ const Modal = React.forwardRef<ViewRef | ScrollViewRef, ModalProps>(
182
195
  justifyContent: 'center' as JustifyContentValue,
183
196
  };
184
197
 
198
+ if (!visible) {
199
+ return null;
200
+ }
201
+
185
202
  return (
186
- <BaseModal
187
- transparent
188
- // Modal is only shown correctly on older Android versions if we set this.
189
- navigationBarTranslucent={
190
- Platform.OS === 'android' && Platform.constants.Version < 35
191
- }
192
- visible={visible}
193
- onRequestClose={handleToggle}
203
+ <Dialog
204
+ id={modal.identifier}
205
+ dialogRef={modalRef}
206
+ backgroundRef={modalRef}
207
+ onClose={handleClose}
208
+ backdrop={backdrop}
209
+ backdropElement={<View style={backdropClasses} />}
194
210
  >
195
- {backdrop && <View style={backdropClasses} />}
196
211
  <FlexView
197
212
  {...elementProps}
198
213
  // @ts-expect-error Type of ref depends on component.
199
- ref={ref}
200
- style={[classes, scrollable && centeredStyle, style]}
214
+ ref={concatRefs(ref, modalRef)}
215
+ role="dialog"
216
+ aria-modal
217
+ aria-labelledby={`${modal.identifier}-title`}
218
+ tabIndex={-1}
219
+ style={[classes, insets, scrollable && centeredStyle, style]}
201
220
  textStyle={textStyle}
202
221
  contentContainerStyle={
203
222
  scrollable
@@ -205,29 +224,22 @@ const Modal = React.forwardRef<ViewRef | ScrollViewRef, ModalProps>(
205
224
  : [{ flexGrow: 1 }, centeredStyle, contentContainerStyle]
206
225
  }
207
226
  >
208
- <BackdropHandler
209
- dialogRef={dialogRef}
210
- onClose={handleToggle}
211
- backdrop={backdrop}
212
- />
213
- <SafeAreaView style={scrollable && { flexShrink: 1 }}>
227
+ <BackdropHandler onClose={handleClose} backdrop={backdrop} />
228
+ <View
229
+ style={[dialogClasses, dialogStyle]}
230
+ textStyle={dialogTextStyle}
231
+ >
214
232
  <View
215
- ref={dialogRef}
216
- style={[dialogClasses, dialogStyle]}
217
- textStyle={dialogTextStyle}
233
+ style={[contentClasses, contentStyle]}
234
+ textStyle={[contentTextClasses, contentTextStyle]}
218
235
  >
219
- <View
220
- style={[contentClasses, contentStyle]}
221
- textStyle={[contentTextClasses, contentTextStyle]}
222
- >
223
- <ModalContext.Provider value={modal}>
224
- <OverlayProvider>{children}</OverlayProvider>
225
- </ModalContext.Provider>
226
- </View>
236
+ <ModalContext.Provider value={modal}>
237
+ {children}
238
+ </ModalContext.Provider>
227
239
  </View>
228
- </SafeAreaView>
240
+ </View>
229
241
  </FlexView>
230
- </BaseModal>
242
+ </Dialog>
231
243
  );
232
244
  },
233
245
  );
@@ -1,11 +1,12 @@
1
- import React from 'react';
2
-
3
- export interface ModalContextProps {
4
- scrollable: boolean;
5
- }
6
-
7
- const ModalContext = React.createContext<ModalContextProps | null>(null);
8
-
9
- ModalContext.displayName = 'ModalContext';
10
-
11
- export default ModalContext;
1
+ import React from 'react';
2
+
3
+ export interface ModalContextProps {
4
+ identifier: string;
5
+ scrollable: boolean;
6
+ }
7
+
8
+ const ModalContext = React.createContext<ModalContextProps | null>(null);
9
+
10
+ ModalContext.displayName = 'ModalContext';
11
+
12
+ export default ModalContext;
@@ -1,31 +1,41 @@
1
- import React from 'react';
2
- import StyleSheet from '../../style/StyleSheet';
3
- import css from '../../style/css';
4
- import Heading from '../Heading';
5
- import { getStyles } from '../../utils';
6
- import type { TextProps, TextRef } from '../Text';
7
-
8
- export interface ModalTitleProps extends TextProps {}
9
-
10
- const styles = StyleSheet.create({
11
- '.modal-title': css`
12
- margin-bottom: 0;
13
- line-height: $font-size-base * $modal-title-line-height;
14
- `,
15
- });
16
-
17
- const ModalTitle = React.forwardRef<TextRef, ModalTitleProps>((props, ref) => {
18
- const { children, style, ...elementProps } = props;
19
-
20
- const classes = getStyles(styles, ['.modal-title']);
21
-
22
- return (
23
- <Heading size={5} {...elementProps} ref={ref} style={[classes, style]}>
24
- {children}
25
- </Heading>
26
- );
27
- });
28
-
29
- ModalTitle.displayName = 'ModalTitle';
30
-
31
- export default ModalTitle;
1
+ import React from 'react';
2
+ import StyleSheet from '../../style/StyleSheet';
3
+ import css from '../../style/css';
4
+ import Heading from '../Heading';
5
+ import { getStyles } from '../../utils';
6
+ import type { TextProps, TextRef } from '../Text';
7
+ import useForcedContext from '../../hooks/useForcedContext';
8
+ import ModalContext from './ModalContext';
9
+
10
+ export interface ModalTitleProps extends TextProps {}
11
+
12
+ const styles = StyleSheet.create({
13
+ '.modal-title': css`
14
+ margin-bottom: 0;
15
+ line-height: $font-size-base * $modal-title-line-height;
16
+ `,
17
+ });
18
+
19
+ const ModalTitle = React.forwardRef<TextRef, ModalTitleProps>((props, ref) => {
20
+ const { children, style, ...elementProps } = props;
21
+
22
+ const { identifier } = useForcedContext(ModalContext);
23
+
24
+ const classes = getStyles(styles, ['.modal-title']);
25
+
26
+ return (
27
+ <Heading
28
+ id={`${identifier}-title`}
29
+ size={5}
30
+ {...elementProps}
31
+ ref={ref}
32
+ style={[classes, style]}
33
+ >
34
+ {children}
35
+ </Heading>
36
+ );
37
+ });
38
+
39
+ ModalTitle.displayName = 'ModalTitle';
40
+
41
+ export default ModalTitle;
@@ -1,25 +1,13 @@
1
- import { useContext, useEffect, useMemo } from 'react';
2
- import Context from '../../Context';
3
-
4
- export default function useModal(visible: boolean, scrollable: boolean) {
5
- const context = useContext(Context);
6
-
7
- useEffect(() => {
8
- if (!visible || !context) {
9
- return undefined;
10
- }
11
-
12
- context.scrollbars.hide();
13
-
14
- return () => {
15
- context.scrollbars.show();
16
- };
17
- }, [visible, context]);
18
-
19
- return useMemo(
20
- () => ({
21
- scrollable,
22
- }),
23
- [scrollable],
24
- );
25
- }
1
+ import { useId, useMemo } from 'react';
2
+
3
+ export default function useModal(scrollable: boolean) {
4
+ const identifier = useId();
5
+
6
+ return useMemo(
7
+ () => ({
8
+ identifier,
9
+ scrollable,
10
+ }),
11
+ [scrollable],
12
+ );
13
+ }
@@ -1,32 +1,31 @@
1
- import { useMemo } from 'react';
2
- import useIdentifier from '../../hooks/useIdentifier';
3
- import useControlledState from '../../hooks/useControlledState';
4
-
5
- type UseTabbableReturnType = {
6
- identifier: string;
7
- activeTarget: string;
8
- setActiveTarget: (target: string) => void;
9
- };
10
-
11
- export default function useTabbable(
12
- defaultActiveTarget: string,
13
- controlledActiveTarget?: string,
14
- onChange?: () => void,
15
- ): UseTabbableReturnType {
16
- const identifier = useIdentifier('tabbable');
17
-
18
- const [activeTarget, setActiveTarget] = useControlledState(
19
- defaultActiveTarget,
20
- controlledActiveTarget,
21
- onChange,
22
- );
23
-
24
- return useMemo(
25
- () => ({
26
- identifier,
27
- activeTarget,
28
- setActiveTarget,
29
- }),
30
- [activeTarget],
31
- );
32
- }
1
+ import { useId, useMemo } from 'react';
2
+ import useControlledState from '../../hooks/useControlledState';
3
+
4
+ type UseTabbableReturnType = {
5
+ identifier: string;
6
+ activeTarget: string;
7
+ setActiveTarget: (target: string) => void;
8
+ };
9
+
10
+ export default function useTabbable(
11
+ defaultActiveTarget: string,
12
+ controlledActiveTarget?: string,
13
+ onChange?: () => void,
14
+ ): UseTabbableReturnType {
15
+ const identifier = useId();
16
+
17
+ const [activeTarget, setActiveTarget] = useControlledState(
18
+ defaultActiveTarget,
19
+ controlledActiveTarget,
20
+ onChange,
21
+ );
22
+
23
+ return useMemo(
24
+ () => ({
25
+ identifier,
26
+ activeTarget,
27
+ setActiveTarget,
28
+ }),
29
+ [activeTarget],
30
+ );
31
+ }