@momo-kits/native-kits 0.163.1-beta.2-debug → 0.163.1-beta.20-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 +112 -0
- package/CLAUDE.md +1 -1
- package/compose/build.gradle.kts +2 -1
- package/compose/build.gradle.kts.backup +1 -0
- package/compose/compose.podspec +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +30 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +8 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +2 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +11 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +40 -55
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +5 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +3 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +19 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +28 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +50 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +25 -22
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +37 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +68 -22
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +7 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +112 -115
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +15 -3
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +33 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +6 -5
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +23 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +11 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +26 -3
- package/gradle/libs.versions.toml +2 -0
- package/gradle.properties +1 -1
- package/ios/Application/ApplicationEnvironment.swift +15 -3
- package/ios/Application/Components.swift +36 -30
- package/ios/Application/FloatingButton.swift +10 -9
- package/ios/Application/Localize.swift +309 -0
- package/ios/Application/MaxApi.swift +18 -0
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -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 +203 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +385 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -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/Navigation/component/HeaderRightWidthKey.swift +11 -0
- package/ios/Application/Navigation/component/NavigationHeaderRight.swift +196 -0
- package/ios/Application/Screen.swift +2 -1
- package/ios/Application/StackScreen.swift +501 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -14
- package/ios/Badge/BadgeRibbon.swift +91 -17
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +137 -28
- package/ios/Carousel/Carousel.swift +196 -0
- package/ios/Checkbox/Checkbox.swift +23 -28
- package/ios/Chip/Chip.swift +56 -33
- package/ios/Collapse/Collapse.swift +192 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +20 -17
- package/ios/Colors+Radius+Spacing/Spacing.swift +3 -1
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +212 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +165 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
- package/ios/Extensions/Color++.swift +32 -0
- package/ios/Icon/Icon.swift +10 -1
- package/ios/IconButton/IconButton.swift +140 -0
- package/ios/Image/Image.swift +16 -3
- package/ios/Information/Information.swift +3 -1
- package/ios/Input/ErrorView.swift +3 -1
- package/ios/Input/Input.swift +72 -33
- package/ios/Input/InputPhoneNumber.swift +33 -21
- package/ios/Input/InputSearch.swift +107 -48
- package/ios/Input/InputTextArea.swift +134 -64
- package/ios/InputDropDown/InputDropDown.swift +201 -0
- package/ios/InputMoney/InputMoney.swift +347 -0
- package/ios/InputOTP/InputOTP.swift +210 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/MoMoUIKits.podspec +5 -0
- 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 +11 -20
- package/ios/Popup/PopupInput.swift +2 -8
- package/ios/Popup/PopupNotify.swift +218 -0
- package/ios/Popup/PopupPromotion.swift +5 -3
- package/ios/ProgressInfo/ProgressInfo.swift +296 -0
- package/ios/Radio/Radio.swift +69 -0
- package/ios/Rating/Rating.swift +82 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -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 +467 -0
- package/ios/SuggestAction/SuggestAction.swift +99 -0
- package/ios/Swipeable/SwipeCell.swift +187 -0
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/Switch/Switch.swift +53 -28
- package/ios/TabView/TabView.swift +534 -0
- package/ios/Tag/Tag.swift +98 -0
- package/ios/Template/TrustBanner/TrustBanner.swift +7 -8
- package/ios/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +485 -0
- package/ios/Typography/FontScaleStore.swift +19 -0
- package/ios/Typography/Text.swift +86 -17
- package/ios/Typography/Typography.swift +12 -14
- package/ios/Uploader/Uploader.swift +174 -0
- package/ios/native-kits.podspec +61 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +20 -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 +24 -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 +64 -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 +279 -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/LocalizeDemo.swift +188 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +229 -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 +51 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/local.properties +2 -2
- package/package.json +1 -1
- package/publish.sh +53 -0
- package/scripts/gen-ios-color.mjs +136 -0
- package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
- package/ios/Application/FontScaleStore.swift +0 -59
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.border
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
4
5
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
6
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
5
7
|
import androidx.compose.runtime.Composable
|
|
6
8
|
import androidx.compose.runtime.getValue
|
|
7
9
|
import androidx.compose.runtime.mutableStateOf
|
|
@@ -17,10 +19,12 @@ import androidx.compose.ui.semantics.contentDescription
|
|
|
17
19
|
import androidx.compose.ui.semantics.semantics
|
|
18
20
|
import androidx.compose.ui.platform.LocalDensity
|
|
19
21
|
import androidx.compose.ui.unit.dp
|
|
20
|
-
import coil3.compose.AsyncImage
|
|
22
|
+
import coil3.compose.AsyncImage as CoilAsyncImage
|
|
21
23
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
22
24
|
import vn.momo.kits.const.AppTheme
|
|
23
25
|
import vn.momo.kits.const.Colors
|
|
26
|
+
import vn.momo.kits.gifimage.GifImage
|
|
27
|
+
import vn.momo.kits.gifimage.GifImageState
|
|
24
28
|
import vn.momo.kits.modifier.conditional
|
|
25
29
|
|
|
26
30
|
data class Options(
|
|
@@ -73,6 +77,19 @@ private fun getHostFromUrl(url: String): String? {
|
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
private fun isGifUrl(url: String): Boolean {
|
|
81
|
+
val path = url.substringBefore('#').substringBefore('?')
|
|
82
|
+
return path.endsWith(".gif", ignoreCase = true)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private fun GifImageState.toImageState(): ImageState {
|
|
86
|
+
return when (this) {
|
|
87
|
+
GifImageState.Success -> ImageState.Success
|
|
88
|
+
GifImageState.Error -> ImageState.Error
|
|
89
|
+
GifImageState.Loading -> ImageState.Loading
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
// Optimized query parameter appending
|
|
77
94
|
private fun appendSizeQueryParam(url: String, value: String): String {
|
|
78
95
|
val fragmentIndex = url.indexOf('#')
|
|
@@ -95,12 +112,12 @@ fun Image(
|
|
|
95
112
|
modifier: Modifier = Modifier,
|
|
96
113
|
options: Options? = null,
|
|
97
114
|
loading: Boolean = true,
|
|
115
|
+
onStateChanged: (ImageState) -> Unit = {},
|
|
98
116
|
) {
|
|
99
117
|
val imageOptions = remember(options) {
|
|
100
118
|
options ?: Options()
|
|
101
119
|
}
|
|
102
120
|
|
|
103
|
-
var imageState by remember { mutableStateOf(ImageState.Loading) }
|
|
104
121
|
val density = LocalDensity.current
|
|
105
122
|
|
|
106
123
|
BoxWithConstraints(
|
|
@@ -121,34 +138,46 @@ fun Image(
|
|
|
121
138
|
processedUrl
|
|
122
139
|
}
|
|
123
140
|
}
|
|
124
|
-
else -> source
|
|
141
|
+
else -> source.toString()
|
|
125
142
|
}
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
var imageState by remember(urlToLoad) { mutableStateOf(ImageState.Loading) }
|
|
146
|
+
fun updateImageState(state: ImageState) {
|
|
147
|
+
imageState = state
|
|
148
|
+
onStateChanged(state)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (isGifUrl(urlToLoad)) {
|
|
152
|
+
GifImage(
|
|
153
|
+
modifier = Modifier.matchParentSize(),
|
|
154
|
+
url = urlToLoad,
|
|
155
|
+
contentDescription = null,
|
|
156
|
+
contentScale = imageOptions.contentScale,
|
|
157
|
+
alignment = imageOptions.alignment,
|
|
158
|
+
colorFilter = imageOptions.colorFilter,
|
|
159
|
+
alpha = imageOptions.alpha,
|
|
160
|
+
onStateChanged = { updateImageState(it.toImageState()) },
|
|
161
|
+
)
|
|
162
|
+
} else {
|
|
163
|
+
CoilAsyncImage(
|
|
164
|
+
modifier = Modifier.matchParentSize(),
|
|
165
|
+
model = urlToLoad,
|
|
166
|
+
contentDescription = null,
|
|
167
|
+
contentScale = imageOptions.contentScale,
|
|
168
|
+
alignment = imageOptions.alignment,
|
|
169
|
+
colorFilter = imageOptions.colorFilter,
|
|
170
|
+
alpha = imageOptions.alpha,
|
|
171
|
+
onLoading = { updateImageState(ImageState.Loading) },
|
|
172
|
+
onSuccess = { updateImageState(ImageState.Success) },
|
|
173
|
+
onError = { updateImageState(ImageState.Error) },
|
|
174
|
+
)
|
|
175
|
+
}
|
|
140
176
|
|
|
141
177
|
when (imageState) {
|
|
142
|
-
ImageState.Loading -> if (loading) Skeleton()
|
|
143
|
-
ImageState.Error -> {
|
|
144
|
-
val theme = AppTheme.current
|
|
145
|
-
Icon(
|
|
146
|
-
source = "media_fail",
|
|
147
|
-
color = theme.colors.text.disable,
|
|
148
|
-
modifier = Modifier.align(Alignment.Center)
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
178
|
ImageState.Success -> {}
|
|
179
|
+
ImageState.Error -> ImageError()
|
|
180
|
+
ImageState.Loading -> if (loading) Skeleton()
|
|
152
181
|
}
|
|
153
182
|
}
|
|
154
183
|
}
|
|
@@ -156,7 +185,7 @@ fun Image(
|
|
|
156
185
|
// Extracted URL processing logic for better performance
|
|
157
186
|
private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
|
|
158
187
|
val host = getHostFromUrl(url)
|
|
159
|
-
return if (host != null && supportedDomains.contains(host)) {
|
|
188
|
+
return if (!isGifUrl(url) && host != null && supportedDomains.contains(host)) {
|
|
160
189
|
val widthPx = with(density) { maxWidth.roundToPx() }
|
|
161
190
|
val pixelRatio = density.density
|
|
162
191
|
val pixelFitForWidth = widthPx * pixelRatio
|
|
@@ -167,6 +196,20 @@ private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp,
|
|
|
167
196
|
}
|
|
168
197
|
}
|
|
169
198
|
|
|
199
|
+
@Composable
|
|
200
|
+
private fun ImageError() {
|
|
201
|
+
val theme = AppTheme.current
|
|
202
|
+
Box(
|
|
203
|
+
modifier = Modifier.fillMaxSize(),
|
|
204
|
+
contentAlignment = Alignment.Center
|
|
205
|
+
) {
|
|
206
|
+
Icon(
|
|
207
|
+
source = "media_fail",
|
|
208
|
+
color = theme.colors.text.disable,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
170
213
|
@Composable
|
|
171
214
|
fun Image(
|
|
172
215
|
source: Painter,
|
|
@@ -185,4 +228,4 @@ fun Image(
|
|
|
185
228
|
colorFilter = colorFilter,
|
|
186
229
|
alpha = alpha,
|
|
187
230
|
)
|
|
188
|
-
}
|
|
231
|
+
}
|
|
@@ -29,6 +29,7 @@ import androidx.compose.ui.Alignment
|
|
|
29
29
|
import androidx.compose.ui.Modifier
|
|
30
30
|
import androidx.compose.ui.focus.onFocusChanged
|
|
31
31
|
import androidx.compose.ui.graphics.Color
|
|
32
|
+
import androidx.compose.ui.graphics.takeOrElse
|
|
32
33
|
import androidx.compose.ui.text.TextStyle
|
|
33
34
|
import androidx.compose.ui.text.input.KeyboardType
|
|
34
35
|
import androidx.compose.ui.text.style.TextOverflow
|
|
@@ -49,7 +50,7 @@ import vn.momo.kits.utils.ifTrue
|
|
|
49
50
|
internal fun RenderRightIconSearch(
|
|
50
51
|
loading: Boolean,
|
|
51
52
|
icon: String,
|
|
52
|
-
color: Color
|
|
53
|
+
color: Color?,
|
|
53
54
|
onClick: () -> Unit,
|
|
54
55
|
iconModifier: Modifier = Modifier
|
|
55
56
|
) {
|
|
@@ -57,7 +58,7 @@ internal fun RenderRightIconSearch(
|
|
|
57
58
|
Box(Modifier.padding(horizontal = Spacing.S)) {
|
|
58
59
|
CircularProgressIndicator(
|
|
59
60
|
modifier = Modifier.size(16.dp),
|
|
60
|
-
color = color,
|
|
61
|
+
color = color ?: AppTheme.current.colors.text.default,
|
|
61
62
|
trackColor = Color.Transparent,
|
|
62
63
|
strokeWidth = 2.dp
|
|
63
64
|
)
|
|
@@ -90,7 +91,7 @@ data class InputSearchProps(
|
|
|
90
91
|
val onPressButtonText: () -> Unit = {},
|
|
91
92
|
val disabled: Boolean = false,
|
|
92
93
|
val icon: String = "",
|
|
93
|
-
val iconColor: Color = Color
|
|
94
|
+
val iconColor: Color? = Color.Unspecified,
|
|
94
95
|
val onRightIconPressed: () -> Unit = {},
|
|
95
96
|
val onFocus: () -> Unit = {},
|
|
96
97
|
val onBlur: () -> Unit = {},
|
|
@@ -113,7 +114,6 @@ data class InputSearchProps(
|
|
|
113
114
|
fun InputSearch(
|
|
114
115
|
inputSearchProps: InputSearchProps = InputSearchProps(
|
|
115
116
|
text = remember { mutableStateOf("") },
|
|
116
|
-
iconColor = AppTheme.current.colors.text.default
|
|
117
117
|
),
|
|
118
118
|
) {
|
|
119
119
|
var isFocused by remember { mutableStateOf(false) }
|
|
@@ -121,7 +121,7 @@ fun InputSearch(
|
|
|
121
121
|
val disabledColor = AppTheme.current.colors.text.disable
|
|
122
122
|
var textColor = AppTheme.current.colors.text.default
|
|
123
123
|
var placeholderColor = AppTheme.current.colors.text.hint
|
|
124
|
-
var iconTintColor = inputSearchProps.iconColor
|
|
124
|
+
var iconTintColor = inputSearchProps.iconColor?.takeOrElse { AppTheme.current.colors.text.default }
|
|
125
125
|
|
|
126
126
|
if (inputSearchProps.disabled) {
|
|
127
127
|
textColor = disabledColor
|
|
@@ -21,9 +21,11 @@ import androidx.compose.ui.unit.sp
|
|
|
21
21
|
import androidx.compose.ui.zIndex
|
|
22
22
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
23
23
|
import vn.momo.kits.const.*
|
|
24
|
+
import vn.momo.kits.modifier.InternalApi
|
|
24
25
|
import vn.momo.kits.modifier.conditional
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
@InternalApi
|
|
28
|
+
const val MAX_LENGTH = 300
|
|
27
29
|
internal val DEFAULT_HEIGHT = 104.dp
|
|
28
30
|
|
|
29
31
|
@Composable
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
5
|
+
import vn.momo.kits.application.ScaleSizeMaxRate
|
|
6
|
+
|
|
7
|
+
@Deprecated(
|
|
8
|
+
"Max font scale is fixed at MAX_FONT_SCALE (1.5); this override is no longer applied. Remove the wrapper.",
|
|
9
|
+
ReplaceWith("content()"),
|
|
10
|
+
)
|
|
11
|
+
@Composable
|
|
12
|
+
fun ScaleSizeScope(
|
|
13
|
+
scaleSizeMaxRate: Float? = null,
|
|
14
|
+
content: @Composable () -> Unit
|
|
15
|
+
) {
|
|
16
|
+
CompositionLocalProvider(
|
|
17
|
+
ScaleSizeMaxRate provides scaleSizeMaxRate,
|
|
18
|
+
) {
|
|
19
|
+
content()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -36,7 +36,6 @@ fun Text(
|
|
|
36
36
|
softWrap: Boolean = true,
|
|
37
37
|
accessibilityId: String? = null,
|
|
38
38
|
inlineContent: Map<String, InlineTextContent> = mapOf(),
|
|
39
|
-
userScaleRate: Float? = null,
|
|
40
39
|
) {
|
|
41
40
|
Text(
|
|
42
41
|
text = AnnotatedString(text),
|
|
@@ -53,8 +52,7 @@ fun Text(
|
|
|
53
52
|
letterSpacing = letterSpacing,
|
|
54
53
|
softWrap = softWrap,
|
|
55
54
|
accessibilityId = accessibilityId,
|
|
56
|
-
inlineContent = inlineContent
|
|
57
|
-
userScaleRate = userScaleRate
|
|
55
|
+
inlineContent = inlineContent
|
|
58
56
|
)
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -76,14 +74,13 @@ fun Text(
|
|
|
76
74
|
softWrap: Boolean = true,
|
|
77
75
|
accessibilityId: String? = null,
|
|
78
76
|
inlineContent: Map<String, InlineTextContent> = mapOf(),
|
|
79
|
-
userScaleRate: Float? = null,
|
|
80
77
|
) {
|
|
81
78
|
// Cache theme access to avoid repeated lookups
|
|
82
79
|
val theme = AppTheme.current
|
|
83
80
|
|
|
84
81
|
// Call @Composable functions directly in composable context
|
|
85
|
-
val scaledFontSize = scaleSize(style.fontSize
|
|
86
|
-
val scaledLineHeight = scaleSize(style.lineHeight
|
|
82
|
+
val scaledFontSize = scaleSize(style.fontSize)
|
|
83
|
+
val scaledLineHeight = scaleSize(style.lineHeight)
|
|
87
84
|
val fontFamilyResult = getFontFamily(fontFamily ?: theme.font, style.fontWeight)
|
|
88
85
|
|
|
89
86
|
// Now memoize the results
|
|
@@ -147,6 +147,17 @@ object Colors {
|
|
|
147
147
|
val red_10 = Color(0xFFFEF4F4)
|
|
148
148
|
val red_11 = Color(0xFFFEF8F8)
|
|
149
149
|
|
|
150
|
+
// Translucent overlays, ported from the React kit's Consts (the reference
|
|
151
|
+
// palette). React spells them `#RRGGBBAA`; Compose's Color takes `0xAARRGGBB`.
|
|
152
|
+
val opacity_black_20 = Color(0x33000000)
|
|
153
|
+
val opacity_black_40 = Color(0x66000000)
|
|
154
|
+
val opacity_black_60 = Color(0x99000000)
|
|
155
|
+
val opacity_black_80 = Color(0xCC000000)
|
|
156
|
+
val opacity_white_20 = Color(0x33FFFFFF)
|
|
157
|
+
val opacity_white_40 = Color(0x66FFFFFF)
|
|
158
|
+
val opacity_white_60 = Color(0x99FFFFFF)
|
|
159
|
+
val opacity_white_80 = Color(0xCCFFFFFF)
|
|
160
|
+
|
|
150
161
|
val colorList: Map<String, Color> = mapOf(
|
|
151
162
|
"black_01" to black_01,
|
|
152
163
|
"black_02" to black_02,
|
|
@@ -302,5 +313,13 @@ object Colors {
|
|
|
302
313
|
"red_09" to red_09,
|
|
303
314
|
"red_10" to red_10,
|
|
304
315
|
"red_11" to red_11,
|
|
316
|
+
"opacity_black_20" to opacity_black_20,
|
|
317
|
+
"opacity_black_40" to opacity_black_40,
|
|
318
|
+
"opacity_black_60" to opacity_black_60,
|
|
319
|
+
"opacity_black_80" to opacity_black_80,
|
|
320
|
+
"opacity_white_20" to opacity_white_20,
|
|
321
|
+
"opacity_white_40" to opacity_white_40,
|
|
322
|
+
"opacity_white_60" to opacity_white_60,
|
|
323
|
+
"opacity_white_80" to opacity_white_80,
|
|
305
324
|
)
|
|
306
325
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package vn.momo.kits.const
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.getValue
|
|
4
|
+
import androidx.compose.runtime.mutableStateOf
|
|
5
|
+
import androidx.compose.runtime.setValue
|
|
6
|
+
|
|
7
|
+
// App-wide font-scale holder. The kit is sandboxed and can't read the host cache directly, so the
|
|
8
|
+
// host (which sees both core and this kit) seeds this once at startup and pushes runtime updates into
|
|
9
|
+
// it. scaleSize() reads it as the fallback, so every screen — including direct NavigationContainer
|
|
10
|
+
// screens with no host-pushed MiniAppContext — scales with no per-render prop and no async flicker.
|
|
11
|
+
// Backed by snapshot state: writes recompose text automatically.
|
|
12
|
+
object KitFontScale {
|
|
13
|
+
var userScaleRate by mutableStateOf(1f)
|
|
14
|
+
private set
|
|
15
|
+
var useOSScaleRate by mutableStateOf(true)
|
|
16
|
+
private set
|
|
17
|
+
|
|
18
|
+
fun update(userScaleRate: Float, useOSScaleRate: Boolean) {
|
|
19
|
+
this.userScaleRate = userScaleRate
|
|
20
|
+
this.useOSScaleRate = useOSScaleRate
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -11,7 +11,7 @@ import androidx.compose.ui.unit.*
|
|
|
11
11
|
import org.jetbrains.compose.resources.Font
|
|
12
12
|
import org.jetbrains.compose.resources.FontResource
|
|
13
13
|
import org.jetbrains.compose.resources.InternalResourceApi
|
|
14
|
-
import vn.momo.kits.application.
|
|
14
|
+
import vn.momo.kits.application.LocalContext
|
|
15
15
|
import vn.momo.kits.platform.getScreenDimensions
|
|
16
16
|
import vn.momo.uikits.resources.*
|
|
17
17
|
import kotlin.math.max
|
|
@@ -22,58 +22,65 @@ const val MAX_FONT_SCALE = 1.5f
|
|
|
22
22
|
const val MAX_DEVICE_SCALE = 5
|
|
23
23
|
|
|
24
24
|
@Composable
|
|
25
|
-
fun scaleSize(size: Float
|
|
26
|
-
val
|
|
27
|
-
|
|
28
|
-
val
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
val fontScale = fontScaleConfig.osFontScale ?: LocalDensity.current.fontScale
|
|
32
|
-
|
|
33
|
-
if (!useOSFontScale) {
|
|
34
|
-
return if (customRate > 1f) customRate * size else size
|
|
25
|
+
fun scaleSize(size: Float): Float {
|
|
26
|
+
val context = LocalContext.current
|
|
27
|
+
// Host-pushed context wins; otherwise fall back to the app-wide KitFontScale holder.
|
|
28
|
+
val useOsScale = context?.useOSScaleRate ?: KitFontScale.useOSScaleRate
|
|
29
|
+
if (!useOsScale) {
|
|
30
|
+
return size * (context?.userScaleRate ?: KitFontScale.userScaleRate)
|
|
35
31
|
}
|
|
32
|
+
val scaleSizeMaxRate: Float = MAX_FONT_SCALE
|
|
33
|
+
val deviceWidth = getScreenDimensions().width
|
|
34
|
+
val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
|
|
35
|
+
|
|
36
|
+
val density = LocalDensity.current
|
|
37
|
+
val fontScale = density.fontScale
|
|
36
38
|
|
|
37
39
|
var fontSizeScaleDevice = size
|
|
38
40
|
var fontSizeScaleOS = size
|
|
41
|
+
|
|
39
42
|
if (deviceScale > 1) {
|
|
40
43
|
fontSizeScaleDevice =
|
|
41
44
|
min(deviceScale * fontSizeScaleDevice, fontSizeScaleDevice + MAX_DEVICE_SCALE)
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
|
|
47
|
+
if (fontScale > 1) {
|
|
48
|
+
fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * scaleSizeMaxRate)
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
return max(
|
|
51
|
+
return max(
|
|
52
|
+
fontSizeScaleDevice,
|
|
53
|
+
fontSizeScaleOS
|
|
54
|
+
)
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
@Composable
|
|
51
|
-
fun scaleSize(size: TextUnit
|
|
58
|
+
fun scaleSize(size: TextUnit): TextUnit {
|
|
52
59
|
if (!size.isSp) return size
|
|
53
60
|
|
|
54
61
|
val density = LocalDensity.current
|
|
55
62
|
|
|
56
|
-
val scaled = scaleSize(size.value
|
|
63
|
+
val scaled = scaleSize(size.value)
|
|
57
64
|
val spValue = scaled / density.fontScale
|
|
58
65
|
|
|
59
66
|
return TextUnit(value = spValue, type = TextUnitType.Sp)
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
@Composable
|
|
63
|
-
fun scaleSize(size: Dp
|
|
64
|
-
return scaleSize(size.value
|
|
70
|
+
fun scaleSize(size: Dp): Dp {
|
|
71
|
+
return scaleSize(size.value).dp
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
@Composable
|
|
68
|
-
fun scaleSize(textStyle: TextStyle
|
|
75
|
+
fun scaleSize(textStyle: TextStyle): TextStyle {
|
|
69
76
|
return textStyle.copy(
|
|
70
77
|
fontSize = if (textStyle.fontSize != TextUnit.Unspecified)
|
|
71
|
-
scaleSize(textStyle.fontSize
|
|
78
|
+
scaleSize(textStyle.fontSize)
|
|
72
79
|
else
|
|
73
80
|
TextUnit.Unspecified,
|
|
74
81
|
|
|
75
82
|
lineHeight = if (textStyle.lineHeight != TextUnit.Unspecified)
|
|
76
|
-
scaleSize(textStyle.lineHeight
|
|
83
|
+
scaleSize(textStyle.lineHeight)
|
|
77
84
|
else
|
|
78
85
|
TextUnit.Unspecified,
|
|
79
86
|
)
|
|
@@ -1,2 +1,52 @@
|
|
|
1
1
|
package vn.momo.kits.layout
|
|
2
2
|
|
|
3
|
+
import androidx.compose.foundation.background
|
|
4
|
+
import androidx.compose.foundation.layout.Arrangement
|
|
5
|
+
import androidx.compose.foundation.layout.Box
|
|
6
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
7
|
+
import androidx.compose.foundation.layout.FlowRow
|
|
8
|
+
import androidx.compose.foundation.layout.PaddingValues
|
|
9
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
10
|
+
import androidx.compose.foundation.layout.padding
|
|
11
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
12
|
+
import androidx.compose.runtime.Composable
|
|
13
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
14
|
+
import androidx.compose.ui.Modifier
|
|
15
|
+
import androidx.compose.ui.draw.clip
|
|
16
|
+
import androidx.compose.ui.draw.shadow
|
|
17
|
+
import androidx.compose.ui.unit.dp
|
|
18
|
+
import vn.momo.kits.components.Image
|
|
19
|
+
import vn.momo.kits.const.AppTheme
|
|
20
|
+
import vn.momo.kits.const.Radius
|
|
21
|
+
import vn.momo.kits.const.Spacing
|
|
22
|
+
|
|
23
|
+
@Composable
|
|
24
|
+
internal fun Card(
|
|
25
|
+
useShadow: Boolean = false,
|
|
26
|
+
backgroundImage: String? = null,
|
|
27
|
+
contentPadding: PaddingValues = PaddingValues(Spacing.M),
|
|
28
|
+
modifier: Modifier = Modifier,
|
|
29
|
+
content: @Composable () -> Unit,
|
|
30
|
+
) {
|
|
31
|
+
val columns = 12
|
|
32
|
+
val gutter = 8.dp
|
|
33
|
+
val shape = RoundedCornerShape(Radius.M)
|
|
34
|
+
var surface = modifier.fillMaxWidth().padding(horizontal = 12.dp)
|
|
35
|
+
if (useShadow) surface = surface.shadow(4.dp, shape)
|
|
36
|
+
surface = surface.clip(shape)
|
|
37
|
+
if (backgroundImage == null) surface = surface.background(AppTheme.current.colors.background.surface)
|
|
38
|
+
Box(modifier = surface) {
|
|
39
|
+
if (backgroundImage != null) {
|
|
40
|
+
Image(source = backgroundImage, modifier = Modifier.matchParentSize())
|
|
41
|
+
}
|
|
42
|
+
BoxWithConstraints(modifier = Modifier.fillMaxWidth().padding(contentPadding)) {
|
|
43
|
+
val sizePerSpan = (maxWidth - gutter * (columns - 1)) / columns - 1.dp / columns
|
|
44
|
+
CompositionLocalProvider(LocalGridContext provides GridContext(columns, gutter, sizePerSpan)) {
|
|
45
|
+
FlowRow(
|
|
46
|
+
horizontalArrangement = Arrangement.spacedBy(gutter),
|
|
47
|
+
verticalArrangement = Arrangement.spacedBy(gutter),
|
|
48
|
+
) { content() }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
package vn.momo.kits.layout
|
|
2
2
|
|
|
3
|
-
import androidx.compose.foundation.layout.
|
|
3
|
+
import androidx.compose.foundation.layout.Column
|
|
4
4
|
import androidx.compose.foundation.layout.height
|
|
5
5
|
import androidx.compose.foundation.layout.width
|
|
6
6
|
import androidx.compose.runtime.Composable
|
|
7
|
+
import androidx.compose.runtime.compositionLocalOf
|
|
7
8
|
import androidx.compose.ui.Modifier
|
|
8
9
|
import androidx.compose.ui.unit.Dp
|
|
10
|
+
import androidx.compose.ui.unit.dp
|
|
9
11
|
|
|
10
|
-
data class GridContext(
|
|
11
|
-
val numberOfColumns:
|
|
12
|
-
val
|
|
13
|
-
val sizePerSpan:
|
|
14
|
-
|
|
15
|
-
)
|
|
12
|
+
internal data class GridContext(
|
|
13
|
+
val numberOfColumns: Int = 12,
|
|
14
|
+
val gutter: Dp = 12.dp,
|
|
15
|
+
val sizePerSpan: Dp = 0.dp,
|
|
16
|
+
) {
|
|
17
|
+
fun sizeForSpan(span: Int): Dp = sizePerSpan * span + gutter * (span - 1)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
internal val LocalGridContext = compositionLocalOf<GridContext?> { null }
|
|
16
21
|
|
|
17
22
|
@Composable
|
|
18
|
-
fun Item(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
content: @Composable () -> Unit,
|
|
23
|
+
internal fun Item(
|
|
24
|
+
widthSpan: Int = 12,
|
|
25
|
+
heightSpan: Int = 0,
|
|
22
26
|
modifier: Modifier = Modifier,
|
|
23
|
-
|
|
27
|
+
content: @Composable () -> Unit,
|
|
24
28
|
) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
modifier = modifier.width(width = Dp(widthItem.toFloat()))
|
|
31
|
-
.height(height = Dp(heightItem.toFloat()))
|
|
32
|
-
) {
|
|
33
|
-
content()
|
|
29
|
+
val grid = LocalGridContext.current
|
|
30
|
+
var m = modifier
|
|
31
|
+
if (grid != null) {
|
|
32
|
+
m = m.width(grid.sizeForSpan(widthSpan))
|
|
33
|
+
if (heightSpan > 0) m = m.height(grid.sizeForSpan(heightSpan))
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
// A Column (not a Box) so multiple children flow VERTICALLY instead of stacking
|
|
36
|
+
// on top of each other — matches the React Item's flex-column content.
|
|
37
|
+
Column(modifier = m) { content() }
|
|
38
|
+
}
|
|
@@ -1,2 +1,39 @@
|
|
|
1
1
|
package vn.momo.kits.layout
|
|
2
2
|
|
|
3
|
+
import androidx.compose.foundation.layout.Arrangement
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
5
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
6
|
+
import androidx.compose.foundation.layout.FlowRow
|
|
7
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
8
|
+
import androidx.compose.foundation.layout.padding
|
|
9
|
+
import androidx.compose.runtime.Composable
|
|
10
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
11
|
+
import androidx.compose.ui.Modifier
|
|
12
|
+
import androidx.compose.ui.unit.dp
|
|
13
|
+
import vn.momo.kits.components.Image
|
|
14
|
+
|
|
15
|
+
@Composable
|
|
16
|
+
internal fun Section(
|
|
17
|
+
useMargin: Boolean = true,
|
|
18
|
+
backgroundImage: String? = null,
|
|
19
|
+
modifier: Modifier = Modifier,
|
|
20
|
+
content: @Composable () -> Unit,
|
|
21
|
+
) {
|
|
22
|
+
val columns = 12
|
|
23
|
+
val gutter = 12.dp
|
|
24
|
+
val margin = if (useMargin) 12.dp else 0.dp
|
|
25
|
+
Box(modifier = modifier.fillMaxWidth().padding(horizontal = margin)) {
|
|
26
|
+
if (backgroundImage != null) {
|
|
27
|
+
Image(source = backgroundImage, modifier = Modifier.matchParentSize())
|
|
28
|
+
}
|
|
29
|
+
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
|
|
30
|
+
val sizePerSpan = (maxWidth - gutter * (columns - 1)) / columns - 1.dp / columns
|
|
31
|
+
CompositionLocalProvider(LocalGridContext provides GridContext(columns, gutter, sizePerSpan)) {
|
|
32
|
+
FlowRow(
|
|
33
|
+
horizontalArrangement = Arrangement.spacedBy(gutter),
|
|
34
|
+
verticalArrangement = Arrangement.spacedBy(gutter),
|
|
35
|
+
) { content() }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|