react-native-nitro-modal 0.1.5 → 0.3.0-rc

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 (99) hide show
  1. package/README.md +65 -11
  2. package/android/src/main/java/com/margelo/nitro/nitromodal/BottomSheetPresenter.kt +335 -34
  3. package/android/src/main/java/com/margelo/nitro/nitromodal/HybridNitroModal.kt +63 -22
  4. package/android/src/main/java/com/margelo/nitro/nitromodal/ModalConfig.kt +31 -1
  5. package/android/src/main/java/com/margelo/nitro/nitromodal/ModalContentRoot.kt +48 -5
  6. package/android/src/main/java/com/margelo/nitro/nitromodal/ModalPresenter.kt +63 -4
  7. package/android/src/main/java/com/margelo/nitro/nitromodal/NitroModalHostView.kt +68 -8
  8. package/ios/HybridNitroModal.swift +111 -20
  9. package/ios/ModalConfig.swift +44 -2
  10. package/ios/NitroModalHostView.swift +73 -8
  11. package/ios/SheetView.swift +575 -0
  12. package/ios/SheetViewController.swift +19 -450
  13. package/lib/module/NitroModal.js +39 -7
  14. package/lib/module/NitroModal.js.map +1 -1
  15. package/lib/module/NitroModalView.js +4 -3
  16. package/lib/module/NitroModalView.js.map +1 -1
  17. package/lib/module/NitroModalView.native.js +3 -0
  18. package/lib/module/NitroModalView.native.js.map +1 -1
  19. package/lib/module/NitroModalView.web.js +159 -0
  20. package/lib/module/NitroModalView.web.js.map +1 -0
  21. package/lib/module/index.js.map +1 -1
  22. package/lib/module/web/AnimatedValue.js +126 -0
  23. package/lib/module/web/AnimatedValue.js.map +1 -0
  24. package/lib/module/web/ModalConfig.js +30 -0
  25. package/lib/module/web/ModalConfig.js.map +1 -0
  26. package/lib/module/web/ModalController.js +306 -0
  27. package/lib/module/web/ModalController.js.map +1 -0
  28. package/lib/module/web/ModalPresenter.js +280 -0
  29. package/lib/module/web/ModalPresenter.js.map +1 -0
  30. package/lib/module/web/PopupPresenter.js +117 -0
  31. package/lib/module/web/PopupPresenter.js.map +1 -0
  32. package/lib/module/web/SheetPresenter.js +494 -0
  33. package/lib/module/web/SheetPresenter.js.map +1 -0
  34. package/lib/module/web/dom.js +138 -0
  35. package/lib/module/web/dom.js.map +1 -0
  36. package/lib/typescript/src/NitroModal.d.ts +35 -4
  37. package/lib/typescript/src/NitroModal.d.ts.map +1 -1
  38. package/lib/typescript/src/NitroModal.nitro.d.ts +29 -2
  39. package/lib/typescript/src/NitroModal.nitro.d.ts.map +1 -1
  40. package/lib/typescript/src/NitroModalView.d.ts +2 -1
  41. package/lib/typescript/src/NitroModalView.d.ts.map +1 -1
  42. package/lib/typescript/src/NitroModalView.native.d.ts +1 -0
  43. package/lib/typescript/src/NitroModalView.native.d.ts.map +1 -1
  44. package/lib/typescript/src/NitroModalView.web.d.ts +6 -0
  45. package/lib/typescript/src/NitroModalView.web.d.ts.map +1 -0
  46. package/lib/typescript/src/index.d.ts +2 -2
  47. package/lib/typescript/src/index.d.ts.map +1 -1
  48. package/lib/typescript/src/web/AnimatedValue.d.ts +49 -0
  49. package/lib/typescript/src/web/AnimatedValue.d.ts.map +1 -0
  50. package/lib/typescript/src/web/ModalConfig.d.ts +30 -0
  51. package/lib/typescript/src/web/ModalConfig.d.ts.map +1 -0
  52. package/lib/typescript/src/web/ModalController.d.ts +70 -0
  53. package/lib/typescript/src/web/ModalController.d.ts.map +1 -0
  54. package/lib/typescript/src/web/ModalPresenter.d.ts +107 -0
  55. package/lib/typescript/src/web/ModalPresenter.d.ts.map +1 -0
  56. package/lib/typescript/src/web/PopupPresenter.d.ts +20 -0
  57. package/lib/typescript/src/web/PopupPresenter.d.ts.map +1 -0
  58. package/lib/typescript/src/web/SheetPresenter.d.ts +65 -0
  59. package/lib/typescript/src/web/SheetPresenter.d.ts.map +1 -0
  60. package/lib/typescript/src/web/dom.d.ts +42 -0
  61. package/lib/typescript/src/web/dom.d.ts.map +1 -0
  62. package/nitrogen/generated/android/c++/JHybridNitroModalSpec.cpp +60 -6
  63. package/nitrogen/generated/android/c++/JHybridNitroModalSpec.hpp +10 -2
  64. package/nitrogen/generated/android/c++/JNamedSheetDetent.hpp +64 -0
  65. package/nitrogen/generated/android/c++/JSheetDetent.cpp +26 -0
  66. package/nitrogen/generated/android/c++/JSheetDetent.hpp +42 -37
  67. package/nitrogen/generated/android/c++/views/JHybridNitroModalStateUpdater.cpp +20 -0
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/HybridNitroModalSpec.kt +40 -0
  69. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/NamedSheetDetent.kt +25 -0
  70. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromodal/SheetDetent.kt +47 -10
  71. package/nitrogen/generated/android/nitromodal+autolinking.cmake +1 -0
  72. package/nitrogen/generated/ios/NitroModal-Swift-Cxx-Bridge.hpp +53 -8
  73. package/nitrogen/generated/ios/NitroModal-Swift-Cxx-Umbrella.hpp +4 -3
  74. package/nitrogen/generated/ios/c++/HybridNitroModalSpecSwift.hpp +32 -5
  75. package/nitrogen/generated/ios/c++/views/HybridNitroModalComponent.mm +24 -0
  76. package/nitrogen/generated/ios/swift/HybridNitroModalSpec.swift +4 -0
  77. package/nitrogen/generated/ios/swift/HybridNitroModalSpec_cxx.swift +110 -5
  78. package/nitrogen/generated/ios/swift/NamedSheetDetent.swift +48 -0
  79. package/nitrogen/generated/ios/swift/SheetDetent.swift +15 -33
  80. package/nitrogen/generated/shared/c++/HybridNitroModalSpec.cpp +8 -0
  81. package/nitrogen/generated/shared/c++/HybridNitroModalSpec.hpp +14 -5
  82. package/nitrogen/generated/shared/c++/{SheetDetent.hpp → NamedSheetDetent.hpp} +17 -17
  83. package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.cpp +9 -1
  84. package/nitrogen/generated/shared/c++/views/HybridNitroModalComponent.hpp +15 -2
  85. package/nitrogen/generated/shared/json/NitroModalConfig.json +4 -0
  86. package/package.json +3 -2
  87. package/src/NitroModal.nitro.ts +30 -2
  88. package/src/NitroModal.tsx +71 -8
  89. package/src/NitroModalView.native.tsx +4 -0
  90. package/src/NitroModalView.tsx +9 -4
  91. package/src/NitroModalView.web.tsx +180 -0
  92. package/src/index.tsx +2 -0
  93. package/src/web/AnimatedValue.ts +193 -0
  94. package/src/web/ModalConfig.ts +67 -0
  95. package/src/web/ModalController.ts +338 -0
  96. package/src/web/ModalPresenter.ts +333 -0
  97. package/src/web/PopupPresenter.ts +129 -0
  98. package/src/web/SheetPresenter.ts +647 -0
  99. package/src/web/dom.ts +171 -0
