@momo-kits/native-kits 0.157.2-debug → 0.157.2
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/package.json +1 -1
- package/build.gradle.kts +0 -11
- package/compose/build.gradle.kts +0 -180
- package/compose/build.gradle.kts.backup +0 -180
- package/compose/compose.podspec +0 -54
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -110
- 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 +0 -57
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -107
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -305
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -720
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -121
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -405
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -85
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -340
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -198
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -357
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -94
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -136
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -148
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -188
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -116
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -448
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -172
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -255
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -231
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -233
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -254
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -241
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -92
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -352
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -103
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -70
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -96
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -96
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -92
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -130
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -214
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -576
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -177
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -205
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -239
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -185
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -285
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -59
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -14
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -50
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -239
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -119
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -98
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -161
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -331
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -497
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -162
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -243
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -187
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -279
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -370
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -132
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -42
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -62
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -88
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -149
- package/gradle/libs.versions.toml +0 -57
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +0 -8
- package/gradle.properties +0 -26
- package/gradlew +0 -252
- package/gradlew.bat +0 -94
- package/settings.gradle.kts +0 -52
|
@@ -1,576 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.components
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.Canvas
|
|
4
|
-
import androidx.compose.foundation.background
|
|
5
|
-
import androidx.compose.foundation.border
|
|
6
|
-
import androidx.compose.foundation.clickable
|
|
7
|
-
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
8
|
-
import androidx.compose.foundation.layout.Arrangement
|
|
9
|
-
import androidx.compose.foundation.layout.Box
|
|
10
|
-
import androidx.compose.foundation.layout.Column
|
|
11
|
-
import androidx.compose.foundation.layout.Row
|
|
12
|
-
import androidx.compose.foundation.layout.Spacer
|
|
13
|
-
import androidx.compose.foundation.layout.offset
|
|
14
|
-
import androidx.compose.foundation.layout.padding
|
|
15
|
-
import androidx.compose.foundation.layout.size
|
|
16
|
-
import androidx.compose.foundation.layout.width
|
|
17
|
-
import androidx.compose.foundation.layout.widthIn
|
|
18
|
-
import androidx.compose.foundation.layout.wrapContentSize
|
|
19
|
-
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
20
|
-
import androidx.compose.runtime.Composable
|
|
21
|
-
import androidx.compose.runtime.LaunchedEffect
|
|
22
|
-
import androidx.compose.runtime.Stable
|
|
23
|
-
import androidx.compose.runtime.getValue
|
|
24
|
-
import androidx.compose.runtime.mutableStateOf
|
|
25
|
-
import androidx.compose.runtime.remember
|
|
26
|
-
import androidx.compose.runtime.setValue
|
|
27
|
-
import androidx.compose.ui.Alignment
|
|
28
|
-
import androidx.compose.ui.Modifier
|
|
29
|
-
import androidx.compose.ui.draw.clip
|
|
30
|
-
import androidx.compose.ui.graphics.Paint
|
|
31
|
-
import androidx.compose.ui.graphics.Path
|
|
32
|
-
import androidx.compose.ui.graphics.PathEffect
|
|
33
|
-
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
|
34
|
-
import androidx.compose.ui.platform.LocalDensity
|
|
35
|
-
import androidx.compose.ui.text.style.TextOverflow
|
|
36
|
-
import androidx.compose.ui.unit.IntOffset
|
|
37
|
-
import androidx.compose.ui.unit.IntRect
|
|
38
|
-
import androidx.compose.ui.unit.IntSize
|
|
39
|
-
import androidx.compose.ui.unit.LayoutDirection
|
|
40
|
-
import androidx.compose.ui.unit.dp
|
|
41
|
-
import androidx.compose.ui.window.Popup
|
|
42
|
-
import androidx.compose.ui.window.PopupPositionProvider
|
|
43
|
-
import androidx.compose.ui.window.PopupProperties
|
|
44
|
-
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
45
|
-
import vn.momo.kits.const.Colors
|
|
46
|
-
import vn.momo.kits.const.Radius
|
|
47
|
-
import vn.momo.kits.const.Spacing
|
|
48
|
-
import vn.momo.kits.const.Typography
|
|
49
|
-
import vn.momo.kits.const.scaleSize
|
|
50
|
-
import vn.momo.kits.modifier.activeOpacityClickable
|
|
51
|
-
import vn.momo.kits.modifier.conditional
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// region Types
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Tooltip placement relative to the anchor element.
|
|
58
|
-
*/
|
|
59
|
-
enum class TooltipPlacement {
|
|
60
|
-
TOP,
|
|
61
|
-
BOTTOM,
|
|
62
|
-
LEFT,
|
|
63
|
-
RIGHT,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Cross-axis alignment of the tooltip relative to the anchor.
|
|
68
|
-
*/
|
|
69
|
-
enum class TooltipAlign {
|
|
70
|
-
START,
|
|
71
|
-
CENTER,
|
|
72
|
-
END,
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Describes a single action button displayed in the tooltip.
|
|
77
|
-
*
|
|
78
|
-
* @param title Text label for the button (used for text buttons).
|
|
79
|
-
* @param icon Icon source for the button (used for icon buttons).
|
|
80
|
-
* @param onPress Callback invoked when the button is pressed.
|
|
81
|
-
*/
|
|
82
|
-
data class TooltipButton(
|
|
83
|
-
val title: String? = null,
|
|
84
|
-
val icon: String? = null,
|
|
85
|
-
val onPress: (() -> Unit)? = null,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* State holder for controlling tooltip visibility imperatively.
|
|
91
|
-
* Equivalent to the React Native `useImperativeHandle` ref pattern.
|
|
92
|
-
*/
|
|
93
|
-
@Stable
|
|
94
|
-
class TooltipState {
|
|
95
|
-
var isVisible by mutableStateOf(false)
|
|
96
|
-
private set
|
|
97
|
-
|
|
98
|
-
/** Shows the tooltip. */
|
|
99
|
-
fun show() {
|
|
100
|
-
isVisible = true
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Hides the tooltip. */
|
|
104
|
-
fun hide() {
|
|
105
|
-
isVisible = false
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Toggles the tooltip visibility. */
|
|
109
|
-
fun toggle() {
|
|
110
|
-
isVisible = !isVisible
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Creates and remembers a [TooltipState].
|
|
116
|
-
*/
|
|
117
|
-
@Composable
|
|
118
|
-
fun rememberTooltipState(): TooltipState {
|
|
119
|
-
return remember { TooltipState() }
|
|
120
|
-
}
|
|
121
|
-
private val TOOLTIP_OFFSET = Spacing.S
|
|
122
|
-
private val ARROW_SIZE = 6.dp
|
|
123
|
-
/**
|
|
124
|
-
* Custom [PopupPositionProvider] that positions the tooltip relative to the anchor.
|
|
125
|
-
*
|
|
126
|
-
* Mirrors the React Native `placementStyle` calculation:
|
|
127
|
-
* - TOP: tooltip bottom edge sits at `anchorTop - TOOLTIP_OFFSET`
|
|
128
|
-
* - BOTTOM: tooltip top edge sits at `anchorBottom + TOOLTIP_OFFSET`
|
|
129
|
-
* - LEFT: tooltip right edge sits at `anchorLeft - TOOLTIP_OFFSET`
|
|
130
|
-
* - RIGHT: tooltip left edge sits at `anchorRight + TOOLTIP_OFFSET`
|
|
131
|
-
*
|
|
132
|
-
* Cross-axis alignment:
|
|
133
|
-
* - start: tooltip aligns to anchor start edge
|
|
134
|
-
* - center: tooltip centers on anchor
|
|
135
|
-
* - end: tooltip aligns to anchor end edge
|
|
136
|
-
*/
|
|
137
|
-
private class TooltipPositionProvider(
|
|
138
|
-
private val placement: TooltipPlacement,
|
|
139
|
-
private val align: TooltipAlign,
|
|
140
|
-
private val offsetPx: Int,
|
|
141
|
-
) : PopupPositionProvider {
|
|
142
|
-
|
|
143
|
-
override fun calculatePosition(
|
|
144
|
-
anchorBounds: IntRect,
|
|
145
|
-
windowSize: IntSize,
|
|
146
|
-
layoutDirection: LayoutDirection,
|
|
147
|
-
popupContentSize: IntSize,
|
|
148
|
-
): IntOffset {
|
|
149
|
-
val anchorX = anchorBounds.left
|
|
150
|
-
val anchorY = anchorBounds.top
|
|
151
|
-
val anchorW = anchorBounds.width
|
|
152
|
-
val anchorH = anchorBounds.height
|
|
153
|
-
val popW = popupContentSize.width
|
|
154
|
-
val popH = popupContentSize.height
|
|
155
|
-
|
|
156
|
-
var x: Int
|
|
157
|
-
var y: Int
|
|
158
|
-
|
|
159
|
-
when (placement) {
|
|
160
|
-
TooltipPlacement.TOP -> {
|
|
161
|
-
y = anchorY - popH - offsetPx
|
|
162
|
-
x = alignHorizontal(anchorX, anchorW, popW)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
TooltipPlacement.BOTTOM -> {
|
|
166
|
-
y = anchorY + anchorH + offsetPx
|
|
167
|
-
x = alignHorizontal(anchorX, anchorW, popW)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
TooltipPlacement.LEFT -> {
|
|
171
|
-
x = anchorX - popW - offsetPx
|
|
172
|
-
y = alignVertical(anchorY, anchorH, popH)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
TooltipPlacement.RIGHT -> {
|
|
176
|
-
x = anchorX + anchorW + offsetPx
|
|
177
|
-
y = alignVertical(anchorY, anchorH, popH)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return IntOffset(x, y)
|
|
182
|
-
}
|
|
183
|
-
private fun alignHorizontal(anchorX: Int, anchorW: Int, popW: Int): Int {
|
|
184
|
-
return when (align) {
|
|
185
|
-
TooltipAlign.START -> anchorX
|
|
186
|
-
TooltipAlign.END -> anchorX + anchorW - popW
|
|
187
|
-
TooltipAlign.CENTER -> anchorX + (anchorW - popW) / 2
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
private fun alignVertical(anchorY: Int, anchorH: Int, popH: Int): Int {
|
|
191
|
-
return when (align) {
|
|
192
|
-
TooltipAlign.START -> anchorY
|
|
193
|
-
TooltipAlign.END -> anchorY + anchorH - popH
|
|
194
|
-
TooltipAlign.CENTER -> anchorY + (anchorH - popH) / 2
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// endregion
|
|
200
|
-
|
|
201
|
-
// region Tooltip Composable
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* A tooltip component that wraps [content] (the anchor) and shows a positioned
|
|
205
|
-
* tooltip popup with title, description, close button, and action buttons.
|
|
206
|
-
*
|
|
207
|
-
* Port of the React Native `Tooltip` component.
|
|
208
|
-
*
|
|
209
|
-
* @param state Controls visibility (use [rememberTooltipState]).
|
|
210
|
-
* @param title Title text displayed in the tooltip header.
|
|
211
|
-
* @param description Description text shown under the title.
|
|
212
|
-
* @param buttons Action buttons rendered at the bottom.
|
|
213
|
-
* @param placement Tooltip position relative to the anchor (default TOP).
|
|
214
|
-
* @param align Cross-axis alignment (default CENTER).
|
|
215
|
-
* @param onVisibleChange Callback when visibility changes.
|
|
216
|
-
* @param onPressClose Callback when the close button (X) is pressed.
|
|
217
|
-
* @param modifier Modifier for the anchor wrapper.
|
|
218
|
-
* @param content The anchor element that the tooltip is attached to.
|
|
219
|
-
*/
|
|
220
|
-
@Composable
|
|
221
|
-
fun Tooltip(
|
|
222
|
-
state: TooltipState,
|
|
223
|
-
title: String? = null,
|
|
224
|
-
description: String? = null,
|
|
225
|
-
buttons: List<TooltipButton> = emptyList(),
|
|
226
|
-
placement: TooltipPlacement = TooltipPlacement.TOP,
|
|
227
|
-
align: TooltipAlign = TooltipAlign.CENTER,
|
|
228
|
-
onVisibleChange: ((Boolean) -> Unit)? = null,
|
|
229
|
-
onPressClose: (() -> Unit)? = null,
|
|
230
|
-
modifier: Modifier = Modifier,
|
|
231
|
-
content: @Composable () -> Unit,
|
|
232
|
-
) {
|
|
233
|
-
val density = LocalDensity.current
|
|
234
|
-
val offsetPx = with(density) { (TOOLTIP_OFFSET + ARROW_SIZE).roundToPx() }
|
|
235
|
-
|
|
236
|
-
LaunchedEffect(state.isVisible) {
|
|
237
|
-
onVisibleChange?.invoke(state.isVisible)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
Box(modifier = modifier) {
|
|
241
|
-
content()
|
|
242
|
-
|
|
243
|
-
if (state.isVisible) {
|
|
244
|
-
val positionProvider = remember(placement, align, offsetPx) {
|
|
245
|
-
TooltipPositionProvider(
|
|
246
|
-
placement = placement,
|
|
247
|
-
align = align,
|
|
248
|
-
offsetPx = offsetPx,
|
|
249
|
-
)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
Popup(
|
|
253
|
-
popupPositionProvider = positionProvider,
|
|
254
|
-
onDismissRequest = { state.hide() },
|
|
255
|
-
properties = PopupProperties(clippingEnabled = false),
|
|
256
|
-
) {
|
|
257
|
-
TooltipPopupContent(
|
|
258
|
-
title = title,
|
|
259
|
-
description = description,
|
|
260
|
-
buttons = buttons,
|
|
261
|
-
placement = placement,
|
|
262
|
-
align = align,
|
|
263
|
-
onPressClose = onPressClose,
|
|
264
|
-
)
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
@Composable
|
|
270
|
-
private fun TooltipPopupContent(
|
|
271
|
-
title: String?,
|
|
272
|
-
description: String?,
|
|
273
|
-
buttons: List<TooltipButton>,
|
|
274
|
-
placement: TooltipPlacement,
|
|
275
|
-
align: TooltipAlign,
|
|
276
|
-
onPressClose: (() -> Unit)? = null,
|
|
277
|
-
) {
|
|
278
|
-
val tooltipMaxWidth = 300.dp
|
|
279
|
-
val tooltipShape = remember { RoundedCornerShape(Radius.S) }
|
|
280
|
-
|
|
281
|
-
Box(modifier = Modifier.wrapContentSize()) {
|
|
282
|
-
Column(
|
|
283
|
-
modifier = Modifier
|
|
284
|
-
.widthIn(max = tooltipMaxWidth)
|
|
285
|
-
.background(Colors.black_17, tooltipShape)
|
|
286
|
-
.clip(tooltipShape)
|
|
287
|
-
.conditional(IsShowBaseLineDebug) {
|
|
288
|
-
border(1.dp, Colors.blue_03)
|
|
289
|
-
}
|
|
290
|
-
.padding(Spacing.M)
|
|
291
|
-
) {
|
|
292
|
-
Row {
|
|
293
|
-
Column(modifier = Modifier.weight(1f, fill = false)) {
|
|
294
|
-
if (!title.isNullOrEmpty()) {
|
|
295
|
-
Text(
|
|
296
|
-
text = title,
|
|
297
|
-
style = Typography.headerSSemibold,
|
|
298
|
-
color = Colors.black_01,
|
|
299
|
-
maxLines = 1,
|
|
300
|
-
modifier = Modifier.padding(bottom = Spacing.XS),
|
|
301
|
-
overflow = TextOverflow.Ellipsis,
|
|
302
|
-
)
|
|
303
|
-
}
|
|
304
|
-
if (!description.isNullOrEmpty()) {
|
|
305
|
-
Text(
|
|
306
|
-
text = description,
|
|
307
|
-
style = Typography.descriptionDefaultRegular,
|
|
308
|
-
color = Colors.black_01,
|
|
309
|
-
maxLines = 2,
|
|
310
|
-
modifier = Modifier.padding(bottom = Spacing.M),
|
|
311
|
-
overflow = TextOverflow.Ellipsis,
|
|
312
|
-
)
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (onPressClose != null) {
|
|
316
|
-
Spacer(Modifier.width(Spacing.M))
|
|
317
|
-
Box(
|
|
318
|
-
modifier = Modifier
|
|
319
|
-
.size(20.dp)
|
|
320
|
-
.activeOpacityClickable {
|
|
321
|
-
onPressClose.invoke()
|
|
322
|
-
}
|
|
323
|
-
) {
|
|
324
|
-
Icon(
|
|
325
|
-
source = "navigation_close",
|
|
326
|
-
size = 20.dp,
|
|
327
|
-
color = Colors.black_01,
|
|
328
|
-
)
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
if (buttons.isNotEmpty()) {
|
|
333
|
-
TooltipButtons(
|
|
334
|
-
buttons = buttons,
|
|
335
|
-
modifier = Modifier.align(Alignment.End),
|
|
336
|
-
)
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
TooltipArrow(
|
|
341
|
-
placement = placement,
|
|
342
|
-
align = align,
|
|
343
|
-
modifier = Modifier.matchParentSize(),
|
|
344
|
-
)
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
@Composable
|
|
348
|
-
private fun TooltipArrow(
|
|
349
|
-
placement: TooltipPlacement,
|
|
350
|
-
align: TooltipAlign,
|
|
351
|
-
modifier: Modifier = Modifier,
|
|
352
|
-
) {
|
|
353
|
-
val arrowWidth = ARROW_SIZE * 2
|
|
354
|
-
val arrowHeight = ARROW_SIZE
|
|
355
|
-
val arrowEdgeMargin = Spacing.M
|
|
356
|
-
|
|
357
|
-
val boxAlignment = when (placement) {
|
|
358
|
-
TooltipPlacement.TOP -> when (align) {
|
|
359
|
-
TooltipAlign.START -> Alignment.BottomStart
|
|
360
|
-
TooltipAlign.CENTER -> Alignment.BottomCenter
|
|
361
|
-
TooltipAlign.END -> Alignment.BottomEnd
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
TooltipPlacement.BOTTOM -> when (align) {
|
|
365
|
-
TooltipAlign.START -> Alignment.TopStart
|
|
366
|
-
TooltipAlign.CENTER -> Alignment.TopCenter
|
|
367
|
-
TooltipAlign.END -> Alignment.TopEnd
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
TooltipPlacement.LEFT -> when (align) {
|
|
371
|
-
TooltipAlign.START -> Alignment.TopEnd
|
|
372
|
-
TooltipAlign.CENTER -> Alignment.CenterEnd
|
|
373
|
-
TooltipAlign.END -> Alignment.BottomEnd
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
TooltipPlacement.RIGHT -> when (align) {
|
|
377
|
-
TooltipAlign.START -> Alignment.TopStart
|
|
378
|
-
TooltipAlign.CENTER -> Alignment.CenterStart
|
|
379
|
-
TooltipAlign.END -> Alignment.BottomStart
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
val canvasWidth = when (placement) {
|
|
384
|
-
TooltipPlacement.TOP, TooltipPlacement.BOTTOM -> arrowWidth
|
|
385
|
-
TooltipPlacement.LEFT, TooltipPlacement.RIGHT -> arrowHeight
|
|
386
|
-
}
|
|
387
|
-
val canvasHeight = when (placement) {
|
|
388
|
-
TooltipPlacement.TOP, TooltipPlacement.BOTTOM -> arrowHeight
|
|
389
|
-
TooltipPlacement.LEFT, TooltipPlacement.RIGHT -> arrowWidth
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
val arrowOverlap = 1.dp
|
|
393
|
-
val offsetX = when (placement) {
|
|
394
|
-
TooltipPlacement.LEFT -> arrowHeight - arrowOverlap
|
|
395
|
-
TooltipPlacement.RIGHT -> -arrowHeight + arrowOverlap
|
|
396
|
-
else -> when (align) {
|
|
397
|
-
TooltipAlign.START -> arrowEdgeMargin
|
|
398
|
-
TooltipAlign.END -> -arrowEdgeMargin
|
|
399
|
-
TooltipAlign.CENTER -> 0.dp
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
val offsetY = when (placement) {
|
|
403
|
-
TooltipPlacement.TOP -> arrowHeight - arrowOverlap
|
|
404
|
-
TooltipPlacement.BOTTOM -> -arrowHeight + arrowOverlap
|
|
405
|
-
else -> when (align) {
|
|
406
|
-
TooltipAlign.START -> arrowEdgeMargin
|
|
407
|
-
TooltipAlign.END -> -arrowEdgeMargin
|
|
408
|
-
TooltipAlign.CENTER -> 0.dp
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
val arrowColor = Colors.black_17
|
|
413
|
-
|
|
414
|
-
Box(modifier = modifier) {
|
|
415
|
-
Canvas(
|
|
416
|
-
modifier = Modifier
|
|
417
|
-
.align(boxAlignment)
|
|
418
|
-
.offset(x = offsetX, y = offsetY)
|
|
419
|
-
.size(width = canvasWidth, height = canvasHeight)
|
|
420
|
-
) {
|
|
421
|
-
val w = size.width
|
|
422
|
-
val h = size.height
|
|
423
|
-
val path = Path().apply {
|
|
424
|
-
when (placement) {
|
|
425
|
-
TooltipPlacement.TOP -> {
|
|
426
|
-
moveTo(0f, 0f)
|
|
427
|
-
lineTo(w, 0f)
|
|
428
|
-
lineTo(w / 2f, h)
|
|
429
|
-
close()
|
|
430
|
-
}
|
|
431
|
-
TooltipPlacement.BOTTOM -> {
|
|
432
|
-
moveTo(0f, h)
|
|
433
|
-
lineTo(w, h)
|
|
434
|
-
lineTo(w / 2f, 0f)
|
|
435
|
-
close()
|
|
436
|
-
}
|
|
437
|
-
TooltipPlacement.LEFT -> {
|
|
438
|
-
moveTo(0f, 0f)
|
|
439
|
-
lineTo(0f, h)
|
|
440
|
-
lineTo(w, h / 2f)
|
|
441
|
-
close()
|
|
442
|
-
}
|
|
443
|
-
TooltipPlacement.RIGHT -> {
|
|
444
|
-
moveTo(w, 0f)
|
|
445
|
-
lineTo(w, h)
|
|
446
|
-
lineTo(0f, h / 2f)
|
|
447
|
-
close()
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
drawIntoCanvas { canvas ->
|
|
452
|
-
val paint = Paint().apply {
|
|
453
|
-
color = arrowColor
|
|
454
|
-
pathEffect = PathEffect.cornerPathEffect(2.dp.toPx())
|
|
455
|
-
}
|
|
456
|
-
canvas.drawPath(path, paint)
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
@Composable
|
|
462
|
-
private fun TooltipButtons(buttons: List<TooltipButton>, modifier: Modifier = Modifier) {
|
|
463
|
-
Row(
|
|
464
|
-
modifier = modifier,
|
|
465
|
-
horizontalArrangement = Arrangement.End,
|
|
466
|
-
verticalAlignment = Alignment.CenterVertically,
|
|
467
|
-
) {
|
|
468
|
-
|
|
469
|
-
if (buttons.size == 1) {
|
|
470
|
-
val btn = buttons[0]
|
|
471
|
-
TooltipSingleButton(btn)
|
|
472
|
-
} else if (buttons.size == 2) {
|
|
473
|
-
val primary = buttons[0]
|
|
474
|
-
val secondary = buttons[1]
|
|
475
|
-
val bothIcons = primary.icon != null && secondary.icon != null
|
|
476
|
-
|
|
477
|
-
if (bothIcons) {
|
|
478
|
-
TooltipIconButton(
|
|
479
|
-
icon = secondary.icon,
|
|
480
|
-
onPress = secondary.onPress ?: {},
|
|
481
|
-
)
|
|
482
|
-
Spacer(modifier = Modifier.width(Spacing.S))
|
|
483
|
-
TooltipIconButton(
|
|
484
|
-
icon = primary.icon,
|
|
485
|
-
onPress = primary.onPress ?: {},
|
|
486
|
-
)
|
|
487
|
-
} else {
|
|
488
|
-
TooltipSecondaryButton(
|
|
489
|
-
title = secondary.title ?: "",
|
|
490
|
-
onPress = secondary.onPress ?: {},
|
|
491
|
-
)
|
|
492
|
-
Spacer(modifier = Modifier.width(Spacing.S))
|
|
493
|
-
TooltipPrimaryButton(
|
|
494
|
-
title = primary.title ?: "",
|
|
495
|
-
onPress = primary.onPress ?: {},
|
|
496
|
-
)
|
|
497
|
-
}
|
|
498
|
-
} else {
|
|
499
|
-
buttons.forEachIndexed { index, btn ->
|
|
500
|
-
if (index > 0) {
|
|
501
|
-
Spacer(modifier = Modifier.width(Spacing.XXS))
|
|
502
|
-
}
|
|
503
|
-
TooltipSingleButton(btn)
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
@Composable
|
|
510
|
-
private fun TooltipSingleButton(btn: TooltipButton) {
|
|
511
|
-
if (btn.icon != null) {
|
|
512
|
-
TooltipIconButton(
|
|
513
|
-
icon = btn.icon,
|
|
514
|
-
onPress = btn.onPress ?: {},
|
|
515
|
-
)
|
|
516
|
-
} else {
|
|
517
|
-
TooltipPrimaryButton(
|
|
518
|
-
title = btn.title ?: "",
|
|
519
|
-
onPress = btn.onPress ?: {},
|
|
520
|
-
)
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
@Composable
|
|
524
|
-
private fun TooltipPrimaryButton(
|
|
525
|
-
title: String,
|
|
526
|
-
onPress: () -> Unit,
|
|
527
|
-
) {
|
|
528
|
-
Button(
|
|
529
|
-
onClick = onPress,
|
|
530
|
-
title = title,
|
|
531
|
-
type = ButtonType.SECONDARY,
|
|
532
|
-
size = Size.MEDIUM,
|
|
533
|
-
isFull = false,
|
|
534
|
-
)
|
|
535
|
-
}
|
|
536
|
-
@Composable
|
|
537
|
-
private fun TooltipSecondaryButton(
|
|
538
|
-
title: String,
|
|
539
|
-
onPress: () -> Unit,
|
|
540
|
-
) {
|
|
541
|
-
Box(
|
|
542
|
-
modifier = Modifier
|
|
543
|
-
.activeOpacityClickable {
|
|
544
|
-
onPress()
|
|
545
|
-
}
|
|
546
|
-
.padding(horizontal = Spacing.M, vertical = Spacing.S),
|
|
547
|
-
) {
|
|
548
|
-
Text(
|
|
549
|
-
text = title,
|
|
550
|
-
color = Colors.black_01,
|
|
551
|
-
style = Typography.actionSBold,
|
|
552
|
-
)
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
@Composable
|
|
556
|
-
private fun TooltipIconButton(
|
|
557
|
-
icon: String,
|
|
558
|
-
onPress: () -> Unit,
|
|
559
|
-
) {
|
|
560
|
-
val iconButtonSize = scaleSize(36f).dp
|
|
561
|
-
|
|
562
|
-
Box(
|
|
563
|
-
modifier = Modifier
|
|
564
|
-
.size(iconButtonSize)
|
|
565
|
-
.background(Colors.black_01, RoundedCornerShape(Radius.XL))
|
|
566
|
-
.clip(RoundedCornerShape(Radius.XL))
|
|
567
|
-
.clickable(
|
|
568
|
-
interactionSource = remember { MutableInteractionSource() },
|
|
569
|
-
indication = null,
|
|
570
|
-
onClick = onPress,
|
|
571
|
-
),
|
|
572
|
-
contentAlignment = Alignment.Center,
|
|
573
|
-
) {
|
|
574
|
-
Icon(source = icon)
|
|
575
|
-
}
|
|
576
|
-
}
|