@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,123 +0,0 @@
|
|
|
1
|
-
package com.example.checkbox
|
|
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.width
|
|
10
|
-
import androidx.compose.material3.Button
|
|
11
|
-
import androidx.compose.material3.Checkbox
|
|
12
|
-
import androidx.compose.material3.MaterialTheme
|
|
13
|
-
import androidx.compose.material3.Text
|
|
14
|
-
import androidx.compose.material3.TextButton
|
|
15
|
-
import androidx.compose.runtime.Composable
|
|
16
|
-
import androidx.compose.runtime.getValue
|
|
17
|
-
import androidx.compose.runtime.mutableStateOf
|
|
18
|
-
import androidx.compose.runtime.remember
|
|
19
|
-
import androidx.compose.runtime.setValue
|
|
20
|
-
import androidx.compose.ui.Alignment
|
|
21
|
-
import androidx.compose.ui.Modifier
|
|
22
|
-
import androidx.compose.ui.text.style.TextDecoration
|
|
23
|
-
import androidx.compose.ui.unit.dp
|
|
24
|
-
|
|
25
|
-
@Composable
|
|
26
|
-
fun TermsAndConditionsCheckbox(
|
|
27
|
-
onTermsAccepted: (Boolean) -> Unit,
|
|
28
|
-
modifier: Modifier = Modifier
|
|
29
|
-
) {
|
|
30
|
-
var isChecked by remember { mutableStateOf(false) }
|
|
31
|
-
|
|
32
|
-
Row(
|
|
33
|
-
modifier = modifier
|
|
34
|
-
.fillMaxWidth()
|
|
35
|
-
.padding(vertical = 8.dp),
|
|
36
|
-
verticalAlignment = Alignment.CenterVertically
|
|
37
|
-
) {
|
|
38
|
-
Checkbox(
|
|
39
|
-
checked = isChecked,
|
|
40
|
-
onCheckedChange = { newValue ->
|
|
41
|
-
isChecked = newValue
|
|
42
|
-
onTermsAccepted(newValue)
|
|
43
|
-
}
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
Spacer(modifier = Modifier.width(8.dp))
|
|
47
|
-
|
|
48
|
-
Column(modifier = Modifier.weight(1f)) {
|
|
49
|
-
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
50
|
-
Text(
|
|
51
|
-
text = "I agree to the",
|
|
52
|
-
style = MaterialTheme.typography.bodyMedium
|
|
53
|
-
)
|
|
54
|
-
TextButton(onClick = { /* Open terms */ }) {
|
|
55
|
-
Text(
|
|
56
|
-
text = "Terms and Conditions",
|
|
57
|
-
style = MaterialTheme.typography.bodyMedium,
|
|
58
|
-
textDecoration = TextDecoration.Underline,
|
|
59
|
-
color = MaterialTheme.colorScheme.primary
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
Text(
|
|
65
|
-
text = "and",
|
|
66
|
-
style = MaterialTheme.typography.bodyMedium
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
TextButton(onClick = { /* Open privacy policy */ }) {
|
|
70
|
-
Text(
|
|
71
|
-
text = "Privacy Policy",
|
|
72
|
-
style = MaterialTheme.typography.bodyMedium,
|
|
73
|
-
textDecoration = TextDecoration.Underline,
|
|
74
|
-
color = MaterialTheme.colorScheme.primary
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
@Composable
|
|
82
|
-
fun CheckBoxExample(
|
|
83
|
-
modifier: Modifier = Modifier
|
|
84
|
-
) {
|
|
85
|
-
var termsAccepted by remember { mutableStateOf(false) }
|
|
86
|
-
|
|
87
|
-
Column(
|
|
88
|
-
modifier = modifier
|
|
89
|
-
.fillMaxWidth()
|
|
90
|
-
.padding(16.dp)
|
|
91
|
-
) {
|
|
92
|
-
Text(
|
|
93
|
-
text = "Create Account",
|
|
94
|
-
style = MaterialTheme.typography.headlineMedium,
|
|
95
|
-
modifier = Modifier.padding(bottom = 24.dp)
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
TermsAndConditionsCheckbox(
|
|
99
|
-
onTermsAccepted = { accepted ->
|
|
100
|
-
termsAccepted = accepted
|
|
101
|
-
}
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
Spacer(modifier = Modifier.height(24.dp))
|
|
105
|
-
|
|
106
|
-
Button(
|
|
107
|
-
onClick = { /* Handle signup */ },
|
|
108
|
-
enabled = termsAccepted,
|
|
109
|
-
modifier = Modifier.fillMaxWidth()
|
|
110
|
-
) {
|
|
111
|
-
Text(text = "Sign Up")
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!termsAccepted) {
|
|
115
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
116
|
-
Text(
|
|
117
|
-
text = "Please accept the terms and conditions to continue",
|
|
118
|
-
style = MaterialTheme.typography.bodySmall,
|
|
119
|
-
color = MaterialTheme.colorScheme.error
|
|
120
|
-
)
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
package com.example
|
|
2
|
-
|
|
3
|
-
import android.app.DatePickerDialog
|
|
4
|
-
import android.app.TimePickerDialog
|
|
5
|
-
import androidx.compose.foundation.layout.Column
|
|
6
|
-
import androidx.compose.foundation.layout.Spacer
|
|
7
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
8
|
-
import androidx.compose.foundation.layout.height
|
|
9
|
-
import androidx.compose.foundation.layout.padding
|
|
10
|
-
import androidx.compose.material3.Button
|
|
11
|
-
import androidx.compose.material3.Text
|
|
12
|
-
import androidx.compose.runtime.Composable
|
|
13
|
-
import androidx.compose.runtime.getValue
|
|
14
|
-
import androidx.compose.runtime.mutableLongStateOf
|
|
15
|
-
import androidx.compose.runtime.mutableStateOf
|
|
16
|
-
import androidx.compose.runtime.remember
|
|
17
|
-
import androidx.compose.runtime.setValue
|
|
18
|
-
import androidx.compose.ui.Modifier
|
|
19
|
-
import androidx.compose.ui.platform.LocalContext
|
|
20
|
-
import androidx.compose.ui.unit.dp
|
|
21
|
-
import vn.momo.kits.components.DateTimePicker
|
|
22
|
-
import vn.momo.kits.components.Title
|
|
23
|
-
import vn.momo.kits.components.TitleType
|
|
24
|
-
import java.text.SimpleDateFormat
|
|
25
|
-
import java.util.Calendar
|
|
26
|
-
import java.util.Date
|
|
27
|
-
import java.util.Locale
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* DateTimePicker Component Example
|
|
31
|
-
*
|
|
32
|
-
* This example demonstrates how to use the DateTimePicker component from MoMo Native Kits
|
|
33
|
-
* for date selection in a Kotlin Multiplatform Compose project.
|
|
34
|
-
*
|
|
35
|
-
* The DateTimePicker supports:
|
|
36
|
-
* - Single date selection
|
|
37
|
-
* - Date range selection (isRangeMode)
|
|
38
|
-
* - Minimum and maximum date constraints
|
|
39
|
-
* - Custom date format
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
@Composable
|
|
43
|
-
fun DateTimePickerExample() {
|
|
44
|
-
val context = LocalContext.current
|
|
45
|
-
|
|
46
|
-
// State for single date selection
|
|
47
|
-
var selectedDate by remember { mutableLongStateOf<Long?>(null) }
|
|
48
|
-
|
|
49
|
-
// State for date range selection
|
|
50
|
-
var startDate by remember { mutableLongStateOf<Long?>(null) }
|
|
51
|
-
var endDate by remember { mutableLongStateOf<Long?>(null) }
|
|
52
|
-
|
|
53
|
-
// State to toggle between single and range mode
|
|
54
|
-
var isRangeMode by remember { mutableStateOf(false) }
|
|
55
|
-
|
|
56
|
-
// Date formatter
|
|
57
|
-
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
|
|
58
|
-
|
|
59
|
-
// Calculate min and max dates (e.g., today and 1 year from now)
|
|
60
|
-
val calendar = Calendar.getInstance()
|
|
61
|
-
val today = calendar.timeInMillis
|
|
62
|
-
|
|
63
|
-
calendar.add(Calendar.YEAR, 1)
|
|
64
|
-
val oneYearFromNow = calendar.timeInMillis
|
|
65
|
-
|
|
66
|
-
Column(
|
|
67
|
-
modifier = Modifier
|
|
68
|
-
.fillMaxWidth()
|
|
69
|
-
.padding(16.dp)
|
|
70
|
-
) {
|
|
71
|
-
// Title
|
|
72
|
-
Title(
|
|
73
|
-
text = "DateTimePicker Example",
|
|
74
|
-
type = TitleType.TITLE_1
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
Spacer(modifier = Modifier.height(24.dp))
|
|
78
|
-
|
|
79
|
-
// Single Date Selection Mode
|
|
80
|
-
Text(text = "Single Date Selection:")
|
|
81
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
82
|
-
|
|
83
|
-
// Display selected date
|
|
84
|
-
Text(
|
|
85
|
-
text = if (selectedDate != null) {
|
|
86
|
-
"Selected: ${dateFormat.format(Date(selectedDate!!))}"
|
|
87
|
-
} else {
|
|
88
|
-
"No date selected"
|
|
89
|
-
}
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
93
|
-
|
|
94
|
-
// Using DateTimePicker for single date selection
|
|
95
|
-
DateTimePicker(
|
|
96
|
-
selectedDate = selectedDate,
|
|
97
|
-
onDateSelected = { timestamp ->
|
|
98
|
-
selectedDate = timestamp
|
|
99
|
-
},
|
|
100
|
-
minDate = today,
|
|
101
|
-
maxDate = oneYearFromNow,
|
|
102
|
-
dateFormat = "dd/MM/yyyy",
|
|
103
|
-
isRangeMode = false,
|
|
104
|
-
modifier = Modifier.fillMaxWidth()
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
Spacer(modifier = Modifier.height(24.dp))
|
|
108
|
-
|
|
109
|
-
// Date Range Selection Mode
|
|
110
|
-
Text(text = "Date Range Selection:")
|
|
111
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
112
|
-
|
|
113
|
-
// Display selected range
|
|
114
|
-
Text(
|
|
115
|
-
text = buildString {
|
|
116
|
-
if (startDate != null && endDate != null) {
|
|
117
|
-
append("From: ${dateFormat.format(Date(startDate!!))}")
|
|
118
|
-
append(" To: ${dateFormat.format(Date(endDate!!))}")
|
|
119
|
-
} else if (startDate != null) {
|
|
120
|
-
append("Start: ${dateFormat.format(Date(startDate!!))}")
|
|
121
|
-
append(" (Select end date)")
|
|
122
|
-
} else {
|
|
123
|
-
append("No range selected")
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
129
|
-
|
|
130
|
-
// Using DateTimePicker for date range selection
|
|
131
|
-
DateTimePicker(
|
|
132
|
-
selectedDate = startDate,
|
|
133
|
-
onDateSelected = { timestamp ->
|
|
134
|
-
if (isRangeMode) {
|
|
135
|
-
// In range mode, handle start/end based on current state
|
|
136
|
-
if (startDate == null || (startDate != null && endDate != null)) {
|
|
137
|
-
startDate = timestamp
|
|
138
|
-
endDate = null
|
|
139
|
-
} else if (timestamp > startDate) {
|
|
140
|
-
endDate = timestamp
|
|
141
|
-
} else {
|
|
142
|
-
startDate = timestamp
|
|
143
|
-
endDate = null
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
selectedDate = timestamp
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
minDate = today,
|
|
150
|
-
maxDate = oneYearFromNow,
|
|
151
|
-
dateFormat = "dd/MM/yyyy",
|
|
152
|
-
isRangeMode = true,
|
|
153
|
-
onRangeSelected = { start, end ->
|
|
154
|
-
startDate = start
|
|
155
|
-
endDate = end
|
|
156
|
-
},
|
|
157
|
-
modifier = Modifier.fillMaxWidth()
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
Spacer(modifier = Modifier.height(24.dp))
|
|
161
|
-
|
|
162
|
-
// Toggle mode button
|
|
163
|
-
Button(
|
|
164
|
-
onClick = {
|
|
165
|
-
isRangeMode = !isRangeMode
|
|
166
|
-
// Reset selection when toggling mode
|
|
167
|
-
selectedDate = null
|
|
168
|
-
startDate = null
|
|
169
|
-
endDate = null
|
|
170
|
-
},
|
|
171
|
-
modifier = Modifier.fillMaxWidth()
|
|
172
|
-
) {
|
|
173
|
-
Text(
|
|
174
|
-
text = if (isRangeMode) "Switch to Single Date Mode" else "Switch to Range Mode"
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
179
|
-
|
|
180
|
-
// Clear selection button
|
|
181
|
-
Button(
|
|
182
|
-
onClick = {
|
|
183
|
-
selectedDate = null
|
|
184
|
-
startDate = null
|
|
185
|
-
endDate = null
|
|
186
|
-
},
|
|
187
|
-
modifier = Modifier.fillMaxWidth()
|
|
188
|
-
) {
|
|
189
|
-
Text(text = "Clear Selection")
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Alternative implementation using Android's built-in DatePickerDialog
|
|
196
|
-
* for more customization options
|
|
197
|
-
*/
|
|
198
|
-
@Composable
|
|
199
|
-
fun AlternativeDatePickerExample() {
|
|
200
|
-
val context = LocalContext.current
|
|
201
|
-
var selectedDate by remember { mutableStateOf<Long?>(null) }
|
|
202
|
-
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
|
|
203
|
-
|
|
204
|
-
Column(
|
|
205
|
-
modifier = Modifier
|
|
206
|
-
.fillMaxWidth()
|
|
207
|
-
.padding(16.dp)
|
|
208
|
-
) {
|
|
209
|
-
Text(
|
|
210
|
-
text = if (selectedDate != null) {
|
|
211
|
-
"Selected: ${dateFormat.format(Date(selectedDate!!))}"
|
|
212
|
-
} else {
|
|
213
|
-
"Tap to select a date"
|
|
214
|
-
}
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
218
|
-
|
|
219
|
-
Button(
|
|
220
|
-
onClick = {
|
|
221
|
-
val calendar = Calendar.getInstance()
|
|
222
|
-
selectedDate?.let { calendar.timeInMillis = it }
|
|
223
|
-
|
|
224
|
-
DatePickerDialog(
|
|
225
|
-
context,
|
|
226
|
-
{ _, year, month, dayOfMonth ->
|
|
227
|
-
val selectedCalendar = Calendar.getInstance()
|
|
228
|
-
selectedCalendar.set(year, month, dayOfMonth)
|
|
229
|
-
selectedDate = selectedCalendar.timeInMillis
|
|
230
|
-
},
|
|
231
|
-
calendar.get(Calendar.YEAR),
|
|
232
|
-
calendar.get(Calendar.MONTH),
|
|
233
|
-
calendar.get(Calendar.DAY_OF_MONTH)
|
|
234
|
-
).show()
|
|
235
|
-
},
|
|
236
|
-
modifier = Modifier.fillMaxWidth()
|
|
237
|
-
) {
|
|
238
|
-
Text(text = "Open Date Picker Dialog")
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Example with TimePicker
|
|
245
|
-
*/
|
|
246
|
-
@Composable
|
|
247
|
-
fun DateTimePickerWithTimeExample() {
|
|
248
|
-
var selectedDate by remember { mutableLongStateOf<Long?>(null) }
|
|
249
|
-
var selectedHour by remember { mutableIntStateOf(0) }
|
|
250
|
-
var selectedMinute by remember { mutableIntStateOf(0) }
|
|
251
|
-
|
|
252
|
-
val context = LocalContext.current
|
|
253
|
-
val dateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault())
|
|
254
|
-
|
|
255
|
-
Column(
|
|
256
|
-
modifier = Modifier
|
|
257
|
-
.fillMaxWidth()
|
|
258
|
-
.padding(16.dp)
|
|
259
|
-
) {
|
|
260
|
-
Text(
|
|
261
|
-
text = if (selectedDate != null) {
|
|
262
|
-
val calendar = Calendar.getInstance()
|
|
263
|
-
calendar.timeInMillis = selectedDate!!
|
|
264
|
-
calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
|
|
265
|
-
calendar.set(Calendar.MINUTE, selectedMinute)
|
|
266
|
-
"Selected: ${dateFormat.format(calendar.time)}"
|
|
267
|
-
} else {
|
|
268
|
-
"Select date and time"
|
|
269
|
-
}
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
Spacer(modifier = Modifier.height(16.dp))
|
|
273
|
-
|
|
274
|
-
// Date selection
|
|
275
|
-
Button(
|
|
276
|
-
onClick = {
|
|
277
|
-
val calendar = Calendar.getInstance()
|
|
278
|
-
selectedDate?.let { calendar.timeInMillis = it }
|
|
279
|
-
|
|
280
|
-
DatePickerDialog(
|
|
281
|
-
context,
|
|
282
|
-
{ _, year, month, dayOfMonth ->
|
|
283
|
-
val selectedCalendar = Calendar.getInstance()
|
|
284
|
-
selectedCalendar.set(year, month, dayOfMonth)
|
|
285
|
-
selectedDate = selectedCalendar.timeInMillis
|
|
286
|
-
},
|
|
287
|
-
calendar.get(Calendar.YEAR),
|
|
288
|
-
calendar.get(Calendar.MONTH),
|
|
289
|
-
calendar.get(Calendar.DAY_OF_MONTH)
|
|
290
|
-
).show()
|
|
291
|
-
},
|
|
292
|
-
modifier = Modifier.fillMaxWidth()
|
|
293
|
-
) {
|
|
294
|
-
Text(text = "Select Date")
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
Spacer(modifier = Modifier.height(8.dp))
|
|
298
|
-
|
|
299
|
-
// Time selection
|
|
300
|
-
Button(
|
|
301
|
-
onClick = {
|
|
302
|
-
TimePickerDialog(
|
|
303
|
-
context,
|
|
304
|
-
{ _, hourOfDay, minute ->
|
|
305
|
-
selectedHour = hourOfDay
|
|
306
|
-
selectedMinute = minute
|
|
307
|
-
},
|
|
308
|
-
selectedHour,
|
|
309
|
-
selectedMinute,
|
|
310
|
-
true // 24-hour format
|
|
311
|
-
).show()
|
|
312
|
-
},
|
|
313
|
-
modifier = Modifier.fillMaxWidth()
|
|
314
|
-
) {
|
|
315
|
-
Text(text = "Select Time")
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|