@@ -0,0 +1,129 @@
1
+ /// <reference lib="dom" />
2
+
3
+ import { AnimatedValue, INSTANT, type Motion } from './AnimatedValue';
4
+ import { prefersReducedMotion, type Insets, type Size } from './dom';
5
+ import { ModalPresenter } from './ModalPresenter';
6
+
7
+ const MARGIN = 16;
8
+ const DEFAULT_CORNER_RADIUS = 16;
9
+ const ENTER_SCALE = 0.9;
10
+
11
+ const ENTER: Motion = { type: 'spring', response: 0.3, dampingRatio: 0.82 };
12
+ const EXIT: Motion = { type: 'timing', duration: 200, easing: (t) => t * t };
13
+
14
+ interface Rect extends Size {
15
+ x: number;
16
+ y: number;
17
+ }
18
+
19
+ /** Area a card may occupy, clear of the safe area and the part of the keyboard above it. */
20
+ function availableRect(
21
+ viewport: Size,
22
+ insets: Insets,
23
+ keyboardHeight: number
24
+ ): Rect {
25
+ const covered = Math.max(0, keyboardHeight - insets.bottom);
26
+ return {
27
+ x: insets.left + MARGIN,
28
+ y: insets.top + MARGIN,
29
+ width: Math.max(
30
+ 0,
31
+ viewport.width - insets.left - insets.right - 2 * MARGIN
32
+ ),
33
+ height: Math.max(
34
+ 0,
35
+ viewport.height - insets.top - insets.bottom - 2 * MARGIN - covered
36
+ ),
37
+ };
38
+ }
39
+
40
+ /** Best guess of the content area before the popup is on screen. */
41
+ export function popupContentArea(viewport: Size, insets: Insets): Size {
42
+ const { width, height } = availableRect(viewport, insets, 0);
43
+ return { width, height };
44
+ }
45
+
46
+ /** `popup` mode: a centered card over the backdrop with a fade/scale transition. */
47
+ export class PopupPresenter extends ModalPresenter {
48
+ /** 0 hidden, 1 presented. */
49
+ private readonly progress = new AnimatedValue(0, 0.001, (value) =>
50
+ this.render(value)
51
+ );
52
+
53
+ protected didShow() {
54
+ this.layout();
55
+ this.progress.set(0);
56
+ }
57
+
58
+ protected animateIn() {
59
+ this.progress.animateTo(1, this.isAnimated ? ENTER : INSTANT, {
60
+ onEnd: () => this.notifyPresented(),
61
+ });
62
+ }
63
+
64
+ protected animateOut(onEnd: () => void) {
65
+ this.progress.animateTo(0, this.isAnimated ? EXIT : INSTANT, { onEnd });
66
+ }
67
+
68
+ protected configDidChange() {
69
+ this.layout();
70
+ this.render(this.progress.value);
71
+ }
72
+
73
+ protected viewportDidChange() {
74
+ this.layout();
75
+ }
76
+
77
+ protected contentSizeDidChange() {
78
+ this.layout();
79
+ }
80
+
81
+ protected stopAnimations() {
82
+ this.progress.stop();
83
+ }
84
+
85
+ private get isAnimated(): boolean {
86
+ return this.config.popupAnimation !== 'none' && !prefersReducedMotion();
87
+ }
88
+
89
+ private layout() {
90
+ const { surface, content, grabber } = this.elements!;
91
+ const behavior = this.config.keyboardBehavior;
92
+ const available = availableRect(
93
+ this.viewport,
94
+ this.insets,
95
+ behavior === 'none' ? 0 : this.keyboardHeight
96
+ );
97
+ const width = Math.min(this.contentSize.width, available.width);
98
+ const height = Math.min(this.contentSize.height, available.height);
99
+ Object.assign(surface.style, {
100
+ left: `${available.x + (available.width - width) / 2}px`,
101
+ top: `${available.y + (available.height - height) / 2}px`,
102
+ width: `${width}px`,
103
+ height: `${height}px`,
104
+ borderRadius: `${this.config.cornerRadius ?? DEFAULT_CORNER_RADIUS}px`,
105
+ });
106
+ grabber.style.display = 'none';
107
+
108
+ // The content host also bounds the content's own (shrink-to-fit) width.
109
+ const area =
110
+ behavior === 'resize'
111
+ ? available
112
+ : availableRect(this.viewport, this.insets, 0);
113
+ content.style.width = `${area.width}px`;
114
+ content.style.height = `${area.height}px`;
115
+ this.reportContentArea(area.width, area.height);
116
+ }
117
+
118
+ private render(progress: number) {
119
+ if (!this.elements) return;
120
+ const { surface, backdrop } = this.elements;
121
+ const visible = Math.min(Math.max(progress, 0), 1);
122
+ const animation = this.config.popupAnimation;
123
+ backdrop.style.opacity = String(visible);
124
+ surface.style.opacity = animation === 'none' ? '1' : String(visible);
125
+ const scale =
126
+ animation === 'scale' ? ENTER_SCALE + (1 - ENTER_SCALE) * progress : 1;
127
+ surface.style.transform = `scale(${scale})`;
128
+ }
129
+ }