@momo-kits/native-kits 0.163.1-beta.15-debug → 0.163.1-beta.16-debug

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.
@@ -78,7 +78,8 @@
78
78
  "Bash(xcodebuild -workspace MoMoPlatform.xcworkspace -list)",
79
79
  "Bash(git --no-pager diff --stat ios/Application/Localize.swift ios/Application/Navigation/NavigationContainer.swift ios/Popup/PopupDisplay.swift ios/Popup/PopupNotify.swift ios/Template/TrustBanner/TrustBanner.swift)",
80
80
  "Bash(git rm *)",
81
- "Bash(echo \"EXIT=$?\")"
81
+ "Bash(echo \"EXIT=$?\")",
82
+ "Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff sample/iosApp/iosApp/Demo/ButtonDemo.swift)"
82
83
  ]
83
84
  }
84
85
  }
@@ -40,7 +40,7 @@ kotlin {
40
40
  }
41
41
 
42
42
  cocoapods {
43
- version = "0.163.1-beta.15-debug"
43
+ version = "0.163.1-beta.16-debug"
44
44
  summary = "IOS Shared module"
45
45
  homepage = "https://momo.vn"
46
46
  ios.deploymentTarget = "15.0"
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |spec|
2
2
  spec.name = 'compose'
3
- spec.version = '0.163.1-beta.15-debug'
3
+ spec.version = '0.163.1-beta.16-debug'
4
4
  spec.homepage = 'https://momo.vn'
5
5
  spec.source = { :http=> ''}
6
6
  spec.authors = ''
package/gradle.properties CHANGED
@@ -18,7 +18,7 @@ kotlin.apple.xcodeCompatibility.nowarn=true
18
18
  name="ComposeKits"
19
19
  group=vn.momo.kits
20
20
  artifact.id=kits
21
- version=0.163.1-beta.15
21
+ version=0.163.1-beta.16
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
@@ -281,25 +281,19 @@ private struct ButtonPressFeedbackStyle: ButtonStyle {
281
281
  func makeBody(configuration: Configuration) -> some View {
282
282
  let pressed = configuration.isPressed && isEnabled
283
283
 
284
- ZStack {
285
- RoundedRectangle(cornerRadius: radius)
286
- .fill(background)
287
- .overlay(
288
- RoundedRectangle(cornerRadius: radius)
289
- .strokeBorder(border ?? .clear, lineWidth: border != nil ? borderWidth : 0)
290
- )
291
- .padding(.horizontal, pressed ? 2 : 0)
292
-
293
- configuration.label
294
- .opacity(pressed ? 0.5 : 1)
295
- }
296
- // Pin the whole button to its intended height explicitly: the bare
297
- // RoundedRectangle background has no intrinsic size of its own, so left
298
- // unconstrained in a ZStack inside a non-height-constraining container
299
- // (e.g. a footer VStack) it can report an oversized ideal height and
300
- // stretch the button — and its container — far taller than intended.
301
- .frame(height: height)
302
- .clipShape(RoundedRectangle(cornerRadius: radius))
303
- .animation(.easeInOut(duration: 0.1), value: pressed)
284
+ configuration.label
285
+ .opacity(pressed ? 0.5 : 1)
286
+ .background(
287
+ RoundedRectangle(cornerRadius: radius)
288
+ .fill(background)
289
+ .overlay(
290
+ RoundedRectangle(cornerRadius: radius)
291
+ .strokeBorder(border ?? .clear, lineWidth: border != nil ? borderWidth : 0)
292
+ )
293
+ .padding(.horizontal, pressed ? 2 : 0)
294
+ )
295
+ .frame(height: height)
296
+ .clipShape(RoundedRectangle(cornerRadius: radius))
297
+ .animation(.easeInOut(duration: 0.1), value: pressed)
304
298
  }
305
299
  }
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKits'
3
- s.version = '0.163.1-beta.15'
3
+ s.version = '0.163.1-beta.16'
4
4
  s.summary = 'MoMoUIKits for iOS'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKitsDemo'
3
- s.version = '0.163.1-beta.15'
3
+ s.version = '0.163.1-beta.16'
4
4
  s.summary = 'Demo browser for MoMoUIKits SwiftUI components'
5
5
  s.homepage = 'https://momo.vn'
6
6
  s.license = { :type => 'MIT' }
@@ -1,100 +1,245 @@
1
1
  //
2
- // Foundation.swift
3
- // Example
2
+ // ButtonDemo.swift
3
+ // MoMoUIKitsDemo
4
4
  //
5
- // Created by Wem on 13/12/2022.
5
+ // SwiftUI port of the Compose demo `sample/shared/.../screens/ButtonUsage.kt`:
6
+ // Preview tab mirrors `PreviewButton`, Playground tab mirrors `PlaygroundButton`.
6
7
  //
7
8
 
8
9
  import Foundation
9
- import Lottie
10
10
  import MoMoUIKits
11
11
  import SwiftUI
12
12
 
13
+ // Mirror the option lists in Compose `DemoScreen.kt`.
14
+ private let buttonTypeList: [(key: String, value: ButtonType)] = [
15
+ ("primary", .primary),
16
+ ("secondary", .secondary),
17
+ ("tonal", .tonal),
18
+ ("outline", .outline),
19
+ ("danger", .danger),
20
+ ("text", .text),
21
+ ("disabled", .disabled),
22
+ ]
23
+
24
+ private let sizeList: [(key: String, value: ButtonSize)] = [
25
+ ("large", .large),
26
+ ("medium", .medium),
27
+ ("small", .small),
28
+ ]
29
+
30
+ // Subset of the Compose `Icons` map — names resolved via `Icon(source:)` / icon.json.
31
+ private let iconOptionList: [String] = [
32
+ "none",
33
+ "arrow_arrow-back",
34
+ "arrow_arrow-next",
35
+ "Phonebook",
36
+ ]
37
+
13
38
  // MARK: - ButtonDemo
14
39
 
15
40
  struct ButtonDemo: View {
16
- // MARK: Internal
41
+ @State private var tab = 0
17
42
 
18
43
  var body: some View {
19
- ScrollView {
20
- VStack {
21
- Toggle("Disabled", isOn: $disabled)
22
-
23
- Group {
24
- Button(title: "Button", action: onPress, type: disabled ? .disabled : .primary, size: .large,
25
- iconRight: AnyView(Image(systemName: "checkmark.circle")))
26
- Button(title: "Button", action: onPress, size: .small)
27
- }
44
+ VStack(spacing: 0) {
45
+ // Stand-in for Compose `DemoScreen`'s Preview/Playground bottom tabs.
46
+ Picker("", selection: $tab) {
47
+ Text("Preview").tag(0)
48
+ Text("Playground").tag(1)
49
+ }
50
+ .pickerStyle(.segmented)
51
+ .padding(.horizontal, 12)
52
+ .padding(.top, 8)
53
+
54
+ if tab == 0 {
55
+ PreviewButton()
56
+ } else {
57
+ PlaygroundButton()
58
+ }
59
+ }
60
+ }
61
+ }
28
62
 
29
- Group {
30
- Button(title: "Button", action: onPress, type: .danger,
31
- iconLeft: AnyView(Image(systemName: "checkmark.circle")))
32
- Button(title: "Button", action: onPress, type: .danger, size: .medium)
33
- Button(title: "Button", action: onPress, type: .danger, size: .small)
34
- }
35
-
36
- Group {
37
- Button(title: "Button", action: onPress, type: .danger, iconLeft: AnyView(Image(systemName: "checkmark.circle")), isFull: false)
38
- Button(title: "Button", action: onPress, type: .danger, size: .medium, isFull: false)
39
- Button(title: "Button", action: onPress, type: .danger, size: .small, isFull: false)
40
- }
63
+ // MARK: - PreviewButton
41
64
 
65
+ private struct PreviewButton: View {
66
+ private let url = "https://static-00.iconduck.com/assets.00/external-link-icon-512x512-h2zzryfc.png"
42
67
 
43
- Group {
44
- Button(title: "Button", action: onPress, type: .tonal, size: .large)
45
- Button(title: "Button", action: onPress, type: .tonal, size: .medium)
46
- Button(title: "Button", action: onPress, type: .tonal, size: .small)
68
+ var body: some View {
69
+ ScrollView {
70
+ VStack(spacing: 0) {
71
+ ButtonSectionBox(title: "Title") {
72
+ Button(title: "Open", action: {})
47
73
  }
48
74
 
49
- Group {
50
- Button(title: "Tinted icon", action: onPress, type: .primary,
51
- iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: true)
52
- Button(title: "Original icon", action: onPress, type: .primary,
53
- iconLeft: AnyView(Image(systemName: "checkmark.circle")), useTintColor: false)
75
+ ButtonSectionBox(title: "Type") {
76
+ Button(title: "PRIMARY", action: {}, type: .primary)
77
+ Button(title: "DANGER", action: {}, type: .danger)
78
+ Button(title: "SECONDARY", action: {}, type: .secondary)
79
+ Button(title: "TONAL", action: {}, type: .tonal)
80
+ Button(title: "OUTLINE", action: {}, type: .outline)
81
+ Button(title: "TEXT", action: {}, type: .text)
82
+ Button(title: "DISABLED", action: {}, type: .disabled)
54
83
  }
55
84
 
56
- Group {
57
- Button(title: "Button", action: onPress, type: .secondary, size: .large)
58
- Button(title: "Button", action: onPress, type: .secondary, size: .medium)
59
- Button(title: "Button", action: onPress, type: .secondary, size: .small)
85
+ ButtonSectionBox(title: "Size") {
86
+ Button(title: "LARGE", action: {}, size: .large)
87
+ Button(title: "MEDIUM", action: {}, size: .medium)
88
+ Button(title: "SMALL", action: {}, size: .small)
60
89
  }
61
90
 
62
- Group {
63
- Button(title: "Button", action: onPress, type: .text, size: .large)
64
- Button(title: "Button", action: onPress, type: .text, size: .medium)
65
- Button(title: "Button", action: onPress, type: .text, size: .small)
91
+ ButtonSectionBox(title: "Loading") {
92
+ Button(title: "PRIMARY", action: {}, type: .primary, loading: true)
93
+ Button(title: "DANGER", action: {}, type: .danger, loading: true)
94
+ Button(title: "SECONDARY", action: {}, type: .secondary, loading: true)
95
+ Button(title: "TONAL", action: {}, type: .tonal, loading: true)
96
+ Button(title: "OUTLINE", action: {}, type: .outline, loading: true)
97
+ Button(title: "TEXT", action: {}, type: .text, loading: true)
98
+ Button(title: "DISABLED", action: {}, type: .disabled, loading: true)
66
99
  }
67
100
 
68
- Group {
69
- Button(title: "Button", action: onPress, type: .outline, size: .large)
70
- Button(title: "Button", action: onPress, type: .outline, size: .medium)
71
- Button(title: "Button", action: onPress, type: .outline, size: .small)
101
+ ButtonSectionBox(title: "Icon Right") {
102
+ Button(title: "Icon", action: {}, iconRight: AnyView(ImageView(url, loading: false)))
72
103
  }
73
104
 
74
- Group {
75
- Button(title: "Button", action: onPress, type: .disabled, size: .large)
76
- Button(title: "Button", action: onPress, type: .disabled, size: .medium)
77
- Button(title: "Button", action: onPress, type: .disabled, size: .small)
105
+ ButtonSectionBox(title: "Icon Left") {
106
+ Button(title: "Icon", action: {}, iconLeft: AnyView(ImageView(url, loading: false)))
78
107
  }
79
- Group {
80
- Button(title: "Button", action: onPress, type: .primary, size: .medium, loading: true)
81
- Button(title: "Button", action: onPress, type: .danger, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), loading: true)
82
- Button(title: "Button", action: onPress, type: .disabled, size: .medium, iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
83
- Button(title: "Button", action: onPress, type: .outline, size: .medium, iconLeft: AnyView(Image(systemName: "checkmark.circle")), iconRight: AnyView(Image(systemName: "checkmark.circle")), loading: true)
84
- Button(title: "Button", action: onPress, type: .secondary, size: .medium, loading: true)
85
- Button(title: "Button", action: onPress, type: .text, size: .medium, loading: true)
86
- Button(title: "Button", action: onPress, type: .tonal, size: .medium, loading: true)
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ // MARK: - PlaygroundButton
114
+
115
+ private struct PlaygroundButton: View {
116
+ @State private var title: String = "Button"
117
+ @State private var type: AnyHashable = "primary"
118
+ @State private var size: AnyHashable = "large"
119
+ @State private var iconRight: AnyHashable = "none"
120
+ @State private var iconLeft: AnyHashable = "none"
121
+ @State private var full = true
122
+ @State private var loading = false
123
+ @State private var useTintColor = true
124
+
125
+ var body: some View {
126
+ VStack(spacing: 0) {
127
+ ButtonSectionBox(title: "Component", alignment: .leading) {
128
+ Button(
129
+ title: title,
130
+ action: {},
131
+ type: buttonTypeList.first { $0.key == type }?.value ?? .primary,
132
+ size: sizeList.first { $0.key == size }?.value ?? .large,
133
+ iconLeft: iconView(iconLeft),
134
+ iconRight: iconView(iconRight),
135
+ isFull: full,
136
+ loading: loading,
137
+ useTintColor: useTintColor
138
+ )
139
+ }
140
+
141
+ ScrollView {
142
+ ButtonSectionBox(title: "Props", alignment: .leading) {
143
+ PropTitle("Children")
144
+ Input(text: $title)
145
+ PropGap()
146
+
147
+ PropTitle("Type")
148
+ RadioGroup(options: buttonTypeList.map(\.key), selection: $type)
149
+ PropGap()
150
+
151
+ PropTitle("Size")
152
+ RadioGroup(options: sizeList.map(\.key), selection: $size)
153
+ PropGap()
154
+
155
+ PropTitle("Full")
156
+ Checkbox($full, title: "\(full)")
157
+ PropGap()
158
+
159
+ PropTitle("Iconright")
160
+ RadioGroup(options: iconOptionList, selection: $iconRight)
161
+ PropGap()
162
+
163
+ PropTitle("Iconleft")
164
+ RadioGroup(options: iconOptionList, selection: $iconLeft)
165
+ PropGap()
166
+
167
+ PropTitle("Loading")
168
+ Checkbox($loading, title: "\(loading)")
169
+ PropGap()
170
+
171
+ PropTitle("Usetinecolor")
172
+ Checkbox($useTintColor, title: "\(useTintColor)")
87
173
  }
88
- }.padding(16)
89
- }.padding(.top)
174
+ }
175
+ }
90
176
  }
91
177
 
92
- func onPress() {
93
- print("Button")
178
+ private func iconView(_ selection: AnyHashable) -> AnyView? {
179
+ guard let name = selection as? String, name != "none" else { return nil }
180
+ return AnyView(Icon(source: name))
94
181
  }
182
+ }
183
+
184
+ // MARK: - Playground helpers
185
+
186
+ private struct PropTitle: View {
187
+ let title: String
188
+
189
+ init(_ title: String) { self.title = title }
190
+
191
+ var body: some View {
192
+ MomoText(title, typography: .headerDefaultBold)
193
+ }
194
+ }
195
+
196
+ private struct PropGap: View {
197
+ var body: some View {
198
+ Spacer().frame(height: Spacing.L)
199
+ }
200
+ }
201
+
202
+ private struct RadioGroup: View {
203
+ let options: [String]
204
+ @Binding var selection: AnyHashable
205
+
206
+ var body: some View {
207
+ ForEach(options, id: \.self) { key in
208
+ Radio(value: key, groupValue: $selection, label: key)
209
+ }
210
+ }
211
+ }
212
+
213
+ // MARK: - ButtonSectionBox
214
+
215
+ /// Titled rounded-card section container, mirroring Compose's `BasicColumnBox`.
216
+ private struct ButtonSectionBox<Content: View>: View {
217
+ @Environment(\.appTheme) private var theme
218
+ let title: String
219
+ var alignment: HorizontalAlignment = .center
220
+ @ViewBuilder let content: () -> Content
221
+
222
+ var body: some View {
223
+ VStack(alignment: .leading, spacing: 8) {
224
+ if !title.isEmpty {
225
+ MomoText(title, typography: .headerMBold)
226
+ .padding(.top, 8)
227
+ }
228
+
229
+ VStack(alignment: alignment, spacing: 8) {
230
+ content()
231
+ }
232
+ .frame(maxWidth: .infinity, alignment: alignment == .leading ? .leading : .center)
233
+ .padding(12)
234
+ .background(theme.colors.background.surface)
235
+ .clipShape(RoundedRectangle(cornerRadius: Radius.M))
236
+ }
237
+ .padding(12)
238
+ }
239
+ }
95
240
 
96
- // MARK: Private
241
+ // MARK: - Preview
97
242
 
98
- @State private var value: String = ""
99
- @State private var disabled: Bool = false
243
+ #Preview {
244
+ ButtonDemo()
100
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.163.1-beta.15-debug",
3
+ "version": "0.163.1-beta.16-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},