react-native-morph-card 0.1.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.
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/android/build.gradle +59 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardModule.kt +120 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardPackage.kt +42 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardSourceManager.kt +40 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardSourceView.kt +755 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardTargetManager.kt +48 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardTargetView.kt +159 -0
- package/android/src/main/java/com/melivalesca/morphcard/MorphCardViewRegistry.kt +24 -0
- package/android/src/main/jni/CMakeLists.txt +62 -0
- package/common/cpp/react/renderer/components/morphcard/RNCMorphCardState.h +30 -0
- package/ios/Fabric/RNCMorphCardSourceComponentView.h +25 -0
- package/ios/Fabric/RNCMorphCardSourceComponentView.mm +582 -0
- package/ios/Fabric/RNCMorphCardTargetComponentView.h +20 -0
- package/ios/Fabric/RNCMorphCardTargetComponentView.mm +99 -0
- package/ios/RNCMorphCardModule.h +14 -0
- package/ios/RNCMorphCardModule.mm +126 -0
- package/ios/RNCMorphCardSource.h +23 -0
- package/ios/RNCMorphCardSource.m +144 -0
- package/ios/RNCMorphCardSourceManager.h +5 -0
- package/ios/RNCMorphCardSourceManager.m +17 -0
- package/ios/RNCMorphCardTarget.h +19 -0
- package/ios/RNCMorphCardTarget.m +27 -0
- package/ios/RNCMorphCardTargetManager.h +5 -0
- package/ios/RNCMorphCardTargetManager.m +16 -0
- package/ios/RNCMorphCardViewRegistry.h +35 -0
- package/ios/RNCMorphCardViewRegistry.m +40 -0
- package/lib/commonjs/MorphCard.types.js +6 -0
- package/lib/commonjs/MorphCard.types.js.map +1 -0
- package/lib/commonjs/MorphCardSource.js +95 -0
- package/lib/commonjs/MorphCardSource.js.map +1 -0
- package/lib/commonjs/MorphCardTarget.js +83 -0
- package/lib/commonjs/MorphCardTarget.js.map +1 -0
- package/lib/commonjs/index.js +45 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/NativeMorphCardModule.js +9 -0
- package/lib/commonjs/specs/NativeMorphCardModule.js.map +1 -0
- package/lib/commonjs/specs/NativeMorphCardSource.js +10 -0
- package/lib/commonjs/specs/NativeMorphCardSource.js.map +1 -0
- package/lib/commonjs/specs/NativeMorphCardTarget.js +10 -0
- package/lib/commonjs/specs/NativeMorphCardTarget.js.map +1 -0
- package/lib/commonjs/useMorphTarget.js +28 -0
- package/lib/commonjs/useMorphTarget.js.map +1 -0
- package/lib/module/MorphCard.types.js +4 -0
- package/lib/module/MorphCard.types.js.map +1 -0
- package/lib/module/MorphCardSource.js +85 -0
- package/lib/module/MorphCardSource.js.map +1 -0
- package/lib/module/MorphCardTarget.js +76 -0
- package/lib/module/MorphCardTarget.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/specs/NativeMorphCardModule.js +5 -0
- package/lib/module/specs/NativeMorphCardModule.js.map +1 -0
- package/lib/module/specs/NativeMorphCardSource.js +5 -0
- package/lib/module/specs/NativeMorphCardSource.js.map +1 -0
- package/lib/module/specs/NativeMorphCardTarget.js +5 -0
- package/lib/module/specs/NativeMorphCardTarget.js.map +1 -0
- package/lib/module/useMorphTarget.js +22 -0
- package/lib/module/useMorphTarget.js.map +1 -0
- package/lib/typescript/src/MorphCard.types.d.ts +29 -0
- package/lib/typescript/src/MorphCard.types.d.ts.map +1 -0
- package/lib/typescript/src/MorphCardSource.d.ts +35 -0
- package/lib/typescript/src/MorphCardSource.d.ts.map +1 -0
- package/lib/typescript/src/MorphCardTarget.d.ts +20 -0
- package/lib/typescript/src/MorphCardTarget.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeMorphCardModule.d.ts +14 -0
- package/lib/typescript/src/specs/NativeMorphCardModule.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeMorphCardSource.d.ts +13 -0
- package/lib/typescript/src/specs/NativeMorphCardSource.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeMorphCardTarget.d.ts +25 -0
- package/lib/typescript/src/specs/NativeMorphCardTarget.d.ts.map +1 -0
- package/lib/typescript/src/useMorphTarget.d.ts +16 -0
- package/lib/typescript/src/useMorphTarget.d.ts.map +1 -0
- package/package.json +101 -0
- package/react-native-morph-card.podspec +41 -0
- package/react-native.config.js +13 -0
- package/src/MorphCard.types.ts +29 -0
- package/src/MorphCardSource.tsx +105 -0
- package/src/MorphCardTarget.tsx +127 -0
- package/src/index.tsx +10 -0
- package/src/specs/NativeMorphCardModule.ts +21 -0
- package/src/specs/NativeMorphCardSource.ts +20 -0
- package/src/specs/NativeMorphCardTarget.ts +38 -0
- package/src/useMorphTarget.ts +21 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MeliValesca
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# react-native-morph-card
|
|
2
|
+
|
|
3
|
+
Native card-to-modal morph transition for React Native. The iOS App Store "card of the day" expand animation, as a library.
|
|
4
|
+
|
|
5
|
+
- Native animations on both platforms (UIKit `UIViewPropertyAnimator` / Android Transition framework)
|
|
6
|
+
- No JS-driven animation, no webview, no experimental flags
|
|
7
|
+
- Works with any navigation setup
|
|
8
|
+
- Supports old and new React Native architecture (Paper + Fabric)
|
|
9
|
+
|
|
10
|
+
> **Status:** Early development — the skeleton is in place, native morph animation is not yet implemented.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
yarn add react-native-morph-card
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### iOS
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
cd ios && pod install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Android
|
|
25
|
+
|
|
26
|
+
No additional steps required.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { MorphCardSource } from 'react-native-morph-card';
|
|
32
|
+
|
|
33
|
+
function App() {
|
|
34
|
+
return (
|
|
35
|
+
<MorphCardSource style={styles.card}>
|
|
36
|
+
<Pressable onPress={() => console.log('Morph!')}>
|
|
37
|
+
<Text>Tap me</Text>
|
|
38
|
+
</Pressable>
|
|
39
|
+
</MorphCardSource>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Running the example app
|
|
45
|
+
|
|
46
|
+
The example app lives in the `example/` directory and uses [`react-native-test-app`](https://github.com/nicklasmoeller/react-native-test-app) to manage the native projects.
|
|
47
|
+
|
|
48
|
+
### Prerequisites
|
|
49
|
+
|
|
50
|
+
| Tool | Version |
|
|
51
|
+
|------|---------|
|
|
52
|
+
| Node.js | >= 18 |
|
|
53
|
+
| Yarn | 1.x |
|
|
54
|
+
| Ruby | >= 2.7 (for CocoaPods) |
|
|
55
|
+
| CocoaPods | ~> 1.15 |
|
|
56
|
+
| Xcode | >= 15 (iOS) |
|
|
57
|
+
| Android Studio | latest (Android) |
|
|
58
|
+
| JDK | 17 |
|
|
59
|
+
|
|
60
|
+
Make sure you have an iOS Simulator or Android Emulator available.
|
|
61
|
+
|
|
62
|
+
### 1. Install dependencies
|
|
63
|
+
|
|
64
|
+
From the repository root:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
# Install root (library) dependencies
|
|
68
|
+
yarn install
|
|
69
|
+
|
|
70
|
+
# Install example app dependencies
|
|
71
|
+
cd example
|
|
72
|
+
yarn install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Run on iOS
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
# Install CocoaPods (from example/ios)
|
|
79
|
+
cd ios
|
|
80
|
+
bundle install
|
|
81
|
+
bundle exec pod install
|
|
82
|
+
cd ..
|
|
83
|
+
|
|
84
|
+
# Start Metro and build
|
|
85
|
+
yarn ios
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This opens the app on the iOS Simulator. Metro starts automatically.
|
|
89
|
+
|
|
90
|
+
If you prefer to build from Xcode, open `example/ios/MorphCardExample.xcworkspace` and press Run.
|
|
91
|
+
|
|
92
|
+
### 3. Run on Android
|
|
93
|
+
|
|
94
|
+
Make sure an Android emulator is running (or a device is connected), then from `example/`:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
yarn android
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Gradle will download dependencies on first run — this can take a few minutes.
|
|
101
|
+
|
|
102
|
+
### 4. Start Metro separately (optional)
|
|
103
|
+
|
|
104
|
+
If you want to start the Metro bundler on its own (e.g. to see logs in a dedicated terminal):
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
cd example
|
|
108
|
+
yarn start
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then run `yarn ios` or `yarn android` in another terminal.
|
|
112
|
+
|
|
113
|
+
### Building JS bundles manually
|
|
114
|
+
|
|
115
|
+
Only needed if you want to test pre-built bundles (not required for normal development):
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
cd example
|
|
119
|
+
yarn build:ios
|
|
120
|
+
yarn build:android
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Troubleshooting
|
|
124
|
+
|
|
125
|
+
| Problem | Fix |
|
|
126
|
+
|---------|-----|
|
|
127
|
+
| `pod install` fails | Run `bundle install` first, then `bundle exec pod install` |
|
|
128
|
+
| Android build fails on first run | Make sure `ANDROID_HOME` is set and an emulator/device is available |
|
|
129
|
+
| Metro can't find `react-native-morph-card` | Run `yarn install` at the repo root first |
|
|
130
|
+
| Duplicate module errors | Delete `node_modules` in both root and `example/`, then reinstall |
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.safeExtGet = { prop, fallback ->
|
|
3
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
apply plugin: 'com.android.library'
|
|
8
|
+
apply plugin: 'kotlin-android'
|
|
9
|
+
|
|
10
|
+
def newArchEnabled = project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
11
|
+
|
|
12
|
+
android {
|
|
13
|
+
namespace "com.melivalesca.morphcard"
|
|
14
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 34)
|
|
15
|
+
|
|
16
|
+
defaultConfig {
|
|
17
|
+
minSdkVersion safeExtGet('minSdkVersion', 21)
|
|
18
|
+
targetSdkVersion safeExtGet('targetSdkVersion', 34)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
sourceSets.main {
|
|
22
|
+
java {
|
|
23
|
+
if (newArchEnabled) {
|
|
24
|
+
srcDirs += 'src/fabric/java'
|
|
25
|
+
} else {
|
|
26
|
+
srcDirs += 'src/paper/java'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
lintOptions {
|
|
32
|
+
abortOnError false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
repositories {
|
|
37
|
+
mavenCentral()
|
|
38
|
+
google()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
dependencies {
|
|
42
|
+
implementation "com.facebook.react:react-native:+"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (newArchEnabled) {
|
|
46
|
+
apply plugin: "com.facebook.react"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
apply plugin: 'com.diffplug.spotless'
|
|
51
|
+
spotless {
|
|
52
|
+
kotlin {
|
|
53
|
+
target '**/*.kt'
|
|
54
|
+
googleJavaFormat()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch (Exception ignored) {
|
|
58
|
+
// Spotless plugin not available in consumer projects
|
|
59
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
package com.melivalesca.morphcard
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.view.View
|
|
6
|
+
import com.facebook.react.bridge.Promise
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
9
|
+
|
|
10
|
+
class MorphCardModule(reactContext: ReactApplicationContext) :
|
|
11
|
+
NativeMorphCardModuleSpec(reactContext) {
|
|
12
|
+
|
|
13
|
+
private val mainHandler = Handler(Looper.getMainLooper())
|
|
14
|
+
|
|
15
|
+
override fun prepareExpand(sourceTag: Double) {
|
|
16
|
+
mainHandler.post {
|
|
17
|
+
val sourceView = MorphCardViewRegistry.getView(sourceTag.toInt())
|
|
18
|
+
if (sourceView is MorphCardSourceView) {
|
|
19
|
+
sourceView.prepareExpand(null)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun setTargetConfig(
|
|
25
|
+
sourceTag: Double,
|
|
26
|
+
targetWidth: Double,
|
|
27
|
+
targetHeight: Double,
|
|
28
|
+
targetBorderRadius: Double,
|
|
29
|
+
contentOffsetY: Double,
|
|
30
|
+
contentCentered: Boolean
|
|
31
|
+
) {
|
|
32
|
+
mainHandler.post {
|
|
33
|
+
val sourceView = MorphCardViewRegistry.getView(sourceTag.toInt())
|
|
34
|
+
if (sourceView is MorphCardSourceView) {
|
|
35
|
+
sourceView.pendingTargetWidth = targetWidth.toFloat()
|
|
36
|
+
sourceView.pendingTargetHeight = targetHeight.toFloat()
|
|
37
|
+
sourceView.pendingTargetBorderRadius = targetBorderRadius.toFloat()
|
|
38
|
+
sourceView.pendingContentOffsetY = contentOffsetY.toFloat()
|
|
39
|
+
sourceView.pendingContentCentered = contentCentered
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun expand(sourceTag: Double, targetTag: Double, promise: Promise) {
|
|
45
|
+
mainHandler.post {
|
|
46
|
+
val sourceView = MorphCardViewRegistry.getView(sourceTag.toInt())
|
|
47
|
+
val targetView = MorphCardViewRegistry.getView(targetTag.toInt())
|
|
48
|
+
|
|
49
|
+
if (sourceView is MorphCardSourceView) {
|
|
50
|
+
// If prepareExpand wasn't called yet (e.g. via morphExpand API),
|
|
51
|
+
// create the overlay now.
|
|
52
|
+
if (!sourceView.hasOverlay) {
|
|
53
|
+
sourceView.prepareExpand(targetView)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Wait until the target view is registered AND its
|
|
57
|
+
// screen container is ready, then animate.
|
|
58
|
+
animateWhenReady(sourceView, targetTag.toInt(), promise, 0)
|
|
59
|
+
} else {
|
|
60
|
+
promise.resolve(false)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private fun animateWhenReady(
|
|
66
|
+
sourceView: MorphCardSourceView,
|
|
67
|
+
targetTag: Int,
|
|
68
|
+
promise: Promise,
|
|
69
|
+
attempt: Int
|
|
70
|
+
) {
|
|
71
|
+
val targetView = MorphCardViewRegistry.getView(targetTag)
|
|
72
|
+
|
|
73
|
+
// Wait if: target not registered yet, OR screen container not found
|
|
74
|
+
val needsWait = targetView == null || !sourceView.isTargetScreenReady(targetView)
|
|
75
|
+
if (needsWait && attempt < 20) {
|
|
76
|
+
mainHandler.postDelayed({
|
|
77
|
+
animateWhenReady(sourceView, targetTag, promise, attempt + 1)
|
|
78
|
+
}, 50)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Re-hide target screen if we found the target late
|
|
83
|
+
if (targetView != null) {
|
|
84
|
+
sourceView.hideTargetScreen(targetView)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
sourceView.animateExpand(targetView, promise)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override fun collapse(sourceTag: Double, promise: Promise) {
|
|
91
|
+
mainHandler.post {
|
|
92
|
+
val sourceView = MorphCardViewRegistry.getView(sourceTag.toInt())
|
|
93
|
+
if (sourceView is MorphCardSourceView) {
|
|
94
|
+
sourceView.collapseWithResolve(promise)
|
|
95
|
+
} else {
|
|
96
|
+
promise.resolve(false)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
override fun getSourceSize(sourceTag: Double, promise: Promise) {
|
|
102
|
+
mainHandler.post {
|
|
103
|
+
val sourceView = MorphCardViewRegistry.getView(sourceTag.toInt())
|
|
104
|
+
val map = WritableNativeMap()
|
|
105
|
+
if (sourceView != null) {
|
|
106
|
+
val density = sourceView.resources.displayMetrics.density
|
|
107
|
+
map.putDouble("width", (sourceView.width / density).toDouble())
|
|
108
|
+
map.putDouble("height", (sourceView.height / density).toDouble())
|
|
109
|
+
} else {
|
|
110
|
+
map.putDouble("width", 0.0)
|
|
111
|
+
map.putDouble("height", 0.0)
|
|
112
|
+
}
|
|
113
|
+
promise.resolve(map)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
companion object {
|
|
118
|
+
const val NAME = "RNCMorphCardModule"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package com.melivalesca.morphcard
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager
|
|
9
|
+
|
|
10
|
+
class MorphCardPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return when (name) {
|
|
13
|
+
MorphCardModule.NAME -> MorphCardModule(reactContext)
|
|
14
|
+
else -> null
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
19
|
+
return ReactModuleInfoProvider {
|
|
20
|
+
mapOf(
|
|
21
|
+
MorphCardModule.NAME to
|
|
22
|
+
ReactModuleInfo(
|
|
23
|
+
MorphCardModule.NAME,
|
|
24
|
+
MorphCardModule.NAME,
|
|
25
|
+
false, // canOverrideExistingModule
|
|
26
|
+
false, // needsEagerInit
|
|
27
|
+
false, // isCxxModule
|
|
28
|
+
true, // isTurboModule
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
override fun createViewManagers(
|
|
35
|
+
reactContext: ReactApplicationContext
|
|
36
|
+
): List<ViewManager<*, *>> {
|
|
37
|
+
return listOf(
|
|
38
|
+
MorphCardSourceManager(),
|
|
39
|
+
MorphCardTargetManager(),
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
package com.melivalesca.morphcard
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
6
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
7
|
+
import com.facebook.react.viewmanagers.RNCMorphCardSourceManagerDelegate
|
|
8
|
+
import com.facebook.react.viewmanagers.RNCMorphCardSourceManagerInterface
|
|
9
|
+
|
|
10
|
+
@ReactModule(name = MorphCardSourceManager.REACT_CLASS)
|
|
11
|
+
class MorphCardSourceManager :
|
|
12
|
+
ViewGroupManager<MorphCardSourceView>(),
|
|
13
|
+
RNCMorphCardSourceManagerInterface<MorphCardSourceView> {
|
|
14
|
+
|
|
15
|
+
private val delegate = RNCMorphCardSourceManagerDelegate(this)
|
|
16
|
+
|
|
17
|
+
override fun getDelegate(): ViewManagerDelegate<MorphCardSourceView> = delegate
|
|
18
|
+
|
|
19
|
+
override fun getName(): String = REACT_CLASS
|
|
20
|
+
|
|
21
|
+
override fun createViewInstance(reactContext: ThemedReactContext): MorphCardSourceView {
|
|
22
|
+
return MorphCardSourceView(reactContext)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun setDuration(view: MorphCardSourceView, value: Double) {
|
|
26
|
+
view.duration = value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun setScaleMode(view: MorphCardSourceView, value: String?) {
|
|
30
|
+
view.scaleMode = value ?: "aspectFill"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun setCardBorderRadius(view: MorphCardSourceView, value: Double) {
|
|
34
|
+
view.borderRadiusDp = value.toFloat()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
companion object {
|
|
38
|
+
const val REACT_CLASS = "RNCMorphCardSource"
|
|
39
|
+
}
|
|
40
|
+
}
|