@momo-kits/native-kits 0.112.1-beta.10 → 0.112.1-beta.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.
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +1 -1
- package/ios/Application/ApplicationContext.swift +13 -0
- package/ios/Application/ApplicationEnvironment.swift +17 -0
- package/ios/Application/Badge.swift +1 -0
- package/ios/Application/Components.swift +2 -4
- package/ios/Application/ComposeApi.swift +22 -0
- package/ios/Application/HeaderRight.swift +48 -38
- package/ios/Application/Screen.swift +19 -73
- package/ios/Badge/BadgeDot.swift +42 -0
- package/ios/Icon/Icon.swift +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public class ApplicationContext {
|
|
4
|
+
public static let shared = ApplicationContext()
|
|
5
|
+
|
|
6
|
+
public var appId: String = ""
|
|
7
|
+
public var appCode: String = ""
|
|
8
|
+
public var appName: Any? = nil
|
|
9
|
+
public var appIcon: String = ""
|
|
10
|
+
public var description: Any? = nil
|
|
11
|
+
|
|
12
|
+
private init() {}
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
public class ApplicationEnvironment: ObservableObject {
|
|
4
|
+
// @Published public var theme: Theme
|
|
5
|
+
// @Published public var applicationContext: ApplicationContext
|
|
6
|
+
// @Published public var composeAPI: ComposeApi
|
|
7
|
+
//
|
|
8
|
+
// public init(
|
|
9
|
+
// theme: Theme,
|
|
10
|
+
// applicationContext: ApplicationContext,
|
|
11
|
+
// composeAPI: ComposeApi
|
|
12
|
+
// ) {
|
|
13
|
+
// self.theme = theme
|
|
14
|
+
// self.applicationContext = applicationContext
|
|
15
|
+
// self.composeAPI = composeAPI
|
|
16
|
+
// }
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -160,10 +160,10 @@ public struct Header: View {
|
|
|
160
160
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
Spacer()
|
|
163
|
+
Spacer()
|
|
164
164
|
|
|
165
165
|
if let headerRight = headerRight {
|
|
166
|
-
|
|
166
|
+
HeaderRight()
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
.frame(height: 52)
|
|
@@ -204,12 +204,10 @@ public struct Header: View {
|
|
|
204
204
|
.foregroundColor(tintIconColor)
|
|
205
205
|
.frame(maxWidth: titlePosition == .center ? .infinity : nil, alignment: titlePosition == .center ? .center : .leading)
|
|
206
206
|
}
|
|
207
|
-
|
|
208
207
|
Spacer()
|
|
209
208
|
}
|
|
210
209
|
.frame(height: 52)
|
|
211
210
|
.padding(.horizontal)
|
|
212
|
-
|
|
213
211
|
}
|
|
214
212
|
.background(Color.clear)
|
|
215
213
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public protocol ComposeApi {
|
|
4
|
+
func request(funcName: String, params: Any, _ completion: ((String) -> Void)?)
|
|
5
|
+
func request(funcName: String, params: Any) -> String
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Default implementation
|
|
9
|
+
public class ComposeApiImpl: ComposeApi {
|
|
10
|
+
public static let shared = ComposeApiImpl()
|
|
11
|
+
|
|
12
|
+
private init() {}
|
|
13
|
+
|
|
14
|
+
public func request(funcName: String, params: Any, _ completion: ((String) -> Void)?) {
|
|
15
|
+
// Implement your API request logic here
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public func request(funcName: String, params: Any) -> String {
|
|
19
|
+
// Implement your API request logic here
|
|
20
|
+
return ""
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import SwiftUI
|
|
2
|
+
import Foundation
|
|
2
3
|
|
|
3
4
|
public struct HeaderRightData {
|
|
4
5
|
var useShortcut: Bool
|
|
@@ -73,10 +74,13 @@ struct NavigationButtonConfig {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
// MARK: - Components
|
|
76
|
-
struct HeaderRight: View {
|
|
77
|
+
public struct HeaderRight: View {
|
|
78
|
+
public init(headerRight: HeaderRightData? = nil) {
|
|
79
|
+
self.headerRight = headerRight
|
|
80
|
+
}
|
|
77
81
|
var headerRight: HeaderRightData?
|
|
78
82
|
|
|
79
|
-
var body: some View {
|
|
83
|
+
public var body: some View {
|
|
80
84
|
HStack(alignment: .center) {
|
|
81
85
|
ToolkitHeaderRight(headerRight: headerRight)
|
|
82
86
|
}
|
|
@@ -87,52 +91,58 @@ struct ToolkitHeaderRight: View {
|
|
|
87
91
|
var headerRight: HeaderRightData?
|
|
88
92
|
@State private var isFavorite: Bool = false
|
|
89
93
|
@State private var isLoading: Bool = false
|
|
94
|
+
@EnvironmentObject private var environment: ApplicationEnvironment
|
|
90
95
|
|
|
91
96
|
// MARK: - Actions
|
|
92
97
|
private func onPressShortcut() {
|
|
93
|
-
|
|
94
|
-
funcName: "onToolAction",
|
|
95
|
-
params: ["item": ["key": "onFavorite"]]
|
|
96
|
-
) { _ in
|
|
97
|
-
isFavorite.toggle()
|
|
98
|
-
}
|
|
98
|
+
// environment.composeAPI.request(
|
|
99
|
+
// funcName: "onToolAction",
|
|
100
|
+
// params: ["item": ["key": "onFavorite"]]
|
|
101
|
+
// ) { _ in
|
|
102
|
+
// isFavorite.toggle()
|
|
103
|
+
// }
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
private func onPressHelpCenter() {
|
|
102
|
-
let context =
|
|
103
|
-
let paramMap: [String: Any] = [
|
|
104
|
-
"appId": context.appId,
|
|
105
|
-
"code": context.appCode,
|
|
106
|
-
"name": context.appName,
|
|
107
|
-
"icon": context.appIcon,
|
|
108
|
-
"description": context.description
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
funcName: "showHelpCenter",
|
|
112
|
-
params: paramMap
|
|
113
|
-
) { _ in }
|
|
107
|
+
// let context = environment.applicationContext
|
|
108
|
+
// let paramMap: [String: Any] = [
|
|
109
|
+
// "appId": context.appId,
|
|
110
|
+
// "code": context.appCode,
|
|
111
|
+
// "name": context.appName,
|
|
112
|
+
// "icon": context.appIcon,
|
|
113
|
+
// "description": context.description
|
|
114
|
+
// ]
|
|
115
|
+
// environment.composeAPI.request(
|
|
116
|
+
// funcName: "showHelpCenter",
|
|
117
|
+
// params: paramMap
|
|
118
|
+
// ) { _ in }
|
|
119
|
+
|
|
120
|
+
print("Press help center")
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
private func onPressClose() {
|
|
117
|
-
|
|
124
|
+
// environment.composeAPI.request(
|
|
125
|
+
// funcName: "dismiss",
|
|
126
|
+
// params: ""
|
|
127
|
+
// ) { _ in }
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
private func onPressMore() {
|
|
121
|
-
let context =
|
|
122
|
-
let params: [String: Any] = [
|
|
123
|
-
"tools": headerRight?.tools.map { $0.toMap() } ?? [],
|
|
124
|
-
"context": [
|
|
125
|
-
"appId": context.appId,
|
|
126
|
-
"code": context.appCode,
|
|
127
|
-
"name": context.appName,
|
|
128
|
-
"icon": context.appIcon,
|
|
129
|
-
"description": context.description
|
|
130
|
-
]
|
|
131
|
-
]
|
|
132
|
-
|
|
133
|
-
funcName: "showTools",
|
|
134
|
-
params: params
|
|
135
|
-
) { _ in }
|
|
131
|
+
// let context = environment.applicationContext
|
|
132
|
+
// let params: [String: Any] = [
|
|
133
|
+
// "tools": headerRight?.tools.map { $0.toMap() } ?? [],
|
|
134
|
+
// "context": [
|
|
135
|
+
// "appId": context.appId,
|
|
136
|
+
// "code": context.appCode,
|
|
137
|
+
// "name": context.appName,
|
|
138
|
+
// "icon": context.appIcon,
|
|
139
|
+
// "description": context.description
|
|
140
|
+
// ]
|
|
141
|
+
// ]
|
|
142
|
+
// environment.composeAPI.request(
|
|
143
|
+
// funcName: "showTools",
|
|
144
|
+
// params: params
|
|
145
|
+
// ) { _ in }
|
|
136
146
|
}
|
|
137
147
|
|
|
138
148
|
private func getNavigationButtonConfig() -> NavigationButtonConfig {
|
|
@@ -193,7 +203,7 @@ struct ToolkitHeaderRight: View {
|
|
|
193
203
|
RoundedRectangle(cornerRadius: 14)
|
|
194
204
|
.stroke(Color.black.opacity(0.2), lineWidth: 0.2)
|
|
195
205
|
)
|
|
196
|
-
.padding(.leading,
|
|
206
|
+
.padding(.leading, Spacing.S)
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
}
|
|
@@ -228,4 +238,4 @@ struct NavigationButton: View {
|
|
|
228
238
|
}
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
|
-
}
|
|
241
|
+
}
|
|
@@ -20,13 +20,13 @@ public struct Screen<Content: View>: View {
|
|
|
20
20
|
var onContentLayout: ((CGRect) -> Void)?
|
|
21
21
|
var useAvoidKeyboard: Bool
|
|
22
22
|
var footer: (() -> AnyView)?
|
|
23
|
-
var headerRight:
|
|
23
|
+
var headerRight: (any View)?
|
|
24
24
|
var animatedHeader: AnimatedHeader? = nil
|
|
25
25
|
var layoutOffset: CGFloat
|
|
26
26
|
var inputSearchProps: InputSearchProps? = nil
|
|
27
27
|
var fabProps: FabProps? = nil
|
|
28
28
|
var content: () -> Content
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
public init(
|
|
31
31
|
backgroundColor: Color? = nil,
|
|
32
32
|
isBack: Bool = true,
|
|
@@ -40,7 +40,7 @@ public struct Screen<Content: View>: View {
|
|
|
40
40
|
onContentLayout: ((CGRect) -> Void)? = nil,
|
|
41
41
|
useAvoidKeyboard: Bool = true,
|
|
42
42
|
footer: (() -> AnyView)? = nil,
|
|
43
|
-
headerRight:
|
|
43
|
+
headerRight: (any View)? = HeaderRight(),
|
|
44
44
|
animatedHeader: AnimatedHeader? = nil,
|
|
45
45
|
layoutOffset: CGFloat = 56,
|
|
46
46
|
inputSearchProps: InputSearchProps? = nil,
|
|
@@ -66,19 +66,19 @@ public struct Screen<Content: View>: View {
|
|
|
66
66
|
self.fabProps = fabProps
|
|
67
67
|
self.content = content
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
@State private var scrollOffset: CGFloat = 0
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
public var body: some View {
|
|
73
73
|
GeometryReader { geometry in
|
|
74
74
|
let safeAreaInsets = geometry.safeAreaInsets
|
|
75
75
|
let statusBarHeight = safeAreaInsets.top
|
|
76
76
|
let keyboardHeight: CGFloat = 0
|
|
77
77
|
let keyboardSize: CGFloat = useAvoidKeyboard ? max(keyboardHeight, 0) : 0
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
ZStack {
|
|
80
80
|
(backgroundColor ?? Color.white).edgesIgnoringSafeArea(.all)
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
VStack(spacing: 0) {
|
|
83
83
|
ZStack {
|
|
84
84
|
if animatedHeader == nil {
|
|
@@ -86,14 +86,14 @@ public struct Screen<Content: View>: View {
|
|
|
86
86
|
} else {
|
|
87
87
|
Color.white.opacity(Double(min(scrollOffset / 114, 1)))
|
|
88
88
|
.overlay(HeaderBackground(headerType: headerType, scrollState: scrollOffset))
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
Header(
|
|
93
93
|
headerType: headerType,
|
|
94
94
|
titlePosition: titlePosition,
|
|
95
95
|
title: title,
|
|
96
|
-
headerRight: headerRight,
|
|
96
|
+
// headerRight: headerRight,
|
|
97
97
|
goBack: goBack,
|
|
98
98
|
opacity: min(scrollOffset / 114, 1),
|
|
99
99
|
animatedHeader: animatedHeader,
|
|
@@ -101,13 +101,13 @@ public struct Screen<Content: View>: View {
|
|
|
101
101
|
inputSearchProps: inputSearchProps
|
|
102
102
|
).padding(.bottom, headerType == .extended ? 0 : -safeAreaTopInset())
|
|
103
103
|
}.padding(.top, -safeAreaTopInset())
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
|
|
105
|
+
|
|
106
106
|
VStack(alignment: horizontalAlignment, spacing: 0) {
|
|
107
107
|
if animatedHeader != nil {
|
|
108
108
|
Spacer().frame(height: statusBarHeight + 52 + layoutOffset)
|
|
109
109
|
}
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
if scrollable {
|
|
112
112
|
ScrollView(.vertical, showsIndicators: false) {
|
|
113
113
|
VStack {
|
|
@@ -125,19 +125,19 @@ public struct Screen<Content: View>: View {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
.padding(.bottom, keyboardSize)
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
|
|
129
|
+
|
|
130
130
|
if let footerView = footer?() {
|
|
131
131
|
ZStack(alignment: .top) {
|
|
132
132
|
Rectangle()
|
|
133
133
|
.fill(Colors.black20)
|
|
134
134
|
.frame(height: 4)
|
|
135
135
|
.shadow(color: Colors.black20.opacity(0.2), radius: 10, x: 0, y: -2)
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
Footer(footerView: footerView, keyboardSize: keyboardSize)
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
if let fabProps = fabProps {
|
|
142
142
|
FloatingButton(
|
|
143
143
|
scrollOffset: scrollOffset,
|
|
@@ -154,7 +154,7 @@ public struct Screen<Content: View>: View {
|
|
|
154
154
|
)
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
}
|
|
@@ -163,7 +163,7 @@ public struct Screen<Content: View>: View {
|
|
|
163
163
|
struct Footer: View {
|
|
164
164
|
var footerView: AnyView
|
|
165
165
|
var keyboardSize: CGFloat
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
var body: some View {
|
|
168
168
|
VStack {
|
|
169
169
|
footerView
|
|
@@ -172,57 +172,3 @@ struct Footer: View {
|
|
|
172
172
|
.background(Colors.black01)
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
|
|
176
|
-
public struct Header: View {
|
|
177
|
-
var headerType: HeaderType = .default
|
|
178
|
-
var titlePosition: TitlePosition
|
|
179
|
-
var title: String
|
|
180
|
-
var headerRight: HeaderRightData?
|
|
181
|
-
var goBack: (() -> Void)?
|
|
182
|
-
var opacity: CGFloat? = nil
|
|
183
|
-
var animatedHeader: AnimatedHeader? = nil
|
|
184
|
-
var scrollState: CGFloat = 0
|
|
185
|
-
var inputSearchProps: InputSearchProps? = nil
|
|
186
|
-
|
|
187
|
-
@State private var colorFraction: CGFloat = 0
|
|
188
|
-
|
|
189
|
-
public init(
|
|
190
|
-
headerType: HeaderType = .default,
|
|
191
|
-
titlePosition: TitlePosition,
|
|
192
|
-
title: String,
|
|
193
|
-
headerRight: HeaderRightData? = nil,
|
|
194
|
-
goBack: (() -> Void)? = nil,
|
|
195
|
-
opacity: CGFloat? = nil,
|
|
196
|
-
animatedHeader: AnimatedHeader? = nil,
|
|
197
|
-
scrollState: CGFloat = 0,
|
|
198
|
-
inputSearchProps: InputSearchProps? = nil
|
|
199
|
-
) {
|
|
200
|
-
self.headerType = headerType
|
|
201
|
-
self.titlePosition = titlePosition
|
|
202
|
-
self.title = title
|
|
203
|
-
self.headerRight = headerRight
|
|
204
|
-
self.goBack = goBack
|
|
205
|
-
self.opacity = opacity
|
|
206
|
-
self.animatedHeader = animatedHeader
|
|
207
|
-
self.scrollState = scrollState
|
|
208
|
-
self.inputSearchProps = inputSearchProps
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
public var body: some View {
|
|
212
|
-
HStack {
|
|
213
|
-
if let goBack = goBack {
|
|
214
|
-
Button(action: goBack) {
|
|
215
|
-
Text("Back")
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
Spacer()
|
|
220
|
-
|
|
221
|
-
if headerRight != nil {
|
|
222
|
-
HeaderRight(headerRight: headerRight)
|
|
223
|
-
.opacity(animatedHeader != nil ? opacity ?? 1 : 1)
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
public enum DotSize {
|
|
4
|
+
case small
|
|
5
|
+
case large
|
|
6
|
+
|
|
7
|
+
var size: CGFloat {
|
|
8
|
+
switch self {
|
|
9
|
+
case .small: return 10
|
|
10
|
+
case .large: return 16
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public struct BadgeDot: View {
|
|
16
|
+
var size: DotSize
|
|
17
|
+
|
|
18
|
+
public init(size: DotSize = .large) {
|
|
19
|
+
self.size = size
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public var body: some View {
|
|
23
|
+
Circle()
|
|
24
|
+
.fill(Colors.red03)
|
|
25
|
+
.frame(width: size.size, height: size.size)
|
|
26
|
+
.overlay(
|
|
27
|
+
Circle()
|
|
28
|
+
.stroke(Colors.black01, lineWidth: 1)
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#if DEBUG
|
|
34
|
+
struct BadgeDot_Previews: PreviewProvider {
|
|
35
|
+
static var previews: some View {
|
|
36
|
+
VStack(spacing: 10) {
|
|
37
|
+
BadgeDot(size: .small)
|
|
38
|
+
BadgeDot(size: .large)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
#endif
|
package/ios/Icon/Icon.swift
CHANGED
|
@@ -43,11 +43,11 @@ public struct Icon: View {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
public var body: some View {
|
|
46
|
-
if let uri = iconSources[source]?.uri {
|
|
47
|
-
ImageView(
|
|
46
|
+
// if let uri = iconSources[source]?.uri {
|
|
47
|
+
ImageView(source)
|
|
48
48
|
.frame(width: size, height: size)
|
|
49
49
|
.foregroundColor(color)
|
|
50
|
-
}
|
|
50
|
+
// }
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|