@momo-kits/native-kits 0.162.2-beta.26 → 0.162.2-beta.27

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 (180) hide show
  1. package/CLAUDE.md +1 -1
  2. package/ios/Application/ApplicationEnvironment.swift +0 -11
  3. package/ios/Application/Components.swift +44 -34
  4. package/ios/Application/FloatingButton.swift +9 -10
  5. package/ios/Application/HeaderRight.swift +45 -79
  6. package/ios/Application/Screen.swift +1 -2
  7. package/ios/Badge/Badge.swift +14 -11
  8. package/ios/Badge/BadgeRibbon.swift +21 -12
  9. package/ios/Button/Button.swift +22 -61
  10. package/ios/Checkbox/Checkbox.swift +13 -14
  11. package/ios/Chip/Chip.swift +9 -23
  12. package/ios/Colors+Radius+Spacing/Colors.swift +12 -12
  13. package/ios/Extensions/Color++.swift +0 -32
  14. package/ios/Icon/Icon.swift +1 -6
  15. package/ios/Input/Input.swift +25 -41
  16. package/ios/Input/InputPhoneNumber.swift +19 -20
  17. package/ios/Input/InputSearch.swift +47 -100
  18. package/ios/Input/InputTextArea.swift +40 -66
  19. package/ios/Popup/PopupDisplay.swift +16 -8
  20. package/ios/Popup/PopupInput.swift +8 -2
  21. package/ios/Swipeable/SwipeCell.swift +0 -185
  22. package/ios/Swipeable/SwipeCellModel.swift +0 -21
  23. package/ios/Typography/Text.swift +5 -79
  24. package/ios/Typography/Typography.swift +0 -3
  25. package/ios/native-kits.podspec +8 -61
  26. package/package.json +1 -1
  27. package/publish.sh +0 -50
  28. package/.claude/settings.local.json +0 -39
  29. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -103
  30. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +0 -215
  31. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +0 -65
  32. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  33. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  34. package/ios/Application/Navigation/HeaderUser.swift +0 -209
  35. package/ios/Application/Navigation/NavigationContainer.swift +0 -176
  36. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  37. package/ios/Application/Navigation/Navigator.swift +0 -364
  38. package/ios/Application/Navigation/Overplay/BottomSheet.swift +0 -188
  39. package/ios/Application/Navigation/Overplay/ModalScreen.swift +0 -68
  40. package/ios/Application/Navigation/Overplay/SnackBar.swift +0 -144
  41. package/ios/Application/Navigation/component/Header.swift +0 -178
  42. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  43. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  44. package/ios/Application/StackScreen.swift +0 -453
  45. package/ios/Avatar/Avatar.swift +0 -193
  46. package/ios/BaselineView/BaselineView.swift +0 -163
  47. package/ios/Carousel/Carousel.swift +0 -181
  48. package/ios/Collapse/Collapse.swift +0 -182
  49. package/ios/Colors+Radius+Spacing/Theme.swift +0 -295
  50. package/ios/DateTimePicker/DateTimePicker.swift +0 -210
  51. package/ios/DateTimePicker/DateTimePickerTypes.swift +0 -55
  52. package/ios/DateTimePicker/DateTimePickerUtils.swift +0 -167
  53. package/ios/DateTimePicker/WheelPicker.swift +0 -161
  54. package/ios/Divider/Divider.swift +0 -16
  55. package/ios/IconButton/IconButton.swift +0 -112
  56. package/ios/InputDropDown/InputDropDown.swift +0 -198
  57. package/ios/InputMoney/InputMoney.swift +0 -335
  58. package/ios/InputOTP/InputOTP.swift +0 -210
  59. package/ios/Loader/Loader.swift +0 -113
  60. package/ios/MoMoUIKits.podspec +0 -5
  61. package/ios/Pagination/PaginationDot.swift +0 -61
  62. package/ios/Pagination/PaginationNumber.swift +0 -35
  63. package/ios/Pagination/PaginationScroll.swift +0 -101
  64. package/ios/Pagination/PaginationWhiteDot.swift +0 -37
  65. package/ios/Popup/PopupNotify.swift +0 -219
  66. package/ios/ProgressInfo/ProgressInfo.swift +0 -294
  67. package/ios/Radio/Radio.swift +0 -70
  68. package/ios/Rating/Rating.swift +0 -82
  69. package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +0 -11
  70. package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +0 -38
  71. package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +0 -38
  72. package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +0 -38
  73. package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +0 -6
  74. package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +0 -38
  75. package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +0 -38
  76. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +0 -38
  77. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +0 -38
  78. package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +0 -38
  79. package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +0 -38
  80. package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +0 -38
  81. package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +0 -38
  82. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +0 -9
  83. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +0 -38
  84. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +0 -38
  85. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +0 -38
  86. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +0 -38
  87. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +0 -38
  88. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +0 -38
  89. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +0 -38
  90. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +0 -38
  91. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +0 -38
  92. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +0 -38
  93. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +0 -38
  94. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +0 -38
  95. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +0 -38
  96. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +0 -38
  97. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +0 -38
  98. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +0 -38
  99. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +0 -38
  100. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +0 -38
  101. package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +0 -38
  102. package/ios/Skeleton/Skeleton.swift +0 -99
  103. package/ios/Slider/Slider.swift +0 -237
  104. package/ios/Stepper/Stepper.swift +0 -220
  105. package/ios/Steps/Steps.swift +0 -451
  106. package/ios/SuggestAction/SuggestAction.swift +0 -97
  107. package/ios/TabView/TabView.swift +0 -530
  108. package/ios/Tag/Tag.swift +0 -98
  109. package/ios/Title/Title.swift +0 -269
  110. package/ios/Tooltip/Tooltip.swift +0 -482
  111. package/ios/Typography/FontScaleStore.swift +0 -19
  112. package/ios/Uploader/Uploader.swift +0 -183
  113. package/ios-demo/MoMoUIKitsDemo.podspec +0 -20
  114. package/ios-demo/Resources/dot_loading.json +0 -558
  115. package/ios-demo/Resources/icon.json +0 -4052
  116. package/ios-demo/Resources/lottie_circle_loader.json +0 -1
  117. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +0 -48
  118. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +0 -25
  119. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +0 -26
  120. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +0 -19
  121. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +0 -33
  122. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +0 -48
  123. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +0 -21
  124. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +0 -17
  125. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +0 -28
  126. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +0 -31
  127. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +0 -24
  128. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +0 -110
  129. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +0 -93
  130. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +0 -269
  131. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +0 -117
  132. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +0 -89
  133. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +0 -100
  134. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +0 -126
  135. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +0 -63
  136. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +0 -20
  137. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +0 -93
  138. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +0 -107
  139. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +0 -124
  140. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +0 -14
  141. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +0 -49
  142. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +0 -278
  143. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +0 -58
  144. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +0 -78
  145. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +0 -138
  146. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +0 -111
  147. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +0 -136
  148. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +0 -107
  149. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +0 -73
  150. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +0 -100
  151. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +0 -32
  152. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +0 -57
  153. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +0 -70
  154. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +0 -227
  155. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +0 -72
  156. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +0 -175
  157. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +0 -121
  158. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +0 -76
  159. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +0 -89
  160. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +0 -32
  161. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +0 -56
  162. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +0 -32
  163. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +0 -150
  164. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +0 -138
  165. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +0 -103
  166. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +0 -94
  167. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +0 -79
  168. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +0 -152
  169. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +0 -33
  170. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +0 -190
  171. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +0 -34
  172. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +0 -182
  173. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +0 -109
  174. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +0 -187
  175. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +0 -87
  176. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +0 -131
  177. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +0 -51
  178. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +0 -15
  179. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +0 -73
  180. package/scripts/gen-ios-color.mjs +0 -136
