@momo-kits/native-kits 0.152.4-beta.2 → 0.152.4-beta.3
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/CODE_OF_CONDUCT.md +133 -0
- package/CONTRIBUTING.md +114 -0
- package/LICENSE +20 -0
- package/README.md +7 -0
- package/build.gradle.kts +32 -0
- package/compose/MoMoComposeKits.podspec +54 -0
- package/compose/build.gradle.kts +149 -0
- package/compose/src/androidMain/AndroidManifest.xml +2 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +105 -0
- package/compose/src/commonMain/composeResources/files/lottie_circle_loader.json +1 -0
- package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
- package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +201 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +222 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +48 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +715 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +214 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +236 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +77 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +27 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +334 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +345 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +90 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +543 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +69 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +143 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +179 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +111 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +384 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +160 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +234 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +223 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +232 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +236 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +228 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +364 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +50 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +34 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +85 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +33 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +338 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +95 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +64 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +89 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +91 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +84 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +208 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +172 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +199 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +237 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +191 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +13 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +191 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +258 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +35 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +59 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +68 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +49 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +232 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +111 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +94 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +159 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +232 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScaleSizeScope.kt +17 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +459 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +169 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +216 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +180 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +251 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +80 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +31 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +385 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +38 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +62 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +88 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +144 -0
- package/gradle.properties +19 -0
- package/gradlew +240 -0
- package/gradlew.bat +91 -0
- package/ios/Application/ApplicationEnvironment.swift +50 -0
- package/ios/Application/Components.swift +263 -0
- package/ios/Application/ComposeApi.swift +22 -0
- package/ios/Application/FloatingButton.swift +172 -0
- package/ios/Application/HeaderRight.swift +271 -0
- package/ios/Application/Screen.swift +249 -0
- package/ios/Badge/BadgeDot.swift +31 -0
- package/ios/Button/Button.swift +211 -0
- package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +126 -0
- package/ios/Checkbox/Checkbox.swift +81 -0
- package/ios/Chip/Chip.swift +96 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +172 -0
- package/ios/Colors+Radius+Spacing/Radius.swift +22 -0
- package/ios/Colors+Radius+Spacing/Spacing.swift +12 -0
- package/ios/Extensions/Color++.swift +25 -0
- package/ios/Icon/Icon.swift +51 -0
- package/ios/Image/Image.swift +70 -0
- package/ios/Input/Input.swift +207 -0
- package/ios/Input/InputPhoneNumber.swift +176 -0
- package/ios/Input/InputSearch.swift +238 -0
- package/ios/Input/InputTextArea.swift +242 -0
- package/ios/Lottie/LottieView.swift +86 -0
- package/ios/OTPKeyboard/KeyboardButton.swift +41 -0
- package/ios/OTPKeyboard/OTPKeyboard.swift +145 -0
- package/ios/Popup/PopupDisplay.swift +284 -0
- package/ios/Popup/PopupInput.swift +96 -0
- package/ios/Popup/PopupPromotion.swift +73 -0
- package/ios/PopupView/FullscreenPopup.swift +251 -0
- package/ios/PopupView/Modifiers.swift +158 -0
- package/ios/PopupView/PopupView.swift +289 -0
- package/ios/PopupView/Utils++.swift +281 -0
- package/ios/ScrollIndicator/ScrollIndicator.swift +110 -0
- package/ios/Swipeable/SwipeCell.swift +278 -0
- package/ios/Swipeable/SwipeCellModel.swift +86 -0
- package/ios/Switch/Switch.swift +44 -0
- package/ios/Template/Logo/Logo.swift +75 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +120 -0
- package/ios/Theme.md +18 -0
- package/ios/Typography/Text.swift +140 -0
- package/ios/Typography/Typography.swift +95 -0
- package/ios/native-kits.podspec +18 -0
- package/package.json +6 -7
- package/settings.gradle.kts +25 -0
- package/shared/build.gradle.kts +0 -74
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.Canvas
|
|
4
|
+
import androidx.compose.foundation.background
|
|
5
|
+
import androidx.compose.foundation.layout.Box
|
|
6
|
+
import androidx.compose.foundation.layout.Row
|
|
7
|
+
import androidx.compose.foundation.layout.height
|
|
8
|
+
import androidx.compose.foundation.layout.padding
|
|
9
|
+
import androidx.compose.foundation.layout.size
|
|
10
|
+
import androidx.compose.foundation.layout.width
|
|
11
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
12
|
+
import androidx.compose.runtime.Composable
|
|
13
|
+
import androidx.compose.runtime.remember
|
|
14
|
+
import androidx.compose.ui.Alignment
|
|
15
|
+
import androidx.compose.ui.Modifier
|
|
16
|
+
import androidx.compose.ui.geometry.CornerRadius
|
|
17
|
+
import androidx.compose.ui.geometry.Offset
|
|
18
|
+
import androidx.compose.ui.geometry.Rect
|
|
19
|
+
import androidx.compose.ui.geometry.RoundRect
|
|
20
|
+
import androidx.compose.ui.geometry.Size
|
|
21
|
+
import androidx.compose.ui.graphics.Color
|
|
22
|
+
import androidx.compose.ui.graphics.Path
|
|
23
|
+
import androidx.compose.ui.graphics.graphicsLayer
|
|
24
|
+
import androidx.compose.ui.layout.ContentScale
|
|
25
|
+
import androidx.compose.ui.platform.LocalDensity
|
|
26
|
+
import androidx.compose.ui.text.rememberTextMeasurer
|
|
27
|
+
import androidx.compose.ui.text.style.TextAlign
|
|
28
|
+
import androidx.compose.ui.text.style.TextOverflow
|
|
29
|
+
import androidx.compose.ui.unit.Dp
|
|
30
|
+
import androidx.compose.ui.unit.dp
|
|
31
|
+
import androidx.compose.ui.unit.sp
|
|
32
|
+
import vn.momo.kits.const.AppTheme
|
|
33
|
+
import vn.momo.kits.const.Colors
|
|
34
|
+
import vn.momo.kits.const.Typography
|
|
35
|
+
import vn.momo.kits.const.getFontFamily
|
|
36
|
+
import vn.momo.kits.const.scaleSize
|
|
37
|
+
|
|
38
|
+
@Composable
|
|
39
|
+
fun BadgeRibbon(
|
|
40
|
+
position: RibbonPosition = RibbonPosition.TopRight,
|
|
41
|
+
label: String = "Label",
|
|
42
|
+
isRound: Boolean = false,
|
|
43
|
+
modifier: Modifier = Modifier,
|
|
44
|
+
) {
|
|
45
|
+
val theme = AppTheme.current
|
|
46
|
+
|
|
47
|
+
val rotate = if (position == RibbonPosition.TopRight || position == RibbonPosition.BottomRight) 180f else 0f
|
|
48
|
+
val useUpTail = position == RibbonPosition.BottomLeft || position == RibbonPosition.TopRight
|
|
49
|
+
val verticalAlignment = when(position){
|
|
50
|
+
RibbonPosition.TopLeft, RibbonPosition.BottomRight -> Alignment.Top
|
|
51
|
+
RibbonPosition.BottomLeft, RibbonPosition.TopRight -> Alignment.Bottom
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Row(
|
|
55
|
+
modifier = modifier
|
|
56
|
+
.height(ribbonHeight)
|
|
57
|
+
.graphicsLayer { rotationZ = rotate },
|
|
58
|
+
verticalAlignment = verticalAlignment
|
|
59
|
+
) {
|
|
60
|
+
if (useUpTail) {
|
|
61
|
+
UpTail()
|
|
62
|
+
} else {
|
|
63
|
+
DownTail()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (isRound) {
|
|
67
|
+
renderRoundContent(label, rotate, theme.colors.warning.primary)
|
|
68
|
+
} else {
|
|
69
|
+
renderSkewContent(label, rotate, theme.colors.warning.primary)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@Composable
|
|
75
|
+
fun renderRoundContent(label: String, rotate: Float, backgroundColor: Color){
|
|
76
|
+
Box(
|
|
77
|
+
modifier = Modifier
|
|
78
|
+
.height(roundHeight)
|
|
79
|
+
.background(
|
|
80
|
+
color = backgroundColor,
|
|
81
|
+
shape = RoundedCornerShape(
|
|
82
|
+
topEnd = roundRightRadius,
|
|
83
|
+
bottomEnd = roundRightRadius,
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
.padding(end = roundPaddingEnd),
|
|
87
|
+
contentAlignment = Alignment.Center,
|
|
88
|
+
) {
|
|
89
|
+
Label(label, rotate)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Composable
|
|
94
|
+
fun renderSkewContent(label: String, rotate: Float, backgroundColor: Color){
|
|
95
|
+
Box(
|
|
96
|
+
modifier = Modifier
|
|
97
|
+
.height(skewBodyHeight)
|
|
98
|
+
.background(backgroundColor),
|
|
99
|
+
contentAlignment = Alignment.Center
|
|
100
|
+
) {
|
|
101
|
+
Label(label, rotate)
|
|
102
|
+
}
|
|
103
|
+
RightTail()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Composable
|
|
107
|
+
fun Label(label: String, rotate: Float){
|
|
108
|
+
Text(
|
|
109
|
+
text = label,
|
|
110
|
+
color = Colors.black_01,
|
|
111
|
+
maxLines = 1,
|
|
112
|
+
overflow = TextOverflow.Ellipsis,
|
|
113
|
+
style = Typography.labelXsMedium,
|
|
114
|
+
modifier = Modifier.graphicsLayer { rotationZ = rotate }
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@Composable
|
|
119
|
+
fun UpTail() {
|
|
120
|
+
Image(
|
|
121
|
+
source = "https://static.momocdn.net/app/img/kits/utils/Head_down_4x.png",
|
|
122
|
+
modifier = Modifier
|
|
123
|
+
.graphicsLayer { rotationZ = 180f }
|
|
124
|
+
.width(headTailWidth)
|
|
125
|
+
.height(headTailHeight),
|
|
126
|
+
options = Options(
|
|
127
|
+
contentScale = ContentScale.FillBounds,
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@Composable
|
|
133
|
+
fun DownTail() {
|
|
134
|
+
Image(
|
|
135
|
+
source = "https://static.momocdn.net/app/img/kits/utils/Head_4x.png",
|
|
136
|
+
modifier = Modifier
|
|
137
|
+
.width(headTailWidth)
|
|
138
|
+
.height(headTailHeight),
|
|
139
|
+
options = Options(
|
|
140
|
+
contentScale = ContentScale.FillBounds,
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@Composable
|
|
146
|
+
fun RightTail() {
|
|
147
|
+
Image(
|
|
148
|
+
source = "https://static.momocdn.net/app/img/kits/utils/Tail_4x.png",
|
|
149
|
+
modifier = Modifier
|
|
150
|
+
.width(skewTailWidth)
|
|
151
|
+
.height(skewTailHeight),
|
|
152
|
+
options = Options(
|
|
153
|
+
contentScale = ContentScale.FillBounds,
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@Composable
|
|
159
|
+
fun RoundedBadgeRibbon(
|
|
160
|
+
text: String = "Label",
|
|
161
|
+
position: RibbonPosition = RibbonPosition.TopLeft,
|
|
162
|
+
modifier: Modifier = Modifier
|
|
163
|
+
) {
|
|
164
|
+
val theme = AppTheme.current
|
|
165
|
+
val density = LocalDensity.current
|
|
166
|
+
val style = Typography.labelXsMedium
|
|
167
|
+
val fontFamily = style.fontFamily
|
|
168
|
+
|
|
169
|
+
val scaledFontSize = scaleSize(style.fontSize.value).sp
|
|
170
|
+
val fontFamilyResult = getFontFamily(fontFamily?.toString() ?: theme.font, style.fontWeight)
|
|
171
|
+
|
|
172
|
+
val fontSize = remember(scaledFontSize) { scaledFontSize }
|
|
173
|
+
val font = remember(fontFamilyResult) { fontFamilyResult }
|
|
174
|
+
val textMeasurer = rememberTextMeasurer()
|
|
175
|
+
|
|
176
|
+
val textLayoutResult = remember(text, fontSize, font) {
|
|
177
|
+
textMeasurer.measure(
|
|
178
|
+
text = text,
|
|
179
|
+
style = style.copy(fontSize = fontSize, fontFamily = font)
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
val textWidth = with(density) { textLayoutResult.size.width.toDp() }
|
|
184
|
+
val textHeight = with(density) { textLayoutResult.size.height.toDp() }
|
|
185
|
+
|
|
186
|
+
val minRibbonHeight = (textHeight * 1.2f).coerceAtLeast(16.dp)
|
|
187
|
+
val paddingBottom = minRibbonHeight / 4f
|
|
188
|
+
val badgeHeight = minRibbonHeight + paddingBottom
|
|
189
|
+
val horizontalPadding = paddingBottom
|
|
190
|
+
val badgeWidth = (textWidth + horizontalPadding * 2).coerceAtLeast(28.dp)
|
|
191
|
+
|
|
192
|
+
val (rotateZ, scaleY, scaleX) = when (position) {
|
|
193
|
+
RibbonPosition.TopLeft -> Triple(0f, 1f, -1f)
|
|
194
|
+
RibbonPosition.TopRight -> Triple(0f, 1f, 1f)
|
|
195
|
+
RibbonPosition.BottomRight -> Triple(0f, -1f, 1f)
|
|
196
|
+
RibbonPosition.BottomLeft -> Triple(0f, -1f, -1f)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
Box(
|
|
200
|
+
modifier = modifier
|
|
201
|
+
.size(width = badgeWidth, height = badgeHeight)
|
|
202
|
+
.graphicsLayer {
|
|
203
|
+
rotationZ = rotateZ
|
|
204
|
+
this.scaleY = scaleY
|
|
205
|
+
this.scaleX = scaleX
|
|
206
|
+
}
|
|
207
|
+
) {
|
|
208
|
+
val roundedRect = (badgeHeight - paddingBottom) / 2f
|
|
209
|
+
|
|
210
|
+
Canvas(modifier = Modifier.matchParentSize()) {
|
|
211
|
+
val width = size.width
|
|
212
|
+
val height = size.height
|
|
213
|
+
val ribbonHeight = height - paddingBottom.toPx()
|
|
214
|
+
val cornerRadius = roundedRect.toPx()
|
|
215
|
+
|
|
216
|
+
val mainColor = Color(0xFFFA541C)
|
|
217
|
+
val tailColor = Color(0xFFC41B24)
|
|
218
|
+
|
|
219
|
+
val headWidth = 4.dp.toPx()
|
|
220
|
+
val leftSectionWidth = width * (9f / 28f)
|
|
221
|
+
val middleSectionWidth = width - leftSectionWidth - headWidth
|
|
222
|
+
val rightX = leftSectionWidth + middleSectionWidth
|
|
223
|
+
|
|
224
|
+
// 1. Tail + 2. BG
|
|
225
|
+
val leftMiddlePath = Path().apply {
|
|
226
|
+
addRoundRect(
|
|
227
|
+
RoundRect(
|
|
228
|
+
rect = Rect(
|
|
229
|
+
left = 0f,
|
|
230
|
+
top = 0f,
|
|
231
|
+
right = rightX + 1f,
|
|
232
|
+
bottom = ribbonHeight
|
|
233
|
+
),
|
|
234
|
+
topLeft = CornerRadius(cornerRadius, cornerRadius),
|
|
235
|
+
topRight = CornerRadius.Zero,
|
|
236
|
+
bottomRight = CornerRadius.Zero,
|
|
237
|
+
bottomLeft = CornerRadius(cornerRadius, cornerRadius)
|
|
238
|
+
)
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
drawPath(
|
|
242
|
+
path = leftMiddlePath,
|
|
243
|
+
color = mainColor
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
// 3. Head
|
|
247
|
+
val headPath = Path().apply {
|
|
248
|
+
addRoundRect(
|
|
249
|
+
RoundRect(
|
|
250
|
+
rect = Rect(
|
|
251
|
+
left = rightX,
|
|
252
|
+
top = 0f,
|
|
253
|
+
right = rightX + headWidth,
|
|
254
|
+
bottom = ribbonHeight
|
|
255
|
+
),
|
|
256
|
+
topLeft = CornerRadius.Zero,
|
|
257
|
+
topRight = CornerRadius(cornerRadius, cornerRadius),
|
|
258
|
+
bottomRight = CornerRadius.Zero,
|
|
259
|
+
bottomLeft = CornerRadius.Zero
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
drawPath(
|
|
264
|
+
path = headPath,
|
|
265
|
+
color = mainColor
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
// Draw bottom tail section
|
|
269
|
+
val tailY = ribbonHeight
|
|
270
|
+
val tailHeight = paddingBottom.toPx()
|
|
271
|
+
val halfHeadWidth = headWidth / 2f
|
|
272
|
+
val tailStartX = rightX + headWidth - halfHeadWidth
|
|
273
|
+
|
|
274
|
+
// Background square (main color)
|
|
275
|
+
drawRect(
|
|
276
|
+
color = mainColor,
|
|
277
|
+
topLeft = Offset(tailStartX, tailY),
|
|
278
|
+
size = Size(halfHeadWidth, halfHeadWidth)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
val tailRoundRadius = tailHeight
|
|
282
|
+
val tailRightPath = Path().apply {
|
|
283
|
+
addRoundRect(
|
|
284
|
+
RoundRect(
|
|
285
|
+
rect = Rect(
|
|
286
|
+
left = tailStartX,
|
|
287
|
+
top = tailY,
|
|
288
|
+
right = tailStartX + halfHeadWidth,
|
|
289
|
+
bottom = tailY + tailHeight
|
|
290
|
+
),
|
|
291
|
+
topLeft = CornerRadius.Zero,
|
|
292
|
+
topRight = CornerRadius(tailRoundRadius, tailRoundRadius),
|
|
293
|
+
bottomRight = CornerRadius(tailRoundRadius, tailRoundRadius),
|
|
294
|
+
bottomLeft = CornerRadius.Zero
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
drawPath(
|
|
299
|
+
path = tailRightPath,
|
|
300
|
+
color = tailColor
|
|
301
|
+
)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
Text(
|
|
305
|
+
text = text,
|
|
306
|
+
modifier = Modifier
|
|
307
|
+
.padding(bottom = paddingBottom)
|
|
308
|
+
.padding(horizontal = paddingBottom / 2)
|
|
309
|
+
.align(Alignment.Center)
|
|
310
|
+
.graphicsLayer {
|
|
311
|
+
rotationZ = rotateZ
|
|
312
|
+
this.scaleY = scaleY
|
|
313
|
+
this.scaleX = scaleX
|
|
314
|
+
},
|
|
315
|
+
textAlign = TextAlign.Center,
|
|
316
|
+
style = Typography.labelXsMedium,
|
|
317
|
+
maxLines = 1,
|
|
318
|
+
overflow = TextOverflow.Ellipsis,
|
|
319
|
+
color = Colors.black_01
|
|
320
|
+
)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
val ribbonHeight: Dp = 20.dp
|
|
325
|
+
val roundHeight: Dp = 16.dp
|
|
326
|
+
val skewBodyHeight: Dp = 16.dp
|
|
327
|
+
val roundRightRadius: Dp = 12.dp
|
|
328
|
+
val roundPaddingEnd: Dp = 6.dp
|
|
329
|
+
val skewTailWidth: Dp = 8.dp
|
|
330
|
+
val skewTailHeight: Dp = 16.dp
|
|
331
|
+
val headTailWidth: Dp = 5.dp
|
|
332
|
+
val headTailHeight: Dp = 20.dp
|
|
333
|
+
|
|
334
|
+
enum class RibbonPosition {TopLeft, TopRight, BottomLeft, BottomRight}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.animation.core.animateDpAsState
|
|
4
|
+
import androidx.compose.animation.core.animateFloatAsState
|
|
5
|
+
import androidx.compose.animation.core.tween
|
|
6
|
+
import androidx.compose.foundation.background
|
|
7
|
+
import androidx.compose.foundation.border
|
|
8
|
+
import androidx.compose.foundation.clickable
|
|
9
|
+
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
10
|
+
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
|
11
|
+
import androidx.compose.foundation.layout.Arrangement
|
|
12
|
+
import androidx.compose.foundation.layout.Box
|
|
13
|
+
import androidx.compose.foundation.layout.Row
|
|
14
|
+
import androidx.compose.foundation.layout.defaultMinSize
|
|
15
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
16
|
+
import androidx.compose.foundation.layout.height
|
|
17
|
+
import androidx.compose.foundation.layout.padding
|
|
18
|
+
import androidx.compose.foundation.layout.size
|
|
19
|
+
import androidx.compose.foundation.layout.width
|
|
20
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
21
|
+
import androidx.compose.runtime.Composable
|
|
22
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
23
|
+
import androidx.compose.runtime.getValue
|
|
24
|
+
import androidx.compose.runtime.remember
|
|
25
|
+
import androidx.compose.runtime.staticCompositionLocalOf
|
|
26
|
+
import androidx.compose.ui.Alignment
|
|
27
|
+
import androidx.compose.ui.Modifier
|
|
28
|
+
import androidx.compose.ui.draw.alpha
|
|
29
|
+
import androidx.compose.ui.draw.clip
|
|
30
|
+
import androidx.compose.ui.graphics.Color
|
|
31
|
+
import androidx.compose.ui.graphics.graphicsLayer
|
|
32
|
+
import androidx.compose.ui.text.TextStyle
|
|
33
|
+
import androidx.compose.ui.text.style.TextOverflow
|
|
34
|
+
import androidx.compose.ui.unit.Dp
|
|
35
|
+
import androidx.compose.ui.unit.dp
|
|
36
|
+
import vn.momo.kits.const.AppTheme
|
|
37
|
+
import vn.momo.kits.const.Colors
|
|
38
|
+
import vn.momo.kits.const.Radius
|
|
39
|
+
import vn.momo.kits.const.Spacing
|
|
40
|
+
import vn.momo.kits.const.Typography
|
|
41
|
+
import vn.momo.kits.platform.LottieAnimation
|
|
42
|
+
|
|
43
|
+
enum class ButtonType {
|
|
44
|
+
PRIMARY,
|
|
45
|
+
SECONDARY,
|
|
46
|
+
TONAL,
|
|
47
|
+
OUTLINE,
|
|
48
|
+
DANGER,
|
|
49
|
+
TEXT,
|
|
50
|
+
DISABLED
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
data class ButtonSpecs(
|
|
54
|
+
val height: Dp,
|
|
55
|
+
val radius: Dp,
|
|
56
|
+
val padding: Dp,
|
|
57
|
+
val width: Dp,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
enum class Size(val value: ButtonSpecs) {
|
|
61
|
+
LARGE(
|
|
62
|
+
ButtonSpecs(
|
|
63
|
+
height = 48.dp,
|
|
64
|
+
radius = Radius.S,
|
|
65
|
+
padding = Spacing.L,
|
|
66
|
+
width = 128.dp
|
|
67
|
+
)
|
|
68
|
+
),
|
|
69
|
+
MEDIUM(
|
|
70
|
+
ButtonSpecs(
|
|
71
|
+
height = 36.dp,
|
|
72
|
+
radius = Radius.S,
|
|
73
|
+
padding = Spacing.M,
|
|
74
|
+
width = 80.dp
|
|
75
|
+
)
|
|
76
|
+
),
|
|
77
|
+
SMALL(
|
|
78
|
+
ButtonSpecs(
|
|
79
|
+
height = 28.dp,
|
|
80
|
+
radius = Radius.S,
|
|
81
|
+
padding = Spacing.S,
|
|
82
|
+
width = 60.dp
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private val styleCache = mapOf(
|
|
88
|
+
Size.LARGE to Typography.actionDefaultBold,
|
|
89
|
+
Size.MEDIUM to Typography.actionSBold,
|
|
90
|
+
Size.SMALL to Typography.actionXsBold
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
private val iconSizeCache = mapOf(
|
|
94
|
+
Size.LARGE to 24.dp,
|
|
95
|
+
Size.MEDIUM to 16.dp,
|
|
96
|
+
Size.SMALL to 16.dp
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
private val iconSpaceCache = mapOf(
|
|
100
|
+
Size.SMALL to Spacing.XS,
|
|
101
|
+
Size.MEDIUM to Spacing.S,
|
|
102
|
+
Size.LARGE to Spacing.S
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
fun getStyle(size: Size): TextStyle {
|
|
106
|
+
return styleCache[size] ?: Typography.actionDefaultBold
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fun getIconSize(size: Size): Dp = iconSizeCache[size] ?: 24.dp
|
|
110
|
+
fun getIconSpace(size: Size): Dp = iconSpaceCache[size] ?: Spacing.S
|
|
111
|
+
|
|
112
|
+
@Composable
|
|
113
|
+
fun getTextColor(loading: Boolean, type: ButtonType): Color {
|
|
114
|
+
val theme = AppTheme.current
|
|
115
|
+
|
|
116
|
+
return remember(type, theme, loading) {
|
|
117
|
+
when (type) {
|
|
118
|
+
ButtonType.DISABLED -> theme.colors.text.disable
|
|
119
|
+
ButtonType.PRIMARY -> Colors.black_01
|
|
120
|
+
ButtonType.SECONDARY -> theme.colors.text.default
|
|
121
|
+
ButtonType.OUTLINE -> theme.colors.primary
|
|
122
|
+
ButtonType.TONAL -> theme.colors.primary
|
|
123
|
+
ButtonType.DANGER -> Colors.black_01
|
|
124
|
+
ButtonType.TEXT -> theme.colors.primary
|
|
125
|
+
}.withLoading(loading)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@Composable
|
|
130
|
+
fun RenderTitle(size: Size, title: String = "", type: ButtonType) {
|
|
131
|
+
val style = remember(size) { getStyle(size) }
|
|
132
|
+
val color = TextColor.current
|
|
133
|
+
Text(
|
|
134
|
+
style = style,
|
|
135
|
+
text = title,
|
|
136
|
+
color = color,
|
|
137
|
+
overflow = TextOverflow.Ellipsis,
|
|
138
|
+
maxLines = 1
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@Composable
|
|
143
|
+
fun RenderIcon(
|
|
144
|
+
size: Size,
|
|
145
|
+
isIconLeft: Boolean,
|
|
146
|
+
useTintColor: Boolean = true,
|
|
147
|
+
icon: String = "",
|
|
148
|
+
forceLoading: Boolean = false
|
|
149
|
+
) {
|
|
150
|
+
val bgColor = BackgroundColor.current
|
|
151
|
+
val iconSize = remember(size) { getIconSize(size) }
|
|
152
|
+
val margin = remember(size) { getIconSpace(size) }
|
|
153
|
+
val color = if (useTintColor) TextColor.current else Color.Unspecified
|
|
154
|
+
|
|
155
|
+
val showLoading = forceLoading
|
|
156
|
+
|
|
157
|
+
val modifier = Modifier.padding(
|
|
158
|
+
start = if (isIconLeft) 0.dp else margin,
|
|
159
|
+
end = if (isIconLeft) margin else 0.dp
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if (showLoading) {
|
|
163
|
+
Box(modifier) {
|
|
164
|
+
LottieAnimation(
|
|
165
|
+
modifier = Modifier.size(iconSize),
|
|
166
|
+
bgColor = bgColor,
|
|
167
|
+
tintColor = color,
|
|
168
|
+
path = "files/lottie_circle_loader"
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
} else if (icon.isNotEmpty()) {
|
|
172
|
+
Icon(
|
|
173
|
+
source = icon,
|
|
174
|
+
color = color,
|
|
175
|
+
size = iconSize,
|
|
176
|
+
modifier = modifier
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private fun shouldLoadingOnLeft(iconLeft: String, iconRight: String): Boolean {
|
|
182
|
+
val hasLeft = iconLeft.isNotEmpty()
|
|
183
|
+
val hasRight = iconRight.isNotEmpty()
|
|
184
|
+
return when {
|
|
185
|
+
!hasLeft && !hasRight -> true
|
|
186
|
+
hasLeft && !hasRight -> true
|
|
187
|
+
!hasLeft && hasRight -> false
|
|
188
|
+
hasLeft && hasRight -> false
|
|
189
|
+
else -> true
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@Composable
|
|
194
|
+
fun getTypeStyle(
|
|
195
|
+
type: ButtonType,
|
|
196
|
+
color: Color? = AppTheme.current.colors.primary,
|
|
197
|
+
size: Size,
|
|
198
|
+
): Modifier {
|
|
199
|
+
val theme = AppTheme.current
|
|
200
|
+
val bgColor = BackgroundColor.current
|
|
201
|
+
val radius = remember(size) { size.value.radius }
|
|
202
|
+
val modifier = Modifier.background(bgColor)
|
|
203
|
+
|
|
204
|
+
return remember(type, color, theme, radius, bgColor) {
|
|
205
|
+
when (type) {
|
|
206
|
+
ButtonType.DISABLED -> modifier
|
|
207
|
+
.border(0.dp, Color.Unspecified, RoundedCornerShape(radius))
|
|
208
|
+
|
|
209
|
+
ButtonType.PRIMARY -> modifier
|
|
210
|
+
.border(0.dp, Color.Unspecified, RoundedCornerShape(radius))
|
|
211
|
+
|
|
212
|
+
ButtonType.SECONDARY -> modifier
|
|
213
|
+
.border(1.dp, theme.colors.border.default, RoundedCornerShape(radius))
|
|
214
|
+
|
|
215
|
+
ButtonType.OUTLINE -> modifier
|
|
216
|
+
.border(1.dp, color ?: theme.colors.primary, RoundedCornerShape(radius))
|
|
217
|
+
|
|
218
|
+
ButtonType.TONAL -> modifier
|
|
219
|
+
.border(0.dp, Color.Unspecified, RoundedCornerShape(radius))
|
|
220
|
+
|
|
221
|
+
ButtonType.DANGER -> modifier
|
|
222
|
+
.border(0.dp, Color.Unspecified, RoundedCornerShape(radius))
|
|
223
|
+
|
|
224
|
+
ButtonType.TEXT -> modifier
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@Composable
|
|
230
|
+
fun getButtonBackgroundColor(
|
|
231
|
+
loading: Boolean,
|
|
232
|
+
type: ButtonType
|
|
233
|
+
): Color {
|
|
234
|
+
val theme = AppTheme.current
|
|
235
|
+
|
|
236
|
+
return remember(loading, type, theme) {
|
|
237
|
+
when (type) {
|
|
238
|
+
ButtonType.DISABLED -> theme.colors.background.disable.withLoading(loading)
|
|
239
|
+
ButtonType.PRIMARY -> theme.colors.primary.withLoading(loading)
|
|
240
|
+
ButtonType.SECONDARY -> theme.colors.background.surface.withLoading(loading)
|
|
241
|
+
ButtonType.OUTLINE -> theme.colors.background.surface.withLoading(loading)
|
|
242
|
+
ButtonType.TONAL -> theme.colors.background.tonal.withLoading(loading)
|
|
243
|
+
ButtonType.DANGER -> theme.colors.error.primary.withLoading(loading)
|
|
244
|
+
ButtonType.TEXT -> Color.Unspecified
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
fun Color.withLoading(loading: Boolean): Color =
|
|
250
|
+
this.copy(alpha = if (loading) 0.75f else 1f)
|
|
251
|
+
|
|
252
|
+
@Composable
|
|
253
|
+
fun Button(
|
|
254
|
+
onClick: () -> Unit,
|
|
255
|
+
type: ButtonType = ButtonType.PRIMARY,
|
|
256
|
+
size: Size = Size.LARGE,
|
|
257
|
+
iconRight: String = "",
|
|
258
|
+
iconLeft: String = "",
|
|
259
|
+
title: String = "Button",
|
|
260
|
+
loading: Boolean = false,
|
|
261
|
+
useTintColor: Boolean = true,
|
|
262
|
+
isFull: Boolean = true,
|
|
263
|
+
modifier: Modifier = Modifier,
|
|
264
|
+
) {
|
|
265
|
+
val radius = remember(size) { size.value.radius }
|
|
266
|
+
val isEnabled = remember(type) { type != ButtonType.DISABLED }
|
|
267
|
+
val loadingOnLeft = remember(iconLeft, iconRight) {
|
|
268
|
+
shouldLoadingOnLeft(iconLeft, iconRight)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
val sizeSpecs = remember(size) { size.value }
|
|
272
|
+
|
|
273
|
+
val interactionSource = remember { MutableInteractionSource() }
|
|
274
|
+
val isPressed by interactionSource.collectIsPressedAsState()
|
|
275
|
+
|
|
276
|
+
val animatedPadding by animateDpAsState(
|
|
277
|
+
targetValue = if (isPressed && isEnabled && !loading) 2.dp else 0.dp,
|
|
278
|
+
animationSpec = tween(100),
|
|
279
|
+
label = "pressPadding"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
val targetAlpha = if (isPressed && isEnabled && !loading) 0.5f else 1f
|
|
283
|
+
val alpha by animateFloatAsState(
|
|
284
|
+
targetValue = targetAlpha,
|
|
285
|
+
animationSpec = tween(100),
|
|
286
|
+
label = "buttonPressAlpha"
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
val clickableModifier =
|
|
290
|
+
if (isEnabled && !loading) {
|
|
291
|
+
modifier
|
|
292
|
+
.then(if (isFull) Modifier.fillMaxWidth() else Modifier)
|
|
293
|
+
.clip(RoundedCornerShape(radius))
|
|
294
|
+
.clickable(
|
|
295
|
+
enabled = isEnabled && !loading,
|
|
296
|
+
interactionSource = interactionSource,
|
|
297
|
+
indication = null,
|
|
298
|
+
onClick = onClick
|
|
299
|
+
)
|
|
300
|
+
.alpha(alpha)
|
|
301
|
+
} else {
|
|
302
|
+
modifier
|
|
303
|
+
.then(if (isFull) Modifier.fillMaxWidth() else Modifier)
|
|
304
|
+
.clip(RoundedCornerShape(radius))
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
CompositionLocalProvider(
|
|
308
|
+
IsLoading provides loading,
|
|
309
|
+
BackgroundColor provides getButtonBackgroundColor(loading, type),
|
|
310
|
+
TextColor provides getTextColor(loading, type)
|
|
311
|
+
) {
|
|
312
|
+
Row(
|
|
313
|
+
modifier = clickableModifier
|
|
314
|
+
.padding(horizontal = animatedPadding)
|
|
315
|
+
.clip(RoundedCornerShape(radius))
|
|
316
|
+
.then(getTypeStyle(type, size = size))
|
|
317
|
+
.padding(horizontal = sizeSpecs.padding)
|
|
318
|
+
.height(sizeSpecs.height),
|
|
319
|
+
horizontalArrangement = Arrangement.Center,
|
|
320
|
+
verticalAlignment = Alignment.CenterVertically,
|
|
321
|
+
) {
|
|
322
|
+
RenderIcon(
|
|
323
|
+
size = size,
|
|
324
|
+
isIconLeft = true,
|
|
325
|
+
useTintColor = useTintColor,
|
|
326
|
+
icon = iconLeft,
|
|
327
|
+
forceLoading = loading && loadingOnLeft
|
|
328
|
+
)
|
|
329
|
+
RenderTitle(size, title, type = type)
|
|
330
|
+
RenderIcon(
|
|
331
|
+
size = size,
|
|
332
|
+
isIconLeft = false,
|
|
333
|
+
useTintColor = useTintColor,
|
|
334
|
+
icon = iconRight,
|
|
335
|
+
forceLoading = loading && !loadingOnLeft
|
|
336
|
+
)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
private val IsLoading = staticCompositionLocalOf<Boolean> { false }
|
|
343
|
+
private val BackgroundColor = staticCompositionLocalOf<Color> { Color.Transparent }
|
|
344
|
+
private val TextColor = staticCompositionLocalOf<Color> { Color.Transparent }
|
|
345
|
+
|