@momo-kits/native-kits 0.162.2-debug → 0.162.2-sp.1-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.
- package/.claude/settings.local.json +55 -0
- package/compose/build.gradle.kts +1 -1
- package/compose/compose.podspec +1 -1
- package/gradle.properties +1 -1
- package/ios/Application/Components.swift +34 -43
- package/ios/Application/FloatingButton.swift +10 -8
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +102 -0
- package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
- package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
- package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
- package/ios/Application/Navigation/HeaderTitle.swift +57 -0
- package/ios/Application/Navigation/HeaderUser.swift +209 -0
- package/ios/Application/Navigation/NavigationContainer.swift +151 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +360 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +176 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +68 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/component/Header.swift +178 -0
- package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
- package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
- package/ios/Application/StackScreen.swift +449 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -13
- package/ios/Badge/BadgeRibbon.swift +12 -19
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +62 -23
- package/ios/Carousel/Carousel.swift +181 -0
- package/ios/Checkbox/Checkbox.swift +14 -12
- package/ios/Chip/Chip.swift +23 -9
- package/ios/Collapse/Collapse.swift +182 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +1 -1
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +210 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +161 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Icon/Icon.swift +6 -1
- package/ios/IconButton/IconButton.swift +112 -0
- package/ios/Information/Information.swift +151 -0
- package/ios/Input/Input.swift +42 -25
- package/ios/Input/InputPhoneNumber.swift +21 -19
- package/ios/Input/InputSearch.swift +101 -45
- package/ios/Input/InputTextArea.swift +67 -40
- package/ios/InputDropDown/InputDropDown.swift +198 -0
- package/ios/InputMoney/InputMoney.swift +335 -0
- package/ios/InputOTP/InputOTP.swift +210 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/MoMoUIKits.podspec +5 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
- package/ios/Pagination/PaginationDot.swift +61 -0
- package/ios/Pagination/PaginationNumber.swift +35 -0
- package/ios/Pagination/PaginationScroll.swift +101 -0
- package/ios/Pagination/PaginationWhiteDot.swift +37 -0
- package/ios/Popup/PopupDisplay.swift +10 -12
- package/ios/Popup/PopupInput.swift +2 -6
- package/ios/Popup/PopupNotify.swift +219 -0
- package/ios/ProgressInfo/ProgressInfo.swift +294 -0
- package/ios/Radio/Radio.swift +70 -0
- package/ios/Rating/Rating.swift +82 -0
- package/ios/Skeleton/Skeleton.swift +99 -0
- package/ios/Slider/Slider.swift +237 -0
- package/ios/Stepper/Stepper.swift +220 -0
- package/ios/Steps/Steps.swift +451 -0
- package/ios/SuggestAction/SuggestAction.swift +97 -0
- package/ios/Swipeable/SwipeCell.swift +185 -0
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/TabView/TabView.swift +530 -0
- package/ios/Tag/Tag.swift +98 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +2 -0
- package/ios/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +482 -0
- package/ios/Typography/Text.swift +77 -5
- package/ios/Typography/Typography.swift +9 -0
- package/ios/Uploader/Uploader.swift +183 -0
- package/ios/native-kits.podspec +58 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +18 -0
- package/ios-demo/README.md +120 -0
- package/ios-demo/Resources/dot_loading.json +558 -0
- package/ios-demo/Resources/icon.json +4052 -0
- package/ios-demo/Resources/lottie_circle_loader.json +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +261 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +227 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +50 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/local.properties +8 -0
- package/package.json +1 -1
- package/publish.sh +50 -0
- package/scripts/gen-ios-color.mjs +136 -0
|
@@ -9,11 +9,12 @@ import SwiftUI
|
|
|
9
9
|
// MARK: - RenderRightIconSearch
|
|
10
10
|
|
|
11
11
|
struct RenderRightIconSearch: View {
|
|
12
|
+
@Environment(\.appTheme) private var theme
|
|
12
13
|
let loading: Bool
|
|
13
14
|
let icon: String
|
|
14
15
|
let color: Color
|
|
15
16
|
let onClick: () -> Void
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
var body: some View {
|
|
18
19
|
HStack(spacing: 0) {
|
|
19
20
|
if loading {
|
|
@@ -24,12 +25,10 @@ struct RenderRightIconSearch: View {
|
|
|
24
25
|
if !icon.isEmpty {
|
|
25
26
|
Divider()
|
|
26
27
|
.frame(width: 1)
|
|
27
|
-
.background(
|
|
28
|
+
.background(theme.colors.primary)
|
|
28
29
|
.padding(.leading, Spacing.S)
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
.foregroundColor(color)
|
|
32
|
-
.frame(width: 24, height: 24)
|
|
31
|
+
Icon(source: icon, size: 24, color: color)
|
|
33
32
|
.padding(.leading, Spacing.S)
|
|
34
33
|
.onTapGesture(perform: onClick)
|
|
35
34
|
}
|
|
@@ -48,14 +47,18 @@ public struct InputSearchProps {
|
|
|
48
47
|
var error: String = ""
|
|
49
48
|
var disabled: Bool = false
|
|
50
49
|
var icon: String = ""
|
|
51
|
-
var iconColor: Color =
|
|
50
|
+
var iconColor: Color? = nil
|
|
52
51
|
var onRightIconPressed: () -> Void = {}
|
|
53
52
|
var onFocus: () -> Void = {}
|
|
54
53
|
var onBlur: () -> Void = {}
|
|
55
54
|
var loading: Bool = false
|
|
56
55
|
var fontWeight: Font.Weight = .regular
|
|
57
56
|
var keyboardType: UIKeyboardType = .default
|
|
58
|
-
|
|
57
|
+
// Mirrors Compose's InputSearchProps.searchIcon — a custom leading icon view.
|
|
58
|
+
var searchIcon: (() -> AnyView)? = nil
|
|
59
|
+
// Mirrors Compose's InputSearchProps.placeholderCustomRender — a custom placeholder view.
|
|
60
|
+
var placeholderCustomRender: (() -> AnyView)? = nil
|
|
61
|
+
|
|
59
62
|
public init(text: Binding<String>,
|
|
60
63
|
buttonText: String = "",
|
|
61
64
|
showButtonText: Bool = false,
|
|
@@ -66,13 +69,15 @@ public struct InputSearchProps {
|
|
|
66
69
|
error: String = "",
|
|
67
70
|
disabled: Bool = false,
|
|
68
71
|
icon: String = "",
|
|
69
|
-
iconColor: Color =
|
|
72
|
+
iconColor: Color? = nil,
|
|
70
73
|
onRightIconPressed: @escaping () -> Void = {},
|
|
71
74
|
onFocus: @escaping () -> Void = {},
|
|
72
75
|
onBlur: @escaping () -> Void = {},
|
|
73
76
|
loading: Bool = false,
|
|
74
77
|
fontWeight: Font.Weight = .regular,
|
|
75
|
-
keyboardType: UIKeyboardType = .default
|
|
78
|
+
keyboardType: UIKeyboardType = .default,
|
|
79
|
+
searchIcon: (() -> AnyView)? = nil,
|
|
80
|
+
placeholderCustomRender: (() -> AnyView)? = nil) {
|
|
76
81
|
self._text = text
|
|
77
82
|
self.buttonText = buttonText
|
|
78
83
|
self.showButtonText = showButtonText
|
|
@@ -90,12 +95,15 @@ public struct InputSearchProps {
|
|
|
90
95
|
self.loading = loading
|
|
91
96
|
self.fontWeight = fontWeight
|
|
92
97
|
self.keyboardType = keyboardType
|
|
98
|
+
self.searchIcon = searchIcon
|
|
99
|
+
self.placeholderCustomRender = placeholderCustomRender
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
// MARK: - InputSearch
|
|
97
104
|
|
|
98
105
|
public struct InputSearch: View {
|
|
106
|
+
@Environment(\.appTheme) private var theme
|
|
99
107
|
@Binding var text: String
|
|
100
108
|
var buttonText: String = ""
|
|
101
109
|
var showButtonText: Bool = false
|
|
@@ -106,17 +114,19 @@ public struct InputSearch: View {
|
|
|
106
114
|
var error: String = ""
|
|
107
115
|
var disabled: Bool = false
|
|
108
116
|
var icon: String = ""
|
|
109
|
-
var iconColor: Color =
|
|
117
|
+
var iconColor: Color? = nil
|
|
110
118
|
var onRightIconPressed: () -> Void = {}
|
|
111
119
|
var onFocus: () -> Void = {}
|
|
112
120
|
var onBlur: () -> Void = {}
|
|
113
121
|
var loading: Bool = false
|
|
114
122
|
var fontWeight: Font.Weight = .regular
|
|
115
123
|
var keyboardType: UIKeyboardType = .default
|
|
116
|
-
|
|
124
|
+
var searchIcon: (() -> AnyView)? = nil
|
|
125
|
+
var placeholderCustomRender: (() -> AnyView)? = nil
|
|
126
|
+
|
|
117
127
|
@State private var isFocused = false
|
|
118
128
|
@State private var isBlurred = false
|
|
119
|
-
|
|
129
|
+
|
|
120
130
|
public init(text: Binding<String>,
|
|
121
131
|
buttonText: String = "",
|
|
122
132
|
showButtonText: Bool = false,
|
|
@@ -127,13 +137,15 @@ public struct InputSearch: View {
|
|
|
127
137
|
error: String = "",
|
|
128
138
|
disabled: Bool = false,
|
|
129
139
|
icon: String = "",
|
|
130
|
-
iconColor: Color =
|
|
140
|
+
iconColor: Color? = nil,
|
|
131
141
|
onRightIconPressed: @escaping () -> Void = {},
|
|
132
142
|
onFocus: @escaping () -> Void = {},
|
|
133
143
|
onBlur: @escaping () -> Void = {},
|
|
134
144
|
loading: Bool = false,
|
|
135
145
|
fontWeight: Font.Weight = .regular,
|
|
136
|
-
keyboardType: UIKeyboardType = .default
|
|
146
|
+
keyboardType: UIKeyboardType = .default,
|
|
147
|
+
searchIcon: (() -> AnyView)? = nil,
|
|
148
|
+
placeholderCustomRender: (() -> AnyView)? = nil) {
|
|
137
149
|
self._text = text
|
|
138
150
|
self.buttonText = buttonText
|
|
139
151
|
self.showButtonText = showButtonText
|
|
@@ -151,23 +163,60 @@ public struct InputSearch: View {
|
|
|
151
163
|
self.loading = loading
|
|
152
164
|
self.fontWeight = fontWeight
|
|
153
165
|
self.keyboardType = keyboardType
|
|
166
|
+
self.searchIcon = searchIcon
|
|
167
|
+
self.placeholderCustomRender = placeholderCustomRender
|
|
154
168
|
}
|
|
155
169
|
|
|
156
|
-
|
|
170
|
+
/// Convenience initializer mirroring Compose's `InputSearch(inputSearchProps)`.
|
|
171
|
+
public init(props: InputSearchProps) {
|
|
172
|
+
self.init(
|
|
173
|
+
text: props.$text,
|
|
174
|
+
buttonText: props.buttonText,
|
|
175
|
+
showButtonText: props.showButtonText,
|
|
176
|
+
showBorder: props.showBorder,
|
|
177
|
+
placeholder: props.placeholder,
|
|
178
|
+
onChangeText: props.onChangeText,
|
|
179
|
+
onPressButtonText: props.onPressButtonText,
|
|
180
|
+
error: props.error,
|
|
181
|
+
disabled: props.disabled,
|
|
182
|
+
icon: props.icon,
|
|
183
|
+
iconColor: props.iconColor,
|
|
184
|
+
onRightIconPressed: props.onRightIconPressed,
|
|
185
|
+
onFocus: props.onFocus,
|
|
186
|
+
onBlur: props.onBlur,
|
|
187
|
+
loading: props.loading,
|
|
188
|
+
fontWeight: props.fontWeight,
|
|
189
|
+
keyboardType: props.keyboardType,
|
|
190
|
+
searchIcon: props.searchIcon,
|
|
191
|
+
placeholderCustomRender: props.placeholderCustomRender
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
157
196
|
public var body: some View {
|
|
197
|
+
let iconColor: Color = disabled ? theme.colors.text.disable : (self.iconColor ?? theme.colors.text.default)
|
|
158
198
|
VStack(alignment: .leading, spacing: 0) {
|
|
159
199
|
HStack(spacing: 0) {
|
|
160
200
|
HStack {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
201
|
+
if let searchIcon = searchIcon {
|
|
202
|
+
searchIcon()
|
|
203
|
+
} else {
|
|
204
|
+
Image(systemName: "magnifyingglass")
|
|
205
|
+
.foregroundColor(theme.colors.text.hint)
|
|
206
|
+
.frame(width: 24, height: 24)
|
|
207
|
+
.padding(.trailing, Spacing.XS)
|
|
208
|
+
}
|
|
209
|
+
|
|
166
210
|
ZStack(alignment: .leading) {
|
|
167
211
|
if text.isEmpty {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
212
|
+
if let placeholderCustomRender = placeholderCustomRender {
|
|
213
|
+
placeholderCustomRender()
|
|
214
|
+
} else {
|
|
215
|
+
Text(placeholder)
|
|
216
|
+
.foregroundColor(disabled ? theme.colors.text.disable : theme.colors.text.hint)
|
|
217
|
+
.font(.system(size: scaleSize(14), weight: fontWeight))
|
|
218
|
+
.ignoreBoldTextSetting()
|
|
219
|
+
}
|
|
171
220
|
}
|
|
172
221
|
TextField("", text: $text, onEditingChanged: { editing in
|
|
173
222
|
isFocused = editing
|
|
@@ -181,25 +230,27 @@ public struct InputSearch: View {
|
|
|
181
230
|
}
|
|
182
231
|
}, onCommit: {})
|
|
183
232
|
.disabled(disabled)
|
|
184
|
-
.foregroundColor(disabled ?
|
|
185
|
-
.font(.system(size:
|
|
233
|
+
.foregroundColor(disabled ? theme.colors.text.disable : theme.colors.text.default)
|
|
234
|
+
.font(.system(size: scaleSize(14), weight: fontWeight))
|
|
235
|
+
.ignoreBoldTextSetting()
|
|
186
236
|
.keyboardType(keyboardType)
|
|
237
|
+
.applyCursorColor(theme.colors.primary)
|
|
187
238
|
}
|
|
188
239
|
|
|
189
240
|
if isFocused && !text.isEmpty {
|
|
190
241
|
SwiftButton(action: { text = "" }) {
|
|
191
242
|
Image(systemName: "xmark.circle.fill")
|
|
192
|
-
.foregroundColor(
|
|
243
|
+
.foregroundColor(theme.colors.text.hint)
|
|
193
244
|
.frame(width: 16, height: 16)
|
|
194
245
|
}
|
|
195
246
|
.padding(.leading, Spacing.S)
|
|
196
247
|
}
|
|
197
248
|
|
|
198
|
-
RenderRightIconSearch(loading: loading, icon: icon, color:
|
|
249
|
+
RenderRightIconSearch(loading: loading, icon: icon, color: iconColor, onClick: onRightIconPressed)
|
|
199
250
|
}
|
|
200
251
|
.padding(.horizontal, Spacing.M)
|
|
201
252
|
.padding(.vertical, Spacing.S)
|
|
202
|
-
.background(
|
|
253
|
+
.background(theme.colors.background.surface)
|
|
203
254
|
.cornerRadius(Radius.XL)
|
|
204
255
|
.overlay(
|
|
205
256
|
RoundedRectangle(cornerRadius: Radius.XL)
|
|
@@ -209,30 +260,35 @@ public struct InputSearch: View {
|
|
|
209
260
|
|
|
210
261
|
if showButtonText {
|
|
211
262
|
SwiftButton(action: onPressButtonText) {
|
|
212
|
-
|
|
213
|
-
.foregroundColor(Colors.black17)
|
|
214
|
-
.font(.system(size: 14, weight: .medium))
|
|
263
|
+
MomoText(buttonText, typography: .actionDefaultBold, color: theme.colors.text.default)
|
|
215
264
|
}
|
|
216
265
|
.padding(.leading, Spacing.L)
|
|
217
266
|
}
|
|
218
267
|
}
|
|
219
268
|
}
|
|
220
269
|
}
|
|
221
|
-
}
|
|
222
270
|
|
|
223
|
-
// MARK: - Helper Functions
|
|
224
|
-
|
|
225
|
-
func getBorderColor(isFocused: Bool, error: String, disabled: Bool) -> Color {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
271
|
+
// MARK: - Helper Functions
|
|
272
|
+
|
|
273
|
+
func getBorderColor(isFocused: Bool, error: String, disabled: Bool) -> Color {
|
|
274
|
+
if disabled {
|
|
275
|
+
return theme.colors.border.disable
|
|
276
|
+
} else if !error.isEmpty {
|
|
277
|
+
return theme.colors.error.primary
|
|
278
|
+
} else if isFocused {
|
|
279
|
+
return theme.colors.primary
|
|
280
|
+
} else {
|
|
281
|
+
return theme.colors.border.default
|
|
282
|
+
}
|
|
234
283
|
}
|
|
235
284
|
}
|
|
236
285
|
|
|
237
|
-
|
|
238
|
-
|
|
286
|
+
private extension View {
|
|
287
|
+
func applyCursorColor(_ color: Color) -> some View {
|
|
288
|
+
if #available(iOS 15.0, *) {
|
|
289
|
+
return self.tint(color)
|
|
290
|
+
} else {
|
|
291
|
+
return self
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
@@ -12,6 +12,12 @@ public let DEFAULT_HEIGHT: CGFloat = 104
|
|
|
12
12
|
|
|
13
13
|
struct UITextViewWrapper: UIViewRepresentable {
|
|
14
14
|
@Binding var text: String
|
|
15
|
+
var maxLength: Int
|
|
16
|
+
var textColor: Color
|
|
17
|
+
var cursorColor: Color
|
|
18
|
+
var fontWeight: Font.Weight
|
|
19
|
+
var disabled: Bool
|
|
20
|
+
var onChangeText: (String) -> Void
|
|
15
21
|
var onDone: (() -> Void)?
|
|
16
22
|
var onFocus: (() -> Void)?
|
|
17
23
|
var onBlur: (() -> Void)?
|
|
@@ -19,11 +25,20 @@ struct UITextViewWrapper: UIViewRepresentable {
|
|
|
19
25
|
func makeUIView(context: Context) -> UITextView {
|
|
20
26
|
let textView = UITextView()
|
|
21
27
|
textView.delegate = context.coordinator
|
|
28
|
+
textView.backgroundColor = .clear
|
|
29
|
+
textView.textContainerInset = .zero
|
|
30
|
+
textView.textContainer.lineFragmentPadding = 0
|
|
22
31
|
return textView
|
|
23
32
|
}
|
|
24
33
|
|
|
25
34
|
func updateUIView(_ uiView: UITextView, context: Context) {
|
|
26
|
-
uiView.text
|
|
35
|
+
if uiView.text != text {
|
|
36
|
+
uiView.text = text
|
|
37
|
+
}
|
|
38
|
+
uiView.textColor = UIColor(textColor)
|
|
39
|
+
uiView.tintColor = UIColor(cursorColor)
|
|
40
|
+
uiView.font = UIFont.systemFont(ofSize: scaleSize(16), weight: fontWeight == .bold ? .bold : .regular)
|
|
41
|
+
uiView.isEditable = !disabled
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
func makeCoordinator() -> Coordinator {
|
|
@@ -38,7 +53,12 @@ struct UITextViewWrapper: UIViewRepresentable {
|
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
func textViewDidChange(_ textView: UITextView) {
|
|
41
|
-
|
|
56
|
+
let limited = String(textView.text.prefix(parent.maxLength))
|
|
57
|
+
if textView.text != limited {
|
|
58
|
+
textView.text = limited
|
|
59
|
+
}
|
|
60
|
+
parent.text = limited
|
|
61
|
+
parent.onChangeText(limited)
|
|
42
62
|
}
|
|
43
63
|
|
|
44
64
|
func textViewDidBeginEditing(_ textView: UITextView) {
|
|
@@ -54,27 +74,31 @@ struct UITextViewWrapper: UIViewRepresentable {
|
|
|
54
74
|
parent.onDone?()
|
|
55
75
|
return false
|
|
56
76
|
}
|
|
57
|
-
|
|
77
|
+
let current = textView.text ?? ""
|
|
78
|
+
guard let range = Range(range, in: current) else { return false }
|
|
79
|
+
let proposed = current.replacingCharacters(in: range, with: text)
|
|
80
|
+
return proposed.count <= parent.maxLength
|
|
58
81
|
}
|
|
59
82
|
}
|
|
60
83
|
}
|
|
61
84
|
|
|
62
85
|
// Make the struct public
|
|
63
86
|
public struct InputTextArea: View {
|
|
87
|
+
@Environment(\.appTheme) private var theme
|
|
64
88
|
@Binding var text: String
|
|
65
89
|
var maxLength: Int = MAX_LENGTH
|
|
66
90
|
var height: CGFloat = DEFAULT_HEIGHT
|
|
67
91
|
var floatingValue: String = ""
|
|
68
|
-
var floatingValueColor: Color
|
|
92
|
+
var floatingValueColor: Color?
|
|
69
93
|
var floatingIcon: String = ""
|
|
70
|
-
var floatingIconColor: Color
|
|
94
|
+
var floatingIconColor: Color?
|
|
71
95
|
var placeholder: String = ""
|
|
72
96
|
var onChangeText: (String) -> Void = { _ in }
|
|
73
97
|
var error: String = ""
|
|
74
98
|
var errorSpacing: Bool = false
|
|
75
99
|
var disabled: Bool = false
|
|
76
100
|
var icon: String = ""
|
|
77
|
-
var iconColor: Color
|
|
101
|
+
var iconColor: Color?
|
|
78
102
|
var onRightIconPressed: () -> Void = {}
|
|
79
103
|
var onFocus: () -> Void = {}
|
|
80
104
|
var onBlur: () -> Void = {}
|
|
@@ -92,16 +116,16 @@ public struct InputTextArea: View {
|
|
|
92
116
|
maxLength: Int = MAX_LENGTH,
|
|
93
117
|
height: CGFloat = DEFAULT_HEIGHT,
|
|
94
118
|
floatingValue: String = "",
|
|
95
|
-
floatingValueColor: Color =
|
|
119
|
+
floatingValueColor: Color? = nil,
|
|
96
120
|
floatingIcon: String = "",
|
|
97
|
-
floatingIconColor: Color =
|
|
121
|
+
floatingIconColor: Color? = nil,
|
|
98
122
|
placeholder: String = "",
|
|
99
123
|
onChangeText: @escaping (String) -> Void = { _ in },
|
|
100
124
|
error: String = "",
|
|
101
125
|
errorSpacing: Bool = false,
|
|
102
126
|
disabled: Bool = false,
|
|
103
127
|
icon: String = "",
|
|
104
|
-
iconColor: Color =
|
|
128
|
+
iconColor: Color? = nil,
|
|
105
129
|
onRightIconPressed: @escaping () -> Void = {},
|
|
106
130
|
onFocus: @escaping () -> Void = {},
|
|
107
131
|
onBlur: @escaping () -> Void = {},
|
|
@@ -138,24 +162,27 @@ public struct InputTextArea: View {
|
|
|
138
162
|
ZStack(alignment: .topLeading) {
|
|
139
163
|
if !floatingValue.isEmpty || !floatingIcon.isEmpty {
|
|
140
164
|
HStack(spacing: 4) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
165
|
+
MomoText(
|
|
166
|
+
floatingValue,
|
|
167
|
+
typography: .labelSMedium,
|
|
168
|
+
color: disabled ? theme.colors.text.disable : (floatingValueColor ?? theme.colors.text.hint)
|
|
169
|
+
)
|
|
144
170
|
|
|
145
171
|
if required {
|
|
146
|
-
|
|
147
|
-
.font(.caption)
|
|
148
|
-
.foregroundColor(.red)
|
|
172
|
+
MomoText("*", typography: .labelSMedium, color: theme.colors.error.primary)
|
|
149
173
|
}
|
|
150
174
|
|
|
151
175
|
if !floatingIcon.isEmpty {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
176
|
+
Icon(
|
|
177
|
+
source: floatingIcon,
|
|
178
|
+
size: 16,
|
|
179
|
+
color: disabled ? theme.colors.text.disable : (floatingIconColor ?? theme.colors.text.default)
|
|
180
|
+
)
|
|
181
|
+
.padding(.leading, Spacing.XS)
|
|
155
182
|
}
|
|
156
183
|
}
|
|
157
|
-
.padding(.horizontal,
|
|
158
|
-
.background(
|
|
184
|
+
.padding(.horizontal, Spacing.S)
|
|
185
|
+
.background(theme.colors.background.surface)
|
|
159
186
|
.offset(x: Spacing.S, y: -height / 10)
|
|
160
187
|
.zIndex(10)
|
|
161
188
|
}
|
|
@@ -164,13 +191,21 @@ public struct InputTextArea: View {
|
|
|
164
191
|
ZStack(alignment: .topLeading) {
|
|
165
192
|
if text.isEmpty {
|
|
166
193
|
Text(placeholder)
|
|
167
|
-
.foregroundColor(disabled ? .
|
|
194
|
+
.foregroundColor(disabled ? theme.colors.text.disable : theme.colors.text.hint)
|
|
168
195
|
.font(.system(size: 16, weight: fontWeight))
|
|
169
196
|
.padding(.horizontal, 16)
|
|
170
197
|
.padding(.vertical, 12)
|
|
171
198
|
}
|
|
172
199
|
|
|
173
|
-
UITextViewWrapper(
|
|
200
|
+
UITextViewWrapper(
|
|
201
|
+
text: $text,
|
|
202
|
+
maxLength: maxLength,
|
|
203
|
+
textColor: disabled ? theme.colors.text.disable : theme.colors.text.default,
|
|
204
|
+
cursorColor: theme.colors.primary,
|
|
205
|
+
fontWeight: fontWeight,
|
|
206
|
+
disabled: disabled,
|
|
207
|
+
onChangeText: onChangeText,
|
|
208
|
+
onDone: {
|
|
174
209
|
// Handle done action if needed
|
|
175
210
|
},
|
|
176
211
|
onFocus: {
|
|
@@ -188,27 +223,20 @@ public struct InputTextArea: View {
|
|
|
188
223
|
|
|
189
224
|
HStack {
|
|
190
225
|
Spacer()
|
|
191
|
-
|
|
192
|
-
.font(.caption)
|
|
193
|
-
.foregroundColor(.gray)
|
|
226
|
+
MomoText("\(text.count)/\(maxLength)", typography: .descriptionXsRegular, color: theme.colors.text.hint)
|
|
194
227
|
}
|
|
195
228
|
.padding(.horizontal, 16)
|
|
196
229
|
.padding(.bottom, 12)
|
|
197
230
|
}
|
|
198
|
-
.background(
|
|
199
|
-
.cornerRadius(
|
|
231
|
+
.background(theme.colors.background.surface)
|
|
232
|
+
.cornerRadius(Radius.S)
|
|
200
233
|
.overlay(
|
|
201
|
-
RoundedRectangle(cornerRadius:
|
|
234
|
+
RoundedRectangle(cornerRadius: Radius.S)
|
|
202
235
|
.stroke(borderColor, lineWidth: 1)
|
|
203
236
|
)
|
|
204
237
|
}
|
|
205
238
|
|
|
206
|
-
|
|
207
|
-
Text(error)
|
|
208
|
-
.font(.caption)
|
|
209
|
-
.foregroundColor(.red)
|
|
210
|
-
.padding(.top, errorSpacing ? 8 : 4)
|
|
211
|
-
}
|
|
239
|
+
ErrorView(errorMessage: error, errorSpacing: errorSpacing, hintText: "")
|
|
212
240
|
}
|
|
213
241
|
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { _ in
|
|
214
242
|
if !isBlurred {
|
|
@@ -223,20 +251,19 @@ public struct InputTextArea: View {
|
|
|
223
251
|
onBlur()
|
|
224
252
|
}
|
|
225
253
|
}
|
|
254
|
+
.ignoreBoldTextSetting()
|
|
226
255
|
}
|
|
227
256
|
|
|
228
257
|
private var borderColor: Color {
|
|
229
258
|
if disabled {
|
|
230
|
-
return
|
|
259
|
+
return theme.colors.border.disable
|
|
231
260
|
} else if !error.isEmpty {
|
|
232
|
-
return .
|
|
261
|
+
return theme.colors.error.primary
|
|
233
262
|
} else if isFocused {
|
|
234
|
-
return
|
|
263
|
+
return theme.colors.primary
|
|
235
264
|
} else {
|
|
236
|
-
return
|
|
265
|
+
return theme.colors.border.default
|
|
237
266
|
}
|
|
238
267
|
|
|
239
268
|
}
|
|
240
269
|
}
|
|
241
|
-
|
|
242
|
-
|