@@ -35,11 +35,17 @@ public struct PopupInput: View {
35
35
 
36
36
  VStack {
37
37
  VStack(alignment: .leading) {
38
- MomoText(title, typography: .headerDefaultBold, color: .black)
38
+ Text(title)
39
+ .foregroundColor(.black)
40
+ .font(.headerText1)
41
+ .ignoreBoldTextSetting()
39
42
  .padding(.top, 12)
40
43
  .padding(.bottom, 24)
41
44
 
42
- MomoText(description, typography: .bodyDefaultRegular, color: .black)
45
+ Text(description)
46
+ .foregroundColor(.black)
47
+ .font(.paragraph)
48
+ .ignoreBoldTextSetting()
43
49
  .opacity(0.6)
44
50
  .multilineTextAlignment(.leading)
45
51
  .padding(.bottom, 20)
@@ -1,191 +1,6 @@
1
1
  import Foundation
2
2
  import SwiftUI
3
3
 
4
- private let swipeActionWidth: CGFloat = 56
5
-
6
- // MARK: - Swipe
7
-
8
- public struct Swipe<Content: View>: View {
9
- private let leftActions: [SwipeAction]
10
- private let rightActions: [SwipeAction]
11
- private let height: CGFloat
12
- private let itemRadius: CGFloat
13
- private let onSwipeableOpen: () -> Void
14
- private let onSwipeableClose: () -> Void
15
- private let onSwipeableLeftOpen: () -> Void
16
- private let onSwipeableRightOpen: () -> Void
17
- private let content: () -> Content
18
-
19
- @State private var offsetX: CGFloat = 0
20
- @State private var dragStartOffsetX: CGFloat?
21
-
22
- public init(
23
- leftActions: [SwipeAction] = [],
24
- rightActions: [SwipeAction] = [],
25
- height: CGFloat = 56,
26
- itemRadius: CGFloat = 0,
27
- onSwipeableOpen: @escaping () -> Void = {},
28
- onSwipeableClose: @escaping () -> Void = {},
29
- onSwipeableLeftOpen: @escaping () -> Void = {},
30
- onSwipeableRightOpen: @escaping () -> Void = {},
31
- @ViewBuilder content: @escaping () -> Content
32
- ) {
33
- self.leftActions = Array(leftActions.prefix(3))
34
- self.rightActions = Array(rightActions.prefix(3))
35
- self.height = height
36
- self.itemRadius = itemRadius
37
- self.onSwipeableOpen = onSwipeableOpen
38
- self.onSwipeableClose = onSwipeableClose
39
- self.onSwipeableLeftOpen = onSwipeableLeftOpen
40
- self.onSwipeableRightOpen = onSwipeableRightOpen
41
- self.content = content
42
- }
43
-
44
- public var body: some View {
45
- let leftWidth = swipeActionWidth * CGFloat(leftActions.count)
46
- let rightWidth = swipeActionWidth * CGFloat(rightActions.count)
47
- let shape = RoundedRectangle(cornerRadius: itemRadius)
48
-
49
- ZStack {
50
- if !leftActions.isEmpty {
51
- HStack(spacing: 0) {
52
- ForEach(Array(leftActions.enumerated()), id: \.offset) { _, action in
53
- SwipeActionButton(
54
- action: action,
55
- height: height,
56
- itemRadius: itemRadius,
57
- defaultBackgroundColor: Colors.primary
58
- )
59
- }
60
- Spacer(minLength: 0)
61
- }
62
- }
63
-
64
- if !rightActions.isEmpty {
65
- HStack(spacing: 0) {
66
- Spacer(minLength: 0)
67
- ForEach(Array(rightActions.enumerated()), id: \.offset) { _, action in
68
- SwipeActionButton(
69
- action: action,
70
- height: height,
71
- itemRadius: itemRadius,
72
- defaultBackgroundColor: Colors.error
73
- )
74
- }
75
- }
76
- }
77
-
78
- ZStack {
79
- Colors.card
80
- content()
81
- }
82
- .frame(maxWidth: .infinity)
83
- .frame(height: height)
84
- .clipShape(shape)
85
- .offset(x: offsetX)
86
- .gesture(
87
- DragGesture(minimumDistance: 8, coordinateSpace: .local)
88
- .onChanged { value in
89
- dragOnChanged(value: value, leftWidth: leftWidth, rightWidth: rightWidth)
90
- }
91
- .onEnded { _ in
92
- dragStartOffsetX = nil
93
- snapToClosest(leftWidth: leftWidth, rightWidth: rightWidth)
94
- }
95
- )
96
- }
97
- .frame(maxWidth: .infinity)
98
- .frame(height: height)
99
- .clipped()
100
- }
101
-
102
- private func dragOnChanged(value: DragGesture.Value, leftWidth: CGFloat, rightWidth: CGFloat) {
103
- if dragStartOffsetX == nil {
104
- dragStartOffsetX = offsetX
105
- }
106
-
107
- let proposedOffset = (dragStartOffsetX ?? 0) + value.translation.width
108
- offsetX = min(max(proposedOffset, -rightWidth), leftWidth)
109
- }
110
-
111
- private func snapToClosest(leftWidth: CGFloat, rightWidth: CGFloat) {
112
- let target: CGFloat
113
-
114
- if offsetX > leftWidth * 0.5, !leftActions.isEmpty {
115
- onSwipeableLeftOpen()
116
- onSwipeableOpen()
117
- target = leftWidth
118
- } else if offsetX < -rightWidth * 0.5, !rightActions.isEmpty {
119
- onSwipeableRightOpen()
120
- onSwipeableOpen()
121
- target = -rightWidth
122
- } else {
123
- onSwipeableClose()
124
- target = 0
125
- }
126
-
127
- withAnimation(.easeOut(duration: 0.2)) {
128
- offsetX = target
129
- }
130
- }
131
- }
132
-
133
- public extension Swipe where Content == EmptyView {
134
- init(
135
- leftActions: [SwipeAction] = [],
136
- rightActions: [SwipeAction] = [],
137
- height: CGFloat = 56,
138
- itemRadius: CGFloat = 0,
139
- onSwipeableOpen: @escaping () -> Void = {},
140
- onSwipeableClose: @escaping () -> Void = {},
141
- onSwipeableLeftOpen: @escaping () -> Void = {},
142
- onSwipeableRightOpen: @escaping () -> Void = {}
143
- ) {
144
- self.init(
145
- leftActions: leftActions,
146
- rightActions: rightActions,
147
- height: height,
148
- itemRadius: itemRadius,
149
- onSwipeableOpen: onSwipeableOpen,
150
- onSwipeableClose: onSwipeableClose,
151
- onSwipeableLeftOpen: onSwipeableLeftOpen,
152
- onSwipeableRightOpen: onSwipeableRightOpen
153
- ) {
154
- EmptyView()
155
- }
156
- }
157
- }
158
-
159
- private struct SwipeActionButton: View {
160
- let action: SwipeAction
161
- let height: CGFloat
162
- let itemRadius: CGFloat
163
- let defaultBackgroundColor: Color
164
-
165
- var body: some View {
166
- SwiftUI.Button(action: action.onPress) {
167
- VStack(spacing: Spacing.XXS) {
168
- if !action.icon.isEmpty {
169
- Icon(source: action.icon, size: 20, color: Colors.black01)
170
- }
171
-
172
- if !action.label.isEmpty {
173
- MomoText(
174
- action.label,
175
- typography: .labelSMedium,
176
- color: Colors.black01,
177
- maxLines: 1
178
- )
179
- }
180
- }
181
- .frame(width: swipeActionWidth, height: height)
182
- .background(action.backgroundColor ?? defaultBackgroundColor)
183
- .clipShape(RoundedRectangle(cornerRadius: itemRadius))
184
- }
185
- .buttonStyle(.plain)
186
- }
187
- }
188
-
189
4
  // MARK: - SwipeCellModifier
190
5
 
191
6
  public struct SwipeCellModifier: ViewModifier {
@@ -3,27 +3,6 @@
3
3
  import Foundation
4
4
  import SwiftUI
5
5
 
6
- // MARK: - SwipeAction
7
-
8
- public struct SwipeAction {
9
- public init(
10
- label: String = "",
11
- icon: String = "",
12
- backgroundColor: Color? = nil,
13
- onPress: @escaping () -> Void = {}
14
- ) {
15
- self.label = label
16
- self.icon = icon
17
- self.backgroundColor = backgroundColor
18
- self.onPress = onPress
19
- }
20
-
21
- public var label: String
22
- public var icon: String
23
- public var backgroundColor: Color?
24
- public var onPress: () -> Void
25
- }
26
-
27
6
  // MARK: - SwipeGroupSide
28
7
 
29
8
  public enum SwipeGroupSide {
@@ -1,9 +1,6 @@
1
1
  import SwiftUI
2
2
 
3
3
  public func scaleSize(_ size: CGFloat, _ scaleRate: CGFloat? = nil) -> CGFloat {
4
- if !FontScaleStore.shared.useOSScaleRate {
5
- return size * FontScaleStore.shared.userScaleRate
6
- }
7
4
  let defaultScreenSize: CGFloat = 375
8
5
  let maxFontScale: CGFloat = scaleRate ?? 1.5
9
6
  let maxDeviceScale: CGFloat = 5
@@ -118,98 +115,27 @@ public extension TypographyStyle {
118
115
  }
119
116
 
120
117
  public struct MomoText: View {
121
- @Environment(\.appTheme) private var theme
122
118
  private let content: String
123
119
  private let typography: TypographyStyle
124
- private let color: Color?
125
- private let textAlign: TextAlignment
126
- private let maxLines: Int
127
- private let minLines: Int
128
- private let lineLimitRange: ClosedRange<Int>?
129
- private let truncationMode: Text.TruncationMode
130
- private let strikethrough: Bool
131
- private let underline: Bool
132
- private let letterSpacing: CGFloat?
133
- private let softWrap: Bool
134
- private let accessibilityId: String?
120
+ private let color: Color
135
121
 
136
122
  public init(
137
123
  _ content: String,
138
124
  typography: TypographyStyle = .bodyDefaultRegular,
139
- color: Color? = nil,
140
- textAlign: TextAlignment = .leading,
141
- maxLines: Int = Int.max,
142
- minLines: Int = 1,
143
- truncationMode: Text.TruncationMode = .tail,
144
- strikethrough: Bool = false,
145
- underline: Bool = false,
146
- letterSpacing: CGFloat? = nil,
147
- softWrap: Bool = true,
148
- accessibilityId: String? = nil
125
+ color: Color = Colors.text
149
126
  ) {
150
127
  self.content = content
151
128
  self.typography = typography
152
129
  self.color = color
153
- self.textAlign = textAlign
154
- self.maxLines = maxLines
155
- self.minLines = minLines
156
- // SwiftUI's range-based `lineLimit` is iOS 16+ only; keep the range for
157
- // newer OS versions and fall back to the legacy single-value overload.
158
- if maxLines == Int.max && minLines <= 1 {
159
- self.lineLimitRange = nil
160
- } else {
161
- let upper = maxLines == Int.max ? Int.max : Swift.max(maxLines, minLines)
162
- self.lineLimitRange = Swift.max(1, minLines)...upper
163
- }
164
- self.truncationMode = truncationMode
165
- self.strikethrough = strikethrough
166
- self.underline = underline
167
- self.letterSpacing = letterSpacing
168
- self.softWrap = softWrap
169
- self.accessibilityId = accessibilityId
170
130
  }
171
131
 
172
132
  public var body: some View {
173
- let textColor = color ?? theme.colors.text.default
174
- // Strikethrough is driven either by the typography variant (mirrors Compose
175
- // *Strikethrough styles) or the explicit `strikethrough` flag.
176
- let isStrikethrough = strikethrough || typography.isStrikethrough
177
-
178
- var text = SwiftUI.Text(content)
133
+ let text = SwiftUI.Text(content)
179
134
  .font(.system(size: scaleSize(typography.fontSize), weight: typography.fontWeight))
180
- .foregroundColor(textColor)
181
- .strikethrough(isStrikethrough, color: textColor)
182
- .underline(underline, color: textColor)
183
-
184
- if let letterSpacing = letterSpacing {
185
- text = text.tracking(letterSpacing)
186
- }
135
+ .foregroundColor(color)
136
+ .lineSpacing(scaleSize(typography.lineHeight) - scaleSize(typography.fontSize))
187
137
 
188
138
  return text
189
- .multilineTextAlignment(textAlign)
190
- .lineSpacing(scaleSize(typography.lineHeight) - scaleSize(typography.fontSize))
191
- .modifier(LineLimitModifier(range: lineLimitRange))
192
- .truncationMode(truncationMode)
193
- .fixedSize(horizontal: !softWrap, vertical: false)
194
- .accessibilityIdentifier(accessibilityId ?? content)
195
139
  .ignoreBoldTextSetting()
196
140
  }
197
141
  }
198
-
199
- // Applies a line-limit range only on iOS 16+. Older targets use the legacy
200
- // single-value overload so the file still compiles for iOS 15.
201
- private struct LineLimitModifier: ViewModifier {
202
- let range: ClosedRange<Int>?
203
-
204
- func body(content: Content) -> some View {
205
- if let range = range {
206
- if #available(iOS 16.0, *) {
207
- content.lineLimit(range)
208
- } else {
209
- content.lineLimit(range.upperBound)
210
- }
211
- } else {
212
- content
213
- }
214
- }
215
- }
@@ -11,9 +11,6 @@ public extension View {
11
11
 
12
12
  public extension Font {
13
13
  static func appFont(size: CGFloat) -> Font {
14
- if !FontScaleStore.shared.useOSScaleRate {
15
- return Font.system(size: size * FontScaleStore.shared.userScaleRate)
16
- }
17
14
  let defaultScreenSize: CGFloat = 375
18
15
  let maxFontScale: CGFloat = 1.5
19
16
  let maxDeviceScale: CGFloat = 5
@@ -1,74 +1,21 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'MoMoUIKits'
3
- s.version = '0.162.2-beta.26'
3
+ s.version = '1.0.0'
4
4
  s.summary = 'MoMoUIKits for iOS'
5
5
  s.homepage = 'https://momo.vn'
6
- s.license = { :type => 'MIT' }
6
+ s.license = { :type => 'MIT', :file => 'LICENSE' }
7
7
  s.author = { 'MoMo' => 'dev@momo.vn' }
8
8
  s.source = { :path => '.' }
9
9
 
10
10
  s.ios.deployment_target = '15.0'
11
11
  s.swift_version = '5.0'
12
- s.module_name = 'MoMoUIKits'
13
12
 
14
- s.source_files = [
15
- "Application/**/*.{swift,m,h}",
16
- "Avatar/**/*.{swift,m,h}",
17
- "Badge/**/*.{swift,m,h}",
18
- "BaselineView/**/*.{swift,m,h}",
19
- "Button/**/*.{swift,m,h}",
20
- "CalculatorKeyboard/**/*.{swift,m,h}",
21
- "Carousel/**/*.{swift,m,h}",
22
- "Checkbox/**/*.{swift,m,h}",
23
- "Chip/**/*.{swift,m,h}",
24
- "Collapse/**/*.{swift,m,h}",
25
- "Colors+Radius+Spacing/**/*.{swift,m,h}",
26
- "DateTimePicker/**/*.{swift,m,h}",
27
- "Divider/**/*.{swift,m,h}",
28
- "Extensions/**/*.{swift,m,h}",
29
- "Icon/**/*.{swift,m,h}",
30
- "IconButton/**/*.{swift,m,h}",
31
- "Image/**/*.{swift,m,h}",
32
- "Information/**/*.{swift,m,h}",
33
- "Input/**/*.{swift,m,h}",
34
- "InputDropDown/**/*.{swift,m,h}",
35
- "InputMoney/**/*.{swift,m,h}",
36
- "InputOTP/**/*.{swift,m,h}",
37
- "Loader/**/*.{swift,m,h}",
38
- "Lottie/**/*.{swift,m,h}",
39
- "OTPKeyboard/**/*.{swift,m,h}",
40
- "Pagination/**/*.{swift,m,h}",
41
- "Popup/**/*.{swift,m,h}",
42
- "PopupView/**/*.{swift,m,h}",
43
- "ProgressInfo/**/*.{swift,m,h}",
44
- "Radio/**/*.{swift,m,h}",
45
- "Rating/**/*.{swift,m,h}",
46
- "ScrollIndicator/**/*.{swift,m,h}",
47
- "Skeleton/**/*.{swift,m,h}",
48
- "Slider/**/*.{swift,m,h}",
49
- "StatusBarTap/**/*.{swift,m,h}",
50
- "Stepper/**/*.{swift,m,h}",
51
- "Steps/**/*.{swift,m,h}",
52
- "SuggestAction/**/*.{swift,m,h}",
53
- "Swipeable/**/*.{swift,m,h}",
54
- "Switch/**/*.{swift,m,h}",
55
- "TabView/**/*.{swift,m,h}",
56
- "Tag/**/*.{swift,m,h}",
57
- "Template/**/*.{swift,m,h}",
58
- "Title/**/*.{swift,m,h}",
59
- "Tooltip/**/*.{swift,m,h}",
60
- "Typography/**/*.{swift,m,h}",
61
- "Uploader/**/*.{swift,m,h}"
62
- ]
63
- s.resource_bundles = {
64
- 'MoMoUIKitsResources' => ['Resources/**/*']
65
- }
13
+ s.source_files = "**/*.{swift,m,h}"
66
14
  s.public_header_files = "StatusBarTap/*.h"
67
- s.frameworks = 'SwiftUI', 'Combine'
68
- s.pod_target_xcconfig = {
69
- 'DEFINES_MODULE' => 'YES'
70
- }
71
- s.dependency 'SDWebImageSwiftUI', '2.2.1'
72
- s.dependency 'lottie-ios', '4.6.0'
15
+ s.framework = 'SwiftUI', 'Combine'
16
+ s.dependency 'SDWebImageSwiftUI'
17
+ s.dependency 'lottie-ios'
73
18
  s.dependency 'SkeletonUI', '1.0.11'
74
19
  end
20
+
21
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.162.2-beta.26",
3
+ "version": "0.162.2-beta.27",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
package/publish.sh CHANGED
@@ -76,54 +76,6 @@ if [ "$MODE" == "beta" ] && [ "$BUMP_MINOR" = true ]; then
76
76
  echo "⚠️ Note: --bump is ignored in beta mode (beta version comes from package.json)."
77
77
  fi
78
78
 
79
- PODSPEC_VERSION_FILES=(
80
- "ios/native-kits.podspec"
81
- "ios-demo/MoMoUIKitsDemo.podspec"
82
- )
83
-
84
- PODSPEC_DEBUG_VERSION_FILES=(
85
- "compose/compose.podspec"
86
- )
87
-
88
- update_podspec_file_version() {
89
- local PODSPEC_FILE="$1"
90
- local PODSPEC_VERSION="$2"
91
-
92
- if [ ! -f "$PODSPEC_FILE" ]; then
93
- echo " ⚠️ Skipped missing podspec: $PODSPEC_FILE"
94
- return
95
- fi
96
-
97
- CURRENT_PODSPEC_VERSION=$(grep -E "^[[:space:]]*[A-Za-z_]+\.version[[:space:]]*=" "$PODSPEC_FILE" | head -n 1 | sed -E "s/.*['\"]([^'\"]+)['\"].*/\1/")
98
-
99
- if [[ "$OSTYPE" == "darwin"* ]]; then
100
- sed -i '' -E "s/^([[:space:]]*[A-Za-z_]+\.version[[:space:]]*=[[:space:]]*)['\"][^'\"]+['\"]/\1'$PODSPEC_VERSION'/" "$PODSPEC_FILE"
101
- else
102
- sed -i -E "s/^([[:space:]]*[A-Za-z_]+\.version[[:space:]]*=[[:space:]]*)['\"][^'\"]+['\"]/\1'$PODSPEC_VERSION'/" "$PODSPEC_FILE"
103
- fi
104
-
105
- UPDATED_PODSPEC_VERSION=$(grep -E "^[[:space:]]*[A-Za-z_]+\.version[[:space:]]*=" "$PODSPEC_FILE" | head -n 1 | sed -E "s/.*['\"]([^'\"]+)['\"].*/\1/")
106
-
107
- if [ "$UPDATED_PODSPEC_VERSION" != "$PODSPEC_VERSION" ]; then
108
- echo "❌ Error: Failed to update $PODSPEC_FILE to version $PODSPEC_VERSION"
109
- exit 1
110
- fi
111
-
112
- echo " $PODSPEC_FILE version updated: $CURRENT_PODSPEC_VERSION → $UPDATED_PODSPEC_VERSION"
113
- }
114
-
115
- update_podspec_versions() {
116
- echo "📝 Updating podspec versions..."
117
-
118
- for PODSPEC_FILE in "${PODSPEC_VERSION_FILES[@]}"; do
119
- update_podspec_file_version "$PODSPEC_FILE" "$VERSION"
120
- done
121
-
122
- for PODSPEC_FILE in "${PODSPEC_DEBUG_VERSION_FILES[@]}"; do
123
- update_podspec_file_version "$PODSPEC_FILE" "${VERSION}-debug"
124
- done
125
- }
126
-
127
79
  # ============================================================================
128
80
  # PHASE 1: CHECK AND UPDATE VERSION
129
81
  # ============================================================================
@@ -267,8 +219,6 @@ phase_check_version() {
267
219
 
268
220
  echo " Gradle version updated: $CURRENT_GRADLE_VERSION → $VERSION"
269
221
 
270
- update_podspec_versions
271
-
272
222
  export VERSION="$VERSION"
273
223
  export NPM_TAG="$NPM_TAG"
274
224
 
@@ -1,39 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(yarn react-native:*)",
5
- "Read(//Users/phuc/.claude/skills/ai-skill-generator/**)",
6
- "Bash(python3 scripts/install_skill.py --update)",
7
- "Bash(cd /Users/phuc/momo-kits/.claude/skills/design-system-kits && mkdir -p .claude/skills/design-system-kits && mv SKILL.md README.md references .claude/skills/design-system-kits/)",
8
- "Bash(mv .claude/skills/design-system-kits/* . && rmdir .claude/skills/design-system-kits && rmdir .claude/skills)",
9
- "Bash(python3 scripts/migrate_screen.py --dry-run sample/shared/src/commonMain/kotlin/screens/ScreenUsage.kt)",
10
- "Bash(python3 scripts/migrate_screen.py --dry-run sample/shared/src/commonMain/kotlin/screens/AnimatedHeaderUsage.kt sample/shared/src/commonMain/kotlin/screens/SnackBarScreenUsage.kt 2>&1)",
11
- "Bash(python3 scripts/migrate_screen.py --dry-run sample/shared/src/commonMain/kotlin/screens/SnackBarScreenUsage.kt)",
12
- "Bash(cp sample/shared/src/commonMain/kotlin/screens/SnackBarScreenUsage.kt /tmp/SnackBarScreenUsage.kt.orig && python3 scripts/migrate_screen.py sample/shared/src/commonMain/kotlin/screens/SnackBarScreenUsage.kt)",
13
- "Bash(cp -r /Users/phuc/.claude/skills/migrate-screen-to-navigation-container /Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container)",
14
- "Bash(mkdir -p /Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/scripts && mv /Users/phuc/momo-native-kits-2/momo-native-kits/scripts/migrate_screen.py /Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/scripts/migrate_screen.py)",
15
- "Bash(python3 .claude/skills/migrate-screen-to-navigation-container/scripts/generate_eval_cases.py)",
16
- "Bash(SKILL=\".claude/skills/migrate-screen-to-navigation-container\" && python3 $SKILL/scripts/migrate_screen.py $SKILL/eval/input/ 2>&1 | tail -20)",
17
- "Bash(SKILL=\".claude/skills/migrate-screen-to-navigation-container\" && cp -r $SKILL/eval/input $SKILL/eval/output && python3 $SKILL/scripts/migrate_screen.py $SKILL/eval/output/ 2>&1 | tail -20)",
18
- "Bash(SKILL=\".claude/skills/migrate-screen-to-navigation-container\" && cp -r $SKILL/eval/input $SKILL/eval/output && python3 $SKILL/scripts/migrate_screen.py $SKILL/eval/output/ 2>&1 | tail -25)",
19
- "Bash(SKILL=\".claude/skills/migrate-screen-to-navigation-container\" && cp -r \"$SKILL/eval/input\" \"$SKILL/eval/output\" && python3 \"$SKILL/scripts/migrate_screen.py\" \"$SKILL/eval/output/\" 2>&1 | tail -25)",
20
- "Bash(SKILL=\"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container\"\ncp -r \"$SKILL/eval/input\" \"$SKILL/eval/output\"\npython3 \"$SKILL/scripts/migrate_screen.py\" \"$SKILL/eval/output/\" 2>&1 | tail -25)",
21
- "Bash(cd \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container\" && python3 scripts/eval_migration.py 2>&1 | tail -80)",
22
- "Bash(cd \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container\" && python3 scripts/eval_migration.py 2>&1 | head -30)",
23
- "Bash(SKILL=\"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container\" && rm -rf \"$SKILL/eval/output\" && cp -r \"$SKILL/eval/input\" \"$SKILL/eval/output\" && python3 \"$SKILL/scripts/migrate_screen.py\" \"$SKILL/eval/output/\" 2>&1 | tail -5)",
24
- "Bash(SKILL=\"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container\"; rm -rf \"${SKILL}/eval/output\"; cp -r \"${SKILL}/eval/input\" \"${SKILL}/eval/output\" && python3 \"${SKILL}/scripts/migrate_screen.py\" \"${SKILL}/eval/output/\" 2>&1 | tail -5)",
25
- "Bash(rm -rf \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/eval/output\" && cp -r \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/eval/input\" \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/eval/output\" && python3 \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/scripts/migrate_screen.py\" \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/eval/output/\" 2>&1 | tail -5)",
26
- "Bash(python3 \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/scripts/eval_migration.py\" 2>&1 | head -35)",
27
- "Bash(python3 \"/Users/phuc/momo-native-kits-2/momo-native-kits/.claude/skills/migrate-screen-to-navigation-container/scripts/eval_migration.py\" 2>&1 | grep -E \"^=|Files eval|Passed|Failed|A0[0-9]|Per-Group|Failures\" | head -40)",
28
- "Bash(find /Users/phuc/momo-kits -name \"*.kt\" 2>/dev/null | head -20)",
29
- "Bash(find /Users/phuc -name \"*PaymentConfirmScreenFull*\" 2>/dev/null | head -10)",
30
- "Bash(./gradlew :compose:compileCommonMainKotlinMetadata -q)",
31
- "Bash(echo \"EXIT=$?\")",
32
- "Read(//tmp/**)",
33
- "Bash(git checkout *)",
34
- "Bash(xargs cat)",
35
- "Bash(git *)",
36
- "WebSearch"
37
- ]
38
- }
39
- }
@@ -1,103 +0,0 @@
1
- //
2
- // BottomTab.swift
3
- // MoMoUIKits
4
- //
5
- // SwiftUI mirror of Compose's `BottomTab` (navigation/bottomtab/BottomTab.kt).
6
- // Hosts a set of tabbed screens, each wrapped in `StackScreen` chrome built
7
- // from that tab's `NavigationOptions`, with a `BottomTabBar` pinned to the
8
- // bottom. Switching tabs cross-fades + scales the content (parity with Compose).
9
- //
10
-
11
- import SwiftUI
12
-
13
- @available(iOS 16.0, *)
14
- public struct BottomTab: View {
15
- private let items: [BottomTabItem]
16
- private let floatingButton: BottomTabFloatingButton?
17
-
18
- @EnvironmentObject private var navigator: Navigator
19
- @State private var selectedIndex: Int = 0
20
-
21
- public init(items: [BottomTabItem], floatingButton: BottomTabFloatingButton? = nil) {
22
- self.items = items
23
- self.floatingButton = floatingButton
24
- }
25
-
26
- private var bottomInset: CGFloat { safeAreaBottomInset() }
27
- private var reservedBottom: CGFloat { BOTTOM_TAB_BAR_HEIGHT + bottomInset + Spacing.S }
28
-
29
- public var body: some View {
30
- ZStack(alignment: .bottom) {
31
- // Tab content area, inset above the bar.
32
- ZStack {
33
- ForEach(items.indices, id: \.self) { index in
34
- if index == selectedIndex {
35
- tabScreen(for: index)
36
- .transition(.scale(scale: 0.97).combined(with: .opacity))
37
- }
38
- }
39
- }
40
- .padding(.bottom, reservedBottom)
41
- .animation(.easeInOut(duration: 0.2), value: selectedIndex)
42
-
43
- // Tab bar + home-indicator filler.
44
- VStack(spacing: 0) {
45
- BottomTabBar(
46
- items: items,
47
- floatingButton: floatingButton,
48
- selectedIndex: selectedIndex,
49
- onTabSelected: { index in
50
- if index != selectedIndex { selectedIndex = index }
51
- }
52
- )
53
- Colors.black01
54
- .frame(height: bottomInset + Spacing.S)
55
- }
56
- }
57
- .frame(maxWidth: .infinity, maxHeight: .infinity)
58
- .ignoresSafeArea(edges: .bottom)
59
- }
60
-
61
- @ViewBuilder
62
- private func tabScreen(for index: Int) -> some View {
63
- let item = items[index]
64
- let options = item.options ?? NavigationOptions()
65
- StackScreen(
66
- backgroundColor: options.backgroundColor,
67
- headerTransparent: options.headerTransparent,
68
- fullScreenContent: options.fullScreenContent,
69
- tintColor: options.tintColor ?? Colors.black17,
70
- isBack: !options.hiddenBack,
71
- headerType: options.headerType,
72
- useAnimated: options.useAnimated,
73
- title: options.title,
74
- headerTitle: options.headerTitle,
75
- titlePosition: options.titlePosition,
76
- // Tab back: non-first tab returns to the first tab, first tab
77
- // delegates to the navigator (mirrors Compose's onBackHandler).
78
- goBack: options.hiddenBack ? nil : {
79
- if index != 0 { selectedIndex = 0 } else { navigator.onBackSafe() }
80
- },
81
- scrollable: options.scrollable,
82
- scrollToTopCallback: options.scrollToTopCallback,
83
- useAvoidKeyboard: options.useAvoidKeyboard,
84
- keyboardShouldPersistTaps: options.keyboardShouldPersistTaps,
85
- footer: options.footer,
86
- headerRight: options.resolvedHeaderRight,
87
- animatedHeader: options.animatedHeader,
88
- layoutOffset: options.layoutOffset,
89
- inputSearchProps: options.inputSearchProps,
90
- fabProps: options.fabProps,
91
- content: { item.screen() }
92
- )
93
- }
94
- }
95
-
96
- /// Bottom safe-area inset (home indicator).
97
- @available(iOS 16.0, *)
98
- private func safeAreaBottomInset() -> CGFloat {
99
- let bottomInset = UIApplication.shared.connectedScenes
100
- .compactMap { ($0 as? UIWindowScene)?.keyWindow?.safeAreaInsets.bottom }
101
- .first ?? 0
102
- return min(bottomInset, 21)
103
- }