@momo-kits/native-kits 0.151.2-test.11 → 0.151.2-test.12

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.
@@ -0,0 +1,54 @@
1
+ Pod::Spec.new do |spec|
2
+ spec.name = 'MoMoComposeKits'
3
+ spec.version = '0.0.1'
4
+ spec.homepage = 'MoMoComposeKits'
5
+ spec.source = { :http=> ''}
6
+ spec.authors = 'M_SERVICE'
7
+ spec.license = ''
8
+ spec.summary = 'MoMoComposeKits'
9
+ spec.vendored_frameworks = 'build/cocoapods/framework/compose.framework'
10
+ spec.libraries = 'c++'
11
+ spec.ios.deployment_target = '13.0'
12
+ spec.dependency 'lottie-ios', '4.4.3'
13
+
14
+ if !Dir.exist?('build/cocoapods/framework/compose.framework') || Dir.empty?('build/cocoapods/framework/compose.framework')
15
+ raise "
16
+
17
+ Kotlin framework 'compose' doesn't exist yet, so a proper Xcode project can't be generated.
18
+ 'pod install' should be executed after running ':generateDummyFramework' Gradle task:
19
+
20
+ ./gradlew :compose:generateDummyFramework
21
+
22
+ Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)"
23
+ end
24
+
25
+ spec.xcconfig = {
26
+ 'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO',
27
+ }
28
+
29
+ spec.pod_target_xcconfig = {
30
+ 'KOTLIN_PROJECT_PATH' => ':compose',
31
+ 'PRODUCT_MODULE_NAME' => 'compose',
32
+ }
33
+
34
+ spec.script_phases = [
35
+ {
36
+ :name => 'Build MoMoComposeKits',
37
+ :execution_position => :before_compile,
38
+ :shell_path => '/bin/sh',
39
+ :script => <<-SCRIPT
40
+ if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then
41
+ echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\""
42
+ exit 0
43
+ fi
44
+ set -ev
45
+ REPO_ROOT="$PODS_TARGET_SRCROOT"
46
+ "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \
47
+ -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \
48
+ -Pkotlin.native.cocoapods.archs="$ARCHS" \
49
+ -Pkotlin.native.cocoapods.configuration="$CONFIGURATION"
50
+ SCRIPT
51
+ }
52
+ ]
53
+ spec.resources = ['build/compose/cocoapods/compose-resources']
54
+ end
@@ -3,13 +3,23 @@ plugins {
3
3
  alias(libs.plugins.jetbrains.kotlin.multiplatform)
4
4
  alias(libs.plugins.compose)
5
5
  alias(libs.plugins.kotlin.compose.compiler)
6
+ id(libs.plugins.jetbrains.kotlin.cocoapods.get().pluginId)
6
7
  kotlin("plugin.serialization")
7
8
  id("maven-publish")
8
9
  }
10
+ fun getVersionFromPackageJson(): String {
11
+ val packageJsonFile = file("../package.json")
12
+ val packageJsonText = packageJsonFile.readText()
13
+ val versionRegex = "\"version\"\\s*:\\s*\"([^\"]*)\"".toRegex()
14
+ val matchResult = versionRegex.find(packageJsonText)
15
+ return matchResult?.groupValues?.get(1) ?: throw IllegalStateException("Version not found in package.json")
16
+ }
9
17
 
18
+ val libName = "MoMoComposeKits"
10
19
  val libGroup = "vn.momo.kits"
11
20
  val libVersion = "0.0.1"
12
21
 
