@momo-kits/native-kits 0.157.1-skill.3-debug → 0.157.1-skill.6-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/skills/momo-native-kits-skills/README.md +52 -0
- package/.claude/skills/momo-native-kits-skills/SKILL.md +32 -0
- package/.claude/skills/momo-native-kits-skills/data-display/SKILL.md +42 -0
- package/.claude/skills/momo-native-kits-skills/feedback/SKILL.md +43 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/popup.md +3 -10
- package/.claude/skills/momo-native-kits-skills/form-controls/SKILL.md +42 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/button.md +2 -3
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/input.md +3 -7
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/radio.md +9 -9
- package/.claude/skills/momo-native-kits-skills/layout/SKILL.md +39 -0
- package/.claude/skills/momo-native-kits-skills/navigation/SKILL.md +38 -0
- package/.claude/skills/momo-native-kits-skills/output/test-report.json +12 -0
- package/.claude/skills/momo-native-kits-skills/output/validation-result.json +108 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills}/references/constants.md +81 -6
- package/.claude/skills/momo-native-kits-skills/references/design-guidelines.md +130 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/android-compose.md +29 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/code-convention.md +118 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/compose-multiplatform.md +29 -0
- package/.claude/skills/momo-native-kits-skills/scripts/logger.js +63 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/badge.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/bottomtab.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/button.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/card.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/checkbox.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/chip.js +59 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/divider.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/global.js +61 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/index.js +54 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/input.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/navigation.js +48 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/popup.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/radio.js +105 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/skeleton.js +20 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/snackbar.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/state.js +21 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/switch.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/text.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/tooltip.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/trustbanner.js +22 -0
- package/.claude/skills/momo-native-kits-skills/scripts/test-on-device.sh +117 -0
- package/.claude/skills/momo-native-kits-skills/scripts/test-runner.js +167 -0
- package/.claude/skills/momo-native-kits-skills/scripts/validate-kits.js +131 -0
- package/.momo-agent.json +13 -0
- package/compose/build.gradle.kts +1 -1
- package/gradle.properties +1 -1
- package/package.json +1 -1
- package/.claude/momo-native-kits-skill/SKILL.md +0 -51
- package/.claude/momo-native-kits-skill/evals/evals.json +0 -95
- package/.claude/momo-native-kits-skill/workspace/iteration-1/benchmark.json +0 -20
- package/.claude/momo-native-kits-skill/workspace/iteration-1/benchmark.md +0 -13
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/with_skill/outputs/ButtonExample.kt +0 -55
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/without_skill/outputs/ButtonExample.kt +0 -45
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/with_skill/outputs/InputPhoneExample.kt +0 -40
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/without_skill/outputs/InputPhoneExample.kt +0 -42
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/with_skill/outputs/BottomTabExample.kt +0 -236
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/without_skill/outputs/BottomTabExample.kt +0 -152
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/with_skill/outputs/CheckBoxExample.kt +0 -49
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/without_skill/outputs/CheckBoxExample.kt +0 -123
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/with_skill/outputs/DateTimePickerExample.kt +0 -318
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/without_skill/outputs/DateTimePickerExample.kt +0 -330
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-card/with_skill/outputs/CardExample.kt +0 -124
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-card/without_skill/outputs/CardExample.kt +0 -71
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-loginform/with_skill/outputs/LoginFormExample.kt +0 -134
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-loginform/without_skill/outputs/LoginFormExample.kt +0 -199
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-navcontainer/with_skill/outputs/NavigationContainerExample.kt +0 -224
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-navcontainer/without_skill/outputs/NavigationContainerExample.kt +0 -225
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-popup/with_skill/outputs/PopupExample.kt +0 -79
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-popup/without_skill/outputs/PopupExample.kt +0 -169
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/with_skill/outputs/SetOptionsExample.kt +0 -255
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/without_skill/outputs/SetOptionsExample.kt +0 -212
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-skeleton/with_skill/outputs/SkeletonExample.kt +0 -199
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-skeleton/without_skill/outputs/SkeletonExample.kt +0 -229
- package/.claude/momo-native-kits-skill/workspace/iteration-3/benchmark.json +0 -20
- package/.claude/momo-native-kits-skill/workspace/iteration-3/benchmark.md +0 -13
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/eval_metadata.json +0 -22
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/with_skill/outputs/PrimaryButtonExample.kt +0 -38
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/without_skill/outputs/PrimaryButtonExample.kt +0 -83
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/without_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/eval_metadata.json +0 -22
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/with_skill/outputs/NavigationContainerExample.kt +0 -547
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/without_skill/outputs/MoMoNavigationContainer.kt +0 -519
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/without_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/eval_metadata.json +0 -27
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/with_skill/outputs/SetOptionsExample.kt +0 -429
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/without_skill/outputs/SetOptionsExample.kt +0 -353
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/without_skill/timing.json +0 -5
- package/.claude/settings.local.json +0 -41
- package/local.properties +0 -8
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/badge.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/chip.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/skeleton.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/text.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/snackbar.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/tooltip.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/trustbanner.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/checkbox.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/switch.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/layout}/references/card.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/layout}/references/divider.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/navigation}/references/navigation.md +0 -0
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
package com.momo.navigation.example
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.layout.Box
|
|
4
|
-
import androidx.compose.foundation.layout.fillMaxSize
|
|
5
|
-
import androidx.compose.material3.Text
|
|
6
|
-
import androidx.compose.runtime.Composable
|
|
7
|
-
import androidx.compose.ui.Alignment
|
|
8
|
-
import androidx.compose.ui.Modifier
|
|
9
|
-
import androidx.navigation.NavHostController
|
|
10
|
-
import androidx.navigation.compose.NavHost
|
|
11
|
-
import androidx.navigation.compose.composable
|
|
12
|
-
import androidx.navigation.compose.rememberNavController
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* MoMo Navigation - SetOptions Example
|
|
16
|
-
*
|
|
17
|
-
* In MoMo's navigation system (built on Compose Navigation),
|
|
18
|
-
* you can use setOptions() to programmatically update navigation options
|
|
19
|
-
* including the header/title.
|
|
20
|
-
*
|
|
21
|
-
* Here's how to change the header title dynamically:
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// Define navigation routes
|
|
25
|
-
sealed class Screen(val route: String) {
|
|
26
|
-
object Home : Screen("home")
|
|
27
|
-
object Detail : Screen("detail/{title}") {
|
|
28
|
-
fun createRoute(title: String) = "detail/$title"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Example: NavBackStackEntry extension to get arguments
|
|
33
|
-
// In MoMo navigation, you can access arguments via savedStateHandle
|
|
34
|
-
// Note: This requires MoMo's extended navigation setup
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Example 1: Basic SetOptions usage in MoMo Navigation
|
|
38
|
-
*
|
|
39
|
-
* In MoMo's navigation, setOptions is typically called within a
|
|
40
|
-
* NavHost or when navigating to update the top app bar.
|
|
41
|
-
*
|
|
42
|
-
* For dynamic header titles, you would typically:
|
|
43
|
-
* 1. Use a state hoisting pattern
|
|
44
|
-
* 2. Pass the title as a navigation argument
|
|
45
|
-
* 3. Update the top bar based on the current destination
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
@Composable
|
|
49
|
-
fun MoMoNavigationExample() {
|
|
50
|
-
val navController = rememberNavController()
|
|
51
|
-
|
|
52
|
-
// State to hold dynamic title - typically this would be in a ViewModel
|
|
53
|
-
val dynamicTitle = androidx.compose.runtime.remember {
|
|
54
|
-
androidx.compose.runtime.mutableStateOf("Home")
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
NavHost(
|
|
58
|
-
navController = navController,
|
|
59
|
-
startDestination = Screen.Home.route
|
|
60
|
-
) {
|
|
61
|
-
composable(Screen.Home.route) {
|
|
62
|
-
// Home screen content
|
|
63
|
-
Box(
|
|
64
|
-
modifier = Modifier.fillMaxSize(),
|
|
65
|
-
contentAlignment = Alignment.Center
|
|
66
|
-
) {
|
|
67
|
-
Text("Home Screen")
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Set options for Home - in practice this is handled by the
|
|
71
|
-
// navigation library's LocalNavigationBar or similar composable
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
composable(
|
|
75
|
-
route = Screen.Detail.route,
|
|
76
|
-
// You can use arguments to get dynamic data
|
|
77
|
-
) { backStackEntry ->
|
|
78
|
-
// Get the title from navigation arguments
|
|
79
|
-
val title = backStackEntry.arguments?.getString("title") ?: "Detail"
|
|
80
|
-
|
|
81
|
-
Box(
|
|
82
|
-
modifier = Modifier.fillMaxSize(),
|
|
83
|
-
contentAlignment = Alignment.Center
|
|
84
|
-
) {
|
|
85
|
-
Text("$title Screen")
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Example 2: Using MoMo's setOptions pattern (if available in your version)
|
|
93
|
-
*
|
|
94
|
-
* In some versions of MoMo navigation, you can use setOptions like this:
|
|
95
|
-
*/
|
|
96
|
-
|
|
97
|
-
fun navigateWithOptions(
|
|
98
|
-
navController: NavHostController,
|
|
99
|
-
title: String
|
|
100
|
-
) {
|
|
101
|
-
// Navigate to the detail screen with the title
|
|
102
|
-
navController.navigate(Screen.Detail.createRoute(title))
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Example 3: Programmatic navigation with dynamic title using Compose Navigation
|
|
107
|
-
*
|
|
108
|
-
* This is the recommended pattern for changing header title dynamically:
|
|
109
|
-
*/
|
|
110
|
-
|
|
111
|
-
@Composable
|
|
112
|
-
fun DynamicHeaderNavigationExample() {
|
|
113
|
-
val navController = rememberNavController()
|
|
114
|
-
|
|
115
|
-
// This state would typically be in a ViewModel
|
|
116
|
-
val currentTitle = androidx.compose.runtime.remember {
|
|
117
|
-
androidx.compose.runtime.mutableStateOf("Home Screen")
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Update the title when navigating
|
|
121
|
-
fun navigateToDetail(newTitle: String) {
|
|
122
|
-
currentTitle.value = newTitle
|
|
123
|
-
navController.navigate(Screen.Detail.createRoute(newTitle))
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Example 4: Complete example with MoMo-style TopAppBar integration
|
|
129
|
-
*/
|
|
130
|
-
|
|
131
|
-
@Composable
|
|
132
|
-
fun FullNavigationExample() {
|
|
133
|
-
val navController = rememberNavController()
|
|
134
|
-
|
|
135
|
-
// This would typically be provided via a ViewModel or navigation library
|
|
136
|
-
val (currentTitle, setCurrentTitle) = androidx.compose.runtime.remember {
|
|
137
|
-
androidx.compose.runtime.mutableStateOf("Home")
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
NavHost(
|
|
141
|
-
navController = navController,
|
|
142
|
-
startDestination = Screen.Home.route
|
|
143
|
-
) {
|
|
144
|
-
composable(Screen.Home.route) {
|
|
145
|
-
HomeScreen(
|
|
146
|
-
onNavigateToDetail = { title ->
|
|
147
|
-
setCurrentTitle(title)
|
|
148
|
-
navController.navigate(Screen.Detail.createRoute(title))
|
|
149
|
-
}
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
composable(Screen.Detail.route) { backStackEntry ->
|
|
154
|
-
val title = backStackEntry.arguments?.getString("title") ?: "Detail"
|
|
155
|
-
DetailScreen(
|
|
156
|
-
title = title,
|
|
157
|
-
onNavigateBack = {
|
|
158
|
-
navController.popBackStack()
|
|
159
|
-
}
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@Composable
|
|
166
|
-
fun HomeScreen(
|
|
167
|
-
onNavigateToDetail: (String) -> Unit
|
|
168
|
-
) {
|
|
169
|
-
Box(
|
|
170
|
-
modifier = Modifier.fillMaxSize(),
|
|
171
|
-
contentAlignment = Alignment.Center
|
|
172
|
-
) {
|
|
173
|
-
Text("Home Screen")
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
@Composable
|
|
178
|
-
fun DetailScreen(
|
|
179
|
-
title: String,
|
|
180
|
-
onNavigateBack: () -> Unit
|
|
181
|
-
) {
|
|
182
|
-
Box(
|
|
183
|
-
modifier = Modifier.fillMaxSize(),
|
|
184
|
-
contentAlignment = Alignment.Center
|
|
185
|
-
) {
|
|
186
|
-
Text("$title Screen")
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Summary: How to change header title dynamically in MoMo Navigation
|
|
192
|
-
*
|
|
193
|
-
* 1. **Use Navigation Arguments**: Pass the title as a route argument
|
|
194
|
-
* navController.navigate("detail/$title")
|
|
195
|
-
*
|
|
196
|
-
* 2. **Read Arguments in Composable**: Access via backStackEntry.arguments
|
|
197
|
-
* val title = backStackEntry.arguments?.getString("title")
|
|
198
|
-
*
|
|
199
|
-
* 3. **State Management**: Use remember/mutableState or a ViewModel
|
|
200
|
-
* to hold and update the current title
|
|
201
|
-
*
|
|
202
|
-
* 4. **Update TopAppBar**: Bind your TopAppBar title to the state
|
|
203
|
-
* that gets updated based on the current destination
|
|
204
|
-
*
|
|
205
|
-
* Note: If MoMo's navigation library has a specific setOptions API,
|
|
206
|
-
* it would typically be used like:
|
|
207
|
-
* navController.setOptions(options = {
|
|
208
|
-
* putString("title", "New Title")
|
|
209
|
-
* })
|
|
210
|
-
*
|
|
211
|
-
* But the standard Compose Navigation approach above is more commonly used.
|
|
212
|
-
*/
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
package com.example
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.layout.Column
|
|
4
|
-
import androidx.compose.foundation.layout.Row
|
|
5
|
-
import androidx.compose.foundation.layout.Spacer
|
|
6
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
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.runtime.Composable
|
|
12
|
-
import androidx.compose.ui.Modifier
|
|
13
|
-
import androidx.compose.ui.unit.dp
|
|
14
|
-
import vn.momo.kits.components.Card
|
|
15
|
-
import vn.momo.kits.components.Skeleton
|
|
16
|
-
import vn.momo.kits.components.Radius
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Example: Loading skeleton for a card component
|
|
20
|
-
*
|
|
21
|
-
* This demonstrates how to create loading skeleton placeholders for cards
|
|
22
|
-
* in MoMo Native Kits to show while content is loading.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Skeleton for a simple card with title
|
|
27
|
-
*/
|
|
28
|
-
@Composable
|
|
29
|
-
fun CardSkeletonSimple() {
|
|
30
|
-
Card(
|
|
31
|
-
modifier = Modifier
|
|
32
|
-
.fillMaxWidth()
|
|
33
|
-
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
34
|
-
) {
|
|
35
|
-
Column(modifier = Modifier.padding(16.dp)) {
|
|
36
|
-
// Title skeleton
|
|
37
|
-
Skeleton(
|
|
38
|
-
width = 120.dp,
|
|
39
|
-
height = 20.dp,
|
|
40
|
-
cornerRadius = Radius.S
|
|
41
|
-
)
|
|
42
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
43
|
-
// Description skeleton
|
|
44
|
-
Skeleton(
|
|
45
|
-
width = 200.dp,
|
|
46
|
-
height = 14.dp,
|
|
47
|
-
cornerRadius = Radius.S
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Skeleton for a card with image and title (matching ListItemCardExample layout)
|
|
55
|
-
*/
|
|
56
|
-
@Composable
|
|
57
|
-
fun CardSkeletonWithImage() {
|
|
58
|
-
Card(
|
|
59
|
-
modifier = Modifier
|
|
60
|
-
.fillMaxWidth()
|
|
61
|
-
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
62
|
-
) {
|
|
63
|
-
Row(
|
|
64
|
-
modifier = Modifier.padding(12.dp)
|
|
65
|
-
) {
|
|
66
|
-
// Image placeholder skeleton
|
|
67
|
-
Skeleton(
|
|
68
|
-
width = 48.dp,
|
|
69
|
-
height = 48.dp,
|
|
70
|
-
cornerRadius = Radius.M
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
// Title placeholder skeleton
|
|
74
|
-
Column(
|
|
75
|
-
modifier = Modifier.padding(start = 12.dp)
|
|
76
|
-
) {
|
|
77
|
-
Skeleton(
|
|
78
|
-
width = 100.dp,
|
|
79
|
-
height = 16.dp,
|
|
80
|
-
cornerRadius = Radius.S
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Skeleton for a card with image, title and description
|
|
89
|
-
* (matching ListItemCardWithDescriptionExample layout)
|
|
90
|
-
*/
|
|
91
|
-
@Composable
|
|
92
|
-
fun CardSkeletonWithImageAndDescription() {
|
|
93
|
-
Card(
|
|
94
|
-
modifier = Modifier
|
|
95
|
-
.fillMaxWidth()
|
|
96
|
-
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
97
|
-
) {
|
|
98
|
-
Row(
|
|
99
|
-
modifier = Modifier.padding(12.dp)
|
|
100
|
-
) {
|
|
101
|
-
// Image placeholder skeleton
|
|
102
|
-
Skeleton(
|
|
103
|
-
width = 56.dp,
|
|
104
|
-
height = 56.dp,
|
|
105
|
-
cornerRadius = Radius.M
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
// Title and description placeholder skeleton
|
|
109
|
-
Column(
|
|
110
|
-
modifier = Modifier.padding(start = 12.dp)
|
|
111
|
-
) {
|
|
112
|
-
Skeleton(
|
|
113
|
-
width = 120.dp,
|
|
114
|
-
height = 18.dp,
|
|
115
|
-
cornerRadius = Radius.S
|
|
116
|
-
)
|
|
117
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
118
|
-
Skeleton(
|
|
119
|
-
width = 180.dp,
|
|
120
|
-
height = 12.dp,
|
|
121
|
-
cornerRadius = Radius.S
|
|
122
|
-
)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Complex skeleton with multiple rows (avatar + text + action)
|
|
130
|
-
*/
|
|
131
|
-
@Composable
|
|
132
|
-
fun CardSkeletonComplex() {
|
|
133
|
-
Card(
|
|
134
|
-
modifier = Modifier
|
|
135
|
-
.fillMaxWidth()
|
|
136
|
-
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
137
|
-
) {
|
|
138
|
-
Column(modifier = Modifier.padding(16.dp)) {
|
|
139
|
-
Row {
|
|
140
|
-
// Avatar skeleton
|
|
141
|
-
Skeleton(
|
|
142
|
-
width = 60.dp,
|
|
143
|
-
height = 60.dp,
|
|
144
|
-
cornerRadius = Radius.XL
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
Column(modifier = Modifier.padding(start = 12.dp)) {
|
|
148
|
-
// Name skeleton
|
|
149
|
-
Skeleton(
|
|
150
|
-
width = 140.dp,
|
|
151
|
-
height = 18.dp,
|
|
152
|
-
cornerRadius = Radius.S
|
|
153
|
-
)
|
|
154
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
155
|
-
// Subtitle skeleton
|
|
156
|
-
Skeleton(
|
|
157
|
-
width = 100.dp,
|
|
158
|
-
height = 14.dp,
|
|
159
|
-
cornerRadius = Radius.S
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
165
|
-
|
|
166
|
-
// Description lines
|
|
167
|
-
Skeleton(
|
|
168
|
-
width = 280.dp,
|
|
169
|
-
height = 14.dp,
|
|
170
|
-
cornerRadius = Radius.S
|
|
171
|
-
)
|
|
172
|
-
Spacer(modifier = Modifier.height(6.dp))
|
|
173
|
-
Skeleton(
|
|
174
|
-
width = 240.dp,
|
|
175
|
-
height = 14.dp,
|
|
176
|
-
cornerRadius = Radius.S
|
|
177
|
-
)
|
|
178
|
-
Spacer(modifier = Modifier.height(6.dp))
|
|
179
|
-
Skeleton(
|
|
180
|
-
width = 180.dp,
|
|
181
|
-
height = 14.dp,
|
|
182
|
-
cornerRadius = Radius.S
|
|
183
|
-
)
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Example: List of card skeletons (loading state for a list)
|
|
190
|
-
*/
|
|
191
|
-
@Composable
|
|
192
|
-
fun CardSkeletonList() {
|
|
193
|
-
Column {
|
|
194
|
-
// Simulating a list of loading cards
|
|
195
|
-
CardSkeletonWithImage()
|
|
196
|
-
CardSkeletonWithImageAndDescription()
|
|
197
|
-
CardSkeletonSimple()
|
|
198
|
-
}
|
|
199
|
-
}
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
package com.example.skeleton
|
|
2
|
-
|
|
3
|
-
import androidx.compose.animation.core.FastOutSlowInEasing
|
|
4
|
-
import androidx.compose.animation.core.RepeatMode
|
|
5
|
-
import androidx.compose.animation.core.animateFloat
|
|
6
|
-
import androidx.compose.animation.core.infiniteRepeatable
|
|
7
|
-
import androidx.compose.animation.core.rememberInfiniteTransition
|
|
8
|
-
import androidx.compose.animation.core.tween
|
|
9
|
-
import androidx.compose.foundation.background
|
|
10
|
-
import androidx.compose.foundation.layout.Arrangement
|
|
11
|
-
import androidx.compose.foundation.layout.Box
|
|
12
|
-
import androidx.compose.foundation.layout.Column
|
|
13
|
-
import androidx.compose.foundation.layout.Row
|
|
14
|
-
import androidx.compose.foundation.layout.Spacer
|
|
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.CircleShape
|
|
21
|
-
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
22
|
-
import androidx.compose.material3.Card
|
|
23
|
-
import androidx.compose.material3.CardDefaults
|
|
24
|
-
import androidx.compose.runtime.Composable
|
|
25
|
-
import androidx.compose.runtime.getValue
|
|
26
|
-
import androidx.compose.ui.Alignment
|
|
27
|
-
import androidx.compose.ui.Modifier
|
|
28
|
-
import androidx.compose.ui.draw.clip
|
|
29
|
-
import androidx.compose.ui.geometry.Offset
|
|
30
|
-
import androidx.compose.ui.graphics.Brush
|
|
31
|
-
import androidx.compose.ui.graphics.Color
|
|
32
|
-
import androidx.compose.ui.unit.dp
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* A loading skeleton component that displays a shimmer effect
|
|
36
|
-
* while content is loading.
|
|
37
|
-
*/
|
|
38
|
-
@Composable
|
|
39
|
-
fun ShimmerSkeleton(
|
|
40
|
-
modifier: Modifier = Modifier,
|
|
41
|
-
content: @Composable (Brush) -> Unit
|
|
42
|
-
) {
|
|
43
|
-
val shimmerColors = listOf(
|
|
44
|
-
Color.LightGray.copy(alpha = 0.6f),
|
|
45
|
-
Color.LightGray.copy(alpha = 0.2f),
|
|
46
|
-
Color.LightGray.copy(alpha = 0.6f)
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
val transition = rememberInfiniteTransition(label = "shimmer")
|
|
50
|
-
val translateAnimation by transition.animateFloat(
|
|
51
|
-
initialValue = 0f,
|
|
52
|
-
targetValue = 1000f,
|
|
53
|
-
animationSpec = infiniteRepeatable(
|
|
54
|
-
animation = tween(
|
|
55
|
-
durationMillis = 1200,
|
|
56
|
-
easing = FastOutSlowInEasing
|
|
57
|
-
),
|
|
58
|
-
repeatMode = RepeatMode.Restart
|
|
59
|
-
),
|
|
60
|
-
label = "shimmer_translate"
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
val brush = Brush.linearGradient(
|
|
64
|
-
colors = shimmerColors,
|
|
65
|
-
start = Offset(translateAnimation - 500f, translateAnimation - 500f),
|
|
66
|
-
end = Offset(translateAnimation, translateAnimation)
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
content(brush)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* A card skeleton that displays a shimmer effect to indicate loading state.
|
|
74
|
-
* This mimics a typical card with an image placeholder, title, subtitle, and action button.
|
|
75
|
-
*/
|
|
76
|
-
@Composable
|
|
77
|
-
fun CardSkeleton(
|
|
78
|
-
modifier: Modifier = Modifier
|
|
79
|
-
) {
|
|
80
|
-
ShimmerSkeleton(modifier = modifier) { brush ->
|
|
81
|
-
Card(
|
|
82
|
-
modifier = modifier
|
|
83
|
-
.fillMaxWidth()
|
|
84
|
-
.padding(16.dp),
|
|
85
|
-
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
|
|
86
|
-
shape = RoundedCornerShape(12.dp)
|
|
87
|
-
) {
|
|
88
|
-
Column(
|
|
89
|
-
modifier = Modifier.padding(16.dp)
|
|
90
|
-
) {
|
|
91
|
-
// Image placeholder
|
|
92
|
-
Box(
|
|
93
|
-
modifier = Modifier
|
|
94
|
-
.fillMaxWidth()
|
|
95
|
-
.height(160.dp)
|
|
96
|
-
.clip(RoundedCornerShape(8.dp))
|
|
97
|
-
.background(brush)
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
101
|
-
|
|
102
|
-
// Title placeholder (2 lines)
|
|
103
|
-
Box(
|
|
104
|
-
modifier = Modifier
|
|
105
|
-
.fillMaxWidth(0.7f)
|
|
106
|
-
.height(20.dp)
|
|
107
|
-
.clip(RoundedCornerShape(4.dp))
|
|
108
|
-
.background(brush)
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
112
|
-
|
|
113
|
-
Box(
|
|
114
|
-
modifier = Modifier
|
|
115
|
-
.fillMaxWidth(0.5f)
|
|
116
|
-
.height(20.dp)
|
|
117
|
-
.clip(RoundedCornerShape(4.dp))
|
|
118
|
-
.background(brush)
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
Spacer(modifier = Modifier.height(12.dp))
|
|
122
|
-
|
|
123
|
-
// Description placeholder (3 lines)
|
|
124
|
-
repeat(3) { index ->
|
|
125
|
-
Box(
|
|
126
|
-
modifier = Modifier
|
|
127
|
-
.fillMaxWidth(if (index == 2) 0.6f else 1f)
|
|
128
|
-
.height(14.dp)
|
|
129
|
-
.clip(RoundedCornerShape(4.dp))
|
|
130
|
-
.background(brush)
|
|
131
|
-
)
|
|
132
|
-
if (index < 2) {
|
|
133
|
-
Spacer(modifier = Modifier.height(6.dp))
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
138
|
-
|
|
139
|
-
// Action button and avatar row
|
|
140
|
-
Row(
|
|
141
|
-
modifier = Modifier.fillMaxWidth(),
|
|
142
|
-
horizontalArrangement = Arrangement.SpaceBetween,
|
|
143
|
-
verticalAlignment = Alignment.CenterVertically
|
|
144
|
-
) {
|
|
145
|
-
// Action button placeholder
|
|
146
|
-
Box(
|
|
147
|
-
modifier = Modifier
|
|
148
|
-
.width(100.dp)
|
|
149
|
-
.height(36.dp)
|
|
150
|
-
.clip(RoundedCornerShape(18.dp))
|
|
151
|
-
.background(brush)
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
// Avatar placeholder
|
|
155
|
-
Box(
|
|
156
|
-
modifier = Modifier
|
|
157
|
-
.size(40.dp)
|
|
158
|
-
.clip(CircleShape)
|
|
159
|
-
.background(brush)
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* A simpler card skeleton with just title and description.
|
|
169
|
-
*/
|
|
170
|
-
@Composable
|
|
171
|
-
fun SimpleCardSkeleton(
|
|
172
|
-
modifier: Modifier = Modifier
|
|
173
|
-
) {
|
|
174
|
-
ShimmerSkeleton(modifier = modifier) { brush ->
|
|
175
|
-
Card(
|
|
176
|
-
modifier = modifier
|
|
177
|
-
.fillMaxWidth()
|
|
178
|
-
.padding(16.dp),
|
|
179
|
-
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
|
|
180
|
-
shape = RoundedCornerShape(8.dp)
|
|
181
|
-
) {
|
|
182
|
-
Column(
|
|
183
|
-
modifier = Modifier.padding(12.dp)
|
|
184
|
-
) {
|
|
185
|
-
// Title
|
|
186
|
-
Box(
|
|
187
|
-
modifier = Modifier
|
|
188
|
-
.fillMaxWidth(0.6f)
|
|
189
|
-
.height(18.dp)
|
|
190
|
-
.clip(RoundedCornerShape(4.dp))
|
|
191
|
-
.background(brush)
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
195
|
-
|
|
196
|
-
// Description
|
|
197
|
-
Box(
|
|
198
|
-
modifier = Modifier
|
|
199
|
-
.fillMaxWidth(0.9f)
|
|
200
|
-
.height(14.dp)
|
|
201
|
-
.clip(RoundedCornerShape(4.dp))
|
|
202
|
-
.background(brush)
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
Spacer(modifier = Modifier.height(4.dp))
|
|
206
|
-
|
|
207
|
-
Box(
|
|
208
|
-
modifier = Modifier
|
|
209
|
-
.fillMaxWidth(0.7f)
|
|
210
|
-
.height(14.dp)
|
|
211
|
-
.clip(RoundedCornerShape(4.dp))
|
|
212
|
-
.background(brush)
|
|
213
|
-
)
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Preview Composable for CardSkeleton
|
|
221
|
-
*/
|
|
222
|
-
@Composable
|
|
223
|
-
fun CardSkeletonPreview() {
|
|
224
|
-
Column {
|
|
225
|
-
CardSkeleton()
|
|
226
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
227
|
-
SimpleCardSkeleton()
|
|
228
|
-
}
|
|
229
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"metadata": {
|
|
3
|
-
"skill_name": "momo-native-kits-skills",
|
|
4
|
-
"skill_path": "<path/to/skill>",
|
|
5
|
-
"executor_model": "<model-name>",
|
|
6
|
-
"analyzer_model": "<model-name>",
|
|
7
|
-
"timestamp": "2026-03-16T09:27:06Z",
|
|
8
|
-
"evals_run": [],
|
|
9
|
-
"runs_per_configuration": 3
|
|
10
|
-
},
|
|
11
|
-
"runs": [],
|
|
12
|
-
"run_summary": {
|
|
13
|
-
"delta": {
|
|
14
|
-
"pass_rate": "+0.00",
|
|
15
|
-
"time_seconds": "+0.0",
|
|
16
|
-
"tokens": "+0"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"notes": []
|
|
20
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Skill Benchmark: momo-native-kits-skills
|
|
2
|
-
|
|
3
|
-
**Model**: <model-name>
|
|
4
|
-
**Date**: 2026-03-16T09:27:06Z
|
|
5
|
-
**Evals**: (3 runs each per configuration)
|
|
6
|
-
|
|
7
|
-
## Summary
|
|
8
|
-
|
|
9
|
-
| Metric | Config A | Config B | Delta |
|
|
10
|
-
|--------|------------|---------------|-------|
|
|
11
|
-
| Pass Rate | 0% ± 0% | 0% ± 0% | +0.00 |
|
|
12
|
-
| Time | 0.0s ± 0.0s | 0.0s ± 0.0s | +0.0s |
|
|
13
|
-
| Tokens | 0 ± 0 | 0 ± 0 | +0 |
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"eval_id": 0,
|
|
3
|
-
"eval_name": "button-primary",
|
|
4
|
-
"prompt": "Show me how to create a primary button with text 'Đăng nhập' in MoMo Native Kits",
|
|
5
|
-
"assertions": [
|
|
6
|
-
{
|
|
7
|
-
"text": "Uses Button from vn.momo.kits.components",
|
|
8
|
-
"passed": true,
|
|
9
|
-
"evidence": "Import vn.momo.kits.components.Button"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"text": "Uses ButtonType.PRIMARY",
|
|
13
|
-
"passed": true,
|
|
14
|
-
"evidence": "type = ButtonType.PRIMARY"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"text": "Title is 'Đăng nhập'",
|
|
18
|
-
"passed": true,
|
|
19
|
-
"evidence": "title = 'Đăng nhập'"
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
}
|