22
+ version = getVersionFromPackageJson()
13
23
  kotlin {
14
24
  androidTarget {
15
25
  publishLibraryVariants("release")
@@ -26,11 +36,30 @@ kotlin {
26
36
 
27
37
  iosTargets.forEach { iosTarget ->
28
38
  iosTarget.binaries.framework {
29
- baseName = "lib"
39
+ baseName = libName
30
40
  isStatic = true
31
41
  }
32
42
  }
33
43
 
44
+ cocoapods {
45
+ name = libName
46
+ summary = libName
47
+ homepage = libName
48
+ authors = "M_SERVICE"
49
+ ios.deploymentTarget = "13.0"
50
+
51
+ framework {
52
+ isStatic = true
53
+ }
54
+
55
+ pod("lottie-ios") {
56
+ moduleName = "Lottie"
57
+ version = "4.4.3"
58
+ extraOpts += listOf("-compiler-option", "-fmodules")
59
+ }
60
+ }
61
+
62
+
34
63
  sourceSets {
35
64
  val commonMain by getting {
36
65
  dependencies {
@@ -47,8 +76,6 @@ kotlin {
47
76
  implementation(libs.coil.multiplatform.network.ktor)
48
77
  implementation(libs.jetbrains.serialization.json)
49
78
  implementation(libs.kotlinx.datetime)
50
- implementation(libs.compottie)
51
- implementation(libs.compottie.res)
52
79
  api(project(":NativeMaxApi"))
53
80
  }
54
81
  }
@@ -57,6 +84,7 @@ kotlin {
57
84
  implementation(libs.ktor.client.okhttp)
58
85
  implementation(libs.jetbrains.coroutines.android)
59
86
  api("androidx.activity:activity-compose:1.8.2")
87
+ implementation(libs.airbnb.lottie)
60
88
  }
61
89
  }
62
90
  if (isDebug) {
@@ -4,15 +4,20 @@ import android.annotation.SuppressLint
4
4
  import android.content.res.Resources
5
5
  import android.graphics.BlurMaskFilter
6
6
  import android.os.Build
7
+ import androidx.compose.ui.graphics.Color
7
8
  import androidx.compose.runtime.Composable
9
+ import androidx.compose.runtime.getValue
10
+ import androidx.compose.ui.Modifier
8
11
  import androidx.compose.ui.graphics.NativePaint
9
12
  import androidx.compose.ui.platform.LocalConfiguration
10
- import androidx.compose.ui.platform.LocalView
11
13
  import androidx.compose.ui.unit.Dp
12
14
  import androidx.compose.ui.unit.dp
13
- import androidx.compose.ui.window.DialogWindowProvider
15
+ import com.airbnb.lottie.compose.LottieCompositionSpec
16
+ import com.airbnb.lottie.compose.LottieConstants
17
+ import com.airbnb.lottie.compose.rememberLottieComposition
14
18
  import vn.momo.kits.const.AppNavigationBar
15
19
  import vn.momo.kits.const.AppStatusBar
20
+ import vn.momo.kits.utils.readJson
16
21
  import androidx.activity.compose.BackHandler as AndroidBackHandler
17
22
 
18
23
  actual fun getPlatformName(): String = "Android"
@@ -50,4 +55,19 @@ actual fun getScreenHeight(): Dp {
50
55
  return getScreenDimensions().height.dp + if (getAndroidBuildVersion() >= 35) 0.dp else AppStatusBar.current + AppNavigationBar.current
51
56
  }
52
57
 
53
- actual fun getAndroidBuildVersion(): Int = Build.VERSION.SDK_INT
58
+ actual fun getAndroidBuildVersion(): Int = Build.VERSION.SDK_INT
59
+
60
+ @Composable
61
+ actual fun LottieAnimation(
62
+ path: String,
63
+ tintColor: Color?,
64
+ modifier: Modifier
65
+ ) {
66
+ val composition by rememberLottieComposition(LottieCompositionSpec.JsonString(readJson(path)))
67
+
68
+ com.airbnb.lottie.compose.LottieAnimation(
69
+ composition = composition,
70
+ modifier = modifier,
71
+ iterations = LottieConstants.IterateForever,
72
+ )
73
+ }
@@ -28,6 +28,7 @@ import vn.momo.kits.const.Radius
28
28
  import vn.momo.kits.const.Spacing
29
29
  import vn.momo.kits.const.Typography
30
30
  import vn.momo.kits.modifier.activeOpacityClickable
31
+ import vn.momo.kits.platform.LottieAnimation
31
32
 
32
33
  enum class ButtonType {
33
34
  PRIMARY,
@@ -145,10 +146,9 @@ fun RenderLeading(
145
146
  ) {
146
147
  if (loading) {
147
148
  Box(Modifier.padding(end = marginRight)) {
148
- LottieView(
149
- path = "files/lottie_circle_loader.json",
150
- tintColor = color,
149
+ LottieAnimation(
151
150
  modifier = Modifier.size(iconSize),
151
+ path = "files/lottie_circle_loader"
152
152
  )
153
153
  }
154
154
  } else {
@@ -2,6 +2,7 @@ package vn.momo.kits.components.datetimepicker
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
4
  import androidx.compose.runtime.remember
5
+ import kotlinx.datetime.Clock
5
6
  import kotlinx.datetime.DatePeriod
6
7
  import kotlinx.datetime.LocalDateTime
7
8
  import kotlinx.datetime.TimeZone
@@ -9,8 +10,6 @@ import kotlinx.datetime.minus
9
10
  import kotlinx.datetime.number
10
11
  import kotlinx.datetime.plus
11
12
  import kotlinx.datetime.toLocalDateTime
12
- import kotlin.time.Clock.System.now
13
- import kotlin.time.ExperimentalTime
14
13
 
15
14
  /**
16
15
  * Format a LocalDateTime object into a string
@@ -150,9 +149,8 @@ val timeMode = listOf("AM", "PM")
150
149
  /**
151
150
  * Get today's date
152
151
  */
153
- @OptIn(ExperimentalTime::class)
154
152
  fun getCurrentDateTime(): LocalDateTime {
155
- return now().toLocalDateTime(TimeZone.currentSystemDefault())
153
+ return Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
156
154
  }
157
155
 
158
156
  /**
@@ -1,6 +1,8 @@
1
1
  package vn.momo.kits.platform
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
+ import androidx.compose.ui.Modifier
5
+ import androidx.compose.ui.graphics.Color
4
6
  import androidx.compose.ui.graphics.NativePaint
5
7
  import androidx.compose.ui.unit.Dp
6
8
 
@@ -25,4 +27,11 @@ expect fun BackHandler(enabled: Boolean, onBack: () -> Unit)
25
27
  @Composable
26
28
  expect fun getScreenHeight(): Dp
27
29
 
28
- expect fun getAndroidBuildVersion(): Int
30
+ expect fun getAndroidBuildVersion(): Int
31
+
32
+ @Composable
33
+ expect fun LottieAnimation(
34
+ path: String,
35
+ tintColor: Color? = null,
36
+ modifier: Modifier = Modifier
37
+ )
@@ -1,9 +1,15 @@
1
1
  package vn.momo.kits.utils
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
+ import androidx.compose.runtime.LaunchedEffect
5
+ import androidx.compose.runtime.MutableState
6
+ import androidx.compose.runtime.getValue
7
+ import androidx.compose.runtime.mutableStateOf
8
+ import androidx.compose.runtime.remember
4
9
  import org.jetbrains.compose.resources.DrawableResource
5
10
  import org.jetbrains.compose.resources.InternalResourceApi
6
11
  import org.jetbrains.compose.resources.ResourceItem
12
+ import org.jetbrains.compose.resources.readResourceBytes
7
13
 
8
14
  @OptIn(InternalResourceApi::class)
9
15
  @Composable
@@ -12,4 +18,40 @@ fun getResource(name: String): DrawableResource {
12
18
  "drawable:$name",
13
19
  setOf(ResourceItem(setOf(), "drawable/$name", -1, -1))
14
20
  )
21
+ }
22
+
23
+ @OptIn(InternalResourceApi::class)
24
+ @Composable
25
+ fun readJson(name: String): String {
26
+ val path = name.plus(".json")
27
+
28
+ val jsonContent by rememberState(path, { "" }) {
29
+ val cached = resourceCache.getOrPut(path) {
30
+ ResourceCache.JSON(
31
+ readResourceBytes(path).decodeToString()
32
+ )
33
+ } as ResourceCache.JSON
34
+ cached.json
35
+ }
36
+
37
+ return jsonContent
38
+ }
39
+
40
+ private val resourceCache = mutableMapOf<String, ResourceCache>()
41
+
42
+ private sealed interface ResourceCache {
43
+ class JSON(val json: String) : ResourceCache
44
+ }
45
+
46
+ @Composable
47
+ fun <T> rememberState(
48
+ key: Any,
49
+ getDefault: () -> T,
50
+ block: suspend () -> T
51
+ ): MutableState<T> {
52
+ val state = remember(key) { mutableStateOf(getDefault()) }
53
+ LaunchedEffect(key) {
54
+ state.value = block()
55
+ }
56
+ return state
15
57
  }
@@ -1,18 +1,31 @@
1
1
  package vn.momo.kits.platform
2
2
 
3
- import androidx.compose.foundation.ExperimentalFoundationApi
3
+ import androidx.compose.foundation.layout.Box
4
4
  import androidx.compose.foundation.layout.WindowInsets
5
5
  import androidx.compose.foundation.layout.asPaddingValues
6
+ import androidx.compose.foundation.layout.fillMaxSize
6
7
  import androidx.compose.foundation.layout.systemBars
7
8
  import androidx.compose.runtime.Composable
9
+ import androidx.compose.runtime.LaunchedEffect
10
+ import androidx.compose.runtime.getValue
11
+ import androidx.compose.runtime.mutableStateOf
12
+ import androidx.compose.runtime.remember
13
+ import androidx.compose.runtime.setValue
14
+ import androidx.compose.ui.Modifier
15
+ import androidx.compose.ui.graphics.Color
8
16
  import androidx.compose.ui.graphics.NativePaint
17
+ import androidx.compose.ui.interop.UIKitView
9
18
  import androidx.compose.ui.unit.Dp
10
19
  import androidx.compose.ui.unit.dp
20
+ import cocoapods.lottie_ios.CompatibleAnimation
21
+ import cocoapods.lottie_ios.CompatibleAnimationView
11
22
  import kotlinx.cinterop.ExperimentalForeignApi
12
23
  import kotlinx.cinterop.get
13
24
  import kotlinx.cinterop.memScoped
14
25
  import org.jetbrains.skia.FilterBlurMode
15
26
  import org.jetbrains.skia.MaskFilter
27
+ import platform.Foundation.NSBundle
28
+ import platform.UIKit.UIColor
16
29
  import platform.UIKit.UIScreen
17
30
 
18
31
 
@@ -46,4 +59,46 @@ actual fun getScreenHeight(): Dp {
46
59
  return getScreenDimensions().height.dp
47
60
  }
48
61
 
49
- actual fun getAndroidBuildVersion(): Int = 999
62
+ actual fun getAndroidBuildVersion(): Int = 999
63
+
64
+ @OptIn(ExperimentalForeignApi::class)
65
+ @Composable
66
+ actual fun LottieAnimation(
67
+ path: String,
68
+ tintColor: Color?,
69
+ modifier: Modifier
70
+ ) {
71
+ var animation by remember { mutableStateOf<CompatibleAnimation?>(null) }
72
+
73
+ LaunchedEffect(Unit) {
74
+ animation = CompatibleAnimation(name = "compose-resources/composeResources/vn.momo.compose.resources/".plus(path), subdirectory = null, NSBundle.mainBundle)
75
+ }
76
+
77
+ when (val value = animation) {
78
+ null -> {
79
+ Box(modifier)
80
+ }
81
+
82
+ else -> {
83
+ val factory = remember {
84
+ {
85
+ CompatibleAnimationView(value).also {
86
+ it.translatesAutoresizingMaskIntoConstraints = true
87
+ it.setBackgroundColor(UIColor.whiteColor)
88
+ it.setLoopAnimationCount(-1.0)
89
+ it.setAnimationSpeed(1.0)
90
+
91
+ it.play()
92
+ }
93
+ }
94
+ }
95
+
96
+ Box(modifier) {
97
+ UIKitView(
98
+ modifier = Modifier.fillMaxSize(),
99
+ factory = factory,
100
+ )
101
+ }
102
+ }
103
+ }
104
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import Foundation
3
2
  import SwiftUI
4
3
  import Lottie
@@ -23,12 +22,85 @@ public enum ButtonSize {
23
22
  case small
24
23
  }
25
24
 
26
- // MARK: - Button
25
+ public struct ButtonStyleData {
26
+ let background: Color
27
+ let content: Color
28
+ let border: Color?
29
+ let borderWidth: CGFloat
30
+
31
+ public init(
32
+ background: Color,
33
+ content: Color,
34
+ border: Color? = nil,
35
+ borderWidth: CGFloat = 1
36
+ ) {
37
+ self.background = background
38
+ self.content = content
39
+ self.border = border
40
+ self.borderWidth = borderWidth
41
+ }
42
+ }
43
+
44
+ // MARK: - ButtonType Extension (Style mapping)
45
+
46
+ public extension ButtonType {
47
+ var style: ButtonStyleData {
48
+ switch self {
49
+ case .primary:
50
+ return ButtonStyleData(
51
+ background: Colors.primary,
52
+ content: Colors.black01
53
+ )
54
+ case .danger:
55
+ return ButtonStyleData(
56
+ background: Colors.error,
57
+ content: Colors.black01
58
+ )
59
+ case .tonal:
60
+ return ButtonStyleData(
61
+ background: Colors.primaryLight,
62
+ content: Colors.primary
63
+ )
64
+ case .text:
65
+ return ButtonStyleData(
66
+ background: .clear,
67
+ content: Colors.primary
68
+ )
69
+ case .secondary:
70
+ return ButtonStyleData(
71
+ background: Colors.black01,
72
+ content: Colors.black17,
73
+ border: Colors.black04
74
+ )
75
+ case .outline:
76
+ return ButtonStyleData(
77
+ background: Colors.card,
78
+ content: Colors.primary,
79
+ border: Colors.primary
80
+ )
81
+ case .disabled:
82
+ return ButtonStyleData(
83
+ background: Colors.black05,
84
+ content: Colors.black06
85
+ )
86
+ }
87
+ }
88
+ }
89
+
90
+ // MARK: - Button View
27
91
 
28
92
  public struct Button: View {
29
93
  // MARK: Lifecycle
30
94
 
31
- public init(title: String = "", action: @escaping () -> Void, type: ButtonType = .primary, size: ButtonSize = .large, iconLeft: AnyView? = nil, iconRight: AnyView? = nil, loading: Bool = false) {
95
+ public init(
96
+ title: String = "",
97
+ action: @escaping () -> Void,
98
+ type: ButtonType = .primary,
99
+ size: ButtonSize = .large,
100
+ iconLeft: AnyView? = nil,
101
+ iconRight: AnyView? = nil,
102
+ loading: Bool = false
103
+ ) {
32
104
  self.title = title
33
105
  self.action = action
34
106
  self.type = type
@@ -38,117 +110,87 @@ public struct Button: View {
38
110
  self.loading = loading
39
111
  }
40
112
 
41
- // MARK: Public
42
-
43
- public var body: some View {
44
- SwiftUI.Button(action: action) {
45
- HStack {
46
- if loading {
47
- LottieView2(name: "lottie_circle_loader", loopMode: .loop)
48
- .frame(width: iconSize, height: iconSize)
49
- .colorMultiply(.white)
50
- } else if let iconLeft = iconLeft {
51
- iconLeft.frame(width: iconSize, height: iconSize)
52
- }
53
- renderTitle(title: title, type: type, size: size).lineLimit(1).truncationMode(.tail)
54
- if let iconRight = iconRight {
55
- iconRight.frame(width: iconSize, height: iconSize)
56
- }
57
- }
58
- .buttonSize(size)
59
- .buttonType(type)
60
- .opacity(loading ? 0.75 : 1.0)
61
- }
62
- .disabled(type == .disabled || loading)
63
- .clipShape(RoundedRectangle(cornerRadius: Radius.S))
64
- }
65
-
66
113
  // MARK: Internal
67
114
 
68
115
  var title: String
69
- var action: () -> Void = {}
70
- var type: ButtonType = .primary
71
- var size: ButtonSize = .large
116
+ var action: () -> Void
117
+ var type: ButtonType
118
+ var size: ButtonSize
72
119
  var iconLeft: AnyView?
73
120
  var iconRight: AnyView?
74
121
  var loading: Bool
75
-
122
+
123
+ // MARK: Private Helpers
124
+
76
125
  private var iconSize: CGFloat {
77
126
  switch size {
78
- case .large: return 24
79
- case .medium: return 16
80
- case .small: return 16
127
+ case .large: return 24
128
+ case .medium, .small: return 16
81
129
  }
82
130
  }
83
131
 
84
- func renderTitle(title: String, type: ButtonType, size: ButtonSize) -> Text {
132
+ private func height(for size: ButtonSize) -> CGFloat {
85
133
  switch size {
86
- case .large:
87
- return Text(title).font(.system(size: 16, weight: Font.Weight.bold))
88
- case .medium:
89
- return Text(title).font(.system(size: 14, weight: Font.Weight.bold))
90
- case .small:
91
- return Text(title).font(.system(size: 12, weight: Font.Weight.bold))
134
+ case .large: return 48
135
+ case .medium: return 36
136
+ case .small: return 28
92
137
  }
93
138
  }
94
- }
95
139
 
96
- private extension View {
97
- func buttonType(_ type: ButtonType) -> some View {
98
- switch type {
99
- case .primary:
100
- return AnyView(self
101
- .background(Colors.primary)
102
- .foregroundColor(Colors.black01)
103
- )
104
- case .danger:
105
- return AnyView(self
106
- .background(Colors.error)
107
- .foregroundColor(Colors.black01)
108
- )
109
- case .tonal:
110
- return AnyView(self
111
- .background(Colors.primaryLight)
112
- .foregroundColor(Colors.primary)
113
- )
114
- case .text:
115
- return AnyView(self
116
- .foregroundColor(Colors.primary)
117
- )
118
- case .secondary:
119
- return AnyView(self
120
- .background(Colors.black01)
121
- .foregroundColor(Colors.black17)
122
- .overlay(RoundedRectangle(cornerRadius: Radius.S).stroke(Colors.black04, lineWidth: 1))
123
- )
124
- case .outline:
125
- return AnyView(self
126
- .background(Colors.card)
127
- .foregroundColor(Colors.primary)
128
- .overlay(RoundedRectangle(cornerRadius: Radius.S).stroke(Colors.primary, lineWidth: 1))
129
- )
130
- case .disabled:
131
- return AnyView(self
132
- .background(Colors.black05)
133
- .foregroundColor(Colors.black06)
134
- )
140
+ private func padding(for size: ButtonSize) -> CGFloat {
141
+ switch size {
142
+ case .large: return Spacing.L
143
+ case .medium: return Spacing.M
144
+ case .small: return Spacing.S
135
145
  }
136
146
  }
137
147
 
138
- func buttonSize(_ size: ButtonSize) -> some View {
148
+ private func renderTitle(title: String, size: ButtonSize) -> Text {
139
149
  switch size {
140
150
  case .large:
141
- return self
142
- .frame(maxWidth: .infinity, minHeight: 48, maxHeight: 48)
143
- .padding([.leading, .trailing], Spacing.L)
151
+ return Text(title).font(.system(size: 16, weight: .bold))
144
152
  case .medium:
145
- return self
146
- .frame(minWidth: 80, maxWidth: .infinity, minHeight: 36, maxHeight: 36)
147
- .padding([.leading, .trailing], Spacing.M)
153
+ return Text(title).font(.system(size: 14, weight: .bold))
148
154
  case .small:
149
- return self
150
- .frame(minWidth: 56, maxWidth: 76, minHeight: 28, maxHeight: 28)
151
- .padding([.leading, .trailing], Spacing.S)
155
+ return Text(title).font(.system(size: 12, weight: .bold))
152
156
  }
153
157
  }
158
+
159
+ // MARK: View
160
+
161
+ public var body: some View {
162
+ let style = type.style
163
+
164
+ SwiftUI.Button(action: action) {
165
+ HStack(spacing: 8) {
166
+ if loading {
167
+ LottieView(name: "lottie_circle_loader", loopMode: .loop)
168
+ .frame(width: iconSize, height: iconSize)
169
+ .colorMultiply(style.content)
170
+ } else if let iconLeft = iconLeft {
171
+ iconLeft.frame(width: iconSize, height: iconSize)
172
+ }
173
+
174
+ renderTitle(title: title, size: size)
175
+ .lineLimit(1)
176
+ .truncationMode(.tail)
177
+
178
+ if let iconRight = iconRight {
179
+ iconRight.frame(width: iconSize, height: iconSize)
180
+ }
181
+ }
182
+ .frame(maxWidth: .infinity)
183
+ .padding(.horizontal, padding(for: size))
184
+ .frame(height: height(for: size))
185
+ .background(style.background)
186
+ .foregroundColor(style.content)
187
+ .overlay(
188
+ RoundedRectangle(cornerRadius: Radius.S)
189
+ .stroke(style.border ?? .clear, lineWidth: style.border != nil ? style.borderWidth : 0)
190
+ )
191
+ .clipShape(RoundedRectangle(cornerRadius: Radius.S))
192
+ .opacity(loading ? 0.75 : 1.0)
193
+ }
194
+ .disabled(type == .disabled || loading)
195
+ }
154
196
  }
@@ -9,7 +9,7 @@
9
9
  import SwiftUI
10
10
  import Lottie
11
11
 
12
- struct LottieView2: UIViewRepresentable {
12
+ struct LottieView: UIViewRepresentable {
13
13
  var name: String = ""
14
14
  var url: String?
15
15
  var loopMode: LottieLoopMode = .playOnce
@@ -19,7 +19,7 @@ struct LottieView2: UIViewRepresentable {
19
19
  // Add static cache for animations
20
20
  private static var animationCache = NSCache<NSString, LottieAnimation>()
21
21
 
22
- func makeUIView(context: UIViewRepresentableContext<LottieView2>) -> UIView {
22
+ func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
23
23
  let view = UIView(frame: .zero)
24
24
 
25
25
  // Configure Lottie with optimized settings
@@ -82,5 +82,5 @@ struct LottieView2: UIViewRepresentable {
82
82
  }
83
83
  }
84
84
 
85
- func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieView2>) {}
85
+ func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieView>) {}
86
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.151.2-test.11",
3
+ "version": "0.151.2-test.12",
4
4
  "private": false,
5
5
  "dependencies": {
6
6
  "@momo-platform/native-max-api": "1.0.18"
@@ -1,39 +0,0 @@
1
- package vn.momo.kits.components
2
-
3
- import androidx.compose.runtime.Composable
4
- import androidx.compose.runtime.getValue
5
- import androidx.compose.ui.Modifier
6
- import androidx.compose.ui.graphics.Color
7
- import androidx.compose.ui.graphics.ColorFilter
8
- import io.github.alexzhirkevich.compottie.Compottie
9
- import io.github.alexzhirkevich.compottie.LottieCompositionSpec
10
- import io.github.alexzhirkevich.compottie.animateLottieCompositionAsState
11
- import io.github.alexzhirkevich.compottie.rememberLottieComposition
12
- import io.github.alexzhirkevich.compottie.rememberLottiePainter
13
- import vn.momo.uikits.resources.Res
14
-
15
- @Composable
16
- fun LottieView(
17
- path: String,
18
- tintColor: Color? = null,
19
- modifier: Modifier = Modifier) {
20
- val composition by rememberLottieComposition {
21
- LottieCompositionSpec.JsonString(
22
- Res.readBytes(path).decodeToString()
23
- )
24
- }
25
-
26
- val progress by animateLottieCompositionAsState(
27
- composition = composition,
28
- iterations = Compottie.IterateForever
29
- )
30
-
31
- Image(
32
- source = rememberLottiePainter(
33
- composition = composition,
34
- progress = { progress }
35
- ),
36
- colorFilter = tintColor?.let { ColorFilter.tint(it) },
37
- modifier = modifier,
38
- )
39
- }